DataSourceWidget.cpp
124 lines
| 3.8 KiB
| text/x-c
|
CppLexer
Alexandre Leroux
|
r82 | #include <DataSource/DataSourceWidget.h> | ||
#include <ui_DataSourceWidget.h> | ||||
#include <DataSource/DataSourceItem.h> | ||||
Alexandre Leroux
|
r477 | #include <DataSource/DataSourceTreeWidgetHelper.h> | ||
Alexandre Leroux
|
r82 | #include <DataSource/DataSourceTreeWidgetItem.h> | ||
Alexandre Leroux
|
r143 | #include <QMenu> | ||
r1478 | namespace | |||
{ | ||||
Alexandre Leroux
|
r82 | |||
/// Number of columns displayed in the tree | ||||
const auto TREE_NB_COLUMNS = 1; | ||||
/// Header labels for the tree | ||||
r1478 | const auto TREE_HEADER_LABELS = QStringList { QObject::tr("Name") }; | |||
Alexandre Leroux
|
r82 | |||
Alexandre Leroux
|
r83 | /** | ||
* Creates the item associated to a data source | ||||
* @param dataSource the data source for which to create the item | ||||
* @return the new item | ||||
*/ | ||||
r1478 | DataSourceTreeWidgetItem* createTreeWidgetItem(DataSourceItem* dataSource) | |||
Alexandre Leroux
|
r83 | { | ||
// Creates item for the data source | ||||
r1478 | auto item = new DataSourceTreeWidgetItem { dataSource }; | |||
Alexandre Leroux
|
r83 | // Generates items for the children of the data source | ||
r1478 | std::for_each(dataSource->cbegin(), dataSource->cend(), | |||
[&item](const std::unique_ptr<DataSourceItem>& child) { | ||||
item->addChild(createTreeWidgetItem(child.get())); | ||||
}); | ||||
Alexandre Leroux
|
r83 | return item; | ||
} | ||||
Alexandre Leroux
|
r82 | } // namespace | ||
r1478 | DataSourceWidget::DataSourceWidget(QWidget* parent) | |||
: QWidget { parent } | ||||
, ui { new Ui::DataSourceWidget } | ||||
, m_Root { std::make_unique<DataSourceItem>( | ||||
DataSourceItemType::NODE, QStringLiteral("Sources")) } | ||||
Alexandre Leroux
|
r82 | { | ||
Alexandre Leroux
|
r109 | ui->setupUi(this); | ||
// Set tree properties | ||||
ui->treeWidget->setColumnCount(TREE_NB_COLUMNS); | ||||
ui->treeWidget->setHeaderLabels(TREE_HEADER_LABELS); | ||||
Alexandre Leroux
|
r143 | ui->treeWidget->setContextMenuPolicy(Qt::CustomContextMenu); | ||
// Connection to show a menu when right clicking on the tree | ||||
connect(ui->treeWidget, &QTreeWidget::customContextMenuRequested, this, | ||||
r1478 | &DataSourceWidget::onTreeMenuRequested); | |||
Alexandre Leroux
|
r475 | |||
// Connection to filter tree | ||||
connect(ui->filterLineEdit, &QLineEdit::textChanged, this, &DataSourceWidget::filterChanged); | ||||
Alexandre Leroux
|
r1034 | |||
// First init | ||||
updateTreeWidget(); | ||||
Alexandre Leroux
|
r82 | } | ||
Alexandre Leroux
|
r83 | |||
r232 | DataSourceWidget::~DataSourceWidget() noexcept | |||
{ | ||||
delete ui; | ||||
} | ||||
r1478 | void DataSourceWidget::addDataSource(DataSourceItem* dataSource) noexcept | |||
Alexandre Leroux
|
r83 | { | ||
Alexandre Leroux
|
r1035 | // Merges the data source (without taking its root) | ||
r1478 | if (dataSource) | |||
{ | ||||
std::for_each(std::cbegin(*dataSource), std::cend(*dataSource), | ||||
[this](const auto& child) { this->m_Root->merge(*child.get()); }); | ||||
Alexandre Leroux
|
r1035 | updateTreeWidget(); | ||
Alexandre Leroux
|
r92 | } | ||
Alexandre Leroux
|
r83 | } | ||
Alexandre Leroux
|
r143 | |||
Alexandre Leroux
|
r1034 | void DataSourceWidget::updateTreeWidget() noexcept | ||
{ | ||||
ui->treeWidget->clear(); | ||||
auto rootItem = createTreeWidgetItem(m_Root.get()); | ||||
ui->treeWidget->addTopLevelItem(rootItem); | ||||
rootItem->setExpanded(true); | ||||
// Sorts tree | ||||
ui->treeWidget->setSortingEnabled(true); | ||||
ui->treeWidget->sortByColumn(0, Qt::AscendingOrder); | ||||
} | ||||
r1478 | void DataSourceWidget::filterChanged(const QString& text) noexcept | |||
Alexandre Leroux
|
r475 | { | ||
r1478 | auto validateItem = [&text](const DataSourceTreeWidgetItem& item) { | |||
auto regExp = QRegExp { text, Qt::CaseInsensitive, QRegExp::Wildcard }; | ||||
Alexandre Leroux
|
r477 | |||
// An item is valid if any of its metadata validates the text filter | ||||
auto itemMetadata = item.data()->data(); | ||||
auto itemMetadataEnd = itemMetadata.cend(); | ||||
auto acceptFilter | ||||
r1478 | = [®Exp](const auto& variant) { return variant.toString().contains(regExp); }; | |||
Alexandre Leroux
|
r477 | |||
return std::find_if(itemMetadata.cbegin(), itemMetadataEnd, acceptFilter) | ||||
r1478 | != itemMetadataEnd; | |||
Alexandre Leroux
|
r477 | }; | ||
// Applies filter on tree widget | ||||
DataSourceTreeWidgetHelper::filter(*ui->treeWidget, validateItem); | ||||
Alexandre Leroux
|
r475 | } | ||
r1478 | void DataSourceWidget::onTreeMenuRequested(const QPoint& pos) noexcept | |||
Alexandre Leroux
|
r143 | { | ||
// Retrieves the selected item in the tree, and build the menu from its actions | ||||
r1478 | if (auto selectedItem = dynamic_cast<DataSourceTreeWidgetItem*>(ui->treeWidget->itemAt(pos))) | |||
{ | ||||
QMenu treeMenu {}; | ||||
Alexandre Leroux
|
r143 | treeMenu.addActions(selectedItem->actions()); | ||
r1478 | if (!treeMenu.isEmpty()) | |||
{ | ||||
Alexandre Leroux
|
r655 | treeMenu.exec(QCursor::pos()); | ||
Alexandre Leroux
|
r143 | } | ||
} | ||||
} | ||||