##// END OF EJS Templates
Add catalogue handling
Add catalogue handling

File last commit:

r1276:4af886ed9de4
r1276:4af886ed9de4
Show More
CatalogueSideBarWidget.cpp
422 lines | 16.3 KiB | text/x-c | CppLexer
/ gui / src / Catalogue / CatalogueSideBarWidget.cpp
Sub widget classes
r1095 #include "Catalogue/CatalogueSideBarWidget.h"
#include "ui_CatalogueSideBarWidget.h"
Display catalogues and events with CatalogueAPI
r1129 #include <SqpApplication.h>
#include <Catalogue/CatalogueController.h>
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 #include <Catalogue/CatalogueExplorerHelper.h>
Refactoring of catalogue: use a custom item class
r1229 #include <Catalogue/CatalogueTreeItems/CatalogueTextTreeItem.h>
#include <Catalogue/CatalogueTreeItems/CatalogueTreeItem.h>
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 #include <Catalogue/CatalogueTreeModel.h>
Display catalogues and events with CatalogueAPI
r1129 #include <CatalogueDao.h>
#include <ComparaisonPredicate.h>
#include <DBCatalogue.h>
Basic context menu on a catalogue item
r1141 #include <QMenu>
Add catalogue handling
r1276 #include <QMessageBox>
Basic context menu on a catalogue item
r1141
Edition of catalogues from the inspector
r1147 Q_LOGGING_CATEGORY(LOG_CatalogueSideBarWidget, "CatalogueSideBarWidget")
Sub widget classes
r1095
Refactoring of catalogue: use a custom item class
r1229 constexpr auto ALL_EVENT_ITEM_TYPE = CatalogueAbstractTreeItem::DEFAULT_TYPE + 1;
constexpr auto TRASH_ITEM_TYPE = CatalogueAbstractTreeItem::DEFAULT_TYPE + 2;
constexpr auto CATALOGUE_ITEM_TYPE = CatalogueAbstractTreeItem::DEFAULT_TYPE + 3;
constexpr auto DATABASE_ITEM_TYPE = CatalogueAbstractTreeItem::DEFAULT_TYPE + 4;
Catalog side bar
r1098
struct CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate {
Display catalogues and events with CatalogueAPI
r1129
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 CatalogueTreeModel *m_TreeModel = nullptr;
void configureTreeWidget(QTreeView *treeView);
QModelIndex addDatabaseItem(const QString &name);
Refactoring of catalogue: use a custom item class
r1229 CatalogueAbstractTreeItem *getDatabaseItem(const QString &name);
Adaptation to the shared pointers of catalogue controller
r1143 void addCatalogueItem(const std::shared_ptr<DBCatalogue> &catalogue,
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 const QModelIndex &databaseIndex);
Edition of catalogues from the inspector
r1147
Refactoring of catalogue: use a custom item class
r1229 CatalogueTreeItem *getCatalogueItem(const std::shared_ptr<DBCatalogue> &catalogue) const;
Add catalogue handling
r1276 void setHasChanges(bool value, const QModelIndex &index, CatalogueSideBarWidget *sideBarWidget);
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 bool hasChanges(const QModelIndex &index, QTreeView *treeView);
Drop of events on a catalogue
r1230
int selectionType(QTreeView *treeView) const
{
auto selectedItems = treeView->selectionModel()->selectedRows();
if (selectedItems.isEmpty()) {
return CatalogueAbstractTreeItem::DEFAULT_TYPE;
}
else {
auto firstIndex = selectedItems.first();
auto firstItem = m_TreeModel->item(firstIndex);
if (!firstItem) {
Q_ASSERT(false);
return CatalogueAbstractTreeItem::DEFAULT_TYPE;
}
auto selectionType = firstItem->type();
for (auto itemIndex : selectedItems) {
auto item = m_TreeModel->item(itemIndex);
if (!item || item->type() != selectionType) {
// Incoherent multi selection
selectionType = CatalogueAbstractTreeItem::DEFAULT_TYPE;
break;
}
}
return selectionType;
}
}
QVector<std::shared_ptr<DBCatalogue> > selectedCatalogues(QTreeView *treeView) const
{
QVector<std::shared_ptr<DBCatalogue> > catalogues;
auto selectedItems = treeView->selectionModel()->selectedRows();
for (auto itemIndex : selectedItems) {
auto item = m_TreeModel->item(itemIndex);
if (item && item->type() == CATALOGUE_ITEM_TYPE) {
catalogues.append(static_cast<CatalogueTreeItem *>(item)->catalogue());
}
}
return catalogues;
}
QStringList selectedRepositories(QTreeView *treeView) const
{
QStringList repositories;
auto selectedItems = treeView->selectionModel()->selectedRows();
for (auto itemIndex : selectedItems) {
auto item = m_TreeModel->item(itemIndex);
if (item && item->type() == DATABASE_ITEM_TYPE) {
repositories.append(item->text());
}
}
return repositories;
}
Catalog side bar
r1098 };
Sub widget classes
r1095 CatalogueSideBarWidget::CatalogueSideBarWidget(QWidget *parent)
Catalog side bar
r1098 : QWidget(parent),
ui(new Ui::CatalogueSideBarWidget),
impl{spimpl::make_unique_impl<CatalogueSideBarWidgetPrivate>()}
Sub widget classes
r1095 {
ui->setupUi(this);
Basic interactions
r1103
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 impl->m_TreeModel = new CatalogueTreeModel(this);
ui->treeView->setModel(impl->m_TreeModel);
impl->configureTreeWidget(ui->treeView);
ui->treeView->header()->setStretchLastSection(false);
ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
ui->treeView->header()->setSectionResizeMode(0, QHeaderView::Stretch);
Display of the save & cancel button next to a catalogue
r1142
Add catalogue handling
r1276 connect(ui->treeView, &QTreeView::clicked, this, &CatalogueSideBarWidget::emitSelection);
connect(ui->treeView->selectionModel(), &QItemSelectionModel::currentChanged, this,
&CatalogueSideBarWidget::emitSelection);
// connect(ui->btnAdd, &QToolButton::clicked, [this]() {
// QVector<std::shared_ptr<DBCatalogue> > catalogues;
// impl->getSelectedItems(ui->treeView, events, eventProducts);
// if (!events.isEmpty() && eventProducts.isEmpty()) {
// if (QMessageBox::warning(this, tr("Remove Event(s)"),
// tr("The selected event(s) will be completly removed "
// "from the repository!\nAre you sure you want to
// continue?"),
// QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
// == QMessageBox::Yes) {
// for (auto event : events) {
// sqpApp->catalogueController().removeEvent(event);
// impl->removeEvent(event, ui->treeView);
// }
// }
// }
// });
connect(impl->m_TreeModel, &CatalogueTreeModel::itemDropped, [this](auto index) {
auto item = impl->m_TreeModel->item(index);
if (item && item->type() == CATALOGUE_ITEM_TYPE) {
auto catalogue = static_cast<CatalogueTreeItem *>(item)->catalogue();
this->setCatalogueChanges(catalogue, true);
Multi selection of catalogues
r1132 }
Add catalogue handling
r1276 });
connect(ui->btnRemove, &QToolButton::clicked, [this]() {
QVector<QPair<std::shared_ptr<DBCatalogue>, CatalogueAbstractTreeItem *> >
cataloguesToItems;
auto selectedIndexes = ui->treeView->selectionModel()->selectedRows();
for (auto index : selectedIndexes) {
auto item = impl->m_TreeModel->item(index);
if (item && item->type() == CATALOGUE_ITEM_TYPE) {
auto catalogue = static_cast<CatalogueTreeItem *>(item)->catalogue();
cataloguesToItems << qMakePair(catalogue, item);
}
}
if (!cataloguesToItems.isEmpty()) {
if (QMessageBox::warning(this, tr("Remove Catalogue(s)"),
tr("The selected catalogues(s) will be completly removed "
"from the repository!\nAre you sure you want to continue?"),
QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
== QMessageBox::Yes) {
for (auto catalogueToItem : cataloguesToItems) {
sqpApp->catalogueController().removeCatalogue(catalogueToItem.first);
impl->m_TreeModel->removeChildItem(
catalogueToItem.second,
impl->m_TreeModel->indexOf(catalogueToItem.second->parent()));
}
}
}
});
Skeleton to fill the inspector with the selection
r1105
Add catalogue handling
r1276 connect(impl->m_TreeModel, &CatalogueTreeModel::itemRenamed, [this](auto index) {
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 auto selectedIndexes = ui->treeView->selectionModel()->selectedRows();
if (selectedIndexes.contains(index)) {
Add catalogue handling
r1276 this->emitSelection();
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 }
Add catalogue handling
r1276 impl->setHasChanges(true, index, this);
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 });
Basic context menu on a catalogue item
r1141
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
Refactoring of catalogue: use a custom item class
r1229 connect(ui->treeView, &QTreeView::customContextMenuRequested, this,
Basic context menu on a catalogue item
r1141 &CatalogueSideBarWidget::onContextMenuRequested);
Sub widget classes
r1095 }
CatalogueSideBarWidget::~CatalogueSideBarWidget()
{
delete ui;
}
Catalog side bar
r1098
Updates model after an event has been created through the colored zone
r1231 void CatalogueSideBarWidget::addCatalogue(const std::shared_ptr<DBCatalogue> &catalogue,
const QString &repository)
{
auto repositoryItem = impl->getDatabaseItem(repository);
impl->addCatalogueItem(catalogue, impl->m_TreeModel->indexOf(repositoryItem));
}
Edition of catalogues from the inspector
r1147 void CatalogueSideBarWidget::setCatalogueChanges(const std::shared_ptr<DBCatalogue> &catalogue,
bool hasChanges)
{
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 if (auto catalogueItem = impl->getCatalogueItem(catalogue)) {
auto index = impl->m_TreeModel->indexOf(catalogueItem);
Add catalogue handling
r1276 impl->setHasChanges(hasChanges, index, this);
Refactoring of catalogue: use a custom item class
r1229 // catalogueItem->refresh();
Edition of catalogues from the inspector
r1147 }
}
Updates model after an event has been created through the colored zone
r1231 QVector<std::shared_ptr<DBCatalogue> >
CatalogueSideBarWidget::getCatalogues(const QString &repository) const
{
QVector<std::shared_ptr<DBCatalogue> > result;
auto repositoryItem = impl->getDatabaseItem(repository);
for (auto child : repositoryItem->children()) {
if (child->type() == CATALOGUE_ITEM_TYPE) {
auto catalogueItem = static_cast<CatalogueTreeItem *>(child);
result << catalogueItem->catalogue();
}
else {
qCWarning(LOG_CatalogueSideBarWidget()) << "getCatalogues: invalid structure";
}
}
return result;
}
Add catalogue handling
r1276 void CatalogueSideBarWidget::emitSelection()
{
auto selectionType = impl->selectionType(ui->treeView);
switch (selectionType) {
case CATALOGUE_ITEM_TYPE:
emit this->catalogueSelected(impl->selectedCatalogues(ui->treeView));
break;
case DATABASE_ITEM_TYPE:
emit this->databaseSelected(impl->selectedRepositories(ui->treeView));
break;
case ALL_EVENT_ITEM_TYPE:
emit this->allEventsSelected();
break;
case TRASH_ITEM_TYPE:
emit this->trashSelected();
break;
default:
emit this->selectionCleared();
break;
}
}
Basic context menu on a catalogue item
r1141 void CatalogueSideBarWidget::onContextMenuRequested(const QPoint &pos)
{
QMenu menu{this};
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 auto currentIndex = ui->treeView->currentIndex();
auto currentItem = impl->m_TreeModel->item(currentIndex);
if (!currentItem) {
return;
}
Basic context menu on a catalogue item
r1141 switch (currentItem->type()) {
case CATALOGUE_ITEM_TYPE:
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 menu.addAction("Rename", [this, currentIndex]() { ui->treeView->edit(currentIndex); });
Basic context menu on a catalogue item
r1141 break;
case DATABASE_ITEM_TYPE:
break;
case ALL_EVENT_ITEM_TYPE:
break;
case TRASH_ITEM_TYPE:
menu.addAction("Empty Trash", []() {
// TODO
});
break;
default:
break;
}
if (!menu.isEmpty()) {
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 menu.exec(ui->treeView->mapToGlobal(pos));
Basic context menu on a catalogue item
r1141 }
}
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 void CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::configureTreeWidget(QTreeView *treeView)
Catalog side bar
r1098 {
Refactoring of catalogue: use a custom item class
r1229 auto allEventsItem = new CatalogueTextTreeItem{QIcon{":/icones/allEvents.png"}, "All Events",
ALL_EVENT_ITEM_TYPE};
Some fixes
r1235 auto allEventIndex = m_TreeModel->addTopLevelItem(allEventsItem);
treeView->setCurrentIndex(allEventIndex);
Catalog side bar
r1098
Refactoring of catalogue: use a custom item class
r1229 auto trashItem
= new CatalogueTextTreeItem{QIcon{":/icones/trash.png"}, "Trash", TRASH_ITEM_TYPE};
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 m_TreeModel->addTopLevelItem(trashItem);
Catalog side bar
r1098
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 auto separator = new QFrame{treeView};
Catalog side bar
r1098 separator->setFrameShape(QFrame::HLine);
Refactoring of catalogue: use a custom item class
r1229 auto separatorItem
= new CatalogueTextTreeItem{QIcon{}, QString{}, CatalogueAbstractTreeItem::DEFAULT_TYPE};
separatorItem->setEnabled(false);
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 auto separatorIndex = m_TreeModel->addTopLevelItem(separatorItem);
treeView->setIndexWidget(separatorIndex, separator);
Methods to add some catalogue items
r1102
Adaptation to last version of catalogue controller
r1164 auto repositories = sqpApp->catalogueController().getRepositories();
for (auto dbname : repositories) {
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 auto dbIndex = addDatabaseItem(dbname);
Adaptation to last version of catalogue controller
r1164 auto catalogues = sqpApp->catalogueController().retrieveCatalogues(dbname);
for (auto catalogue : catalogues) {
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 addCatalogueItem(catalogue, dbIndex);
Adaptation to last version of catalogue controller
r1164 }
Display catalogues and events with CatalogueAPI
r1129 }
Methods to add some catalogue items
r1102
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 treeView->expandAll();
Methods to add some catalogue items
r1102 }
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 QModelIndex
CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::addDatabaseItem(const QString &name)
Methods to add some catalogue items
r1102 {
Refactoring of catalogue: use a custom item class
r1229 auto databaseItem
= new CatalogueTextTreeItem{QIcon{":/icones/database.png"}, {name}, DATABASE_ITEM_TYPE};
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 auto databaseIndex = m_TreeModel->addTopLevelItem(databaseItem);
Methods to add some catalogue items
r1102
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 return databaseIndex;
Methods to add some catalogue items
r1102 }
Refactoring of catalogue: use a custom item class
r1229 CatalogueAbstractTreeItem *
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::getDatabaseItem(const QString &name)
Methods to facilitate add/remove operations
r1134 {
Refactoring of catalogue: use a custom item class
r1229 for (auto item : m_TreeModel->topLevelItems()) {
if (item->type() == DATABASE_ITEM_TYPE && item->text() == name) {
Methods to facilitate add/remove operations
r1134 return item;
}
}
return nullptr;
}
Methods to add some catalogue items
r1102 void CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::addCatalogueItem(
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 const std::shared_ptr<DBCatalogue> &catalogue, const QModelIndex &databaseIndex)
Methods to add some catalogue items
r1102 {
Refactoring of catalogue: use a custom item class
r1229 auto catalogueItem
= new CatalogueTreeItem{catalogue, QIcon{":/icones/catalogue.png"}, CATALOGUE_ITEM_TYPE};
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 m_TreeModel->addChildItem(catalogueItem, databaseIndex);
Catalog side bar
r1098 }
Edition of catalogues from the inspector
r1147
Refactoring of catalogue: use a custom item class
r1229 CatalogueTreeItem *CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::getCatalogueItem(
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 const std::shared_ptr<DBCatalogue> &catalogue) const
Edition of catalogues from the inspector
r1147 {
Refactoring of catalogue: use a custom item class
r1229 for (auto item : m_TreeModel->topLevelItems()) {
Edition of catalogues from the inspector
r1147 if (item->type() == DATABASE_ITEM_TYPE) {
Refactoring of catalogue: use a custom item class
r1229 for (auto childItem : item->children()) {
Edition of catalogues from the inspector
r1147 if (childItem->type() == CATALOGUE_ITEM_TYPE) {
Refactoring of catalogue: use a custom item class
r1229 auto catalogueItem = static_cast<CatalogueTreeItem *>(childItem);
Edition of catalogues from the inspector
r1147 if (catalogueItem->catalogue() == catalogue) {
return catalogueItem;
}
}
else {
qCWarning(LOG_CatalogueSideBarWidget()) << "getCatalogueItem: Invalid tree "
"structure. A database item should "
"only contain catalogues.";
Q_ASSERT(false);
}
}
}
}
return nullptr;
}
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228
Add catalogue handling
r1276 void CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::setHasChanges(
bool value, const QModelIndex &index, CatalogueSideBarWidget *sideBarWidget)
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 {
Add catalogue handling
r1276 std::shared_ptr<DBCatalogue> catalogue = nullptr;
auto item = m_TreeModel->item(index);
if (item && item->type() == CATALOGUE_ITEM_TYPE) {
catalogue = static_cast<CatalogueTreeItem *>(item)->catalogue();
}
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 auto validationIndex = index.sibling(index.row(), (int)CatalogueTreeModel::Column::Validation);
if (value) {
Add catalogue handling
r1276 if (!hasChanges(validationIndex, sideBarWidget->ui->treeView)) {
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 auto widget = CatalogueExplorerHelper::buildValidationWidget(
Add catalogue handling
r1276 sideBarWidget->ui->treeView,
[this, validationIndex, sideBarWidget, catalogue]() {
if (catalogue) {
sqpApp->catalogueController().saveCatalogue(catalogue);
}
setHasChanges(false, validationIndex, sideBarWidget);
},
[this, validationIndex, sideBarWidget, catalogue, item]() {
if (catalogue) {
bool removed;
sqpApp->catalogueController().discardCatalogue(catalogue, removed);
if (removed) {
m_TreeModel->removeChildItem(item,
m_TreeModel->indexOf(item->parent()));
}
else {
m_TreeModel->refresh(m_TreeModel->indexOf(item));
setHasChanges(false, validationIndex, sideBarWidget);
}
sideBarWidget->emitSelection();
}
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 });
Add catalogue handling
r1276 sideBarWidget->ui->treeView->setIndexWidget(validationIndex, widget);
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 }
}
else {
// Note: the widget is destroyed
Add catalogue handling
r1276 sideBarWidget->ui->treeView->setIndexWidget(validationIndex, nullptr);
Refactoring of catalogue display using a QTreeView and a custom model based on QTreeWidgetItem
r1228 }
}
bool CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::hasChanges(const QModelIndex &index,
QTreeView *treeView)
{
auto validationIndex = index.sibling(index.row(), (int)CatalogueTreeModel::Column::Validation);
return treeView->indexWidget(validationIndex) != nullptr;
}