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