@@ -0,0 +1,71 | |||
|
1 | #ifndef EVENTSMODEL_H | |
|
2 | #define EVENTSMODEL_H | |
|
3 | #include <Catalogue/CatalogueController.h> | |
|
4 | #include <QAbstractItemModel> | |
|
5 | #include <array> | |
|
6 | ||
|
7 | class EventsModel : public QAbstractItemModel | |
|
8 | { | |
|
9 | Q_OBJECT | |
|
10 | std::vector<CatalogueController::Event_ptr> _events; | |
|
11 | ||
|
12 | enum class ItemType | |
|
13 | { | |
|
14 | None, | |
|
15 | Event, | |
|
16 | Product | |
|
17 | }; | |
|
18 | ||
|
19 | enum class Columns | |
|
20 | { | |
|
21 | Name = 0, | |
|
22 | TStart = 1, | |
|
23 | TEnd = 2, | |
|
24 | Tags = 3, | |
|
25 | Product = 4, | |
|
26 | Validation = 5, | |
|
27 | NbColumn = 6 | |
|
28 | }; | |
|
29 | ||
|
30 | const std::array<QString, static_cast<int>(Columns::NbColumn)> ColumnsNames | |
|
31 | = { "Name", "Start time", "Stop time", "Tags", "Product(s)", "" }; | |
|
32 | ||
|
33 | ||
|
34 | public: | |
|
35 | EventsModel(QObject* parent = nullptr); | |
|
36 | ||
|
37 | ||
|
38 | ItemType type(const QModelIndex& index) const; | |
|
39 | ||
|
40 | Qt::ItemFlags flags(const QModelIndex& index) const override | |
|
41 | { | |
|
42 | return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled; | |
|
43 | } | |
|
44 | QVariant data(int col, const CatalogueController::Event_ptr& event) const; | |
|
45 | QVariant data(int col, const CatalogueController::Product_t& product) const; | |
|
46 | QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; | |
|
47 | ||
|
48 | QModelIndex index( | |
|
49 | int row, int column, const QModelIndex& parent = QModelIndex()) const override; | |
|
50 | ||
|
51 | QModelIndex parent(const QModelIndex& index) const override; | |
|
52 | ||
|
53 | int rowCount(const QModelIndex& parent = QModelIndex()) const override; | |
|
54 | ||
|
55 | int columnCount(const QModelIndex& parent = QModelIndex()) const override; | |
|
56 | ||
|
57 | QVariant headerData( | |
|
58 | int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; | |
|
59 | ||
|
60 | void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override; | |
|
61 | ||
|
62 | public slots: | |
|
63 | void setEvents(std::vector<CatalogueController::Event_ptr> events) | |
|
64 | { | |
|
65 | beginResetModel(); | |
|
66 | std::swap(_events, events); | |
|
67 | endResetModel(); | |
|
68 | } | |
|
69 | }; | |
|
70 | ||
|
71 | #endif // EVENTSMODEL_H |
@@ -0,0 +1,18 | |||
|
1 | #ifndef EVENTSTREEVIEW_H | |
|
2 | #define EVENTSTREEVIEW_H | |
|
3 | ||
|
4 | #include <Catalogue/CatalogueController.h> | |
|
5 | #include <QObject> | |
|
6 | #include <QTreeView> | |
|
7 | ||
|
8 | class EventsTreeView : public QTreeView | |
|
9 | { | |
|
10 | Q_OBJECT | |
|
11 | public: | |
|
12 | EventsTreeView(QWidget* parent = nullptr); | |
|
13 | ||
|
14 | public slots: | |
|
15 | void setEvents(std::vector<CatalogueController::Event_ptr> events); | |
|
16 | }; | |
|
17 | ||
|
18 | #endif // EVENTSTREEVIEW_H |
@@ -0,0 +1,83 | |||
|
1 | #ifndef REPOSITORIESMODEL_H | |
|
2 | #define REPOSITORIESMODEL_H | |
|
3 | #include <Catalogue/CatalogueController.h> | |
|
4 | #include <QAbstractItemModel> | |
|
5 | #include <QIcon> | |
|
6 | #include <QObject> | |
|
7 | ||
|
8 | class RepositoriesModel : public QAbstractItemModel | |
|
9 | { | |
|
10 | Q_OBJECT | |
|
11 | ||
|
12 | ||
|
13 | enum class ItemType | |
|
14 | { | |
|
15 | None, | |
|
16 | Catalogue, | |
|
17 | Repository | |
|
18 | }; | |
|
19 | ||
|
20 | struct RepoModelItem | |
|
21 | { | |
|
22 | ItemType type; | |
|
23 | std::variant<QString, CatalogueController::Catalogue_ptr> item; | |
|
24 | RepoModelItem() : type { ItemType::None } {} | |
|
25 | RepoModelItem(const QString& repo); | |
|
26 | RepoModelItem(const CatalogueController::Catalogue_ptr& catalogue, RepoModelItem* parent) | |
|
27 | : type { ItemType::Catalogue } | |
|
28 | , item { catalogue } | |
|
29 | , parent { parent } | |
|
30 | , icon { ":/icones/catalogue.png" } | |
|
31 | { | |
|
32 | } | |
|
33 | QString repository() const { return std::get<QString>(item); } | |
|
34 | CatalogueController::Catalogue_ptr catalogue() const | |
|
35 | { | |
|
36 | return std::get<CatalogueController::Catalogue_ptr>(item); | |
|
37 | } | |
|
38 | QVariant data(int role) const; | |
|
39 | QString text() const | |
|
40 | { | |
|
41 | if (type == ItemType::Catalogue) | |
|
42 | return QString::fromStdString(catalogue()->name); | |
|
43 | if (type == ItemType::Repository) | |
|
44 | return repository(); | |
|
45 | return QString(); | |
|
46 | } | |
|
47 | std::vector<std::unique_ptr<RepoModelItem>> children; | |
|
48 | RepoModelItem* parent = nullptr; | |
|
49 | QIcon icon; | |
|
50 | }; | |
|
51 | ||
|
52 | std::vector<std::unique_ptr<RepoModelItem>> _items; | |
|
53 | ||
|
54 | inline RepoModelItem* to_item(const QModelIndex& index) const | |
|
55 | { | |
|
56 | return static_cast<RepoModelItem*>(index.internalPointer()); | |
|
57 | } | |
|
58 | ||
|
59 | public: | |
|
60 | RepositoriesModel(QObject* parent = nullptr); | |
|
61 | ||
|
62 | ItemType type(const QModelIndex& index) const; | |
|
63 | ||
|
64 | Qt::ItemFlags flags(const QModelIndex& index) const override | |
|
65 | { | |
|
66 | return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled; | |
|
67 | } | |
|
68 | ||
|
69 | QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; | |
|
70 | ||
|
71 | QModelIndex index( | |
|
72 | int row, int column, const QModelIndex& parent = QModelIndex()) const override; | |
|
73 | ||
|
74 | QModelIndex parent(const QModelIndex& index) const override; | |
|
75 | ||
|
76 | int rowCount(const QModelIndex& parent = QModelIndex()) const override; | |
|
77 | ||
|
78 | int columnCount(const QModelIndex& parent = QModelIndex()) const override { return 1; } | |
|
79 | public slots: | |
|
80 | void refresh(); | |
|
81 | }; | |
|
82 | ||
|
83 | #endif // REPOSITORIESMODEL_H |
@@ -0,0 +1,185 | |||
|
1 | #include "Catalogue2/eventsmodel.h" | |
|
2 | #include <SqpApplication.h> | |
|
3 | ||
|
4 | EventsModel::EventsModel(QObject* parent) : QAbstractItemModel(parent) {} | |
|
5 | ||
|
6 | EventsModel::ItemType EventsModel::type(const QModelIndex& index) const | |
|
7 | { | |
|
8 | if (!index.isValid()) | |
|
9 | { | |
|
10 | return ItemType::None; | |
|
11 | } | |
|
12 | else if (index.internalPointer() == nullptr) | |
|
13 | { | |
|
14 | return ItemType::Event; | |
|
15 | } | |
|
16 | else | |
|
17 | { | |
|
18 | return ItemType::Product; | |
|
19 | } | |
|
20 | } | |
|
21 | ||
|
22 | QVariant EventsModel::data(int col, const CatalogueController::Event_ptr& event) const | |
|
23 | { | |
|
24 | switch (static_cast<Columns>(col)) | |
|
25 | { | |
|
26 | case EventsModel::Columns::Name: | |
|
27 | return QString::fromStdString(event->name); | |
|
28 | case EventsModel::Columns::TStart: | |
|
29 | if (auto start = event->startTime()) | |
|
30 | return DateUtils::dateTime(*start).toString(DATETIME_FORMAT_ONE_LINE); | |
|
31 | else | |
|
32 | return QVariant {}; | |
|
33 | case EventsModel::Columns::TEnd: | |
|
34 | if (auto stop = event->stopTime()) | |
|
35 | return DateUtils::dateTime(*stop).toString(DATETIME_FORMAT_ONE_LINE); | |
|
36 | else | |
|
37 | return QVariant {}; | |
|
38 | case EventsModel::Columns::Product: | |
|
39 | { | |
|
40 | QStringList eventProductList; | |
|
41 | for (const auto& evtProduct : event->products) | |
|
42 | { | |
|
43 | eventProductList << QString::fromStdString(evtProduct.name); | |
|
44 | } | |
|
45 | return eventProductList.join(";"); | |
|
46 | } | |
|
47 | case EventsModel::Columns::Tags: | |
|
48 | { | |
|
49 | QString tagList; | |
|
50 | for (const auto& tag : event->tags) | |
|
51 | { | |
|
52 | tagList += QString::fromStdString(tag); | |
|
53 | tagList += ' '; | |
|
54 | } | |
|
55 | return tagList; | |
|
56 | } | |
|
57 | default: | |
|
58 | break; | |
|
59 | } | |
|
60 | return QVariant {}; | |
|
61 | } | |
|
62 | ||
|
63 | QVariant EventsModel::data(int col, const CatalogueController::Product_t& product) const | |
|
64 | { | |
|
65 | switch (static_cast<Columns>(col)) | |
|
66 | { | |
|
67 | case EventsModel::Columns::Name: | |
|
68 | return QString::fromStdString(product.name); | |
|
69 | case EventsModel::Columns::TStart: | |
|
70 | return DateUtils::dateTime(product.startTime).toString(DATETIME_FORMAT_ONE_LINE); | |
|
71 | case EventsModel::Columns::TEnd: | |
|
72 | return DateUtils::dateTime(product.stopTime).toString(DATETIME_FORMAT_ONE_LINE); | |
|
73 | case EventsModel::Columns::Product: | |
|
74 | return QString::fromStdString(product.name); | |
|
75 | default: | |
|
76 | break; | |
|
77 | } | |
|
78 | return QVariant {}; | |
|
79 | } | |
|
80 | ||
|
81 | QVariant EventsModel::data(const QModelIndex& index, int role) const | |
|
82 | { | |
|
83 | if (_events.size() && index.isValid() && role == Qt::DisplayRole) | |
|
84 | { | |
|
85 | switch (type(index)) | |
|
86 | { | |
|
87 | case EventsModel::ItemType::Event: | |
|
88 | return data(index.column(), _events[index.row()]); | |
|
89 | case EventsModel::ItemType::Product: | |
|
90 | { | |
|
91 | auto event = static_cast<CatalogueController::Event_t*>(index.internalPointer()); | |
|
92 | return data(index.column(), event->products[index.row()]); | |
|
93 | } | |
|
94 | default: | |
|
95 | break; | |
|
96 | } | |
|
97 | } | |
|
98 | return QVariant {}; | |
|
99 | } | |
|
100 | ||
|
101 | QModelIndex EventsModel::index(int row, int column, const QModelIndex& parent) const | |
|
102 | { | |
|
103 | if (!hasIndex(row, column, parent)) | |
|
104 | { | |
|
105 | return QModelIndex(); | |
|
106 | } | |
|
107 | ||
|
108 | switch (type(parent)) | |
|
109 | { | |
|
110 | case EventsModel::ItemType::None: | |
|
111 | return createIndex(row, column, nullptr); | |
|
112 | case EventsModel::ItemType::Event: | |
|
113 | { | |
|
114 | return createIndex(row, column, _events[parent.row()].get()); | |
|
115 | } | |
|
116 | case EventsModel::ItemType::Product: | |
|
117 | break; | |
|
118 | default: | |
|
119 | break; | |
|
120 | } | |
|
121 | ||
|
122 | return QModelIndex(); | |
|
123 | } | |
|
124 | ||
|
125 | QModelIndex EventsModel::parent(const QModelIndex& index) const | |
|
126 | { | |
|
127 | switch (type(index)) | |
|
128 | { | |
|
129 | case EventsModel::ItemType::None: | |
|
130 | break; | |
|
131 | case EventsModel::ItemType::Event: | |
|
132 | break; | |
|
133 | case EventsModel::ItemType::Product: | |
|
134 | { | |
|
135 | auto parentEvent = static_cast<CatalogueController::Event_t*>(index.internalPointer()); | |
|
136 | auto pos = std::distance(std::cbegin(_events), | |
|
137 | std::find_if(std::cbegin(_events), std::cend(_events), | |
|
138 | [parentEvent](auto event) { return event.get() == parentEvent; })); | |
|
139 | if (pos >= 0 && pos < _events.size()) | |
|
140 | { | |
|
141 | return createIndex(pos, 0); | |
|
142 | } | |
|
143 | } | |
|
144 | } | |
|
145 | return QModelIndex(); | |
|
146 | } | |
|
147 | ||
|
148 | int EventsModel::rowCount(const QModelIndex& parent) const | |
|
149 | { | |
|
150 | if (parent.column() > 0) | |
|
151 | { | |
|
152 | return 0; | |
|
153 | } | |
|
154 | ||
|
155 | switch (type(parent)) | |
|
156 | { | |
|
157 | case EventsModel::ItemType::None: | |
|
158 | return _events.size(); | |
|
159 | case EventsModel::ItemType::Event: | |
|
160 | return _events[parent.row()]->products.size(); | |
|
161 | break; | |
|
162 | case EventsModel::ItemType::Product: | |
|
163 | break; | |
|
164 | default: | |
|
165 | break; | |
|
166 | } | |
|
167 | return 0; | |
|
168 | } | |
|
169 | ||
|
170 | int EventsModel::columnCount(const QModelIndex& parent) const | |
|
171 | { | |
|
172 | return static_cast<int>(EventsModel::Columns::NbColumn); | |
|
173 | } | |
|
174 | ||
|
175 | QVariant EventsModel::headerData(int section, Qt::Orientation orientation, int role) const | |
|
176 | { | |
|
177 | if (orientation == Qt::Horizontal && role == Qt::DisplayRole && section < ColumnsNames.size()) | |
|
178 | { | |
|
179 | return ColumnsNames[section]; | |
|
180 | } | |
|
181 | ||
|
182 | return QVariant(); | |
|
183 | } | |
|
184 | ||
|
185 | void EventsModel::sort(int column, Qt::SortOrder order) {} |
@@ -0,0 +1,12 | |||
|
1 | #include <Catalogue2/eventsmodel.h> | |
|
2 | #include <Catalogue2/eventstreeview.h> | |
|
3 | ||
|
4 | EventsTreeView::EventsTreeView(QWidget* parent) : QTreeView(parent) | |
|
5 | { | |
|
6 | this->setModel(new EventsModel()); | |
|
7 | } | |
|
8 | ||
|
9 | void EventsTreeView::setEvents(std::vector<CatalogueController::Event_ptr> events) | |
|
10 | { | |
|
11 | static_cast<EventsModel*>(this->model())->setEvents(events); | |
|
12 | } |
@@ -0,0 +1,107 | |||
|
1 | #include <Catalogue2/repositoriesmodel.h> | |
|
2 | #include <Common/containers.h> | |
|
3 | #include <SqpApplication.h> | |
|
4 | ||
|
5 | ||
|
6 | RepositoriesModel::RepositoriesModel(QObject* parent) : QAbstractItemModel(parent) | |
|
7 | { | |
|
8 | refresh(); | |
|
9 | } | |
|
10 | ||
|
11 | RepositoriesModel::ItemType RepositoriesModel::type(const QModelIndex& index) const | |
|
12 | { | |
|
13 | if (RepoModelItem* item = to_item(index)) | |
|
14 | { | |
|
15 | return item->type; | |
|
16 | } | |
|
17 | return ItemType::None; | |
|
18 | } | |
|
19 | ||
|
20 | void RepositoriesModel::refresh() | |
|
21 | { | |
|
22 | beginResetModel(); | |
|
23 | _items.clear(); | |
|
24 | _items.push_back(std::make_unique<RepoModelItem>("All")); | |
|
25 | _items.push_back(std::make_unique<RepoModelItem>("Trash")); | |
|
26 | auto repo_list = sqpApp->catalogueController().repositories(); | |
|
27 | std::transform(std::begin(repo_list), std::end(repo_list), std::back_inserter(_items), | |
|
28 | [](const auto& repo_name) { return std::make_unique<RepoModelItem>(repo_name); }); | |
|
29 | endResetModel(); | |
|
30 | } | |
|
31 | ||
|
32 | QVariant RepositoriesModel::data(const QModelIndex& index, int role) const | |
|
33 | { | |
|
34 | if (index.isValid() && index.column() == 0) | |
|
35 | { | |
|
36 | return to_item(index)->data(role); | |
|
37 | } | |
|
38 | return QVariant {}; | |
|
39 | } | |
|
40 | ||
|
41 | QModelIndex RepositoriesModel::index(int row, int column, const QModelIndex& parent) const | |
|
42 | { | |
|
43 | if (!hasIndex(row, column, parent)) | |
|
44 | { | |
|
45 | return QModelIndex(); | |
|
46 | } | |
|
47 | ||
|
48 | switch (type(parent)) | |
|
49 | { | |
|
50 | case RepositoriesModel::ItemType::None: // is a repo | |
|
51 | return createIndex(row, column, _items[row].get()); | |
|
52 | case RepositoriesModel::ItemType::Repository: // is a catalogue | |
|
53 | return createIndex(row, column, to_item(parent)->children[row].get()); | |
|
54 | case RepositoriesModel::ItemType::Catalogue: | |
|
55 | return createIndex(row, column, new RepoModelItem()); | |
|
56 | } | |
|
57 | ||
|
58 | return QModelIndex(); | |
|
59 | } | |
|
60 | ||
|
61 | QModelIndex RepositoriesModel::parent(const QModelIndex& index) const | |
|
62 | { | |
|
63 | auto item = to_item(index); | |
|
64 | if (item->type == ItemType::Catalogue) | |
|
65 | { | |
|
66 | auto repoIndex = SciQLop::containers::index_of(_items, item->parent); | |
|
67 | return createIndex(repoIndex, 0, item->parent); | |
|
68 | } | |
|
69 | return QModelIndex(); | |
|
70 | } | |
|
71 | ||
|
72 | int RepositoriesModel::rowCount(const QModelIndex& parent) const | |
|
73 | { | |
|
74 | switch (type(parent)) | |
|
75 | { | |
|
76 | case RepositoriesModel::ItemType::None: | |
|
77 | return _items.size(); | |
|
78 | case RepositoriesModel::ItemType::Repository: | |
|
79 | return to_item(parent)->children.size(); | |
|
80 | case RepositoriesModel::ItemType::Catalogue: | |
|
81 | break; | |
|
82 | } | |
|
83 | return 0; | |
|
84 | } | |
|
85 | ||
|
86 | RepositoriesModel::RepoModelItem::RepoModelItem(const QString& repo) | |
|
87 | : type { ItemType::Repository }, item { repo }, icon { ":/icones/database.png" } | |
|
88 | { | |
|
89 | auto catalogues = sqpApp->catalogueController().catalogues(repo); | |
|
90 | std::transform(std::begin(catalogues), std::end(catalogues), std::back_inserter(children), | |
|
91 | [this](auto& catalogue) { return std::make_unique<RepoModelItem>(catalogue, this); }); | |
|
92 | } | |
|
93 | ||
|
94 | QVariant RepositoriesModel::RepoModelItem::data(int role) const | |
|
95 | { | |
|
96 | switch (role) | |
|
97 | { | |
|
98 | case Qt::EditRole: | |
|
99 | case Qt::DisplayRole: | |
|
100 | return text(); | |
|
101 | case Qt::DecorationRole: | |
|
102 | return QVariant { icon }; | |
|
103 | default: | |
|
104 | break; | |
|
105 | } | |
|
106 | return QVariant {}; | |
|
107 | } |
@@ -0,0 +1,68 | |||
|
1 | #include <QMainWindow> | |
|
2 | #include <QObject> | |
|
3 | #include <QScreen> | |
|
4 | #include <QString> | |
|
5 | #include <QWheelEvent> | |
|
6 | #include <QtTest> | |
|
7 | ||
|
8 | #include <QTreeView> | |
|
9 | ||
|
10 | ||
|
11 | #include <Common/cpp_utils.h> | |
|
12 | #include <SqpApplication.h> | |
|
13 | ||
|
14 | #include <GUITestUtils.h> | |
|
15 | #include <TestProviders.h> | |
|
16 | ||
|
17 | //#include <Catalogue/CatalogueEventsWidget.h> | |
|
18 | ||
|
19 | #include <Catalogue2/eventstreeview.h> | |
|
20 | ||
|
21 | ||
|
22 | class An_EventList : public QObject | |
|
23 | { | |
|
24 | Q_OBJECT | |
|
25 | public: | |
|
26 | explicit An_EventList(QObject* parent = Q_NULLPTR) : QObject(parent) {} | |
|
27 | ||
|
28 | private slots: | |
|
29 | }; | |
|
30 | ||
|
31 | // QT_BEGIN_NAMESPACE | |
|
32 | // QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS | |
|
33 | // QT_END_NAMESPACE | |
|
34 | // int main(int argc, char* argv[]) | |
|
35 | //{ | |
|
36 | // SqpApplication app { argc, argv }; | |
|
37 | // app.setAttribute(Qt::AA_Use96Dpi, true); | |
|
38 | // QTEST_DISABLE_KEYPAD_NAVIGATION; | |
|
39 | // QTEST_ADD_GPU_BLACKLIST_SUPPORT; | |
|
40 | // An_EventList tc; | |
|
41 | // QTEST_SET_MAIN_SOURCE_PATH; | |
|
42 | // return QTest::qExec(&tc, argc, argv); | |
|
43 | //} | |
|
44 | ||
|
45 | #include "main.moc" | |
|
46 | ||
|
47 | ||
|
48 | int main(int argc, char* argv[]) | |
|
49 | { | |
|
50 | QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); | |
|
51 | ||
|
52 | SqpApplication a { argc, argv }; | |
|
53 | EventsTreeView w; | |
|
54 | std::vector<CatalogueController::Event_ptr> events; | |
|
55 | for (auto _ : std::array<char, 10>()) | |
|
56 | { | |
|
57 | static int i = 0; | |
|
58 | auto event = CatalogueController::make_event_ptr(); | |
|
59 | event->name = std::string("Event ") + std::to_string(i++); | |
|
60 | event->products = { CatalogueController::Event_t::Product_t { "Product1", 10., 11. }, | |
|
61 | CatalogueController::Event_t::Product_t { "Product2", 11., 12. }, | |
|
62 | CatalogueController::Event_t::Product_t { "Product3", 10.2, 11. } }; | |
|
63 | events.push_back(event); | |
|
64 | } | |
|
65 | w.setEvents(events); | |
|
66 | w.show(); | |
|
67 | return a.exec(); | |
|
68 | } |
@@ -0,0 +1,65 | |||
|
1 | #include <QMainWindow> | |
|
2 | #include <QObject> | |
|
3 | #include <QScreen> | |
|
4 | #include <QString> | |
|
5 | #include <QWheelEvent> | |
|
6 | #include <QtTest> | |
|
7 | ||
|
8 | #include <QTreeView> | |
|
9 | ||
|
10 | ||
|
11 | #include <Common/cpp_utils.h> | |
|
12 | #include <SqpApplication.h> | |
|
13 | ||
|
14 | #include <GUITestUtils.h> | |
|
15 | #include <TestProviders.h> | |
|
16 | ||
|
17 | //#include <Catalogue/CatalogueEventsWidget.h> | |
|
18 | ||
|
19 | #include <Catalogue2/eventstreeview.h> | |
|
20 | #include <Catalogue2/repositoriesmodel.h> | |
|
21 | ||
|
22 | ||
|
23 | class An_EventList : public QObject | |
|
24 | { | |
|
25 | Q_OBJECT | |
|
26 | public: | |
|
27 | explicit An_EventList(QObject* parent = Q_NULLPTR) : QObject(parent) {} | |
|
28 | ||
|
29 | private slots: | |
|
30 | }; | |
|
31 | ||
|
32 | // QT_BEGIN_NAMESPACE | |
|
33 | // QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS | |
|
34 | // QT_END_NAMESPACE | |
|
35 | // int main(int argc, char* argv[]) | |
|
36 | //{ | |
|
37 | // SqpApplication app { argc, argv }; | |
|
38 | // app.setAttribute(Qt::AA_Use96Dpi, true); | |
|
39 | // QTEST_DISABLE_KEYPAD_NAVIGATION; | |
|
40 | // QTEST_ADD_GPU_BLACKLIST_SUPPORT; | |
|
41 | // An_EventList tc; | |
|
42 | // QTEST_SET_MAIN_SOURCE_PATH; | |
|
43 | // return QTest::qExec(&tc, argc, argv); | |
|
44 | //} | |
|
45 | ||
|
46 | #include "main.moc" | |
|
47 | ||
|
48 | ||
|
49 | int main(int argc, char* argv[]) | |
|
50 | { | |
|
51 | Q_INIT_RESOURCE(sqpguiresources); | |
|
52 | QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); | |
|
53 | ||
|
54 | SqpApplication a { argc, argv }; | |
|
55 | QTreeView w; | |
|
56 | sqpApp->catalogueController().add("test"); | |
|
57 | sqpApp->catalogueController().add("stuff"); | |
|
58 | sqpApp->catalogueController().add("default"); | |
|
59 | sqpApp->catalogueController().add("new catalogue", "default"); | |
|
60 | sqpApp->catalogueController().add("new catalogue2", "default"); | |
|
61 | RepositoriesModel* model = new RepositoriesModel(); | |
|
62 | w.setModel(model); | |
|
63 | w.show(); | |
|
64 | return a.exec(); | |
|
65 | } |
@@ -0,0 +1,30 | |||
|
1 | { | |
|
2 | "app-id": "org.LPP.SciQLop", | |
|
3 | "runtime": "org.kde.Platform", | |
|
4 | "runtime-version": "5.12", | |
|
5 | "sdk": "org.kde.Sdk", | |
|
6 | "command": "sciqlop", | |
|
7 | "finish-args": [ | |
|
8 | "--socket=x11", | |
|
9 | "--socket=wayland", | |
|
10 | "--socket=session-bus", | |
|
11 | "--share=ipc", | |
|
12 | "--device=dri", | |
|
13 | "--share=network", | |
|
14 | "--filesystem=home" | |
|
15 | ], | |
|
16 | "modules": [ | |
|
17 | { | |
|
18 | "name": "sciqlop", | |
|
19 | "buildsystem" : "meson", | |
|
20 | "config-opts" : ["-DFlatpak=true", "-Ddefault_library=static"], | |
|
21 | "sources" : [ | |
|
22 | { | |
|
23 | "type" : "git", | |
|
24 | "url" : "https://github.com/LaboratoryOfPlasmaPhysics/SciQLOP", | |
|
25 | "branch" : "master" | |
|
26 | } | |
|
27 | ] | |
|
28 | } | |
|
29 | ] | |
|
30 | } No newline at end of file |
@@ -1,84 +1,96 | |||
|
1 | 1 | cmake_minimum_required(VERSION 3.6) |
|
2 | 2 | project(SciQLOP CXX) |
|
3 | 3 | |
|
4 | 4 | include(GNUInstallDirs) |
|
5 | 5 | |
|
6 | 6 | SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}/cmake") |
|
7 | 7 | |
|
8 | 8 | OPTION (CPPCHECK "Analyzes the source code with cppcheck" OFF) |
|
9 | 9 | OPTION (CLANG_TIDY "Analyzes the source code with Clang Tidy" OFF) |
|
10 | 10 | OPTION (IWYU "Analyzes the source code with Include What You Use" OFF) |
|
11 | 11 | OPTION (Coverage "Enables code coverage" OFF) |
|
12 | OPTION (BUILD_APP "Build SciQLop application" ON) | |
|
13 | OPTION (BUILD_CORE "Build SciQLop Core module" ON) | |
|
14 | OPTION (BUILD_GUI "Build SciQLop GUI module" ON) | |
|
15 | OPTION (BUILD_PLUGINS "Build SciQLop plugins" ON) | |
|
12 | 16 | |
|
13 | 17 | set(CMAKE_CXX_STANDARD 17) |
|
14 | 18 | |
|
15 | 19 | set(CMAKE_AUTOMOC ON) |
|
16 | 20 | #https://gitlab.kitware.com/cmake/cmake/issues/15227 |
|
17 | 21 | #set(CMAKE_AUTOUIC ON) |
|
18 | 22 | if(POLICY CMP0071) |
|
19 | 23 | cmake_policy(SET CMP0071 OLD) |
|
20 | 24 | endif() |
|
21 | 25 | set(CMAKE_AUTORCC ON) |
|
22 | 26 | set(CMAKE_INCLUDE_CURRENT_DIR ON) |
|
23 | 27 | |
|
24 | 28 | if(NOT DEFINED CMAKE_INSTALL_RPATH_USE_LINK_PATH) |
|
25 | 29 | set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) |
|
26 | 30 | endif() |
|
27 | 31 | if(NOT DEFINED CMAKE_MACOSX_RPATH) |
|
28 | 32 | set(CMAKE_MACOSX_RPATH TRUE) |
|
29 | 33 | endif() |
|
30 | 34 | |
|
31 | 35 | if(NOT CMAKE_BUILD_TYPE) |
|
32 | 36 | set(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE) |
|
33 | 37 | endif() |
|
34 | 38 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -g3") |
|
35 | 39 | |
|
36 | 40 | find_package(Qt5 COMPONENTS Core Widgets Network PrintSupport Svg Test REQUIRED) |
|
37 | 41 | |
|
38 | 42 | IF(CPPCHECK) |
|
39 | 43 | set(CMAKE_CXX_CPPCHECK "cppcheck;--enable=warning,style") |
|
40 | 44 | ENDIF(CPPCHECK) |
|
41 | 45 | |
|
42 | 46 | IF(CLANG_TIDY) |
|
43 | 47 | set(CMAKE_CXX_CLANG_TIDY "clang-tidy;-style=file;-checks=*") |
|
44 | 48 | ENDIF(CLANG_TIDY) |
|
45 | 49 | |
|
46 | 50 | IF(IWYU) |
|
47 | 51 | set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "include-what-you-use") |
|
48 | 52 | ENDIF(IWYU) |
|
49 | 53 | |
|
50 | 54 | IF(Coverage) |
|
51 | 55 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -g -O0 -Wall -W -Wshadow -Wunused-variable -Wunused-parameter -Wunused-function -Wunused -Wno-system-headers -Wno-deprecated -Woverloaded-virtual -Wwrite-strings -fprofile-arcs -ftest-coverage") |
|
52 | 56 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g -O0 -Wall -W -Wshadow -Wunused-variable \ |
|
53 | 57 | -Wunused-parameter -Wunused-function -Wunused -Wno-system-headers \ |
|
54 | 58 | -Wno-deprecated -Woverloaded-virtual -Wwrite-strings -fprofile-arcs -ftest-coverage") |
|
55 | 59 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") |
|
56 | 60 | |
|
57 | 61 | add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/gcov.html |
|
58 | 62 | COMMAND gcovr --exclude='.*Test.*' --exclude='.*external.*' --object-directory ${CMAKE_BINARY_DIR} -r ${CMAKE_SOURCE_DIR} --html --html-details -o ${CMAKE_CURRENT_BINARY_DIR}/gcov.html |
|
59 | 63 | ) |
|
60 | 64 | add_custom_target(gcovr |
|
61 | 65 | DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/gcov.html gcovr |
|
62 | 66 | ) |
|
63 | 67 | add_custom_target(show_coverage |
|
64 | 68 | COMMAND xdg-open ${CMAKE_CURRENT_BINARY_DIR}/gcov.html |
|
65 | 69 | DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/gcov.html gcovr |
|
66 | 70 | ) |
|
67 | 71 | ENDIF(Coverage) |
|
68 | 72 | |
|
69 | 73 | enable_testing() |
|
70 | 74 | |
|
75 | if(BUILD_CORE) | |
|
71 | 76 | find_package(SciQLOPCore CONFIG QUIET) |
|
72 | 77 | if (NOT SciQLOPCore_FOUND) |
|
73 | 78 | if(NOT IS_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/core) |
|
74 | 79 | message("Init submodule Core") |
|
75 | 80 | execute_process(COMMAND git submodule init core WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) |
|
76 | 81 | execute_process(COMMAND git submodule update core WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) |
|
77 | 82 | endif() |
|
78 | 83 | add_subdirectory(core) |
|
79 | 84 | endif() |
|
85 | endif() | |
|
80 | 86 | |
|
87 | if(BUILD_GUI) | |
|
81 | 88 | add_subdirectory(gui) |
|
89 | endif() | |
|
90 | if(BUILD_APP) | |
|
82 | 91 | add_subdirectory(app) |
|
92 | endif() | |
|
93 | if(BUILD_PLUGINS) | |
|
83 | 94 | add_subdirectory(plugins) |
|
95 | endif() | |
|
84 | 96 | #add_subdirectory(docs) |
@@ -1,394 +1,396 | |||
|
1 | 1 | /*------------------------------------------------------------------------------ |
|
2 | 2 | -- This file is a part of the SciQLop Software |
|
3 | 3 | -- Copyright (C) 2017, Plasma Physics Laboratory - CNRS |
|
4 | 4 | -- |
|
5 | 5 | -- This program is free software; you can redistribute it and/or modify |
|
6 | 6 | -- it under the terms of the GNU General Public License as published by |
|
7 | 7 | -- the Free Software Foundation; either version 2 of the License, or |
|
8 | 8 | -- (at your option) any later version. |
|
9 | 9 | -- |
|
10 | 10 | -- This program is distributed in the hope that it will be useful, |
|
11 | 11 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 | 12 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
13 | 13 | -- GNU General Public License for more details. |
|
14 | 14 | -- |
|
15 | 15 | -- You should have received a copy of the GNU General Public License |
|
16 | 16 | -- along with this program; if not, write to the Free Software |
|
17 | 17 | -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
18 | 18 | -------------------------------------------------------------------------------*/ |
|
19 | 19 | /*-- Author : Alexis Jeandet |
|
20 | 20 | -- Mail : alexis.jeandet@member.fsf.org |
|
21 | 21 | ----------------------------------------------------------------------------*/ |
|
22 | 22 | #include "MainWindow.h" |
|
23 | 23 | #include "ui_MainWindow.h" |
|
24 | 24 | |
|
25 | 25 | #include <Catalogue/CatalogueController.h> |
|
26 | 26 | #include <Catalogue/CatalogueExplorer.h> |
|
27 | 27 | #include <DataSource/DataSourceController.h> |
|
28 | 28 | #include <DataSource/DataSourceWidget.h> |
|
29 | 29 | #include <Settings/SqpSettingsDialog.h> |
|
30 | 30 | #include <Settings/SqpSettingsGeneralWidget.h> |
|
31 | 31 | #include <SidePane/SqpSidePane.h> |
|
32 | 32 | #include <SqpApplication.h> |
|
33 | 33 | #include <Time/TimeController.h> |
|
34 | 34 | #include <TimeWidget/TimeWidget.h> |
|
35 | 35 | #include <Variable/Variable.h> |
|
36 | 36 | #include <Visualization/VisualizationController.h> |
|
37 | 37 | |
|
38 | 38 | #include <QAction> |
|
39 | 39 | #include <QCloseEvent> |
|
40 | 40 | #include <QDate> |
|
41 | 41 | #include <QDir> |
|
42 | 42 | #include <QFileDialog> |
|
43 | 43 | #include <QMessageBox> |
|
44 | 44 | #include <QToolBar> |
|
45 | 45 | #include <QToolButton> |
|
46 | 46 | #include <memory.h> |
|
47 | 47 | |
|
48 | 48 | #include "iostream" |
|
49 | 49 | |
|
50 | 50 | Q_LOGGING_CATEGORY(LOG_MainWindow, "MainWindow") |
|
51 | 51 | |
|
52 |
namespace |
|
|
52 | namespace | |
|
53 | { | |
|
53 | 54 | const auto LEFTMAININSPECTORWIDGETSPLITTERINDEX = 0; |
|
54 | 55 | const auto LEFTINSPECTORSIDEPANESPLITTERINDEX = 1; |
|
55 | 56 | const auto VIEWPLITTERINDEX = 2; |
|
56 | 57 | const auto RIGHTINSPECTORSIDEPANESPLITTERINDEX = 3; |
|
57 | 58 | const auto RIGHTMAININSPECTORWIDGETSPLITTERINDEX = 4; |
|
58 | 59 | } |
|
59 | 60 | |
|
60 |
class MainWindow::MainWindowPrivate |
|
|
61 | class MainWindow::MainWindowPrivate | |
|
62 | { | |
|
61 | 63 | public: |
|
62 | 64 |
explicit MainWindowPrivate(MainWindow |
|
63 |
: m_LastOpenLeftInspectorSize{} |
|
|
64 |
|
|
|
65 |
|
|
|
66 |
|
|
|
67 |
|
|
|
65 | : m_LastOpenLeftInspectorSize {} | |
|
66 | , m_LastOpenRightInspectorSize {} | |
|
67 | , m_GeneralSettingsWidget { new SqpSettingsGeneralWidget { mainWindow } } | |
|
68 | , m_SettingsDialog { new SqpSettingsDialog { mainWindow } } | |
|
69 | //, m_CatalogExplorer { new CatalogueExplorer { mainWindow } } | |
|
68 | 70 | { |
|
69 | 71 | } |
|
70 | 72 | |
|
71 | 73 | QSize m_LastOpenLeftInspectorSize; |
|
72 | 74 | QSize m_LastOpenRightInspectorSize; |
|
73 | 75 | /// General settings widget. MainWindow has the ownership |
|
74 | 76 |
SqpSettingsGeneralWidget |
|
75 | 77 | /// Settings dialog. MainWindow has the ownership |
|
76 | 78 |
SqpSettingsDialog |
|
77 | 79 | /// Catalogue dialog. MainWindow has the ownership |
|
78 |
CatalogueExplorer |
|
|
80 | // CatalogueExplorer* m_CatalogExplorer; | |
|
79 | 81 | |
|
80 | 82 |
bool checkDataToSave(QWidget |
|
81 | 83 | }; |
|
82 | 84 | |
|
83 | 85 |
MainWindow::MainWindow(QWidget |
|
84 |
: QMainWindow{parent} |
|
|
85 |
|
|
|
86 |
|
|
|
86 | : QMainWindow { parent } | |
|
87 | , m_Ui { new Ui::MainWindow } | |
|
88 | , impl { spimpl::make_unique_impl<MainWindowPrivate>(this) } | |
|
87 | 89 | { |
|
88 | 90 | m_Ui->setupUi(this); |
|
89 | 91 | |
|
90 | 92 | m_Ui->splitter->setCollapsible(LEFTINSPECTORSIDEPANESPLITTERINDEX, false); |
|
91 | 93 | m_Ui->splitter->setCollapsible(RIGHTINSPECTORSIDEPANESPLITTERINDEX, false); |
|
92 | 94 | |
|
93 | impl->m_CatalogExplorer->setVisualizationWidget(m_Ui->view); | |
|
94 | ||
|
95 | ||
|
96 | ||
|
95 | // impl->m_CatalogExplorer->setVisualizationWidget(m_Ui->view); | |
|
97 | 96 | |
|
98 | 97 | |
|
99 | 98 | auto spacerLeftTop = new QWidget{}; |
|
100 | 99 | spacerLeftTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); |
|
101 | 100 | |
|
102 | 101 | auto spacerLeftBottom = new QWidget{}; |
|
103 | 102 | spacerLeftBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); |
|
104 | 103 | |
|
105 | 104 | |
|
106 | 105 | auto spacerRightTop = new QWidget{}; |
|
107 | 106 | spacerRightTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); |
|
108 | 107 | |
|
109 | 108 | auto spacerRightBottom = new QWidget{}; |
|
110 | 109 | spacerRightBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); |
|
111 | 110 | |
|
112 | 111 | |
|
113 | 112 | auto openInspector = [this](bool checked, bool right, auto action) { |
|
114 | ||
|
115 |
|
|
|
113 | action->setIcon( | |
|
114 | QIcon { (checked ^ right) ? ":/icones/next.png" : ":/icones/previous.png" }); | |
|
116 | 115 | |
|
117 | 116 |
auto |
|
118 | 117 | = right ? impl->m_LastOpenRightInspectorSize : impl->m_LastOpenLeftInspectorSize; |
|
119 | 118 | |
|
120 | 119 | auto nextInspectorSize = right ? m_Ui->rightMainInspectorWidget->size() |
|
121 | 120 | : m_Ui->leftMainInspectorWidget->size(); |
|
122 | 121 | |
|
123 | 122 | // Update of the last opened geometry |
|
124 |
if (checked) |
|
|
123 | if (checked) | |
|
124 | { | |
|
125 | 125 | lastInspectorSize = nextInspectorSize; |
|
126 | 126 | } |
|
127 | 127 | |
|
128 | 128 | auto startSize = lastInspectorSize; |
|
129 | 129 | auto endSize = startSize; |
|
130 | 130 | endSize.setWidth(0); |
|
131 | 131 | |
|
132 | 132 | auto splitterInspectorIndex |
|
133 | 133 | = right ? RIGHTMAININSPECTORWIDGETSPLITTERINDEX : LEFTMAININSPECTORWIDGETSPLITTERINDEX; |
|
134 | 134 | |
|
135 | 135 | auto currentSizes = m_Ui->splitter->sizes(); |
|
136 |
if (checked) |
|
|
136 | if (checked) | |
|
137 | { | |
|
137 | 138 | // adjust sizes individually here, e.g. |
|
138 | 139 | currentSizes[splitterInspectorIndex] -= lastInspectorSize.width(); |
|
139 | 140 | currentSizes[VIEWPLITTERINDEX] += lastInspectorSize.width(); |
|
140 | 141 | m_Ui->splitter->setSizes(currentSizes); |
|
141 | 142 | } |
|
142 |
else |
|
|
143 | else | |
|
144 | { | |
|
143 | 145 | // adjust sizes individually here, e.g. |
|
144 | 146 | currentSizes[splitterInspectorIndex] += lastInspectorSize.width(); |
|
145 | 147 | currentSizes[VIEWPLITTERINDEX] -= lastInspectorSize.width(); |
|
146 | 148 | m_Ui->splitter->setSizes(currentSizes); |
|
147 | 149 | } |
|
148 | ||
|
149 | 150 | }; |
|
150 | 151 | |
|
151 | 152 | |
|
152 | 153 | // //////////////// // |
|
153 | 154 | // Menu and Toolbar // |
|
154 | 155 | // //////////////// // |
|
155 | 156 | this->menuBar()->addAction(tr("File")); |
|
156 | 157 | auto toolsMenu = this->menuBar()->addMenu(tr("Tools")); |
|
157 | 158 | toolsMenu->addAction(tr("Settings..."), [this]() { |
|
158 | 159 | // Loads settings |
|
159 | 160 | impl->m_SettingsDialog->loadSettings(); |
|
160 | 161 | |
|
161 | 162 | // Open settings dialog and save settings if the dialog is accepted |
|
162 |
if (impl->m_SettingsDialog->exec() == QDialog::Accepted) |
|
|
163 | if (impl->m_SettingsDialog->exec() == QDialog::Accepted) | |
|
164 | { | |
|
163 | 165 | impl->m_SettingsDialog->saveSettings(); |
|
164 | 166 | } |
|
165 | ||
|
166 | 167 | }); |
|
167 | 168 | |
|
168 | 169 | auto mainToolBar = this->addToolBar(QStringLiteral("MainToolBar")); |
|
169 | 170 | |
|
170 | 171 | auto timeWidget = new TimeWidget{}; |
|
171 | 172 | mainToolBar->addWidget(timeWidget); |
|
172 | 173 | |
|
173 | 174 | // Interaction modes |
|
174 | 175 | auto actionPointerMode = new QAction{QIcon(":/icones/pointer.png"), "Move", this}; |
|
175 | 176 | actionPointerMode->setCheckable(true); |
|
176 |
actionPointerMode->setChecked( |
|
|
177 |
|
|
|
177 | actionPointerMode->setChecked( | |
|
178 | sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::None); | |
|
178 | 179 | connect(actionPointerMode, &QAction::triggered, |
|
179 | 180 |
|
|
180 | 181 | |
|
181 | 182 | auto actionZoomMode = new QAction{QIcon(":/icones/zoom.png"), "Zoom", this}; |
|
182 | 183 | actionZoomMode->setCheckable(true); |
|
183 |
actionZoomMode->setChecked( |
|
|
184 |
|
|
|
185 |
connect(actionZoomMode, &QAction::triggered, |
|
|
186 | sqpApp->setPlotsInteractionMode(SqpApplication::PlotsInteractionMode::ZoomBox); | |
|
187 | }); | |
|
184 | actionZoomMode->setChecked( | |
|
185 | sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::ZoomBox); | |
|
186 | connect(actionZoomMode, &QAction::triggered, | |
|
187 | []() { sqpApp->setPlotsInteractionMode(SqpApplication::PlotsInteractionMode::ZoomBox); }); | |
|
188 | 188 | |
|
189 | 189 | auto actionOrganisationMode = new QAction{QIcon(":/icones/drag.png"), "Organize", this}; |
|
190 | 190 | actionOrganisationMode->setCheckable(true); |
|
191 |
actionOrganisationMode->setChecked( |
|
|
192 |
|
|
|
191 | actionOrganisationMode->setChecked( | |
|
192 | sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::DragAndDrop); | |
|
193 | 193 | connect(actionOrganisationMode, &QAction::triggered, []() { |
|
194 | 194 | sqpApp->setPlotsInteractionMode(SqpApplication::PlotsInteractionMode::DragAndDrop); |
|
195 | 195 | }); |
|
196 | 196 | |
|
197 | 197 | auto actionZonesMode = new QAction{QIcon(":/icones/rectangle.png"), "Zones", this}; |
|
198 | 198 | actionZonesMode->setCheckable(true); |
|
199 |
actionZonesMode->setChecked( |
|
|
200 |
|
|
|
199 | actionZonesMode->setChecked( | |
|
200 | sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones); | |
|
201 | 201 | connect(actionZonesMode, &QAction::triggered, []() { |
|
202 | 202 | sqpApp->setPlotsInteractionMode(SqpApplication::PlotsInteractionMode::SelectionZones); |
|
203 | 203 | }); |
|
204 | 204 | |
|
205 | 205 | auto modeActionGroup = new QActionGroup{this}; |
|
206 | 206 | modeActionGroup->addAction(actionZoomMode); |
|
207 | 207 | modeActionGroup->addAction(actionZonesMode); |
|
208 | 208 | modeActionGroup->addAction(actionOrganisationMode); |
|
209 | 209 | modeActionGroup->addAction(actionPointerMode); |
|
210 | 210 | modeActionGroup->setExclusive(true); |
|
211 | 211 | |
|
212 | 212 | mainToolBar->addSeparator(); |
|
213 | 213 | mainToolBar->addAction(actionPointerMode); |
|
214 | 214 | mainToolBar->addAction(actionZoomMode); |
|
215 | 215 | mainToolBar->addAction(actionOrganisationMode); |
|
216 | 216 | mainToolBar->addAction(actionZonesMode); |
|
217 | 217 | mainToolBar->addSeparator(); |
|
218 | 218 | |
|
219 | 219 | // Cursors |
|
220 | 220 | auto btnCursor = new QToolButton{this}; |
|
221 | 221 | btnCursor->setIcon(QIcon(":/icones/cursor.png")); |
|
222 | 222 | btnCursor->setText("Cursor"); |
|
223 | 223 | btnCursor->setToolTip("Cursor"); |
|
224 | 224 | btnCursor->setPopupMode(QToolButton::InstantPopup); |
|
225 | 225 | auto cursorMenu = new QMenu("CursorMenu", this); |
|
226 | 226 | btnCursor->setMenu(cursorMenu); |
|
227 | 227 | |
|
228 | 228 | auto noCursorAction = cursorMenu->addAction("No Cursor"); |
|
229 | 229 | noCursorAction->setCheckable(true); |
|
230 |
noCursorAction->setChecked( |
|
|
231 |
|
|
|
230 | noCursorAction->setChecked( | |
|
231 | sqpApp->plotsCursorMode() == SqpApplication::PlotsCursorMode::NoCursor); | |
|
232 | 232 | connect(noCursorAction, &QAction::triggered, |
|
233 | 233 |
|
|
234 | 234 | |
|
235 | 235 | cursorMenu->addSeparator(); |
|
236 | 236 | auto verticalCursorAction = cursorMenu->addAction("Vertical Cursor"); |
|
237 | 237 | verticalCursorAction->setCheckable(true); |
|
238 |
verticalCursorAction->setChecked( |
|
|
239 |
|
|
|
238 | verticalCursorAction->setChecked( | |
|
239 | sqpApp->plotsCursorMode() == SqpApplication::PlotsCursorMode::Vertical); | |
|
240 | 240 | connect(verticalCursorAction, &QAction::triggered, |
|
241 | 241 |
|
|
242 | 242 | |
|
243 | 243 | auto temporalCursorAction = cursorMenu->addAction("Temporal Cursor"); |
|
244 | 244 | temporalCursorAction->setCheckable(true); |
|
245 |
temporalCursorAction->setChecked( |
|
|
246 |
|
|
|
245 | temporalCursorAction->setChecked( | |
|
246 | sqpApp->plotsCursorMode() == SqpApplication::PlotsCursorMode::Temporal); | |
|
247 | 247 | connect(temporalCursorAction, &QAction::triggered, |
|
248 | 248 |
|
|
249 | 249 | |
|
250 | 250 | auto horizontalCursorAction = cursorMenu->addAction("Horizontal Cursor"); |
|
251 | 251 | horizontalCursorAction->setCheckable(true); |
|
252 |
horizontalCursorAction->setChecked( |
|
|
253 |
|
|
|
252 | horizontalCursorAction->setChecked( | |
|
253 | sqpApp->plotsCursorMode() == SqpApplication::PlotsCursorMode::Horizontal); | |
|
254 | 254 | connect(horizontalCursorAction, &QAction::triggered, |
|
255 | 255 |
|
|
256 | 256 | |
|
257 | 257 | auto crossCursorAction = cursorMenu->addAction("Cross Cursor"); |
|
258 | 258 | crossCursorAction->setCheckable(true); |
|
259 |
crossCursorAction->setChecked( |
|
|
260 |
|
|
|
259 | crossCursorAction->setChecked( | |
|
260 | sqpApp->plotsCursorMode() == SqpApplication::PlotsCursorMode::Cross); | |
|
261 | 261 | connect(crossCursorAction, &QAction::triggered, |
|
262 | 262 |
|
|
263 | 263 | |
|
264 | 264 | mainToolBar->addWidget(btnCursor); |
|
265 | 265 | |
|
266 | 266 | auto cursorModeActionGroup = new QActionGroup{this}; |
|
267 | 267 | cursorModeActionGroup->setExclusive(true); |
|
268 | 268 | cursorModeActionGroup->addAction(noCursorAction); |
|
269 | 269 | cursorModeActionGroup->addAction(verticalCursorAction); |
|
270 | 270 | cursorModeActionGroup->addAction(temporalCursorAction); |
|
271 | 271 | cursorModeActionGroup->addAction(horizontalCursorAction); |
|
272 | 272 | cursorModeActionGroup->addAction(crossCursorAction); |
|
273 | 273 | |
|
274 | 274 | // Catalog |
|
275 | 275 | mainToolBar->addSeparator(); |
|
276 | mainToolBar->addAction(QIcon(":/icones/catalogue.png"), "Catalogues", | |
|
277 |
|
|
|
276 | // mainToolBar->addAction(QIcon(":/icones/catalogue.png"), "Catalogues", | |
|
277 | // [this]() { impl->m_CatalogExplorer->show(); }); | |
|
278 | 278 | |
|
279 | 279 | // //////// // |
|
280 | 280 | // Settings // |
|
281 | 281 | // //////// // |
|
282 | 282 | |
|
283 | 283 | // Registers "general settings" widget to the settings dialog |
|
284 |
impl->m_SettingsDialog->registerWidget( |
|
|
285 | impl->m_GeneralSettingsWidget); | |
|
284 | impl->m_SettingsDialog->registerWidget( | |
|
285 | QStringLiteral("General"), impl->m_GeneralSettingsWidget); | |
|
286 | 286 | |
|
287 | 287 | // /////////// // |
|
288 | 288 | // Connections // |
|
289 | 289 | // /////////// // |
|
290 | 290 | |
|
291 | 291 | // Controllers / controllers connections |
|
292 |
// connect(&sqpApp->timeController(), SIGNAL(timeUpdated(DateTimeRange)), |
|
|
292 | // connect(&sqpApp->timeController(), SIGNAL(timeUpdated(DateTimeRange)), | |
|
293 | // &sqpApp->variableController(), | |
|
293 | 294 | // SLOT(onDateTimeOnSelection(DateTimeRange))); |
|
294 | 295 | |
|
295 | 296 | // Widgets / controllers connections |
|
296 | 297 | |
|
297 | 298 | // DataSource |
|
298 | 299 |
connect(&sqpApp->dataSourceController(), SIGNAL(dataSourceItemSet(DataSourceItem |
|
299 | 300 |
|
|
300 | 301 | |
|
301 | 302 | // Time |
|
302 | 303 | connect(timeWidget, SIGNAL(timeUpdated(DateTimeRange)), &sqpApp->timeController(), |
|
303 | 304 |
|
|
304 | 305 | |
|
305 | 306 | // Visualization |
|
306 | 307 | connect(&sqpApp->visualizationController(), |
|
307 | 308 |
|
|
308 | 309 |
|
|
309 | 310 | |
|
310 | 311 | connect(&sqpApp->visualizationController(), |
|
311 | 312 |
|
|
312 | 313 |
|
|
313 | 314 | |
|
314 | 315 | // Widgets / widgets connections |
|
315 | 316 | |
|
316 | 317 | // For the following connections, we use DirectConnection to allow each widget that can |
|
317 | 318 | // potentially attach a menu to the variable's menu to do so before this menu is displayed. |
|
318 | 319 | // The order of connections is also important, since it determines the order in which each |
|
319 | 320 | // widget will attach its menu |
|
320 | connect( | |
|
321 | m_Ui->variableInspectorWidget, | |
|
321 | connect(m_Ui->variableInspectorWidget, | |
|
322 | 322 |
SIGNAL(tableMenuAboutToBeDisplayed(QMenu |
|
323 | 323 |
m_Ui->view, SLOT(attachVariableMenu(QMenu |
|
324 | 324 | Qt::DirectConnection); |
|
325 | 325 | } |
|
326 | 326 | |
|
327 | MainWindow::~MainWindow() | |
|
328 | { | |
|
329 | } | |
|
327 | MainWindow::~MainWindow() {} | |
|
330 | 328 | |
|
331 | 329 |
void MainWindow::changeEvent(QEvent |
|
332 | 330 | { |
|
333 | 331 | QMainWindow::changeEvent(e); |
|
334 |
switch (e->type()) |
|
|
332 | switch (e->type()) | |
|
333 | { | |
|
335 | 334 | case QEvent::LanguageChange: |
|
336 | 335 | m_Ui->retranslateUi(this); |
|
337 | 336 | break; |
|
338 | 337 | default: |
|
339 | 338 | break; |
|
340 | 339 | } |
|
341 | 340 | } |
|
342 | 341 | |
|
343 | 342 |
void MainWindow::closeEvent(QCloseEvent |
|
344 | 343 | { |
|
345 |
if (!impl->checkDataToSave(this)) |
|
|
344 | if (!impl->checkDataToSave(this)) | |
|
345 | { | |
|
346 | 346 | event->ignore(); |
|
347 | 347 | } |
|
348 |
else |
|
|
348 | else | |
|
349 | { | |
|
349 | 350 | event->accept(); |
|
350 | 351 | } |
|
351 | 352 | } |
|
352 | 353 | |
|
353 | 354 |
void MainWindow::keyPressEvent(QKeyEvent |
|
354 | 355 | { |
|
355 | 356 | switch (event->key()) |
|
356 | 357 | { |
|
357 | 358 | case Qt::Key_F11: |
|
358 | 359 | if(this->isFullScreen()) |
|
359 | 360 | { |
|
360 | 361 | this->showNormal(); |
|
361 | 362 | } |
|
362 | 363 | else |
|
363 | 364 | { |
|
364 | 365 | this->showFullScreen(); |
|
365 | 366 | } |
|
366 | 367 | break; |
|
367 | 368 | default: |
|
368 | 369 | break; |
|
369 | 370 | } |
|
370 | 371 | } |
|
371 | 372 | |
|
372 | 373 |
bool MainWindow::MainWindowPrivate::checkDataToSave(QWidget |
|
373 | 374 | { |
|
374 | auto hasChanges = sqpApp->catalogueController().hasChanges(); | |
|
375 |
if (hasChanges) |
|
|
376 | // There are some unsaved changes | |
|
377 | switch (QMessageBox::question( | |
|
378 | parentWidget, tr("Save changes"), | |
|
379 | tr("The catalogue controller has unsaved changes.\nDo you want to save them ?"), | |
|
380 | QMessageBox::SaveAll | QMessageBox::Discard | QMessageBox::Cancel, | |
|
381 |
QMessageBox::SaveAll)) |
|
|
382 | case QMessageBox::SaveAll: | |
|
383 | sqpApp->catalogueController().saveAll(); | |
|
384 | break; | |
|
385 | case QMessageBox::Discard: | |
|
386 | break; | |
|
387 | case QMessageBox::Cancel: | |
|
388 | default: | |
|
389 | return false; | |
|
390 | } | |
|
391 | } | |
|
375 | // auto hasChanges = sqpApp->catalogueController().hasChanges(); | |
|
376 | // if (hasChanges) | |
|
377 | // { | |
|
378 | // // There are some unsaved changes | |
|
379 | // switch (QMessageBox::question(parentWidget, tr("Save changes"), | |
|
380 | // tr("The catalogue controller has unsaved changes.\nDo you want to save them ?"), | |
|
381 | // QMessageBox::SaveAll | QMessageBox::Discard | QMessageBox::Cancel, | |
|
382 | // QMessageBox::SaveAll)) | |
|
383 | // { | |
|
384 | // case QMessageBox::SaveAll: | |
|
385 | // sqpApp->catalogueController().saveAll(); | |
|
386 | // break; | |
|
387 | // case QMessageBox::Discard: | |
|
388 | // break; | |
|
389 | // case QMessageBox::Cancel: | |
|
390 | // default: | |
|
391 | // return false; | |
|
392 | // } | |
|
393 | // } | |
|
392 | 394 | |
|
393 | 395 | return true; |
|
394 | 396 | } |
@@ -1,1 +1,1 | |||
|
1 | Subproject commit 5eaca9d9803c4051e857e1b4064748638dab02aa | |
|
1 | Subproject commit 548ec6a0c922e626003babc8b21a3953b777eae2 |
@@ -1,54 +1,186 | |||
|
1 | 1 | ο»ΏFILE (GLOB_RECURSE gui_SRCS |
|
2 | include/*.h | |
|
3 | src/*.cpp | |
|
4 | resources/*.qrc | |
|
2 | ||
|
3 | include/DataSource/DataSourceWidget.h | |
|
4 | include/DataSource/DataSourceTreeWidget.h | |
|
5 | include/DataSource/DataSourceTreeWidgetItem.h | |
|
6 | include/DataSource/DataSourceTreeWidgetHelper.h | |
|
7 | include/SqpApplication.h | |
|
8 | include/Common/ColorUtils.h | |
|
9 | include/Common/VisualizationDef.h | |
|
10 | include/SidePane/SqpSidePane.h | |
|
11 | include/Catalogue2/eventsmodel.h | |
|
12 | include/Catalogue2/eventstreeview.h | |
|
13 | include/Catalogue2/repositoriesmodel.h | |
|
14 | # include/Catalogue/CatalogueActionManager.h | |
|
15 | # include/Catalogue/CatalogueTreeModel.h | |
|
16 | # include/Catalogue/CatalogueExplorer.h | |
|
17 | # include/Catalogue/CatalogueSideBarWidget.h | |
|
18 | # include/Catalogue/CatalogueInspectorWidget.h | |
|
19 | # include/Catalogue/CatalogueTreeItems/CatalogueTextTreeItem.h | |
|
20 | # include/Catalogue/CatalogueTreeItems/CatalogueTreeItem.h | |
|
21 | # include/Catalogue/CatalogueTreeItems/CatalogueAbstractTreeItem.h | |
|
22 | # include/Catalogue/CatalogueEventsModel.h | |
|
23 | # include/Catalogue/CatalogueEventsWidget.h | |
|
24 | # include/Catalogue/CatalogueExplorerHelper.h | |
|
25 | include/Visualization/VisualizationGraphHelper.h | |
|
26 | include/Visualization/VisualizationTabWidget.h | |
|
27 | include/Visualization/VisualizationDefs.h | |
|
28 | include/Visualization/QCustomPlotSynchronizer.h | |
|
29 | include/Visualization/QCPColorMapIterator.h | |
|
30 | include/Visualization/operations/GenerateVariableMenuOperation.h | |
|
31 | include/Visualization/operations/RemoveVariableOperation.h | |
|
32 | include/Visualization/operations/FindVariableOperation.h | |
|
33 | include/Visualization/operations/MenuBuilder.h | |
|
34 | include/Visualization/operations/RescaleAxeOperation.h | |
|
35 | include/Visualization/PlottablesRenderingUtils.h | |
|
36 | include/Visualization/IVisualizationWidgetVisitor.h | |
|
37 | include/Visualization/VisualizationGraphWidget.h | |
|
38 | include/Visualization/IVisualizationWidget.h | |
|
39 | include/Visualization/IVariableContainer.h | |
|
40 | include/Visualization/SqpColorScale.h | |
|
41 | include/Visualization/VisualizationWidget.h | |
|
42 | include/Visualization/VisualizationZoneWidget.h | |
|
43 | include/Visualization/VisualizationMultiZoneSelectionDialog.h | |
|
44 | include/Visualization/VisualizationGraphRenderingDelegate.h | |
|
45 | include/Visualization/AxisRenderingUtils.h | |
|
46 | include/Visualization/VisualizationSelectionZoneItem.h | |
|
47 | include/Visualization/VisualizationDragWidget.h | |
|
48 | include/Visualization/VisualizationActionManager.h | |
|
49 | include/Visualization/IGraphSynchronizer.h | |
|
50 | include/Visualization/ColorScaleEditor.h | |
|
51 | include/Visualization/MacScrollBarStyle.h | |
|
52 | include/Visualization/VisualizationSelectionZoneManager.h | |
|
53 | include/Visualization/qcustomplot.h | |
|
54 | include/Visualization/VisualizationDragDropContainer.h | |
|
55 | include/Visualization/VisualizationCursorItem.h | |
|
56 | include/Settings/SqpSettingsDialog.h | |
|
57 | include/Settings/SqpSettingsGeneralWidget.h | |
|
58 | include/Variable/VariableMenuHeaderWidget.h | |
|
59 | include/Variable/VariableInspectorTableView.h | |
|
60 | include/Variable/VariableInspectorWidget.h | |
|
61 | include/Variable/RenameVariableDialog.h | |
|
62 | include/TimeWidget/TimeWidget.h | |
|
63 | include/DragAndDrop/DragDropScroller.h | |
|
64 | include/DragAndDrop/DragDropTabSwitcher.h | |
|
65 | include/DragAndDrop/DragDropGuiController.h | |
|
66 | include/Actions/FilteringAction.h | |
|
67 | include/Actions/ActionsGuiController.h | |
|
68 | include/Actions/SelectionZoneAction.h | |
|
69 | ||
|
70 | ||
|
71 | ||
|
72 | ||
|
73 | src/DataSource/DataSourceTreeWidgetItem.cpp | |
|
74 | src/DataSource/DataSourceWidget.cpp | |
|
75 | src/DataSource/DataSourceTreeWidget.cpp | |
|
76 | src/DataSource/DataSourceTreeWidgetHelper.cpp | |
|
77 | src/Common/ColorUtils.cpp | |
|
78 | src/Common/VisualizationDef.cpp | |
|
79 | src/SidePane/SqpSidePane.cpp | |
|
80 | src/Catalogue2/eventsmodel.cpp | |
|
81 | src/Catalogue2/eventstreeview.cpp | |
|
82 | src/Catalogue2/repositoriesmodel.cpp | |
|
83 | #src/Catalogue/CatalogueEventsWidget.cpp | |
|
84 | #src/Catalogue/CatalogueSideBarWidget.cpp | |
|
85 | #src/Catalogue/CatalogueTreeItems/CatalogueAbstractTreeItem.cpp | |
|
86 | #src/Catalogue/CatalogueTreeItems/CatalogueTextTreeItem.cpp | |
|
87 | #src/Catalogue/CatalogueTreeItems/CatalogueTreeItem.cpp | |
|
88 | #src/Catalogue/CatalogueExplorerHelper.cpp | |
|
89 | #src/Catalogue/CatalogueExplorer.cpp | |
|
90 | #src/Catalogue/CatalogueTreeModel.cpp | |
|
91 | #src/Catalogue/CatalogueInspectorWidget.cpp | |
|
92 | #src/Catalogue/CatalogueEventsModel.cpp | |
|
93 | #src/Catalogue/CatalogueActionManager.cpp | |
|
94 | src/Visualization/VisualizationDragDropContainer.cpp | |
|
95 | src/Visualization/VisualizationTabWidget.cpp | |
|
96 | src/Visualization/VisualizationWidget.cpp | |
|
97 | src/Visualization/MacScrollBarStyle.cpp | |
|
98 | src/Visualization/VisualizationCursorItem.cpp | |
|
99 | src/Visualization/operations/MenuBuilder.cpp | |
|
100 | src/Visualization/operations/RemoveVariableOperation.cpp | |
|
101 | src/Visualization/operations/FindVariableOperation.cpp | |
|
102 | src/Visualization/operations/GenerateVariableMenuOperation.cpp | |
|
103 | src/Visualization/operations/RescaleAxeOperation.cpp | |
|
104 | src/Visualization/AxisRenderingUtils.cpp | |
|
105 | src/Visualization/PlottablesRenderingUtils.cpp | |
|
106 | src/Visualization/VisualizationGraphRenderingDelegate.cpp | |
|
107 | src/Visualization/VisualizationSelectionZoneManager.cpp | |
|
108 | src/Visualization/QCPColorMapIterator.cpp | |
|
109 | src/Visualization/ColorScaleEditor.cpp | |
|
110 | src/Visualization/VisualizationGraphHelper.cpp | |
|
111 | src/Visualization/VisualizationGraphWidget.cpp | |
|
112 | src/Visualization/VisualizationDragWidget.cpp | |
|
113 | src/Visualization/VisualizationZoneWidget.cpp | |
|
114 | src/Visualization/VisualizationActionManager.cpp | |
|
115 | src/Visualization/VisualizationSelectionZoneItem.cpp | |
|
116 | src/Visualization/QCustomPlotSynchronizer.cpp | |
|
117 | src/Visualization/qcustomplot.cpp | |
|
118 | src/Visualization/VisualizationMultiZoneSelectionDialog.cpp | |
|
119 | src/Visualization/SqpColorScale.cpp | |
|
120 | src/Settings/SqpSettingsGeneralWidget.cpp | |
|
121 | src/Settings/SqpSettingsDialog.cpp | |
|
122 | src/SqpApplication.cpp | |
|
123 | src/Variable/VariableInspectorWidget.cpp | |
|
124 | src/Variable/VariableMenuHeaderWidget.cpp | |
|
125 | src/Variable/RenameVariableDialog.cpp | |
|
126 | src/Variable/VariableInspectorTableView.cpp | |
|
127 | src/TimeWidget/TimeWidget.cpp | |
|
128 | src/DragAndDrop/DragDropScroller.cpp | |
|
129 | src/DragAndDrop/DragDropTabSwitcher.cpp | |
|
130 | src/DragAndDrop/DragDropGuiController.cpp | |
|
131 | src/Actions/ActionsGuiController.cpp | |
|
132 | src/Actions/SelectionZoneAction.cpp | |
|
133 | src/Actions/FilteringAction.cpp | |
|
134 | ||
|
135 | ./resources/sqpguiresources.qrc | |
|
5 | 136 | ) |
|
6 | 137 | |
|
138 | ||
|
7 | 139 | QT5_WRAP_UI( |
|
8 | 140 | UiGenerated_SRCS |
|
9 | 141 | ui/DataSource/DataSourceWidget.ui |
|
10 | 142 | ui/Settings/SqpSettingsDialog.ui |
|
11 | 143 | ui/Settings/SqpSettingsGeneralWidget.ui |
|
12 | 144 | ui/SidePane/SqpSidePane.ui |
|
13 | 145 | ui/TimeWidget/TimeWidget.ui |
|
14 | 146 | ui/Variable/RenameVariableDialog.ui |
|
15 | 147 | ui/Variable/VariableInspectorWidget.ui |
|
16 | 148 | ui/Variable/VariableMenuHeaderWidget.ui |
|
17 | 149 | ui/Visualization/ColorScaleEditor.ui |
|
18 | 150 | ui/Visualization/VisualizationGraphWidget.ui |
|
19 | 151 | ui/Visualization/VisualizationTabWidget.ui |
|
20 | 152 | ui/Visualization/VisualizationWidget.ui |
|
21 | 153 | ui/Visualization/VisualizationZoneWidget.ui |
|
22 | 154 | ui/Visualization/VisualizationMultiZoneSelectionDialog.ui |
|
23 | ui/Catalogue/CatalogueEventsWidget.ui | |
|
24 | ui/Catalogue/CatalogueExplorer.ui | |
|
25 | ui/Catalogue/CatalogueInspectorWidget.ui | |
|
26 | ui/Catalogue/CatalogueSideBarWidget.ui | |
|
155 | #ui/Catalogue/CatalogueEventsWidget.ui | |
|
156 | #ui/Catalogue/CatalogueExplorer.ui | |
|
157 | #ui/Catalogue/CatalogueInspectorWidget.ui | |
|
158 | #ui/Catalogue/CatalogueSideBarWidget.ui | |
|
27 | 159 | ) |
|
28 | 160 | |
|
29 | 161 | add_library(sciqlopgui ${gui_SRCS} ${UiGenerated_SRCS}) |
|
30 | 162 | SET_TARGET_PROPERTIES(sciqlopgui PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE) |
|
31 | 163 | |
|
32 | 164 | target_include_directories(sciqlopgui PUBLIC |
|
33 | 165 | $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> |
|
34 | 166 | $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/Visualization> |
|
35 | 167 | $<INSTALL_INTERFACE:include/SciQLOP> |
|
36 | 168 | ) |
|
37 | 169 | |
|
38 | 170 | target_link_libraries(sciqlopgui PUBLIC |
|
39 | 171 | Qt5::Widgets |
|
40 | 172 | Qt5::PrintSupport |
|
41 | 173 | Qt5::Svg |
|
42 | 174 | sciqlopcore |
|
43 | 175 | ) |
|
44 | 176 | |
|
45 | 177 | install(TARGETS sciqlopgui EXPORT SciQLOPGuiConfig |
|
46 | 178 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} |
|
47 | 179 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} |
|
48 | 180 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) |
|
49 | 181 | |
|
50 | 182 | install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/SciQLOP) |
|
51 | 183 | install(EXPORT SciQLOPGuiConfig DESTINATION share/SciQLOPGui/cmake) |
|
52 | 184 | export(TARGETS sciqlopgui FILE SciQLOPGuiConfig.cmake) |
|
53 | 185 | |
|
54 | 186 | subdirs(tests) |
@@ -1,70 +1,85 | |||
|
1 | 1 | #ifndef SCIQLOP_CATALOGUEEVENTSMODEL_H |
|
2 | 2 | #define SCIQLOP_CATALOGUEEVENTSMODEL_H |
|
3 | 3 | |
|
4 | 4 | #include <Common/spimpl.h> |
|
5 | 5 | #include <QAbstractItemModel> |
|
6 | 6 | #include <QLoggingCategory> |
|
7 | 7 | #include <unordered_set> |
|
8 | #include <vector> | |
|
8 | 9 | |
|
9 | class DBCatalogue; | |
|
10 | class DBEvent; | |
|
11 | class DBEventProduct; | |
|
10 | #include <Catalogue/CatalogueController.h> | |
|
12 | 11 | |
|
13 | 12 | Q_DECLARE_LOGGING_CATEGORY(LOG_CatalogueEventsModel) |
|
14 | 13 | |
|
15 |
class CatalogueEventsModel : public QAbstractItemModel |
|
|
14 | class CatalogueEventsModel : public QAbstractItemModel | |
|
15 | { | |
|
16 | 16 | Q_OBJECT |
|
17 | 17 | |
|
18 | 18 | signals: |
|
19 | 19 | void modelSorted(); |
|
20 | 20 | |
|
21 | 21 | public: |
|
22 | 22 |
CatalogueEventsModel(QObject |
|
23 | 23 | |
|
24 | enum class Column { Name, TStart, TEnd, Tags, Product, Validation, NbColumn }; | |
|
24 | enum class Column | |
|
25 | { | |
|
26 | Name, | |
|
27 | TStart, | |
|
28 | TEnd, | |
|
29 | Tags, | |
|
30 | Product, | |
|
31 | Validation, | |
|
32 | NbColumn | |
|
33 | }; | |
|
25 | 34 | |
|
26 | 35 |
void setSourceCatalogues(const QVector<std::shared_ptr<DBCatalogue> |
|
27 |
void setEvents(const |
|
|
36 | void setEvents(const std::vector<CatalogueController::Event_ptr>& events); | |
|
28 | 37 |
void addEvent(const std::shared_ptr<DBEvent> |
|
29 | 38 |
void removeEvent(const std::shared_ptr<DBEvent> |
|
30 | QVector<std::shared_ptr<DBEvent> > events() const; | |
|
39 | std::vector<CatalogueController::Event_ptr> events() const; | |
|
31 | 40 | |
|
32 | enum class ItemType { Root, Event, EventProduct }; | |
|
41 | enum class ItemType | |
|
42 | { | |
|
43 | Root, | |
|
44 | Event, | |
|
45 | EventProduct | |
|
46 | }; | |
|
33 | 47 |
ItemType itemTypeOf(const QModelIndex |
|
34 |
|
|
|
35 |
|
|
|
36 |
std:: |
|
|
48 | CatalogueController::Event_ptr getEvent(const QModelIndex& index) const; | |
|
49 | CatalogueController::Event_ptr getParentEvent(const QModelIndex& index) const; | |
|
50 | std::optional<CatalogueController::Product_t> getEventProduct(const QModelIndex& index) const; | |
|
37 | 51 | |
|
38 | 52 | /// Refresh the data for the specified event |
|
39 | void refreshEvent(const std::shared_ptr<DBEvent> &event, bool refreshEventProducts = false); | |
|
53 | void refreshEvent( | |
|
54 | const CatalogueController::Event_ptr& event, bool refreshEventProducts = false); | |
|
40 | 55 | |
|
41 | 56 | /// Returns a QModelIndex which represent the specified event |
|
42 |
QModelIndex indexOf(const |
|
|
57 | QModelIndex indexOf(const CatalogueController::Event_ptr& event) const; | |
|
43 | 58 | |
|
44 | 59 | /// Marks a change flag on the specified event to allow sorting on the validation column |
|
45 | 60 |
void setEventHasChanges(const std::shared_ptr<DBEvent> |
|
46 | 61 | |
|
47 | 62 | /// Returns true if the specified event has unsaved changes |
|
48 | 63 |
bool eventsHasChanges(const std::shared_ptr<DBEvent> |
|
49 | 64 | |
|
50 | 65 | // Model |
|
51 | 66 |
QModelIndex index(int row, int column, const QModelIndex |
|
52 | 67 |
QModelIndex parent(const QModelIndex |
|
53 | 68 |
int rowCount(const QModelIndex |
|
54 | 69 |
int columnCount(const QModelIndex |
|
55 | 70 |
Qt::ItemFlags flags(const QModelIndex |
|
56 | 71 |
QVariant data(const QModelIndex |
|
57 | QVariant headerData(int section, Qt::Orientation orientation, | |
|
58 |
|
|
|
72 | QVariant headerData( | |
|
73 | int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; | |
|
59 | 74 | void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override; |
|
60 | 75 | |
|
61 | 76 | Qt::DropActions supportedDragActions() const override; |
|
62 | 77 | QStringList mimeTypes() const override; |
|
63 | 78 |
QMimeData |
|
64 | 79 | |
|
65 | 80 | private: |
|
66 | 81 | class CatalogueEventsModelPrivate; |
|
67 | 82 | spimpl::unique_impl_ptr<CatalogueEventsModelPrivate> impl; |
|
68 | 83 | }; |
|
69 | 84 | |
|
70 | 85 | #endif // SCIQLOP_CATALOGUEEVENTSMODEL_H |
@@ -1,174 +1,190 | |||
|
1 | 1 | #include "Catalogue/CatalogueActionManager.h" |
|
2 | 2 | |
|
3 | 3 | #include <Actions/ActionsGuiController.h> |
|
4 | 4 | #include <Catalogue/CatalogueController.h> |
|
5 | 5 | #include <DataSource/DataSourceItem.h> |
|
6 | 6 | #include <SqpApplication.h> |
|
7 | 7 | #include <Variable/Variable.h> |
|
8 | 8 | #include <Visualization/VisualizationGraphWidget.h> |
|
9 | 9 | #include <Visualization/VisualizationSelectionZoneItem.h> |
|
10 | 10 | |
|
11 | 11 | #include <Catalogue/CatalogueEventsWidget.h> |
|
12 | 12 | #include <Catalogue/CatalogueExplorer.h> |
|
13 | 13 | #include <Catalogue/CatalogueSideBarWidget.h> |
|
14 | 14 | |
|
15 | #include <CatalogueDao.h> | |
|
16 | #include <DBCatalogue.h> | |
|
17 | #include <DBEvent.h> | |
|
18 | #include <DBEventProduct.h> | |
|
15 | //#include <CatalogueDao.h> | |
|
16 | //#include <DBCatalogue.h> | |
|
17 | //#include <DBEvent.h> | |
|
18 | //#include <DBEventProduct.h> | |
|
19 | ||
|
20 | #include <Catalogue/CatalogueController.h> | |
|
21 | #include <Event.hpp> | |
|
19 | 22 | |
|
20 | 23 | #include <QBoxLayout> |
|
21 | 24 | #include <QComboBox> |
|
22 | 25 | #include <QDialog> |
|
23 | 26 | #include <QDialogButtonBox> |
|
24 | 27 | #include <QLineEdit> |
|
25 | 28 | #include <memory> |
|
26 | 29 | |
|
27 | 30 | const auto CATALOGUE_MENU_NAME = QObject::tr("Catalogues"); |
|
28 | 31 | const auto CATALOGUE_CREATE_EVENT_MENU_NAME = QObject::tr("New Event..."); |
|
29 | 32 | |
|
30 | 33 | const auto DEFAULT_EVENT_NAME = QObject::tr("Event"); |
|
31 | 34 | const auto DEFAULT_CATALOGUE_NAME = QObject::tr("Catalogue"); |
|
32 | 35 | |
|
33 |
struct CatalogueActionManager::CatalogueActionManagerPrivate |
|
|
36 | struct CatalogueActionManager::CatalogueActionManagerPrivate | |
|
37 | { | |
|
34 | 38 | |
|
35 | 39 |
CatalogueExplorer |
|
36 | 40 |
QVector<std::shared_ptr<SelectionZoneAction> |
|
37 | 41 | |
|
38 | 42 |
CatalogueActionManagerPrivate(CatalogueExplorer |
|
39 | 43 | : m_CatalogueExplorer(catalogueExplorer) |
|
40 | 44 | { |
|
41 | 45 | } |
|
42 | 46 | |
|
43 | 47 |
void createEventFromZones(const QString |
|
44 | 48 |
|
|
45 | const std::shared_ptr<DBCatalogue> &catalogue = nullptr) | |
|
49 | const CatalogueController::Catalogue_ptr& catalogue = nullptr) | |
|
46 | 50 | { |
|
47 |
auto event = |
|
|
48 |
event-> |
|
|
51 | auto event = CatalogueController::make_event_ptr(); | |
|
52 | event->name = eventName.toStdString(); | |
|
49 | 53 | |
|
50 | std::list<DBEventProduct> productList; | |
|
51 |
for (auto zone : zones) |
|
|
54 | // std::list<DBEventProduct> productList; | |
|
55 | for (auto zone : zones) | |
|
56 | { | |
|
52 | 57 | auto graph = zone->parentGraphWidget(); |
|
53 |
for (auto var : graph->variables()) |
|
|
54 | auto eventProduct = std::make_shared<DBEventProduct>(); | |
|
55 | eventProduct->setEvent(*event); | |
|
58 | for (auto var : graph->variables()) | |
|
59 | { | |
|
56 | 60 | |
|
61 | auto eventProduct = CatalogueController::Product_t(); | |
|
57 | 62 | auto productId |
|
58 | 63 | = var->metadata().value(DataSourceItem::ID_DATA_KEY, "UnknownID").toString(); |
|
59 | 64 | |
|
60 | 65 | auto zoneRange = zone->range(); |
|
61 |
eventProduct |
|
|
62 |
eventProduct |
|
|
66 | eventProduct.startTime = zoneRange.m_TStart; | |
|
67 | eventProduct.stopTime = zoneRange.m_TEnd; | |
|
63 | 68 | |
|
64 |
eventProduct |
|
|
65 | ||
|
66 | productList.push_back(*eventProduct); | |
|
69 | eventProduct.name = productId.toStdString(); | |
|
70 | event->products.push_back(std::move(eventProduct)); | |
|
67 | 71 | } |
|
68 | 72 | } |
|
69 | 73 | |
|
70 | event->setEventProducts(productList); | |
|
71 | ||
|
72 | sqpApp->catalogueController().addEvent(event); | |
|
74 | sqpApp->catalogueController().add(event); | |
|
73 | 75 | |
|
74 | 76 | |
|
75 |
if (catalogue) |
|
|
76 | catalogue->addEvent(event->getUniqId()); | |
|
77 | sqpApp->catalogueController().updateCatalogue(catalogue); | |
|
78 | m_CatalogueExplorer->sideBarWidget().setCatalogueChanges(catalogue, true); | |
|
79 | if (m_CatalogueExplorer->eventsWidget().displayedCatalogues().contains(catalogue)) { | |
|
80 | m_CatalogueExplorer->eventsWidget().addEvent(event); | |
|
81 |
m_CatalogueExplorer-> |
|
|
82 | } | |
|
83 | } | |
|
84 | else if (m_CatalogueExplorer->eventsWidget().isAllEventsDisplayed()) { | |
|
85 | m_CatalogueExplorer->eventsWidget().addEvent(event); | |
|
86 | m_CatalogueExplorer->eventsWidget().setEventChanges(event, true); | |
|
77 | if (catalogue) | |
|
78 | { | |
|
79 | catalogue->add(event); | |
|
80 | // TODO use notifications | |
|
81 | // this shouldn't know GUI stuff and care about which widget to update | |
|
82 | // sqpApp->catalogueController().updateCatalogue(catalogue); | |
|
83 | // m_CatalogueExplorer->sideBarWidget().setCatalogueChanges(catalogue, true); | |
|
84 | // if | |
|
85 | // (m_CatalogueExplorer->eventsWidget().displayedCatalogues().contains(catalogue)) | |
|
86 | // { | |
|
87 | // m_CatalogueExplorer->eventsWidget().addEvent(event); | |
|
88 | // m_CatalogueExplorer->eventsWidget().setEventChanges(event, true); | |
|
89 | // } | |
|
90 | } | |
|
91 | else if (m_CatalogueExplorer->eventsWidget().isAllEventsDisplayed()) | |
|
92 | { | |
|
93 | // m_CatalogueExplorer->eventsWidget().addEvent(event); | |
|
94 | // m_CatalogueExplorer->eventsWidget().setEventChanges(event, true); | |
|
87 | 95 | } |
|
88 | 96 | } |
|
89 | 97 | |
|
90 | 98 | SelectionZoneAction::EnableFunction createEventEnableFuntion() const |
|
91 | 99 | { |
|
92 | 100 | return [](auto zones) { |
|
93 | ||
|
94 | 101 | // Checks that all variables in the zones doesn't refer to the same product |
|
95 | 102 | QSet<QString> usedDatasource; |
|
96 |
for (auto zone : zones) |
|
|
103 | for (auto zone : zones) | |
|
104 | { | |
|
97 | 105 | auto graph = zone->parentGraphWidget(); |
|
98 | 106 | auto variables = graph->variables(); |
|
99 | 107 | |
|
100 |
for (auto var : variables) |
|
|
108 | for (auto var : variables) | |
|
109 | { | |
|
101 | 110 | auto datasourceId |
|
102 | 111 | = var->metadata().value(DataSourceItem::ID_DATA_KEY).toString(); |
|
103 |
if (!usedDatasource.contains(datasourceId)) |
|
|
112 | if (!usedDatasource.contains(datasourceId)) | |
|
113 | { | |
|
104 | 114 | usedDatasource.insert(datasourceId); |
|
105 | 115 | } |
|
106 |
else |
|
|
116 | else | |
|
117 | { | |
|
107 | 118 | return false; |
|
108 | 119 | } |
|
109 | 120 | } |
|
110 | 121 | } |
|
111 | 122 | |
|
112 | 123 | return true; |
|
113 | 124 | }; |
|
114 | 125 | } |
|
115 | 126 | }; |
|
116 | 127 | |
|
117 | 128 |
CatalogueActionManager::CatalogueActionManager(CatalogueExplorer |
|
118 | 129 | : impl{spimpl::make_unique_impl<CatalogueActionManagerPrivate>(catalogueExplorer)} |
|
119 | 130 | { |
|
120 | 131 | } |
|
121 | 132 | |
|
122 | 133 | void CatalogueActionManager::installSelectionZoneActions() |
|
123 | 134 | { |
|
124 | auto &actionController = sqpApp->actionsGuiController(); | |
|
135 | // auto &actionController = sqpApp->actionsGuiController(); | |
|
125 | 136 | |
|
126 | auto createEventAction = actionController.addSectionZoneAction( | |
|
127 |
{CATALOGUE_MENU_NAME, CATALOGUE_CREATE_EVENT_MENU_NAME}, QObject::tr("Without |
|
|
128 |
[this](auto zones) { impl->createEventFromZones(DEFAULT_EVENT_NAME, |
|
|
129 | createEventAction->setEnableFunction(impl->createEventEnableFuntion()); | |
|
130 | createEventAction->setAllowedFiltering(false); | |
|
137 | // auto createEventAction = actionController.addSectionZoneAction( | |
|
138 | // {CATALOGUE_MENU_NAME, CATALOGUE_CREATE_EVENT_MENU_NAME}, QObject::tr("Without | |
|
139 | // Catalogue"), [this](auto zones) { impl->createEventFromZones(DEFAULT_EVENT_NAME, | |
|
140 | // zones); }); | |
|
141 | // createEventAction->setEnableFunction(impl->createEventEnableFuntion()); | |
|
142 | // createEventAction->setAllowedFiltering(false); | |
|
131 | 143 | |
|
132 | auto createEventInNewCatalogueAction = actionController.addSectionZoneAction( | |
|
133 |
{CATALOGUE_MENU_NAME, CATALOGUE_CREATE_EVENT_MENU_NAME}, QObject::tr("In New |
|
|
134 | [this](auto zones) { | |
|
144 | // auto createEventInNewCatalogueAction = actionController.addSectionZoneAction( | |
|
145 | // {CATALOGUE_MENU_NAME, CATALOGUE_CREATE_EVENT_MENU_NAME}, QObject::tr("In New | |
|
146 | // Catalogue"), [this](auto zones) { | |
|
135 | 147 | |
|
136 | auto newCatalogue = std::make_shared<DBCatalogue>(); | |
|
137 | newCatalogue->setName(DEFAULT_CATALOGUE_NAME); | |
|
138 | sqpApp->catalogueController().addCatalogue(newCatalogue); | |
|
139 | impl->m_CatalogueExplorer->sideBarWidget().addCatalogue(newCatalogue, | |
|
140 | REPOSITORY_DEFAULT); | |
|
148 | // auto newCatalogue = std::make_shared<DBCatalogue>(); | |
|
149 | // newCatalogue->setName(DEFAULT_CATALOGUE_NAME); | |
|
150 | // sqpApp->catalogueController().addCatalogue(newCatalogue); | |
|
151 | // impl->m_CatalogueExplorer->sideBarWidget().addCatalogue(newCatalogue, | |
|
152 | // REPOSITORY_DEFAULT); | |
|
141 | 153 | |
|
142 | impl->createEventFromZones(DEFAULT_EVENT_NAME, zones, newCatalogue); | |
|
143 | }); | |
|
144 | createEventInNewCatalogueAction->setEnableFunction(impl->createEventEnableFuntion()); | |
|
145 | createEventInNewCatalogueAction->setAllowedFiltering(false); | |
|
154 | // impl->createEventFromZones(DEFAULT_EVENT_NAME, zones, newCatalogue); | |
|
155 | // }); | |
|
156 | // createEventInNewCatalogueAction->setEnableFunction(impl->createEventEnableFuntion()); | |
|
157 | // createEventInNewCatalogueAction->setAllowedFiltering(false); | |
|
146 | 158 | |
|
147 | refreshCreateInCatalogueAction(); | |
|
159 | // refreshCreateInCatalogueAction(); | |
|
148 | 160 | |
|
149 |
actionController.addFilterForMenu({CATALOGUE_MENU_NAME, |
|
|
161 | // actionController.addFilterForMenu({CATALOGUE_MENU_NAME, | |
|
162 | // CATALOGUE_CREATE_EVENT_MENU_NAME}); | |
|
150 | 163 | } |
|
151 | 164 | |
|
152 | 165 | void CatalogueActionManager::refreshCreateInCatalogueAction() |
|
153 | 166 | { |
|
154 |
auto |
|
|
155 | ||
|
156 |
for (auto action : impl->m_CreateInCatalogueActions) |
|
|
157 | actionController.removeAction(action); | |
|
158 | } | |
|
159 | impl->m_CreateInCatalogueActions.clear(); | |
|
160 | ||
|
161 | auto allCatalogues | |
|
162 | = impl->m_CatalogueExplorer->sideBarWidget().getCatalogues(REPOSITORY_DEFAULT); | |
|
163 | ||
|
164 | for (auto catalogue : allCatalogues) { | |
|
165 |
auto catalogue |
|
|
166 | auto createEventInCatalogueAction = actionController.addSectionZoneAction( | |
|
167 | {CATALOGUE_MENU_NAME, CATALOGUE_CREATE_EVENT_MENU_NAME}, | |
|
168 | QObject::tr("In \"").append(catalogueName).append("\""), [this, catalogue](auto zones) { | |
|
169 | impl->createEventFromZones(DEFAULT_EVENT_NAME, zones, catalogue); | |
|
170 | }); | |
|
171 | createEventInCatalogueAction->setEnableFunction(impl->createEventEnableFuntion()); | |
|
172 | impl->m_CreateInCatalogueActions << createEventInCatalogueAction; | |
|
173 | } | |
|
167 | // auto& actionController = sqpApp->actionsGuiController(); | |
|
168 | ||
|
169 | // for (auto action : impl->m_CreateInCatalogueActions) | |
|
170 | // { | |
|
171 | // actionController.removeAction(action); | |
|
172 | // } | |
|
173 | // impl->m_CreateInCatalogueActions.clear(); | |
|
174 | ||
|
175 | // auto allCatalogues | |
|
176 | // = impl->m_CatalogueExplorer->sideBarWidget().getCatalogues(REPOSITORY_DEFAULT); | |
|
177 | ||
|
178 | // for (auto catalogue : allCatalogues) | |
|
179 | // { | |
|
180 | // auto catalogueName = catalogue->getName(); | |
|
181 | // auto createEventInCatalogueAction = actionController.addSectionZoneAction( | |
|
182 | // { CATALOGUE_MENU_NAME, CATALOGUE_CREATE_EVENT_MENU_NAME }, | |
|
183 | // QObject::tr("In \"").append(catalogueName).append("\""), [this, catalogue](auto | |
|
184 | // zones) { | |
|
185 | // impl->createEventFromZones(DEFAULT_EVENT_NAME, zones, catalogue); | |
|
186 | // }); | |
|
187 | // createEventInCatalogueAction->setEnableFunction(impl->createEventEnableFuntion()); | |
|
188 | // impl->m_CreateInCatalogueActions << createEventInCatalogueAction; | |
|
189 | // } | |
|
174 | 190 | } |
@@ -1,484 +1,502 | |||
|
1 | 1 | #include "Catalogue/CatalogueEventsModel.h" |
|
2 | 2 | |
|
3 | 3 | #include <Catalogue/CatalogueController.h> |
|
4 | 4 | #include <Common/DateUtils.h> |
|
5 | 5 | #include <Common/MimeTypesDef.h> |
|
6 | #include <DBEvent.h> | |
|
7 | #include <DBEventProduct.h> | |
|
8 | #include <DBTag.h> | |
|
9 | 6 | #include <Data/DateTimeRange.h> |
|
7 | #include <Repository.hpp> | |
|
10 | 8 | #include <SqpApplication.h> |
|
11 | 9 | #include <Time/TimeController.h> |
|
12 | 10 | |
|
13 | 11 | #include <list> |
|
14 | 12 | #include <unordered_map> |
|
15 | 13 | |
|
16 | 14 | #include <QHash> |
|
17 | 15 | #include <QMimeData> |
|
18 | 16 | |
|
19 | 17 | Q_LOGGING_CATEGORY(LOG_CatalogueEventsModel, "CatalogueEventsModel") |
|
20 | 18 | |
|
21 | 19 | const auto EVENT_ITEM_TYPE = 1; |
|
22 | 20 | const auto EVENT_PRODUCT_ITEM_TYPE = 2; |
|
23 | 21 | |
|
24 |
struct CatalogueEventsModel::CatalogueEventsModelPrivate |
|
|
25 | QVector<std::shared_ptr<DBEvent> > m_Events; | |
|
26 | std::unordered_map<DBEvent *, QVector<std::shared_ptr<DBEventProduct> > > m_EventProducts; | |
|
27 | QVector<std::shared_ptr<DBCatalogue> > m_SourceCatalogue; | |
|
22 | struct CatalogueEventsModel::CatalogueEventsModelPrivate | |
|
23 | { | |
|
24 | std::vector<CatalogueController::Event_ptr> m_Events; | |
|
25 | // std::unordered_map<DBEvent*, QVector<std::shared_ptr<DBEventProduct>>> m_EventProducts; | |
|
26 | // QVector<std::shared_ptr<DBCatalogue>> m_SourceCatalogue; | |
|
28 | 27 | |
|
29 | 28 | QStringList columnNames() |
|
30 | 29 | { |
|
31 |
return QStringList{tr("Event"), tr("TStart"), |
|
|
32 | tr("Tags"), tr("Product"), tr("")}; | |
|
30 | return QStringList { tr("Event"), tr("TStart"), tr("TEnd"), tr("Tags"), tr("Product"), | |
|
31 | tr("") }; | |
|
33 | 32 | } |
|
34 | 33 | |
|
35 |
QVariant sortData(int col, const |
|
|
34 | QVariant sortData(int col, const CatalogueController::Event_ptr& event) const | |
|
35 | { | |
|
36 | if (col == (int)CatalogueEventsModel::Column::Validation) | |
|
36 | 37 | { |
|
37 | if (col == (int)CatalogueEventsModel::Column::Validation) { | |
|
38 | auto hasChanges = sqpApp->catalogueController().eventHasChanges(event); | |
|
38 | auto hasChanges = sqpApp->catalogueController().hasUnsavedChanges(event); | |
|
39 | 39 | return hasChanges ? true : QVariant(); |
|
40 | 40 | } |
|
41 | 41 | |
|
42 | 42 | return eventData(col, event); |
|
43 | 43 | } |
|
44 | 44 | |
|
45 |
QVariant eventData(int col, const |
|
|
45 | QVariant eventData(int col, const CatalogueController::Event_ptr& event) const | |
|
46 | { | |
|
47 | switch (static_cast<Column>(col)) | |
|
46 | 48 | { |
|
47 | switch (static_cast<Column>(col)) { | |
|
48 | 49 | case CatalogueEventsModel::Column::Name: |
|
49 |
return event-> |
|
|
50 | return QString::fromStdString(event->name); | |
|
50 | 51 | case CatalogueEventsModel::Column::TStart: |
|
51 | return nbEventProducts(event) > 0 | |
|
52 | ? DateUtils::dateTime(event->getTStart()) | |
|
53 | .toString(DATETIME_FORMAT_ONE_LINE) | |
|
54 |
|
|
|
52 | if (auto start = event->startTime()) | |
|
53 | return DateUtils::dateTime(*start).toString(DATETIME_FORMAT_ONE_LINE); | |
|
54 | else | |
|
55 | return QVariant {}; | |
|
55 | 56 | case CatalogueEventsModel::Column::TEnd: |
|
56 | return nbEventProducts(event) > 0 | |
|
57 | ? DateUtils::dateTime(event->getTEnd()) | |
|
58 | .toString(DATETIME_FORMAT_ONE_LINE) | |
|
59 |
|
|
|
60 |
case CatalogueEventsModel::Column::Product: |
|
|
61 | auto eventProducts = event->getEventProducts(); | |
|
57 | if (auto stop = event->stopTime()) | |
|
58 | return DateUtils::dateTime(*stop).toString(DATETIME_FORMAT_ONE_LINE); | |
|
59 | else | |
|
60 | return QVariant {}; | |
|
61 | case CatalogueEventsModel::Column::Product: | |
|
62 | { | |
|
62 | 63 | QStringList eventProductList; |
|
63 |
for (auto evtProduct : event |
|
|
64 | eventProductList << evtProduct.getProductId(); | |
|
64 | for (const auto& evtProduct : event->products) | |
|
65 | { | |
|
66 | eventProductList << QString::fromStdString(evtProduct.name); | |
|
65 | 67 | } |
|
66 | 68 | return eventProductList.join(";"); |
|
67 | 69 | } |
|
68 |
case CatalogueEventsModel::Column::Tags: |
|
|
70 | case CatalogueEventsModel::Column::Tags: | |
|
71 | { | |
|
69 | 72 | QString tagList; |
|
70 |
auto tag |
|
|
71 |
|
|
|
72 |
tagList += tag |
|
|
73 | for (const auto& tag : event->tags) | |
|
74 | { | |
|
75 | tagList += QString::fromStdString(tag); | |
|
73 | 76 | tagList += ' '; |
|
74 | 77 | } |
|
75 | ||
|
76 | 78 | return tagList; |
|
77 | 79 | } |
|
78 | 80 | case CatalogueEventsModel::Column::Validation: |
|
79 | 81 | return QVariant(); |
|
80 | 82 | default: |
|
81 | 83 | break; |
|
82 | 84 | } |
|
83 | 85 | |
|
84 | 86 | Q_ASSERT(false); |
|
85 | 87 | return QStringLiteral("Unknown Data"); |
|
86 | 88 | } |
|
87 | 89 | |
|
88 |
void parseEventProduct(const |
|
|
90 | void parseEventProduct(const CatalogueController::Event_ptr& event) | |
|
89 | 91 | { |
|
90 |
for (auto product : event-> |
|
|
91 | m_EventProducts[event.get()].append(std::make_shared<DBEventProduct>(product)); | |
|
92 | } | |
|
92 | // for (auto& product : event->products) | |
|
93 | // { | |
|
94 | // m_EventProducts[event.get()].append(std::make_shared<DBEventProduct>(product)); | |
|
95 | // } | |
|
93 | 96 | } |
|
94 | 97 | |
|
95 |
|
|
|
98 | std::size_t nbEventProducts(const CatalogueController::Event_ptr& event) const | |
|
99 | { | |
|
100 | if (event) | |
|
96 | 101 | { |
|
97 | auto eventProductsIt = m_EventProducts.find(event.get()); | |
|
98 | if (eventProductsIt != m_EventProducts.cend()) { | |
|
99 | return m_EventProducts.at(event.get()).count(); | |
|
102 | return event->products.size(); | |
|
100 | 103 | } |
|
101 |
else |
|
|
104 | else | |
|
105 | { | |
|
102 | 106 | return 0; |
|
103 | 107 | } |
|
104 | 108 | } |
|
105 | 109 | |
|
106 |
QVariant eventProductData(int col, const |
|
|
110 | QVariant eventProductData(int col, const CatalogueController::Product_t& eventProduct) const | |
|
111 | { | |
|
112 | switch (static_cast<Column>(col)) | |
|
107 | 113 | { |
|
108 | switch (static_cast<Column>(col)) { | |
|
109 | 114 | case CatalogueEventsModel::Column::Name: |
|
110 |
return eventProduct |
|
|
115 | return QString::fromStdString(eventProduct.name); | |
|
111 | 116 | case CatalogueEventsModel::Column::TStart: |
|
112 |
return DateUtils::dateTime(eventProduct |
|
|
117 | return DateUtils::dateTime(eventProduct.startTime) | |
|
113 | 118 | .toString(DATETIME_FORMAT_ONE_LINE); |
|
114 | 119 | case CatalogueEventsModel::Column::TEnd: |
|
115 |
return DateUtils::dateTime(eventProduct |
|
|
120 | return DateUtils::dateTime(eventProduct.stopTime) | |
|
116 | 121 | .toString(DATETIME_FORMAT_ONE_LINE); |
|
117 | 122 | case CatalogueEventsModel::Column::Product: |
|
118 |
return eventProduct |
|
|
123 | return QString::fromStdString(eventProduct.name); | |
|
119 | 124 | case CatalogueEventsModel::Column::Tags: |
|
120 | 125 | return QString(); |
|
121 | 126 | case CatalogueEventsModel::Column::Validation: |
|
122 | 127 | return QVariant(); |
|
123 | 128 | default: |
|
124 | 129 | break; |
|
125 | 130 | } |
|
126 | 131 | |
|
127 | 132 | Q_ASSERT(false); |
|
128 | 133 | return QStringLiteral("Unknown Data"); |
|
129 | 134 | } |
|
130 | 135 | |
|
131 | 136 |
void refreshChildrenOfIndex(CatalogueEventsModel |
|
132 | 137 | { |
|
133 | 138 | auto childCount = model->rowCount(index); |
|
134 | 139 | auto colCount = model->columnCount(); |
|
135 |
emit model->dataChanged( |
|
|
136 |
|
|
|
140 | emit model->dataChanged( | |
|
141 | model->index(0, 0, index), model->index(childCount, colCount, index)); | |
|
137 | 142 | } |
|
138 | 143 | }; |
|
139 | 144 | |
|
140 | 145 |
CatalogueEventsModel::CatalogueEventsModel(QObject |
|
141 | : QAbstractItemModel(parent), impl{spimpl::make_unique_impl<CatalogueEventsModelPrivate>()} | |
|
146 | : QAbstractItemModel(parent) | |
|
147 | , impl { spimpl::make_unique_impl<CatalogueEventsModelPrivate>() } | |
|
142 | 148 | { |
|
143 | 149 | } |
|
144 | 150 | |
|
145 | 151 | void CatalogueEventsModel::setSourceCatalogues( |
|
146 | 152 |
const QVector<std::shared_ptr<DBCatalogue> |
|
147 | 153 | { |
|
148 | impl->m_SourceCatalogue = catalogues; | |
|
154 | // impl->m_SourceCatalogue = catalogues; | |
|
149 | 155 | } |
|
150 | 156 | |
|
151 |
void CatalogueEventsModel::setEvents(const |
|
|
157 | void CatalogueEventsModel::setEvents(const std::vector<CatalogueController::Event_ptr>& events) | |
|
152 | 158 | { |
|
153 | 159 | beginResetModel(); |
|
154 | 160 | |
|
155 | 161 | impl->m_Events = events; |
|
156 | impl->m_EventProducts.clear(); | |
|
157 | for (auto event : events) { | |
|
158 | impl->parseEventProduct(event); | |
|
159 | } | |
|
160 | 162 | |
|
161 | 163 | endResetModel(); |
|
162 | 164 | } |
|
163 | 165 | |
|
164 |
|
|
|
166 | CatalogueController::Event_ptr CatalogueEventsModel::getEvent(const QModelIndex& index) const | |
|
167 | { | |
|
168 | if (itemTypeOf(index) == CatalogueEventsModel::ItemType::Event) | |
|
165 | 169 | { |
|
166 | if (itemTypeOf(index) == CatalogueEventsModel::ItemType::Event) { | |
|
167 | return impl->m_Events.value(index.row()); | |
|
170 | return impl->m_Events[index.row()]; | |
|
168 | 171 | } |
|
169 |
else |
|
|
172 | else | |
|
173 | { | |
|
170 | 174 | return nullptr; |
|
171 | 175 | } |
|
172 | 176 | } |
|
173 | 177 | |
|
174 |
|
|
|
178 | CatalogueController::Event_ptr CatalogueEventsModel::getParentEvent(const QModelIndex& index) const | |
|
179 | { | |
|
180 | if (itemTypeOf(index) == CatalogueEventsModel::ItemType::EventProduct) | |
|
175 | 181 | { |
|
176 | if (itemTypeOf(index) == CatalogueEventsModel::ItemType::EventProduct) { | |
|
177 | 182 | return getEvent(index.parent()); |
|
178 | 183 | } |
|
179 |
else |
|
|
184 | else | |
|
185 | { | |
|
180 | 186 | return nullptr; |
|
181 | 187 | } |
|
182 | 188 | } |
|
183 | 189 | |
|
184 | std::shared_ptr<DBEventProduct> | |
|
185 | CatalogueEventsModel::getEventProduct(const QModelIndex &index) const | |
|
190 | std::optional<CatalogueController::Product_t> CatalogueEventsModel::getEventProduct( | |
|
191 | const QModelIndex& index) const | |
|
186 | 192 | { |
|
187 |
if (itemTypeOf(index) == CatalogueEventsModel::ItemType::EventProduct) |
|
|
188 | auto event = static_cast<DBEvent *>(index.internalPointer()); | |
|
189 | return impl->m_EventProducts.at(event).value(index.row()); | |
|
193 | if (itemTypeOf(index) == CatalogueEventsModel::ItemType::EventProduct) | |
|
194 | { | |
|
195 | auto event = *static_cast<CatalogueController::Event_ptr*>(index.internalPointer()); | |
|
196 | return event->products[index.row()]; | |
|
190 | 197 | } |
|
191 |
else |
|
|
192 | return nullptr; | |
|
198 | else | |
|
199 | { | |
|
200 | return std::nullopt; | |
|
193 | 201 | } |
|
194 | 202 | } |
|
195 | 203 | |
|
196 | 204 |
void CatalogueEventsModel::addEvent(const std::shared_ptr<DBEvent> |
|
197 | 205 | { |
|
198 | beginInsertRows(QModelIndex(), impl->m_Events.count(), impl->m_Events.count()); | |
|
199 | impl->m_Events.append(event); | |
|
200 | impl->parseEventProduct(event); | |
|
201 | endInsertRows(); | |
|
206 | // beginInsertRows(QModelIndex(), impl->m_Events.count(), impl->m_Events.count()); | |
|
207 | // impl->m_Events.append(event); | |
|
208 | // impl->parseEventProduct(event); | |
|
209 | // endInsertRows(); | |
|
202 | 210 | |
|
203 | // Also refreshes its children event products | |
|
204 | auto eventIndex = index(impl->m_Events.count(), 0); | |
|
205 | impl->refreshChildrenOfIndex(this, eventIndex); | |
|
211 | // // Also refreshes its children event products | |
|
212 | // auto eventIndex = index(impl->m_Events.count(), 0); | |
|
213 | // impl->refreshChildrenOfIndex(this, eventIndex); | |
|
206 | 214 | } |
|
207 | 215 | |
|
208 | 216 |
void CatalogueEventsModel::removeEvent(const std::shared_ptr<DBEvent> |
|
209 | 217 | { |
|
210 | auto index = impl->m_Events.indexOf(event); | |
|
211 |
if (index >= 0) |
|
|
212 | beginRemoveRows(QModelIndex(), index, index); | |
|
213 | impl->m_Events.removeAt(index); | |
|
214 |
impl->m_Event |
|
|
215 | endRemoveRows(); | |
|
216 | } | |
|
218 | // auto index = impl->m_Events.indexOf(event); | |
|
219 | // if (index >= 0) | |
|
220 | // { | |
|
221 | // beginRemoveRows(QModelIndex(), index, index); | |
|
222 | // impl->m_Events.removeAt(index); | |
|
223 | // impl->m_EventProducts.erase(event.get()); | |
|
224 | // endRemoveRows(); | |
|
225 | // } | |
|
217 | 226 | } |
|
218 | 227 | |
|
219 |
|
|
|
228 | std::vector<CatalogueController::Event_ptr> CatalogueEventsModel::events() const | |
|
220 | 229 | { |
|
221 | 230 | return impl->m_Events; |
|
222 | 231 | } |
|
223 | 232 | |
|
224 |
void CatalogueEventsModel::refreshEvent( |
|
|
225 | bool refreshEventProducts) | |
|
233 | void CatalogueEventsModel::refreshEvent( | |
|
234 | const CatalogueController::Event_ptr& event, bool refreshEventProducts) | |
|
226 | 235 | { |
|
227 | 236 | auto eventIndex = indexOf(event); |
|
228 |
if (eventIndex.isValid()) |
|
|
229 | ||
|
230 | if (refreshEventProducts) { | |
|
231 | // Reparse the associated event products | |
|
232 | ||
|
233 | auto nbEventProducts = impl->nbEventProducts(event); | |
|
234 | auto newNbOfEventProducts = event->getEventProducts().size(); | |
|
235 | if (newNbOfEventProducts < nbEventProducts) { | |
|
236 | beginRemoveRows(eventIndex, newNbOfEventProducts, nbEventProducts - 1); | |
|
237 | impl->m_EventProducts.erase(event.get()); | |
|
238 | impl->parseEventProduct(event); | |
|
239 | endRemoveRows(); | |
|
240 | } | |
|
241 | else if (newNbOfEventProducts > nbEventProducts) { | |
|
242 | beginInsertRows(eventIndex, nbEventProducts, newNbOfEventProducts - 1); | |
|
243 | impl->m_EventProducts.erase(event.get()); | |
|
244 | impl->parseEventProduct(event); | |
|
245 | endInsertRows(); | |
|
246 | } | |
|
247 | else { // newNbOfEventProducts == nbEventProducts | |
|
248 | impl->m_EventProducts.erase(event.get()); | |
|
249 | impl->parseEventProduct(event); | |
|
250 | } | |
|
251 | } | |
|
252 | ||
|
237 | if (eventIndex.isValid()) | |
|
238 | { | |
|
253 | 239 | // Refreshes the event line |
|
254 | 240 | auto colCount = columnCount(); |
|
255 | 241 | emit dataChanged(eventIndex, index(eventIndex.row(), colCount)); |
|
256 | ||
|
257 | 242 | // Also refreshes its children event products |
|
258 | 243 | impl->refreshChildrenOfIndex(this, eventIndex); |
|
259 | 244 | } |
|
260 |
else |
|
|
245 | else | |
|
246 | { | |
|
261 | 247 | qCWarning(LOG_CatalogueEventsModel()) << "refreshEvent: event not found."; |
|
262 | 248 | } |
|
263 | 249 | } |
|
264 | 250 | |
|
265 |
QModelIndex CatalogueEventsModel::indexOf(const |
|
|
251 | QModelIndex CatalogueEventsModel::indexOf(const CatalogueController::Event_ptr& event) const | |
|
252 | { | |
|
253 | auto pos = std::distance(std::begin(impl->m_Events), | |
|
254 | find(std::begin(impl->m_Events), std::end(impl->m_Events), event)); | |
|
255 | if (pos >= 0 && pos < impl->m_Events.size()) | |
|
266 | 256 | { |
|
267 | auto row = impl->m_Events.indexOf(event); | |
|
268 | if (row >= 0) { | |
|
269 | return index(row, 0); | |
|
257 | return index(pos, 0); | |
|
270 | 258 | } |
|
271 | 259 | |
|
272 | 260 | return QModelIndex(); |
|
273 | 261 | } |
|
274 | 262 | |
|
275 | 263 |
QModelIndex CatalogueEventsModel::index(int row, int column, const QModelIndex |
|
276 | 264 | { |
|
277 |
if (!hasIndex(row, column, parent)) |
|
|
265 | if (!hasIndex(row, column, parent)) | |
|
266 | { | |
|
278 | 267 | return QModelIndex(); |
|
279 | 268 | } |
|
280 | 269 | |
|
281 |
switch (itemTypeOf(parent)) |
|
|
270 | switch (itemTypeOf(parent)) | |
|
271 | { | |
|
282 | 272 | case CatalogueEventsModel::ItemType::Root: |
|
283 | 273 | return createIndex(row, column); |
|
284 |
case CatalogueEventsModel::ItemType::Event: |
|
|
274 | case CatalogueEventsModel::ItemType::Event: | |
|
275 | { | |
|
285 | 276 | auto event = getEvent(parent); |
|
286 | 277 | return createIndex(row, column, event.get()); |
|
287 | 278 | } |
|
288 | 279 | case CatalogueEventsModel::ItemType::EventProduct: |
|
289 | 280 | break; |
|
290 | 281 | default: |
|
291 | 282 | break; |
|
292 | 283 | } |
|
293 | 284 | |
|
294 | 285 | return QModelIndex(); |
|
295 | 286 | } |
|
296 | 287 | |
|
297 | 288 |
QModelIndex CatalogueEventsModel::parent(const QModelIndex |
|
298 | 289 | { |
|
299 |
switch (itemTypeOf(index)) |
|
|
300 | case CatalogueEventsModel::ItemType::EventProduct: { | |
|
301 | auto parentEvent = static_cast<DBEvent *>(index.internalPointer()); | |
|
302 | auto it | |
|
303 | = std::find_if(impl->m_Events.cbegin(), impl->m_Events.cend(), | |
|
304 | [parentEvent](auto event) { return event.get() == parentEvent; }); | |
|
290 | switch (itemTypeOf(index)) | |
|
291 | { | |
|
292 | case CatalogueEventsModel::ItemType::EventProduct: | |
|
293 | { | |
|
294 | auto parentEvent | |
|
295 | = *static_cast<CatalogueController::Event_ptr*>(index.internalPointer()); | |
|
296 | auto it = std::find_if(impl->m_Events.cbegin(), impl->m_Events.cend(), | |
|
297 | [parentEvent](auto event) { return event.get() == parentEvent.get(); }); | |
|
305 | 298 | |
|
306 |
if (it != impl->m_Events.cend()) |
|
|
299 | if (it != impl->m_Events.cend()) | |
|
300 | { | |
|
307 | 301 | return createIndex(it - impl->m_Events.cbegin(), 0); |
|
308 | 302 | } |
|
309 |
else |
|
|
303 | else | |
|
304 | { | |
|
310 | 305 | return QModelIndex(); |
|
311 | 306 | } |
|
312 | 307 | } |
|
313 | 308 | case CatalogueEventsModel::ItemType::Root: |
|
314 | 309 | break; |
|
315 | 310 | case CatalogueEventsModel::ItemType::Event: |
|
316 | 311 | break; |
|
317 | 312 | default: |
|
318 | 313 | break; |
|
319 | 314 | } |
|
320 | 315 | |
|
321 | 316 | return QModelIndex(); |
|
322 | 317 | } |
|
323 | 318 | |
|
324 | 319 |
int CatalogueEventsModel::rowCount(const QModelIndex |
|
325 | 320 | { |
|
326 |
if (parent.column() > 0) |
|
|
321 | if (parent.column() > 0) | |
|
322 | { | |
|
327 | 323 | return 0; |
|
328 | 324 | } |
|
329 | 325 | |
|
330 |
switch (itemTypeOf(parent)) |
|
|
326 | switch (itemTypeOf(parent)) | |
|
327 | { | |
|
331 | 328 | case CatalogueEventsModel::ItemType::Root: |
|
332 |
return impl->m_Events. |
|
|
333 |
case CatalogueEventsModel::ItemType::Event: |
|
|
329 | return impl->m_Events.size(); | |
|
330 | case CatalogueEventsModel::ItemType::Event: | |
|
331 | { | |
|
334 | 332 | auto event = getEvent(parent); |
|
335 |
return |
|
|
333 | return event->products.size(); | |
|
336 | 334 | } |
|
337 | 335 | case CatalogueEventsModel::ItemType::EventProduct: |
|
338 | 336 | break; |
|
339 | 337 | default: |
|
340 | 338 | break; |
|
341 | 339 | } |
|
342 | 340 | |
|
343 | 341 | return 0; |
|
344 | 342 | } |
|
345 | 343 | |
|
346 | 344 |
int CatalogueEventsModel::columnCount(const QModelIndex |
|
347 | 345 | { |
|
348 | 346 | return static_cast<int>(CatalogueEventsModel::Column::NbColumn); |
|
349 | 347 | } |
|
350 | 348 | |
|
351 | 349 |
Qt::ItemFlags CatalogueEventsModel::flags(const QModelIndex |
|
352 | 350 | { |
|
353 | 351 | return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled; |
|
354 | 352 | } |
|
355 | 353 | |
|
356 | 354 |
QVariant CatalogueEventsModel::data(const QModelIndex |
|
357 | 355 | { |
|
358 |
if (index.isValid()) |
|
|
356 | if (index.isValid()) | |
|
357 | { | |
|
359 | 358 | |
|
360 | 359 | auto type = itemTypeOf(index); |
|
361 |
if (type == CatalogueEventsModel::ItemType::Event) |
|
|
360 | if (type == CatalogueEventsModel::ItemType::Event) | |
|
361 | { | |
|
362 | 362 | auto event = getEvent(index); |
|
363 |
switch (role) |
|
|
363 | switch (role) | |
|
364 | { | |
|
364 | 365 | case Qt::DisplayRole: |
|
365 | 366 | return impl->eventData(index.column(), event); |
|
366 | 367 | break; |
|
367 | 368 | } |
|
368 | 369 | } |
|
369 |
else if (type == CatalogueEventsModel::ItemType::EventProduct) |
|
|
370 | else if (type == CatalogueEventsModel::ItemType::EventProduct) | |
|
371 | { | |
|
370 | 372 | auto product = getEventProduct(index); |
|
371 |
|
|
|
373 | if (product) | |
|
374 | { | |
|
375 | switch (role) | |
|
376 | { | |
|
372 | 377 | case Qt::DisplayRole: |
|
373 | return impl->eventProductData(index.column(), product); | |
|
378 | return impl->eventProductData(index.column(), *product); | |
|
374 | 379 | break; |
|
375 | 380 | } |
|
376 | 381 | } |
|
377 | 382 | } |
|
383 | } | |
|
378 | 384 | |
|
379 | 385 | return QVariant{}; |
|
380 | 386 | } |
|
381 | 387 | |
|
382 | 388 | QVariant CatalogueEventsModel::headerData(int section, Qt::Orientation orientation, int role) const |
|
383 | 389 | { |
|
384 |
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) |
|
|
390 | if (orientation == Qt::Horizontal && role == Qt::DisplayRole) | |
|
391 | { | |
|
385 | 392 | return impl->columnNames().value(section); |
|
386 | 393 | } |
|
387 | 394 | |
|
388 | 395 | return QVariant(); |
|
389 | 396 | } |
|
390 | 397 | |
|
391 | 398 | void CatalogueEventsModel::sort(int column, Qt::SortOrder order) |
|
392 | 399 | { |
|
393 | 400 | beginResetModel(); |
|
394 | std::sort(impl->m_Events.begin(), impl->m_Events.end(), | |
|
395 |
|
|
|
401 | std::sort( | |
|
402 | impl->m_Events.begin(), impl->m_Events.end(), [this, column, order](auto e1, auto e2) { | |
|
396 | 403 |
|
|
397 | 404 |
|
|
398 | 405 | |
|
399 | 406 |
|
|
400 | 407 | |
|
401 | 408 |
|
|
402 | 409 |
|
|
403 | 410 | |
|
404 | 411 | endResetModel(); |
|
405 | 412 | emit modelSorted(); |
|
406 | 413 | } |
|
407 | 414 | |
|
408 | 415 | Qt::DropActions CatalogueEventsModel::supportedDragActions() const |
|
409 | 416 | { |
|
410 | 417 | return Qt::CopyAction | Qt::MoveAction; |
|
411 | 418 | } |
|
412 | 419 | |
|
413 | 420 | QStringList CatalogueEventsModel::mimeTypes() const |
|
414 | 421 | { |
|
415 | 422 | return {MIME_TYPE_EVENT_LIST, MIME_TYPE_SOURCE_CATALOGUE_LIST, MIME_TYPE_TIME_RANGE}; |
|
416 | 423 | } |
|
417 | 424 | |
|
418 | 425 |
QMimeData |
|
419 | 426 | { |
|
420 | 427 | auto mimeData = new QMimeData; |
|
421 | 428 | |
|
422 | bool isFirst = true; | |
|
423 | ||
|
424 |
QVector<std::shared_ptr<DBEvent> |
|
|
425 |
QVector<std::shared_ptr<DBEventProduct> |
|
|
426 | ||
|
427 | DateTimeRange firstTimeRange; | |
|
428 |
for (const auto |
|
|
429 | if (index.column() == 0) { // only the first column | |
|
430 | ||
|
431 | auto type = itemTypeOf(index); | |
|
432 | if (type == ItemType::Event) { | |
|
433 |
auto |
|
|
434 | eventList << event; | |
|
435 | ||
|
436 | if (isFirst) { | |
|
437 | isFirst = false; | |
|
438 | firstTimeRange.m_TStart = event->getTStart(); | |
|
439 | firstTimeRange.m_TEnd = event->getTEnd(); | |
|
440 |
|
|
|
441 | } | |
|
442 | else if (type == ItemType::EventProduct) { | |
|
443 | auto product = getEventProduct(index); | |
|
444 | eventProductList << product; | |
|
445 | ||
|
446 | if (isFirst) { | |
|
447 | isFirst = false; | |
|
448 | firstTimeRange.m_TStart = product->getTStart(); | |
|
449 | firstTimeRange.m_TEnd = product->getTEnd(); | |
|
450 | } | |
|
451 | } | |
|
452 | } | |
|
453 | } | |
|
454 | ||
|
455 | if (!eventList.isEmpty() && eventProductList.isEmpty()) { | |
|
456 | auto eventsEncodedData = sqpApp->catalogueController().mimeDataForEvents(eventList); | |
|
457 | mimeData->setData(MIME_TYPE_EVENT_LIST, eventsEncodedData); | |
|
458 | ||
|
459 | auto sourceCataloguesEncodedData | |
|
460 | = sqpApp->catalogueController().mimeDataForCatalogues(impl->m_SourceCatalogue); | |
|
461 | mimeData->setData(MIME_TYPE_SOURCE_CATALOGUE_LIST, sourceCataloguesEncodedData); | |
|
462 | } | |
|
463 | ||
|
464 | if (eventList.count() + eventProductList.count() == 1) { | |
|
465 | // No time range MIME data if multiple events are dragged | |
|
466 | auto timeEncodedData = TimeController::mimeDataForTimeRange(firstTimeRange); | |
|
467 | mimeData->setData(MIME_TYPE_TIME_RANGE, timeEncodedData); | |
|
468 | } | |
|
429 | // bool isFirst = true; | |
|
430 | ||
|
431 | // QVector<std::shared_ptr<DBEvent>> eventList; | |
|
432 | // QVector<std::shared_ptr<DBEventProduct>> eventProductList; | |
|
433 | ||
|
434 | // DateTimeRange firstTimeRange; | |
|
435 | // for (const auto& index : indexes) | |
|
436 | // { | |
|
437 | // if (index.column() == 0) | |
|
438 | // { // only the first column | |
|
439 | ||
|
440 | // auto type = itemTypeOf(index); | |
|
441 | // if (type == ItemType::Event) | |
|
442 | // { | |
|
443 | // auto event = getEvent(index); | |
|
444 | // eventList << event; | |
|
445 | ||
|
446 | // if (isFirst) | |
|
447 | // { | |
|
448 | // isFirst = false; | |
|
449 | // firstTimeRange.m_TStart = event->; | |
|
450 | // firstTimeRange.m_TEnd = event->getTEnd(); | |
|
451 | // } | |
|
452 | // } | |
|
453 | // else if (type == ItemType::EventProduct) | |
|
454 | // { | |
|
455 | // auto product = getEventProduct(index); | |
|
456 | // eventProductList << product; | |
|
457 | ||
|
458 | // if (isFirst) | |
|
459 | // { | |
|
460 | // isFirst = false; | |
|
461 | // firstTimeRange.m_TStart = product->getTStart(); | |
|
462 | // firstTimeRange.m_TEnd = product->getTEnd(); | |
|
463 | // } | |
|
464 | // } | |
|
465 | // } | |
|
466 | // } | |
|
467 | ||
|
468 | // if (!eventList.isEmpty() && eventProductList.isEmpty()) | |
|
469 | // { | |
|
470 | // auto eventsEncodedData = sqpApp->catalogueController().mimeDataForEvents(eventList); | |
|
471 | // mimeData->setData(MIME_TYPE_EVENT_LIST, eventsEncodedData); | |
|
472 | ||
|
473 | // auto sourceCataloguesEncodedData | |
|
474 | // = sqpApp->catalogueController().mimeDataForCatalogues(impl->m_SourceCatalogue); | |
|
475 | // mimeData->setData(MIME_TYPE_SOURCE_CATALOGUE_LIST, sourceCataloguesEncodedData); | |
|
476 | // } | |
|
477 | ||
|
478 | // if (eventList.count() + eventProductList.count() == 1) | |
|
479 | // { | |
|
480 | // // No time range MIME data if multiple events are dragged | |
|
481 | // auto timeEncodedData = TimeController::mimeDataForTimeRange(firstTimeRange); | |
|
482 | // mimeData->setData(MIME_TYPE_TIME_RANGE, timeEncodedData); | |
|
483 | // } | |
|
469 | 484 | |
|
470 | 485 | return mimeData; |
|
471 | 486 | } |
|
472 | 487 | |
|
473 | 488 |
CatalogueEventsModel::ItemType CatalogueEventsModel::itemTypeOf(const QModelIndex |
|
474 | 489 | { |
|
475 |
if (!index.isValid()) |
|
|
490 | if (!index.isValid()) | |
|
491 | { | |
|
476 | 492 | return ItemType::Root; |
|
477 | 493 | } |
|
478 |
else if (index.internalPointer() == nullptr) |
|
|
494 | else if (index.internalPointer() == nullptr) | |
|
495 | { | |
|
479 | 496 | return ItemType::Event; |
|
480 | 497 | } |
|
481 |
else |
|
|
498 | else | |
|
499 | { | |
|
482 | 500 | return ItemType::EventProduct; |
|
483 | 501 | } |
|
484 | 502 | } |
@@ -1,196 +1,193 | |||
|
1 | 1 | #include "SqpApplication.h" |
|
2 | 2 | |
|
3 | 3 | #include <Actions/ActionsGuiController.h> |
|
4 | 4 | #include <Catalogue/CatalogueController.h> |
|
5 | 5 | #include <Data/IDataProvider.h> |
|
6 | 6 | #include <DataSource/DataSourceController.h> |
|
7 | 7 | #include <DragAndDrop/DragDropGuiController.h> |
|
8 | 8 | #include <Network/NetworkController.h> |
|
9 | 9 | #include <QThread> |
|
10 | 10 | #include <Time/TimeController.h> |
|
11 | 11 | #include <Variable/Variable.h> |
|
12 | 12 | #include <Variable/VariableController2.h> |
|
13 | 13 | #include <Variable/VariableModel2.h> |
|
14 | 14 | #include <Visualization/VisualizationController.h> |
|
15 | 15 | |
|
16 | 16 | Q_LOGGING_CATEGORY(LOG_SqpApplication, "SqpApplication") |
|
17 | 17 | |
|
18 |
class SqpApplication::SqpApplicationPrivate |
|
|
18 | class SqpApplication::SqpApplicationPrivate | |
|
19 | { | |
|
19 | 20 | public: |
|
20 | 21 | SqpApplicationPrivate() |
|
21 |
: m_VariableController{std::make_shared<VariableController2>()} |
|
|
22 |
|
|
|
23 |
|
|
|
22 | : m_VariableController { std::make_shared<VariableController2>() } | |
|
23 | , m_PlotInterractionMode(SqpApplication::PlotsInteractionMode::None) | |
|
24 | , m_PlotCursorMode(SqpApplication::PlotsCursorMode::NoCursor) | |
|
24 | 25 | { |
|
25 | 26 | // /////////////////////////////// // |
|
26 | 27 | // Connections between controllers // |
|
27 | 28 | // /////////////////////////////// // |
|
28 | 29 | |
|
29 | 30 | // VariableController <-> DataSourceController |
|
30 | connect(&m_DataSourceController, | |
|
31 | &DataSourceController::createVariable,[](const QString &variableName, | |
|
32 | const QVariantHash &variableMetadata, | |
|
33 | std::shared_ptr<IDataProvider> variableProvider) | |
|
34 | { | |
|
35 | sqpApp->variableController().createVariable(variableName,variableMetadata,variableProvider,sqpApp->timeController().dateTime()); | |
|
31 | connect(&m_DataSourceController, &DataSourceController::createVariable, | |
|
32 | [](const QString& variableName, const QVariantHash& variableMetadata, | |
|
33 | std::shared_ptr<IDataProvider> variableProvider) { | |
|
34 | sqpApp->variableController().createVariable(variableName, variableMetadata, | |
|
35 | variableProvider, sqpApp->timeController().dateTime()); | |
|
36 | 36 | }); |
|
37 | 37 | |
|
38 | 38 | // VariableController <-> VisualizationController |
|
39 | 39 | // connect(m_VariableController.get(), |
|
40 | 40 | // SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), |
|
41 | 41 | // m_VisualizationController.get(), |
|
42 |
// SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), |
|
|
42 | // SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), | |
|
43 | // Qt::DirectConnection); | |
|
43 | 44 | |
|
44 | 45 | // connect(m_VariableController.get(), |
|
45 | 46 | // SIGNAL(rangeChanged(std::shared_ptr<Variable>, const DateTimeRange &)), |
|
46 | 47 | // m_VisualizationController.get(), |
|
47 | 48 | // SIGNAL(rangeChanged(std::shared_ptr<Variable>, const DateTimeRange &))); |
|
48 | 49 | |
|
49 | 50 | |
|
50 | 51 | m_DataSourceController.moveToThread(&m_DataSourceControllerThread); |
|
51 | 52 | m_DataSourceControllerThread.setObjectName("DataSourceControllerThread"); |
|
52 | 53 | m_NetworkController.moveToThread(&m_NetworkControllerThread); |
|
53 | 54 | m_NetworkControllerThread.setObjectName("NetworkControllerThread"); |
|
54 | 55 | m_VisualizationController.moveToThread(&m_VisualizationControllerThread); |
|
55 | 56 | m_VisualizationControllerThread.setObjectName("VsualizationControllerThread"); |
|
56 | 57 | |
|
57 | 58 | // Additionnal init |
|
58 | 59 | //m_VariableController->setTimeController(m_TimeController.get()); |
|
59 | 60 | } |
|
60 | 61 | |
|
61 | 62 | virtual ~SqpApplicationPrivate() |
|
62 | 63 | { |
|
63 | 64 | m_DataSourceControllerThread.quit(); |
|
64 | 65 | m_DataSourceControllerThread.wait(); |
|
65 | 66 | |
|
66 | 67 | m_NetworkControllerThread.quit(); |
|
67 | 68 | m_NetworkControllerThread.wait(); |
|
68 | 69 | |
|
69 | 70 | m_VisualizationControllerThread.quit(); |
|
70 | 71 | m_VisualizationControllerThread.wait(); |
|
71 | 72 | } |
|
72 | 73 | |
|
73 | 74 | DataSourceController m_DataSourceController; |
|
74 | 75 | std::shared_ptr<VariableController2> m_VariableController; |
|
75 | 76 | TimeController m_TimeController; |
|
76 | 77 | NetworkController m_NetworkController; |
|
77 | 78 | VisualizationController m_VisualizationController; |
|
78 | 79 | CatalogueController m_CatalogueController; |
|
79 | 80 | |
|
80 | 81 | QThread m_DataSourceControllerThread; |
|
81 | 82 | QThread m_NetworkControllerThread; |
|
82 | 83 | QThread m_VisualizationControllerThread; |
|
83 | 84 | |
|
84 | 85 | DragDropGuiController m_DragDropGuiController; |
|
85 | 86 | ActionsGuiController m_ActionsGuiController; |
|
86 | 87 | |
|
87 | 88 | SqpApplication::PlotsInteractionMode m_PlotInterractionMode; |
|
88 | 89 | SqpApplication::PlotsCursorMode m_PlotCursorMode; |
|
89 | 90 | }; |
|
90 | 91 | |
|
91 | 92 | |
|
92 | 93 |
SqpApplication::SqpApplication(int |
|
93 | 94 | : QApplication{argc, argv}, impl{spimpl::make_unique_impl<SqpApplicationPrivate>()} |
|
94 | 95 | { |
|
95 | 96 | qCDebug(LOG_SqpApplication()) << tr("SqpApplication construction") << QThread::currentThread(); |
|
96 | 97 | |
|
97 | 98 | QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); |
|
98 | 99 | |
|
99 | connect(&impl->m_DataSourceControllerThread, &QThread::started, | |
|
100 |
|
|
|
101 | connect(&impl->m_DataSourceControllerThread, &QThread::finished, | |
|
102 |
|
|
|
100 | connect(&impl->m_DataSourceControllerThread, &QThread::started, &impl->m_DataSourceController, | |
|
101 | &DataSourceController::initialize); | |
|
102 | connect(&impl->m_DataSourceControllerThread, &QThread::finished, &impl->m_DataSourceController, | |
|
103 | &DataSourceController::finalize); | |
|
103 | 104 | |
|
104 | 105 | connect(&impl->m_NetworkControllerThread, &QThread::started, &impl->m_NetworkController, |
|
105 | 106 |
|
|
106 | 107 | connect(&impl->m_NetworkControllerThread, &QThread::finished, &impl->m_NetworkController, |
|
107 | 108 |
|
|
108 | 109 | |
|
109 | 110 | connect(&impl->m_VisualizationControllerThread, &QThread::started, |
|
110 | 111 |
|
|
111 | 112 | connect(&impl->m_VisualizationControllerThread, &QThread::finished, |
|
112 | 113 |
|
|
113 | 114 | |
|
114 | 115 | impl->m_DataSourceControllerThread.start(); |
|
115 | 116 | impl->m_NetworkControllerThread.start(); |
|
116 | 117 | impl->m_VisualizationControllerThread.start(); |
|
117 | impl->m_CatalogueController.initialize(); | |
|
118 | // impl->m_CatalogueController.initialize(); | |
|
118 | 119 | } |
|
119 | 120 | |
|
120 | SqpApplication::~SqpApplication() | |
|
121 | { | |
|
122 | } | |
|
121 | SqpApplication::~SqpApplication() {} | |
|
123 | 122 | |
|
124 | void SqpApplication::initialize() | |
|
125 | { | |
|
126 | } | |
|
123 | void SqpApplication::initialize() {} | |
|
127 | 124 | |
|
128 | 125 |
DataSourceController |
|
129 | 126 | { |
|
130 | 127 | return impl->m_DataSourceController; |
|
131 | 128 | } |
|
132 | 129 | |
|
133 | 130 |
NetworkController |
|
134 | 131 | { |
|
135 | 132 | return impl->m_NetworkController; |
|
136 | 133 | } |
|
137 | 134 | |
|
138 | 135 |
TimeController |
|
139 | 136 | { |
|
140 | 137 | return impl->m_TimeController; |
|
141 | 138 | } |
|
142 | 139 | |
|
143 | 140 |
VariableController2 |
|
144 | 141 | { |
|
145 | 142 | return *impl->m_VariableController; |
|
146 | 143 | } |
|
147 | 144 | |
|
148 | 145 | std::shared_ptr<VariableController2> SqpApplication::variableControllerOwner() noexcept |
|
149 | 146 | { |
|
150 | 147 | return impl->m_VariableController; |
|
151 | 148 | } |
|
152 | 149 | |
|
153 | 150 | //VariableModel2 &SqpApplication::variableModel() noexcept |
|
154 | 151 | //{ |
|
155 | 152 | // return impl->m_VariableModel; |
|
156 | 153 | //} |
|
157 | 154 | |
|
158 | 155 |
VisualizationController |
|
159 | 156 | { |
|
160 | 157 | return impl->m_VisualizationController; |
|
161 | 158 | } |
|
162 | 159 | |
|
163 | 160 |
CatalogueController |
|
164 | 161 | { |
|
165 | 162 | return impl->m_CatalogueController; |
|
166 | 163 | } |
|
167 | 164 | |
|
168 | 165 |
DragDropGuiController |
|
169 | 166 | { |
|
170 | 167 | return impl->m_DragDropGuiController; |
|
171 | 168 | } |
|
172 | 169 | |
|
173 | 170 |
ActionsGuiController |
|
174 | 171 | { |
|
175 | 172 | return impl->m_ActionsGuiController; |
|
176 | 173 | } |
|
177 | 174 | |
|
178 | 175 | SqpApplication::PlotsInteractionMode SqpApplication::plotsInteractionMode() const |
|
179 | 176 | { |
|
180 | 177 | return impl->m_PlotInterractionMode; |
|
181 | 178 | } |
|
182 | 179 | |
|
183 | 180 | void SqpApplication::setPlotsInteractionMode(SqpApplication::PlotsInteractionMode mode) |
|
184 | 181 | { |
|
185 | 182 | impl->m_PlotInterractionMode = mode; |
|
186 | 183 | } |
|
187 | 184 | |
|
188 | 185 | SqpApplication::PlotsCursorMode SqpApplication::plotsCursorMode() const |
|
189 | 186 | { |
|
190 | 187 | return impl->m_PlotCursorMode; |
|
191 | 188 | } |
|
192 | 189 | |
|
193 | 190 | void SqpApplication::setPlotsCursorMode(SqpApplication::PlotsCursorMode mode) |
|
194 | 191 | { |
|
195 | 192 | impl->m_PlotCursorMode = mode; |
|
196 | 193 | } |
@@ -1,3 +1,6 | |||
|
1 | 1 | subdirs(GUITestUtils) |
|
2 | 2 | declare_test(simple_graph simple_graph simple_graph/main.cpp "sciqlopgui;TestUtils;GUITestUtils;Qt5::Test") |
|
3 | 3 | declare_test(multiple_sync_graph multiple_sync_graph multiple_sync_graph/main.cpp "sciqlopgui;TestUtils;GUITestUtils;Qt5::Test") |
|
4 | ||
|
5 | declare_test(event_list event_list catalogue/event_list/main.cpp "sciqlopgui;TestUtils;GUITestUtils;Qt5::Test") | |
|
6 | declare_test(repository_list repository_list catalogue/repository_list/main.cpp "sciqlopgui;TestUtils;GUITestUtils;Qt5::Test") |
@@ -1,171 +1,172 | |||
|
1 | 1 | #ifndef GUITESTUTILS_H |
|
2 | 2 | #define GUITESTUTILS_H |
|
3 | 3 | |
|
4 | 4 | #include <Common/cpp_utils.h> |
|
5 |
#include <Q |
|
|
5 | #include <QCoreApplication> | |
|
6 | 6 | #include <QCursor> |
|
7 | #include <QDesktopWidget> | |
|
7 | 8 | #include <QMouseEvent> |
|
8 |
#include <Q |
|
|
9 | #include <QPoint> | |
|
9 | 10 | #include <QtTest> |
|
10 | #include <QDesktopWidget> | |
|
11 | ||
|
12 | #include <qcustomplot.h> | |
|
13 | 11 | |
|
14 | 12 | #include <SqpApplication.h> |
|
15 | 13 | #include <Variable/Variable.h> |
|
14 | #include <Variable/VariableController2.h> | |
|
15 | #include <qcustomplot.h> | |
|
16 | 16 | |
|
17 | 17 | template <typename T> |
|
18 | 18 | QPoint center(T* widget) |
|
19 | 19 | { |
|
20 | 20 | return QPoint{widget->width()/2,widget->height()/2}; |
|
21 | 21 | } |
|
22 | 22 | |
|
23 | 23 | HAS_METHOD(viewport) |
|
24 | 24 | |
|
25 | 25 | template <typename T> |
|
26 | 26 | static inline constexpr bool is_QWidgetOrDerived = std::is_base_of<QWidget,T>::value; |
|
27 | 27 | |
|
28 | template <typename T> using viewport_type = decltype(std::declval<T>().viewport()); | |
|
28 | template <typename T> | |
|
29 | using viewport_type = decltype(std::declval<T>().viewport()); | |
|
29 | 30 | |
|
30 | 31 | HAS_METHOD(topLevelItem) |
|
31 | 32 | |
|
32 | 33 | template<typename T> |
|
33 | 34 | void mouseMove(T* widget, QPoint pos, Qt::MouseButton mouseModifier) |
|
34 | 35 | { |
|
35 | 36 | QCursor::setPos(widget->mapToGlobal(pos)); |
|
36 | 37 | QMouseEvent event(QEvent::MouseMove, pos, Qt::NoButton, mouseModifier, Qt::NoModifier); |
|
37 | 38 | if constexpr(has_viewport<T>) |
|
38 | 39 | { |
|
39 | 40 | if constexpr(is_QWidgetOrDerived<viewport_type<T>>) |
|
40 | 41 | { |
|
41 | 42 | qApp->sendEvent(widget->viewport(), &event); |
|
42 | 43 | } |
|
43 | 44 | else |
|
44 | 45 | { |
|
45 | 46 | qApp->sendEvent(widget, &event); |
|
46 | 47 | } |
|
47 | 48 | } |
|
48 | 49 | else |
|
49 | 50 | { |
|
50 | 51 | qApp->sendEvent(widget, &event); |
|
51 | 52 | } |
|
52 | 53 | qApp->processEvents(); |
|
53 | 54 | } |
|
54 | 55 | |
|
55 | 56 | |
|
56 | 57 | template <typename T> |
|
57 | 58 | void setMouseTracking(T* widget) |
|
58 | 59 | { |
|
59 | 60 | if constexpr(has_viewport<T>) |
|
60 | 61 | { |
|
61 | 62 | if constexpr(is_QWidgetOrDerived<viewport_type<T>>) |
|
62 | 63 | { |
|
63 | 64 | widget->viewport()->setMouseTracking(true); |
|
64 | 65 | } |
|
65 | 66 | else |
|
66 | 67 | { |
|
67 | 68 | widget->setMouseTracking(true); |
|
68 | 69 | } |
|
69 | 70 | } |
|
70 | 71 | else |
|
71 | 72 | { |
|
72 | 73 | widget->setMouseTracking(true); |
|
73 | 74 | } |
|
74 | 75 | } |
|
75 | 76 | |
|
76 | 77 | template <typename T, typename T2> |
|
77 | 78 | auto getItem(T* widget, T2 itemIndex) |
|
78 | 79 | { |
|
79 | 80 | if constexpr(has_topLevelItem<T>) |
|
80 | 81 | { |
|
81 | 82 |
return |
|
82 | 83 | } |
|
83 | 84 | else |
|
84 | 85 | { |
|
85 | 86 |
return |
|
86 | 87 | } |
|
87 | 88 | } |
|
88 | 89 | |
|
89 | 90 | #define SELECT_ITEM(widget, itemIndex, item)\ |
|
90 | 91 | auto item = getItem(widget, itemIndex);\ |
|
91 | 92 | {\ |
|
92 | 93 | auto itemCenterPos = widget->visualItemRect(item).center();\ |
|
93 | 94 | QTest::mouseClick(widget->viewport(), Qt::LeftButton, Qt::NoModifier, itemCenterPos);\ |
|
94 | 95 | QVERIFY(widget->selectedItems().size() > 0);\ |
|
95 | 96 | QVERIFY(widget->selectedItems().contains(item));\ |
|
96 | 97 | } |
|
97 | 98 | |
|
98 | 99 | |
|
99 | 100 | #define GET_CHILD_WIDGET_FOR_GUI_TESTS(parent, child, childType, childName)\ |
|
100 | 101 | childType* child = parent.findChild<childType*>(childName); \ |
|
101 | 102 | QVERIFY(child!=Q_NULLPTR); \ |
|
102 | 103 | setMouseTracking(child); |
|
103 | 104 | |
|
104 | 105 | template<typename T1, typename T2, typename T3, typename T4=void> |
|
105 | 106 | void dragnDropItem(T1* sourceWidget, T2* destWidget, T3* item, T4* destItem=Q_NULLPTR) |
|
106 | 107 | { |
|
107 | 108 | auto itemCenterPos = sourceWidget->visualItemRect(item).center(); |
|
108 | 109 | if constexpr(has_viewport<T1>) |
|
109 | 110 | { |
|
110 | 111 | QTest::mousePress(sourceWidget->viewport(), Qt::LeftButton, Qt::NoModifier, itemCenterPos); |
|
111 | 112 | } |
|
112 | 113 | else |
|
113 | 114 | { |
|
114 | 115 | QTest::mousePress(sourceWidget, Qt::LeftButton, Qt::NoModifier, itemCenterPos); |
|
115 | 116 | } |
|
116 | 117 | mouseMove(sourceWidget,itemCenterPos, Qt::LeftButton); |
|
117 | 118 | itemCenterPos+=QPoint(0,-10); |
|
118 | 119 | QTimer::singleShot(100,[destWidget,destItem](){ |
|
119 | 120 | mouseMove(destWidget, destWidget->rect().center(),Qt::LeftButton); |
|
120 | 121 | mouseMove(destWidget, destWidget->rect().center()+QPoint(0,-10),Qt::LeftButton); |
|
121 | 122 | if constexpr(!std::is_same_v<void, T4>) |
|
122 | 123 | { |
|
123 | 124 | auto destItemCenterPos = destWidget->visualItemRect(destItem).center(); |
|
124 | 125 | QTest::mouseRelease(destWidget, Qt::LeftButton, Qt::NoModifier, destItemCenterPos); |
|
125 | 126 | } |
|
126 | 127 | else if constexpr(has_viewport<T2>) |
|
127 | 128 | { |
|
128 | 129 | QTest::mouseRelease(destWidget->viewport(), Qt::LeftButton); |
|
129 | 130 | } |
|
130 | 131 | else |
|
131 | 132 | { |
|
132 | 133 | QTest::mouseRelease(destWidget, Qt::LeftButton); |
|
133 | 134 | } |
|
134 | 135 | QTest::mouseRelease(destWidget->viewport(), Qt::LeftButton); |
|
135 | 136 | }); |
|
136 | 137 | mouseMove(sourceWidget,itemCenterPos,Qt::LeftButton); |
|
137 | 138 | } |
|
138 | 139 | |
|
139 | 140 | template <typename T> |
|
140 | 141 | void scroll_graph(T* w, int dx) |
|
141 | 142 | { |
|
142 | 143 | auto cent = center(w); |
|
143 | 144 | QTest::mousePress(w, Qt::LeftButton, Qt::NoModifier, cent, 1); |
|
144 | 145 | mouseMove(w, {cent.x() + dx, cent.y()}, Qt::LeftButton); |
|
145 | 146 | QTest::mouseRelease(w, Qt::LeftButton); |
|
146 | 147 | } |
|
147 | 148 | |
|
148 | 149 |
ALIAS_TEMPLATE_FUNCTION(isReady, static_cast<SqpApplication |
|
149 | 150 | |
|
150 | 151 | void waitForVar(std::shared_ptr<Variable> var) |
|
151 | 152 | { |
|
152 | 153 | while (!isReady(var)) |
|
153 | 154 | QCoreApplication::processEvents(); |
|
154 | 155 | } |
|
155 | 156 | |
|
156 | 157 | template<typename T> |
|
157 | 158 | bool prepare_gui_test(T* w) |
|
158 | 159 | { |
|
159 | w->setGeometry(QRect(QPoint(QApplication::desktop()->geometry().center() - QPoint(250, 250)), | |
|
160 | QSize(500, 500))); | |
|
160 | w->setGeometry(QRect( | |
|
161 | QPoint(QApplication::desktop()->geometry().center() - QPoint(250, 250)), QSize(500, 500))); | |
|
161 | 162 | w->show(); |
|
162 | 163 | qApp->setActiveWindow(w); |
|
163 | 164 | return QTest::qWaitForWindowActive(w); |
|
164 | 165 | } |
|
165 | 166 | |
|
166 | 167 | #define GET_CHILD_WIDGET_FOR_GUI_TESTS(parent, child, childType, childName)\ |
|
167 | 168 | childType* child = parent.findChild<childType*>(childName); \ |
|
168 | 169 | QVERIFY(child!=Q_NULLPTR); \ |
|
169 | 170 | setMouseTracking(child); |
|
170 | 171 | |
|
171 | 172 | #endif |
General Comments 0
You need to be logged in to leave comments.
Login now