##// END OF EJS Templates
Merge branch 'develop' of...
perrinel -
r1315:7185ea8182da merge
parent child
Show More
@@ -1,461 +1,462
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 class CatalogueController::CatalogueControllerPrivate {
31 31
32 32 public:
33 33 explicit CatalogueControllerPrivate(CatalogueController *parent) : m_Q{parent} {}
34 34
35 35 CatalogueDao m_CatalogueDao;
36 36
37 37 QStringList m_RepositoryList;
38 38 CatalogueController *m_Q;
39 39
40 40 QSet<QString> m_EventKeysWithChanges;
41 41
42 42 QString eventUniqueKey(const std::shared_ptr<DBEvent> &event) const;
43 43
44 44 void copyDBtoDB(const QString &dbFrom, const QString &dbTo);
45 45 QString toWorkRepository(QString repository);
46 46 QString toSyncRepository(QString repository);
47 47 void savAllDB();
48 48
49 49 void saveEvent(std::shared_ptr<DBEvent> event, bool persist = true);
50 50 void saveCatalogue(std::shared_ptr<DBCatalogue> catalogue, bool persist = true);
51 51 };
52 52
53 53 CatalogueController::CatalogueController(QObject *parent)
54 54 : impl{spimpl::make_unique_impl<CatalogueControllerPrivate>(this)}
55 55 {
56 56 qCDebug(LOG_CatalogueController()) << tr("CatalogueController construction")
57 57 << QThread::currentThread();
58 58 }
59 59
60 60 CatalogueController::~CatalogueController()
61 61 {
62 62 qCDebug(LOG_CatalogueController()) << tr("CatalogueController destruction")
63 63 << QThread::currentThread();
64 64 }
65 65
66 66 QStringList CatalogueController::getRepositories() const
67 67 {
68 68 return impl->m_RepositoryList;
69 69 }
70 70
71 71 void CatalogueController::addDB(const QString &dbPath)
72 72 {
73 73 QDir dbDir(dbPath);
74 74 if (dbDir.exists()) {
75 75 auto dirName = dbDir.dirName();
76 76
77 77 if (std::find(impl->m_RepositoryList.cbegin(), impl->m_RepositoryList.cend(), dirName)
78 78 != impl->m_RepositoryList.cend()) {
79 79 qCCritical(LOG_CatalogueController())
80 80 << tr("Impossible to addDB that is already loaded");
81 81 }
82 82
83 83 if (!impl->m_CatalogueDao.addDB(dbPath, dirName)) {
84 84 qCCritical(LOG_CatalogueController())
85 85 << tr("Impossible to addDB %1 from %2 ").arg(dirName, dbPath);
86 86 }
87 87 else {
88 88 impl->m_RepositoryList << dirName;
89 89 impl->copyDBtoDB(dirName, impl->toWorkRepository(dirName));
90 90 }
91 91 }
92 92 else {
93 93 qCCritical(LOG_CatalogueController()) << tr("Impossible to addDB that not exists: ")
94 94 << dbPath;
95 95 }
96 96 }
97 97
98 98 void CatalogueController::saveDB(const QString &destinationPath, const QString &repository)
99 99 {
100 100 if (!impl->m_CatalogueDao.saveDB(destinationPath, repository)) {
101 101 qCCritical(LOG_CatalogueController())
102 102 << tr("Impossible to saveDB %1 from %2 ").arg(repository, destinationPath);
103 103 }
104 104 }
105 105
106 106 std::list<std::shared_ptr<DBEvent> >
107 107 CatalogueController::retrieveEvents(const QString &repository) const
108 108 {
109 109 QString dbDireName = repository.isEmpty() ? REPOSITORY_DEFAULT : repository;
110 110
111 111 auto eventsShared = std::list<std::shared_ptr<DBEvent> >{};
112 112 auto events = impl->m_CatalogueDao.getEvents(impl->toWorkRepository(dbDireName));
113 113 for (auto event : events) {
114 114 eventsShared.push_back(std::make_shared<DBEvent>(event));
115 115 }
116 116 return eventsShared;
117 117 }
118 118
119 119 std::list<std::shared_ptr<DBEvent> > CatalogueController::retrieveAllEvents() const
120 120 {
121 121 auto eventsShared = std::list<std::shared_ptr<DBEvent> >{};
122 122 for (auto repository : impl->m_RepositoryList) {
123 123 eventsShared.splice(eventsShared.end(), retrieveEvents(repository));
124 124 }
125 125
126 126 return eventsShared;
127 127 }
128 128
129 129 std::list<std::shared_ptr<DBEvent> >
130 130 CatalogueController::retrieveEventsFromCatalogue(std::shared_ptr<DBCatalogue> catalogue) const
131 131 {
132 132 auto eventsShared = std::list<std::shared_ptr<DBEvent> >{};
133 133 auto events = impl->m_CatalogueDao.getCatalogueEvents(*catalogue);
134 134 for (auto event : events) {
135 135 eventsShared.push_back(std::make_shared<DBEvent>(event));
136 136 }
137 137 return eventsShared;
138 138 }
139 139
140 140 void CatalogueController::updateEvent(std::shared_ptr<DBEvent> event)
141 141 {
142 142 event->setRepository(impl->toWorkRepository(event->getRepository()));
143 143
144 144 auto uniqueId = impl->eventUniqueKey(event);
145 145 impl->m_EventKeysWithChanges.insert(uniqueId);
146 146
147 147 impl->m_CatalogueDao.updateEvent(*event);
148 148 }
149 149
150 150 void CatalogueController::updateEventProduct(std::shared_ptr<DBEventProduct> eventProduct)
151 151 {
152 152 impl->m_CatalogueDao.updateEventProduct(*eventProduct);
153 153 }
154 154
155 155 void CatalogueController::removeEvent(std::shared_ptr<DBEvent> event)
156 156 {
157 157 // Remove it from both repository and repository_work
158 158 event->setRepository(impl->toWorkRepository(event->getRepository()));
159 159 impl->m_CatalogueDao.removeEvent(*event);
160 160 event->setRepository(impl->toSyncRepository(event->getRepository()));
161 161 impl->m_CatalogueDao.removeEvent(*event);
162 162 impl->savAllDB();
163 163 }
164 164
165 165 void CatalogueController::addEvent(std::shared_ptr<DBEvent> event)
166 166 {
167 167 event->setRepository(impl->toWorkRepository(event->getRepository()));
168 168
169 169 auto eventTemp = *event;
170 170 impl->m_CatalogueDao.addEvent(eventTemp);
171 171
172 172 // Call update is necessary at the creation of add Event if it has some tags or some event
173 173 // products
174 174 if (!event->getEventProducts().empty() || !event->getTags().empty()) {
175 175
176 176 auto eventProductsTemp = eventTemp.getEventProducts();
177 177 auto eventProductTempUpdated = std::list<DBEventProduct>{};
178 178 for (auto eventProductTemp : eventProductsTemp) {
179 179 eventProductTemp.setEvent(eventTemp);
180 180 eventProductTempUpdated.push_back(eventProductTemp);
181 181 }
182 182 eventTemp.setEventProducts(eventProductTempUpdated);
183 183
184 184 impl->m_CatalogueDao.updateEvent(eventTemp);
185 185 }
186 186
187
188 187 // update event parameter
189 188 auto uniqIdPredicate = std::make_shared<ComparaisonPredicate>(
190 189 QString{"uniqId"}, event->getUniqId(), ComparaisonOperation::EQUALEQUAL);
191 190
192 191 auto workRepositoryPredicate = std::make_shared<ComparaisonPredicate>(
193 192 QString{"repository"}, impl->toWorkRepository(event->getRepository()),
194 193 ComparaisonOperation::EQUALEQUAL);
195 194
196 195 auto workPred = std::make_shared<CompoundPredicate>(CompoundOperation::AND);
197 196 workPred->AddRequestPredicate(uniqIdPredicate);
198 197 workPred->AddRequestPredicate(workRepositoryPredicate);
199 198
200
201 199 auto workEvent = impl->m_CatalogueDao.getEvent(workPred);
202 200 *event = workEvent;
201
202 auto uniqueId = impl->eventUniqueKey(event);
203 impl->m_EventKeysWithChanges.insert(uniqueId);
203 204 }
204 205
205 206 void CatalogueController::saveEvent(std::shared_ptr<DBEvent> event)
206 207 {
207 208 impl->saveEvent(event, true);
208 209 impl->m_EventKeysWithChanges.remove(impl->eventUniqueKey(event));
209 210 }
210 211
211 212 void CatalogueController::discardEvent(std::shared_ptr<DBEvent> event, bool &removed)
212 213 {
213 214 auto uniqIdPredicate = std::make_shared<ComparaisonPredicate>(
214 215 QString{"uniqId"}, event->getUniqId(), ComparaisonOperation::EQUALEQUAL);
215 216
216 217 auto syncRepositoryPredicate = std::make_shared<ComparaisonPredicate>(
217 218 QString{"repository"}, impl->toSyncRepository(event->getRepository()),
218 219 ComparaisonOperation::EQUALEQUAL);
219 220
220 221 auto syncPred = std::make_shared<CompoundPredicate>(CompoundOperation::AND);
221 222 syncPred->AddRequestPredicate(uniqIdPredicate);
222 223 syncPred->AddRequestPredicate(syncRepositoryPredicate);
223 224
224 225
225 226 auto workRepositoryPredicate = std::make_shared<ComparaisonPredicate>(
226 227 QString{"repository"}, impl->toWorkRepository(event->getRepository()),
227 228 ComparaisonOperation::EQUALEQUAL);
228 229
229 230 auto workPred = std::make_shared<CompoundPredicate>(CompoundOperation::AND);
230 231 workPred->AddRequestPredicate(uniqIdPredicate);
231 232 workPred->AddRequestPredicate(workRepositoryPredicate);
232 233
233 234
234 235 auto syncEvent = impl->m_CatalogueDao.getEvent(syncPred);
235 236 if (!syncEvent.getUniqId().isNull()) {
236 237 removed = false;
237 238 impl->m_CatalogueDao.copyEvent(syncEvent, impl->toWorkRepository(event->getRepository()),
238 239 true);
239 240
240 241 auto workEvent = impl->m_CatalogueDao.getEvent(workPred);
241 242 *event = workEvent;
242 243 impl->m_EventKeysWithChanges.remove(impl->eventUniqueKey(event));
243 244 }
244 245 else {
245 246 removed = true;
246 247 // Since the element wasn't in sync repository. Discard it means remove it
247 248 event->setRepository(impl->toWorkRepository(event->getRepository()));
248 249 impl->m_CatalogueDao.removeEvent(*event);
249 250 }
250 251 }
251 252
252 253 bool CatalogueController::eventHasChanges(std::shared_ptr<DBEvent> event) const
253 254 {
254 255 return impl->m_EventKeysWithChanges.contains(impl->eventUniqueKey(event));
255 256 }
256 257
257 258 std::list<std::shared_ptr<DBCatalogue> >
258 259 CatalogueController::retrieveCatalogues(const QString &repository) const
259 260 {
260 261 QString dbDireName = repository.isEmpty() ? REPOSITORY_DEFAULT : repository;
261 262
262 263 auto cataloguesShared = std::list<std::shared_ptr<DBCatalogue> >{};
263 264 auto catalogues = impl->m_CatalogueDao.getCatalogues(impl->toWorkRepository(dbDireName));
264 265 for (auto catalogue : catalogues) {
265 266 cataloguesShared.push_back(std::make_shared<DBCatalogue>(catalogue));
266 267 }
267 268 return cataloguesShared;
268 269 }
269 270
270 271 void CatalogueController::updateCatalogue(std::shared_ptr<DBCatalogue> catalogue)
271 272 {
272 273 catalogue->setRepository(impl->toWorkRepository(catalogue->getRepository()));
273 274
274 275 impl->m_CatalogueDao.updateCatalogue(*catalogue);
275 276 }
276 277
277 278 void CatalogueController::removeCatalogue(std::shared_ptr<DBCatalogue> catalogue)
278 279 {
279 280 // Remove it from both repository and repository_work
280 281 catalogue->setRepository(impl->toWorkRepository(catalogue->getRepository()));
281 282 impl->m_CatalogueDao.removeCatalogue(*catalogue);
282 283 catalogue->setRepository(impl->toSyncRepository(catalogue->getRepository()));
283 284 impl->m_CatalogueDao.removeCatalogue(*catalogue);
284 285 }
285 286
286 287 void CatalogueController::saveCatalogue(std::shared_ptr<DBCatalogue> catalogue)
287 288 {
288 289 impl->saveCatalogue(catalogue, true);
289 290 }
290 291
291 292 void CatalogueController::saveAll()
292 293 {
293 294 for (auto repository : impl->m_RepositoryList) {
294 295 // Save Event
295 296 auto events = this->retrieveEvents(repository);
296 297 for (auto event : events) {
297 298 impl->saveEvent(event, false);
298 299 }
299 300
300 301 // Save Catalogue
301 302 auto catalogues = this->retrieveCatalogues(repository);
302 303 for (auto catalogue : catalogues) {
303 304 impl->saveCatalogue(catalogue, false);
304 305 }
305 306 }
306 307
307 308 impl->savAllDB();
308 309 impl->m_EventKeysWithChanges.clear();
309 310 }
310 311
311 312 bool CatalogueController::hasChanges() const
312 313 {
313 314 return !impl->m_EventKeysWithChanges.isEmpty(); // TODO: catalogues
314 315 }
315 316
316 317 QByteArray
317 318 CatalogueController::mimeDataForEvents(const QVector<std::shared_ptr<DBEvent> > &events) const
318 319 {
319 320 auto encodedData = QByteArray{};
320 321
321 322 QMap<QString, QVariantList> idsPerRepository;
322 323 for (auto event : events) {
323 324 idsPerRepository[event->getRepository()] << event->getUniqId();
324 325 }
325 326
326 327 QDataStream stream{&encodedData, QIODevice::WriteOnly};
327 328 stream << idsPerRepository;
328 329
329 330 return encodedData;
330 331 }
331 332
332 333 QVector<std::shared_ptr<DBEvent> >
333 334 CatalogueController::eventsForMimeData(const QByteArray &mimeData) const
334 335 {
335 336 auto events = QVector<std::shared_ptr<DBEvent> >{};
336 337 QDataStream stream{mimeData};
337 338
338 339 QMap<QString, QVariantList> idsPerRepository;
339 340 stream >> idsPerRepository;
340 341
341 342 for (auto it = idsPerRepository.cbegin(); it != idsPerRepository.cend(); ++it) {
342 343 auto repository = it.key();
343 344 auto allRepositoryEvent = retrieveEvents(repository);
344 345 for (auto uuid : it.value()) {
345 346 for (auto repositoryEvent : allRepositoryEvent) {
346 347 if (uuid.toUuid() == repositoryEvent->getUniqId()) {
347 348 events << repositoryEvent;
348 349 }
349 350 }
350 351 }
351 352 }
352 353
353 354 return events;
354 355 }
355 356
356 357 void CatalogueController::initialize()
357 358 {
358 359 qCDebug(LOG_CatalogueController()) << tr("CatalogueController init")
359 360 << QThread::currentThread();
360 361
361 362 impl->m_CatalogueDao.initialize();
362 363 auto defaultRepositoryLocation
363 364 = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
364 365
365 366 QDir defaultRepositoryLocationDir;
366 367 if (defaultRepositoryLocationDir.mkpath(defaultRepositoryLocation)) {
367 368 defaultRepositoryLocationDir.cd(defaultRepositoryLocation);
368 369 auto defaultRepository = defaultRepositoryLocationDir.absoluteFilePath(REPOSITORY_DEFAULT);
369 370
370 371 qCInfo(LOG_CatalogueController()) << tr("Persistant data loading from: ")
371 372 << defaultRepository;
372 373
373 374 QDir dbDir(defaultRepository);
374 375 impl->m_RepositoryList << REPOSITORY_DEFAULT;
375 376 if (dbDir.exists()) {
376 377 auto dirName = dbDir.dirName();
377 378
378 379 if (impl->m_CatalogueDao.addDB(defaultRepository, dirName)) {
379 380 impl->copyDBtoDB(dirName, impl->toWorkRepository(dirName));
380 381 }
381 382 }
382 383 else {
383 384 qCInfo(LOG_CatalogueController()) << tr("Initialisation of Default repository detected")
384 385 << defaultRepository;
385 386 }
386 387 }
387 388 else {
388 389 qCWarning(LOG_CatalogueController())
389 390 << tr("Cannot load the persistent default repository from ")
390 391 << defaultRepositoryLocation;
391 392 }
392 393
393 394 qCDebug(LOG_CatalogueController()) << tr("CatalogueController init END");
394 395 }
395 396
396 397 QString CatalogueController::CatalogueControllerPrivate::eventUniqueKey(
397 398 const std::shared_ptr<DBEvent> &event) const
398 399 {
399 400 return event->getUniqId().toString().append(event->getRepository());
400 401 }
401 402
402 403 void CatalogueController::CatalogueControllerPrivate::copyDBtoDB(const QString &dbFrom,
403 404 const QString &dbTo)
404 405 {
405 406 // auto cataloguesShared = std::list<std::shared_ptr<DBCatalogue> >{};
406 407 auto catalogues = m_CatalogueDao.getCatalogues(dbFrom);
407 408 auto events = m_CatalogueDao.getEvents(dbFrom);
408 409 for (auto catalogue : catalogues) {
409 410 m_CatalogueDao.copyCatalogue(catalogue, dbTo, true);
410 411 }
411 412
412 413 for (auto event : events) {
413 414 m_CatalogueDao.copyEvent(event, dbTo, true);
414 415 }
415 416 }
416 417
417 418 QString CatalogueController::CatalogueControllerPrivate::toWorkRepository(QString repository)
418 419 {
419 420 auto syncRepository = toSyncRepository(repository);
420 421
421 422 return QString("%1%2").arg(syncRepository, REPOSITORY_WORK_SUFFIX);
422 423 }
423 424
424 425 QString CatalogueController::CatalogueControllerPrivate::toSyncRepository(QString repository)
425 426 {
426 427 auto syncRepository = repository;
427 428 if (repository.endsWith(REPOSITORY_WORK_SUFFIX)) {
428 429 syncRepository.remove(REPOSITORY_WORK_SUFFIX);
429 430 }
430 431 else if (repository.endsWith(REPOSITORY_TRASH_SUFFIX)) {
431 432 syncRepository.remove(REPOSITORY_TRASH_SUFFIX);
432 433 }
433 434 return syncRepository;
434 435 }
435 436
436 437 void CatalogueController::CatalogueControllerPrivate::savAllDB()
437 438 {
438 439 for (auto repository : m_RepositoryList) {
439 440 auto defaultRepositoryLocation
440 441 = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
441 442 m_CatalogueDao.saveDB(defaultRepositoryLocation, repository);
442 443 }
443 444 }
444 445
445 446 void CatalogueController::CatalogueControllerPrivate::saveEvent(std::shared_ptr<DBEvent> event,
446 447 bool persist)
447 448 {
448 449 m_CatalogueDao.copyEvent(*event, toSyncRepository(event->getRepository()), true);
449 450 if (persist) {
450 451 savAllDB();
451 452 }
452 453 }
453 454
454 455 void CatalogueController::CatalogueControllerPrivate::saveCatalogue(
455 456 std::shared_ptr<DBCatalogue> catalogue, bool persist)
456 457 {
457 458 m_CatalogueDao.copyCatalogue(*catalogue, toSyncRepository(catalogue->getRepository()), true);
458 459 if (persist) {
459 460 savAllDB();
460 461 }
461 462 }
@@ -1,136 +1,143
1 1 #include "Catalogue/CatalogueActionManager.h"
2 2
3 3 #include <Actions/ActionsGuiController.h>
4 4 #include <Catalogue/CatalogueController.h>
5 5 #include <DataSource/DataSourceItem.h>
6 6 #include <SqpApplication.h>
7 7 #include <Variable/Variable.h>
8 8 #include <Visualization/VisualizationGraphWidget.h>
9 9 #include <Visualization/VisualizationSelectionZoneItem.h>
10 10
11 11 #include <Catalogue/CatalogueEventsWidget.h>
12 12 #include <Catalogue/CatalogueExplorer.h>
13 13 #include <Catalogue/CatalogueSideBarWidget.h>
14 14 #include <Catalogue/CreateEventDialog.h>
15 15
16 16 #include <CatalogueDao.h>
17 17 #include <DBCatalogue.h>
18 18 #include <DBEvent.h>
19 19 #include <DBEventProduct.h>
20 20
21 21 #include <QBoxLayout>
22 22 #include <QComboBox>
23 23 #include <QDialog>
24 24 #include <QDialogButtonBox>
25 25 #include <QLineEdit>
26 26 #include <memory>
27 27
28 28 struct CatalogueActionManager::CatalogueActionManagerPrivate {
29 29
30 30 CatalogueExplorer *m_CatalogueExplorer = nullptr;
31 31
32 32 CatalogueActionManagerPrivate(CatalogueExplorer *catalogueExplorer)
33 33 : m_CatalogueExplorer(catalogueExplorer)
34 34 {
35 35 }
36 36
37 37 void createEventFromZones(const QString &eventName,
38 38 const QVector<VisualizationSelectionZoneItem *> &zones,
39 39 const std::shared_ptr<DBCatalogue> &catalogue = nullptr)
40 40 {
41 41 auto event = std::make_shared<DBEvent>();
42 42 event->setName(eventName);
43 43
44 44 std::list<DBEventProduct> productList;
45 45 for (auto zone : zones) {
46 46 auto graph = zone->parentGraphWidget();
47 47 for (auto var : graph->variables()) {
48 48 auto eventProduct = std::make_shared<DBEventProduct>();
49 49 eventProduct->setEvent(*event);
50 50
51 51 auto zoneRange = zone->range();
52 52 eventProduct->setTStart(zoneRange.m_TStart);
53 53 eventProduct->setTEnd(zoneRange.m_TEnd);
54 54
55 55 eventProduct->setProductId(
56 56 var->metadata().value(DataSourceItem::ID_DATA_KEY, "UnknownID").toString());
57 57
58 58 productList.push_back(*eventProduct);
59 59 }
60 60 }
61 61
62 62 event->setEventProducts(productList);
63 63
64 64 sqpApp->catalogueController().addEvent(event);
65 65
66 66
67 67 if (catalogue) {
68 68 // TODO
69 69 // catalogue->addEvent(event);
70 70 m_CatalogueExplorer->sideBarWidget().setCatalogueChanges(catalogue, true);
71 71 if (m_CatalogueExplorer->eventsWidget().displayedCatalogues().contains(catalogue)) {
72 72 m_CatalogueExplorer->eventsWidget().addEvent(event);
73 73 m_CatalogueExplorer->eventsWidget().setEventChanges(event, true);
74 74 }
75 75 }
76 76 else if (m_CatalogueExplorer->eventsWidget().isAllEventsDisplayed()) {
77 77 m_CatalogueExplorer->eventsWidget().addEvent(event);
78 78 m_CatalogueExplorer->eventsWidget().setEventChanges(event, true);
79 79 }
80 80 }
81 81 };
82 82
83 83 CatalogueActionManager::CatalogueActionManager(CatalogueExplorer *catalogueExplorer)
84 84 : impl{spimpl::make_unique_impl<CatalogueActionManagerPrivate>(catalogueExplorer)}
85 85 {
86 86 }
87 87
88 88 void CatalogueActionManager::installSelectionZoneActions()
89 89 {
90 90 auto &actionController = sqpApp->actionsGuiController();
91 91
92 92 auto createEventEnableFuntion = [](auto zones) {
93 QSet<VisualizationGraphWidget *> usedGraphs;
93
94 // Checks that all variables in the zones doesn't refer to the same product
95 QSet<QString> usedDatasource;
94 96 for (auto zone : zones) {
95 97 auto graph = zone->parentGraphWidget();
96 if (!usedGraphs.contains(graph)) {
97 usedGraphs.insert(graph);
98 }
99 else {
100 return false;
98 auto variables = graph->variables();
99
100 for (auto var : variables) {
101 auto datasourceId = var->metadata().value(DataSourceItem::ID_DATA_KEY).toString();
102 if (!usedDatasource.contains(datasourceId)) {
103 usedDatasource.insert(datasourceId);
104 }
105 else {
106 return false;
107 }
101 108 }
102 109 }
103 110
104 111 return true;
105 112 };
106 113
107 114 auto createEventAction = actionController.addSectionZoneAction(
108 115 {QObject::tr("Catalogues")}, QObject::tr("New Event..."), [this](auto zones) {
109 116 CreateEventDialog dialog(
110 117 impl->m_CatalogueExplorer->sideBarWidget().getCatalogues(REPOSITORY_DEFAULT));
111 118 dialog.hideCatalogueChoice();
112 119 if (dialog.exec() == QDialog::Accepted) {
113 120 impl->createEventFromZones(dialog.eventName(), zones);
114 121 }
115 122 });
116 123 createEventAction->setEnableFunction(createEventEnableFuntion);
117 124
118 125 auto createEventInCatalogueAction = actionController.addSectionZoneAction(
119 126 {QObject::tr("Catalogues")}, QObject::tr("New Event in Catalogue..."), [this](auto zones) {
120 127 CreateEventDialog dialog(
121 128 impl->m_CatalogueExplorer->sideBarWidget().getCatalogues(REPOSITORY_DEFAULT));
122 129 if (dialog.exec() == QDialog::Accepted) {
123 130 auto selectedCatalogue = dialog.selectedCatalogue();
124 131 if (!selectedCatalogue) {
125 132 selectedCatalogue = std::make_shared<DBCatalogue>();
126 133 selectedCatalogue->setName(dialog.catalogueName());
127 134 // sqpApp->catalogueController().addCatalogue(selectedCatalogue); TODO
128 135 impl->m_CatalogueExplorer->sideBarWidget().addCatalogue(selectedCatalogue,
129 136 REPOSITORY_DEFAULT);
130 137 }
131 138
132 139 impl->createEventFromZones(dialog.eventName(), zones, selectedCatalogue);
133 140 }
134 141 });
135 142 createEventInCatalogueAction->setEnableFunction(createEventEnableFuntion);
136 143 }
@@ -1,466 +1,470
1 1 #include "Catalogue/CatalogueEventsWidget.h"
2 2 #include "ui_CatalogueEventsWidget.h"
3 3
4 4 #include <Catalogue/CatalogueController.h>
5 5 #include <Catalogue/CatalogueEventsModel.h>
6 6 #include <Catalogue/CatalogueExplorerHelper.h>
7 7 #include <CatalogueDao.h>
8 8 #include <DBCatalogue.h>
9 9 #include <SqpApplication.h>
10 10 #include <Visualization/VisualizationTabWidget.h>
11 11 #include <Visualization/VisualizationWidget.h>
12 12 #include <Visualization/VisualizationZoneWidget.h>
13 13
14 14 #include <QDialog>
15 15 #include <QDialogButtonBox>
16 16 #include <QListWidget>
17 17 #include <QMessageBox>
18 18
19 19 Q_LOGGING_CATEGORY(LOG_CatalogueEventsWidget, "CatalogueEventsWidget")
20 20
21 21 /// Fixed size of the validation column
22 22 const auto VALIDATION_COLUMN_SIZE = 35;
23 23
24 24 struct CatalogueEventsWidget::CatalogueEventsWidgetPrivate {
25 25
26 26 CatalogueEventsModel *m_Model = nullptr;
27 27 QStringList m_ZonesForTimeMode;
28 28 QString m_ZoneForGraphMode;
29 29 QVector<std::shared_ptr<DBCatalogue> > m_DisplayedCatalogues;
30 bool m_AllEventDisplayed = false;
30 31
31 32 VisualizationWidget *m_VisualizationWidget = nullptr;
32 33
33 34 void setEvents(const QVector<std::shared_ptr<DBEvent> > &events, CatalogueEventsWidget *widget)
34 35 {
35 36 widget->ui->treeView->setSortingEnabled(false);
36 37 m_Model->setEvents(events);
37 38 widget->ui->treeView->setSortingEnabled(true);
38 39
39 40 for (auto event : events) {
40 41 if (sqpApp->catalogueController().eventHasChanges(event)) {
41 42 auto index = m_Model->indexOf(event);
42 43 widget->setEventChanges(event, true);
43 44 }
44 45 }
45 46 }
46 47
47 48 void addEvent(const std::shared_ptr<DBEvent> &event, QTreeView *treeView)
48 49 {
49 50 treeView->setSortingEnabled(false);
50 51 m_Model->addEvent(event);
51 52 treeView->setSortingEnabled(true);
52 53 }
53 54
54 55 void removeEvent(const std::shared_ptr<DBEvent> &event, QTreeView *treeView)
55 56 {
56 57 treeView->setSortingEnabled(false);
57 58 m_Model->removeEvent(event);
58 59 treeView->setSortingEnabled(true);
59 60 }
60 61
61 62 QStringList getAvailableVisualizationZoneList() const
62 63 {
63 64 if (m_VisualizationWidget) {
64 65 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
65 66 return tab->availableZoneWidgets();
66 67 }
67 68 }
68 69
69 70 return QStringList{};
70 71 }
71 72
72 73 QStringList selectZone(QWidget *parent, const QStringList &selectedZones,
73 74 bool allowMultiSelection, const QPoint &location)
74 75 {
75 76 auto availableZones = getAvailableVisualizationZoneList();
76 77 if (availableZones.isEmpty()) {
77 78 return QStringList{};
78 79 }
79 80
80 81 QDialog d(parent, Qt::Tool);
81 82 d.setWindowTitle("Choose a zone");
82 83 auto layout = new QVBoxLayout{&d};
83 84 layout->setContentsMargins(0, 0, 0, 0);
84 85 auto listWidget = new QListWidget{&d};
85 86 layout->addWidget(listWidget);
86 87
87 88 QSet<QListWidgetItem *> checkedItems;
88 89 for (auto zone : availableZones) {
89 90 auto item = new QListWidgetItem{zone};
90 91 item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
91 92 if (selectedZones.contains(zone)) {
92 93 item->setCheckState(Qt::Checked);
93 94 checkedItems << item;
94 95 }
95 96 else {
96 97 item->setCheckState(Qt::Unchecked);
97 98 }
98 99
99 100 listWidget->addItem(item);
100 101 }
101 102
102 103 auto buttonBox = new QDialogButtonBox{QDialogButtonBox::Ok, &d};
103 104 layout->addWidget(buttonBox);
104 105
105 106 QObject::connect(buttonBox, &QDialogButtonBox::accepted, &d, &QDialog::accept);
106 107 QObject::connect(buttonBox, &QDialogButtonBox::rejected, &d, &QDialog::reject);
107 108
108 109 QObject::connect(listWidget, &QListWidget::itemChanged,
109 110 [&checkedItems, allowMultiSelection, listWidget](auto item) {
110 111 if (item->checkState() == Qt::Checked) {
111 112 if (!allowMultiSelection) {
112 113 for (auto checkedItem : checkedItems) {
113 114 listWidget->blockSignals(true);
114 115 checkedItem->setCheckState(Qt::Unchecked);
115 116 listWidget->blockSignals(false);
116 117 }
117 118
118 119 checkedItems.clear();
119 120 }
120 121 checkedItems << item;
121 122 }
122 123 else {
123 124 checkedItems.remove(item);
124 125 }
125 126 });
126 127
127 128 QStringList result;
128 129
129 130 d.setMinimumWidth(120);
130 131 d.resize(d.minimumSizeHint());
131 132 d.move(location);
132 133 if (d.exec() == QDialog::Accepted) {
133 134 for (auto item : checkedItems) {
134 135 result += item->text();
135 136 }
136 137 }
137 138 else {
138 139 result = selectedZones;
139 140 }
140 141
141 142 return result;
142 143 }
143 144
144 145 void updateForTimeMode(QTreeView *treeView)
145 146 {
146 147 auto selectedRows = treeView->selectionModel()->selectedRows();
147 148
148 149 if (selectedRows.count() == 1) {
149 150 auto event = m_Model->getEvent(selectedRows.first());
150 151 if (event) {
151 152 if (m_VisualizationWidget) {
152 153 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
153 154
154 155 for (auto zoneName : m_ZonesForTimeMode) {
155 156 if (auto zone = tab->getZoneWithName(zoneName)) {
156 157 SqpRange eventRange;
157 158 eventRange.m_TStart = event->getTStart();
158 159 eventRange.m_TEnd = event->getTEnd();
159 160 zone->setZoneRange(eventRange);
160 161 }
161 162 }
162 163 }
163 164 else {
164 165 qCWarning(LOG_CatalogueEventsWidget())
165 166 << "updateTimeZone: no tab found in the visualization";
166 167 }
167 168 }
168 169 else {
169 170 qCWarning(LOG_CatalogueEventsWidget())
170 171 << "updateTimeZone: visualization widget not found";
171 172 }
172 173 }
173 174 }
174 175 else {
175 176 qCWarning(LOG_CatalogueEventsWidget())
176 177 << "updateTimeZone: not compatible with multiple events selected";
177 178 }
178 179 }
179 180
180 181 void updateForGraphMode(QTreeView *treeView)
181 182 {
182 183 auto selectedRows = treeView->selectionModel()->selectedRows();
183 184
184 185 if (selectedRows.count() == 1) {
185 186 auto event = m_Model->getEvent(selectedRows.first());
186 187 if (m_VisualizationWidget) {
187 188 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
188 189 if (auto zone = tab->getZoneWithName(m_ZoneForGraphMode)) {
189 190 // TODO
190 191 }
191 192 }
192 193 else {
193 194 qCWarning(LOG_CatalogueEventsWidget())
194 195 << "updateGraphMode: no tab found in the visualization";
195 196 }
196 197 }
197 198 else {
198 199 qCWarning(LOG_CatalogueEventsWidget())
199 200 << "updateGraphMode: visualization widget not found";
200 201 }
201 202 }
202 203 else {
203 204 qCWarning(LOG_CatalogueEventsWidget())
204 205 << "updateGraphMode: not compatible with multiple events selected";
205 206 }
206 207 }
207 208
208 209 void getSelectedItems(
209 210 QTreeView *treeView, QVector<std::shared_ptr<DBEvent> > &events,
210 211 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > &eventProducts)
211 212 {
212 213 for (auto rowIndex : treeView->selectionModel()->selectedRows()) {
213 214 auto itemType = m_Model->itemTypeOf(rowIndex);
214 215 if (itemType == CatalogueEventsModel::ItemType::Event) {
215 216 events << m_Model->getEvent(rowIndex);
216 217 }
217 218 else if (itemType == CatalogueEventsModel::ItemType::EventProduct) {
218 219 eventProducts << qMakePair(m_Model->getParentEvent(rowIndex),
219 220 m_Model->getEventProduct(rowIndex));
220 221 }
221 222 }
222 223 }
223 224 };
224 225
225 226 CatalogueEventsWidget::CatalogueEventsWidget(QWidget *parent)
226 227 : QWidget(parent),
227 228 ui(new Ui::CatalogueEventsWidget),
228 229 impl{spimpl::make_unique_impl<CatalogueEventsWidgetPrivate>()}
229 230 {
230 231 ui->setupUi(this);
231 232
232 233 impl->m_Model = new CatalogueEventsModel{this};
233 234 ui->treeView->setModel(impl->m_Model);
234 235
235 236 ui->treeView->setSortingEnabled(true);
236 237 ui->treeView->setDragDropMode(QAbstractItemView::DragDrop);
237 238 ui->treeView->setDragEnabled(true);
238 239
239 240 connect(ui->btnTime, &QToolButton::clicked, [this](auto checked) {
240 241 if (checked) {
241 242 ui->btnChart->setChecked(false);
242 243 impl->m_ZonesForTimeMode
243 244 = impl->selectZone(this, impl->m_ZonesForTimeMode, true,
244 245 this->mapToGlobal(ui->btnTime->frameGeometry().center()));
245 246
246 247 impl->updateForTimeMode(ui->treeView);
247 248 }
248 249 });
249 250
250 251 connect(ui->btnChart, &QToolButton::clicked, [this](auto checked) {
251 252 if (checked) {
252 253 ui->btnTime->setChecked(false);
253 254 impl->m_ZoneForGraphMode
254 255 = impl->selectZone(this, {impl->m_ZoneForGraphMode}, false,
255 256 this->mapToGlobal(ui->btnChart->frameGeometry().center()))
256 257 .value(0);
257 258
258 259 impl->updateForGraphMode(ui->treeView);
259 260 }
260 261 });
261 262
262 263 connect(ui->btnRemove, &QToolButton::clicked, [this]() {
263 264 QVector<std::shared_ptr<DBEvent> > events;
264 265 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
265 266 impl->getSelectedItems(ui->treeView, events, eventProducts);
266 267
267 268 if (!events.isEmpty() && eventProducts.isEmpty()) {
268 269
269 270 if (QMessageBox::warning(this, tr("Remove Event(s)"),
270 271 tr("The selected event(s) will be completly removed "
271 272 "from the repository!\nAre you sure you want to continue?"),
272 273 QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
273 274 == QMessageBox::Yes) {
274 275
275 276 for (auto event : events) {
276 277 sqpApp->catalogueController().removeEvent(event);
277 278 impl->removeEvent(event, ui->treeView);
278 279 }
279 280 }
280 281 }
281 282 });
282 283
283 284 connect(ui->treeView, &QTreeView::clicked, this, &CatalogueEventsWidget::emitSelection);
284 285 connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
285 286 &CatalogueEventsWidget::emitSelection);
286 287
287 288 ui->btnRemove->setEnabled(false); // Disabled by default when nothing is selected
288 289 connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, [this]() {
289 290 auto isNotMultiSelection = ui->treeView->selectionModel()->selectedRows().count() <= 1;
290 291 ui->btnChart->setEnabled(isNotMultiSelection);
291 292 ui->btnTime->setEnabled(isNotMultiSelection);
292 293
293 294 if (isNotMultiSelection && ui->btnTime->isChecked()) {
294 295 impl->updateForTimeMode(ui->treeView);
295 296 }
296 297 else if (isNotMultiSelection && ui->btnChart->isChecked()) {
297 298 impl->updateForGraphMode(ui->treeView);
298 299 }
299 300
300 301 QVector<std::shared_ptr<DBEvent> > events;
301 302 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
302 303 impl->getSelectedItems(ui->treeView, events, eventProducts);
303 304 ui->btnRemove->setEnabled(!events.isEmpty() && eventProducts.isEmpty());
304 305 });
305 306
306 307 ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
307 308 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Tags,
308 309 QHeaderView::Stretch);
309 310 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Validation,
310 311 QHeaderView::Fixed);
311 312 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Name,
312 313 QHeaderView::Interactive);
313 314 ui->treeView->header()->resizeSection((int)CatalogueEventsModel::Column::Validation,
314 315 VALIDATION_COLUMN_SIZE);
315 316 ui->treeView->header()->setSortIndicatorShown(true);
316 317
317 318 connect(impl->m_Model, &CatalogueEventsModel::modelSorted, [this]() {
318 319 auto allEvents = impl->m_Model->events();
319 320 for (auto event : allEvents) {
320 321 setEventChanges(event, sqpApp->catalogueController().eventHasChanges(event));
321 322 }
322 323 });
323 324
324 325 populateWithAllEvents();
325 326 }
326 327
327 328 CatalogueEventsWidget::~CatalogueEventsWidget()
328 329 {
329 330 delete ui;
330 331 }
331 332
332 333 void CatalogueEventsWidget::setVisualizationWidget(VisualizationWidget *visualization)
333 334 {
334 335 impl->m_VisualizationWidget = visualization;
335 336 }
336 337
337 338 void CatalogueEventsWidget::addEvent(const std::shared_ptr<DBEvent> &event)
338 339 {
339 340 impl->addEvent(event, ui->treeView);
340 341 }
341 342
342 343 void CatalogueEventsWidget::setEventChanges(const std::shared_ptr<DBEvent> &event, bool hasChanges)
343 344 {
344 345 impl->m_Model->refreshEvent(event);
345 346
346 347 auto eventIndex = impl->m_Model->indexOf(event);
347 348 auto validationIndex
348 349 = eventIndex.sibling(eventIndex.row(), (int)CatalogueEventsModel::Column::Validation);
349 350
350 351 if (validationIndex.isValid()) {
351 352 if (hasChanges) {
352 353 if (ui->treeView->indexWidget(validationIndex) == nullptr) {
353 354 auto widget = CatalogueExplorerHelper::buildValidationWidget(
354 355 ui->treeView,
355 356 [this, event]() {
356 357 sqpApp->catalogueController().saveEvent(event);
357 358 setEventChanges(event, false);
358 359 },
359 360 [this, event]() {
360 361 bool removed = false;
361 362 sqpApp->catalogueController().discardEvent(event, removed);
362 363 if (removed) {
363 364 impl->m_Model->removeEvent(event);
364 365 }
365 366 else {
366 367 setEventChanges(event, false);
367 368 impl->m_Model->refreshEvent(event, true);
368 369 }
369 370 emitSelection();
370 371 });
371 372 ui->treeView->setIndexWidget(validationIndex, widget);
372 373 }
373 374 }
374 375 else {
375 376 // Note: the widget is destroyed
376 377 ui->treeView->setIndexWidget(validationIndex, nullptr);
377 378 }
378 379 }
379 380 else {
380 381 qCWarning(LOG_CatalogueEventsWidget())
381 382 << "setEventChanges: the event is not displayed in the model.";
382 383 }
383 384 }
384 385
385 386 QVector<std::shared_ptr<DBCatalogue> > CatalogueEventsWidget::displayedCatalogues() const
386 387 {
387 388 return impl->m_DisplayedCatalogues;
388 389 }
389 390
390 391 bool CatalogueEventsWidget::isAllEventsDisplayed() const
391 392 {
392 return impl->m_DisplayedCatalogues.isEmpty() && !impl->m_Model->events().isEmpty();
393 return impl->m_AllEventDisplayed;
393 394 }
394 395
395 396 bool CatalogueEventsWidget::isEventDisplayed(const std::shared_ptr<DBEvent> &event) const
396 397 {
397 398 return impl->m_Model->indexOf(event).isValid();
398 399 }
399 400
400 401 void CatalogueEventsWidget::populateWithCatalogues(
401 402 const QVector<std::shared_ptr<DBCatalogue> > &catalogues)
402 403 {
403 404 impl->m_DisplayedCatalogues = catalogues;
405 impl->m_AllEventDisplayed = false;
404 406
405 407 QSet<QUuid> eventIds;
406 408 QVector<std::shared_ptr<DBEvent> > events;
407 409
408 410 for (auto catalogue : catalogues) {
409 411 auto catalogueEvents = sqpApp->catalogueController().retrieveEventsFromCatalogue(catalogue);
410 412 for (auto event : catalogueEvents) {
411 413 if (!eventIds.contains(event->getUniqId())) {
412 414 events << event;
413 415 eventIds.insert(event->getUniqId());
414 416 }
415 417 }
416 418 }
417 419
418 420 impl->setEvents(events, this);
419 421 }
420 422
421 423 void CatalogueEventsWidget::populateWithAllEvents()
422 424 {
423 425 impl->m_DisplayedCatalogues.clear();
426 impl->m_AllEventDisplayed = true;
424 427
425 428 auto allEvents = sqpApp->catalogueController().retrieveAllEvents();
426 429
427 430 QVector<std::shared_ptr<DBEvent> > events;
428 431 for (auto event : allEvents) {
429 432 events << event;
430 433 }
431 434
432 435 impl->setEvents(events, this);
433 436 }
434 437
435 438 void CatalogueEventsWidget::clear()
436 439 {
437 440 impl->m_DisplayedCatalogues.clear();
441 impl->m_AllEventDisplayed = false;
438 442 impl->setEvents({}, this);
439 443 }
440 444
441 445 void CatalogueEventsWidget::refresh()
442 446 {
443 if (impl->m_DisplayedCatalogues.isEmpty()) {
447 if (isAllEventsDisplayed()) {
444 448 populateWithAllEvents();
445 449 }
446 else {
450 else if (!impl->m_DisplayedCatalogues.isEmpty()) {
447 451 populateWithCatalogues(impl->m_DisplayedCatalogues);
448 452 }
449 453 }
450 454
451 455 void CatalogueEventsWidget::emitSelection()
452 456 {
453 457 QVector<std::shared_ptr<DBEvent> > events;
454 458 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
455 459 impl->getSelectedItems(ui->treeView, events, eventProducts);
456 460
457 461 if (!events.isEmpty() && eventProducts.isEmpty()) {
458 462 emit eventsSelected(events);
459 463 }
460 464 else if (events.isEmpty() && !eventProducts.isEmpty()) {
461 465 emit eventProductsSelected(eventProducts);
462 466 }
463 467 else {
464 468 emit selectionCleared();
465 469 }
466 470 }
General Comments 0
You need to be logged in to leave comments. Login now