From c5e93e891fc654dc0f0c50529a708a2afc1e7e1d 2018-01-08 15:51:20 From: Thibaud Rabillard Date: 2018-01-08 15:51:20 Subject: [PATCH] Move event in catalogue with Drag&Drop --- diff --git a/core/include/Catalogue/CatalogueController.h b/core/include/Catalogue/CatalogueController.h index 3218d28..a385242 100644 --- a/core/include/Catalogue/CatalogueController.h +++ b/core/include/Catalogue/CatalogueController.h @@ -74,6 +74,13 @@ public: /// Returns the list of variables contained in a MIME data QVector > eventsForMimeData(const QByteArray &mimeData) const; + /// Returns the MIME data associated to a list of variables + QByteArray + mimeDataForCatalogues(const QVector > &catalogues) const; + + /// Returns the list of variables contained in a MIME data + QVector > cataloguesForMimeData(const QByteArray &mimeData) const; + public slots: /// Manage init/end of the controller void initialize(); diff --git a/core/include/Common/MimeTypesDef.h b/core/include/Common/MimeTypesDef.h index cb8113a..00dcd3a 100644 --- a/core/include/Common/MimeTypesDef.h +++ b/core/include/Common/MimeTypesDef.h @@ -16,6 +16,7 @@ extern SCIQLOP_CORE_EXPORT const QString MIME_TYPE_PRODUCT_LIST; extern SCIQLOP_CORE_EXPORT const QString MIME_TYPE_TIME_RANGE; extern SCIQLOP_CORE_EXPORT const QString MIME_TYPE_SELECTION_ZONE; extern SCIQLOP_CORE_EXPORT const QString MIME_TYPE_EVENT_LIST; +extern SCIQLOP_CORE_EXPORT const QString MIME_TYPE_SOURCE_CATALOGUE_LIST; #endif // SCIQLOP_MIMETYPESDEF_H diff --git a/core/src/Catalogue/CatalogueController.cpp b/core/src/Catalogue/CatalogueController.cpp index 95607ca..ee018a0 100644 --- a/core/src/Catalogue/CatalogueController.cpp +++ b/core/src/Catalogue/CatalogueController.cpp @@ -382,6 +382,46 @@ CatalogueController::eventsForMimeData(const QByteArray &mimeData) const return events; } +QByteArray CatalogueController::mimeDataForCatalogues( + const QVector > &catalogues) const +{ + auto encodedData = QByteArray{}; + + QMap idsPerRepository; + for (auto catalogue : catalogues) { + idsPerRepository[catalogue->getRepository()] << catalogue->getUniqId(); + } + + QDataStream stream{&encodedData, QIODevice::WriteOnly}; + stream << idsPerRepository; + + return encodedData; +} + +QVector > +CatalogueController::cataloguesForMimeData(const QByteArray &mimeData) const +{ + auto catalogues = QVector >{}; + QDataStream stream{mimeData}; + + QMap idsPerRepository; + stream >> idsPerRepository; + + for (auto it = idsPerRepository.cbegin(); it != idsPerRepository.cend(); ++it) { + auto repository = it.key(); + auto allRepositoryCatalogues = retrieveCatalogues(repository); + for (auto uuid : it.value()) { + for (auto repositoryCatalogues : allRepositoryCatalogues) { + if (uuid.toUuid() == repositoryCatalogues->getUniqId()) { + catalogues << repositoryCatalogues; + } + } + } + } + + return catalogues; +} + void CatalogueController::initialize() { qCDebug(LOG_CatalogueController()) << tr("CatalogueController init") diff --git a/core/src/Common/MimeTypesDef.cpp b/core/src/Common/MimeTypesDef.cpp index 85a5347..7fdc6f4 100644 --- a/core/src/Common/MimeTypesDef.cpp +++ b/core/src/Common/MimeTypesDef.cpp @@ -7,3 +7,4 @@ const QString MIME_TYPE_PRODUCT_LIST = QStringLiteral("sciqlop/product-list"); const QString MIME_TYPE_TIME_RANGE = QStringLiteral("sciqlop/time-range"); const QString MIME_TYPE_SELECTION_ZONE = QStringLiteral("sciqlop/selection-zone"); const QString MIME_TYPE_EVENT_LIST = QStringLiteral("sciqlop/event-list"); +const QString MIME_TYPE_SOURCE_CATALOGUE_LIST = QStringLiteral("sciqlop/source-catalogue-list"); diff --git a/gui/include/Catalogue/CatalogueEventsModel.h b/gui/include/Catalogue/CatalogueEventsModel.h index 6251ac4..b0ba54c 100644 --- a/gui/include/Catalogue/CatalogueEventsModel.h +++ b/gui/include/Catalogue/CatalogueEventsModel.h @@ -6,6 +6,7 @@ #include #include +class DBCatalogue; class DBEvent; class DBEventProduct; @@ -22,6 +23,7 @@ public: enum class Column { Name, TStart, TEnd, Tags, Product, Validation, NbColumn }; + void setSourceCatalogues(const QVector > &catalogues); void setEvents(const QVector > &events); void addEvent(const std::shared_ptr &event); void removeEvent(const std::shared_ptr &event); diff --git a/gui/include/Catalogue/CatalogueTreeModel.h b/gui/include/Catalogue/CatalogueTreeModel.h index bc49d0d..c526657 100644 --- a/gui/include/Catalogue/CatalogueTreeModel.h +++ b/gui/include/Catalogue/CatalogueTreeModel.h @@ -16,7 +16,7 @@ class CatalogueTreeModel : public QAbstractItemModel { signals: void itemRenamed(const QModelIndex &index); - void itemDropped(const QModelIndex &parentIndex); + void itemDropped(const QModelIndex &parentIndex, const QMimeData *data, Qt::DropAction action); public: CatalogueTreeModel(QObject *parent = nullptr); diff --git a/gui/src/Catalogue/CatalogueEventsModel.cpp b/gui/src/Catalogue/CatalogueEventsModel.cpp index 9a79328..e34edfc 100644 --- a/gui/src/Catalogue/CatalogueEventsModel.cpp +++ b/gui/src/Catalogue/CatalogueEventsModel.cpp @@ -24,6 +24,7 @@ const auto EVENT_PRODUCT_ITEM_TYPE = 2; struct CatalogueEventsModel::CatalogueEventsModelPrivate { QVector > m_Events; std::unordered_map > > m_EventProducts; + QVector > m_SourceCatalogue; QStringList columnNames() { @@ -129,6 +130,12 @@ CatalogueEventsModel::CatalogueEventsModel(QObject *parent) { } +void CatalogueEventsModel::setSourceCatalogues( + const QVector > &catalogues) +{ + impl->m_SourceCatalogue = catalogues; +} + void CatalogueEventsModel::setEvents(const QVector > &events) { beginResetModel(); @@ -388,12 +395,12 @@ void CatalogueEventsModel::sort(int column, Qt::SortOrder order) Qt::DropActions CatalogueEventsModel::supportedDragActions() const { - return Qt::CopyAction; + return Qt::CopyAction | Qt::MoveAction; } QStringList CatalogueEventsModel::mimeTypes() const { - return {MIME_TYPE_EVENT_LIST, MIME_TYPE_TIME_RANGE}; + return {MIME_TYPE_EVENT_LIST, MIME_TYPE_SOURCE_CATALOGUE_LIST, MIME_TYPE_TIME_RANGE}; } QMimeData *CatalogueEventsModel::mimeData(const QModelIndexList &indexes) const @@ -436,6 +443,10 @@ QMimeData *CatalogueEventsModel::mimeData(const QModelIndexList &indexes) const if (!eventList.isEmpty() && eventProductList.isEmpty()) { auto eventsEncodedData = sqpApp->catalogueController().mimeDataForEvents(eventList); mimeData->setData(MIME_TYPE_EVENT_LIST, eventsEncodedData); + + auto sourceCataloguesEncodedData + = sqpApp->catalogueController().mimeDataForCatalogues(impl->m_SourceCatalogue); + mimeData->setData(MIME_TYPE_SOURCE_CATALOGUE_LIST, sourceCataloguesEncodedData); } if (eventList.count() + eventProductList.count() == 1) { diff --git a/gui/src/Catalogue/CatalogueEventsWidget.cpp b/gui/src/Catalogue/CatalogueEventsWidget.cpp index 9299528..6a70ae8 100644 --- a/gui/src/Catalogue/CatalogueEventsWidget.cpp +++ b/gui/src/Catalogue/CatalogueEventsWidget.cpp @@ -44,6 +44,7 @@ struct CatalogueEventsWidget::CatalogueEventsWidgetPrivate { void setEvents(const QVector > &events, CatalogueEventsWidget *widget) { widget->ui->treeView->setSortingEnabled(false); + m_Model->setSourceCatalogues(m_DisplayedCatalogues); m_Model->setEvents(events); widget->ui->treeView->setSortingEnabled(true); diff --git a/gui/src/Catalogue/CatalogueSideBarWidget.cpp b/gui/src/Catalogue/CatalogueSideBarWidget.cpp index e38c8ab..f752924 100644 --- a/gui/src/Catalogue/CatalogueSideBarWidget.cpp +++ b/gui/src/Catalogue/CatalogueSideBarWidget.cpp @@ -8,11 +8,13 @@ #include #include #include +#include #include #include #include #include +#include Q_LOGGING_CATEGORY(LOG_CatalogueSideBarWidget, "CatalogueSideBarWidget") @@ -126,13 +128,26 @@ CatalogueSideBarWidget::CatalogueSideBarWidget(QWidget *parent) }); - 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(item)->catalogue(); - this->setCatalogueChanges(catalogue, true); - } - }); + connect(impl->m_TreeModel, &CatalogueTreeModel::itemDropped, + [this](auto index, auto mimeData, auto action) { + auto item = impl->m_TreeModel->item(index); + if (item && item->type() == CATALOGUE_ITEM_TYPE) { + auto catalogue = static_cast(item)->catalogue(); + this->setCatalogueChanges(catalogue, true); + } + + if (action == Qt::MoveAction) { + /// Display a save button on source catalogues + auto sourceCatalogues = sqpApp->catalogueController().cataloguesForMimeData( + mimeData->data(MIME_TYPE_SOURCE_CATALOGUE_LIST)); + for (auto catalogue : sourceCatalogues) { + if (auto catalogueItem = impl->getCatalogueItem(catalogue)) { + this->setCatalogueChanges(catalogue, true); + } + } + } + }); + connect(ui->btnRemove, &QToolButton::clicked, [this]() { QVector, CatalogueAbstractTreeItem *> > cataloguesToItems; @@ -344,7 +359,7 @@ CatalogueTreeItem *CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::getCat for (auto childItem : item->children()) { if (childItem->type() == CATALOGUE_ITEM_TYPE) { auto catalogueItem = static_cast(childItem); - if (catalogueItem->catalogue() == catalogue) { + if (catalogueItem->catalogue()->getUniqId() == catalogue->getUniqId()) { return catalogueItem; } } diff --git a/gui/src/Catalogue/CatalogueTreeItems/CatalogueTreeItem.cpp b/gui/src/Catalogue/CatalogueTreeItems/CatalogueTreeItem.cpp index e4fc8b7..9ec3f9b 100644 --- a/gui/src/Catalogue/CatalogueTreeItems/CatalogueTreeItem.cpp +++ b/gui/src/Catalogue/CatalogueTreeItems/CatalogueTreeItem.cpp @@ -76,12 +76,22 @@ Qt::ItemFlags CatalogueTreeItem::flags(int column) const bool CatalogueTreeItem::canDropMimeData(const QMimeData *data, Qt::DropAction action) { + // Check that the event is not dropped on the same catalogue + auto sourceCatalogues = sqpApp->catalogueController().cataloguesForMimeData( + data->data(MIME_TYPE_SOURCE_CATALOGUE_LIST)); + for (auto catalogue : sourceCatalogues) { + if (catalogue->getUniqId() == impl->m_Catalogue->getUniqId()) { + return false; + } + } + auto events = sqpApp->catalogueController().eventsForMimeData(data->data(MIME_TYPE_EVENT_LIST)); auto canDrop = data->hasFormat(MIME_TYPE_EVENT_LIST); for (auto event : events) { canDrop &= (event->getRepository() == impl->m_Catalogue->getRepository()); } + return canDrop; } @@ -89,14 +99,28 @@ bool CatalogueTreeItem::dropMimeData(const QMimeData *data, Qt::DropAction actio { Q_ASSERT(canDropMimeData(data, action)); // Warning: Check that the events aren't already in the catalogue - // Also check for the repository !!! + // No need to check check for the repository: inter-repository drop is forbidden in + // canDropMimeData auto events = sqpApp->catalogueController().eventsForMimeData(data->data(MIME_TYPE_EVENT_LIST)); + auto sourceCatalogues = sqpApp->catalogueController().cataloguesForMimeData( + data->data(MIME_TYPE_SOURCE_CATALOGUE_LIST)); for (auto event : events) { + + if (action == Qt::MoveAction) { + for (auto catalogue : sourceCatalogues) { + catalogue->removeEvent(event->getUniqId()); + } + } + impl->m_Catalogue->addEvent(event->getUniqId()); - sqpApp->catalogueController().updateCatalogue(impl->m_Catalogue); } + + for (auto catalogue : sourceCatalogues) { + sqpApp->catalogueController().updateCatalogue(catalogue); + } + sqpApp->catalogueController().updateCatalogue(impl->m_Catalogue); } std::shared_ptr CatalogueTreeItem::catalogue() const diff --git a/gui/src/Catalogue/CatalogueTreeModel.cpp b/gui/src/Catalogue/CatalogueTreeModel.cpp index 2708821..bf72ba1 100644 --- a/gui/src/Catalogue/CatalogueTreeModel.cpp +++ b/gui/src/Catalogue/CatalogueTreeModel.cpp @@ -178,6 +178,7 @@ bool CatalogueTreeModel::setData(const QModelIndex &index, const QVariant &value return false; } + bool CatalogueTreeModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const { @@ -200,7 +201,7 @@ bool CatalogueTreeModel::dropMimeData(const QMimeData *data, Qt::DropAction acti if (draggedItem) { result = draggedItem->dropMimeData(data, action); if (result) { - emit itemDropped(draggedIndex); + emit itemDropped(draggedIndex, data, action); } } @@ -214,5 +215,5 @@ Qt::DropActions CatalogueTreeModel::supportedDropActions() const QStringList CatalogueTreeModel::mimeTypes() const { - return {MIME_TYPE_EVENT_LIST}; + return {MIME_TYPE_EVENT_LIST, MIME_TYPE_SOURCE_CATALOGUE_LIST}; }