##// END OF EJS Templates
Fix move of an event in another catalogue
trabillard -
r1325:99a785298325
parent child
Show More
@@ -1,28 +1,29
1 #ifndef SCIQLOP_CATALOGUETREEITEM_H
1 #ifndef SCIQLOP_CATALOGUETREEITEM_H
2 #define SCIQLOP_CATALOGUETREEITEM_H
2 #define SCIQLOP_CATALOGUETREEITEM_H
3
3
4 #include <Catalogue/CatalogueTreeItems/CatalogueAbstractTreeItem.h>
4 #include <Catalogue/CatalogueTreeItems/CatalogueAbstractTreeItem.h>
5 #include <Common/spimpl.h>
5 #include <Common/spimpl.h>
6
6
7 class DBCatalogue;
7 class DBCatalogue;
8
8
9
9
10 class CatalogueTreeItem : public CatalogueAbstractTreeItem {
10 class CatalogueTreeItem : public CatalogueAbstractTreeItem {
11 public:
11 public:
12 CatalogueTreeItem(std::shared_ptr<DBCatalogue> catalogue, const QIcon &icon, int type);
12 CatalogueTreeItem(std::shared_ptr<DBCatalogue> catalogue, const QIcon &icon, int type);
13
13
14 QVariant data(int column, int role) const override;
14 QVariant data(int column, int role) const override;
15 bool setData(int column, int role, const QVariant &value) override;
15 bool setData(int column, int role, const QVariant &value) override;
16 Qt::ItemFlags flags(int column) const override;
16 Qt::ItemFlags flags(int column) const override;
17 bool canDropMimeData(const QMimeData *data, Qt::DropAction action) override;
17 bool canDropMimeData(const QMimeData *data, Qt::DropAction action) override;
18 bool dropMimeData(const QMimeData *data, Qt::DropAction action) override;
18 bool dropMimeData(const QMimeData *data, Qt::DropAction action) override;
19
19
20 /// Returns the catalogue represented by the item
20 /// Returns the catalogue represented by the item
21 std::shared_ptr<DBCatalogue> catalogue() const;
21 std::shared_ptr<DBCatalogue> catalogue() const;
22 void replaceCatalogue(const std::shared_ptr<DBCatalogue> &catalogue);
22
23
23 private:
24 private:
24 class CatalogueTreeItemPrivate;
25 class CatalogueTreeItemPrivate;
25 spimpl::unique_impl_ptr<CatalogueTreeItemPrivate> impl;
26 spimpl::unique_impl_ptr<CatalogueTreeItemPrivate> impl;
26 };
27 };
27
28
28 #endif // SCIQLOP_CATALOGUETREEITEM_H
29 #endif // SCIQLOP_CATALOGUETREEITEM_H
@@ -1,447 +1,451
1 #include "Catalogue/CatalogueSideBarWidget.h"
1 #include "Catalogue/CatalogueSideBarWidget.h"
2 #include "ui_CatalogueSideBarWidget.h"
2 #include "ui_CatalogueSideBarWidget.h"
3 #include <SqpApplication.h>
3 #include <SqpApplication.h>
4
4
5 #include <Catalogue/CatalogueController.h>
5 #include <Catalogue/CatalogueController.h>
6 #include <Catalogue/CatalogueExplorerHelper.h>
6 #include <Catalogue/CatalogueExplorerHelper.h>
7 #include <Catalogue/CatalogueTreeItems/CatalogueTextTreeItem.h>
7 #include <Catalogue/CatalogueTreeItems/CatalogueTextTreeItem.h>
8 #include <Catalogue/CatalogueTreeItems/CatalogueTreeItem.h>
8 #include <Catalogue/CatalogueTreeItems/CatalogueTreeItem.h>
9 #include <Catalogue/CatalogueTreeModel.h>
9 #include <Catalogue/CatalogueTreeModel.h>
10 #include <CatalogueDao.h>
10 #include <CatalogueDao.h>
11 #include <Common/MimeTypesDef.h>
11 #include <Common/MimeTypesDef.h>
12 #include <ComparaisonPredicate.h>
12 #include <ComparaisonPredicate.h>
13 #include <DBCatalogue.h>
13 #include <DBCatalogue.h>
14
14
15 #include <QKeyEvent>
15 #include <QKeyEvent>
16 #include <QMenu>
16 #include <QMenu>
17 #include <QMessageBox>
17 #include <QMessageBox>
18 #include <QMimeData>
18 #include <QMimeData>
19
19
20 Q_LOGGING_CATEGORY(LOG_CatalogueSideBarWidget, "CatalogueSideBarWidget")
20 Q_LOGGING_CATEGORY(LOG_CatalogueSideBarWidget, "CatalogueSideBarWidget")
21
21
22
22
23 constexpr auto ALL_EVENT_ITEM_TYPE = CatalogueAbstractTreeItem::DEFAULT_TYPE + 1;
23 constexpr auto ALL_EVENT_ITEM_TYPE = CatalogueAbstractTreeItem::DEFAULT_TYPE + 1;
24 constexpr auto TRASH_ITEM_TYPE = CatalogueAbstractTreeItem::DEFAULT_TYPE + 2;
24 constexpr auto TRASH_ITEM_TYPE = CatalogueAbstractTreeItem::DEFAULT_TYPE + 2;
25 constexpr auto CATALOGUE_ITEM_TYPE = CatalogueAbstractTreeItem::DEFAULT_TYPE + 3;
25 constexpr auto CATALOGUE_ITEM_TYPE = CatalogueAbstractTreeItem::DEFAULT_TYPE + 3;
26 constexpr auto DATABASE_ITEM_TYPE = CatalogueAbstractTreeItem::DEFAULT_TYPE + 4;
26 constexpr auto DATABASE_ITEM_TYPE = CatalogueAbstractTreeItem::DEFAULT_TYPE + 4;
27
27
28
28
29 struct CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate {
29 struct CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate {
30
30
31 CatalogueTreeModel *m_TreeModel = nullptr;
31 CatalogueTreeModel *m_TreeModel = nullptr;
32
32
33 void configureTreeWidget(QTreeView *treeView);
33 void configureTreeWidget(QTreeView *treeView);
34 QModelIndex addDatabaseItem(const QString &name);
34 QModelIndex addDatabaseItem(const QString &name);
35 CatalogueAbstractTreeItem *getDatabaseItem(const QString &name);
35 CatalogueAbstractTreeItem *getDatabaseItem(const QString &name);
36 CatalogueAbstractTreeItem *addCatalogueItem(const std::shared_ptr<DBCatalogue> &catalogue,
36 CatalogueAbstractTreeItem *addCatalogueItem(const std::shared_ptr<DBCatalogue> &catalogue,
37 const QModelIndex &databaseIndex);
37 const QModelIndex &databaseIndex);
38
38
39 CatalogueTreeItem *getCatalogueItem(const std::shared_ptr<DBCatalogue> &catalogue) const;
39 CatalogueTreeItem *getCatalogueItem(const std::shared_ptr<DBCatalogue> &catalogue) const;
40 void setHasChanges(bool value, const QModelIndex &index, CatalogueSideBarWidget *sideBarWidget);
40 void setHasChanges(bool value, const QModelIndex &index, CatalogueSideBarWidget *sideBarWidget);
41 bool hasChanges(const QModelIndex &index, QTreeView *treeView);
41 bool hasChanges(const QModelIndex &index, QTreeView *treeView);
42
42
43 int selectionType(QTreeView *treeView) const
43 int selectionType(QTreeView *treeView) const
44 {
44 {
45 auto selectedItems = treeView->selectionModel()->selectedRows();
45 auto selectedItems = treeView->selectionModel()->selectedRows();
46 if (selectedItems.isEmpty()) {
46 if (selectedItems.isEmpty()) {
47 return CatalogueAbstractTreeItem::DEFAULT_TYPE;
47 return CatalogueAbstractTreeItem::DEFAULT_TYPE;
48 }
48 }
49 else {
49 else {
50 auto firstIndex = selectedItems.first();
50 auto firstIndex = selectedItems.first();
51 auto firstItem = m_TreeModel->item(firstIndex);
51 auto firstItem = m_TreeModel->item(firstIndex);
52 if (!firstItem) {
52 if (!firstItem) {
53 Q_ASSERT(false);
53 Q_ASSERT(false);
54 return CatalogueAbstractTreeItem::DEFAULT_TYPE;
54 return CatalogueAbstractTreeItem::DEFAULT_TYPE;
55 }
55 }
56 auto selectionType = firstItem->type();
56 auto selectionType = firstItem->type();
57
57
58 for (auto itemIndex : selectedItems) {
58 for (auto itemIndex : selectedItems) {
59 auto item = m_TreeModel->item(itemIndex);
59 auto item = m_TreeModel->item(itemIndex);
60 if (!item || item->type() != selectionType) {
60 if (!item || item->type() != selectionType) {
61 // Incoherent multi selection
61 // Incoherent multi selection
62 selectionType = CatalogueAbstractTreeItem::DEFAULT_TYPE;
62 selectionType = CatalogueAbstractTreeItem::DEFAULT_TYPE;
63 break;
63 break;
64 }
64 }
65 }
65 }
66
66
67 return selectionType;
67 return selectionType;
68 }
68 }
69 }
69 }
70
70
71 QVector<std::shared_ptr<DBCatalogue> > selectedCatalogues(QTreeView *treeView) const
71 QVector<std::shared_ptr<DBCatalogue> > selectedCatalogues(QTreeView *treeView) const
72 {
72 {
73 QVector<std::shared_ptr<DBCatalogue> > catalogues;
73 QVector<std::shared_ptr<DBCatalogue> > catalogues;
74 auto selectedItems = treeView->selectionModel()->selectedRows();
74 auto selectedItems = treeView->selectionModel()->selectedRows();
75 for (auto itemIndex : selectedItems) {
75 for (auto itemIndex : selectedItems) {
76 auto item = m_TreeModel->item(itemIndex);
76 auto item = m_TreeModel->item(itemIndex);
77 if (item && item->type() == CATALOGUE_ITEM_TYPE) {
77 if (item && item->type() == CATALOGUE_ITEM_TYPE) {
78 catalogues.append(static_cast<CatalogueTreeItem *>(item)->catalogue());
78 catalogues.append(static_cast<CatalogueTreeItem *>(item)->catalogue());
79 }
79 }
80 }
80 }
81
81
82 return catalogues;
82 return catalogues;
83 }
83 }
84
84
85 QStringList selectedRepositories(QTreeView *treeView) const
85 QStringList selectedRepositories(QTreeView *treeView) const
86 {
86 {
87 QStringList repositories;
87 QStringList repositories;
88 auto selectedItems = treeView->selectionModel()->selectedRows();
88 auto selectedItems = treeView->selectionModel()->selectedRows();
89 for (auto itemIndex : selectedItems) {
89 for (auto itemIndex : selectedItems) {
90 auto item = m_TreeModel->item(itemIndex);
90 auto item = m_TreeModel->item(itemIndex);
91 if (item && item->type() == DATABASE_ITEM_TYPE) {
91 if (item && item->type() == DATABASE_ITEM_TYPE) {
92 repositories.append(item->text());
92 repositories.append(item->text());
93 }
93 }
94 }
94 }
95
95
96 return repositories;
96 return repositories;
97 }
97 }
98 };
98 };
99
99
100 CatalogueSideBarWidget::CatalogueSideBarWidget(QWidget *parent)
100 CatalogueSideBarWidget::CatalogueSideBarWidget(QWidget *parent)
101 : QWidget(parent),
101 : QWidget(parent),
102 ui(new Ui::CatalogueSideBarWidget),
102 ui(new Ui::CatalogueSideBarWidget),
103 impl{spimpl::make_unique_impl<CatalogueSideBarWidgetPrivate>()}
103 impl{spimpl::make_unique_impl<CatalogueSideBarWidgetPrivate>()}
104 {
104 {
105 ui->setupUi(this);
105 ui->setupUi(this);
106
106
107 impl->m_TreeModel = new CatalogueTreeModel(this);
107 impl->m_TreeModel = new CatalogueTreeModel(this);
108 ui->treeView->setModel(impl->m_TreeModel);
108 ui->treeView->setModel(impl->m_TreeModel);
109
109
110 impl->configureTreeWidget(ui->treeView);
110 impl->configureTreeWidget(ui->treeView);
111
111
112 ui->treeView->header()->setStretchLastSection(false);
112 ui->treeView->header()->setStretchLastSection(false);
113 ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
113 ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
114 ui->treeView->header()->setSectionResizeMode((int)CatalogueTreeModel::Column::Name,
114 ui->treeView->header()->setSectionResizeMode((int)CatalogueTreeModel::Column::Name,
115 QHeaderView::Stretch);
115 QHeaderView::Stretch);
116
116
117 connect(ui->treeView, &QTreeView::clicked, this, &CatalogueSideBarWidget::emitSelection);
117 connect(ui->treeView, &QTreeView::clicked, this, &CatalogueSideBarWidget::emitSelection);
118 connect(ui->treeView->selectionModel(), &QItemSelectionModel::currentChanged, this,
118 connect(ui->treeView->selectionModel(), &QItemSelectionModel::currentChanged, this,
119 &CatalogueSideBarWidget::emitSelection);
119 &CatalogueSideBarWidget::emitSelection);
120
120
121
121
122 connect(ui->btnAdd, &QToolButton::clicked, [this]() {
122 connect(ui->btnAdd, &QToolButton::clicked, [this]() {
123 auto catalogue = std::make_shared<DBCatalogue>();
123 auto catalogue = std::make_shared<DBCatalogue>();
124 catalogue->setName(QString("Cat"));
124 catalogue->setName(QString("Cat"));
125 sqpApp->catalogueController().addCatalogue(catalogue);
125 sqpApp->catalogueController().addCatalogue(catalogue);
126 auto item = this->addCatalogue(catalogue, REPOSITORY_DEFAULT);
126 auto item = this->addCatalogue(catalogue, REPOSITORY_DEFAULT);
127 this->setCatalogueChanges(catalogue, true);
127 this->setCatalogueChanges(catalogue, true);
128 ui->treeView->edit(impl->m_TreeModel->indexOf(item));
128 ui->treeView->edit(impl->m_TreeModel->indexOf(item));
129
129
130 });
130 });
131
131
132
132
133 connect(impl->m_TreeModel, &CatalogueTreeModel::itemDropped,
133 connect(impl->m_TreeModel, &CatalogueTreeModel::itemDropped,
134 [this](auto index, auto mimeData, auto action) {
134 [this](auto index, auto mimeData, auto action) {
135 auto item = impl->m_TreeModel->item(index);
135 auto item = impl->m_TreeModel->item(index);
136
136 if (item && item->type() == CATALOGUE_ITEM_TYPE) {
137 if (item && item->type() == CATALOGUE_ITEM_TYPE) {
137 auto catalogue = static_cast<CatalogueTreeItem *>(item)->catalogue();
138 auto catalogue = static_cast<CatalogueTreeItem *>(item)->catalogue();
138 this->setCatalogueChanges(catalogue, true);
139 this->setCatalogueChanges(catalogue, true);
139 }
140 }
140
141
141 if (action == Qt::MoveAction) {
142 if (action == Qt::MoveAction) {
142 /// Display a save button on source catalogues
143 /// Display a save button on source catalogues
143 auto sourceCatalogues = sqpApp->catalogueController().cataloguesForMimeData(
144 auto sourceCatalogues = sqpApp->catalogueController().cataloguesForMimeData(
144 mimeData->data(MIME_TYPE_SOURCE_CATALOGUE_LIST));
145 mimeData->data(MIME_TYPE_SOURCE_CATALOGUE_LIST));
145 for (auto catalogue : sourceCatalogues) {
146 for (auto catalogue : sourceCatalogues) {
146 if (auto catalogueItem = impl->getCatalogueItem(catalogue)) {
147 if (auto catalogueItem = impl->getCatalogueItem(catalogue)) {
148 catalogueItem->replaceCatalogue(catalogue);
147 this->setCatalogueChanges(catalogue, true);
149 this->setCatalogueChanges(catalogue, true);
148 }
150 }
149 }
151 }
152
153 this->emitSelection();
150 }
154 }
151 });
155 });
152
156
153 connect(ui->btnRemove, &QToolButton::clicked, [this]() {
157 connect(ui->btnRemove, &QToolButton::clicked, [this]() {
154 QVector<QPair<std::shared_ptr<DBCatalogue>, CatalogueAbstractTreeItem *> >
158 QVector<QPair<std::shared_ptr<DBCatalogue>, CatalogueAbstractTreeItem *> >
155 cataloguesToItems;
159 cataloguesToItems;
156 auto selectedIndexes = ui->treeView->selectionModel()->selectedRows();
160 auto selectedIndexes = ui->treeView->selectionModel()->selectedRows();
157
161
158 for (auto index : selectedIndexes) {
162 for (auto index : selectedIndexes) {
159 auto item = impl->m_TreeModel->item(index);
163 auto item = impl->m_TreeModel->item(index);
160 if (item && item->type() == CATALOGUE_ITEM_TYPE) {
164 if (item && item->type() == CATALOGUE_ITEM_TYPE) {
161 auto catalogue = static_cast<CatalogueTreeItem *>(item)->catalogue();
165 auto catalogue = static_cast<CatalogueTreeItem *>(item)->catalogue();
162 cataloguesToItems << qMakePair(catalogue, item);
166 cataloguesToItems << qMakePair(catalogue, item);
163 }
167 }
164 }
168 }
165
169
166 if (!cataloguesToItems.isEmpty()) {
170 if (!cataloguesToItems.isEmpty()) {
167
171
168 if (QMessageBox::warning(this, tr("Remove Catalogue(s)"),
172 if (QMessageBox::warning(this, tr("Remove Catalogue(s)"),
169 tr("The selected catalogues(s) will be completly removed "
173 tr("The selected catalogues(s) will be completly removed "
170 "from the repository!\nAre you sure you want to continue?"),
174 "from the repository!\nAre you sure you want to continue?"),
171 QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
175 QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
172 == QMessageBox::Yes) {
176 == QMessageBox::Yes) {
173
177
174 for (auto catalogueToItem : cataloguesToItems) {
178 for (auto catalogueToItem : cataloguesToItems) {
175 sqpApp->catalogueController().removeCatalogue(catalogueToItem.first);
179 sqpApp->catalogueController().removeCatalogue(catalogueToItem.first);
176 impl->m_TreeModel->removeChildItem(
180 impl->m_TreeModel->removeChildItem(
177 catalogueToItem.second,
181 catalogueToItem.second,
178 impl->m_TreeModel->indexOf(catalogueToItem.second->parent()));
182 impl->m_TreeModel->indexOf(catalogueToItem.second->parent()));
179 }
183 }
180 emitSelection();
184 emitSelection();
181 }
185 }
182 }
186 }
183 });
187 });
184
188
185 connect(impl->m_TreeModel, &CatalogueTreeModel::itemRenamed, [this](auto index) {
189 connect(impl->m_TreeModel, &CatalogueTreeModel::itemRenamed, [this](auto index) {
186 auto selectedIndexes = ui->treeView->selectionModel()->selectedRows();
190 auto selectedIndexes = ui->treeView->selectionModel()->selectedRows();
187 if (selectedIndexes.contains(index)) {
191 if (selectedIndexes.contains(index)) {
188 this->emitSelection();
192 this->emitSelection();
189 }
193 }
190 impl->setHasChanges(true, index, this);
194 impl->setHasChanges(true, index, this);
191 });
195 });
192
196
193 ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
197 ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
194 connect(ui->treeView, &QTreeView::customContextMenuRequested, this,
198 connect(ui->treeView, &QTreeView::customContextMenuRequested, this,
195 &CatalogueSideBarWidget::onContextMenuRequested);
199 &CatalogueSideBarWidget::onContextMenuRequested);
196 }
200 }
197
201
198 CatalogueSideBarWidget::~CatalogueSideBarWidget()
202 CatalogueSideBarWidget::~CatalogueSideBarWidget()
199 {
203 {
200 delete ui;
204 delete ui;
201 }
205 }
202
206
203 CatalogueAbstractTreeItem *
207 CatalogueAbstractTreeItem *
204 CatalogueSideBarWidget::addCatalogue(const std::shared_ptr<DBCatalogue> &catalogue,
208 CatalogueSideBarWidget::addCatalogue(const std::shared_ptr<DBCatalogue> &catalogue,
205 const QString &repository)
209 const QString &repository)
206 {
210 {
207 auto repositoryItem = impl->getDatabaseItem(repository);
211 auto repositoryItem = impl->getDatabaseItem(repository);
208 return impl->addCatalogueItem(catalogue, impl->m_TreeModel->indexOf(repositoryItem));
212 return impl->addCatalogueItem(catalogue, impl->m_TreeModel->indexOf(repositoryItem));
209 }
213 }
210
214
211 void CatalogueSideBarWidget::setCatalogueChanges(const std::shared_ptr<DBCatalogue> &catalogue,
215 void CatalogueSideBarWidget::setCatalogueChanges(const std::shared_ptr<DBCatalogue> &catalogue,
212 bool hasChanges)
216 bool hasChanges)
213 {
217 {
214 if (auto catalogueItem = impl->getCatalogueItem(catalogue)) {
218 if (auto catalogueItem = impl->getCatalogueItem(catalogue)) {
215 auto index = impl->m_TreeModel->indexOf(catalogueItem);
219 auto index = impl->m_TreeModel->indexOf(catalogueItem);
216 impl->setHasChanges(hasChanges, index, this);
220 impl->setHasChanges(hasChanges, index, this);
217 // catalogueItem->refresh();
221 // catalogueItem->refresh();
218 }
222 }
219 }
223 }
220
224
221 QVector<std::shared_ptr<DBCatalogue> >
225 QVector<std::shared_ptr<DBCatalogue> >
222 CatalogueSideBarWidget::getCatalogues(const QString &repository) const
226 CatalogueSideBarWidget::getCatalogues(const QString &repository) const
223 {
227 {
224 QVector<std::shared_ptr<DBCatalogue> > result;
228 QVector<std::shared_ptr<DBCatalogue> > result;
225 auto repositoryItem = impl->getDatabaseItem(repository);
229 auto repositoryItem = impl->getDatabaseItem(repository);
226 for (auto child : repositoryItem->children()) {
230 for (auto child : repositoryItem->children()) {
227 if (child->type() == CATALOGUE_ITEM_TYPE) {
231 if (child->type() == CATALOGUE_ITEM_TYPE) {
228 auto catalogueItem = static_cast<CatalogueTreeItem *>(child);
232 auto catalogueItem = static_cast<CatalogueTreeItem *>(child);
229 result << catalogueItem->catalogue();
233 result << catalogueItem->catalogue();
230 }
234 }
231 else {
235 else {
232 qCWarning(LOG_CatalogueSideBarWidget()) << "getCatalogues: invalid structure";
236 qCWarning(LOG_CatalogueSideBarWidget()) << "getCatalogues: invalid structure";
233 }
237 }
234 }
238 }
235
239
236 return result;
240 return result;
237 }
241 }
238
242
239 void CatalogueSideBarWidget::emitSelection()
243 void CatalogueSideBarWidget::emitSelection()
240 {
244 {
241 auto selectionType = impl->selectionType(ui->treeView);
245 auto selectionType = impl->selectionType(ui->treeView);
242
246
243 switch (selectionType) {
247 switch (selectionType) {
244 case CATALOGUE_ITEM_TYPE:
248 case CATALOGUE_ITEM_TYPE:
245 emit this->catalogueSelected(impl->selectedCatalogues(ui->treeView));
249 emit this->catalogueSelected(impl->selectedCatalogues(ui->treeView));
246 break;
250 break;
247 case DATABASE_ITEM_TYPE:
251 case DATABASE_ITEM_TYPE:
248 emit this->databaseSelected(impl->selectedRepositories(ui->treeView));
252 emit this->databaseSelected(impl->selectedRepositories(ui->treeView));
249 break;
253 break;
250 case ALL_EVENT_ITEM_TYPE:
254 case ALL_EVENT_ITEM_TYPE:
251 emit this->allEventsSelected();
255 emit this->allEventsSelected();
252 break;
256 break;
253 case TRASH_ITEM_TYPE:
257 case TRASH_ITEM_TYPE:
254 emit this->trashSelected();
258 emit this->trashSelected();
255 break;
259 break;
256 default:
260 default:
257 emit this->selectionCleared();
261 emit this->selectionCleared();
258 break;
262 break;
259 }
263 }
260 }
264 }
261
265
262 void CatalogueSideBarWidget::onContextMenuRequested(const QPoint &pos)
266 void CatalogueSideBarWidget::onContextMenuRequested(const QPoint &pos)
263 {
267 {
264 QMenu menu{this};
268 QMenu menu{this};
265
269
266 auto currentIndex = ui->treeView->currentIndex();
270 auto currentIndex = ui->treeView->currentIndex();
267 auto currentItem = impl->m_TreeModel->item(currentIndex);
271 auto currentItem = impl->m_TreeModel->item(currentIndex);
268 if (!currentItem) {
272 if (!currentItem) {
269 return;
273 return;
270 }
274 }
271
275
272 switch (currentItem->type()) {
276 switch (currentItem->type()) {
273 case CATALOGUE_ITEM_TYPE:
277 case CATALOGUE_ITEM_TYPE:
274 menu.addAction("Rename", [this, currentIndex]() { ui->treeView->edit(currentIndex); });
278 menu.addAction("Rename", [this, currentIndex]() { ui->treeView->edit(currentIndex); });
275 break;
279 break;
276 case DATABASE_ITEM_TYPE:
280 case DATABASE_ITEM_TYPE:
277 break;
281 break;
278 case ALL_EVENT_ITEM_TYPE:
282 case ALL_EVENT_ITEM_TYPE:
279 break;
283 break;
280 case TRASH_ITEM_TYPE:
284 case TRASH_ITEM_TYPE:
281 menu.addAction("Empty Trash", []() {
285 menu.addAction("Empty Trash", []() {
282 // TODO
286 // TODO
283 });
287 });
284 break;
288 break;
285 default:
289 default:
286 break;
290 break;
287 }
291 }
288
292
289 if (!menu.isEmpty()) {
293 if (!menu.isEmpty()) {
290 menu.exec(ui->treeView->mapToGlobal(pos));
294 menu.exec(ui->treeView->mapToGlobal(pos));
291 }
295 }
292 }
296 }
293
297
294 void CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::configureTreeWidget(QTreeView *treeView)
298 void CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::configureTreeWidget(QTreeView *treeView)
295 {
299 {
296 auto allEventsItem = new CatalogueTextTreeItem{QIcon{":/icones/allEvents.png"}, "All Events",
300 auto allEventsItem = new CatalogueTextTreeItem{QIcon{":/icones/allEvents.png"}, "All Events",
297 ALL_EVENT_ITEM_TYPE};
301 ALL_EVENT_ITEM_TYPE};
298 auto allEventIndex = m_TreeModel->addTopLevelItem(allEventsItem);
302 auto allEventIndex = m_TreeModel->addTopLevelItem(allEventsItem);
299 treeView->setCurrentIndex(allEventIndex);
303 treeView->setCurrentIndex(allEventIndex);
300
304
301 auto trashItem
305 auto trashItem
302 = new CatalogueTextTreeItem{QIcon{":/icones/trash.png"}, "Trash", TRASH_ITEM_TYPE};
306 = new CatalogueTextTreeItem{QIcon{":/icones/trash.png"}, "Trash", TRASH_ITEM_TYPE};
303 m_TreeModel->addTopLevelItem(trashItem);
307 m_TreeModel->addTopLevelItem(trashItem);
304
308
305 auto separator = new QFrame{treeView};
309 auto separator = new QFrame{treeView};
306 separator->setFrameShape(QFrame::HLine);
310 separator->setFrameShape(QFrame::HLine);
307 auto separatorItem
311 auto separatorItem
308 = new CatalogueTextTreeItem{QIcon{}, QString{}, CatalogueAbstractTreeItem::DEFAULT_TYPE};
312 = new CatalogueTextTreeItem{QIcon{}, QString{}, CatalogueAbstractTreeItem::DEFAULT_TYPE};
309 separatorItem->setEnabled(false);
313 separatorItem->setEnabled(false);
310 auto separatorIndex = m_TreeModel->addTopLevelItem(separatorItem);
314 auto separatorIndex = m_TreeModel->addTopLevelItem(separatorItem);
311 treeView->setIndexWidget(separatorIndex, separator);
315 treeView->setIndexWidget(separatorIndex, separator);
312
316
313 auto repositories = sqpApp->catalogueController().getRepositories();
317 auto repositories = sqpApp->catalogueController().getRepositories();
314 for (auto dbname : repositories) {
318 for (auto dbname : repositories) {
315 auto dbIndex = addDatabaseItem(dbname);
319 auto dbIndex = addDatabaseItem(dbname);
316 auto catalogues = sqpApp->catalogueController().retrieveCatalogues(dbname);
320 auto catalogues = sqpApp->catalogueController().retrieveCatalogues(dbname);
317 for (auto catalogue : catalogues) {
321 for (auto catalogue : catalogues) {
318 addCatalogueItem(catalogue, dbIndex);
322 addCatalogueItem(catalogue, dbIndex);
319 }
323 }
320 }
324 }
321
325
322 treeView->expandAll();
326 treeView->expandAll();
323 }
327 }
324
328
325 QModelIndex
329 QModelIndex
326 CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::addDatabaseItem(const QString &name)
330 CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::addDatabaseItem(const QString &name)
327 {
331 {
328 auto databaseItem
332 auto databaseItem
329 = new CatalogueTextTreeItem{QIcon{":/icones/database.png"}, {name}, DATABASE_ITEM_TYPE};
333 = new CatalogueTextTreeItem{QIcon{":/icones/database.png"}, {name}, DATABASE_ITEM_TYPE};
330 auto databaseIndex = m_TreeModel->addTopLevelItem(databaseItem);
334 auto databaseIndex = m_TreeModel->addTopLevelItem(databaseItem);
331
335
332 return databaseIndex;
336 return databaseIndex;
333 }
337 }
334
338
335 CatalogueAbstractTreeItem *
339 CatalogueAbstractTreeItem *
336 CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::getDatabaseItem(const QString &name)
340 CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::getDatabaseItem(const QString &name)
337 {
341 {
338 for (auto item : m_TreeModel->topLevelItems()) {
342 for (auto item : m_TreeModel->topLevelItems()) {
339 if (item->type() == DATABASE_ITEM_TYPE && item->text() == name) {
343 if (item->type() == DATABASE_ITEM_TYPE && item->text() == name) {
340 return item;
344 return item;
341 }
345 }
342 }
346 }
343
347
344 return nullptr;
348 return nullptr;
345 }
349 }
346
350
347 CatalogueAbstractTreeItem *CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::addCatalogueItem(
351 CatalogueAbstractTreeItem *CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::addCatalogueItem(
348 const std::shared_ptr<DBCatalogue> &catalogue, const QModelIndex &databaseIndex)
352 const std::shared_ptr<DBCatalogue> &catalogue, const QModelIndex &databaseIndex)
349 {
353 {
350 auto catalogueItem
354 auto catalogueItem
351 = new CatalogueTreeItem{catalogue, QIcon{":/icones/catalogue.png"}, CATALOGUE_ITEM_TYPE};
355 = new CatalogueTreeItem{catalogue, QIcon{":/icones/catalogue.png"}, CATALOGUE_ITEM_TYPE};
352 m_TreeModel->addChildItem(catalogueItem, databaseIndex);
356 m_TreeModel->addChildItem(catalogueItem, databaseIndex);
353
357
354 return catalogueItem;
358 return catalogueItem;
355 }
359 }
356
360
357 CatalogueTreeItem *CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::getCatalogueItem(
361 CatalogueTreeItem *CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::getCatalogueItem(
358 const std::shared_ptr<DBCatalogue> &catalogue) const
362 const std::shared_ptr<DBCatalogue> &catalogue) const
359 {
363 {
360 for (auto item : m_TreeModel->topLevelItems()) {
364 for (auto item : m_TreeModel->topLevelItems()) {
361 if (item->type() == DATABASE_ITEM_TYPE) {
365 if (item->type() == DATABASE_ITEM_TYPE) {
362 for (auto childItem : item->children()) {
366 for (auto childItem : item->children()) {
363 if (childItem->type() == CATALOGUE_ITEM_TYPE) {
367 if (childItem->type() == CATALOGUE_ITEM_TYPE) {
364 auto catalogueItem = static_cast<CatalogueTreeItem *>(childItem);
368 auto catalogueItem = static_cast<CatalogueTreeItem *>(childItem);
365 if (catalogueItem->catalogue()->getUniqId() == catalogue->getUniqId()) {
369 if (catalogueItem->catalogue()->getUniqId() == catalogue->getUniqId()) {
366 return catalogueItem;
370 return catalogueItem;
367 }
371 }
368 }
372 }
369 else {
373 else {
370 qCWarning(LOG_CatalogueSideBarWidget()) << "getCatalogueItem: Invalid tree "
374 qCWarning(LOG_CatalogueSideBarWidget()) << "getCatalogueItem: Invalid tree "
371 "structure. A database item should "
375 "structure. A database item should "
372 "only contain catalogues.";
376 "only contain catalogues.";
373 Q_ASSERT(false);
377 Q_ASSERT(false);
374 }
378 }
375 }
379 }
376 }
380 }
377 }
381 }
378
382
379 return nullptr;
383 return nullptr;
380 }
384 }
381
385
382 void CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::setHasChanges(
386 void CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::setHasChanges(
383 bool value, const QModelIndex &index, CatalogueSideBarWidget *sideBarWidget)
387 bool value, const QModelIndex &index, CatalogueSideBarWidget *sideBarWidget)
384 {
388 {
385 std::shared_ptr<DBCatalogue> catalogue = nullptr;
389 std::shared_ptr<DBCatalogue> catalogue = nullptr;
386 auto item = m_TreeModel->item(index);
390 auto item = m_TreeModel->item(index);
387 if (item && item->type() == CATALOGUE_ITEM_TYPE) {
391 if (item && item->type() == CATALOGUE_ITEM_TYPE) {
388 catalogue = static_cast<CatalogueTreeItem *>(item)->catalogue();
392 catalogue = static_cast<CatalogueTreeItem *>(item)->catalogue();
389 }
393 }
390
394
391 auto validationIndex = index.sibling(index.row(), (int)CatalogueTreeModel::Column::Validation);
395 auto validationIndex = index.sibling(index.row(), (int)CatalogueTreeModel::Column::Validation);
392 if (value) {
396 if (value) {
393 if (!hasChanges(validationIndex, sideBarWidget->ui->treeView)) {
397 if (!hasChanges(validationIndex, sideBarWidget->ui->treeView)) {
394 auto widget = CatalogueExplorerHelper::buildValidationWidget(
398 auto widget = CatalogueExplorerHelper::buildValidationWidget(
395 sideBarWidget->ui->treeView,
399 sideBarWidget->ui->treeView,
396 [this, validationIndex, sideBarWidget, catalogue]() {
400 [this, validationIndex, sideBarWidget, catalogue]() {
397 if (catalogue) {
401 if (catalogue) {
398 sqpApp->catalogueController().saveCatalogue(catalogue);
402 sqpApp->catalogueController().saveCatalogue(catalogue);
399 emit sideBarWidget->catalogueSaved(catalogue);
403 emit sideBarWidget->catalogueSaved(catalogue);
400 }
404 }
401 setHasChanges(false, validationIndex, sideBarWidget);
405 setHasChanges(false, validationIndex, sideBarWidget);
402 },
406 },
403 [this, validationIndex, sideBarWidget, catalogue, item]() {
407 [this, validationIndex, sideBarWidget, catalogue, item]() {
404 if (catalogue) {
408 if (catalogue) {
405 bool removed;
409 bool removed;
406 sqpApp->catalogueController().discardCatalogue(catalogue, removed);
410 sqpApp->catalogueController().discardCatalogue(catalogue, removed);
407
411
408 if (removed) {
412 if (removed) {
409 m_TreeModel->removeChildItem(item,
413 m_TreeModel->removeChildItem(item,
410 m_TreeModel->indexOf(item->parent()));
414 m_TreeModel->indexOf(item->parent()));
411 }
415 }
412 else {
416 else {
413 m_TreeModel->refresh(m_TreeModel->indexOf(item));
417 m_TreeModel->refresh(m_TreeModel->indexOf(item));
414 setHasChanges(false, validationIndex, sideBarWidget);
418 setHasChanges(false, validationIndex, sideBarWidget);
415 }
419 }
416 sideBarWidget->emitSelection();
420 sideBarWidget->emitSelection();
417 }
421 }
418 });
422 });
419 sideBarWidget->ui->treeView->setIndexWidget(validationIndex, widget);
423 sideBarWidget->ui->treeView->setIndexWidget(validationIndex, widget);
420 sideBarWidget->ui->treeView->header()->resizeSection(
424 sideBarWidget->ui->treeView->header()->resizeSection(
421 (int)CatalogueTreeModel::Column::Validation, QHeaderView::ResizeToContents);
425 (int)CatalogueTreeModel::Column::Validation, QHeaderView::ResizeToContents);
422 }
426 }
423 }
427 }
424 else {
428 else {
425 // Note: the widget is destroyed
429 // Note: the widget is destroyed
426 sideBarWidget->ui->treeView->setIndexWidget(validationIndex, nullptr);
430 sideBarWidget->ui->treeView->setIndexWidget(validationIndex, nullptr);
427 }
431 }
428 }
432 }
429
433
430 bool CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::hasChanges(const QModelIndex &index,
434 bool CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::hasChanges(const QModelIndex &index,
431 QTreeView *treeView)
435 QTreeView *treeView)
432 {
436 {
433 auto validationIndex = index.sibling(index.row(), (int)CatalogueTreeModel::Column::Validation);
437 auto validationIndex = index.sibling(index.row(), (int)CatalogueTreeModel::Column::Validation);
434 return treeView->indexWidget(validationIndex) != nullptr;
438 return treeView->indexWidget(validationIndex) != nullptr;
435 }
439 }
436
440
437
441
438 void CatalogueSideBarWidget::keyPressEvent(QKeyEvent *event)
442 void CatalogueSideBarWidget::keyPressEvent(QKeyEvent *event)
439 {
443 {
440 switch (event->key()) {
444 switch (event->key()) {
441 case Qt::Key_Delete: {
445 case Qt::Key_Delete: {
442 ui->btnRemove->click();
446 ui->btnRemove->click();
443 }
447 }
444 default:
448 default:
445 break;
449 break;
446 }
450 }
447 }
451 }
@@ -1,126 +1,131
1 #include "Catalogue/CatalogueTreeItems/CatalogueTreeItem.h"
1 #include "Catalogue/CatalogueTreeItems/CatalogueTreeItem.h"
2 #include <Catalogue/CatalogueExplorerHelper.h>
2 #include <Catalogue/CatalogueExplorerHelper.h>
3
3
4 #include <Catalogue/CatalogueController.h>
4 #include <Catalogue/CatalogueController.h>
5 #include <Common/MimeTypesDef.h>
5 #include <Common/MimeTypesDef.h>
6 #include <QIcon>
6 #include <QIcon>
7 #include <QMimeData>
7 #include <QMimeData>
8 #include <SqpApplication.h>
8 #include <SqpApplication.h>
9
9
10 #include <memory>
10 #include <memory>
11
11
12 #include <DBCatalogue.h>
12 #include <DBCatalogue.h>
13
13
14 struct CatalogueTreeItem::CatalogueTreeItemPrivate {
14 struct CatalogueTreeItem::CatalogueTreeItemPrivate {
15
15
16 std::shared_ptr<DBCatalogue> m_Catalogue;
16 std::shared_ptr<DBCatalogue> m_Catalogue;
17 QIcon m_Icon;
17 QIcon m_Icon;
18
18
19 CatalogueTreeItemPrivate(std::shared_ptr<DBCatalogue> catalogue, const QIcon &icon)
19 CatalogueTreeItemPrivate(std::shared_ptr<DBCatalogue> catalogue, const QIcon &icon)
20 : m_Catalogue(catalogue), m_Icon(icon)
20 : m_Catalogue(catalogue), m_Icon(icon)
21 {
21 {
22 }
22 }
23 };
23 };
24
24
25
25
26 CatalogueTreeItem::CatalogueTreeItem(std::shared_ptr<DBCatalogue> catalogue, const QIcon &icon,
26 CatalogueTreeItem::CatalogueTreeItem(std::shared_ptr<DBCatalogue> catalogue, const QIcon &icon,
27 int type)
27 int type)
28 : CatalogueAbstractTreeItem(type),
28 : CatalogueAbstractTreeItem(type),
29 impl{spimpl::make_unique_impl<CatalogueTreeItemPrivate>(catalogue, icon)}
29 impl{spimpl::make_unique_impl<CatalogueTreeItemPrivate>(catalogue, icon)}
30 {
30 {
31 }
31 }
32
32
33 QVariant CatalogueTreeItem::data(int column, int role) const
33 QVariant CatalogueTreeItem::data(int column, int role) const
34 {
34 {
35 if (column == 0) {
35 if (column == 0) {
36 switch (role) {
36 switch (role) {
37 case Qt::EditRole: // fallthrough
37 case Qt::EditRole: // fallthrough
38 case Qt::DisplayRole:
38 case Qt::DisplayRole:
39 return impl->m_Catalogue->getName();
39 return impl->m_Catalogue->getName();
40 case Qt::DecorationRole:
40 case Qt::DecorationRole:
41 return impl->m_Icon;
41 return impl->m_Icon;
42 default:
42 default:
43 break;
43 break;
44 }
44 }
45 }
45 }
46
46
47 return QVariant();
47 return QVariant();
48 }
48 }
49
49
50 bool CatalogueTreeItem::setData(int column, int role, const QVariant &value)
50 bool CatalogueTreeItem::setData(int column, int role, const QVariant &value)
51 {
51 {
52 bool result = false;
52 bool result = false;
53
53
54 if (role == Qt::EditRole && column == 0) {
54 if (role == Qt::EditRole && column == 0) {
55 auto newName = value.toString();
55 auto newName = value.toString();
56 if (newName != impl->m_Catalogue->getName()) {
56 if (newName != impl->m_Catalogue->getName()) {
57 impl->m_Catalogue->setName(newName);
57 impl->m_Catalogue->setName(newName);
58 sqpApp->catalogueController().updateCatalogue(impl->m_Catalogue);
58 sqpApp->catalogueController().updateCatalogue(impl->m_Catalogue);
59 result = true;
59 result = true;
60 }
60 }
61 }
61 }
62
62
63 return result;
63 return result;
64 }
64 }
65
65
66 Qt::ItemFlags CatalogueTreeItem::flags(int column) const
66 Qt::ItemFlags CatalogueTreeItem::flags(int column) const
67 {
67 {
68 if (column == 0) {
68 if (column == 0) {
69 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable
69 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable
70 | Qt::ItemIsDropEnabled;
70 | Qt::ItemIsDropEnabled;
71 }
71 }
72 else {
72 else {
73 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
73 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
74 }
74 }
75 }
75 }
76
76
77 bool CatalogueTreeItem::canDropMimeData(const QMimeData *data, Qt::DropAction action)
77 bool CatalogueTreeItem::canDropMimeData(const QMimeData *data, Qt::DropAction action)
78 {
78 {
79 // Check that the event is not dropped on the same catalogue
79 // Check that the event is not dropped on the same catalogue
80 auto sourceCatalogues = sqpApp->catalogueController().cataloguesForMimeData(
80 auto sourceCatalogues = sqpApp->catalogueController().cataloguesForMimeData(
81 data->data(MIME_TYPE_SOURCE_CATALOGUE_LIST));
81 data->data(MIME_TYPE_SOURCE_CATALOGUE_LIST));
82 for (auto catalogue : sourceCatalogues) {
82 for (auto catalogue : sourceCatalogues) {
83 if (catalogue->getUniqId() == impl->m_Catalogue->getUniqId()) {
83 if (catalogue->getUniqId() == impl->m_Catalogue->getUniqId()) {
84 return false;
84 return false;
85 }
85 }
86 }
86 }
87
87
88 auto events = sqpApp->catalogueController().eventsForMimeData(data->data(MIME_TYPE_EVENT_LIST));
88 auto events = sqpApp->catalogueController().eventsForMimeData(data->data(MIME_TYPE_EVENT_LIST));
89 auto canDrop = data->hasFormat(MIME_TYPE_EVENT_LIST);
89 auto canDrop = data->hasFormat(MIME_TYPE_EVENT_LIST);
90
90
91 for (auto event : events) {
91 for (auto event : events) {
92 canDrop &= (event->getRepository() == impl->m_Catalogue->getRepository());
92 canDrop &= (event->getRepository() == impl->m_Catalogue->getRepository());
93 }
93 }
94
94
95 return canDrop;
95 return canDrop;
96 }
96 }
97
97
98 bool CatalogueTreeItem::dropMimeData(const QMimeData *data, Qt::DropAction action)
98 bool CatalogueTreeItem::dropMimeData(const QMimeData *data, Qt::DropAction action)
99 {
99 {
100 Q_ASSERT(canDropMimeData(data, action));
100 Q_ASSERT(canDropMimeData(data, action));
101 // Warning: Check that the events aren't already in the catalogue
101 // Warning: Check that the events aren't already in the catalogue
102 // No need to check check for the repository: inter-repository drop is forbidden in
102 // No need to check check for the repository: inter-repository drop is forbidden in
103 // canDropMimeData
103 // canDropMimeData
104
104
105 auto events = sqpApp->catalogueController().eventsForMimeData(data->data(MIME_TYPE_EVENT_LIST));
105 auto events = sqpApp->catalogueController().eventsForMimeData(data->data(MIME_TYPE_EVENT_LIST));
106 auto sourceCatalogues = sqpApp->catalogueController().cataloguesForMimeData(
106 auto sourceCatalogues = sqpApp->catalogueController().cataloguesForMimeData(
107 data->data(MIME_TYPE_SOURCE_CATALOGUE_LIST));
107 data->data(MIME_TYPE_SOURCE_CATALOGUE_LIST));
108
108
109 for (auto event : events) {
109 for (auto event : events) {
110
110
111 if (action == Qt::MoveAction) {
111 if (action == Qt::MoveAction) {
112 for (auto catalogue : sourceCatalogues) {
112 for (auto catalogue : sourceCatalogues) {
113 catalogue->removeEvent(event->getUniqId());
113 catalogue->removeEvent(event->getUniqId());
114 sqpApp->catalogueController().updateCatalogue(catalogue);
114 sqpApp->catalogueController().updateCatalogue(catalogue);
115 }
115 }
116 }
116 }
117
117
118 impl->m_Catalogue->addEvent(event->getUniqId());
118 impl->m_Catalogue->addEvent(event->getUniqId());
119 sqpApp->catalogueController().updateCatalogue(impl->m_Catalogue);
119 sqpApp->catalogueController().updateCatalogue(impl->m_Catalogue);
120 }
120 }
121 }
121 }
122
122
123 std::shared_ptr<DBCatalogue> CatalogueTreeItem::catalogue() const
123 std::shared_ptr<DBCatalogue> CatalogueTreeItem::catalogue() const
124 {
124 {
125 return impl->m_Catalogue;
125 return impl->m_Catalogue;
126 }
126 }
127
128 void CatalogueTreeItem::replaceCatalogue(const std::shared_ptr<DBCatalogue> &catalogue)
129 {
130 impl->m_Catalogue = catalogue;
131 }
General Comments 0
You need to be logged in to leave comments. Login now