##// END OF EJS Templates
Merge branch 'feature/CatalogueGuiPart3' into develop
trabillard -
r1165:c3afe020c8f9 merge
parent child
Show More
@@ -0,0 +1,17
1 #ifndef SCIQLOP_CATALOGUEACTIONMANAGER_H
2 #define SCIQLOP_CATALOGUEACTIONMANAGER_H
3
4 #include <Common/spimpl.h>
5
6 class CatalogueActionManager {
7 public:
8 CatalogueActionManager();
9
10 void installSelectionZoneActions();
11
12 private:
13 class CatalogueActionManagerPrivate;
14 spimpl::unique_impl_ptr<CatalogueActionManagerPrivate> impl;
15 };
16
17 #endif // SCIQLOP_CATALOGUEACTIONMANAGER_H
@@ -0,0 +1,13
1 #ifndef SCIQLOP_CATALOGUEEXPLORERHELPER_H
2 #define SCIQLOP_CATALOGUEEXPLORERHELPER_H
3
4 #include <QWidget>
5
6 #include <functional>
7
8 struct CatalogueExplorerHelper {
9 static QWidget *buildValidationWidget(QWidget *parent, std::function<void()> save,
10 std::function<void()> discard);
11 };
12
13 #endif // SCIQLOP_CATALOGUEEXPLORERHELPER_H
@@ -0,0 +1,35
1 #ifndef SCIQLOP_CREATEEVENTDIALOG_H
2 #define SCIQLOP_CREATEEVENTDIALOG_H
3
4 #include <Common/spimpl.h>
5 #include <QDialog>
6 #include <memory>
7
8 namespace Ui {
9 class CreateEventDialog;
10 }
11
12 class DBCatalogue;
13
14 class CreateEventDialog : public QDialog {
15 Q_OBJECT
16
17 public:
18 explicit CreateEventDialog(QWidget *parent = 0);
19 virtual ~CreateEventDialog();
20
21 void hideCatalogueChoice();
22
23 QString eventName() const;
24
25 std::shared_ptr<DBCatalogue> selectedCatalogue() const;
26 QString catalogueName() const;
27
28 private:
29 Ui::CreateEventDialog *ui;
30
31 class CreateEventDialogPrivate;
32 spimpl::unique_impl_ptr<CreateEventDialogPrivate> impl;
33 };
34
35 #endif // SCIQLOP_CREATEEVENTDIALOG_H
@@ -0,0 +1,107
1 #include "Catalogue/CatalogueActionManager.h"
2
3 #include <Actions/ActionsGuiController.h>
4 #include <Catalogue/CatalogueController.h>
5 #include <SqpApplication.h>
6 #include <Variable/Variable.h>
7 #include <Visualization/VisualizationGraphWidget.h>
8 #include <Visualization/VisualizationSelectionZoneItem.h>
9
10 #include <Catalogue/CreateEventDialog.h>
11
12 #include <DBCatalogue.h>
13 #include <DBEvent.h>
14 #include <DBEventProduct.h>
15
16 #include <QBoxLayout>
17 #include <QComboBox>
18 #include <QDialog>
19 #include <QDialogButtonBox>
20 #include <QLineEdit>
21 #include <memory>
22
23 struct CatalogueActionManager::CatalogueActionManagerPrivate {
24 void createEventFromZones(const QString &eventName,
25 const QVector<VisualizationSelectionZoneItem *> &zones,
26 const std::shared_ptr<DBCatalogue> &catalogue = nullptr)
27 {
28 auto event = std::make_shared<DBEvent>();
29 event->setName(eventName);
30
31 std::list<DBEventProduct> productList;
32 for (auto zone : zones) {
33 auto graph = zone->parentGraphWidget();
34 for (auto var : graph->variables()) {
35 auto eventProduct = std::make_shared<DBEventProduct>();
36 eventProduct->setEvent(*event);
37
38 auto zoneRange = zone->range();
39 eventProduct->setTStart(zoneRange.m_TStart);
40 eventProduct->setTEnd(zoneRange.m_TEnd);
41
42 eventProduct->setProductId(var->metadata().value("id", "TODO").toString()); // todo
43
44 productList.push_back(*eventProduct);
45 }
46 }
47
48 event->setEventProducts(productList);
49
50 sqpApp->catalogueController().addEvent(event);
51
52 if (catalogue) {
53 // TODO
54 // catalogue->addEvent(event);
55 }
56 }
57 };
58
59 CatalogueActionManager::CatalogueActionManager()
60 : impl{spimpl::make_unique_impl<CatalogueActionManagerPrivate>()}
61 {
62 }
63
64 void CatalogueActionManager::installSelectionZoneActions()
65 {
66 auto &actionController = sqpApp->actionsGuiController();
67
68 auto createEventEnableFuntion = [](auto zones) {
69 QSet<VisualizationGraphWidget *> usedGraphs;
70 for (auto zone : zones) {
71 auto graph = zone->parentGraphWidget();
72 if (!usedGraphs.contains(graph)) {
73 usedGraphs.insert(graph);
74 }
75 else {
76 return false;
77 }
78 }
79
80 return true;
81 };
82
83 auto createEventAction = actionController.addSectionZoneAction(
84 {QObject::tr("Catalogues")}, QObject::tr("New Event..."), [this](auto zones) {
85 CreateEventDialog dialog;
86 dialog.hideCatalogueChoice();
87 if (dialog.exec() == QDialog::Accepted) {
88 impl->createEventFromZones(dialog.eventName(), zones);
89 }
90 });
91 createEventAction->setEnableFunction(createEventEnableFuntion);
92
93 auto createEventInCatalogueAction = actionController.addSectionZoneAction(
94 {QObject::tr("Catalogues")}, QObject::tr("New Event in Catalogue..."), [this](auto zones) {
95 CreateEventDialog dialog;
96 if (dialog.exec() == QDialog::Accepted) {
97 auto selectedCatalogue = dialog.selectedCatalogue();
98 if (!selectedCatalogue) {
99 selectedCatalogue = std::make_shared<DBCatalogue>();
100 selectedCatalogue->setName(dialog.catalogueName());
101 }
102
103 impl->createEventFromZones(dialog.eventName(), zones, selectedCatalogue);
104 }
105 });
106 createEventInCatalogueAction->setEnableFunction(createEventEnableFuntion);
107 }
@@ -0,0 +1,32
1 #include "Catalogue/CatalogueExplorerHelper.h"
2
3 #include <QBoxLayout>
4 #include <QToolButton>
5
6 const auto VALIDATION_BUTTON_ICON_SIZE = 12;
7
8 QWidget *CatalogueExplorerHelper::buildValidationWidget(QWidget *parent, std::function<void()> save,
9 std::function<void()> discard)
10 {
11 auto widget = new QWidget{parent};
12
13 auto layout = new QHBoxLayout{widget};
14 layout->setContentsMargins(0, 0, 0, 0);
15 layout->setSpacing(0);
16
17 auto btnValid = new QToolButton{widget};
18 btnValid->setIcon(QIcon{":/icones/save"});
19 btnValid->setIconSize(QSize{VALIDATION_BUTTON_ICON_SIZE, VALIDATION_BUTTON_ICON_SIZE});
20 btnValid->setAutoRaise(true);
21 QObject::connect(btnValid, &QToolButton::clicked, save);
22 layout->addWidget(btnValid);
23
24 auto btnDiscard = new QToolButton{widget};
25 btnDiscard->setIcon(QIcon{":/icones/discard"});
26 btnDiscard->setIconSize(QSize{VALIDATION_BUTTON_ICON_SIZE, VALIDATION_BUTTON_ICON_SIZE});
27 btnDiscard->setAutoRaise(true);
28 QObject::connect(btnDiscard, &QToolButton::clicked, discard);
29 layout->addWidget(btnDiscard);
30
31 return widget;
32 }
@@ -0,0 +1,59
1 #include "Catalogue/CreateEventDialog.h"
2 #include "ui_CreateEventDialog.h"
3
4 #include <Catalogue/CatalogueController.h>
5 #include <SqpApplication.h>
6
7 #include <DBCatalogue.h>
8
9 struct CreateEventDialog::CreateEventDialogPrivate {
10 QVector<std::shared_ptr<DBCatalogue> > m_DisplayedCatalogues;
11 };
12
13 CreateEventDialog::CreateEventDialog(QWidget *parent)
14 : QDialog(parent),
15 ui(new Ui::CreateEventDialog),
16 impl{spimpl::make_unique_impl<CreateEventDialogPrivate>()}
17 {
18 ui->setupUi(this);
19
20 connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
21 connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
22
23 auto catalogues = sqpApp->catalogueController().retrieveCatalogues();
24 for (auto cat : catalogues) {
25 ui->cbCatalogue->addItem(cat->getName());
26 impl->m_DisplayedCatalogues << cat;
27 }
28 }
29
30 CreateEventDialog::~CreateEventDialog()
31 {
32 delete ui;
33 }
34
35 void CreateEventDialog::hideCatalogueChoice()
36 {
37 ui->cbCatalogue->hide();
38 ui->lblCatalogue->hide();
39 }
40
41 QString CreateEventDialog::eventName() const
42 {
43 return ui->leEvent->text();
44 }
45
46 std::shared_ptr<DBCatalogue> CreateEventDialog::selectedCatalogue() const
47 {
48 auto catalogue = impl->m_DisplayedCatalogues.value(ui->cbCatalogue->currentIndex());
49 if (!catalogue || catalogue->getName() != catalogueName()) {
50 return nullptr;
51 }
52
53 return catalogue;
54 }
55
56 QString CreateEventDialog::catalogueName() const
57 {
58 return ui->cbCatalogue->currentText();
59 }
@@ -0,0 +1,55
1 <?xml version="1.0" encoding="UTF-8"?>
2 <ui version="4.0">
3 <class>CreateEventDialog</class>
4 <widget class="QDialog" name="CreateEventDialog">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>324</width>
10 <height>93</height>
11 </rect>
12 </property>
13 <property name="windowTitle">
14 <string>New Event</string>
15 </property>
16 <layout class="QGridLayout" name="gridLayout">
17 <item row="0" column="0">
18 <widget class="QLabel" name="label">
19 <property name="text">
20 <string>Event Name</string>
21 </property>
22 </widget>
23 </item>
24 <item row="0" column="1">
25 <widget class="QLineEdit" name="leEvent"/>
26 </item>
27 <item row="1" column="0">
28 <widget class="QLabel" name="lblCatalogue">
29 <property name="text">
30 <string>Catalogue</string>
31 </property>
32 </widget>
33 </item>
34 <item row="1" column="1">
35 <widget class="QComboBox" name="cbCatalogue">
36 <property name="editable">
37 <bool>true</bool>
38 </property>
39 <property name="insertPolicy">
40 <enum>QComboBox::NoInsert</enum>
41 </property>
42 </widget>
43 </item>
44 <item row="2" column="0" colspan="2">
45 <widget class="QDialogButtonBox" name="buttonBox">
46 <property name="standardButtons">
47 <set>QDialogButtonBox::Ok</set>
48 </property>
49 </widget>
50 </item>
51 </layout>
52 </widget>
53 <resources/>
54 <connections/>
55 </ui>
@@ -52,7 +52,8 public:
52 // Catalogue
52 // Catalogue
53 // bool createCatalogue(const QString &name, QVector<QUuid> eventList);
53 // bool createCatalogue(const QString &name, QVector<QUuid> eventList);
54 /// retrieveEvents with empty repository retrieve them from the default repository
54 /// retrieveEvents with empty repository retrieve them from the default repository
55 std::list<std::shared_ptr<DBCatalogue> > retrieveCatalogues(const QString &repository) const;
55 std::list<std::shared_ptr<DBCatalogue> > retrieveCatalogues(const QString &repository
56 = QString()) const;
56 void updateCatalogue(std::shared_ptr<DBCatalogue> catalogue);
57 void updateCatalogue(std::shared_ptr<DBCatalogue> catalogue);
57 void removeCatalogue(std::shared_ptr<DBCatalogue> catalogue);
58 void removeCatalogue(std::shared_ptr<DBCatalogue> catalogue);
58 void saveCatalogue(std::shared_ptr<DBCatalogue> catalogue);
59 void saveCatalogue(std::shared_ptr<DBCatalogue> catalogue);
@@ -148,7 +148,7 void CatalogueController::removeEvent(std::shared_ptr<DBEvent> event)
148
148
149 void CatalogueController::addEvent(std::shared_ptr<DBEvent> event)
149 void CatalogueController::addEvent(std::shared_ptr<DBEvent> event)
150 {
150 {
151 event->setRepository(impl->toSyncRepository(event->getRepository()));
151 event->setRepository(impl->toWorkRepository(event->getRepository()));
152
152
153 impl->m_CatalogueDao.addEvent(*event);
153 impl->m_CatalogueDao.addEvent(*event);
154
154
@@ -255,14 +255,23 void CatalogueController::waitForFinish()
255 void CatalogueController::CatalogueControllerPrivate::copyDBtoDB(const QString &dbFrom,
255 void CatalogueController::CatalogueControllerPrivate::copyDBtoDB(const QString &dbFrom,
256 const QString &dbTo)
256 const QString &dbTo)
257 {
257 {
258 auto catalogues = m_Q->retrieveCatalogues(dbFrom);
258 auto cataloguesShared = std::list<std::shared_ptr<DBCatalogue> >{};
259 auto events = m_Q->retrieveEvents(dbFrom);
259 auto catalogues = m_CatalogueDao.getCatalogues(dbFrom);
260
261 for (auto catalogue : catalogues) {
260 for (auto catalogue : catalogues) {
262 m_CatalogueDao.copyCatalogue(*catalogue, dbTo, true);
261 cataloguesShared.push_back(std::make_shared<DBCatalogue>(catalogue));
263 }
262 }
264
263
264 auto eventsShared = std::list<std::shared_ptr<DBEvent> >{};
265 auto events = m_CatalogueDao.getEvents(dbFrom);
265 for (auto event : events) {
266 for (auto event : events) {
267 eventsShared.push_back(std::make_shared<DBEvent>(event));
268 }
269
270 for (auto catalogue : cataloguesShared) {
271 m_CatalogueDao.copyCatalogue(*catalogue, dbTo, true);
272 }
273
274 for (auto event : eventsShared) {
266 m_CatalogueDao.copyEvent(*event, dbTo, true);
275 m_CatalogueDao.copyEvent(*event, dbTo, true);
267 }
276 }
268 }
277 }
@@ -3,17 +3,29
3
3
4 #include <Common/spimpl.h>
4 #include <Common/spimpl.h>
5 #include <QAbstractItemModel>
5 #include <QAbstractItemModel>
6 #include <QLoggingCategory>
7 #include <unordered_set>
6
8
7 class DBEvent;
9 class DBEvent;
8 class DBEventProduct;
10 class DBEventProduct;
9
11
12 Q_DECLARE_LOGGING_CATEGORY(LOG_CatalogueEventsModel)
13
10 class CatalogueEventsModel : public QAbstractItemModel {
14 class CatalogueEventsModel : public QAbstractItemModel {
15 Q_OBJECT
16
17 signals:
18 void modelSorted();
19
11 public:
20 public:
12 CatalogueEventsModel(QObject *parent = nullptr);
21 CatalogueEventsModel(QObject *parent = nullptr);
13
22
23 enum class Column { Name, TStart, TEnd, Tags, Product, Validation, NbColumn };
24
14 void setEvents(const QVector<std::shared_ptr<DBEvent> > &events);
25 void setEvents(const QVector<std::shared_ptr<DBEvent> > &events);
15 void addEvent(const std::shared_ptr<DBEvent> &event);
26 void addEvent(const std::shared_ptr<DBEvent> &event);
16 void removeEvent(const std::shared_ptr<DBEvent> &event);
27 void removeEvent(const std::shared_ptr<DBEvent> &event);
28 QVector<std::shared_ptr<DBEvent> > events() const;
17
29
18 enum class ItemType { Root, Event, EventProduct };
30 enum class ItemType { Root, Event, EventProduct };
19 ItemType itemTypeOf(const QModelIndex &index) const;
31 ItemType itemTypeOf(const QModelIndex &index) const;
@@ -21,8 +33,18 public:
21 std::shared_ptr<DBEvent> getParentEvent(const QModelIndex &index) const;
33 std::shared_ptr<DBEvent> getParentEvent(const QModelIndex &index) const;
22 std::shared_ptr<DBEventProduct> getEventProduct(const QModelIndex &index) const;
34 std::shared_ptr<DBEventProduct> getEventProduct(const QModelIndex &index) const;
23
35
36 /// Refresh the data for the specified event
24 void refreshEvent(const std::shared_ptr<DBEvent> &event);
37 void refreshEvent(const std::shared_ptr<DBEvent> &event);
25
38
39 /// Returns a QModelIndex which represent the specified event
40 QModelIndex indexOf(const std::shared_ptr<DBEvent> &event) const;
41
42 /// Marks a change flag on the specified event to allow sorting on the validation column
43 void setEventHasChanges(const std::shared_ptr<DBEvent> &event, bool hasChanges);
44
45 /// Returns true if the specified event has unsaved changes
46 bool eventsHasChanges(const std::shared_ptr<DBEvent> &event) const;
47
26 // Model
48 // Model
27 QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
49 QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
28 QModelIndex parent(const QModelIndex &index) const;
50 QModelIndex parent(const QModelIndex &index) const;
@@ -36,6 +36,7 public:
36
36
37 public slots:
37 public slots:
38 void populateWithCatalogues(const QVector<std::shared_ptr<DBCatalogue> > &catalogues);
38 void populateWithCatalogues(const QVector<std::shared_ptr<DBCatalogue> > &catalogues);
39 void populateWithAllEvents();
39
40
40 private:
41 private:
41 Ui::CatalogueEventsWidget *ui;
42 Ui::CatalogueEventsWidget *ui;
@@ -22,6 +22,9 public:
22 /// changes
22 /// changes
23 void setHasChanges(bool value);
23 void setHasChanges(bool value);
24
24
25 /// Returns true if the widget indicating the event has unsaved changes is displayed
26 bool hasChanges();
27
25 /// Refreshes the data displayed by the item from the catalogue
28 /// Refreshes the data displayed by the item from the catalogue
26 void refresh();
29 void refresh();
27
30
@@ -25,7 +25,9 gui_moc_headers = [
25 'include/Catalogue/CatalogueExplorer.h',
25 'include/Catalogue/CatalogueExplorer.h',
26 'include/Catalogue/CatalogueEventsWidget.h',
26 'include/Catalogue/CatalogueEventsWidget.h',
27 'include/Catalogue/CatalogueSideBarWidget.h',
27 'include/Catalogue/CatalogueSideBarWidget.h',
28 'include/Catalogue/CatalogueInspectorWidget.h'
28 'include/Catalogue/CatalogueInspectorWidget.h',
29 'include/Catalogue/CatalogueEventsModel.h',
30 'include/Catalogue/CreateEventDialog.ui'
29 ]
31 ]
30
32
31 gui_ui_files = [
33 gui_ui_files = [
@@ -46,7 +48,8 gui_ui_files = [
46 'ui/Catalogue/CatalogueExplorer.ui',
48 'ui/Catalogue/CatalogueExplorer.ui',
47 'ui/Catalogue/CatalogueEventsWidget.ui',
49 'ui/Catalogue/CatalogueEventsWidget.ui',
48 'ui/Catalogue/CatalogueSideBarWidget.ui',
50 'ui/Catalogue/CatalogueSideBarWidget.ui',
49 'ui/Catalogue/CatalogueInspectorWidget.ui'
51 'ui/Catalogue/CatalogueInspectorWidget.ui',
52 'ui/Catalogue/CreateEventDialog.ui'
50 ]
53 ]
51
54
52 gui_qresources = ['resources/sqpguiresources.qrc']
55 gui_qresources = ['resources/sqpguiresources.qrc']
@@ -116,7 +119,10 gui_sources = [
116 'src/Catalogue/CatalogueSideBarWidget.cpp',
119 'src/Catalogue/CatalogueSideBarWidget.cpp',
117 'src/Catalogue/CatalogueInspectorWidget.cpp',
120 'src/Catalogue/CatalogueInspectorWidget.cpp',
118 'src/Catalogue/CatalogueTreeWidgetItem.cpp',
121 'src/Catalogue/CatalogueTreeWidgetItem.cpp',
119 'src/Catalogue/CatalogueEventsModel.cpp'
122 'src/Catalogue/CatalogueEventsModel.cpp',
123 'src/Catalogue/CatalogueExplorerHelper.cpp',
124 'src/Catalogue/CatalogueActionManager.cpp',
125 'src/Catalogue/CreateEventDialog.cpp'
120 ]
126 ]
121
127
122 gui_inc = include_directories(['include'])
128 gui_inc = include_directories(['include'])
@@ -15,38 +15,46
15 #include <QHash>
15 #include <QHash>
16 #include <QMimeData>
16 #include <QMimeData>
17
17
18 Q_LOGGING_CATEGORY(LOG_CatalogueEventsModel, "CatalogueEventsModel")
19
18 const auto EVENT_ITEM_TYPE = 1;
20 const auto EVENT_ITEM_TYPE = 1;
19 const auto EVENT_PRODUCT_ITEM_TYPE = 2;
21 const auto EVENT_PRODUCT_ITEM_TYPE = 2;
20
22
21 struct CatalogueEventsModel::CatalogueEventsModelPrivate {
23 struct CatalogueEventsModel::CatalogueEventsModelPrivate {
22 QVector<std::shared_ptr<DBEvent> > m_Events;
24 QVector<std::shared_ptr<DBEvent> > m_Events;
23 std::unordered_map<DBEvent *, QVector<std::shared_ptr<DBEventProduct> > > m_EventProducts;
25 std::unordered_map<DBEvent *, QVector<std::shared_ptr<DBEventProduct> > > m_EventProducts;
26 std::unordered_set<std::shared_ptr<DBEvent> > m_EventsWithChanges;
24
27
25 enum class Column { Name, TStart, TEnd, Tags, Product, NbColumn };
26 QStringList columnNames()
28 QStringList columnNames()
27 {
29 {
28 return QStringList{tr("Event"), tr("TStart"), tr("TEnd"), tr("Tags"), tr("Product")};
30 return QStringList{tr("Event"), tr("TStart"), tr("TEnd"),
31 tr("Tags"), tr("Product"), tr("")};
32 }
33
34 QVariant sortData(int col, const std::shared_ptr<DBEvent> &event) const
35 {
36 if (col == (int)CatalogueEventsModel::Column::Validation) {
37 return m_EventsWithChanges.find(event) != m_EventsWithChanges.cend() ? true
38 : QVariant();
39 }
40
41 return eventData(col, event);
29 }
42 }
30
43
31 QVariant eventData(int col, const std::shared_ptr<DBEvent> &event) const
44 QVariant eventData(int col, const std::shared_ptr<DBEvent> &event) const
32 {
45 {
33 switch (static_cast<Column>(col)) {
46 switch (static_cast<Column>(col)) {
34 case Column::Name:
47 case CatalogueEventsModel::Column::Name:
35 return event->getName();
48 return event->getName();
36 case Column::TStart:
49 case CatalogueEventsModel::Column::TStart:
37 return DateUtils::dateTime(event->getTStart());
50 return nbEventProducts(event) > 0 ? DateUtils::dateTime(event->getTStart())
38 case Column::TEnd:
51 : QVariant{};
39 return DateUtils::dateTime(event->getTEnd());
52 case CatalogueEventsModel::Column::TEnd:
40 case Column::Product: {
53 return nbEventProducts(event) > 0 ? DateUtils::dateTime(event->getTEnd())
41 auto eventProductsIt = m_EventProducts.find(event.get());
54 : QVariant{};
42 if (eventProductsIt != m_EventProducts.cend()) {
55 case CatalogueEventsModel::Column::Product:
43 return QString::number(m_EventProducts.at(event.get()).count()) + " product(s)";
56 return QString::number(nbEventProducts(event)) + " product(s)";
44 }
57 case CatalogueEventsModel::Column::Tags: {
45 else {
46 return "0 product";
47 }
48 }
49 case Column::Tags: {
50 QString tagList;
58 QString tagList;
51 auto tags = event->getTags();
59 auto tags = event->getTags();
52 for (auto tag : tags) {
60 for (auto tag : tags) {
@@ -56,6 +64,8 struct CatalogueEventsModel::CatalogueEventsModelPrivate {
56
64
57 return tagList;
65 return tagList;
58 }
66 }
67 case CatalogueEventsModel::Column::Validation:
68 return QVariant();
59 default:
69 default:
60 break;
70 break;
61 }
71 }
@@ -71,20 +81,32 struct CatalogueEventsModel::CatalogueEventsModelPrivate {
71 }
81 }
72 }
82 }
73
83
84 int nbEventProducts(const std::shared_ptr<DBEvent> &event) const
85 {
86 auto eventProductsIt = m_EventProducts.find(event.get());
87 if (eventProductsIt != m_EventProducts.cend()) {
88 return m_EventProducts.at(event.get()).count();
89 }
90 else {
91 return 0;
92 }
93 }
94
74 QVariant eventProductData(int col, const std::shared_ptr<DBEventProduct> &eventProduct) const
95 QVariant eventProductData(int col, const std::shared_ptr<DBEventProduct> &eventProduct) const
75 {
96 {
76 switch (static_cast<Column>(col)) {
97 switch (static_cast<Column>(col)) {
77 case Column::Name:
98 case CatalogueEventsModel::Column::Name:
78 return eventProduct->getProductId();
99 return eventProduct->getProductId();
79 case Column::TStart:
100 case CatalogueEventsModel::Column::TStart:
80 return DateUtils::dateTime(eventProduct->getTStart());
101 return DateUtils::dateTime(eventProduct->getTStart());
81 case Column::TEnd:
102 case CatalogueEventsModel::Column::TEnd:
82 return DateUtils::dateTime(eventProduct->getTEnd());
103 return DateUtils::dateTime(eventProduct->getTEnd());
83 case Column::Product:
104 case CatalogueEventsModel::Column::Product:
84 return eventProduct->getProductId();
105 return eventProduct->getProductId();
85 case Column::Tags: {
106 case CatalogueEventsModel::Column::Tags:
86 return QString();
107 return QString();
87 }
108 case CatalogueEventsModel::Column::Validation:
109 return QVariant();
88 default:
110 default:
89 break;
111 break;
90 }
112 }
@@ -105,6 +127,7 void CatalogueEventsModel::setEvents(const QVector<std::shared_ptr<DBEvent> > &e
105
127
106 impl->m_Events = events;
128 impl->m_Events = events;
107 impl->m_EventProducts.clear();
129 impl->m_EventProducts.clear();
130 impl->m_EventsWithChanges.clear();
108 for (auto event : events) {
131 for (auto event : events) {
109 impl->parseEventProduct(event);
132 impl->parseEventProduct(event);
110 }
133 }
@@ -159,21 +182,58 void CatalogueEventsModel::removeEvent(const std::shared_ptr<DBEvent> &event)
159 beginRemoveRows(QModelIndex(), index, index);
182 beginRemoveRows(QModelIndex(), index, index);
160 impl->m_Events.removeAt(index);
183 impl->m_Events.removeAt(index);
161 impl->m_EventProducts.erase(event.get());
184 impl->m_EventProducts.erase(event.get());
185 impl->m_EventsWithChanges.erase(event);
162 endRemoveRows();
186 endRemoveRows();
163 }
187 }
164 }
188 }
165
189
190 QVector<std::shared_ptr<DBEvent> > CatalogueEventsModel::events() const
191 {
192 return impl->m_Events;
193 }
194
166 void CatalogueEventsModel::refreshEvent(const std::shared_ptr<DBEvent> &event)
195 void CatalogueEventsModel::refreshEvent(const std::shared_ptr<DBEvent> &event)
167 {
196 {
168 auto i = impl->m_Events.indexOf(event);
197 auto eventIndex = indexOf(event);
169 if (i >= 0) {
198 if (eventIndex.isValid()) {
170 auto eventIndex = index(i, 0);
199
200 // Refreshes the event line
171 auto colCount = columnCount();
201 auto colCount = columnCount();
172 emit dataChanged(eventIndex, index(i, colCount));
202 emit dataChanged(eventIndex, index(eventIndex.row(), colCount));
173
203
204 // Also refreshes its children event products
174 auto childCount = rowCount(eventIndex);
205 auto childCount = rowCount(eventIndex);
175 emit dataChanged(index(0, 0, eventIndex), index(childCount, colCount, eventIndex));
206 emit dataChanged(index(0, 0, eventIndex), index(childCount, colCount, eventIndex));
176 }
207 }
208 else {
209 qCWarning(LOG_CatalogueEventsModel()) << "refreshEvent: event not found.";
210 }
211 }
212
213 QModelIndex CatalogueEventsModel::indexOf(const std::shared_ptr<DBEvent> &event) const
214 {
215 auto row = impl->m_Events.indexOf(event);
216 if (row >= 0) {
217 return index(row, 0);
218 }
219
220 return QModelIndex();
221 }
222
223 void CatalogueEventsModel::setEventHasChanges(const std::shared_ptr<DBEvent> &event,
224 bool hasChanges)
225 {
226 if (hasChanges) {
227 impl->m_EventsWithChanges.insert(event);
228 }
229 else {
230 impl->m_EventsWithChanges.erase(event);
231 }
232 }
233
234 bool CatalogueEventsModel::eventsHasChanges(const std::shared_ptr<DBEvent> &event) const
235 {
236 return impl->m_EventsWithChanges.find(event) != impl->m_EventsWithChanges.cend();
177 }
237 }
178
238
179 QModelIndex CatalogueEventsModel::index(int row, int column, const QModelIndex &parent) const
239 QModelIndex CatalogueEventsModel::index(int row, int column, const QModelIndex &parent) const
@@ -249,7 +309,7 int CatalogueEventsModel::rowCount(const QModelIndex &parent) const
249
309
250 int CatalogueEventsModel::columnCount(const QModelIndex &parent) const
310 int CatalogueEventsModel::columnCount(const QModelIndex &parent) const
251 {
311 {
252 return static_cast<int>(CatalogueEventsModelPrivate::Column::NbColumn);
312 return static_cast<int>(CatalogueEventsModel::Column::NbColumn);
253 }
313 }
254
314
255 Qt::ItemFlags CatalogueEventsModel::flags(const QModelIndex &index) const
315 Qt::ItemFlags CatalogueEventsModel::flags(const QModelIndex &index) const
@@ -296,8 +356,8 void CatalogueEventsModel::sort(int column, Qt::SortOrder order)
296 {
356 {
297 std::sort(impl->m_Events.begin(), impl->m_Events.end(),
357 std::sort(impl->m_Events.begin(), impl->m_Events.end(),
298 [this, column, order](auto e1, auto e2) {
358 [this, column, order](auto e1, auto e2) {
299 auto data1 = impl->eventData(column, e1);
359 auto data1 = impl->sortData(column, e1);
300 auto data2 = impl->eventData(column, e2);
360 auto data2 = impl->sortData(column, e2);
301
361
302 auto result = data1.toString() < data2.toString();
362 auto result = data1.toString() < data2.toString();
303
363
@@ -305,6 +365,7 void CatalogueEventsModel::sort(int column, Qt::SortOrder order)
305 });
365 });
306
366
307 emit dataChanged(QModelIndex(), QModelIndex());
367 emit dataChanged(QModelIndex(), QModelIndex());
368 emit modelSorted();
308 }
369 }
309
370
310 Qt::DropActions CatalogueEventsModel::supportedDragActions() const
371 Qt::DropActions CatalogueEventsModel::supportedDragActions() const
@@ -3,6 +3,7
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 <CatalogueDao.h>
7 #include <CatalogueDao.h>
7 #include <DBCatalogue.h>
8 #include <DBCatalogue.h>
8 #include <SqpApplication.h>
9 #include <SqpApplication.h>
@@ -16,8 +17,8
16
17
17 Q_LOGGING_CATEGORY(LOG_CatalogueEventsWidget, "CatalogueEventsWidget")
18 Q_LOGGING_CATEGORY(LOG_CatalogueEventsWidget, "CatalogueEventsWidget")
18
19
19 /// Format of the dates appearing in the label of a cursor
20 /// Fixed size of the validation column
20 const auto DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd hh:mm:ss");
21 const auto VALIDATION_COLUMN_SIZE = 35;
21
22
22 struct CatalogueEventsWidget::CatalogueEventsWidgetPrivate {
23 struct CatalogueEventsWidget::CatalogueEventsWidgetPrivate {
23
24
@@ -277,8 +278,20 CatalogueEventsWidget::CatalogueEventsWidget(QWidget *parent)
277 });
278 });
278
279
279 ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
280 ui->treeView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
280 ui->treeView->header()->setSectionResizeMode(0, QHeaderView::Stretch);
281 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Name,
282 QHeaderView::Stretch);
283 ui->treeView->header()->setSectionResizeMode((int)CatalogueEventsModel::Column::Validation,
284 QHeaderView::Fixed);
285 ui->treeView->header()->resizeSection((int)CatalogueEventsModel::Column::Validation,
286 VALIDATION_COLUMN_SIZE);
281 ui->treeView->header()->setSortIndicatorShown(true);
287 ui->treeView->header()->setSortIndicatorShown(true);
288
289 connect(impl->m_Model, &CatalogueEventsModel::modelSorted, [this]() {
290 auto allEvents = impl->m_Model->events();
291 for (auto event : allEvents) {
292 setEventChanges(event, impl->m_Model->eventsHasChanges(event));
293 }
294 });
282 }
295 }
283
296
284 CatalogueEventsWidget::~CatalogueEventsWidget()
297 CatalogueEventsWidget::~CatalogueEventsWidget()
@@ -294,6 +307,25 void CatalogueEventsWidget::setVisualizationWidget(VisualizationWidget *visualiz
294 void CatalogueEventsWidget::setEventChanges(const std::shared_ptr<DBEvent> &event, bool hasChanges)
307 void CatalogueEventsWidget::setEventChanges(const std::shared_ptr<DBEvent> &event, bool hasChanges)
295 {
308 {
296 impl->m_Model->refreshEvent(event);
309 impl->m_Model->refreshEvent(event);
310
311 auto eventIndex = impl->m_Model->indexOf(event);
312 auto validationIndex
313 = eventIndex.sibling(eventIndex.row(), (int)CatalogueEventsModel::Column::Validation);
314
315 if (hasChanges) {
316 if (ui->treeView->indexWidget(validationIndex) == nullptr) {
317 auto widget = CatalogueExplorerHelper::buildValidationWidget(
318 ui->treeView, [this, event]() { setEventChanges(event, false); },
319 [this, event]() { setEventChanges(event, false); });
320 ui->treeView->setIndexWidget(validationIndex, widget);
321 }
322 }
323 else {
324 // Note: the widget is destroyed
325 ui->treeView->setIndexWidget(validationIndex, nullptr);
326 }
327
328 impl->m_Model->setEventHasChanges(event, hasChanges);
297 }
329 }
298
330
299 void CatalogueEventsWidget::populateWithCatalogues(
331 void CatalogueEventsWidget::populateWithCatalogues(
@@ -314,3 +346,15 void CatalogueEventsWidget::populateWithCatalogues(
314
346
315 impl->setEvents(events, ui->treeView);
347 impl->setEvents(events, ui->treeView);
316 }
348 }
349
350 void CatalogueEventsWidget::populateWithAllEvents()
351 {
352 auto allEvents = sqpApp->catalogueController().retrieveAllEvents();
353
354 QVector<std::shared_ptr<DBEvent> > events;
355 for (auto event : allEvents) {
356 events << event;
357 }
358
359 impl->setEvents(events, ui->treeView);
360 }
@@ -1,12 +1,16
1 #include "Catalogue/CatalogueExplorer.h"
1 #include "Catalogue/CatalogueExplorer.h"
2 #include "ui_CatalogueExplorer.h"
2 #include "ui_CatalogueExplorer.h"
3
3
4 #include <Catalogue/CatalogueActionManager.h>
5 #include <Catalogue/CatalogueController.h>
6 #include <SqpApplication.h>
4 #include <Visualization/VisualizationWidget.h>
7 #include <Visualization/VisualizationWidget.h>
5
8
6 #include <DBCatalogue.h>
9 #include <DBCatalogue.h>
7 #include <DBEvent.h>
10 #include <DBEvent.h>
8
11
9 struct CatalogueExplorer::CatalogueExplorerPrivate {
12 struct CatalogueExplorer::CatalogueExplorerPrivate {
13 CatalogueActionManager m_ActionManager;
10 };
14 };
11
15
12 CatalogueExplorer::CatalogueExplorer(QWidget *parent)
16 CatalogueExplorer::CatalogueExplorer(QWidget *parent)
@@ -16,6 +20,8 CatalogueExplorer::CatalogueExplorer(QWidget *parent)
16 {
20 {
17 ui->setupUi(this);
21 ui->setupUi(this);
18
22
23 impl->m_ActionManager.installSelectionZoneActions();
24
19 connect(ui->catalogues, &CatalogueSideBarWidget::catalogueSelected, [this](auto catalogues) {
25 connect(ui->catalogues, &CatalogueSideBarWidget::catalogueSelected, [this](auto catalogues) {
20 if (catalogues.count() == 1) {
26 if (catalogues.count() == 1) {
21 ui->inspector->setCatalogue(catalogues.first());
27 ui->inspector->setCatalogue(catalogues.first());
@@ -34,8 +40,10 CatalogueExplorer::CatalogueExplorer(QWidget *parent)
34 connect(ui->catalogues, &CatalogueSideBarWidget::trashSelected,
40 connect(ui->catalogues, &CatalogueSideBarWidget::trashSelected,
35 [this]() { ui->inspector->showPage(CatalogueInspectorWidget::Page::Empty); });
41 [this]() { ui->inspector->showPage(CatalogueInspectorWidget::Page::Empty); });
36
42
37 connect(ui->catalogues, &CatalogueSideBarWidget::allEventsSelected,
43 connect(ui->catalogues, &CatalogueSideBarWidget::allEventsSelected, [this]() {
38 [this]() { ui->inspector->showPage(CatalogueInspectorWidget::Page::Empty); });
44 ui->inspector->showPage(CatalogueInspectorWidget::Page::Empty);
45 ui->events->populateWithAllEvents();
46 });
39
47
40 connect(ui->catalogues, &CatalogueSideBarWidget::selectionCleared,
48 connect(ui->catalogues, &CatalogueSideBarWidget::selectionCleared,
41 [this]() { ui->inspector->showPage(CatalogueInspectorWidget::Page::Empty); });
49 [this]() { ui->inspector->showPage(CatalogueInspectorWidget::Page::Empty); });
@@ -62,11 +70,15 CatalogueExplorer::CatalogueExplorer(QWidget *parent)
62 connect(ui->events, &CatalogueEventsWidget::selectionCleared,
70 connect(ui->events, &CatalogueEventsWidget::selectionCleared,
63 [this]() { ui->inspector->showPage(CatalogueInspectorWidget::Page::Empty); });
71 [this]() { ui->inspector->showPage(CatalogueInspectorWidget::Page::Empty); });
64
72
65 connect(ui->inspector, &CatalogueInspectorWidget::catalogueUpdated,
73 connect(ui->inspector, &CatalogueInspectorWidget::catalogueUpdated, [this](auto catalogue) {
66 [this](auto catalogue) { ui->catalogues->setCatalogueChanges(catalogue, true); });
74 sqpApp->catalogueController().updateCatalogue(catalogue);
75 ui->catalogues->setCatalogueChanges(catalogue, true);
76 });
67
77
68 connect(ui->inspector, &CatalogueInspectorWidget::eventUpdated,
78 connect(ui->inspector, &CatalogueInspectorWidget::eventUpdated, [this](auto event) {
69 [this](auto event) { ui->events->setEventChanges(event, true); });
79 sqpApp->catalogueController().updateEvent(event);
80 ui->events->setEventChanges(event, true);
81 });
70
82
71 connect(ui->inspector, &CatalogueInspectorWidget::eventProductUpdated,
83 connect(ui->inspector, &CatalogueInspectorWidget::eventProductUpdated,
72 [this](auto event, auto eventProduct) { ui->events->setEventChanges(event, true); });
84 [this](auto event, auto eventProduct) { ui->events->setEventChanges(event, true); });
@@ -176,11 +176,14 void CatalogueSideBarWidget::CatalogueSideBarWidgetPrivate::configureTreeWidget(
176 treeWidget->addTopLevelItem(separatorItem);
176 treeWidget->addTopLevelItem(separatorItem);
177 treeWidget->setItemWidget(separatorItem, 0, separator);
177 treeWidget->setItemWidget(separatorItem, 0, separator);
178
178
179 auto db = addDatabaseItem("Default", treeWidget);
179 auto repositories = sqpApp->catalogueController().getRepositories();
180 for (auto dbname : repositories) {
181 auto db = addDatabaseItem(dbname, treeWidget);
180
182
181 auto catalogues = sqpApp->catalogueController().retrieveCatalogues("Default");
183 auto catalogues = sqpApp->catalogueController().retrieveCatalogues(dbname);
182 for (auto catalogue : catalogues) {
184 for (auto catalogue : catalogues) {
183 addCatalogueItem(catalogue, db);
185 addCatalogueItem(catalogue, db);
186 }
184 }
187 }
185
188
186 treeWidget->expandAll();
189 treeWidget->expandAll();
@@ -1,12 +1,12
1 #include "Catalogue/CatalogueTreeWidgetItem.h"
1 #include "Catalogue/CatalogueTreeWidgetItem.h"
2 #include <Catalogue/CatalogueExplorerHelper.h>
3
4 #include <Catalogue/CatalogueController.h>
5 #include <SqpApplication.h>
2
6
3 #include <memory>
7 #include <memory>
4
8
5 #include <DBCatalogue.h>
9 #include <DBCatalogue.h>
6 #include <QBoxLayout>
7 #include <QToolButton>
8
9 const auto VALIDATION_BUTTON_ICON_SIZE = 12;
10
10
11 /// Column in the tree widget where the apply and cancel buttons must appear
11 /// Column in the tree widget where the apply and cancel buttons must appear
12 const auto APPLY_CANCEL_BUTTONS_COLUMN = 1;
12 const auto APPLY_CANCEL_BUTTONS_COLUMN = 1;
@@ -50,6 +50,7 void CatalogueTreeWidgetItem::setData(int column, int role, const QVariant &valu
50 if (newName != impl->m_Catalogue->getName()) {
50 if (newName != impl->m_Catalogue->getName()) {
51 setText(0, newName);
51 setText(0, newName);
52 impl->m_Catalogue->setName(newName);
52 impl->m_Catalogue->setName(newName);
53 sqpApp->catalogueController().updateCatalogue(impl->m_Catalogue);
53 setHasChanges(true);
54 setHasChanges(true);
54 }
55 }
55 }
56 }
@@ -66,29 +67,11 std::shared_ptr<DBCatalogue> CatalogueTreeWidgetItem::catalogue() const
66 void CatalogueTreeWidgetItem::setHasChanges(bool value)
67 void CatalogueTreeWidgetItem::setHasChanges(bool value)
67 {
68 {
68 if (value) {
69 if (value) {
69 if (treeWidget()->itemWidget(this, APPLY_CANCEL_BUTTONS_COLUMN) == nullptr) {
70 if (!hasChanges()) {
70 auto widet = new QWidget{treeWidget()};
71 auto widget = CatalogueExplorerHelper::buildValidationWidget(
71
72 treeWidget(), [this]() { setHasChanges(false); },
72 auto layout = new QHBoxLayout{widet};
73 [this]() { setHasChanges(false); });
73 layout->setContentsMargins(0, 0, 0, 0);
74 treeWidget()->setItemWidget(this, APPLY_CANCEL_BUTTONS_COLUMN, widget);
74 layout->setSpacing(0);
75
76 auto btnValid = new QToolButton{widet};
77 btnValid->setIcon(QIcon{":/icones/save"});
78 btnValid->setIconSize(QSize{VALIDATION_BUTTON_ICON_SIZE, VALIDATION_BUTTON_ICON_SIZE});
79 btnValid->setAutoRaise(true);
80 QObject::connect(btnValid, &QToolButton::clicked, [this]() { setHasChanges(false); });
81 layout->addWidget(btnValid);
82
83 auto btnDiscard = new QToolButton{widet};
84 btnDiscard->setIcon(QIcon{":/icones/discard"});
85 btnDiscard->setIconSize(
86 QSize{VALIDATION_BUTTON_ICON_SIZE, VALIDATION_BUTTON_ICON_SIZE});
87 btnDiscard->setAutoRaise(true);
88 QObject::connect(btnDiscard, &QToolButton::clicked, [this]() { setHasChanges(false); });
89 layout->addWidget(btnDiscard);
90
91 treeWidget()->setItemWidget(this, APPLY_CANCEL_BUTTONS_COLUMN, {widet});
92 }
75 }
93 }
76 }
94 else {
77 else {
@@ -97,6 +80,11 void CatalogueTreeWidgetItem::setHasChanges(bool value)
97 }
80 }
98 }
81 }
99
82
83 bool CatalogueTreeWidgetItem::hasChanges()
84 {
85 return treeWidget()->itemWidget(this, APPLY_CANCEL_BUTTONS_COLUMN) != nullptr;
86 }
87
100 void CatalogueTreeWidgetItem::refresh()
88 void CatalogueTreeWidgetItem::refresh()
101 {
89 {
102 emitDataChanged();
90 emitDataChanged();
General Comments 0
You need to be logged in to leave comments. Login now