##// END OF EJS Templates
Add discard method for event
perrinel -
r1243:85d482a16060
parent child
Show More
@@ -1,82 +1,83
1 1 #ifndef SCIQLOP_CATALOGUECONTROLLER_H
2 2 #define SCIQLOP_CATALOGUECONTROLLER_H
3 3
4 4 #include "CoreGlobal.h"
5 5
6 6 #include <Data/SqpRange.h>
7 7
8 8 #include <QLoggingCategory>
9 9 #include <QObject>
10 10 #include <QUuid>
11 11
12 12 #include <Common/spimpl.h>
13 13
14 14 #include <memory>
15 15
16 16 class DBCatalogue;
17 17 class DBEvent;
18 18 class DBEventProduct;
19 19
20 20 Q_DECLARE_LOGGING_CATEGORY(LOG_CatalogueController)
21 21
22 22 class DataSourceItem;
23 23 class Variable;
24 24
25 25 /**
26 26 * @brief The CatalogueController class aims to handle catalogues and event using the CatalogueAPI
27 27 * library.
28 28 */
29 29 class SCIQLOP_CORE_EXPORT CatalogueController : public QObject {
30 30 Q_OBJECT
31 31 public:
32 32 explicit CatalogueController(QObject *parent = 0);
33 33 virtual ~CatalogueController();
34 34
35 35 // DB
36 36 QStringList getRepositories() const;
37 37 void addDB(const QString &dbPath);
38 38 void saveDB(const QString &destinationPath, const QString &repository);
39 39
40 40 // Event
41 41 /// retrieveEvents with empty repository retrieve them from the default repository
42 42 std::list<std::shared_ptr<DBEvent> > retrieveEvents(const QString &repository) const;
43 43 std::list<std::shared_ptr<DBEvent> > retrieveAllEvents() const;
44 44 std::list<std::shared_ptr<DBEvent> >
45 45 retrieveEventsFromCatalogue(std::shared_ptr<DBCatalogue> catalogue) const;
46 46 void addEvent(std::shared_ptr<DBEvent> event);
47 47 void updateEvent(std::shared_ptr<DBEvent> event);
48 48 void updateEventProduct(std::shared_ptr<DBEventProduct> eventProduct);
49 49 void removeEvent(std::shared_ptr<DBEvent> event);
50 50 // void trashEvent(std::shared_ptr<DBEvent> event);
51 // void restore(QUuid eventId);
51 // void restore(std::shared_ptr<DBEvent> event);
52 52 void saveEvent(std::shared_ptr<DBEvent> event);
53 void discardEvent(std::shared_ptr<DBEvent> event);
53 54 bool eventHasChanges(std::shared_ptr<DBEvent> event) const;
54 55
55 56 // Catalogue
56 57 // bool createCatalogue(const QString &name, QVector<QUuid> eventList);
57 58 /// retrieveEvents with empty repository retrieve them from the default repository
58 59 std::list<std::shared_ptr<DBCatalogue> > retrieveCatalogues(const QString &repository
59 60 = QString()) const;
60 61 void updateCatalogue(std::shared_ptr<DBCatalogue> catalogue);
61 62 void removeCatalogue(std::shared_ptr<DBCatalogue> catalogue);
62 63 void saveCatalogue(std::shared_ptr<DBCatalogue> catalogue);
63 64
64 65 void saveAll();
65 66 bool hasChanges() const;
66 67
67 68 /// Returns the MIME data associated to a list of variables
68 69 QByteArray mimeDataForEvents(const QVector<std::shared_ptr<DBEvent> > &events) const;
69 70
70 71 /// Returns the list of variables contained in a MIME data
71 72 QVector<std::shared_ptr<DBEvent> > eventsForMimeData(const QByteArray &mimeData) const;
72 73
73 74 public slots:
74 75 /// Manage init/end of the controller
75 76 void initialize();
76 77
77 78 private:
78 79 class CatalogueControllerPrivate;
79 80 spimpl::unique_impl_ptr<CatalogueControllerPrivate> impl;
80 81 };
81 82
82 83 #endif // SCIQLOP_CATALOGUECONTROLLER_H
@@ -1,389 +1,409
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 187
188 188 void CatalogueController::saveEvent(std::shared_ptr<DBEvent> event)
189 189 {
190 190 impl->saveEvent(event, true);
191 191 impl->m_EventKeysWithChanges.remove(impl->eventUniqueKey(event));
192 192 }
193 193
194 void CatalogueController::discardEvent(std::shared_ptr<DBEvent> event)
195 {
196 auto uniqIdPredicate = std::make_shared<ComparaisonPredicate>(
197 QString{"uniqId"}, event->getUniqId(), ComparaisonOperation::EQUALEQUAL);
198
199 auto repositoryPredicate = std::make_shared<ComparaisonPredicate>(
200 QString{"repository"}, impl->toSyncRepository(event->getRepository()),
201 ComparaisonOperation::EQUALEQUAL);
202
203 auto compCompoundPred = std::make_shared<CompoundPredicate>(CompoundOperation::AND);
204 compCompoundPred->AddRequestPredicate(uniqIdPredicate);
205 compCompoundPred->AddRequestPredicate(repositoryPredicate);
206
207
208 auto syncEvent = impl->m_CatalogueDao.getEvent(compCompoundPred);
209 impl->m_CatalogueDao.copyEvent(syncEvent, impl->toWorkRepository(event->getRepository()), true);
210 *event = syncEvent;
211 impl->m_EventKeysWithChanges.remove(impl->eventUniqueKey(event));
212 }
213
194 214 bool CatalogueController::eventHasChanges(std::shared_ptr<DBEvent> event) const
195 215 {
196 216 return impl->m_EventKeysWithChanges.contains(impl->eventUniqueKey(event));
197 217 }
198 218
199 219 std::list<std::shared_ptr<DBCatalogue> >
200 220 CatalogueController::retrieveCatalogues(const QString &repository) const
201 221 {
202 222 QString dbDireName = repository.isEmpty() ? REPOSITORY_DEFAULT : repository;
203 223
204 224 auto cataloguesShared = std::list<std::shared_ptr<DBCatalogue> >{};
205 225 auto catalogues = impl->m_CatalogueDao.getCatalogues(impl->toWorkRepository(dbDireName));
206 226 for (auto catalogue : catalogues) {
207 227 cataloguesShared.push_back(std::make_shared<DBCatalogue>(catalogue));
208 228 }
209 229 return cataloguesShared;
210 230 }
211 231
212 232 void CatalogueController::updateCatalogue(std::shared_ptr<DBCatalogue> catalogue)
213 233 {
214 234 catalogue->setRepository(impl->toWorkRepository(catalogue->getRepository()));
215 235
216 236 impl->m_CatalogueDao.updateCatalogue(*catalogue);
217 237 }
218 238
219 239 void CatalogueController::removeCatalogue(std::shared_ptr<DBCatalogue> catalogue)
220 240 {
221 241 // Remove it from both repository and repository_work
222 242 catalogue->setRepository(impl->toWorkRepository(catalogue->getRepository()));
223 243 impl->m_CatalogueDao.removeCatalogue(*catalogue);
224 244 catalogue->setRepository(impl->toSyncRepository(catalogue->getRepository()));
225 245 impl->m_CatalogueDao.removeCatalogue(*catalogue);
226 246 }
227 247
228 248 void CatalogueController::saveCatalogue(std::shared_ptr<DBCatalogue> catalogue)
229 249 {
230 250 impl->saveCatalogue(catalogue, true);
231 251 }
232 252
233 253 void CatalogueController::saveAll()
234 254 {
235 255 for (auto repository : impl->m_RepositoryList) {
236 256 // Save Event
237 257 auto events = this->retrieveEvents(repository);
238 258 for (auto event : events) {
239 259 impl->saveEvent(event, false);
240 260 }
241 261
242 262 // Save Catalogue
243 263 auto catalogues = this->retrieveCatalogues(repository);
244 264 for (auto catalogue : catalogues) {
245 265 impl->saveCatalogue(catalogue, false);
246 266 }
247 267 }
248 268
249 269 impl->savAllDB();
250 270 impl->m_EventKeysWithChanges.clear();
251 271 }
252 272
253 273 bool CatalogueController::hasChanges() const
254 274 {
255 275 return !impl->m_EventKeysWithChanges.isEmpty(); // TODO: catalogues
256 276 }
257 277
258 278 QByteArray
259 279 CatalogueController::mimeDataForEvents(const QVector<std::shared_ptr<DBEvent> > &events) const
260 280 {
261 281 auto encodedData = QByteArray{};
262 282
263 283 QMap<QString, QVariantList> idsPerRepository;
264 284 for (auto event : events) {
265 285 idsPerRepository[event->getRepository()] << event->getUniqId();
266 286 }
267 287
268 288 QDataStream stream{&encodedData, QIODevice::WriteOnly};
269 289 stream << idsPerRepository;
270 290
271 291 return encodedData;
272 292 }
273 293
274 294 QVector<std::shared_ptr<DBEvent> >
275 295 CatalogueController::eventsForMimeData(const QByteArray &mimeData) const
276 296 {
277 297 auto events = QVector<std::shared_ptr<DBEvent> >{};
278 298 QDataStream stream{mimeData};
279 299
280 300 QMap<QString, QVariantList> idsPerRepository;
281 301 stream >> idsPerRepository;
282 302
283 303 for (auto it = idsPerRepository.cbegin(); it != idsPerRepository.cend(); ++it) {
284 304 auto repository = it.key();
285 305 auto allRepositoryEvent = retrieveEvents(repository);
286 306 for (auto uuid : it.value()) {
287 307 for (auto repositoryEvent : allRepositoryEvent) {
288 308 if (uuid.toUuid() == repositoryEvent->getUniqId()) {
289 309 events << repositoryEvent;
290 310 }
291 311 }
292 312 }
293 313 }
294 314
295 315 return events;
296 316 }
297 317
298 318 void CatalogueController::initialize()
299 319 {
300 qCDebug(LOG_CatalogueController())
301 << tr("CatalogueController init") << QThread::currentThread();
320 qCDebug(LOG_CatalogueController()) << tr("CatalogueController init")
321 << QThread::currentThread();
302 322
303 323 impl->m_CatalogueDao.initialize();
304 324 auto defaultRepositoryLocation
305 325 = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
306 326
307 327 QDir defaultRepositoryLocationDir;
308 328 if (defaultRepositoryLocationDir.mkpath(defaultRepositoryLocation)) {
309 329 defaultRepositoryLocationDir.cd(defaultRepositoryLocation);
310 330 auto defaultRepository = defaultRepositoryLocationDir.absoluteFilePath(REPOSITORY_DEFAULT);
311 331 qCInfo(LOG_CatalogueController()) << tr("Persistant data loading from: ")
312 332 << defaultRepository;
313 333 this->addDB(defaultRepository);
314 334 }
315 335 else {
316 336 qCWarning(LOG_CatalogueController())
317 337 << tr("Cannot load the persistent default repository from ")
318 338 << defaultRepositoryLocation;
319 339 }
320 340
321 341 qCDebug(LOG_CatalogueController()) << tr("CatalogueController init END");
322 342 }
323 343
324 344 QString CatalogueController::CatalogueControllerPrivate::eventUniqueKey(
325 345 const std::shared_ptr<DBEvent> &event) const
326 346 {
327 347 return event->getUniqId().toString().append(event->getRepository());
328 348 }
329 349
330 350 void CatalogueController::CatalogueControllerPrivate::copyDBtoDB(const QString &dbFrom,
331 351 const QString &dbTo)
332 352 {
333 353 // auto cataloguesShared = std::list<std::shared_ptr<DBCatalogue> >{};
334 354 auto catalogues = m_CatalogueDao.getCatalogues(dbFrom);
335 355 auto events = m_CatalogueDao.getEvents(dbFrom);
336 356 for (auto catalogue : catalogues) {
337 357 m_CatalogueDao.copyCatalogue(catalogue, dbTo, true);
338 358 }
339 359
340 360 for (auto event : events) {
341 361 m_CatalogueDao.copyEvent(event, dbTo, true);
342 362 }
343 363 }
344 364
345 365 QString CatalogueController::CatalogueControllerPrivate::toWorkRepository(QString repository)
346 366 {
347 367 auto syncRepository = toSyncRepository(repository);
348 368
349 369 return QString("%1%2").arg(syncRepository, REPOSITORY_WORK_SUFFIX);
350 370 }
351 371
352 372 QString CatalogueController::CatalogueControllerPrivate::toSyncRepository(QString repository)
353 373 {
354 374 auto syncRepository = repository;
355 375 if (repository.endsWith(REPOSITORY_WORK_SUFFIX)) {
356 376 syncRepository.remove(REPOSITORY_WORK_SUFFIX);
357 377 }
358 378 else if (repository.endsWith(REPOSITORY_TRASH_SUFFIX)) {
359 379 syncRepository.remove(REPOSITORY_TRASH_SUFFIX);
360 380 }
361 381 return syncRepository;
362 382 }
363 383
364 384 void CatalogueController::CatalogueControllerPrivate::savAllDB()
365 385 {
366 386 for (auto repository : m_RepositoryList) {
367 387 auto defaultRepositoryLocation
368 388 = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
369 389 m_CatalogueDao.saveDB(defaultRepositoryLocation, repository);
370 390 }
371 391 }
372 392
373 393 void CatalogueController::CatalogueControllerPrivate::saveEvent(std::shared_ptr<DBEvent> event,
374 394 bool persist)
375 395 {
376 396 m_CatalogueDao.copyEvent(*event, toSyncRepository(event->getRepository()), true);
377 397 if (persist) {
378 398 savAllDB();
379 399 }
380 400 }
381 401
382 402 void CatalogueController::CatalogueControllerPrivate::saveCatalogue(
383 403 std::shared_ptr<DBCatalogue> catalogue, bool persist)
384 404 {
385 405 m_CatalogueDao.copyCatalogue(*catalogue, toSyncRepository(catalogue->getRepository()), true);
386 406 if (persist) {
387 407 savAllDB();
388 408 }
389 409 }
@@ -1,453 +1,457
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 30
31 31 VisualizationWidget *m_VisualizationWidget = nullptr;
32 32
33 33 void setEvents(const QVector<std::shared_ptr<DBEvent> > &events, CatalogueEventsWidget *widget)
34 34 {
35 35 widget->ui->treeView->setSortingEnabled(false);
36 36 m_Model->setEvents(events);
37 37 widget->ui->treeView->setSortingEnabled(true);
38 38
39 39 for (auto event : events) {
40 40 if (sqpApp->catalogueController().eventHasChanges(event)) {
41 41 auto index = m_Model->indexOf(event);
42 42 widget->setEventChanges(event, true);
43 43 }
44 44 }
45 45 }
46 46
47 47 void addEvent(const std::shared_ptr<DBEvent> &event, QTreeView *treeView)
48 48 {
49 49 treeView->setSortingEnabled(false);
50 50 m_Model->addEvent(event);
51 51 treeView->setSortingEnabled(true);
52 52 }
53 53
54 54 void removeEvent(const std::shared_ptr<DBEvent> &event, QTreeView *treeView)
55 55 {
56 56 treeView->setSortingEnabled(false);
57 57 m_Model->removeEvent(event);
58 58 treeView->setSortingEnabled(true);
59 59 }
60 60
61 61 QStringList getAvailableVisualizationZoneList() const
62 62 {
63 63 if (m_VisualizationWidget) {
64 64 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
65 65 return tab->availableZoneWidgets();
66 66 }
67 67 }
68 68
69 69 return QStringList{};
70 70 }
71 71
72 72 QStringList selectZone(QWidget *parent, const QStringList &selectedZones,
73 73 bool allowMultiSelection, const QPoint &location)
74 74 {
75 75 auto availableZones = getAvailableVisualizationZoneList();
76 76 if (availableZones.isEmpty()) {
77 77 return QStringList{};
78 78 }
79 79
80 80 QDialog d(parent, Qt::Tool);
81 81 d.setWindowTitle("Choose a zone");
82 82 auto layout = new QVBoxLayout{&d};
83 83 layout->setContentsMargins(0, 0, 0, 0);
84 84 auto listWidget = new QListWidget{&d};
85 85 layout->addWidget(listWidget);
86 86
87 87 QSet<QListWidgetItem *> checkedItems;
88 88 for (auto zone : availableZones) {
89 89 auto item = new QListWidgetItem{zone};
90 90 item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
91 91 if (selectedZones.contains(zone)) {
92 92 item->setCheckState(Qt::Checked);
93 93 checkedItems << item;
94 94 }
95 95 else {
96 96 item->setCheckState(Qt::Unchecked);
97 97 }
98 98
99 99 listWidget->addItem(item);
100 100 }
101 101
102 102 auto buttonBox = new QDialogButtonBox{QDialogButtonBox::Ok, &d};
103 103 layout->addWidget(buttonBox);
104 104
105 105 QObject::connect(buttonBox, &QDialogButtonBox::accepted, &d, &QDialog::accept);
106 106 QObject::connect(buttonBox, &QDialogButtonBox::rejected, &d, &QDialog::reject);
107 107
108 108 QObject::connect(listWidget, &QListWidget::itemChanged,
109 109 [&checkedItems, allowMultiSelection, listWidget](auto item) {
110 110 if (item->checkState() == Qt::Checked) {
111 111 if (!allowMultiSelection) {
112 112 for (auto checkedItem : checkedItems) {
113 113 listWidget->blockSignals(true);
114 114 checkedItem->setCheckState(Qt::Unchecked);
115 115 listWidget->blockSignals(false);
116 116 }
117 117
118 118 checkedItems.clear();
119 119 }
120 120 checkedItems << item;
121 121 }
122 122 else {
123 123 checkedItems.remove(item);
124 124 }
125 125 });
126 126
127 127 QStringList result;
128 128
129 129 d.setMinimumWidth(120);
130 130 d.resize(d.minimumSizeHint());
131 131 d.move(location);
132 132 if (d.exec() == QDialog::Accepted) {
133 133 for (auto item : checkedItems) {
134 134 result += item->text();
135 135 }
136 136 }
137 137 else {
138 138 result = selectedZones;
139 139 }
140 140
141 141 return result;
142 142 }
143 143
144 144 void updateForTimeMode(QTreeView *treeView)
145 145 {
146 146 auto selectedRows = treeView->selectionModel()->selectedRows();
147 147
148 148 if (selectedRows.count() == 1) {
149 149 auto event = m_Model->getEvent(selectedRows.first());
150 150 if (event) {
151 151 if (m_VisualizationWidget) {
152 152 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
153 153
154 154 for (auto zoneName : m_ZonesForTimeMode) {
155 155 if (auto zone = tab->getZoneWithName(zoneName)) {
156 156 SqpRange eventRange;
157 157 eventRange.m_TStart = event->getTStart();
158 158 eventRange.m_TEnd = event->getTEnd();
159 159 zone->setZoneRange(eventRange);
160 160 }
161 161 }
162 162 }
163 163 else {
164 164 qCWarning(LOG_CatalogueEventsWidget())
165 165 << "updateTimeZone: no tab found in the visualization";
166 166 }
167 167 }
168 168 else {
169 169 qCWarning(LOG_CatalogueEventsWidget())
170 170 << "updateTimeZone: visualization widget not found";
171 171 }
172 172 }
173 173 }
174 174 else {
175 175 qCWarning(LOG_CatalogueEventsWidget())
176 176 << "updateTimeZone: not compatible with multiple events selected";
177 177 }
178 178 }
179 179
180 180 void updateForGraphMode(QTreeView *treeView)
181 181 {
182 182 auto selectedRows = treeView->selectionModel()->selectedRows();
183 183
184 184 if (selectedRows.count() == 1) {
185 185 auto event = m_Model->getEvent(selectedRows.first());
186 186 if (m_VisualizationWidget) {
187 187 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
188 188 if (auto zone = tab->getZoneWithName(m_ZoneForGraphMode)) {
189 189 // TODO
190 190 }
191 191 }
192 192 else {
193 193 qCWarning(LOG_CatalogueEventsWidget())
194 194 << "updateGraphMode: no tab found in the visualization";
195 195 }
196 196 }
197 197 else {
198 198 qCWarning(LOG_CatalogueEventsWidget())
199 199 << "updateGraphMode: visualization widget not found";
200 200 }
201 201 }
202 202 else {
203 203 qCWarning(LOG_CatalogueEventsWidget())
204 204 << "updateGraphMode: not compatible with multiple events selected";
205 205 }
206 206 }
207 207
208 208 void getSelectedItems(
209 209 QTreeView *treeView, QVector<std::shared_ptr<DBEvent> > &events,
210 210 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > &eventProducts)
211 211 {
212 212 for (auto rowIndex : treeView->selectionModel()->selectedRows()) {
213 213 auto itemType = m_Model->itemTypeOf(rowIndex);
214 214 if (itemType == CatalogueEventsModel::ItemType::Event) {
215 215 events << m_Model->getEvent(rowIndex);
216 216 }
217 217 else if (itemType == CatalogueEventsModel::ItemType::EventProduct) {
218 218 eventProducts << qMakePair(m_Model->getParentEvent(rowIndex),
219 219 m_Model->getEventProduct(rowIndex));
220 220 }
221 221 }
222 222 }
223 223 };
224 224
225 225 CatalogueEventsWidget::CatalogueEventsWidget(QWidget *parent)
226 226 : QWidget(parent),
227 227 ui(new Ui::CatalogueEventsWidget),
228 228 impl{spimpl::make_unique_impl<CatalogueEventsWidgetPrivate>()}
229 229 {
230 230 ui->setupUi(this);
231 231
232 232 impl->m_Model = new CatalogueEventsModel{this};
233 233 ui->treeView->setModel(impl->m_Model);
234 234
235 235 ui->treeView->setSortingEnabled(true);
236 236 ui->treeView->setDragDropMode(QAbstractItemView::DragDrop);
237 237 ui->treeView->setDragEnabled(true);
238 238
239 239 connect(ui->btnTime, &QToolButton::clicked, [this](auto checked) {
240 240 if (checked) {
241 241 ui->btnChart->setChecked(false);
242 242 impl->m_ZonesForTimeMode
243 243 = impl->selectZone(this, impl->m_ZonesForTimeMode, true,
244 244 this->mapToGlobal(ui->btnTime->frameGeometry().center()));
245 245
246 246 impl->updateForTimeMode(ui->treeView);
247 247 }
248 248 });
249 249
250 250 connect(ui->btnChart, &QToolButton::clicked, [this](auto checked) {
251 251 if (checked) {
252 252 ui->btnTime->setChecked(false);
253 253 impl->m_ZoneForGraphMode
254 254 = impl->selectZone(this, {impl->m_ZoneForGraphMode}, false,
255 255 this->mapToGlobal(ui->btnChart->frameGeometry().center()))
256 256 .value(0);
257 257
258 258 impl->updateForGraphMode(ui->treeView);
259 259 }
260 260 });
261 261
262 262 connect(ui->btnRemove, &QToolButton::clicked, [this]() {
263 263 QVector<std::shared_ptr<DBEvent> > events;
264 264 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
265 265 impl->getSelectedItems(ui->treeView, events, eventProducts);
266 266
267 267 if (!events.isEmpty() && eventProducts.isEmpty()) {
268 268
269 269 if (QMessageBox::warning(this, tr("Remove Event(s)"),
270 270 tr("The selected event(s) will be completly removed "
271 271 "from the repository!\nAre you sure you want to continue?"),
272 272 QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
273 273 == QMessageBox::Yes) {
274 274
275 275 for (auto event : events) {
276 276 sqpApp->catalogueController().removeEvent(event);
277 277 impl->removeEvent(event, ui->treeView);
278 278 }
279 279 }
280 280 }
281 281 });
282 282
283 283 auto emitSelection = [this]() {
284 284 QVector<std::shared_ptr<DBEvent> > events;
285 285 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
286 286 impl->getSelectedItems(ui->treeView, events, eventProducts);
287 287
288 288 if (!events.isEmpty() && eventProducts.isEmpty()) {
289 289 emit this->eventsSelected(events);
290 290 }
291 291 else if (events.isEmpty() && !eventProducts.isEmpty()) {
292 292 emit this->eventProductsSelected(eventProducts);
293 293 }
294 294 else {
295 295 emit this->selectionCleared();
296 296 }
297 297 };
298 298
299 299 connect(ui->treeView, &QTreeView::clicked, emitSelection);
300 300 connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, emitSelection);
301 301
302 302 ui->btnRemove->setEnabled(false); // Disabled by default when nothing is selected
303 303 connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, [this]() {
304 304 auto isNotMultiSelection = ui->treeView->selectionModel()->selectedRows().count() <= 1;
305 305 ui->btnChart->setEnabled(isNotMultiSelection);
306 306 ui->btnTime->setEnabled(isNotMultiSelection);
307 307
308 308 if (isNotMultiSelection && ui->btnTime->isChecked()) {
309 309 impl->updateForTimeMode(ui->treeView);
310 310 }
311 311 else if (isNotMultiSelection && ui->btnChart->isChecked()) {
312 312 impl->updateForGraphMode(ui->treeView);
313 313 }
314 314
315 315 QVector<std::shared_ptr<DBEvent> > events;
316 316 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
317 317 impl->getSelectedItems(ui->treeView, events, eventProducts);
318 318 ui->btnRemove->setEnabled(!events.isEmpty() && eventProducts.isEmpty());
319 319 });
320 320
321 321 ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
322 322 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Tags,
323 323 QHeaderView::Stretch);
324 324 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Validation,
325 325 QHeaderView::Fixed);
326 326 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Name,
327 327 QHeaderView::Interactive);
328 328 ui->treeView->header()->resizeSection((int)CatalogueEventsModel::Column::Validation,
329 329 VALIDATION_COLUMN_SIZE);
330 330 ui->treeView->header()->setSortIndicatorShown(true);
331 331
332 332 connect(impl->m_Model, &CatalogueEventsModel::modelSorted, [this]() {
333 333 auto allEvents = impl->m_Model->events();
334 334 for (auto event : allEvents) {
335 335 setEventChanges(event, sqpApp->catalogueController().eventHasChanges(event));
336 336 }
337 337 });
338 338
339 339 populateWithAllEvents();
340 340 }
341 341
342 342 CatalogueEventsWidget::~CatalogueEventsWidget()
343 343 {
344 344 delete ui;
345 345 }
346 346
347 347 void CatalogueEventsWidget::setVisualizationWidget(VisualizationWidget *visualization)
348 348 {
349 349 impl->m_VisualizationWidget = visualization;
350 350 }
351 351
352 352 void CatalogueEventsWidget::addEvent(const std::shared_ptr<DBEvent> &event)
353 353 {
354 354 impl->addEvent(event, ui->treeView);
355 355 }
356 356
357 357 void CatalogueEventsWidget::setEventChanges(const std::shared_ptr<DBEvent> &event, bool hasChanges)
358 358 {
359 359 impl->m_Model->refreshEvent(event);
360 360
361 361 auto eventIndex = impl->m_Model->indexOf(event);
362 362 auto validationIndex
363 363 = eventIndex.sibling(eventIndex.row(), (int)CatalogueEventsModel::Column::Validation);
364 364
365 365 if (validationIndex.isValid()) {
366 366 if (hasChanges) {
367 367 if (ui->treeView->indexWidget(validationIndex) == nullptr) {
368 368 auto widget = CatalogueExplorerHelper::buildValidationWidget(
369 369 ui->treeView,
370 370 [this, event]() {
371 371 sqpApp->catalogueController().saveEvent(event);
372 372 setEventChanges(event, false);
373 373 },
374 [this, event]() { setEventChanges(event, false); });
374 [this, event]() {
375 sqpApp->catalogueController().discardEvent(event);
376 setEventChanges(event, false);
377 impl->m_Model->refreshEvent(event);
378 });
375 379 ui->treeView->setIndexWidget(validationIndex, widget);
376 380 }
377 381 }
378 382 else {
379 383 // Note: the widget is destroyed
380 384 ui->treeView->setIndexWidget(validationIndex, nullptr);
381 385 }
382 386 }
383 387 else {
384 388 qCWarning(LOG_CatalogueEventsWidget())
385 389 << "setEventChanges: the event is not displayed in the model.";
386 390 }
387 391 }
388 392
389 393 QVector<std::shared_ptr<DBCatalogue> > CatalogueEventsWidget::displayedCatalogues() const
390 394 {
391 395 return impl->m_DisplayedCatalogues;
392 396 }
393 397
394 398 bool CatalogueEventsWidget::isAllEventsDisplayed() const
395 399 {
396 400 return impl->m_DisplayedCatalogues.isEmpty() && !impl->m_Model->events().isEmpty();
397 401 }
398 402
399 403 bool CatalogueEventsWidget::isEventDisplayed(const std::shared_ptr<DBEvent> &event) const
400 404 {
401 405 return impl->m_Model->indexOf(event).isValid();
402 406 }
403 407
404 408 void CatalogueEventsWidget::populateWithCatalogues(
405 409 const QVector<std::shared_ptr<DBCatalogue> > &catalogues)
406 410 {
407 411 impl->m_DisplayedCatalogues = catalogues;
408 412
409 413 QSet<QUuid> eventIds;
410 414 QVector<std::shared_ptr<DBEvent> > events;
411 415
412 416 for (auto catalogue : catalogues) {
413 417 auto catalogueEvents = sqpApp->catalogueController().retrieveEventsFromCatalogue(catalogue);
414 418 for (auto event : catalogueEvents) {
415 419 if (!eventIds.contains(event->getUniqId())) {
416 420 events << event;
417 421 eventIds.insert(event->getUniqId());
418 422 }
419 423 }
420 424 }
421 425
422 426 impl->setEvents(events, this);
423 427 }
424 428
425 429 void CatalogueEventsWidget::populateWithAllEvents()
426 430 {
427 431 impl->m_DisplayedCatalogues.clear();
428 432
429 433 auto allEvents = sqpApp->catalogueController().retrieveAllEvents();
430 434
431 435 QVector<std::shared_ptr<DBEvent> > events;
432 436 for (auto event : allEvents) {
433 437 events << event;
434 438 }
435 439
436 440 impl->setEvents(events, this);
437 441 }
438 442
439 443 void CatalogueEventsWidget::clear()
440 444 {
441 445 impl->m_DisplayedCatalogues.clear();
442 446 impl->setEvents({}, this);
443 447 }
444 448
445 449 void CatalogueEventsWidget::refresh()
446 450 {
447 451 if (impl->m_DisplayedCatalogues.isEmpty()) {
448 452 populateWithAllEvents();
449 453 }
450 454 else {
451 455 populateWithCatalogues(impl->m_DisplayedCatalogues);
452 456 }
453 457 }
@@ -1,339 +1,337
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 <ComparaisonPredicate.h>
12 12 #include <DBCatalogue.h>
13 13
14 14 #include <QMenu>
15 15
16 16 Q_LOGGING_CATEGORY(LOG_CatalogueSideBarWidget, "CatalogueSideBarWidget")
17 17
18 18
19 19 constexpr auto ALL_EVENT_ITEM_TYPE = CatalogueAbstractTreeItem::DEFAULT_TYPE + 1;
20 20 constexpr auto TRASH_ITEM_TYPE = CatalogueAbstractTreeItem::DEFAULT_TYPE + 2;
21 21 constexpr auto CATALOGUE_ITEM_TYPE = CatalogueAbstractTreeItem::DEFAULT_TYPE + 3;
22 22 constexpr auto DATABASE_ITEM_TYPE = CatalogueAbstractTreeItem::DEFAULT_TYPE + 4;
23 23
24 24
25 25 struct CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate {
26 26
27 27 CatalogueTreeModel *m_TreeModel = nullptr;
28 28
29 29 void configureTreeWidget(QTreeView *treeView);
30 30 QModelIndex addDatabaseItem(const QString &name);
31 31 CatalogueAbstractTreeItem *getDatabaseItem(const QString &name);
32 32 void addCatalogueItem(const std::shared_ptr<DBCatalogue> &catalogue,
33 33 const QModelIndex &databaseIndex);
34 34
35 35 CatalogueTreeItem *getCatalogueItem(const std::shared_ptr<DBCatalogue> &catalogue) const;
36 36 void setHasChanges(bool value, const QModelIndex &index, QTreeView *treeView);
37 37 bool hasChanges(const QModelIndex &index, QTreeView *treeView);
38 38
39 39 int selectionType(QTreeView *treeView) const
40 40 {
41 41 auto selectedItems = treeView->selectionModel()->selectedRows();
42 42 if (selectedItems.isEmpty()) {
43 43 return CatalogueAbstractTreeItem::DEFAULT_TYPE;
44 44 }
45 45 else {
46 46 auto firstIndex = selectedItems.first();
47 47 auto firstItem = m_TreeModel->item(firstIndex);
48 48 if (!firstItem) {
49 49 Q_ASSERT(false);
50 50 return CatalogueAbstractTreeItem::DEFAULT_TYPE;
51 51 }
52 52 auto selectionType = firstItem->type();
53 53
54 54 for (auto itemIndex : selectedItems) {
55 55 auto item = m_TreeModel->item(itemIndex);
56 56 if (!item || item->type() != selectionType) {
57 57 // Incoherent multi selection
58 58 selectionType = CatalogueAbstractTreeItem::DEFAULT_TYPE;
59 59 break;
60 60 }
61 61 }
62 62
63 63 return selectionType;
64 64 }
65 65 }
66 66
67 67 QVector<std::shared_ptr<DBCatalogue> > selectedCatalogues(QTreeView *treeView) const
68 68 {
69 69 QVector<std::shared_ptr<DBCatalogue> > catalogues;
70 70 auto selectedItems = treeView->selectionModel()->selectedRows();
71 71 for (auto itemIndex : selectedItems) {
72 72 auto item = m_TreeModel->item(itemIndex);
73 73 if (item && item->type() == CATALOGUE_ITEM_TYPE) {
74 74 catalogues.append(static_cast<CatalogueTreeItem *>(item)->catalogue());
75 75 }
76 76 }
77 77
78 78 return catalogues;
79 79 }
80 80
81 81 QStringList selectedRepositories(QTreeView *treeView) const
82 82 {
83 83 QStringList repositories;
84 84 auto selectedItems = treeView->selectionModel()->selectedRows();
85 85 for (auto itemIndex : selectedItems) {
86 86 auto item = m_TreeModel->item(itemIndex);
87 87 if (item && item->type() == DATABASE_ITEM_TYPE) {
88 88 repositories.append(item->text());
89 89 }
90 90 }
91 91
92 92 return repositories;
93 93 }
94 94 };
95 95
96 96 CatalogueSideBarWidget::CatalogueSideBarWidget(QWidget *parent)
97 97 : QWidget(parent),
98 98 ui(new Ui::CatalogueSideBarWidget),
99 99 impl{spimpl::make_unique_impl<CatalogueSideBarWidgetPrivate>()}
100 100 {
101 101 ui->setupUi(this);
102 102
103 103 impl->m_TreeModel = new CatalogueTreeModel(this);
104 104 ui->treeView->setModel(impl->m_TreeModel);
105 105
106 106 impl->configureTreeWidget(ui->treeView);
107 107
108 108 ui->treeView->header()->setStretchLastSection(false);
109 109 ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
110 110 ui->treeView->header()->setSectionResizeMode(0, QHeaderView::Stretch);
111 111
112 112 auto emitSelection = [this]() {
113 113
114 114 auto selectionType = impl->selectionType(ui->treeView);
115 115
116 116 switch (selectionType) {
117 117 case CATALOGUE_ITEM_TYPE:
118 118 emit this->catalogueSelected(impl->selectedCatalogues(ui->treeView));
119 119 break;
120 120 case DATABASE_ITEM_TYPE:
121 121 emit this->databaseSelected(impl->selectedRepositories(ui->treeView));
122 122 break;
123 123 case ALL_EVENT_ITEM_TYPE:
124 124 emit this->allEventsSelected();
125 125 break;
126 126 case TRASH_ITEM_TYPE:
127 127 emit this->trashSelected();
128 128 break;
129 129 default:
130 130 emit this->selectionCleared();
131 131 break;
132 132 }
133 133 };
134 134
135 135 connect(ui->treeView, &QTreeView::clicked, emitSelection);
136 136 connect(ui->treeView->selectionModel(), &QItemSelectionModel::currentChanged, emitSelection);
137 137 connect(impl->m_TreeModel, &CatalogueTreeModel::itemRenamed, [emitSelection, this](auto index) {
138 138 auto selectedIndexes = ui->treeView->selectionModel()->selectedRows();
139 139 if (selectedIndexes.contains(index)) {
140 140 emitSelection();
141 141 }
142 142
143 143 auto item = impl->m_TreeModel->item(index);
144 144 impl->setHasChanges(true, index, ui->treeView);
145 145 });
146 146
147 147 ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
148 148 connect(ui->treeView, &QTreeView::customContextMenuRequested, this,
149 149 &CatalogueSideBarWidget::onContextMenuRequested);
150 150 }
151 151
152 152 CatalogueSideBarWidget::~CatalogueSideBarWidget()
153 153 {
154 154 delete ui;
155 155 }
156 156
157 157 void CatalogueSideBarWidget::addCatalogue(const std::shared_ptr<DBCatalogue> &catalogue,
158 158 const QString &repository)
159 159 {
160 160 auto repositoryItem = impl->getDatabaseItem(repository);
161 161 impl->addCatalogueItem(catalogue, impl->m_TreeModel->indexOf(repositoryItem));
162 162 }
163 163
164 164 void CatalogueSideBarWidget::setCatalogueChanges(const std::shared_ptr<DBCatalogue> &catalogue,
165 165 bool hasChanges)
166 166 {
167 167 if (auto catalogueItem = impl->getCatalogueItem(catalogue)) {
168 168 auto index = impl->m_TreeModel->indexOf(catalogueItem);
169 169 impl->setHasChanges(hasChanges, index, ui->treeView);
170 170 // catalogueItem->refresh();
171 171 }
172 172 }
173 173
174 174 QVector<std::shared_ptr<DBCatalogue> >
175 175 CatalogueSideBarWidget::getCatalogues(const QString &repository) const
176 176 {
177 177 QVector<std::shared_ptr<DBCatalogue> > result;
178 178 auto repositoryItem = impl->getDatabaseItem(repository);
179 179 for (auto child : repositoryItem->children()) {
180 180 if (child->type() == CATALOGUE_ITEM_TYPE) {
181 181 auto catalogueItem = static_cast<CatalogueTreeItem *>(child);
182 182 result << catalogueItem->catalogue();
183 183 }
184 184 else {
185 185 qCWarning(LOG_CatalogueSideBarWidget()) << "getCatalogues: invalid structure";
186 186 }
187 187 }
188 188
189 189 return result;
190 190 }
191 191
192 192 void CatalogueSideBarWidget::onContextMenuRequested(const QPoint &pos)
193 193 {
194 194 QMenu menu{this};
195 195
196 196 auto currentIndex = ui->treeView->currentIndex();
197 197 auto currentItem = impl->m_TreeModel->item(currentIndex);
198 198 if (!currentItem) {
199 199 return;
200 200 }
201 201
202 202 switch (currentItem->type()) {
203 203 case CATALOGUE_ITEM_TYPE:
204 204 menu.addAction("Rename", [this, currentIndex]() { ui->treeView->edit(currentIndex); });
205 205 break;
206 206 case DATABASE_ITEM_TYPE:
207 207 break;
208 208 case ALL_EVENT_ITEM_TYPE:
209 209 break;
210 210 case TRASH_ITEM_TYPE:
211 211 menu.addAction("Empty Trash", []() {
212 212 // TODO
213 213 });
214 214 break;
215 215 default:
216 216 break;
217 217 }
218 218
219 219 if (!menu.isEmpty()) {
220 220 menu.exec(ui->treeView->mapToGlobal(pos));
221 221 }
222 222 }
223 223
224 224 void CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::configureTreeWidget(QTreeView *treeView)
225 225 {
226 226 auto allEventsItem = new CatalogueTextTreeItem{QIcon{":/icones/allEvents.png"}, "All Events",
227 227 ALL_EVENT_ITEM_TYPE};
228 228 auto allEventIndex = m_TreeModel->addTopLevelItem(allEventsItem);
229 229 treeView->setCurrentIndex(allEventIndex);
230 230
231 231 auto trashItem
232 232 = new CatalogueTextTreeItem{QIcon{":/icones/trash.png"}, "Trash", TRASH_ITEM_TYPE};
233 233 m_TreeModel->addTopLevelItem(trashItem);
234 234
235 235 auto separator = new QFrame{treeView};
236 236 separator->setFrameShape(QFrame::HLine);
237 237 auto separatorItem
238 238 = new CatalogueTextTreeItem{QIcon{}, QString{}, CatalogueAbstractTreeItem::DEFAULT_TYPE};
239 239 separatorItem->setEnabled(false);
240 240 auto separatorIndex = m_TreeModel->addTopLevelItem(separatorItem);
241 241 treeView->setIndexWidget(separatorIndex, separator);
242 242
243 243 auto repositories = sqpApp->catalogueController().getRepositories();
244 244 for (auto dbname : repositories) {
245 245 auto dbIndex = addDatabaseItem(dbname);
246 246 auto catalogues = sqpApp->catalogueController().retrieveCatalogues(dbname);
247 247 for (auto catalogue : catalogues) {
248 248 addCatalogueItem(catalogue, dbIndex);
249 249 }
250 250 }
251 251
252 252 treeView->expandAll();
253 253 }
254 254
255 255 QModelIndex
256 256 CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::addDatabaseItem(const QString &name)
257 257 {
258 258 auto databaseItem
259 259 = new CatalogueTextTreeItem{QIcon{":/icones/database.png"}, {name}, DATABASE_ITEM_TYPE};
260 260 auto databaseIndex = m_TreeModel->addTopLevelItem(databaseItem);
261 261
262 262 return databaseIndex;
263 263 }
264 264
265 265 CatalogueAbstractTreeItem *
266 266 CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::getDatabaseItem(const QString &name)
267 267 {
268 268 for (auto item : m_TreeModel->topLevelItems()) {
269 269 if (item->type() == DATABASE_ITEM_TYPE && item->text() == name) {
270 270 return item;
271 271 }
272 272 }
273 273
274 274 return nullptr;
275 275 }
276 276
277 277 void CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::addCatalogueItem(
278 278 const std::shared_ptr<DBCatalogue> &catalogue, const QModelIndex &databaseIndex)
279 279 {
280 280 auto catalogueItem
281 281 = new CatalogueTreeItem{catalogue, QIcon{":/icones/catalogue.png"}, CATALOGUE_ITEM_TYPE};
282 282 m_TreeModel->addChildItem(catalogueItem, databaseIndex);
283 283 }
284 284
285 285 CatalogueTreeItem *CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::getCatalogueItem(
286 286 const std::shared_ptr<DBCatalogue> &catalogue) const
287 287 {
288 288 for (auto item : m_TreeModel->topLevelItems()) {
289 289 if (item->type() == DATABASE_ITEM_TYPE) {
290 290 for (auto childItem : item->children()) {
291 291 if (childItem->type() == CATALOGUE_ITEM_TYPE) {
292 292 auto catalogueItem = static_cast<CatalogueTreeItem *>(childItem);
293 293 if (catalogueItem->catalogue() == catalogue) {
294 294 return catalogueItem;
295 295 }
296 296 }
297 297 else {
298 298 qCWarning(LOG_CatalogueSideBarWidget()) << "getCatalogueItem: Invalid tree "
299 299 "structure. A database item should "
300 300 "only contain catalogues.";
301 301 Q_ASSERT(false);
302 302 }
303 303 }
304 304 }
305 305 }
306 306
307 307 return nullptr;
308 308 }
309 309
310 310 void CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::setHasChanges(bool value,
311 311 const QModelIndex &index,
312 312 QTreeView *treeView)
313 313 {
314 314 auto validationIndex = index.sibling(index.row(), (int)CatalogueTreeModel::Column::Validation);
315 315 if (value) {
316 316 if (!hasChanges(validationIndex, treeView)) {
317 317 auto widget = CatalogueExplorerHelper::buildValidationWidget(
318 treeView,
319 [this, validationIndex, treeView]() {
320 setHasChanges(false, validationIndex, treeView);
321 },
318 treeView, [this, validationIndex,
319 treeView]() { setHasChanges(false, validationIndex, treeView); },
322 320 [this, validationIndex, treeView]() {
323 321 setHasChanges(false, validationIndex, treeView);
324 322 });
325 323 treeView->setIndexWidget(validationIndex, widget);
326 324 }
327 325 }
328 326 else {
329 327 // Note: the widget is destroyed
330 328 treeView->setIndexWidget(validationIndex, nullptr);
331 329 }
332 330 }
333 331
334 332 bool CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::hasChanges(const QModelIndex &index,
335 333 QTreeView *treeView)
336 334 {
337 335 auto validationIndex = index.sibling(index.row(), (int)CatalogueTreeModel::Column::Validation);
338 336 return treeView->indexWidget(validationIndex) != nullptr;
339 337 }
General Comments 0
You need to be logged in to leave comments. Login now