##// END OF EJS Templates
Save a statical catalogue now remove events save gui button
perrinel -
r1370:8af4c223fdc1
parent child
Show More
@@ -1,566 +1,574
1 1 #include <Catalogue/CatalogueController.h>
2 2
3 3 #include <Variable/Variable.h>
4 4
5 5 #include <CatalogueDao.h>
6 6
7 7 #include <ComparaisonPredicate.h>
8 8 #include <CompoundPredicate.h>
9 9 #include <DBCatalogue.h>
10 10 #include <DBEvent.h>
11 11 #include <DBEventProduct.h>
12 12 #include <DBTag.h>
13 13 #include <IRequestPredicate.h>
14 14
15 15 #include <QDataStream>
16 16 #include <QMutex>
17 17 #include <QThread>
18 18
19 19 #include <QDir>
20 20 #include <QStandardPaths>
21 21
22 22 Q_LOGGING_CATEGORY(LOG_CatalogueController, "CatalogueController")
23 23
24 24 namespace {
25 25
26 26 static QString REPOSITORY_WORK_SUFFIX = QString{"_work"};
27 27 static QString REPOSITORY_TRASH_SUFFIX = QString{"_trash"};
28 28 }
29 29
30 30 /**
31 31 * Possible types of an repository
32 32 */
33 33 enum class DBType { SYNC, WORK, TRASH };
34 34 class CatalogueController::CatalogueControllerPrivate {
35 35
36 36 public:
37 37 explicit CatalogueControllerPrivate(CatalogueController *parent) : m_Q{parent} {}
38 38
39 39 CatalogueDao m_CatalogueDao;
40 40
41 41 QStringList m_RepositoryList;
42 42 CatalogueController *m_Q;
43 43
44 44 QSet<QString> m_KeysWithChanges;
45 45
46 46 QString eventUniqueKey(const std::shared_ptr<DBEvent> &event) const;
47 47 QString catalogueUniqueKey(const std::shared_ptr<DBCatalogue> &catalogue) const;
48 48
49 49 void copyDBtoDB(const QString &dbFrom, const QString &dbTo);
50 50 QString toWorkRepository(QString repository);
51 51 QString toSyncRepository(QString repository);
52 52 void savAllDB();
53 53
54 54 void saveEvent(std::shared_ptr<DBEvent> event, bool persist = true);
55 55 void saveCatalogue(std::shared_ptr<DBCatalogue> catalogue, bool persist = true);
56 56
57 57 std::shared_ptr<IRequestPredicate> createFinder(const QUuid &uniqId, const QString &repository,
58 58 DBType type);
59 59 };
60 60
61 61 CatalogueController::CatalogueController(QObject *parent)
62 62 : impl{spimpl::make_unique_impl<CatalogueControllerPrivate>(this)}
63 63 {
64 64 qCDebug(LOG_CatalogueController()) << tr("CatalogueController construction")
65 65 << QThread::currentThread();
66 66 }
67 67
68 68 CatalogueController::~CatalogueController()
69 69 {
70 70 qCDebug(LOG_CatalogueController()) << tr("CatalogueController destruction")
71 71 << QThread::currentThread();
72 72 }
73 73
74 74 QStringList CatalogueController::getRepositories() const
75 75 {
76 76 return impl->m_RepositoryList;
77 77 }
78 78
79 79 void CatalogueController::addDB(const QString &dbPath)
80 80 {
81 81 QDir dbDir(dbPath);
82 82 if (dbDir.exists()) {
83 83 auto dirName = dbDir.dirName();
84 84
85 85 if (std::find(impl->m_RepositoryList.cbegin(), impl->m_RepositoryList.cend(), dirName)
86 86 != impl->m_RepositoryList.cend()) {
87 87 qCCritical(LOG_CatalogueController())
88 88 << tr("Impossible to addDB that is already loaded");
89 89 }
90 90
91 91 if (!impl->m_CatalogueDao.addDB(dbPath, dirName)) {
92 92 qCCritical(LOG_CatalogueController())
93 93 << tr("Impossible to addDB %1 from %2 ").arg(dirName, dbPath);
94 94 }
95 95 else {
96 96 impl->m_RepositoryList << dirName;
97 97 impl->copyDBtoDB(dirName, impl->toWorkRepository(dirName));
98 98 }
99 99 }
100 100 else {
101 101 qCCritical(LOG_CatalogueController()) << tr("Impossible to addDB that not exists: ")
102 102 << dbPath;
103 103 }
104 104 }
105 105
106 106 void CatalogueController::saveDB(const QString &destinationPath, const QString &repository)
107 107 {
108 108 if (!impl->m_CatalogueDao.saveDB(destinationPath, repository)) {
109 109 qCCritical(LOG_CatalogueController())
110 110 << tr("Impossible to saveDB %1 from %2 ").arg(repository, destinationPath);
111 111 }
112 112 }
113 113
114 114 std::list<std::shared_ptr<DBEvent> >
115 115 CatalogueController::retrieveEvents(const QString &repository) const
116 116 {
117 117 QString dbDireName = repository.isEmpty() ? REPOSITORY_DEFAULT : repository;
118 118
119 119 auto eventsShared = std::list<std::shared_ptr<DBEvent> >{};
120 120 auto events = impl->m_CatalogueDao.getEvents(impl->toWorkRepository(dbDireName));
121 121 for (auto event : events) {
122 122 eventsShared.push_back(std::make_shared<DBEvent>(event));
123 123 }
124 124 return eventsShared;
125 125 }
126 126
127 127 std::list<std::shared_ptr<DBEvent> > CatalogueController::retrieveAllEvents() const
128 128 {
129 129 auto eventsShared = std::list<std::shared_ptr<DBEvent> >{};
130 130 for (auto repository : impl->m_RepositoryList) {
131 131 eventsShared.splice(eventsShared.end(), retrieveEvents(repository));
132 132 }
133 133
134 134 return eventsShared;
135 135 }
136 136
137 137 std::list<std::shared_ptr<DBEvent> >
138 138 CatalogueController::retrieveEventsFromCatalogue(std::shared_ptr<DBCatalogue> catalogue) const
139 139 {
140 140 auto eventsShared = std::list<std::shared_ptr<DBEvent> >{};
141 141 auto events = impl->m_CatalogueDao.getCatalogueEvents(*catalogue);
142 142 for (auto event : events) {
143 143 eventsShared.push_back(std::make_shared<DBEvent>(event));
144 144 }
145 145 return eventsShared;
146 146 }
147 147
148 148 void CatalogueController::updateEvent(std::shared_ptr<DBEvent> event)
149 149 {
150 150 event->setRepository(impl->toWorkRepository(event->getRepository()));
151 151
152 152 auto uniqueId = impl->eventUniqueKey(event);
153 153 impl->m_KeysWithChanges.insert(uniqueId);
154 154
155 155 impl->m_CatalogueDao.updateEvent(*event);
156 156 }
157 157
158 158 void CatalogueController::updateEventProduct(std::shared_ptr<DBEventProduct> eventProduct)
159 159 {
160 160 impl->m_CatalogueDao.updateEventProduct(*eventProduct);
161 161 }
162 162
163 163 void CatalogueController::removeEvent(std::shared_ptr<DBEvent> event)
164 164 {
165 165 // Remove it from both repository and repository_work
166 166 event->setRepository(impl->toWorkRepository(event->getRepository()));
167 167 impl->m_CatalogueDao.removeEvent(*event);
168 168 event->setRepository(impl->toSyncRepository(event->getRepository()));
169 169 impl->m_CatalogueDao.removeEvent(*event);
170 170 impl->savAllDB();
171 171 }
172 172
173 173 void CatalogueController::addEvent(std::shared_ptr<DBEvent> event)
174 174 {
175 175 event->setRepository(impl->toWorkRepository(event->getRepository()));
176 176
177 177 auto eventTemp = *event;
178 178 impl->m_CatalogueDao.addEvent(eventTemp);
179 179
180 180 // Call update is necessary at the creation of add Event if it has some tags or some event
181 181 // products
182 182 if (!event->getEventProducts().empty() || !event->getTags().empty()) {
183 183
184 184 auto eventProductsTemp = eventTemp.getEventProducts();
185 185 auto eventProductTempUpdated = std::list<DBEventProduct>{};
186 186 for (auto eventProductTemp : eventProductsTemp) {
187 187 eventProductTemp.setEvent(eventTemp);
188 188 eventProductTempUpdated.push_back(eventProductTemp);
189 189 }
190 190 eventTemp.setEventProducts(eventProductTempUpdated);
191 191
192 192 impl->m_CatalogueDao.updateEvent(eventTemp);
193 193 }
194 194
195 195 auto workPred = impl->createFinder(event->getUniqId(), event->getRepository(), DBType::WORK);
196 196
197 197 auto workEvent = impl->m_CatalogueDao.getEvent(workPred);
198 198 *event = workEvent;
199 199
200 200
201 201 auto uniqueId = impl->eventUniqueKey(event);
202 202 impl->m_KeysWithChanges.insert(uniqueId);
203 203 }
204 204
205 205 void CatalogueController::saveEvent(std::shared_ptr<DBEvent> event)
206 206 {
207 207 impl->saveEvent(event, true);
208 208 impl->m_KeysWithChanges.remove(impl->eventUniqueKey(event));
209 209 }
210 210
211 211 void CatalogueController::discardEvent(std::shared_ptr<DBEvent> event, bool &removed)
212 212 {
213 213 auto syncPred = impl->createFinder(event->getUniqId(), event->getRepository(), DBType::SYNC);
214 214 auto workPred = impl->createFinder(event->getUniqId(), event->getRepository(), DBType::WORK);
215 215
216 216 auto syncEvent = impl->m_CatalogueDao.getEvent(syncPred);
217 217 if (!syncEvent.getUniqId().isNull()) {
218 218 removed = false;
219 219 impl->m_CatalogueDao.copyEvent(syncEvent, impl->toWorkRepository(event->getRepository()),
220 220 true);
221 221
222 222 auto workEvent = impl->m_CatalogueDao.getEvent(workPred);
223 223 *event = workEvent;
224 224 impl->m_KeysWithChanges.remove(impl->eventUniqueKey(event));
225 225 }
226 226 else {
227 227 removed = true;
228 228 // Since the element wasn't in sync repository. Discard it means remove it
229 229 event->setRepository(impl->toWorkRepository(event->getRepository()));
230 230 impl->m_CatalogueDao.removeEvent(*event);
231 231 }
232 232 }
233 233
234 234 bool CatalogueController::eventHasChanges(std::shared_ptr<DBEvent> event) const
235 235 {
236 236 return impl->m_KeysWithChanges.contains(impl->eventUniqueKey(event));
237 237 }
238 238
239 239 std::list<std::shared_ptr<DBCatalogue> >
240 240 CatalogueController::retrieveCatalogues(const QString &repository) const
241 241 {
242 242 QString dbDireName = repository.isEmpty() ? REPOSITORY_DEFAULT : repository;
243 243
244 244 auto cataloguesShared = std::list<std::shared_ptr<DBCatalogue> >{};
245 245 auto catalogues = impl->m_CatalogueDao.getCatalogues(impl->toWorkRepository(dbDireName));
246 246 for (auto catalogue : catalogues) {
247 247 cataloguesShared.push_back(std::make_shared<DBCatalogue>(catalogue));
248 248 }
249 249 return cataloguesShared;
250 250 }
251 251
252 252 void CatalogueController::addCatalogue(std::shared_ptr<DBCatalogue> catalogue)
253 253 {
254 254 catalogue->setRepository(impl->toWorkRepository(catalogue->getRepository()));
255 255
256 256 auto catalogueTemp = *catalogue;
257 257 impl->m_CatalogueDao.addCatalogue(catalogueTemp);
258 258
259 259 auto workPred
260 260 = impl->createFinder(catalogue->getUniqId(), catalogue->getRepository(), DBType::WORK);
261 261
262 262 auto workCatalogue = impl->m_CatalogueDao.getCatalogue(workPred);
263 263 *catalogue = workCatalogue;
264 264
265 265 auto uniqueId = impl->catalogueUniqueKey(catalogue);
266 266 impl->m_KeysWithChanges.insert(uniqueId);
267 267 }
268 268
269 269 void CatalogueController::updateCatalogue(std::shared_ptr<DBCatalogue> catalogue)
270 270 {
271 271 catalogue->setRepository(impl->toWorkRepository(catalogue->getRepository()));
272 272
273 273 auto uniqueId = impl->catalogueUniqueKey(catalogue);
274 274 impl->m_KeysWithChanges.insert(uniqueId);
275 275
276 276 impl->m_CatalogueDao.updateCatalogue(*catalogue);
277 277 }
278 278
279 279 void CatalogueController::removeCatalogue(std::shared_ptr<DBCatalogue> catalogue)
280 280 {
281 281 // Remove it from both repository and repository_work
282 282 catalogue->setRepository(impl->toWorkRepository(catalogue->getRepository()));
283 283 impl->m_CatalogueDao.removeCatalogue(*catalogue);
284 284 catalogue->setRepository(impl->toSyncRepository(catalogue->getRepository()));
285 285 impl->m_CatalogueDao.removeCatalogue(*catalogue);
286 286 impl->savAllDB();
287 287 }
288 288
289 289 void CatalogueController::saveCatalogue(std::shared_ptr<DBCatalogue> catalogue)
290 290 {
291 291 impl->saveCatalogue(catalogue, true);
292 292 impl->m_KeysWithChanges.remove(impl->catalogueUniqueKey(catalogue));
293
294 // remove key of events of the catalogue
295 if (catalogue->getType() == CatalogueType::STATIC) {
296 auto events = this->retrieveEventsFromCatalogue(catalogue);
297 for (auto event : events) {
298 impl->m_KeysWithChanges.remove(impl->eventUniqueKey(event));
299 }
300 }
293 301 }
294 302
295 303 void CatalogueController::discardCatalogue(std::shared_ptr<DBCatalogue> catalogue, bool &removed)
296 304 {
297 305 auto syncPred
298 306 = impl->createFinder(catalogue->getUniqId(), catalogue->getRepository(), DBType::SYNC);
299 307 auto workPred
300 308 = impl->createFinder(catalogue->getUniqId(), catalogue->getRepository(), DBType::WORK);
301 309
302 310 auto syncCatalogue = impl->m_CatalogueDao.getCatalogue(syncPred);
303 311 if (!syncCatalogue.getUniqId().isNull()) {
304 312 removed = false;
305 313 impl->m_CatalogueDao.copyCatalogue(
306 314 syncCatalogue, impl->toWorkRepository(catalogue->getRepository()), true);
307 315
308 316 auto workCatalogue = impl->m_CatalogueDao.getCatalogue(workPred);
309 317 *catalogue = workCatalogue;
310 318 impl->m_KeysWithChanges.remove(impl->catalogueUniqueKey(catalogue));
311 319 }
312 320 else {
313 321 removed = true;
314 322 // Since the element wasn't in sync repository. Discard it means remove it
315 323 catalogue->setRepository(impl->toWorkRepository(catalogue->getRepository()));
316 324 impl->m_CatalogueDao.removeCatalogue(*catalogue);
317 325 }
318 326 }
319 327
320 328 void CatalogueController::saveAll()
321 329 {
322 330 for (auto repository : impl->m_RepositoryList) {
323 331 // Save Event
324 332 auto events = this->retrieveEvents(repository);
325 333 for (auto event : events) {
326 334 impl->saveEvent(event, false);
327 335 }
328 336
329 337 // Save Catalogue
330 338 auto catalogues = this->retrieveCatalogues(repository);
331 339 for (auto catalogue : catalogues) {
332 340 impl->saveCatalogue(catalogue, false);
333 341 }
334 342 }
335 343
336 344 impl->savAllDB();
337 345 impl->m_KeysWithChanges.clear();
338 346 }
339 347
340 348 bool CatalogueController::hasChanges() const
341 349 {
342 350 return !impl->m_KeysWithChanges.isEmpty();
343 351 }
344 352
345 353 QByteArray
346 354 CatalogueController::mimeDataForEvents(const QVector<std::shared_ptr<DBEvent> > &events) const
347 355 {
348 356 auto encodedData = QByteArray{};
349 357
350 358 QMap<QString, QVariantList> idsPerRepository;
351 359 for (auto event : events) {
352 360 idsPerRepository[event->getRepository()] << event->getUniqId();
353 361 }
354 362
355 363 QDataStream stream{&encodedData, QIODevice::WriteOnly};
356 364 stream << idsPerRepository;
357 365
358 366 return encodedData;
359 367 }
360 368
361 369 QVector<std::shared_ptr<DBEvent> >
362 370 CatalogueController::eventsForMimeData(const QByteArray &mimeData) const
363 371 {
364 372 auto events = QVector<std::shared_ptr<DBEvent> >{};
365 373 QDataStream stream{mimeData};
366 374
367 375 QMap<QString, QVariantList> idsPerRepository;
368 376 stream >> idsPerRepository;
369 377
370 378 for (auto it = idsPerRepository.cbegin(); it != idsPerRepository.cend(); ++it) {
371 379 auto repository = it.key();
372 380 auto allRepositoryEvent = retrieveEvents(repository);
373 381 for (auto uuid : it.value()) {
374 382 for (auto repositoryEvent : allRepositoryEvent) {
375 383 if (uuid.toUuid() == repositoryEvent->getUniqId()) {
376 384 events << repositoryEvent;
377 385 }
378 386 }
379 387 }
380 388 }
381 389
382 390 return events;
383 391 }
384 392
385 393 QByteArray CatalogueController::mimeDataForCatalogues(
386 394 const QVector<std::shared_ptr<DBCatalogue> > &catalogues) const
387 395 {
388 396 auto encodedData = QByteArray{};
389 397
390 398 QMap<QString, QVariantList> idsPerRepository;
391 399 for (auto catalogue : catalogues) {
392 400 idsPerRepository[catalogue->getRepository()] << catalogue->getUniqId();
393 401 }
394 402
395 403 QDataStream stream{&encodedData, QIODevice::WriteOnly};
396 404 stream << idsPerRepository;
397 405
398 406 return encodedData;
399 407 }
400 408
401 409 QVector<std::shared_ptr<DBCatalogue> >
402 410 CatalogueController::cataloguesForMimeData(const QByteArray &mimeData) const
403 411 {
404 412 auto catalogues = QVector<std::shared_ptr<DBCatalogue> >{};
405 413 QDataStream stream{mimeData};
406 414
407 415 QMap<QString, QVariantList> idsPerRepository;
408 416 stream >> idsPerRepository;
409 417
410 418 for (auto it = idsPerRepository.cbegin(); it != idsPerRepository.cend(); ++it) {
411 419 auto repository = it.key();
412 420 auto allRepositoryCatalogues = retrieveCatalogues(repository);
413 421 for (auto uuid : it.value()) {
414 422 for (auto repositoryCatalogues : allRepositoryCatalogues) {
415 423 if (uuid.toUuid() == repositoryCatalogues->getUniqId()) {
416 424 catalogues << repositoryCatalogues;
417 425 }
418 426 }
419 427 }
420 428 }
421 429
422 430 return catalogues;
423 431 }
424 432
425 433 void CatalogueController::initialize()
426 434 {
427 435 qCDebug(LOG_CatalogueController()) << tr("CatalogueController init")
428 436 << QThread::currentThread();
429 437
430 438 impl->m_CatalogueDao.initialize();
431 439 auto defaultRepositoryLocation
432 440 = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
433 441
434 442 QDir defaultRepositoryLocationDir;
435 443 if (defaultRepositoryLocationDir.mkpath(defaultRepositoryLocation)) {
436 444 defaultRepositoryLocationDir.cd(defaultRepositoryLocation);
437 445 auto defaultRepository = defaultRepositoryLocationDir.absoluteFilePath(REPOSITORY_DEFAULT);
438 446
439 447 qCInfo(LOG_CatalogueController()) << tr("Persistant data loading from: ")
440 448 << defaultRepository;
441 449
442 450 QDir dbDir(defaultRepository);
443 451 impl->m_RepositoryList << REPOSITORY_DEFAULT;
444 452 if (dbDir.exists()) {
445 453 auto dirName = dbDir.dirName();
446 454
447 455 if (impl->m_CatalogueDao.addDB(defaultRepository, dirName)) {
448 456 impl->copyDBtoDB(dirName, impl->toWorkRepository(dirName));
449 457 }
450 458 }
451 459 else {
452 460 qCInfo(LOG_CatalogueController()) << tr("Initialisation of Default repository detected")
453 461 << defaultRepository;
454 462 }
455 463 }
456 464 else {
457 465 qCWarning(LOG_CatalogueController())
458 466 << tr("Cannot load the persistent default repository from ")
459 467 << defaultRepositoryLocation;
460 468 }
461 469
462 470 qCDebug(LOG_CatalogueController()) << tr("CatalogueController init END");
463 471 }
464 472
465 473 QString CatalogueController::CatalogueControllerPrivate::eventUniqueKey(
466 474 const std::shared_ptr<DBEvent> &event) const
467 475 {
468 476 return event->getUniqId().toString().append(event->getRepository());
469 477 }
470 478
471 479 QString CatalogueController::CatalogueControllerPrivate::catalogueUniqueKey(
472 480 const std::shared_ptr<DBCatalogue> &catalogue) const
473 481 {
474 482 return catalogue->getUniqId().toString().append(catalogue->getRepository());
475 483 }
476 484
477 485 void CatalogueController::CatalogueControllerPrivate::copyDBtoDB(const QString &dbFrom,
478 486 const QString &dbTo)
479 487 {
480 488 // auto cataloguesShared = std::list<std::shared_ptr<DBCatalogue> >{};
481 489 auto catalogues = m_CatalogueDao.getCatalogues(dbFrom);
482 490 auto events = m_CatalogueDao.getEvents(dbFrom);
483 491 for (auto catalogue : catalogues) {
484 492 m_CatalogueDao.copyCatalogue(catalogue, dbTo, true);
485 493 }
486 494
487 495 for (auto event : events) {
488 496 m_CatalogueDao.copyEvent(event, dbTo, true);
489 497 }
490 498 }
491 499
492 500 QString CatalogueController::CatalogueControllerPrivate::toWorkRepository(QString repository)
493 501 {
494 502 auto syncRepository = toSyncRepository(repository);
495 503
496 504 return QString("%1%2").arg(syncRepository, REPOSITORY_WORK_SUFFIX);
497 505 }
498 506
499 507 QString CatalogueController::CatalogueControllerPrivate::toSyncRepository(QString repository)
500 508 {
501 509 auto syncRepository = repository;
502 510 if (repository.endsWith(REPOSITORY_WORK_SUFFIX)) {
503 511 syncRepository.remove(REPOSITORY_WORK_SUFFIX);
504 512 }
505 513 else if (repository.endsWith(REPOSITORY_TRASH_SUFFIX)) {
506 514 syncRepository.remove(REPOSITORY_TRASH_SUFFIX);
507 515 }
508 516 return syncRepository;
509 517 }
510 518
511 519 void CatalogueController::CatalogueControllerPrivate::savAllDB()
512 520 {
513 521 for (auto repository : m_RepositoryList) {
514 522 auto defaultRepositoryLocation
515 523 = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
516 524 m_CatalogueDao.saveDB(defaultRepositoryLocation, repository);
517 525 }
518 526 }
519 527
520 528 void CatalogueController::CatalogueControllerPrivate::saveEvent(std::shared_ptr<DBEvent> event,
521 529 bool persist)
522 530 {
523 531 m_CatalogueDao.copyEvent(*event, toSyncRepository(event->getRepository()), true);
524 532 if (persist) {
525 533 savAllDB();
526 534 }
527 535 }
528 536
529 537 void CatalogueController::CatalogueControllerPrivate::saveCatalogue(
530 538 std::shared_ptr<DBCatalogue> catalogue, bool persist)
531 539 {
532 540 m_CatalogueDao.copyCatalogue(*catalogue, toSyncRepository(catalogue->getRepository()), true);
533 541 if (persist) {
534 542 savAllDB();
535 543 }
536 544 }
537 545
538 546 std::shared_ptr<IRequestPredicate> CatalogueController::CatalogueControllerPrivate::createFinder(
539 547 const QUuid &uniqId, const QString &repository, DBType type)
540 548 {
541 549 // update catalogue parameter
542 550 auto uniqIdPredicate = std::make_shared<ComparaisonPredicate>(QString{"uniqId"}, uniqId,
543 551 ComparaisonOperation::EQUALEQUAL);
544 552
545 553 auto repositoryType = repository;
546 554 switch (type) {
547 555 case DBType::SYNC:
548 556 repositoryType = toSyncRepository(repositoryType);
549 557 break;
550 558 case DBType::WORK:
551 559 repositoryType = toWorkRepository(repositoryType);
552 560 break;
553 561 case DBType::TRASH:
554 562 default:
555 563 break;
556 564 }
557 565
558 566 auto repositoryPredicate = std::make_shared<ComparaisonPredicate>(
559 567 QString{"repository"}, repositoryType, ComparaisonOperation::EQUALEQUAL);
560 568
561 569 auto finderPred = std::make_shared<CompoundPredicate>(CompoundOperation::AND);
562 570 finderPred->AddRequestPredicate(uniqIdPredicate);
563 571 finderPred->AddRequestPredicate(repositoryPredicate);
564 572
565 573 return finderPred;
566 574 }
@@ -1,71 +1,72
1 1 #ifndef SCIQLOP_CATALOGUEEVENTSWIDGET_H
2 2 #define SCIQLOP_CATALOGUEEVENTSWIDGET_H
3 3
4 4 #include <Common/spimpl.h>
5 5 #include <QLoggingCategory>
6 6 #include <QWidget>
7 7
8 8 class DBCatalogue;
9 9 class DBEvent;
10 10 class DBEventProduct;
11 11 class VisualizationWidget;
12 12 class VisualizationSelectionZoneItem;
13 13
14 14 namespace Ui {
15 15 class CatalogueEventsWidget;
16 16 }
17 17
18 18 Q_DECLARE_LOGGING_CATEGORY(LOG_CatalogueEventsWidget)
19 19
20 20 class CatalogueEventsWidget : public QWidget {
21 21 Q_OBJECT
22 22
23 23 signals:
24 24 void eventsSelected(const QVector<std::shared_ptr<DBEvent> > &event);
25 25 void eventsRemoved(const QVector<std::shared_ptr<DBEvent> > &event);
26 26 void eventProductsSelected(
27 27 const QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > >
28 28 &eventproducts);
29 29 void selectionCleared();
30 30 void selectionZoneAdded(const std::shared_ptr<DBEvent> &event, const QString &productId,
31 31 VisualizationSelectionZoneItem *selectionZone);
32 32
33 33 void eventCataloguesModified(const QVector<std::shared_ptr<DBCatalogue> > &catalogues);
34 34
35 35 public:
36 36 explicit CatalogueEventsWidget(QWidget *parent = 0);
37 37 virtual ~CatalogueEventsWidget();
38 38
39 39 void setVisualizationWidget(VisualizationWidget *visualization);
40 40
41 41 void addEvent(const std::shared_ptr<DBEvent> &event);
42 42 void setEventChanges(const std::shared_ptr<DBEvent> &event, bool hasChanges);
43 void setEventsChanges(const std::shared_ptr<DBEvent> &event, bool hasChanges);
43 44
44 45 QVector<std::shared_ptr<DBCatalogue> > displayedCatalogues() const;
45 46 bool isAllEventsDisplayed() const;
46 47 bool isEventDisplayed(const std::shared_ptr<DBEvent> &event) const;
47 48
48 49 void refreshEvent(const std::shared_ptr<DBEvent> &event);
49 50
50 51 public slots:
51 52 void populateWithCatalogues(const QVector<std::shared_ptr<DBCatalogue> > &catalogues);
52 53 void populateWithAllEvents();
53 54 void clear();
54 55 void refresh();
55 56
56 57 // QWidget interface
57 58 protected:
58 59 void keyPressEvent(QKeyEvent *event);
59 60
60 61
61 62 private:
62 63 Ui::CatalogueEventsWidget *ui;
63 64
64 65 class CatalogueEventsWidgetPrivate;
65 66 spimpl::unique_impl_ptr<CatalogueEventsWidgetPrivate> impl;
66 67
67 68 private slots:
68 69 void emitSelection();
69 70 };
70 71
71 72 #endif // SCIQLOP_CATALOGUEEVENTSWIDGET_H
@@ -1,55 +1,56
1 1 #ifndef SCIQLOP_CATALOGUESIDEBARWIDGET_H
2 2 #define SCIQLOP_CATALOGUESIDEBARWIDGET_H
3 3
4 4 #include <Common/spimpl.h>
5 5 #include <QLoggingCategory>
6 6 #include <QTreeWidgetItem>
7 7 #include <QWidget>
8 8
9 9 class CatalogueAbstractTreeItem;
10 10 class DBCatalogue;
11 11
12 12 namespace Ui {
13 13 class CatalogueSideBarWidget;
14 14 }
15 15
16 16 Q_DECLARE_LOGGING_CATEGORY(LOG_CatalogueSideBarWidget)
17 17
18 18 class CatalogueSideBarWidget : public QWidget {
19 19 Q_OBJECT
20 20
21 21 signals:
22 22 void catalogueSelected(const QVector<std::shared_ptr<DBCatalogue> > &catalogues);
23 23 void databaseSelected(const QStringList &databases);
24 24 void allEventsSelected();
25 25 void trashSelected();
26 26 void selectionCleared();
27 void catalogueSaved(const std::shared_ptr<DBCatalogue> &catalogue);
27 28
28 29 public:
29 30 explicit CatalogueSideBarWidget(QWidget *parent = 0);
30 31 virtual ~CatalogueSideBarWidget();
31 32
32 33 CatalogueAbstractTreeItem *addCatalogue(const std::shared_ptr<DBCatalogue> &catalogue,
33 34 const QString &repository);
34 35 void setCatalogueChanges(const std::shared_ptr<DBCatalogue> &catalogue, bool hasChanges);
35 36
36 37 QVector<std::shared_ptr<DBCatalogue> > getCatalogues(const QString &repository) const;
37 38
38 39 // QWidget interface
39 40 protected:
40 41 void keyPressEvent(QKeyEvent *event);
41 42
42 43 private slots:
43 44 void emitSelection();
44 45
45 46 private:
46 47 Ui::CatalogueSideBarWidget *ui;
47 48
48 49 class CatalogueSideBarWidgetPrivate;
49 50 spimpl::unique_impl_ptr<CatalogueSideBarWidgetPrivate> impl;
50 51
51 52 private slots:
52 53 void onContextMenuRequested(const QPoint &pos);
53 54 };
54 55
55 56 #endif // SCIQLOP_CATALOGUESIDEBARWIDGET_H
@@ -1,200 +1,203
1 1 #include "Catalogue/CatalogueExplorer.h"
2 2 #include "ui_CatalogueExplorer.h"
3 3
4 4 #include <Catalogue/CatalogueActionManager.h>
5 5 #include <Catalogue/CatalogueController.h>
6 6 #include <SqpApplication.h>
7 7 #include <Visualization/VisualizationGraphWidget.h>
8 8 #include <Visualization/VisualizationSelectionZoneItem.h>
9 9 #include <Visualization/VisualizationWidget.h>
10 10
11 11 #include <DBCatalogue.h>
12 12 #include <DBEvent.h>
13 13 #include <DBEventProduct.h>
14 14
15 15 #include <unordered_map>
16 16
17 17 struct CatalogueExplorer::CatalogueExplorerPrivate {
18 18 CatalogueActionManager m_ActionManager;
19 19 std::unordered_map<std::shared_ptr<DBEvent>, QVector<VisualizationSelectionZoneItem *> >
20 20 m_SelectionZonesPerEvents;
21 21
22 22 QMetaObject::Connection m_Conn;
23 23
24 24 CatalogueExplorerPrivate(CatalogueExplorer *catalogueExplorer)
25 25 : m_ActionManager(catalogueExplorer)
26 26 {
27 27 }
28 28 };
29 29
30 30 CatalogueExplorer::CatalogueExplorer(QWidget *parent)
31 31 : QDialog(parent, Qt::Dialog | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint),
32 32 ui(new Ui::CatalogueExplorer),
33 33 impl{spimpl::make_unique_impl<CatalogueExplorerPrivate>(this)}
34 34 {
35 35 ui->setupUi(this);
36 36
37 37 impl->m_ActionManager.installSelectionZoneActions();
38 38
39 39 // Updates events and inspector when something is selected in the catalogue widget
40 40 connect(ui->catalogues, &CatalogueSideBarWidget::catalogueSelected, [this](auto catalogues) {
41 41 if (catalogues.count() == 1) {
42 42 ui->inspector->setCatalogue(catalogues.first());
43 43 }
44 44 else {
45 45 ui->inspector->showPage(CatalogueInspectorWidget::Page::Empty);
46 46 }
47 47
48 48 ui->events->populateWithCatalogues(catalogues);
49 49 });
50 50
51 51 connect(ui->catalogues, &CatalogueSideBarWidget::databaseSelected, [this](auto databases) {
52 52 ui->inspector->showPage(CatalogueInspectorWidget::Page::Empty);
53 53 });
54 54
55 55 connect(ui->catalogues, &CatalogueSideBarWidget::trashSelected, [this]() {
56 56 ui->inspector->showPage(CatalogueInspectorWidget::Page::Empty);
57 57 ui->events->clear();
58 58 });
59 59
60 60 connect(ui->catalogues, &CatalogueSideBarWidget::allEventsSelected, [this]() {
61 61 ui->inspector->showPage(CatalogueInspectorWidget::Page::Empty);
62 62 ui->events->populateWithAllEvents();
63 63 });
64 64
65 65 connect(ui->catalogues, &CatalogueSideBarWidget::databaseSelected, [this](auto databaseList) {
66 66 QVector<std::shared_ptr<DBCatalogue> > catalogueList;
67 67 for (auto database : databaseList) {
68 68 catalogueList.append(ui->catalogues->getCatalogues(database));
69 69 }
70 70 ui->events->populateWithCatalogues(catalogueList);
71 71 ui->inspector->showPage(CatalogueInspectorWidget::Page::Empty);
72 72 });
73 73
74 74 connect(ui->catalogues, &CatalogueSideBarWidget::selectionCleared, [this]() {
75 75 ui->inspector->showPage(CatalogueInspectorWidget::Page::Empty);
76 76 ui->events->clear();
77 77 });
78 78
79 connect(ui->catalogues, &CatalogueSideBarWidget::catalogueSaved, ui->events,
80 &CatalogueEventsWidget::refresh);
81
79 82 // Updates the inspectot when something is selected in the events
80 83 connect(ui->events, &CatalogueEventsWidget::eventsSelected, [this](auto events) {
81 84 if (events.count() == 1) {
82 85 ui->inspector->setEvent(events.first());
83 86 }
84 87 else {
85 88 ui->inspector->showPage(CatalogueInspectorWidget::Page::Empty);
86 89 }
87 90 });
88 91
89 92 connect(ui->events, &CatalogueEventsWidget::eventProductsSelected, [this](auto eventProducts) {
90 93 if (eventProducts.count() == 1) {
91 94 ui->inspector->setEventProduct(eventProducts.first().first,
92 95 eventProducts.first().second);
93 96 }
94 97 else {
95 98 ui->inspector->showPage(CatalogueInspectorWidget::Page::Empty);
96 99 }
97 100 });
98 101
99 102 connect(ui->events, &CatalogueEventsWidget::selectionCleared,
100 103 [this]() { ui->inspector->showPage(CatalogueInspectorWidget::Page::Empty); });
101 104
102 105 // Manage Selection Zones associated to events
103 106 connect(ui->events, &CatalogueEventsWidget::selectionZoneAdded,
104 107 [this](auto event, auto productId, auto zone) {
105 108 this->addSelectionZoneItem(event, productId, zone);
106 109 });
107 110
108 111 connect(ui->events, &CatalogueEventsWidget::eventsRemoved, [this](auto events) {
109 112 for (auto event : events) {
110 113 auto associatedSelectionZonesIt = impl->m_SelectionZonesPerEvents.find(event);
111 114 if (associatedSelectionZonesIt != impl->m_SelectionZonesPerEvents.cend()) {
112 115 for (auto selectionZone : associatedSelectionZonesIt->second) {
113 116 auto parentGraph = selectionZone->parentGraphWidget();
114 117 parentGraph->removeSelectionZone(selectionZone);
115 118 }
116 119
117 120 impl->m_SelectionZonesPerEvents.erase(event);
118 121 }
119 122 }
120 123 });
121 124
122 125 // Updates changes from the inspector
123 126 connect(ui->inspector, &CatalogueInspectorWidget::catalogueUpdated, [this](auto catalogue) {
124 127 sqpApp->catalogueController().updateCatalogue(catalogue);
125 128 ui->catalogues->setCatalogueChanges(catalogue, true);
126 129 });
127 130
128 131 connect(ui->inspector, &CatalogueInspectorWidget::eventUpdated, [this](auto event) {
129 132 sqpApp->catalogueController().updateEvent(event);
130 133 ui->events->setEventChanges(event, true);
131 134 });
132 135
133 136 connect(ui->inspector, &CatalogueInspectorWidget::eventProductUpdated,
134 137 [this](auto event, auto eventProduct) {
135 138 sqpApp->catalogueController().updateEventProduct(eventProduct);
136 139 ui->events->setEventChanges(event, true);
137 140 });
138 141
139 142 connect(ui->events, &CatalogueEventsWidget::eventCataloguesModified,
140 143 [this](const QVector<std::shared_ptr<DBCatalogue> > &catalogues) {
141 144 for (auto catalogue : catalogues) {
142 145 ui->catalogues->setCatalogueChanges(catalogue, true);
143 146 }
144 147 });
145 148 }
146 149
147 150 CatalogueExplorer::~CatalogueExplorer()
148 151 {
149 152 disconnect(impl->m_Conn);
150 153 delete ui;
151 154 }
152 155
153 156 void CatalogueExplorer::setVisualizationWidget(VisualizationWidget *visualization)
154 157 {
155 158 ui->events->setVisualizationWidget(visualization);
156 159 }
157 160
158 161 CatalogueEventsWidget &CatalogueExplorer::eventsWidget() const
159 162 {
160 163 return *ui->events;
161 164 }
162 165
163 166 CatalogueSideBarWidget &CatalogueExplorer::sideBarWidget() const
164 167 {
165 168 return *ui->catalogues;
166 169 }
167 170
168 171 void CatalogueExplorer::clearSelectionZones()
169 172 {
170 173 impl->m_SelectionZonesPerEvents.clear();
171 174 }
172 175
173 176 void CatalogueExplorer::addSelectionZoneItem(const std::shared_ptr<DBEvent> &event,
174 177 const QString &productId,
175 178 VisualizationSelectionZoneItem *selectionZone)
176 179 {
177 180 impl->m_SelectionZonesPerEvents[event] << selectionZone;
178 181 connect(selectionZone, &VisualizationSelectionZoneItem::rangeEdited,
179 182 [event, productId, this](auto range) {
180 183 auto productList = event->getEventProducts();
181 184 for (auto &product : productList) {
182 185 if (product.getProductId() == productId) {
183 186 product.setTStart(range.m_TStart);
184 187 product.setTEnd(range.m_TEnd);
185 188 }
186 189 }
187 190 event->setEventProducts(productList);
188 191 sqpApp->catalogueController().updateEvent(event);
189 192 ui->events->refreshEvent(event);
190 193 ui->events->setEventChanges(event, true);
191 194 ui->inspector->refresh();
192 195 });
193 196
194 197 impl->m_Conn = connect(selectionZone, &VisualizationSelectionZoneItem::destroyed,
195 198 [event, selectionZone, this]() {
196 199 if (!impl->m_SelectionZonesPerEvents.empty()) {
197 200 impl->m_SelectionZonesPerEvents[event].removeAll(selectionZone);
198 201 }
199 202 });
200 203 }
@@ -1,442 +1,443
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 179 }
180 180 }
181 181 });
182 182
183 183 connect(impl->m_TreeModel, &CatalogueTreeModel::itemRenamed, [this](auto index) {
184 184 auto selectedIndexes = ui->treeView->selectionModel()->selectedRows();
185 185 if (selectedIndexes.contains(index)) {
186 186 this->emitSelection();
187 187 }
188 188 impl->setHasChanges(true, index, this);
189 189 });
190 190
191 191 ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
192 192 connect(ui->treeView, &QTreeView::customContextMenuRequested, this,
193 193 &CatalogueSideBarWidget::onContextMenuRequested);
194 194 }
195 195
196 196 CatalogueSideBarWidget::~CatalogueSideBarWidget()
197 197 {
198 198 delete ui;
199 199 }
200 200
201 201 CatalogueAbstractTreeItem *
202 202 CatalogueSideBarWidget::addCatalogue(const std::shared_ptr<DBCatalogue> &catalogue,
203 203 const QString &repository)
204 204 {
205 205 auto repositoryItem = impl->getDatabaseItem(repository);
206 206 return impl->addCatalogueItem(catalogue, impl->m_TreeModel->indexOf(repositoryItem));
207 207 }
208 208
209 209 void CatalogueSideBarWidget::setCatalogueChanges(const std::shared_ptr<DBCatalogue> &catalogue,
210 210 bool hasChanges)
211 211 {
212 212 if (auto catalogueItem = impl->getCatalogueItem(catalogue)) {
213 213 auto index = impl->m_TreeModel->indexOf(catalogueItem);
214 214 impl->setHasChanges(hasChanges, index, this);
215 215 // catalogueItem->refresh();
216 216 }
217 217 }
218 218
219 219 QVector<std::shared_ptr<DBCatalogue> >
220 220 CatalogueSideBarWidget::getCatalogues(const QString &repository) const
221 221 {
222 222 QVector<std::shared_ptr<DBCatalogue> > result;
223 223 auto repositoryItem = impl->getDatabaseItem(repository);
224 224 for (auto child : repositoryItem->children()) {
225 225 if (child->type() == CATALOGUE_ITEM_TYPE) {
226 226 auto catalogueItem = static_cast<CatalogueTreeItem *>(child);
227 227 result << catalogueItem->catalogue();
228 228 }
229 229 else {
230 230 qCWarning(LOG_CatalogueSideBarWidget()) << "getCatalogues: invalid structure";
231 231 }
232 232 }
233 233
234 234 return result;
235 235 }
236 236
237 237 void CatalogueSideBarWidget::emitSelection()
238 238 {
239 239 auto selectionType = impl->selectionType(ui->treeView);
240 240
241 241 switch (selectionType) {
242 242 case CATALOGUE_ITEM_TYPE:
243 243 emit this->catalogueSelected(impl->selectedCatalogues(ui->treeView));
244 244 break;
245 245 case DATABASE_ITEM_TYPE:
246 246 emit this->databaseSelected(impl->selectedRepositories(ui->treeView));
247 247 break;
248 248 case ALL_EVENT_ITEM_TYPE:
249 249 emit this->allEventsSelected();
250 250 break;
251 251 case TRASH_ITEM_TYPE:
252 252 emit this->trashSelected();
253 253 break;
254 254 default:
255 255 emit this->selectionCleared();
256 256 break;
257 257 }
258 258 }
259 259
260 260 void CatalogueSideBarWidget::onContextMenuRequested(const QPoint &pos)
261 261 {
262 262 QMenu menu{this};
263 263
264 264 auto currentIndex = ui->treeView->currentIndex();
265 265 auto currentItem = impl->m_TreeModel->item(currentIndex);
266 266 if (!currentItem) {
267 267 return;
268 268 }
269 269
270 270 switch (currentItem->type()) {
271 271 case CATALOGUE_ITEM_TYPE:
272 272 menu.addAction("Rename", [this, currentIndex]() { ui->treeView->edit(currentIndex); });
273 273 break;
274 274 case DATABASE_ITEM_TYPE:
275 275 break;
276 276 case ALL_EVENT_ITEM_TYPE:
277 277 break;
278 278 case TRASH_ITEM_TYPE:
279 279 menu.addAction("Empty Trash", []() {
280 280 // TODO
281 281 });
282 282 break;
283 283 default:
284 284 break;
285 285 }
286 286
287 287 if (!menu.isEmpty()) {
288 288 menu.exec(ui->treeView->mapToGlobal(pos));
289 289 }
290 290 }
291 291
292 292 void CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::configureTreeWidget(QTreeView *treeView)
293 293 {
294 294 auto allEventsItem = new CatalogueTextTreeItem{QIcon{":/icones/allEvents.png"}, "All Events",
295 295 ALL_EVENT_ITEM_TYPE};
296 296 auto allEventIndex = m_TreeModel->addTopLevelItem(allEventsItem);
297 297 treeView->setCurrentIndex(allEventIndex);
298 298
299 299 auto trashItem
300 300 = new CatalogueTextTreeItem{QIcon{":/icones/trash.png"}, "Trash", TRASH_ITEM_TYPE};
301 301 m_TreeModel->addTopLevelItem(trashItem);
302 302
303 303 auto separator = new QFrame{treeView};
304 304 separator->setFrameShape(QFrame::HLine);
305 305 auto separatorItem
306 306 = new CatalogueTextTreeItem{QIcon{}, QString{}, CatalogueAbstractTreeItem::DEFAULT_TYPE};
307 307 separatorItem->setEnabled(false);
308 308 auto separatorIndex = m_TreeModel->addTopLevelItem(separatorItem);
309 309 treeView->setIndexWidget(separatorIndex, separator);
310 310
311 311 auto repositories = sqpApp->catalogueController().getRepositories();
312 312 for (auto dbname : repositories) {
313 313 auto dbIndex = addDatabaseItem(dbname);
314 314 auto catalogues = sqpApp->catalogueController().retrieveCatalogues(dbname);
315 315 for (auto catalogue : catalogues) {
316 316 addCatalogueItem(catalogue, dbIndex);
317 317 }
318 318 }
319 319
320 320 treeView->expandAll();
321 321 }
322 322
323 323 QModelIndex
324 324 CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::addDatabaseItem(const QString &name)
325 325 {
326 326 auto databaseItem
327 327 = new CatalogueTextTreeItem{QIcon{":/icones/database.png"}, {name}, DATABASE_ITEM_TYPE};
328 328 auto databaseIndex = m_TreeModel->addTopLevelItem(databaseItem);
329 329
330 330 return databaseIndex;
331 331 }
332 332
333 333 CatalogueAbstractTreeItem *
334 334 CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::getDatabaseItem(const QString &name)
335 335 {
336 336 for (auto item : m_TreeModel->topLevelItems()) {
337 337 if (item->type() == DATABASE_ITEM_TYPE && item->text() == name) {
338 338 return item;
339 339 }
340 340 }
341 341
342 342 return nullptr;
343 343 }
344 344
345 345 CatalogueAbstractTreeItem *CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::addCatalogueItem(
346 346 const std::shared_ptr<DBCatalogue> &catalogue, const QModelIndex &databaseIndex)
347 347 {
348 348 auto catalogueItem
349 349 = new CatalogueTreeItem{catalogue, QIcon{":/icones/catalogue.png"}, CATALOGUE_ITEM_TYPE};
350 350 m_TreeModel->addChildItem(catalogueItem, databaseIndex);
351 351
352 352 return catalogueItem;
353 353 }
354 354
355 355 CatalogueTreeItem *CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::getCatalogueItem(
356 356 const std::shared_ptr<DBCatalogue> &catalogue) const
357 357 {
358 358 for (auto item : m_TreeModel->topLevelItems()) {
359 359 if (item->type() == DATABASE_ITEM_TYPE) {
360 360 for (auto childItem : item->children()) {
361 361 if (childItem->type() == CATALOGUE_ITEM_TYPE) {
362 362 auto catalogueItem = static_cast<CatalogueTreeItem *>(childItem);
363 363 if (catalogueItem->catalogue()->getUniqId() == catalogue->getUniqId()) {
364 364 return catalogueItem;
365 365 }
366 366 }
367 367 else {
368 368 qCWarning(LOG_CatalogueSideBarWidget()) << "getCatalogueItem: Invalid tree "
369 369 "structure. A database item should "
370 370 "only contain catalogues.";
371 371 Q_ASSERT(false);
372 372 }
373 373 }
374 374 }
375 375 }
376 376
377 377 return nullptr;
378 378 }
379 379
380 380 void CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::setHasChanges(
381 381 bool value, const QModelIndex &index, CatalogueSideBarWidget *sideBarWidget)
382 382 {
383 383 std::shared_ptr<DBCatalogue> catalogue = nullptr;
384 384 auto item = m_TreeModel->item(index);
385 385 if (item && item->type() == CATALOGUE_ITEM_TYPE) {
386 386 catalogue = static_cast<CatalogueTreeItem *>(item)->catalogue();
387 387 }
388 388
389 389 auto validationIndex = index.sibling(index.row(), (int)CatalogueTreeModel::Column::Validation);
390 390 if (value) {
391 391 if (!hasChanges(validationIndex, sideBarWidget->ui->treeView)) {
392 392 auto widget = CatalogueExplorerHelper::buildValidationWidget(
393 393 sideBarWidget->ui->treeView,
394 394 [this, validationIndex, sideBarWidget, catalogue]() {
395 395 if (catalogue) {
396 396 sqpApp->catalogueController().saveCatalogue(catalogue);
397 emit sideBarWidget->catalogueSaved(catalogue);
397 398 }
398 399 setHasChanges(false, validationIndex, sideBarWidget);
399 400 },
400 401 [this, validationIndex, sideBarWidget, catalogue, item]() {
401 402 if (catalogue) {
402 403 bool removed;
403 404 sqpApp->catalogueController().discardCatalogue(catalogue, removed);
404 405
405 406 if (removed) {
406 407 m_TreeModel->removeChildItem(item,
407 408 m_TreeModel->indexOf(item->parent()));
408 409 }
409 410 else {
410 411 m_TreeModel->refresh(m_TreeModel->indexOf(item));
411 412 setHasChanges(false, validationIndex, sideBarWidget);
412 413 }
413 414 sideBarWidget->emitSelection();
414 415 }
415 416 });
416 417 sideBarWidget->ui->treeView->setIndexWidget(validationIndex, widget);
417 418 }
418 419 }
419 420 else {
420 421 // Note: the widget is destroyed
421 422 sideBarWidget->ui->treeView->setIndexWidget(validationIndex, nullptr);
422 423 }
423 424 }
424 425
425 426 bool CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::hasChanges(const QModelIndex &index,
426 427 QTreeView *treeView)
427 428 {
428 429 auto validationIndex = index.sibling(index.row(), (int)CatalogueTreeModel::Column::Validation);
429 430 return treeView->indexWidget(validationIndex) != nullptr;
430 431 }
431 432
432 433
433 434 void CatalogueSideBarWidget::keyPressEvent(QKeyEvent *event)
434 435 {
435 436 switch (event->key()) {
436 437 case Qt::Key_Delete: {
437 438 ui->btnRemove->click();
438 439 }
439 440 default:
440 441 break;
441 442 }
442 443 }
General Comments 0
You need to be logged in to leave comments. Login now