##// END OF EJS Templates
Add supp shortcut for Catalogues
perrinel -
r1368:2f97b648f297
parent child
Show More
@@ -1,66 +1,71
1 #ifndef SCIQLOP_CATALOGUEEVENTSWIDGET_H
1 #ifndef SCIQLOP_CATALOGUEEVENTSWIDGET_H
2 #define SCIQLOP_CATALOGUEEVENTSWIDGET_H
2 #define SCIQLOP_CATALOGUEEVENTSWIDGET_H
3
3
4 #include <Common/spimpl.h>
4 #include <Common/spimpl.h>
5 #include <QLoggingCategory>
5 #include <QLoggingCategory>
6 #include <QWidget>
6 #include <QWidget>
7
7
8 class DBCatalogue;
8 class DBCatalogue;
9 class DBEvent;
9 class DBEvent;
10 class DBEventProduct;
10 class DBEventProduct;
11 class VisualizationWidget;
11 class VisualizationWidget;
12 class VisualizationSelectionZoneItem;
12 class VisualizationSelectionZoneItem;
13
13
14 namespace Ui {
14 namespace Ui {
15 class CatalogueEventsWidget;
15 class CatalogueEventsWidget;
16 }
16 }
17
17
18 Q_DECLARE_LOGGING_CATEGORY(LOG_CatalogueEventsWidget)
18 Q_DECLARE_LOGGING_CATEGORY(LOG_CatalogueEventsWidget)
19
19
20 class CatalogueEventsWidget : public QWidget {
20 class CatalogueEventsWidget : public QWidget {
21 Q_OBJECT
21 Q_OBJECT
22
22
23 signals:
23 signals:
24 void eventsSelected(const QVector<std::shared_ptr<DBEvent> > &event);
24 void eventsSelected(const QVector<std::shared_ptr<DBEvent> > &event);
25 void eventsRemoved(const QVector<std::shared_ptr<DBEvent> > &event);
25 void eventsRemoved(const QVector<std::shared_ptr<DBEvent> > &event);
26 void eventProductsSelected(
26 void eventProductsSelected(
27 const QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > >
27 const QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > >
28 &eventproducts);
28 &eventproducts);
29 void selectionCleared();
29 void selectionCleared();
30 void selectionZoneAdded(const std::shared_ptr<DBEvent> &event, const QString &productId,
30 void selectionZoneAdded(const std::shared_ptr<DBEvent> &event, const QString &productId,
31 VisualizationSelectionZoneItem *selectionZone);
31 VisualizationSelectionZoneItem *selectionZone);
32
32
33 void eventCataloguesModified(const QVector<std::shared_ptr<DBCatalogue> > &catalogues);
33 void eventCataloguesModified(const QVector<std::shared_ptr<DBCatalogue> > &catalogues);
34
34
35 public:
35 public:
36 explicit CatalogueEventsWidget(QWidget *parent = 0);
36 explicit CatalogueEventsWidget(QWidget *parent = 0);
37 virtual ~CatalogueEventsWidget();
37 virtual ~CatalogueEventsWidget();
38
38
39 void setVisualizationWidget(VisualizationWidget *visualization);
39 void setVisualizationWidget(VisualizationWidget *visualization);
40
40
41 void addEvent(const std::shared_ptr<DBEvent> &event);
41 void addEvent(const std::shared_ptr<DBEvent> &event);
42 void setEventChanges(const std::shared_ptr<DBEvent> &event, bool hasChanges);
42 void setEventChanges(const std::shared_ptr<DBEvent> &event, bool hasChanges);
43
43
44 QVector<std::shared_ptr<DBCatalogue> > displayedCatalogues() const;
44 QVector<std::shared_ptr<DBCatalogue> > displayedCatalogues() const;
45 bool isAllEventsDisplayed() const;
45 bool isAllEventsDisplayed() const;
46 bool isEventDisplayed(const std::shared_ptr<DBEvent> &event) const;
46 bool isEventDisplayed(const std::shared_ptr<DBEvent> &event) const;
47
47
48 void refreshEvent(const std::shared_ptr<DBEvent> &event);
48 void refreshEvent(const std::shared_ptr<DBEvent> &event);
49
49
50 public slots:
50 public slots:
51 void populateWithCatalogues(const QVector<std::shared_ptr<DBCatalogue> > &catalogues);
51 void populateWithCatalogues(const QVector<std::shared_ptr<DBCatalogue> > &catalogues);
52 void populateWithAllEvents();
52 void populateWithAllEvents();
53 void clear();
53 void clear();
54 void refresh();
54 void refresh();
55
55
56 // QWidget interface
57 protected:
58 void keyPressEvent(QKeyEvent *event);
59
60
56 private:
61 private:
57 Ui::CatalogueEventsWidget *ui;
62 Ui::CatalogueEventsWidget *ui;
58
63
59 class CatalogueEventsWidgetPrivate;
64 class CatalogueEventsWidgetPrivate;
60 spimpl::unique_impl_ptr<CatalogueEventsWidgetPrivate> impl;
65 spimpl::unique_impl_ptr<CatalogueEventsWidgetPrivate> impl;
61
66
62 private slots:
67 private slots:
63 void emitSelection();
68 void emitSelection();
64 };
69 };
65
70
66 #endif // SCIQLOP_CATALOGUEEVENTSWIDGET_H
71 #endif // SCIQLOP_CATALOGUEEVENTSWIDGET_H
@@ -1,51 +1,55
1 #ifndef SCIQLOP_CATALOGUESIDEBARWIDGET_H
1 #ifndef SCIQLOP_CATALOGUESIDEBARWIDGET_H
2 #define SCIQLOP_CATALOGUESIDEBARWIDGET_H
2 #define SCIQLOP_CATALOGUESIDEBARWIDGET_H
3
3
4 #include <Common/spimpl.h>
4 #include <Common/spimpl.h>
5 #include <QLoggingCategory>
5 #include <QLoggingCategory>
6 #include <QTreeWidgetItem>
6 #include <QTreeWidgetItem>
7 #include <QWidget>
7 #include <QWidget>
8
8
9 class CatalogueAbstractTreeItem;
9 class CatalogueAbstractTreeItem;
10 class DBCatalogue;
10 class DBCatalogue;
11
11
12 namespace Ui {
12 namespace Ui {
13 class CatalogueSideBarWidget;
13 class CatalogueSideBarWidget;
14 }
14 }
15
15
16 Q_DECLARE_LOGGING_CATEGORY(LOG_CatalogueSideBarWidget)
16 Q_DECLARE_LOGGING_CATEGORY(LOG_CatalogueSideBarWidget)
17
17
18 class CatalogueSideBarWidget : public QWidget {
18 class CatalogueSideBarWidget : public QWidget {
19 Q_OBJECT
19 Q_OBJECT
20
20
21 signals:
21 signals:
22 void catalogueSelected(const QVector<std::shared_ptr<DBCatalogue> > &catalogues);
22 void catalogueSelected(const QVector<std::shared_ptr<DBCatalogue> > &catalogues);
23 void databaseSelected(const QStringList &databases);
23 void databaseSelected(const QStringList &databases);
24 void allEventsSelected();
24 void allEventsSelected();
25 void trashSelected();
25 void trashSelected();
26 void selectionCleared();
26 void selectionCleared();
27
27
28 public:
28 public:
29 explicit CatalogueSideBarWidget(QWidget *parent = 0);
29 explicit CatalogueSideBarWidget(QWidget *parent = 0);
30 virtual ~CatalogueSideBarWidget();
30 virtual ~CatalogueSideBarWidget();
31
31
32 CatalogueAbstractTreeItem *addCatalogue(const std::shared_ptr<DBCatalogue> &catalogue,
32 CatalogueAbstractTreeItem *addCatalogue(const std::shared_ptr<DBCatalogue> &catalogue,
33 const QString &repository);
33 const QString &repository);
34 void setCatalogueChanges(const std::shared_ptr<DBCatalogue> &catalogue, bool hasChanges);
34 void setCatalogueChanges(const std::shared_ptr<DBCatalogue> &catalogue, bool hasChanges);
35
35
36 QVector<std::shared_ptr<DBCatalogue> > getCatalogues(const QString &repository) const;
36 QVector<std::shared_ptr<DBCatalogue> > getCatalogues(const QString &repository) const;
37
37
38 // QWidget interface
39 protected:
40 void keyPressEvent(QKeyEvent *event);
41
38 private slots:
42 private slots:
39 void emitSelection();
43 void emitSelection();
40
44
41 private:
45 private:
42 Ui::CatalogueSideBarWidget *ui;
46 Ui::CatalogueSideBarWidget *ui;
43
47
44 class CatalogueSideBarWidgetPrivate;
48 class CatalogueSideBarWidgetPrivate;
45 spimpl::unique_impl_ptr<CatalogueSideBarWidgetPrivate> impl;
49 spimpl::unique_impl_ptr<CatalogueSideBarWidgetPrivate> impl;
46
50
47 private slots:
51 private slots:
48 void onContextMenuRequested(const QPoint &pos);
52 void onContextMenuRequested(const QPoint &pos);
49 };
53 };
50
54
51 #endif // SCIQLOP_CATALOGUESIDEBARWIDGET_H
55 #endif // SCIQLOP_CATALOGUESIDEBARWIDGET_H
@@ -1,614 +1,627
1 #include "Catalogue/CatalogueEventsWidget.h"
1 #include "Catalogue/CatalogueEventsWidget.h"
2 #include "ui_CatalogueEventsWidget.h"
2 #include "ui_CatalogueEventsWidget.h"
3
3
4 #include <Catalogue/CatalogueController.h>
4 #include <Catalogue/CatalogueController.h>
5 #include <Catalogue/CatalogueEventsModel.h>
5 #include <Catalogue/CatalogueEventsModel.h>
6 #include <Catalogue/CatalogueExplorerHelper.h>
6 #include <Catalogue/CatalogueExplorerHelper.h>
7 #include <CatalogueDao.h>
7 #include <CatalogueDao.h>
8 #include <DBCatalogue.h>
8 #include <DBCatalogue.h>
9 #include <DBEventProduct.h>
9 #include <DBEventProduct.h>
10 #include <DataSource/DataSourceController.h>
10 #include <DataSource/DataSourceController.h>
11 #include <DataSource/DataSourceItem.h>
11 #include <DataSource/DataSourceItem.h>
12 #include <SqpApplication.h>
12 #include <SqpApplication.h>
13 #include <Variable/Variable.h>
13 #include <Variable/Variable.h>
14 #include <Variable/VariableController.h>
14 #include <Variable/VariableController.h>
15 #include <Visualization/VisualizationGraphWidget.h>
15 #include <Visualization/VisualizationGraphWidget.h>
16 #include <Visualization/VisualizationTabWidget.h>
16 #include <Visualization/VisualizationTabWidget.h>
17 #include <Visualization/VisualizationWidget.h>
17 #include <Visualization/VisualizationWidget.h>
18 #include <Visualization/VisualizationZoneWidget.h>
18 #include <Visualization/VisualizationZoneWidget.h>
19
19
20 #include <QDialog>
20 #include <QDialog>
21 #include <QDialogButtonBox>
21 #include <QDialogButtonBox>
22 #include <QKeyEvent>
22 #include <QListWidget>
23 #include <QListWidget>
23 #include <QMessageBox>
24 #include <QMessageBox>
24
25
25 Q_LOGGING_CATEGORY(LOG_CatalogueEventsWidget, "CatalogueEventsWidget")
26 Q_LOGGING_CATEGORY(LOG_CatalogueEventsWidget, "CatalogueEventsWidget")
26
27
27 /// Fixed size of the validation column
28 /// Fixed size of the validation column
28 const auto VALIDATION_COLUMN_SIZE = 35;
29 const auto VALIDATION_COLUMN_SIZE = 35;
29
30
30 /// Percentage added to the range of a event when it is displayed
31 /// Percentage added to the range of a event when it is displayed
31 const auto EVENT_RANGE_MARGE = 30; // in %
32 const auto EVENT_RANGE_MARGE = 30; // in %
32
33
33 struct CatalogueEventsWidget::CatalogueEventsWidgetPrivate {
34 struct CatalogueEventsWidget::CatalogueEventsWidgetPrivate {
34
35
35 CatalogueEventsModel *m_Model = nullptr;
36 CatalogueEventsModel *m_Model = nullptr;
36 QStringList m_ZonesForTimeMode;
37 QStringList m_ZonesForTimeMode;
37 QString m_ZoneForGraphMode;
38 QString m_ZoneForGraphMode;
38 QVector<std::shared_ptr<DBCatalogue> > m_DisplayedCatalogues;
39 QVector<std::shared_ptr<DBCatalogue> > m_DisplayedCatalogues;
39 bool m_AllEventDisplayed = false;
40 bool m_AllEventDisplayed = false;
40 QVector<VisualizationGraphWidget *> m_CustomGraphs;
41 QVector<VisualizationGraphWidget *> m_CustomGraphs;
41
42
42 VisualizationWidget *m_VisualizationWidget = nullptr;
43 VisualizationWidget *m_VisualizationWidget = nullptr;
43
44
44 void setEvents(const QVector<std::shared_ptr<DBEvent> > &events, CatalogueEventsWidget *widget)
45 void setEvents(const QVector<std::shared_ptr<DBEvent> > &events, CatalogueEventsWidget *widget)
45 {
46 {
46 widget->ui->treeView->setSortingEnabled(false);
47 widget->ui->treeView->setSortingEnabled(false);
47 m_Model->setSourceCatalogues(m_DisplayedCatalogues);
48 m_Model->setSourceCatalogues(m_DisplayedCatalogues);
48 m_Model->setEvents(events);
49 m_Model->setEvents(events);
49 widget->ui->treeView->setSortingEnabled(true);
50 widget->ui->treeView->setSortingEnabled(true);
50
51
51 for (auto event : events) {
52 for (auto event : events) {
52 if (sqpApp->catalogueController().eventHasChanges(event)) {
53 if (sqpApp->catalogueController().eventHasChanges(event)) {
53 auto index = m_Model->indexOf(event);
54 auto index = m_Model->indexOf(event);
54 widget->setEventChanges(event, true);
55 widget->setEventChanges(event, true);
55 }
56 }
56 }
57 }
57 }
58 }
58
59
59 void addEvent(const std::shared_ptr<DBEvent> &event, QTreeView *treeView)
60 void addEvent(const std::shared_ptr<DBEvent> &event, QTreeView *treeView)
60 {
61 {
61 treeView->setSortingEnabled(false);
62 treeView->setSortingEnabled(false);
62 m_Model->addEvent(event);
63 m_Model->addEvent(event);
63 treeView->setSortingEnabled(true);
64 treeView->setSortingEnabled(true);
64 }
65 }
65
66
66 void removeEvent(const std::shared_ptr<DBEvent> &event, QTreeView *treeView)
67 void removeEvent(const std::shared_ptr<DBEvent> &event, QTreeView *treeView)
67 {
68 {
68 treeView->setSortingEnabled(false);
69 treeView->setSortingEnabled(false);
69 m_Model->removeEvent(event);
70 m_Model->removeEvent(event);
70 treeView->setSortingEnabled(true);
71 treeView->setSortingEnabled(true);
71 }
72 }
72
73
73 QStringList getAvailableVisualizationZoneList() const
74 QStringList getAvailableVisualizationZoneList() const
74 {
75 {
75 if (m_VisualizationWidget) {
76 if (m_VisualizationWidget) {
76 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
77 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
77 return tab->availableZoneWidgets();
78 return tab->availableZoneWidgets();
78 }
79 }
79 }
80 }
80
81
81 return QStringList{};
82 return QStringList{};
82 }
83 }
83
84
84 QStringList selectZone(QWidget *parent, const QStringList &selectedZones,
85 QStringList selectZone(QWidget *parent, const QStringList &selectedZones,
85 bool allowMultiSelection, const QPoint &location)
86 bool allowMultiSelection, const QPoint &location)
86 {
87 {
87 auto availableZones = getAvailableVisualizationZoneList();
88 auto availableZones = getAvailableVisualizationZoneList();
88 if (availableZones.isEmpty()) {
89 if (availableZones.isEmpty()) {
89 return QStringList{};
90 return QStringList{};
90 }
91 }
91
92
92 QDialog d(parent, Qt::Tool);
93 QDialog d(parent, Qt::Tool);
93 d.setWindowTitle("Choose a zone");
94 d.setWindowTitle("Choose a zone");
94 auto layout = new QVBoxLayout{&d};
95 auto layout = new QVBoxLayout{&d};
95 layout->setContentsMargins(0, 0, 0, 0);
96 layout->setContentsMargins(0, 0, 0, 0);
96 auto listWidget = new QListWidget{&d};
97 auto listWidget = new QListWidget{&d};
97 layout->addWidget(listWidget);
98 layout->addWidget(listWidget);
98
99
99 QSet<QListWidgetItem *> checkedItems;
100 QSet<QListWidgetItem *> checkedItems;
100 for (auto zone : availableZones) {
101 for (auto zone : availableZones) {
101 auto item = new QListWidgetItem{zone};
102 auto item = new QListWidgetItem{zone};
102 item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
103 item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
103 if (selectedZones.contains(zone)) {
104 if (selectedZones.contains(zone)) {
104 item->setCheckState(Qt::Checked);
105 item->setCheckState(Qt::Checked);
105 checkedItems << item;
106 checkedItems << item;
106 }
107 }
107 else {
108 else {
108 item->setCheckState(Qt::Unchecked);
109 item->setCheckState(Qt::Unchecked);
109 }
110 }
110
111
111 listWidget->addItem(item);
112 listWidget->addItem(item);
112 }
113 }
113
114
114 auto buttonBox = new QDialogButtonBox{QDialogButtonBox::Ok, &d};
115 auto buttonBox = new QDialogButtonBox{QDialogButtonBox::Ok, &d};
115 layout->addWidget(buttonBox);
116 layout->addWidget(buttonBox);
116
117
117 QObject::connect(buttonBox, &QDialogButtonBox::accepted, &d, &QDialog::accept);
118 QObject::connect(buttonBox, &QDialogButtonBox::accepted, &d, &QDialog::accept);
118 QObject::connect(buttonBox, &QDialogButtonBox::rejected, &d, &QDialog::reject);
119 QObject::connect(buttonBox, &QDialogButtonBox::rejected, &d, &QDialog::reject);
119
120
120 QObject::connect(listWidget, &QListWidget::itemChanged,
121 QObject::connect(listWidget, &QListWidget::itemChanged,
121 [&checkedItems, allowMultiSelection, listWidget](auto item) {
122 [&checkedItems, allowMultiSelection, listWidget](auto item) {
122 if (item->checkState() == Qt::Checked) {
123 if (item->checkState() == Qt::Checked) {
123 if (!allowMultiSelection) {
124 if (!allowMultiSelection) {
124 for (auto checkedItem : checkedItems) {
125 for (auto checkedItem : checkedItems) {
125 listWidget->blockSignals(true);
126 listWidget->blockSignals(true);
126 checkedItem->setCheckState(Qt::Unchecked);
127 checkedItem->setCheckState(Qt::Unchecked);
127 listWidget->blockSignals(false);
128 listWidget->blockSignals(false);
128 }
129 }
129
130
130 checkedItems.clear();
131 checkedItems.clear();
131 }
132 }
132 checkedItems << item;
133 checkedItems << item;
133 }
134 }
134 else {
135 else {
135 checkedItems.remove(item);
136 checkedItems.remove(item);
136 }
137 }
137 });
138 });
138
139
139 QStringList result;
140 QStringList result;
140
141
141 d.setMinimumWidth(120);
142 d.setMinimumWidth(120);
142 d.resize(d.minimumSizeHint());
143 d.resize(d.minimumSizeHint());
143 d.move(location);
144 d.move(location);
144 if (d.exec() == QDialog::Accepted) {
145 if (d.exec() == QDialog::Accepted) {
145 for (auto item : checkedItems) {
146 for (auto item : checkedItems) {
146 result += item->text();
147 result += item->text();
147 }
148 }
148 }
149 }
149 else {
150 else {
150 result = selectedZones;
151 result = selectedZones;
151 }
152 }
152
153
153 return result;
154 return result;
154 }
155 }
155
156
156 void updateForTimeMode(QTreeView *treeView)
157 void updateForTimeMode(QTreeView *treeView)
157 {
158 {
158 auto selectedRows = treeView->selectionModel()->selectedRows();
159 auto selectedRows = treeView->selectionModel()->selectedRows();
159
160
160 if (selectedRows.count() == 1) {
161 if (selectedRows.count() == 1) {
161 auto event = m_Model->getEvent(selectedRows.first());
162 auto event = m_Model->getEvent(selectedRows.first());
162 if (event) {
163 if (event) {
163 if (m_VisualizationWidget) {
164 if (m_VisualizationWidget) {
164 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
165 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
165
166
166 for (auto zoneName : m_ZonesForTimeMode) {
167 for (auto zoneName : m_ZonesForTimeMode) {
167 if (auto zone = tab->getZoneWithName(zoneName)) {
168 if (auto zone = tab->getZoneWithName(zoneName)) {
168 SqpRange eventRange;
169 SqpRange eventRange;
169 eventRange.m_TStart = event->getTStart();
170 eventRange.m_TStart = event->getTStart();
170 eventRange.m_TEnd = event->getTEnd();
171 eventRange.m_TEnd = event->getTEnd();
171 zone->setZoneRange(eventRange);
172 zone->setZoneRange(eventRange);
172 }
173 }
173 }
174 }
174 }
175 }
175 else {
176 else {
176 qCWarning(LOG_CatalogueEventsWidget())
177 qCWarning(LOG_CatalogueEventsWidget())
177 << "updateTimeZone: no tab found in the visualization";
178 << "updateTimeZone: no tab found in the visualization";
178 }
179 }
179 }
180 }
180 else {
181 else {
181 qCWarning(LOG_CatalogueEventsWidget())
182 qCWarning(LOG_CatalogueEventsWidget())
182 << "updateTimeZone: visualization widget not found";
183 << "updateTimeZone: visualization widget not found";
183 }
184 }
184 }
185 }
185 }
186 }
186 else {
187 else {
187 qCWarning(LOG_CatalogueEventsWidget())
188 qCWarning(LOG_CatalogueEventsWidget())
188 << "updateTimeZone: not compatible with multiple events selected";
189 << "updateTimeZone: not compatible with multiple events selected";
189 }
190 }
190 }
191 }
191
192
192 QVector<SqpRange> getGraphRanges(const std::shared_ptr<DBEvent> &event)
193 QVector<SqpRange> getGraphRanges(const std::shared_ptr<DBEvent> &event)
193 {
194 {
194 // Retrieves the range of each product and the maximum size
195 // Retrieves the range of each product and the maximum size
195 QVector<SqpRange> graphRanges;
196 QVector<SqpRange> graphRanges;
196 double maxDt = 0;
197 double maxDt = 0;
197 for (auto eventProduct : event->getEventProducts()) {
198 for (auto eventProduct : event->getEventProducts()) {
198 SqpRange eventRange;
199 SqpRange eventRange;
199 eventRange.m_TStart = eventProduct.getTStart();
200 eventRange.m_TStart = eventProduct.getTStart();
200 eventRange.m_TEnd = eventProduct.getTEnd();
201 eventRange.m_TEnd = eventProduct.getTEnd();
201 graphRanges << eventRange;
202 graphRanges << eventRange;
202
203
203 auto dt = eventRange.m_TEnd - eventRange.m_TStart;
204 auto dt = eventRange.m_TEnd - eventRange.m_TStart;
204 if (dt > maxDt) {
205 if (dt > maxDt) {
205 maxDt = dt;
206 maxDt = dt;
206 }
207 }
207 }
208 }
208
209
209 // Adds the marge
210 // Adds the marge
210 maxDt *= (100.0 + EVENT_RANGE_MARGE) / 100.0;
211 maxDt *= (100.0 + EVENT_RANGE_MARGE) / 100.0;
211
212
212 // Corrects the graph ranges so that they all have the same size
213 // Corrects the graph ranges so that they all have the same size
213 QVector<SqpRange> correctedGraphRanges;
214 QVector<SqpRange> correctedGraphRanges;
214 for (auto range : graphRanges) {
215 for (auto range : graphRanges) {
215 auto dt = range.m_TEnd - range.m_TStart;
216 auto dt = range.m_TEnd - range.m_TStart;
216 auto diff = qAbs((maxDt - dt) / 2.0);
217 auto diff = qAbs((maxDt - dt) / 2.0);
217
218
218 SqpRange correctedRange;
219 SqpRange correctedRange;
219 correctedRange.m_TStart = range.m_TStart - diff;
220 correctedRange.m_TStart = range.m_TStart - diff;
220 correctedRange.m_TEnd = range.m_TEnd + diff;
221 correctedRange.m_TEnd = range.m_TEnd + diff;
221
222
222 correctedGraphRanges << correctedRange;
223 correctedGraphRanges << correctedRange;
223 }
224 }
224
225
225 return correctedGraphRanges;
226 return correctedGraphRanges;
226 }
227 }
227
228
228 void updateForGraphMode(CatalogueEventsWidget *catalogueEventWidget)
229 void updateForGraphMode(CatalogueEventsWidget *catalogueEventWidget)
229 {
230 {
230 auto selectedRows = catalogueEventWidget->ui->treeView->selectionModel()->selectedRows();
231 auto selectedRows = catalogueEventWidget->ui->treeView->selectionModel()->selectedRows();
231 if (selectedRows.count() != 1) {
232 if (selectedRows.count() != 1) {
232 qCWarning(LOG_CatalogueEventsWidget())
233 qCWarning(LOG_CatalogueEventsWidget())
233 << "updateGraphMode: not compatible with multiple events selected";
234 << "updateGraphMode: not compatible with multiple events selected";
234 return;
235 return;
235 }
236 }
236
237
237 if (!m_VisualizationWidget) {
238 if (!m_VisualizationWidget) {
238 qCWarning(LOG_CatalogueEventsWidget())
239 qCWarning(LOG_CatalogueEventsWidget())
239 << "updateGraphMode: visualization widget not found";
240 << "updateGraphMode: visualization widget not found";
240 return;
241 return;
241 }
242 }
242
243
243 auto event = m_Model->getEvent(selectedRows.first());
244 auto event = m_Model->getEvent(selectedRows.first());
244 if (!event) {
245 if (!event) {
245 // A event product is probably selected
246 // A event product is probably selected
246 qCInfo(LOG_CatalogueEventsWidget()) << "updateGraphMode: no events are selected";
247 qCInfo(LOG_CatalogueEventsWidget()) << "updateGraphMode: no events are selected";
247 return;
248 return;
248 }
249 }
249
250
250 auto tab = m_VisualizationWidget->currentTabWidget();
251 auto tab = m_VisualizationWidget->currentTabWidget();
251 if (!tab) {
252 if (!tab) {
252 qCWarning(LOG_CatalogueEventsWidget())
253 qCWarning(LOG_CatalogueEventsWidget())
253 << "updateGraphMode: no tab found in the visualization";
254 << "updateGraphMode: no tab found in the visualization";
254 return;
255 return;
255 }
256 }
256
257
257 auto zone = tab->getZoneWithName(m_ZoneForGraphMode);
258 auto zone = tab->getZoneWithName(m_ZoneForGraphMode);
258 if (!zone) {
259 if (!zone) {
259 qCWarning(LOG_CatalogueEventsWidget()) << "updateGraphMode: zone not found";
260 qCWarning(LOG_CatalogueEventsWidget()) << "updateGraphMode: zone not found";
260 return;
261 return;
261 }
262 }
262
263
263 // Closes the previous graph and delete the asociated variables
264 // Closes the previous graph and delete the asociated variables
264 for (auto graph : m_CustomGraphs) {
265 for (auto graph : m_CustomGraphs) {
265 graph->close();
266 graph->close();
266 auto variables = graph->variables().toVector();
267 auto variables = graph->variables().toVector();
267
268
268 QMetaObject::invokeMethod(&sqpApp->variableController(), "deleteVariables",
269 QMetaObject::invokeMethod(&sqpApp->variableController(), "deleteVariables",
269 Qt::QueuedConnection,
270 Qt::QueuedConnection,
270 Q_ARG(QVector<std::shared_ptr<Variable> >, variables));
271 Q_ARG(QVector<std::shared_ptr<Variable> >, variables));
271 }
272 }
272 m_CustomGraphs.clear();
273 m_CustomGraphs.clear();
273
274
274 // Closes the remaining graphs inside the zone
275 // Closes the remaining graphs inside the zone
275 zone->closeAllGraphs();
276 zone->closeAllGraphs();
276
277
277 // Calculates the range of each graph which will be created
278 // Calculates the range of each graph which will be created
278 auto graphRange = getGraphRanges(event);
279 auto graphRange = getGraphRanges(event);
279
280
280 // Loops through the event products and create the graph
281 // Loops through the event products and create the graph
281 auto itRange = graphRange.cbegin();
282 auto itRange = graphRange.cbegin();
282 for (auto eventProduct : event->getEventProducts()) {
283 for (auto eventProduct : event->getEventProducts()) {
283 auto productId = eventProduct.getProductId();
284 auto productId = eventProduct.getProductId();
284
285
285 auto range = *itRange;
286 auto range = *itRange;
286 ++itRange;
287 ++itRange;
287
288
288 SqpRange productRange;
289 SqpRange productRange;
289 productRange.m_TStart = eventProduct.getTStart();
290 productRange.m_TStart = eventProduct.getTStart();
290 productRange.m_TEnd = eventProduct.getTEnd();
291 productRange.m_TEnd = eventProduct.getTEnd();
291
292
292 auto context = new QObject{catalogueEventWidget};
293 auto context = new QObject{catalogueEventWidget};
293 QObject::connect(
294 QObject::connect(
294 &sqpApp->variableController(), &VariableController::variableAdded, context,
295 &sqpApp->variableController(), &VariableController::variableAdded, context,
295 [this, catalogueEventWidget, zone, context, event, range, productRange,
296 [this, catalogueEventWidget, zone, context, event, range, productRange,
296 productId](auto variable) {
297 productId](auto variable) {
297
298
298 if (variable->metadata().value(DataSourceItem::ID_DATA_KEY).toString()
299 if (variable->metadata().value(DataSourceItem::ID_DATA_KEY).toString()
299 == productId) {
300 == productId) {
300 auto graph = zone->createGraph(variable);
301 auto graph = zone->createGraph(variable);
301 graph->setAutoRangeOnVariableInitialization(false);
302 graph->setAutoRangeOnVariableInitialization(false);
302
303
303 auto selectionZone
304 auto selectionZone
304 = graph->addSelectionZone(event->getName(), productRange);
305 = graph->addSelectionZone(event->getName(), productRange);
305 emit catalogueEventWidget->selectionZoneAdded(event, productId,
306 emit catalogueEventWidget->selectionZoneAdded(event, productId,
306 selectionZone);
307 selectionZone);
307 m_CustomGraphs << graph;
308 m_CustomGraphs << graph;
308
309
309 graph->setGraphRange(range, true);
310 graph->setGraphRange(range, true);
310
311
311 // Removes the graph from the graph list if it is closed manually
312 // Removes the graph from the graph list if it is closed manually
312 QObject::connect(graph, &VisualizationGraphWidget::destroyed,
313 QObject::connect(graph, &VisualizationGraphWidget::destroyed,
313 [this, graph]() { m_CustomGraphs.removeAll(graph); });
314 [this, graph]() { m_CustomGraphs.removeAll(graph); });
314
315
315 delete context; // removes the connection
316 delete context; // removes the connection
316 }
317 }
317 },
318 },
318 Qt::QueuedConnection);
319 Qt::QueuedConnection);
319
320
320 QMetaObject::invokeMethod(&sqpApp->dataSourceController(),
321 QMetaObject::invokeMethod(&sqpApp->dataSourceController(),
321 "requestVariableFromProductIdKey", Qt::QueuedConnection,
322 "requestVariableFromProductIdKey", Qt::QueuedConnection,
322 Q_ARG(QString, productId));
323 Q_ARG(QString, productId));
323 }
324 }
324 }
325 }
325
326
326 void getSelectedItems(
327 void getSelectedItems(
327 QTreeView *treeView, QVector<std::shared_ptr<DBEvent> > &events,
328 QTreeView *treeView, QVector<std::shared_ptr<DBEvent> > &events,
328 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > &eventProducts)
329 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > &eventProducts)
329 {
330 {
330 for (auto rowIndex : treeView->selectionModel()->selectedRows()) {
331 for (auto rowIndex : treeView->selectionModel()->selectedRows()) {
331 auto itemType = m_Model->itemTypeOf(rowIndex);
332 auto itemType = m_Model->itemTypeOf(rowIndex);
332 if (itemType == CatalogueEventsModel::ItemType::Event) {
333 if (itemType == CatalogueEventsModel::ItemType::Event) {
333 events << m_Model->getEvent(rowIndex);
334 events << m_Model->getEvent(rowIndex);
334 }
335 }
335 else if (itemType == CatalogueEventsModel::ItemType::EventProduct) {
336 else if (itemType == CatalogueEventsModel::ItemType::EventProduct) {
336 eventProducts << qMakePair(m_Model->getParentEvent(rowIndex),
337 eventProducts << qMakePair(m_Model->getParentEvent(rowIndex),
337 m_Model->getEventProduct(rowIndex));
338 m_Model->getEventProduct(rowIndex));
338 }
339 }
339 }
340 }
340 }
341 }
341 };
342 };
342
343
343 CatalogueEventsWidget::CatalogueEventsWidget(QWidget *parent)
344 CatalogueEventsWidget::CatalogueEventsWidget(QWidget *parent)
344 : QWidget(parent),
345 : QWidget(parent),
345 ui(new Ui::CatalogueEventsWidget),
346 ui(new Ui::CatalogueEventsWidget),
346 impl{spimpl::make_unique_impl<CatalogueEventsWidgetPrivate>()}
347 impl{spimpl::make_unique_impl<CatalogueEventsWidgetPrivate>()}
347 {
348 {
348 ui->setupUi(this);
349 ui->setupUi(this);
349
350
350 impl->m_Model = new CatalogueEventsModel{this};
351 impl->m_Model = new CatalogueEventsModel{this};
351 ui->treeView->setModel(impl->m_Model);
352 ui->treeView->setModel(impl->m_Model);
352
353
353 ui->treeView->setSortingEnabled(true);
354 ui->treeView->setSortingEnabled(true);
354 ui->treeView->setDragDropMode(QAbstractItemView::DragDrop);
355 ui->treeView->setDragDropMode(QAbstractItemView::DragDrop);
355 ui->treeView->setDragEnabled(true);
356 ui->treeView->setDragEnabled(true);
356
357
357 connect(ui->btnTime, &QToolButton::clicked, [this](auto checked) {
358 connect(ui->btnTime, &QToolButton::clicked, [this](auto checked) {
358 if (checked) {
359 if (checked) {
359 ui->btnChart->setChecked(false);
360 ui->btnChart->setChecked(false);
360 impl->m_ZonesForTimeMode
361 impl->m_ZonesForTimeMode
361 = impl->selectZone(this, impl->m_ZonesForTimeMode, true,
362 = impl->selectZone(this, impl->m_ZonesForTimeMode, true,
362 this->mapToGlobal(ui->btnTime->frameGeometry().center()));
363 this->mapToGlobal(ui->btnTime->frameGeometry().center()));
363
364
364 impl->updateForTimeMode(ui->treeView);
365 impl->updateForTimeMode(ui->treeView);
365 }
366 }
366 });
367 });
367
368
368 connect(ui->btnChart, &QToolButton::clicked, [this](auto checked) {
369 connect(ui->btnChart, &QToolButton::clicked, [this](auto checked) {
369 if (checked) {
370 if (checked) {
370 ui->btnTime->setChecked(false);
371 ui->btnTime->setChecked(false);
371 impl->m_ZoneForGraphMode
372 impl->m_ZoneForGraphMode
372 = impl->selectZone(this, {impl->m_ZoneForGraphMode}, false,
373 = impl->selectZone(this, {impl->m_ZoneForGraphMode}, false,
373 this->mapToGlobal(ui->btnChart->frameGeometry().center()))
374 this->mapToGlobal(ui->btnChart->frameGeometry().center()))
374 .value(0);
375 .value(0);
375
376
376 impl->updateForGraphMode(this);
377 impl->updateForGraphMode(this);
377 }
378 }
378 });
379 });
379
380
380 connect(ui->btnRemove, &QToolButton::clicked, [this]() {
381 connect(ui->btnRemove, &QToolButton::clicked, [this]() {
381 QVector<std::shared_ptr<DBEvent> > events;
382 QVector<std::shared_ptr<DBEvent> > events;
382 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
383 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
383 impl->getSelectedItems(ui->treeView, events, eventProducts);
384 impl->getSelectedItems(ui->treeView, events, eventProducts);
384
385
385 if (!events.isEmpty() && eventProducts.isEmpty()) {
386 if (!events.isEmpty() && eventProducts.isEmpty()) {
386
387
387 auto canRemoveEvent
388 auto canRemoveEvent
388 = !this->isAllEventsDisplayed()
389 = !this->isAllEventsDisplayed()
389 || (QMessageBox::warning(
390 || (QMessageBox::warning(
390 this, tr("Remove Event(s)"),
391 this, tr("Remove Event(s)"),
391 tr("The selected event(s) will be permanently removed "
392 tr("The selected event(s) will be permanently removed "
392 "from the repository!\nAre you sure you want to continue?"),
393 "from the repository!\nAre you sure you want to continue?"),
393 QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
394 QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
394 == QMessageBox::Yes);
395 == QMessageBox::Yes);
395
396
396 if (canRemoveEvent) {
397 if (canRemoveEvent) {
397 for (auto event : events) {
398 for (auto event : events) {
398 if (this->isAllEventsDisplayed()) {
399 if (this->isAllEventsDisplayed()) {
399 sqpApp->catalogueController().removeEvent(event);
400 sqpApp->catalogueController().removeEvent(event);
400 impl->removeEvent(event, ui->treeView);
401 impl->removeEvent(event, ui->treeView);
401 }
402 }
402 else {
403 else {
403 QVector<std::shared_ptr<DBCatalogue> > modifiedCatalogues;
404 QVector<std::shared_ptr<DBCatalogue> > modifiedCatalogues;
404 for (auto catalogue : this->displayedCatalogues()) {
405 for (auto catalogue : this->displayedCatalogues()) {
405 if (catalogue->removeEvent(event->getUniqId())) {
406 if (catalogue->removeEvent(event->getUniqId())) {
406 sqpApp->catalogueController().updateCatalogue(catalogue);
407 sqpApp->catalogueController().updateCatalogue(catalogue);
407 modifiedCatalogues << catalogue;
408 modifiedCatalogues << catalogue;
408 }
409 }
409 }
410 }
410 if (!modifiedCatalogues.empty()) {
411 if (!modifiedCatalogues.empty()) {
411 emit eventCataloguesModified(modifiedCatalogues);
412 emit eventCataloguesModified(modifiedCatalogues);
412 }
413 }
413 }
414 }
414 impl->m_Model->removeEvent(event);
415 impl->m_Model->removeEvent(event);
415 }
416 }
416
417
417
418
418 emit this->eventsRemoved(events);
419 emit this->eventsRemoved(events);
419 }
420 }
420 }
421 }
421 });
422 });
422
423
423 connect(ui->treeView, &QTreeView::clicked, this, &CatalogueEventsWidget::emitSelection);
424 connect(ui->treeView, &QTreeView::clicked, this, &CatalogueEventsWidget::emitSelection);
424 connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
425 connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
425 &CatalogueEventsWidget::emitSelection);
426 &CatalogueEventsWidget::emitSelection);
426
427
427 ui->btnRemove->setEnabled(false); // Disabled by default when nothing is selected
428 ui->btnRemove->setEnabled(false); // Disabled by default when nothing is selected
428 connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, [this]() {
429 connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, [this]() {
429 auto isNotMultiSelection = ui->treeView->selectionModel()->selectedRows().count() <= 1;
430 auto isNotMultiSelection = ui->treeView->selectionModel()->selectedRows().count() <= 1;
430 ui->btnChart->setEnabled(isNotMultiSelection);
431 ui->btnChart->setEnabled(isNotMultiSelection);
431 ui->btnTime->setEnabled(isNotMultiSelection);
432 ui->btnTime->setEnabled(isNotMultiSelection);
432
433
433 if (isNotMultiSelection && ui->btnTime->isChecked()) {
434 if (isNotMultiSelection && ui->btnTime->isChecked()) {
434 impl->updateForTimeMode(ui->treeView);
435 impl->updateForTimeMode(ui->treeView);
435 }
436 }
436 else if (isNotMultiSelection && ui->btnChart->isChecked()) {
437 else if (isNotMultiSelection && ui->btnChart->isChecked()) {
437 impl->updateForGraphMode(this);
438 impl->updateForGraphMode(this);
438 }
439 }
439
440
440 QVector<std::shared_ptr<DBEvent> > events;
441 QVector<std::shared_ptr<DBEvent> > events;
441 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
442 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
442 impl->getSelectedItems(ui->treeView, events, eventProducts);
443 impl->getSelectedItems(ui->treeView, events, eventProducts);
443 ui->btnRemove->setEnabled(!events.isEmpty() && eventProducts.isEmpty());
444 ui->btnRemove->setEnabled(!events.isEmpty() && eventProducts.isEmpty());
444 });
445 });
445
446
446 ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
447 ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
447 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Tags,
448 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Tags,
448 QHeaderView::Stretch);
449 QHeaderView::Stretch);
449 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Validation,
450 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Validation,
450 QHeaderView::Fixed);
451 QHeaderView::Fixed);
451 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Name,
452 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Name,
452 QHeaderView::Interactive);
453 QHeaderView::Interactive);
453 ui->treeView->header()->resizeSection((int)CatalogueEventsModel::Column::Validation,
454 ui->treeView->header()->resizeSection((int)CatalogueEventsModel::Column::Validation,
454 VALIDATION_COLUMN_SIZE);
455 VALIDATION_COLUMN_SIZE);
455 ui->treeView->header()->setSortIndicatorShown(true);
456 ui->treeView->header()->setSortIndicatorShown(true);
456
457
457 connect(impl->m_Model, &CatalogueEventsModel::modelSorted, [this]() {
458 connect(impl->m_Model, &CatalogueEventsModel::modelSorted, [this]() {
458 auto allEvents = impl->m_Model->events();
459 auto allEvents = impl->m_Model->events();
459 for (auto event : allEvents) {
460 for (auto event : allEvents) {
460 setEventChanges(event, sqpApp->catalogueController().eventHasChanges(event));
461 setEventChanges(event, sqpApp->catalogueController().eventHasChanges(event));
461 }
462 }
462 });
463 });
463
464
464 populateWithAllEvents();
465 populateWithAllEvents();
465 }
466 }
466
467
467 CatalogueEventsWidget::~CatalogueEventsWidget()
468 CatalogueEventsWidget::~CatalogueEventsWidget()
468 {
469 {
469 delete ui;
470 delete ui;
470 }
471 }
471
472
472 void CatalogueEventsWidget::setVisualizationWidget(VisualizationWidget *visualization)
473 void CatalogueEventsWidget::setVisualizationWidget(VisualizationWidget *visualization)
473 {
474 {
474 impl->m_VisualizationWidget = visualization;
475 impl->m_VisualizationWidget = visualization;
475 }
476 }
476
477
477 void CatalogueEventsWidget::addEvent(const std::shared_ptr<DBEvent> &event)
478 void CatalogueEventsWidget::addEvent(const std::shared_ptr<DBEvent> &event)
478 {
479 {
479 impl->addEvent(event, ui->treeView);
480 impl->addEvent(event, ui->treeView);
480 }
481 }
481
482
482 void CatalogueEventsWidget::setEventChanges(const std::shared_ptr<DBEvent> &event, bool hasChanges)
483 void CatalogueEventsWidget::setEventChanges(const std::shared_ptr<DBEvent> &event, bool hasChanges)
483 {
484 {
484 impl->m_Model->refreshEvent(event);
485 impl->m_Model->refreshEvent(event);
485
486
486 auto eventIndex = impl->m_Model->indexOf(event);
487 auto eventIndex = impl->m_Model->indexOf(event);
487 auto validationIndex
488 auto validationIndex
488 = eventIndex.sibling(eventIndex.row(), (int)CatalogueEventsModel::Column::Validation);
489 = eventIndex.sibling(eventIndex.row(), (int)CatalogueEventsModel::Column::Validation);
489
490
490 if (validationIndex.isValid()) {
491 if (validationIndex.isValid()) {
491 if (hasChanges) {
492 if (hasChanges) {
492 if (ui->treeView->indexWidget(validationIndex) == nullptr) {
493 if (ui->treeView->indexWidget(validationIndex) == nullptr) {
493 auto widget = CatalogueExplorerHelper::buildValidationWidget(
494 auto widget = CatalogueExplorerHelper::buildValidationWidget(
494 ui->treeView,
495 ui->treeView,
495 [this, event]() {
496 [this, event]() {
496 sqpApp->catalogueController().saveEvent(event);
497 sqpApp->catalogueController().saveEvent(event);
497 setEventChanges(event, false);
498 setEventChanges(event, false);
498 },
499 },
499 [this, event]() {
500 [this, event]() {
500 bool removed = false;
501 bool removed = false;
501 sqpApp->catalogueController().discardEvent(event, removed);
502 sqpApp->catalogueController().discardEvent(event, removed);
502 if (removed) {
503 if (removed) {
503 impl->m_Model->removeEvent(event);
504 impl->m_Model->removeEvent(event);
504 }
505 }
505 else {
506 else {
506 setEventChanges(event, false);
507 setEventChanges(event, false);
507 impl->m_Model->refreshEvent(event, true);
508 impl->m_Model->refreshEvent(event, true);
508 }
509 }
509 emitSelection();
510 emitSelection();
510 });
511 });
511 ui->treeView->setIndexWidget(validationIndex, widget);
512 ui->treeView->setIndexWidget(validationIndex, widget);
512 }
513 }
513 }
514 }
514 else {
515 else {
515 // Note: the widget is destroyed
516 // Note: the widget is destroyed
516 ui->treeView->setIndexWidget(validationIndex, nullptr);
517 ui->treeView->setIndexWidget(validationIndex, nullptr);
517 }
518 }
518 }
519 }
519 else {
520 else {
520 qCWarning(LOG_CatalogueEventsWidget())
521 qCWarning(LOG_CatalogueEventsWidget())
521 << "setEventChanges: the event is not displayed in the model.";
522 << "setEventChanges: the event is not displayed in the model.";
522 }
523 }
523 }
524 }
524
525
525 QVector<std::shared_ptr<DBCatalogue> > CatalogueEventsWidget::displayedCatalogues() const
526 QVector<std::shared_ptr<DBCatalogue> > CatalogueEventsWidget::displayedCatalogues() const
526 {
527 {
527 return impl->m_DisplayedCatalogues;
528 return impl->m_DisplayedCatalogues;
528 }
529 }
529
530
530 bool CatalogueEventsWidget::isAllEventsDisplayed() const
531 bool CatalogueEventsWidget::isAllEventsDisplayed() const
531 {
532 {
532 return impl->m_AllEventDisplayed;
533 return impl->m_AllEventDisplayed;
533 }
534 }
534
535
535 bool CatalogueEventsWidget::isEventDisplayed(const std::shared_ptr<DBEvent> &event) const
536 bool CatalogueEventsWidget::isEventDisplayed(const std::shared_ptr<DBEvent> &event) const
536 {
537 {
537 return impl->m_Model->indexOf(event).isValid();
538 return impl->m_Model->indexOf(event).isValid();
538 }
539 }
539
540
540 void CatalogueEventsWidget::refreshEvent(const std::shared_ptr<DBEvent> &event)
541 void CatalogueEventsWidget::refreshEvent(const std::shared_ptr<DBEvent> &event)
541 {
542 {
542 impl->m_Model->refreshEvent(event, true);
543 impl->m_Model->refreshEvent(event, true);
543 }
544 }
544
545
545 void CatalogueEventsWidget::populateWithCatalogues(
546 void CatalogueEventsWidget::populateWithCatalogues(
546 const QVector<std::shared_ptr<DBCatalogue> > &catalogues)
547 const QVector<std::shared_ptr<DBCatalogue> > &catalogues)
547 {
548 {
548 impl->m_DisplayedCatalogues = catalogues;
549 impl->m_DisplayedCatalogues = catalogues;
549 impl->m_AllEventDisplayed = false;
550 impl->m_AllEventDisplayed = false;
550
551
551 QSet<QUuid> eventIds;
552 QSet<QUuid> eventIds;
552 QVector<std::shared_ptr<DBEvent> > events;
553 QVector<std::shared_ptr<DBEvent> > events;
553
554
554 for (auto catalogue : catalogues) {
555 for (auto catalogue : catalogues) {
555 auto catalogueEvents = sqpApp->catalogueController().retrieveEventsFromCatalogue(catalogue);
556 auto catalogueEvents = sqpApp->catalogueController().retrieveEventsFromCatalogue(catalogue);
556 for (auto event : catalogueEvents) {
557 for (auto event : catalogueEvents) {
557 if (!eventIds.contains(event->getUniqId())) {
558 if (!eventIds.contains(event->getUniqId())) {
558 events << event;
559 events << event;
559 eventIds.insert(event->getUniqId());
560 eventIds.insert(event->getUniqId());
560 }
561 }
561 }
562 }
562 }
563 }
563
564
564 impl->setEvents(events, this);
565 impl->setEvents(events, this);
565 }
566 }
566
567
567 void CatalogueEventsWidget::populateWithAllEvents()
568 void CatalogueEventsWidget::populateWithAllEvents()
568 {
569 {
569 impl->m_DisplayedCatalogues.clear();
570 impl->m_DisplayedCatalogues.clear();
570 impl->m_AllEventDisplayed = true;
571 impl->m_AllEventDisplayed = true;
571
572
572 auto allEvents = sqpApp->catalogueController().retrieveAllEvents();
573 auto allEvents = sqpApp->catalogueController().retrieveAllEvents();
573
574
574 QVector<std::shared_ptr<DBEvent> > events;
575 QVector<std::shared_ptr<DBEvent> > events;
575 for (auto event : allEvents) {
576 for (auto event : allEvents) {
576 events << event;
577 events << event;
577 }
578 }
578
579
579 impl->setEvents(events, this);
580 impl->setEvents(events, this);
580 }
581 }
581
582
582 void CatalogueEventsWidget::clear()
583 void CatalogueEventsWidget::clear()
583 {
584 {
584 impl->m_DisplayedCatalogues.clear();
585 impl->m_DisplayedCatalogues.clear();
585 impl->m_AllEventDisplayed = false;
586 impl->m_AllEventDisplayed = false;
586 impl->setEvents({}, this);
587 impl->setEvents({}, this);
587 }
588 }
588
589
589 void CatalogueEventsWidget::refresh()
590 void CatalogueEventsWidget::refresh()
590 {
591 {
591 if (isAllEventsDisplayed()) {
592 if (isAllEventsDisplayed()) {
592 populateWithAllEvents();
593 populateWithAllEvents();
593 }
594 }
594 else if (!impl->m_DisplayedCatalogues.isEmpty()) {
595 else if (!impl->m_DisplayedCatalogues.isEmpty()) {
595 populateWithCatalogues(impl->m_DisplayedCatalogues);
596 populateWithCatalogues(impl->m_DisplayedCatalogues);
596 }
597 }
597 }
598 }
598
599
599 void CatalogueEventsWidget::emitSelection()
600 void CatalogueEventsWidget::emitSelection()
600 {
601 {
601 QVector<std::shared_ptr<DBEvent> > events;
602 QVector<std::shared_ptr<DBEvent> > events;
602 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
603 QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > > eventProducts;
603 impl->getSelectedItems(ui->treeView, events, eventProducts);
604 impl->getSelectedItems(ui->treeView, events, eventProducts);
604
605
605 if (!events.isEmpty() && eventProducts.isEmpty()) {
606 if (!events.isEmpty() && eventProducts.isEmpty()) {
606 emit eventsSelected(events);
607 emit eventsSelected(events);
607 }
608 }
608 else if (events.isEmpty() && !eventProducts.isEmpty()) {
609 else if (events.isEmpty() && !eventProducts.isEmpty()) {
609 emit eventProductsSelected(eventProducts);
610 emit eventProductsSelected(eventProducts);
610 }
611 }
611 else {
612 else {
612 emit selectionCleared();
613 emit selectionCleared();
613 }
614 }
614 }
615 }
616
617
618 void CatalogueEventsWidget::keyPressEvent(QKeyEvent *event)
619 {
620 switch (event->key()) {
621 case Qt::Key_Delete: {
622 ui->btnRemove->click();
623 }
624 default:
625 break;
626 }
627 }
@@ -1,429 +1,442
1 #include "Catalogue/CatalogueSideBarWidget.h"
1 #include "Catalogue/CatalogueSideBarWidget.h"
2 #include "ui_CatalogueSideBarWidget.h"
2 #include "ui_CatalogueSideBarWidget.h"
3 #include <SqpApplication.h>
3 #include <SqpApplication.h>
4
4
5 #include <Catalogue/CatalogueController.h>
5 #include <Catalogue/CatalogueController.h>
6 #include <Catalogue/CatalogueExplorerHelper.h>
6 #include <Catalogue/CatalogueExplorerHelper.h>
7 #include <Catalogue/CatalogueTreeItems/CatalogueTextTreeItem.h>
7 #include <Catalogue/CatalogueTreeItems/CatalogueTextTreeItem.h>
8 #include <Catalogue/CatalogueTreeItems/CatalogueTreeItem.h>
8 #include <Catalogue/CatalogueTreeItems/CatalogueTreeItem.h>
9 #include <Catalogue/CatalogueTreeModel.h>
9 #include <Catalogue/CatalogueTreeModel.h>
10 #include <CatalogueDao.h>
10 #include <CatalogueDao.h>
11 #include <Common/MimeTypesDef.h>
11 #include <Common/MimeTypesDef.h>
12 #include <ComparaisonPredicate.h>
12 #include <ComparaisonPredicate.h>
13 #include <DBCatalogue.h>
13 #include <DBCatalogue.h>
14
14
15 #include <QKeyEvent>
15 #include <QMenu>
16 #include <QMenu>
16 #include <QMessageBox>
17 #include <QMessageBox>
17 #include <QMimeData>
18 #include <QMimeData>
18
19
19 Q_LOGGING_CATEGORY(LOG_CatalogueSideBarWidget, "CatalogueSideBarWidget")
20 Q_LOGGING_CATEGORY(LOG_CatalogueSideBarWidget, "CatalogueSideBarWidget")
20
21
21
22
22 constexpr auto ALL_EVENT_ITEM_TYPE = CatalogueAbstractTreeItem::DEFAULT_TYPE + 1;
23 constexpr auto ALL_EVENT_ITEM_TYPE = CatalogueAbstractTreeItem::DEFAULT_TYPE + 1;
23 constexpr auto TRASH_ITEM_TYPE = CatalogueAbstractTreeItem::DEFAULT_TYPE + 2;
24 constexpr auto TRASH_ITEM_TYPE = CatalogueAbstractTreeItem::DEFAULT_TYPE + 2;
24 constexpr auto CATALOGUE_ITEM_TYPE = CatalogueAbstractTreeItem::DEFAULT_TYPE + 3;
25 constexpr auto CATALOGUE_ITEM_TYPE = CatalogueAbstractTreeItem::DEFAULT_TYPE + 3;
25 constexpr auto DATABASE_ITEM_TYPE = CatalogueAbstractTreeItem::DEFAULT_TYPE + 4;
26 constexpr auto DATABASE_ITEM_TYPE = CatalogueAbstractTreeItem::DEFAULT_TYPE + 4;
26
27
27
28
28 struct CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate {
29 struct CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate {
29
30
30 CatalogueTreeModel *m_TreeModel = nullptr;
31 CatalogueTreeModel *m_TreeModel = nullptr;
31
32
32 void configureTreeWidget(QTreeView *treeView);
33 void configureTreeWidget(QTreeView *treeView);
33 QModelIndex addDatabaseItem(const QString &name);
34 QModelIndex addDatabaseItem(const QString &name);
34 CatalogueAbstractTreeItem *getDatabaseItem(const QString &name);
35 CatalogueAbstractTreeItem *getDatabaseItem(const QString &name);
35 CatalogueAbstractTreeItem *addCatalogueItem(const std::shared_ptr<DBCatalogue> &catalogue,
36 CatalogueAbstractTreeItem *addCatalogueItem(const std::shared_ptr<DBCatalogue> &catalogue,
36 const QModelIndex &databaseIndex);
37 const QModelIndex &databaseIndex);
37
38
38 CatalogueTreeItem *getCatalogueItem(const std::shared_ptr<DBCatalogue> &catalogue) const;
39 CatalogueTreeItem *getCatalogueItem(const std::shared_ptr<DBCatalogue> &catalogue) const;
39 void setHasChanges(bool value, const QModelIndex &index, CatalogueSideBarWidget *sideBarWidget);
40 void setHasChanges(bool value, const QModelIndex &index, CatalogueSideBarWidget *sideBarWidget);
40 bool hasChanges(const QModelIndex &index, QTreeView *treeView);
41 bool hasChanges(const QModelIndex &index, QTreeView *treeView);
41
42
42 int selectionType(QTreeView *treeView) const
43 int selectionType(QTreeView *treeView) const
43 {
44 {
44 auto selectedItems = treeView->selectionModel()->selectedRows();
45 auto selectedItems = treeView->selectionModel()->selectedRows();
45 if (selectedItems.isEmpty()) {
46 if (selectedItems.isEmpty()) {
46 return CatalogueAbstractTreeItem::DEFAULT_TYPE;
47 return CatalogueAbstractTreeItem::DEFAULT_TYPE;
47 }
48 }
48 else {
49 else {
49 auto firstIndex = selectedItems.first();
50 auto firstIndex = selectedItems.first();
50 auto firstItem = m_TreeModel->item(firstIndex);
51 auto firstItem = m_TreeModel->item(firstIndex);
51 if (!firstItem) {
52 if (!firstItem) {
52 Q_ASSERT(false);
53 Q_ASSERT(false);
53 return CatalogueAbstractTreeItem::DEFAULT_TYPE;
54 return CatalogueAbstractTreeItem::DEFAULT_TYPE;
54 }
55 }
55 auto selectionType = firstItem->type();
56 auto selectionType = firstItem->type();
56
57
57 for (auto itemIndex : selectedItems) {
58 for (auto itemIndex : selectedItems) {
58 auto item = m_TreeModel->item(itemIndex);
59 auto item = m_TreeModel->item(itemIndex);
59 if (!item || item->type() != selectionType) {
60 if (!item || item->type() != selectionType) {
60 // Incoherent multi selection
61 // Incoherent multi selection
61 selectionType = CatalogueAbstractTreeItem::DEFAULT_TYPE;
62 selectionType = CatalogueAbstractTreeItem::DEFAULT_TYPE;
62 break;
63 break;
63 }
64 }
64 }
65 }
65
66
66 return selectionType;
67 return selectionType;
67 }
68 }
68 }
69 }
69
70
70 QVector<std::shared_ptr<DBCatalogue> > selectedCatalogues(QTreeView *treeView) const
71 QVector<std::shared_ptr<DBCatalogue> > selectedCatalogues(QTreeView *treeView) const
71 {
72 {
72 QVector<std::shared_ptr<DBCatalogue> > catalogues;
73 QVector<std::shared_ptr<DBCatalogue> > catalogues;
73 auto selectedItems = treeView->selectionModel()->selectedRows();
74 auto selectedItems = treeView->selectionModel()->selectedRows();
74 for (auto itemIndex : selectedItems) {
75 for (auto itemIndex : selectedItems) {
75 auto item = m_TreeModel->item(itemIndex);
76 auto item = m_TreeModel->item(itemIndex);
76 if (item && item->type() == CATALOGUE_ITEM_TYPE) {
77 if (item && item->type() == CATALOGUE_ITEM_TYPE) {
77 catalogues.append(static_cast<CatalogueTreeItem *>(item)->catalogue());
78 catalogues.append(static_cast<CatalogueTreeItem *>(item)->catalogue());
78 }
79 }
79 }
80 }
80
81
81 return catalogues;
82 return catalogues;
82 }
83 }
83
84
84 QStringList selectedRepositories(QTreeView *treeView) const
85 QStringList selectedRepositories(QTreeView *treeView) const
85 {
86 {
86 QStringList repositories;
87 QStringList repositories;
87 auto selectedItems = treeView->selectionModel()->selectedRows();
88 auto selectedItems = treeView->selectionModel()->selectedRows();
88 for (auto itemIndex : selectedItems) {
89 for (auto itemIndex : selectedItems) {
89 auto item = m_TreeModel->item(itemIndex);
90 auto item = m_TreeModel->item(itemIndex);
90 if (item && item->type() == DATABASE_ITEM_TYPE) {
91 if (item && item->type() == DATABASE_ITEM_TYPE) {
91 repositories.append(item->text());
92 repositories.append(item->text());
92 }
93 }
93 }
94 }
94
95
95 return repositories;
96 return repositories;
96 }
97 }
97 };
98 };
98
99
99 CatalogueSideBarWidget::CatalogueSideBarWidget(QWidget *parent)
100 CatalogueSideBarWidget::CatalogueSideBarWidget(QWidget *parent)
100 : QWidget(parent),
101 : QWidget(parent),
101 ui(new Ui::CatalogueSideBarWidget),
102 ui(new Ui::CatalogueSideBarWidget),
102 impl{spimpl::make_unique_impl<CatalogueSideBarWidgetPrivate>()}
103 impl{spimpl::make_unique_impl<CatalogueSideBarWidgetPrivate>()}
103 {
104 {
104 ui->setupUi(this);
105 ui->setupUi(this);
105
106
106 impl->m_TreeModel = new CatalogueTreeModel(this);
107 impl->m_TreeModel = new CatalogueTreeModel(this);
107 ui->treeView->setModel(impl->m_TreeModel);
108 ui->treeView->setModel(impl->m_TreeModel);
108
109
109 impl->configureTreeWidget(ui->treeView);
110 impl->configureTreeWidget(ui->treeView);
110
111
111 ui->treeView->header()->setStretchLastSection(false);
112 ui->treeView->header()->setStretchLastSection(false);
112 ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
113 ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
113 ui->treeView->header()->setSectionResizeMode(0, QHeaderView::Stretch);
114 ui->treeView->header()->setSectionResizeMode(0, QHeaderView::Stretch);
114
115
115 connect(ui->treeView, &QTreeView::clicked, this, &CatalogueSideBarWidget::emitSelection);
116 connect(ui->treeView, &QTreeView::clicked, this, &CatalogueSideBarWidget::emitSelection);
116 connect(ui->treeView->selectionModel(), &QItemSelectionModel::currentChanged, this,
117 connect(ui->treeView->selectionModel(), &QItemSelectionModel::currentChanged, this,
117 &CatalogueSideBarWidget::emitSelection);
118 &CatalogueSideBarWidget::emitSelection);
118
119
119
120
120 connect(ui->btnAdd, &QToolButton::clicked, [this]() {
121 connect(ui->btnAdd, &QToolButton::clicked, [this]() {
121 auto catalogue = std::make_shared<DBCatalogue>();
122 auto catalogue = std::make_shared<DBCatalogue>();
122 catalogue->setName(QString("Cat"));
123 catalogue->setName(QString("Cat"));
123 sqpApp->catalogueController().addCatalogue(catalogue);
124 sqpApp->catalogueController().addCatalogue(catalogue);
124 auto item = this->addCatalogue(catalogue, REPOSITORY_DEFAULT);
125 auto item = this->addCatalogue(catalogue, REPOSITORY_DEFAULT);
125 this->setCatalogueChanges(catalogue, true);
126 this->setCatalogueChanges(catalogue, true);
126 ui->treeView->edit(impl->m_TreeModel->indexOf(item));
127 ui->treeView->edit(impl->m_TreeModel->indexOf(item));
127
128
128 });
129 });
129
130
130
131
131 connect(impl->m_TreeModel, &CatalogueTreeModel::itemDropped,
132 connect(impl->m_TreeModel, &CatalogueTreeModel::itemDropped,
132 [this](auto index, auto mimeData, auto action) {
133 [this](auto index, auto mimeData, auto action) {
133 auto item = impl->m_TreeModel->item(index);
134 auto item = impl->m_TreeModel->item(index);
134 if (item && item->type() == CATALOGUE_ITEM_TYPE) {
135 if (item && item->type() == CATALOGUE_ITEM_TYPE) {
135 auto catalogue = static_cast<CatalogueTreeItem *>(item)->catalogue();
136 auto catalogue = static_cast<CatalogueTreeItem *>(item)->catalogue();
136 this->setCatalogueChanges(catalogue, true);
137 this->setCatalogueChanges(catalogue, true);
137 }
138 }
138
139
139 if (action == Qt::MoveAction) {
140 if (action == Qt::MoveAction) {
140 /// Display a save button on source catalogues
141 /// Display a save button on source catalogues
141 auto sourceCatalogues = sqpApp->catalogueController().cataloguesForMimeData(
142 auto sourceCatalogues = sqpApp->catalogueController().cataloguesForMimeData(
142 mimeData->data(MIME_TYPE_SOURCE_CATALOGUE_LIST));
143 mimeData->data(MIME_TYPE_SOURCE_CATALOGUE_LIST));
143 for (auto catalogue : sourceCatalogues) {
144 for (auto catalogue : sourceCatalogues) {
144 if (auto catalogueItem = impl->getCatalogueItem(catalogue)) {
145 if (auto catalogueItem = impl->getCatalogueItem(catalogue)) {
145 this->setCatalogueChanges(catalogue, true);
146 this->setCatalogueChanges(catalogue, true);
146 }
147 }
147 }
148 }
148 }
149 }
149 });
150 });
150
151
151 connect(ui->btnRemove, &QToolButton::clicked, [this]() {
152 connect(ui->btnRemove, &QToolButton::clicked, [this]() {
152 QVector<QPair<std::shared_ptr<DBCatalogue>, CatalogueAbstractTreeItem *> >
153 QVector<QPair<std::shared_ptr<DBCatalogue>, CatalogueAbstractTreeItem *> >
153 cataloguesToItems;
154 cataloguesToItems;
154 auto selectedIndexes = ui->treeView->selectionModel()->selectedRows();
155 auto selectedIndexes = ui->treeView->selectionModel()->selectedRows();
155
156
156 for (auto index : selectedIndexes) {
157 for (auto index : selectedIndexes) {
157 auto item = impl->m_TreeModel->item(index);
158 auto item = impl->m_TreeModel->item(index);
158 if (item && item->type() == CATALOGUE_ITEM_TYPE) {
159 if (item && item->type() == CATALOGUE_ITEM_TYPE) {
159 auto catalogue = static_cast<CatalogueTreeItem *>(item)->catalogue();
160 auto catalogue = static_cast<CatalogueTreeItem *>(item)->catalogue();
160 cataloguesToItems << qMakePair(catalogue, item);
161 cataloguesToItems << qMakePair(catalogue, item);
161 }
162 }
162 }
163 }
163
164
164 if (!cataloguesToItems.isEmpty()) {
165 if (!cataloguesToItems.isEmpty()) {
165
166
166 if (QMessageBox::warning(this, tr("Remove Catalogue(s)"),
167 if (QMessageBox::warning(this, tr("Remove Catalogue(s)"),
167 tr("The selected catalogues(s) will be completly removed "
168 tr("The selected catalogues(s) will be completly removed "
168 "from the repository!\nAre you sure you want to continue?"),
169 "from the repository!\nAre you sure you want to continue?"),
169 QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
170 QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
170 == QMessageBox::Yes) {
171 == QMessageBox::Yes) {
171
172
172 for (auto catalogueToItem : cataloguesToItems) {
173 for (auto catalogueToItem : cataloguesToItems) {
173 sqpApp->catalogueController().removeCatalogue(catalogueToItem.first);
174 sqpApp->catalogueController().removeCatalogue(catalogueToItem.first);
174 impl->m_TreeModel->removeChildItem(
175 impl->m_TreeModel->removeChildItem(
175 catalogueToItem.second,
176 catalogueToItem.second,
176 impl->m_TreeModel->indexOf(catalogueToItem.second->parent()));
177 impl->m_TreeModel->indexOf(catalogueToItem.second->parent()));
177 }
178 }
178 }
179 }
179 }
180 }
180 });
181 });
181
182
182 connect(impl->m_TreeModel, &CatalogueTreeModel::itemRenamed, [this](auto index) {
183 connect(impl->m_TreeModel, &CatalogueTreeModel::itemRenamed, [this](auto index) {
183 auto selectedIndexes = ui->treeView->selectionModel()->selectedRows();
184 auto selectedIndexes = ui->treeView->selectionModel()->selectedRows();
184 if (selectedIndexes.contains(index)) {
185 if (selectedIndexes.contains(index)) {
185 this->emitSelection();
186 this->emitSelection();
186 }
187 }
187 impl->setHasChanges(true, index, this);
188 impl->setHasChanges(true, index, this);
188 });
189 });
189
190
190 ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
191 ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
191 connect(ui->treeView, &QTreeView::customContextMenuRequested, this,
192 connect(ui->treeView, &QTreeView::customContextMenuRequested, this,
192 &CatalogueSideBarWidget::onContextMenuRequested);
193 &CatalogueSideBarWidget::onContextMenuRequested);
193 }
194 }
194
195
195 CatalogueSideBarWidget::~CatalogueSideBarWidget()
196 CatalogueSideBarWidget::~CatalogueSideBarWidget()
196 {
197 {
197 delete ui;
198 delete ui;
198 }
199 }
199
200
200 CatalogueAbstractTreeItem *
201 CatalogueAbstractTreeItem *
201 CatalogueSideBarWidget::addCatalogue(const std::shared_ptr<DBCatalogue> &catalogue,
202 CatalogueSideBarWidget::addCatalogue(const std::shared_ptr<DBCatalogue> &catalogue,
202 const QString &repository)
203 const QString &repository)
203 {
204 {
204 auto repositoryItem = impl->getDatabaseItem(repository);
205 auto repositoryItem = impl->getDatabaseItem(repository);
205 return impl->addCatalogueItem(catalogue, impl->m_TreeModel->indexOf(repositoryItem));
206 return impl->addCatalogueItem(catalogue, impl->m_TreeModel->indexOf(repositoryItem));
206 }
207 }
207
208
208 void CatalogueSideBarWidget::setCatalogueChanges(const std::shared_ptr<DBCatalogue> &catalogue,
209 void CatalogueSideBarWidget::setCatalogueChanges(const std::shared_ptr<DBCatalogue> &catalogue,
209 bool hasChanges)
210 bool hasChanges)
210 {
211 {
211 if (auto catalogueItem = impl->getCatalogueItem(catalogue)) {
212 if (auto catalogueItem = impl->getCatalogueItem(catalogue)) {
212 auto index = impl->m_TreeModel->indexOf(catalogueItem);
213 auto index = impl->m_TreeModel->indexOf(catalogueItem);
213 impl->setHasChanges(hasChanges, index, this);
214 impl->setHasChanges(hasChanges, index, this);
214 // catalogueItem->refresh();
215 // catalogueItem->refresh();
215 }
216 }
216 }
217 }
217
218
218 QVector<std::shared_ptr<DBCatalogue> >
219 QVector<std::shared_ptr<DBCatalogue> >
219 CatalogueSideBarWidget::getCatalogues(const QString &repository) const
220 CatalogueSideBarWidget::getCatalogues(const QString &repository) const
220 {
221 {
221 QVector<std::shared_ptr<DBCatalogue> > result;
222 QVector<std::shared_ptr<DBCatalogue> > result;
222 auto repositoryItem = impl->getDatabaseItem(repository);
223 auto repositoryItem = impl->getDatabaseItem(repository);
223 for (auto child : repositoryItem->children()) {
224 for (auto child : repositoryItem->children()) {
224 if (child->type() == CATALOGUE_ITEM_TYPE) {
225 if (child->type() == CATALOGUE_ITEM_TYPE) {
225 auto catalogueItem = static_cast<CatalogueTreeItem *>(child);
226 auto catalogueItem = static_cast<CatalogueTreeItem *>(child);
226 result << catalogueItem->catalogue();
227 result << catalogueItem->catalogue();
227 }
228 }
228 else {
229 else {
229 qCWarning(LOG_CatalogueSideBarWidget()) << "getCatalogues: invalid structure";
230 qCWarning(LOG_CatalogueSideBarWidget()) << "getCatalogues: invalid structure";
230 }
231 }
231 }
232 }
232
233
233 return result;
234 return result;
234 }
235 }
235
236
236 void CatalogueSideBarWidget::emitSelection()
237 void CatalogueSideBarWidget::emitSelection()
237 {
238 {
238 auto selectionType = impl->selectionType(ui->treeView);
239 auto selectionType = impl->selectionType(ui->treeView);
239
240
240 switch (selectionType) {
241 switch (selectionType) {
241 case CATALOGUE_ITEM_TYPE:
242 case CATALOGUE_ITEM_TYPE:
242 emit this->catalogueSelected(impl->selectedCatalogues(ui->treeView));
243 emit this->catalogueSelected(impl->selectedCatalogues(ui->treeView));
243 break;
244 break;
244 case DATABASE_ITEM_TYPE:
245 case DATABASE_ITEM_TYPE:
245 emit this->databaseSelected(impl->selectedRepositories(ui->treeView));
246 emit this->databaseSelected(impl->selectedRepositories(ui->treeView));
246 break;
247 break;
247 case ALL_EVENT_ITEM_TYPE:
248 case ALL_EVENT_ITEM_TYPE:
248 emit this->allEventsSelected();
249 emit this->allEventsSelected();
249 break;
250 break;
250 case TRASH_ITEM_TYPE:
251 case TRASH_ITEM_TYPE:
251 emit this->trashSelected();
252 emit this->trashSelected();
252 break;
253 break;
253 default:
254 default:
254 emit this->selectionCleared();
255 emit this->selectionCleared();
255 break;
256 break;
256 }
257 }
257 }
258 }
258
259
259 void CatalogueSideBarWidget::onContextMenuRequested(const QPoint &pos)
260 void CatalogueSideBarWidget::onContextMenuRequested(const QPoint &pos)
260 {
261 {
261 QMenu menu{this};
262 QMenu menu{this};
262
263
263 auto currentIndex = ui->treeView->currentIndex();
264 auto currentIndex = ui->treeView->currentIndex();
264 auto currentItem = impl->m_TreeModel->item(currentIndex);
265 auto currentItem = impl->m_TreeModel->item(currentIndex);
265 if (!currentItem) {
266 if (!currentItem) {
266 return;
267 return;
267 }
268 }
268
269
269 switch (currentItem->type()) {
270 switch (currentItem->type()) {
270 case CATALOGUE_ITEM_TYPE:
271 case CATALOGUE_ITEM_TYPE:
271 menu.addAction("Rename", [this, currentIndex]() { ui->treeView->edit(currentIndex); });
272 menu.addAction("Rename", [this, currentIndex]() { ui->treeView->edit(currentIndex); });
272 break;
273 break;
273 case DATABASE_ITEM_TYPE:
274 case DATABASE_ITEM_TYPE:
274 break;
275 break;
275 case ALL_EVENT_ITEM_TYPE:
276 case ALL_EVENT_ITEM_TYPE:
276 break;
277 break;
277 case TRASH_ITEM_TYPE:
278 case TRASH_ITEM_TYPE:
278 menu.addAction("Empty Trash", []() {
279 menu.addAction("Empty Trash", []() {
279 // TODO
280 // TODO
280 });
281 });
281 break;
282 break;
282 default:
283 default:
283 break;
284 break;
284 }
285 }
285
286
286 if (!menu.isEmpty()) {
287 if (!menu.isEmpty()) {
287 menu.exec(ui->treeView->mapToGlobal(pos));
288 menu.exec(ui->treeView->mapToGlobal(pos));
288 }
289 }
289 }
290 }
290
291
291 void CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::configureTreeWidget(QTreeView *treeView)
292 void CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::configureTreeWidget(QTreeView *treeView)
292 {
293 {
293 auto allEventsItem = new CatalogueTextTreeItem{QIcon{":/icones/allEvents.png"}, "All Events",
294 auto allEventsItem = new CatalogueTextTreeItem{QIcon{":/icones/allEvents.png"}, "All Events",
294 ALL_EVENT_ITEM_TYPE};
295 ALL_EVENT_ITEM_TYPE};
295 auto allEventIndex = m_TreeModel->addTopLevelItem(allEventsItem);
296 auto allEventIndex = m_TreeModel->addTopLevelItem(allEventsItem);
296 treeView->setCurrentIndex(allEventIndex);
297 treeView->setCurrentIndex(allEventIndex);
297
298
298 auto trashItem
299 auto trashItem
299 = new CatalogueTextTreeItem{QIcon{":/icones/trash.png"}, "Trash", TRASH_ITEM_TYPE};
300 = new CatalogueTextTreeItem{QIcon{":/icones/trash.png"}, "Trash", TRASH_ITEM_TYPE};
300 m_TreeModel->addTopLevelItem(trashItem);
301 m_TreeModel->addTopLevelItem(trashItem);
301
302
302 auto separator = new QFrame{treeView};
303 auto separator = new QFrame{treeView};
303 separator->setFrameShape(QFrame::HLine);
304 separator->setFrameShape(QFrame::HLine);
304 auto separatorItem
305 auto separatorItem
305 = new CatalogueTextTreeItem{QIcon{}, QString{}, CatalogueAbstractTreeItem::DEFAULT_TYPE};
306 = new CatalogueTextTreeItem{QIcon{}, QString{}, CatalogueAbstractTreeItem::DEFAULT_TYPE};
306 separatorItem->setEnabled(false);
307 separatorItem->setEnabled(false);
307 auto separatorIndex = m_TreeModel->addTopLevelItem(separatorItem);
308 auto separatorIndex = m_TreeModel->addTopLevelItem(separatorItem);
308 treeView->setIndexWidget(separatorIndex, separator);
309 treeView->setIndexWidget(separatorIndex, separator);
309
310
310 auto repositories = sqpApp->catalogueController().getRepositories();
311 auto repositories = sqpApp->catalogueController().getRepositories();
311 for (auto dbname : repositories) {
312 for (auto dbname : repositories) {
312 auto dbIndex = addDatabaseItem(dbname);
313 auto dbIndex = addDatabaseItem(dbname);
313 auto catalogues = sqpApp->catalogueController().retrieveCatalogues(dbname);
314 auto catalogues = sqpApp->catalogueController().retrieveCatalogues(dbname);
314 for (auto catalogue : catalogues) {
315 for (auto catalogue : catalogues) {
315 addCatalogueItem(catalogue, dbIndex);
316 addCatalogueItem(catalogue, dbIndex);
316 }
317 }
317 }
318 }
318
319
319 treeView->expandAll();
320 treeView->expandAll();
320 }
321 }
321
322
322 QModelIndex
323 QModelIndex
323 CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::addDatabaseItem(const QString &name)
324 CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::addDatabaseItem(const QString &name)
324 {
325 {
325 auto databaseItem
326 auto databaseItem
326 = new CatalogueTextTreeItem{QIcon{":/icones/database.png"}, {name}, DATABASE_ITEM_TYPE};
327 = new CatalogueTextTreeItem{QIcon{":/icones/database.png"}, {name}, DATABASE_ITEM_TYPE};
327 auto databaseIndex = m_TreeModel->addTopLevelItem(databaseItem);
328 auto databaseIndex = m_TreeModel->addTopLevelItem(databaseItem);
328
329
329 return databaseIndex;
330 return databaseIndex;
330 }
331 }
331
332
332 CatalogueAbstractTreeItem *
333 CatalogueAbstractTreeItem *
333 CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::getDatabaseItem(const QString &name)
334 CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::getDatabaseItem(const QString &name)
334 {
335 {
335 for (auto item : m_TreeModel->topLevelItems()) {
336 for (auto item : m_TreeModel->topLevelItems()) {
336 if (item->type() == DATABASE_ITEM_TYPE && item->text() == name) {
337 if (item->type() == DATABASE_ITEM_TYPE && item->text() == name) {
337 return item;
338 return item;
338 }
339 }
339 }
340 }
340
341
341 return nullptr;
342 return nullptr;
342 }
343 }
343
344
344 CatalogueAbstractTreeItem *CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::addCatalogueItem(
345 CatalogueAbstractTreeItem *CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::addCatalogueItem(
345 const std::shared_ptr<DBCatalogue> &catalogue, const QModelIndex &databaseIndex)
346 const std::shared_ptr<DBCatalogue> &catalogue, const QModelIndex &databaseIndex)
346 {
347 {
347 auto catalogueItem
348 auto catalogueItem
348 = new CatalogueTreeItem{catalogue, QIcon{":/icones/catalogue.png"}, CATALOGUE_ITEM_TYPE};
349 = new CatalogueTreeItem{catalogue, QIcon{":/icones/catalogue.png"}, CATALOGUE_ITEM_TYPE};
349 m_TreeModel->addChildItem(catalogueItem, databaseIndex);
350 m_TreeModel->addChildItem(catalogueItem, databaseIndex);
350
351
351 return catalogueItem;
352 return catalogueItem;
352 }
353 }
353
354
354 CatalogueTreeItem *CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::getCatalogueItem(
355 CatalogueTreeItem *CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::getCatalogueItem(
355 const std::shared_ptr<DBCatalogue> &catalogue) const
356 const std::shared_ptr<DBCatalogue> &catalogue) const
356 {
357 {
357 for (auto item : m_TreeModel->topLevelItems()) {
358 for (auto item : m_TreeModel->topLevelItems()) {
358 if (item->type() == DATABASE_ITEM_TYPE) {
359 if (item->type() == DATABASE_ITEM_TYPE) {
359 for (auto childItem : item->children()) {
360 for (auto childItem : item->children()) {
360 if (childItem->type() == CATALOGUE_ITEM_TYPE) {
361 if (childItem->type() == CATALOGUE_ITEM_TYPE) {
361 auto catalogueItem = static_cast<CatalogueTreeItem *>(childItem);
362 auto catalogueItem = static_cast<CatalogueTreeItem *>(childItem);
362 if (catalogueItem->catalogue()->getUniqId() == catalogue->getUniqId()) {
363 if (catalogueItem->catalogue()->getUniqId() == catalogue->getUniqId()) {
363 return catalogueItem;
364 return catalogueItem;
364 }
365 }
365 }
366 }
366 else {
367 else {
367 qCWarning(LOG_CatalogueSideBarWidget()) << "getCatalogueItem: Invalid tree "
368 qCWarning(LOG_CatalogueSideBarWidget()) << "getCatalogueItem: Invalid tree "
368 "structure. A database item should "
369 "structure. A database item should "
369 "only contain catalogues.";
370 "only contain catalogues.";
370 Q_ASSERT(false);
371 Q_ASSERT(false);
371 }
372 }
372 }
373 }
373 }
374 }
374 }
375 }
375
376
376 return nullptr;
377 return nullptr;
377 }
378 }
378
379
379 void CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::setHasChanges(
380 void CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::setHasChanges(
380 bool value, const QModelIndex &index, CatalogueSideBarWidget *sideBarWidget)
381 bool value, const QModelIndex &index, CatalogueSideBarWidget *sideBarWidget)
381 {
382 {
382 std::shared_ptr<DBCatalogue> catalogue = nullptr;
383 std::shared_ptr<DBCatalogue> catalogue = nullptr;
383 auto item = m_TreeModel->item(index);
384 auto item = m_TreeModel->item(index);
384 if (item && item->type() == CATALOGUE_ITEM_TYPE) {
385 if (item && item->type() == CATALOGUE_ITEM_TYPE) {
385 catalogue = static_cast<CatalogueTreeItem *>(item)->catalogue();
386 catalogue = static_cast<CatalogueTreeItem *>(item)->catalogue();
386 }
387 }
387
388
388 auto validationIndex = index.sibling(index.row(), (int)CatalogueTreeModel::Column::Validation);
389 auto validationIndex = index.sibling(index.row(), (int)CatalogueTreeModel::Column::Validation);
389 if (value) {
390 if (value) {
390 if (!hasChanges(validationIndex, sideBarWidget->ui->treeView)) {
391 if (!hasChanges(validationIndex, sideBarWidget->ui->treeView)) {
391 auto widget = CatalogueExplorerHelper::buildValidationWidget(
392 auto widget = CatalogueExplorerHelper::buildValidationWidget(
392 sideBarWidget->ui->treeView,
393 sideBarWidget->ui->treeView,
393 [this, validationIndex, sideBarWidget, catalogue]() {
394 [this, validationIndex, sideBarWidget, catalogue]() {
394 if (catalogue) {
395 if (catalogue) {
395 sqpApp->catalogueController().saveCatalogue(catalogue);
396 sqpApp->catalogueController().saveCatalogue(catalogue);
396 }
397 }
397 setHasChanges(false, validationIndex, sideBarWidget);
398 setHasChanges(false, validationIndex, sideBarWidget);
398 },
399 },
399 [this, validationIndex, sideBarWidget, catalogue, item]() {
400 [this, validationIndex, sideBarWidget, catalogue, item]() {
400 if (catalogue) {
401 if (catalogue) {
401 bool removed;
402 bool removed;
402 sqpApp->catalogueController().discardCatalogue(catalogue, removed);
403 sqpApp->catalogueController().discardCatalogue(catalogue, removed);
403
404
404 if (removed) {
405 if (removed) {
405 m_TreeModel->removeChildItem(item,
406 m_TreeModel->removeChildItem(item,
406 m_TreeModel->indexOf(item->parent()));
407 m_TreeModel->indexOf(item->parent()));
407 }
408 }
408 else {
409 else {
409 m_TreeModel->refresh(m_TreeModel->indexOf(item));
410 m_TreeModel->refresh(m_TreeModel->indexOf(item));
410 setHasChanges(false, validationIndex, sideBarWidget);
411 setHasChanges(false, validationIndex, sideBarWidget);
411 }
412 }
412 sideBarWidget->emitSelection();
413 sideBarWidget->emitSelection();
413 }
414 }
414 });
415 });
415 sideBarWidget->ui->treeView->setIndexWidget(validationIndex, widget);
416 sideBarWidget->ui->treeView->setIndexWidget(validationIndex, widget);
416 }
417 }
417 }
418 }
418 else {
419 else {
419 // Note: the widget is destroyed
420 // Note: the widget is destroyed
420 sideBarWidget->ui->treeView->setIndexWidget(validationIndex, nullptr);
421 sideBarWidget->ui->treeView->setIndexWidget(validationIndex, nullptr);
421 }
422 }
422 }
423 }
423
424
424 bool CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::hasChanges(const QModelIndex &index,
425 bool CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::hasChanges(const QModelIndex &index,
425 QTreeView *treeView)
426 QTreeView *treeView)
426 {
427 {
427 auto validationIndex = index.sibling(index.row(), (int)CatalogueTreeModel::Column::Validation);
428 auto validationIndex = index.sibling(index.row(), (int)CatalogueTreeModel::Column::Validation);
428 return treeView->indexWidget(validationIndex) != nullptr;
429 return treeView->indexWidget(validationIndex) != nullptr;
429 }
430 }
431
432
433 void CatalogueSideBarWidget::keyPressEvent(QKeyEvent *event)
434 {
435 switch (event->key()) {
436 case Qt::Key_Delete: {
437 ui->btnRemove->click();
438 }
439 default:
440 break;
441 }
442 }
General Comments 0
You need to be logged in to leave comments. Login now