diff --git a/core/include/Catalogue/CatalogueController.h b/core/include/Catalogue/CatalogueController.h index 303dacd..de8c463 100644 --- a/core/include/Catalogue/CatalogueController.h +++ b/core/include/Catalogue/CatalogueController.h @@ -62,6 +62,12 @@ public: void saveAll(); + /// Returns the MIME data associated to a list of variables + QByteArray mimeDataForEvents(const QVector > &events) const; + + /// Returns the list of variables contained in a MIME data + QVector > eventsForMimeData(const QByteArray &mimeData) const; + public slots: /// Manage init/end of the controller void initialize(); diff --git a/core/src/Catalogue/CatalogueController.cpp b/core/src/Catalogue/CatalogueController.cpp index 26bdddb..38bc38d 100644 --- a/core/src/Catalogue/CatalogueController.cpp +++ b/core/src/Catalogue/CatalogueController.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -236,6 +237,46 @@ void CatalogueController::saveAll() impl->savAllDB(); } +QByteArray +CatalogueController::mimeDataForEvents(const QVector > &events) const +{ + auto encodedData = QByteArray{}; + + QMap idsPerRepository; + for (auto event : events) { + idsPerRepository[event->getRepository()] << event->getUniqId(); + } + + QDataStream stream{&encodedData, QIODevice::WriteOnly}; + stream << idsPerRepository; + + return encodedData; +} + +QVector > +CatalogueController::eventsForMimeData(const QByteArray &mimeData) const +{ + auto events = QVector >{}; + QDataStream stream{mimeData}; + + QMap idsPerRepository; + stream >> idsPerRepository; + + for (auto it = idsPerRepository.cbegin(); it != idsPerRepository.cend(); ++it) { + auto repository = it.key(); + auto allRepositoryEvent = retrieveEvents(repository); + for (auto uuid : it.value()) { + for (auto repositoryEvent : allRepositoryEvent) { + if (uuid.toUuid() == repositoryEvent->getUniqId()) { + events << repositoryEvent; + } + } + } + } + + return events; +} + void CatalogueController::initialize() { qCDebug(LOG_CatalogueController()) << tr("CatalogueController init") diff --git a/gui/include/Catalogue/CatalogueTreeItems/CatalogueAbstractTreeItem.h b/gui/include/Catalogue/CatalogueTreeItems/CatalogueAbstractTreeItem.h index f520332..7fc10fc 100644 --- a/gui/include/Catalogue/CatalogueTreeItems/CatalogueAbstractTreeItem.h +++ b/gui/include/Catalogue/CatalogueTreeItems/CatalogueAbstractTreeItem.h @@ -25,6 +25,7 @@ public: virtual Qt::ItemFlags flags(int column) const; virtual bool setData(int column, int role, const QVariant &value); virtual bool canDropMimeData(const QMimeData *data, Qt::DropAction action); + virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action); private: class CatalogueAbstractTreeItemPrivate; diff --git a/gui/include/Catalogue/CatalogueTreeItems/CatalogueTreeItem.h b/gui/include/Catalogue/CatalogueTreeItems/CatalogueTreeItem.h index 7165cdc..4aa26d0 100644 --- a/gui/include/Catalogue/CatalogueTreeItems/CatalogueTreeItem.h +++ b/gui/include/Catalogue/CatalogueTreeItems/CatalogueTreeItem.h @@ -15,6 +15,7 @@ public: bool setData(int column, int role, const QVariant &value) override; Qt::ItemFlags flags(int column) const override; bool canDropMimeData(const QMimeData *data, Qt::DropAction action) override; + bool dropMimeData(const QMimeData *data, Qt::DropAction action) override; /// Returns the catalogue represented by the item std::shared_ptr catalogue() const; diff --git a/gui/include/Catalogue/CatalogueTreeModel.h b/gui/include/Catalogue/CatalogueTreeModel.h index 592a276..ac14836 100644 --- a/gui/include/Catalogue/CatalogueTreeModel.h +++ b/gui/include/Catalogue/CatalogueTreeModel.h @@ -16,6 +16,7 @@ class CatalogueTreeModel : public QAbstractItemModel { signals: void itemRenamed(const QModelIndex &index); + void itemDropped(const QModelIndex &parentIndex); public: CatalogueTreeModel(QObject *parent = nullptr); diff --git a/gui/src/Catalogue/CatalogueEventsModel.cpp b/gui/src/Catalogue/CatalogueEventsModel.cpp index de66396..7fa6024 100644 --- a/gui/src/Catalogue/CatalogueEventsModel.cpp +++ b/gui/src/Catalogue/CatalogueEventsModel.cpp @@ -1,5 +1,6 @@ #include "Catalogue/CatalogueEventsModel.h" +#include #include #include #include @@ -370,7 +371,7 @@ void CatalogueEventsModel::sort(int column, Qt::SortOrder order) Qt::DropActions CatalogueEventsModel::supportedDragActions() const { - return Qt::CopyAction | Qt::MoveAction; + return Qt::CopyAction; } QStringList CatalogueEventsModel::mimeTypes() const @@ -415,9 +416,10 @@ QMimeData *CatalogueEventsModel::mimeData(const QModelIndexList &indexes) const } } - auto eventsEncodedData - = QByteArray{}; // sqpApp->catalogueController().->mimeDataForEvents(eventList); //TODO - mimeData->setData(MIME_TYPE_EVENT_LIST, eventsEncodedData); + if (!eventList.isEmpty() && eventProductList.isEmpty()) { + auto eventsEncodedData = sqpApp->catalogueController().mimeDataForEvents(eventList); + mimeData->setData(MIME_TYPE_EVENT_LIST, eventsEncodedData); + } if (eventList.count() + eventProductList.count() == 1) { // No time range MIME data if multiple events are dragged diff --git a/gui/src/Catalogue/CatalogueSideBarWidget.cpp b/gui/src/Catalogue/CatalogueSideBarWidget.cpp index c6088a4..66cb1a8 100644 --- a/gui/src/Catalogue/CatalogueSideBarWidget.cpp +++ b/gui/src/Catalogue/CatalogueSideBarWidget.cpp @@ -35,6 +35,62 @@ struct CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate { CatalogueTreeItem *getCatalogueItem(const std::shared_ptr &catalogue) const; void setHasChanges(bool value, const QModelIndex &index, QTreeView *treeView); bool hasChanges(const QModelIndex &index, QTreeView *treeView); + + 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 > selectedCatalogues(QTreeView *treeView) const + { + QVector > 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(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; + } }; CatalogueSideBarWidget::CatalogueSideBarWidget(QWidget *parent) @@ -55,63 +111,25 @@ CatalogueSideBarWidget::CatalogueSideBarWidget(QWidget *parent) auto emitSelection = [this]() { - auto selectedItems = ui->treeView->selectionModel()->selectedRows(); - if (selectedItems.isEmpty()) { - emit this->selectionCleared(); + 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; } - else { - QVector > catalogues; - QStringList databases; - auto firstIndex = selectedItems.first(); - auto firstItem = impl->m_TreeModel->item(firstIndex); - if (!firstItem) { - Q_ASSERT(false); - return; - } - auto selectionType = firstItem->type(); - - for (auto itemIndex : selectedItems) { - auto item = impl->m_TreeModel->item(itemIndex); - if (item && item->type() == selectionType) { - switch (selectionType) { - case CATALOGUE_ITEM_TYPE: - catalogues.append(static_cast(item)->catalogue()); - break; - case DATABASE_ITEM_TYPE: - databases.append(item->text()); - case ALL_EVENT_ITEM_TYPE: // fallthrough - case TRASH_ITEM_TYPE: // fallthrough - default: - break; - } - } - else { - // Incoherent multi selection - selectionType = -1; - break; - } - } - - switch (selectionType) { - case CATALOGUE_ITEM_TYPE: - emit this->catalogueSelected(catalogues); - break; - case DATABASE_ITEM_TYPE: - emit this->databaseSelected(databases); - break; - case ALL_EVENT_ITEM_TYPE: - emit this->allEventsSelected(); - break; - case TRASH_ITEM_TYPE: - emit this->trashSelected(); - break; - default: - emit this->selectionCleared(); - break; - } - } - - }; connect(ui->treeView, &QTreeView::clicked, emitSelection); diff --git a/gui/src/Catalogue/CatalogueTreeItems/CatalogueAbstractTreeItem.cpp b/gui/src/Catalogue/CatalogueTreeItems/CatalogueAbstractTreeItem.cpp index dde38ba..3fb084c 100644 --- a/gui/src/Catalogue/CatalogueTreeItems/CatalogueAbstractTreeItem.cpp +++ b/gui/src/Catalogue/CatalogueTreeItems/CatalogueAbstractTreeItem.cpp @@ -72,3 +72,10 @@ bool CatalogueAbstractTreeItem::canDropMimeData(const QMimeData *data, Qt::DropA Q_UNUSED(action); return false; } + +bool CatalogueAbstractTreeItem::dropMimeData(const QMimeData *data, Qt::DropAction action) +{ + Q_UNUSED(data); + Q_UNUSED(action); + return false; +} diff --git a/gui/src/Catalogue/CatalogueTreeItems/CatalogueTreeItem.cpp b/gui/src/Catalogue/CatalogueTreeItems/CatalogueTreeItem.cpp index 55c1994..78bcd4b 100644 --- a/gui/src/Catalogue/CatalogueTreeItems/CatalogueTreeItem.cpp +++ b/gui/src/Catalogue/CatalogueTreeItems/CatalogueTreeItem.cpp @@ -79,6 +79,16 @@ bool CatalogueTreeItem::canDropMimeData(const QMimeData *data, Qt::DropAction ac return data->hasFormat(MIME_TYPE_EVENT_LIST); } +bool CatalogueTreeItem::dropMimeData(const QMimeData *data, Qt::DropAction action) +{ + Q_ASSERT(canDropMimeData(data, action)); + + auto events = sqpApp->catalogueController().eventsForMimeData(data->data(MIME_TYPE_EVENT_LIST)); + // impl->m_Catalogue->addEvents(events); TODO: move events in the new catalogue + // Warning: Check that the events aren't already in the catalogue + // Also check for the repository !!! +} + std::shared_ptr CatalogueTreeItem::catalogue() const { return impl->m_Catalogue; diff --git a/gui/src/Catalogue/CatalogueTreeModel.cpp b/gui/src/Catalogue/CatalogueTreeModel.cpp index 43cb96f..86ac456 100644 --- a/gui/src/Catalogue/CatalogueTreeModel.cpp +++ b/gui/src/Catalogue/CatalogueTreeModel.cpp @@ -43,7 +43,7 @@ void CatalogueTreeModel::addChildItem(CatalogueAbstractTreeItem *child, parentItem->addChild(child); endInsertRows(); - emit dataChanged(QModelIndex(), QModelIndex()); + emit dataChanged(parentIndex, parentIndex); } CatalogueAbstractTreeItem *CatalogueTreeModel::item(const QModelIndex &index) const @@ -176,7 +176,18 @@ bool CatalogueTreeModel::canDropMimeData(const QMimeData *data, Qt::DropAction a bool CatalogueTreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { - return false; + bool result = false; + + auto draggedIndex = parent; + auto draggedItem = item(draggedIndex); + if (draggedItem) { + result = draggedItem->dropMimeData(data, action); + if (result) { + emit itemDropped(draggedIndex); + } + } + + return result; } Qt::DropActions CatalogueTreeModel::supportedDropActions() const diff --git a/gui/ui/Catalogue/CatalogueSideBarWidget.ui b/gui/ui/Catalogue/CatalogueSideBarWidget.ui index c8cadef..fc227c5 100644 --- a/gui/ui/Catalogue/CatalogueSideBarWidget.ui +++ b/gui/ui/Catalogue/CatalogueSideBarWidget.ui @@ -79,6 +79,9 @@ QAbstractItemView::DragDrop + + QAbstractItemView::ExtendedSelection + false