##// END OF EJS Templates
New Catalogue API WIP, basic models and views implemented...
jeandet -
r1406:10c898bf875c
parent child
Show More
@@ -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
71 find_package(SciQLOPCore CONFIG QUIET)
72 if (NOT SciQLOPCore_FOUND)
73 if(NOT IS_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/core)
74 message("Init submodule Core")
75 execute_process(COMMAND git submodule init core WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
76 execute_process(COMMAND git submodule update core WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
75 if(BUILD_CORE)
76 find_package(SciQLOPCore CONFIG QUIET)
77 if (NOT SciQLOPCore_FOUND)
78 if(NOT IS_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/core)
79 message("Init submodule Core")
80 execute_process(COMMAND git submodule init core WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
81 execute_process(COMMAND git submodule update core WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
82 endif()
83 add_subdirectory(core)
77 84 endif()
78 add_subdirectory(core)
79 85 endif()
80 86
81 add_subdirectory(gui)
82 add_subdirectory(app)
83 add_subdirectory(plugins)
87 if(BUILD_GUI)
88 add_subdirectory(gui)
89 endif()
90 if(BUILD_APP)
91 add_subdirectory(app)
92 endif()
93 if(BUILD_PLUGINS)
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 explicit MainWindowPrivate(MainWindow *mainWindow)
63 : m_LastOpenLeftInspectorSize{},
64 m_LastOpenRightInspectorSize{},
65 m_GeneralSettingsWidget{new SqpSettingsGeneralWidget{mainWindow}},
66 m_SettingsDialog{new SqpSettingsDialog{mainWindow}},
67 m_CatalogExplorer{new CatalogueExplorer{mainWindow}}
64 explicit MainWindowPrivate(MainWindow* mainWindow)
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 SqpSettingsGeneralWidget *m_GeneralSettingsWidget;
76 SqpSettingsGeneralWidget* m_GeneralSettingsWidget;
75 77 /// Settings dialog. MainWindow has the ownership
76 SqpSettingsDialog *m_SettingsDialog;
78 SqpSettingsDialog* m_SettingsDialog;
77 79 /// Catalogue dialog. MainWindow has the ownership
78 CatalogueExplorer *m_CatalogExplorer;
80 // CatalogueExplorer* m_CatalogExplorer;
79 81
80 bool checkDataToSave(QWidget *parentWidget);
82 bool checkDataToSave(QWidget* parentWidget);
81 83 };
82 84
83 MainWindow::MainWindow(QWidget *parent)
84 : QMainWindow{parent},
85 m_Ui{new Ui::MainWindow},
86 impl{spimpl::make_unique_impl<MainWindowPrivate>(this)}
85 MainWindow::MainWindow(QWidget* parent)
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
95 // impl->m_CatalogExplorer->setVisualizationWidget(m_Ui->view);
96 96
97 97
98
99 auto spacerLeftTop = new QWidget{};
98 auto spacerLeftTop = new QWidget {};
100 99 spacerLeftTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
101 100
102 auto spacerLeftBottom = new QWidget{};
101 auto spacerLeftBottom = new QWidget {};
103 102 spacerLeftBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
104 103
105 104
106 auto spacerRightTop = new QWidget{};
105 auto spacerRightTop = new QWidget {};
107 106 spacerRightTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
108 107
109 auto spacerRightBottom = new QWidget{};
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) {
113 action->setIcon(
114 QIcon { (checked ^ right) ? ":/icones/next.png" : ":/icones/previous.png" });
114 115
115 action->setIcon(QIcon{(checked ^ right) ? ":/icones/next.png" : ":/icones/previous.png"});
116
117 auto &lastInspectorSize
116 auto& lastInspectorSize
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 auto timeWidget = new TimeWidget{};
171 auto timeWidget = new TimeWidget {};
171 172 mainToolBar->addWidget(timeWidget);
172 173
173 174 // Interaction modes
174 auto actionPointerMode = new QAction{QIcon(":/icones/pointer.png"), "Move", this};
175 auto actionPointerMode = new QAction { QIcon(":/icones/pointer.png"), "Move", this };
175 176 actionPointerMode->setCheckable(true);
176 actionPointerMode->setChecked(sqpApp->plotsInteractionMode()
177 == SqpApplication::PlotsInteractionMode::None);
177 actionPointerMode->setChecked(
178 sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::None);
178 179 connect(actionPointerMode, &QAction::triggered,
179 []() { sqpApp->setPlotsInteractionMode(SqpApplication::PlotsInteractionMode::None); });
180 []() { sqpApp->setPlotsInteractionMode(SqpApplication::PlotsInteractionMode::None); });
180 181
181 auto actionZoomMode = new QAction{QIcon(":/icones/zoom.png"), "Zoom", this};
182 auto actionZoomMode = new QAction { QIcon(":/icones/zoom.png"), "Zoom", this };
182 183 actionZoomMode->setCheckable(true);
183 actionZoomMode->setChecked(sqpApp->plotsInteractionMode()
184 == SqpApplication::PlotsInteractionMode::ZoomBox);
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 auto actionOrganisationMode = new QAction{QIcon(":/icones/drag.png"), "Organize", this};
189 auto actionOrganisationMode = new QAction { QIcon(":/icones/drag.png"), "Organize", this };
190 190 actionOrganisationMode->setCheckable(true);
191 actionOrganisationMode->setChecked(sqpApp->plotsInteractionMode()
192 == SqpApplication::PlotsInteractionMode::DragAndDrop);
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 auto actionZonesMode = new QAction{QIcon(":/icones/rectangle.png"), "Zones", this};
197 auto actionZonesMode = new QAction { QIcon(":/icones/rectangle.png"), "Zones", this };
198 198 actionZonesMode->setCheckable(true);
199 actionZonesMode->setChecked(sqpApp->plotsInteractionMode()
200 == SqpApplication::PlotsInteractionMode::SelectionZones);
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 auto modeActionGroup = new QActionGroup{this};
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 auto btnCursor = new QToolButton{this};
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(sqpApp->plotsCursorMode()
231 == SqpApplication::PlotsCursorMode::NoCursor);
230 noCursorAction->setChecked(
231 sqpApp->plotsCursorMode() == SqpApplication::PlotsCursorMode::NoCursor);
232 232 connect(noCursorAction, &QAction::triggered,
233 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::NoCursor); });
233 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::NoCursor); });
234 234
235 235 cursorMenu->addSeparator();
236 236 auto verticalCursorAction = cursorMenu->addAction("Vertical Cursor");
237 237 verticalCursorAction->setCheckable(true);
238 verticalCursorAction->setChecked(sqpApp->plotsCursorMode()
239 == SqpApplication::PlotsCursorMode::Vertical);
238 verticalCursorAction->setChecked(
239 sqpApp->plotsCursorMode() == SqpApplication::PlotsCursorMode::Vertical);
240 240 connect(verticalCursorAction, &QAction::triggered,
241 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::Vertical); });
241 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::Vertical); });
242 242
243 243 auto temporalCursorAction = cursorMenu->addAction("Temporal Cursor");
244 244 temporalCursorAction->setCheckable(true);
245 temporalCursorAction->setChecked(sqpApp->plotsCursorMode()
246 == SqpApplication::PlotsCursorMode::Temporal);
245 temporalCursorAction->setChecked(
246 sqpApp->plotsCursorMode() == SqpApplication::PlotsCursorMode::Temporal);
247 247 connect(temporalCursorAction, &QAction::triggered,
248 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::Temporal); });
248 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::Temporal); });
249 249
250 250 auto horizontalCursorAction = cursorMenu->addAction("Horizontal Cursor");
251 251 horizontalCursorAction->setCheckable(true);
252 horizontalCursorAction->setChecked(sqpApp->plotsCursorMode()
253 == SqpApplication::PlotsCursorMode::Horizontal);
252 horizontalCursorAction->setChecked(
253 sqpApp->plotsCursorMode() == SqpApplication::PlotsCursorMode::Horizontal);
254 254 connect(horizontalCursorAction, &QAction::triggered,
255 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::Horizontal); });
255 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::Horizontal); });
256 256
257 257 auto crossCursorAction = cursorMenu->addAction("Cross Cursor");
258 258 crossCursorAction->setCheckable(true);
259 crossCursorAction->setChecked(sqpApp->plotsCursorMode()
260 == SqpApplication::PlotsCursorMode::Cross);
259 crossCursorAction->setChecked(
260 sqpApp->plotsCursorMode() == SqpApplication::PlotsCursorMode::Cross);
261 261 connect(crossCursorAction, &QAction::triggered,
262 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::Cross); });
262 []() { sqpApp->setPlotsCursorMode(SqpApplication::PlotsCursorMode::Cross); });
263 263
264 264 mainToolBar->addWidget(btnCursor);
265 265
266 auto cursorModeActionGroup = new QActionGroup{this};
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 [this]() { impl->m_CatalogExplorer->show(); });
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(QStringLiteral("General"),
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)), &sqpApp->variableController(),
293 // SLOT(onDateTimeOnSelection(DateTimeRange)));
292 // connect(&sqpApp->timeController(), SIGNAL(timeUpdated(DateTimeRange)),
293 // &sqpApp->variableController(),
294 // SLOT(onDateTimeOnSelection(DateTimeRange)));
294 295
295 296 // Widgets / controllers connections
296 297
297 298 // DataSource
298 connect(&sqpApp->dataSourceController(), SIGNAL(dataSourceItemSet(DataSourceItem *)),
299 m_Ui->dataSourceWidget, SLOT(addDataSource(DataSourceItem *)));
299 connect(&sqpApp->dataSourceController(), SIGNAL(dataSourceItemSet(DataSourceItem*)),
300 m_Ui->dataSourceWidget, SLOT(addDataSource(DataSourceItem*)));
300 301
301 302 // Time
302 303 connect(timeWidget, SIGNAL(timeUpdated(DateTimeRange)), &sqpApp->timeController(),
303 SLOT(onTimeToUpdate(DateTimeRange)));
304 SLOT(onTimeToUpdate(DateTimeRange)));
304 305
305 306 // Visualization
306 307 connect(&sqpApp->visualizationController(),
307 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), m_Ui->view,
308 SLOT(onVariableAboutToBeDeleted(std::shared_ptr<Variable>)));
308 SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), m_Ui->view,
309 SLOT(onVariableAboutToBeDeleted(std::shared_ptr<Variable>)));
309 310
310 311 connect(&sqpApp->visualizationController(),
311 SIGNAL(rangeChanged(std::shared_ptr<Variable>, const DateTimeRange &)), m_Ui->view,
312 SLOT(onRangeChanged(std::shared_ptr<Variable>, const DateTimeRange &)));
312 SIGNAL(rangeChanged(std::shared_ptr<Variable>, const DateTimeRange&)), m_Ui->view,
313 SLOT(onRangeChanged(std::shared_ptr<Variable>, const DateTimeRange&)));
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,
322 SIGNAL(tableMenuAboutToBeDisplayed(QMenu *, const QVector<std::shared_ptr<Variable> > &)),
323 m_Ui->view, SLOT(attachVariableMenu(QMenu *, const QVector<std::shared_ptr<Variable> > &)),
321 connect(m_Ui->variableInspectorWidget,
322 SIGNAL(tableMenuAboutToBeDisplayed(QMenu*, const QVector<std::shared_ptr<Variable>>&)),
323 m_Ui->view, SLOT(attachVariableMenu(QMenu*, const QVector<std::shared_ptr<Variable>>&)),
324 324 Qt::DirectConnection);
325 325 }
326 326
327 MainWindow::~MainWindow()
328 {
329 }
327 MainWindow::~MainWindow() {}
330 328
331 void MainWindow::changeEvent(QEvent *e)
329 void MainWindow::changeEvent(QEvent* e)
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 void MainWindow::closeEvent(QCloseEvent *event)
342 void MainWindow::closeEvent(QCloseEvent* event)
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 void MainWindow::keyPressEvent(QKeyEvent *event)
354 void MainWindow::keyPressEvent(QKeyEvent* event)
354 355 {
355 356 switch (event->key())
356 357 {
357 case Qt::Key_F11:
358 if(this->isFullScreen())
359 {
360 this->showNormal();
361 }
362 else
363 {
364 this->showFullScreen();
365 }
366 break;
367 default:
368 break;
358 case Qt::Key_F11:
359 if (this->isFullScreen())
360 {
361 this->showNormal();
362 }
363 else
364 {
365 this->showFullScreen();
366 }
367 break;
368 default:
369 break;
369 370 }
370 371 }
371 372
372 bool MainWindow::MainWindowPrivate::checkDataToSave(QWidget *parentWidget)
373 bool MainWindow::MainWindowPrivate::checkDataToSave(QWidget* parentWidget)
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 CatalogueEventsModel(QObject *parent = nullptr);
23
24 enum class Column { Name, TStart, TEnd, Tags, Product, Validation, NbColumn };
25
26 void setSourceCatalogues(const QVector<std::shared_ptr<DBCatalogue> > &catalogues);
27 void setEvents(const QVector<std::shared_ptr<DBEvent> > &events);
28 void addEvent(const std::shared_ptr<DBEvent> &event);
29 void removeEvent(const std::shared_ptr<DBEvent> &event);
30 QVector<std::shared_ptr<DBEvent> > events() const;
31
32 enum class ItemType { Root, Event, EventProduct };
33 ItemType itemTypeOf(const QModelIndex &index) const;
34 std::shared_ptr<DBEvent> getEvent(const QModelIndex &index) const;
35 std::shared_ptr<DBEvent> getParentEvent(const QModelIndex &index) const;
36 std::shared_ptr<DBEventProduct> getEventProduct(const QModelIndex &index) const;
22 CatalogueEventsModel(QObject* parent = nullptr);
23
24 enum class Column
25 {
26 Name,
27 TStart,
28 TEnd,
29 Tags,
30 Product,
31 Validation,
32 NbColumn
33 };
34
35 void setSourceCatalogues(const QVector<std::shared_ptr<DBCatalogue>>& catalogues);
36 void setEvents(const std::vector<CatalogueController::Event_ptr>& events);
37 void addEvent(const std::shared_ptr<DBEvent>& event);
38 void removeEvent(const std::shared_ptr<DBEvent>& event);
39 std::vector<CatalogueController::Event_ptr> events() const;
40
41 enum class ItemType
42 {
43 Root,
44 Event,
45 EventProduct
46 };
47 ItemType itemTypeOf(const QModelIndex& index) const;
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 std::shared_ptr<DBEvent> &event) 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 void setEventHasChanges(const std::shared_ptr<DBEvent> &event, bool hasChanges);
60 void setEventHasChanges(const std::shared_ptr<DBEvent>& event, bool hasChanges);
46 61
47 62 /// Returns true if the specified event has unsaved changes
48 bool eventsHasChanges(const std::shared_ptr<DBEvent> &event) const;
63 bool eventsHasChanges(const std::shared_ptr<DBEvent>& event) const;
49 64
50 65 // Model
51 QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
52 QModelIndex parent(const QModelIndex &index) const;
53 int rowCount(const QModelIndex &parent = QModelIndex()) const override;
54 int columnCount(const QModelIndex &parent = QModelIndex()) const override;
55 Qt::ItemFlags flags(const QModelIndex &index) const override;
56 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
57 QVariant headerData(int section, Qt::Orientation orientation,
58 int role = Qt::DisplayRole) const override;
66 QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const;
67 QModelIndex parent(const QModelIndex& index) const;
68 int rowCount(const QModelIndex& parent = QModelIndex()) const override;
69 int columnCount(const QModelIndex& parent = QModelIndex()) const override;
70 Qt::ItemFlags flags(const QModelIndex& index) const override;
71 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
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 QMimeData *mimeData(const QModelIndexList &indexes) const override;
78 QMimeData* mimeData(const QModelIndexList& indexes) const override;
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 CatalogueExplorer *m_CatalogueExplorer = nullptr;
36 QVector<std::shared_ptr<SelectionZoneAction> > m_CreateInCatalogueActions;
39 CatalogueExplorer* m_CatalogueExplorer = nullptr;
40 QVector<std::shared_ptr<SelectionZoneAction>> m_CreateInCatalogueActions;
37 41
38 CatalogueActionManagerPrivate(CatalogueExplorer *catalogueExplorer)
42 CatalogueActionManagerPrivate(CatalogueExplorer* catalogueExplorer)
39 43 : m_CatalogueExplorer(catalogueExplorer)
40 44 {
41 45 }
42 46
43 void createEventFromZones(const QString &eventName,
44 const QVector<VisualizationSelectionZoneItem *> &zones,
45 const std::shared_ptr<DBCatalogue> &catalogue = nullptr)
47 void createEventFromZones(const QString& eventName,
48 const QVector<VisualizationSelectionZoneItem*>& zones,
49 const CatalogueController::Catalogue_ptr& catalogue = nullptr)
46 50 {
47 auto event = std::make_shared<DBEvent>();
48 event->setName(eventName);
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->setTStart(zoneRange.m_TStart);
62 eventProduct->setTEnd(zoneRange.m_TEnd);
66 eventProduct.startTime = zoneRange.m_TStart;
67 eventProduct.stopTime = zoneRange.m_TEnd;
63 68
64 eventProduct->setProductId(productId);
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);
73
74
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->eventsWidget().setEventChanges(event, true);
82 }
74 sqpApp->catalogueController().add(event);
75
76
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 // }
83 90 }
84 else if (m_CatalogueExplorer->eventsWidget().isAllEventsDisplayed()) {
85 m_CatalogueExplorer->eventsWidget().addEvent(event);
86 m_CatalogueExplorer->eventsWidget().setEventChanges(event, true);
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 CatalogueActionManager::CatalogueActionManager(CatalogueExplorer *catalogueExplorer)
118 : impl{spimpl::make_unique_impl<CatalogueActionManagerPrivate>(catalogueExplorer)}
128 CatalogueActionManager::CatalogueActionManager(CatalogueExplorer* catalogueExplorer)
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();
125
126 auto createEventAction = actionController.addSectionZoneAction(
127 {CATALOGUE_MENU_NAME, CATALOGUE_CREATE_EVENT_MENU_NAME}, QObject::tr("Without Catalogue"),
128 [this](auto zones) { impl->createEventFromZones(DEFAULT_EVENT_NAME, zones); });
129 createEventAction->setEnableFunction(impl->createEventEnableFuntion());
130 createEventAction->setAllowedFiltering(false);
131
132 auto createEventInNewCatalogueAction = actionController.addSectionZoneAction(
133 {CATALOGUE_MENU_NAME, CATALOGUE_CREATE_EVENT_MENU_NAME}, QObject::tr("In New Catalogue"),
134 [this](auto zones) {
135
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);
141
142 impl->createEventFromZones(DEFAULT_EVENT_NAME, zones, newCatalogue);
143 });
144 createEventInNewCatalogueAction->setEnableFunction(impl->createEventEnableFuntion());
145 createEventInNewCatalogueAction->setAllowedFiltering(false);
146
147 refreshCreateInCatalogueAction();
148
149 actionController.addFilterForMenu({CATALOGUE_MENU_NAME, CATALOGUE_CREATE_EVENT_MENU_NAME});
135 // auto &actionController = sqpApp->actionsGuiController();
136
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);
143
144 // auto createEventInNewCatalogueAction = actionController.addSectionZoneAction(
145 // {CATALOGUE_MENU_NAME, CATALOGUE_CREATE_EVENT_MENU_NAME}, QObject::tr("In New
146 // Catalogue"), [this](auto zones) {
147
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);
153
154 // impl->createEventFromZones(DEFAULT_EVENT_NAME, zones, newCatalogue);
155 // });
156 // createEventInNewCatalogueAction->setEnableFunction(impl->createEventEnableFuntion());
157 // createEventInNewCatalogueAction->setAllowedFiltering(false);
158
159 // refreshCreateInCatalogueAction();
160
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 &actionController = sqpApp->actionsGuiController();
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 catalogueName = catalogue->getName();
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"), tr("TEnd"),
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 std::shared_ptr<DBEvent> &event) const
34 QVariant sortData(int col, const CatalogueController::Event_ptr& event) const
36 35 {
37 if (col == (int)CatalogueEventsModel::Column::Validation) {
38 auto hasChanges = sqpApp->catalogueController().eventHasChanges(event);
36 if (col == (int)CatalogueEventsModel::Column::Validation)
37 {
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 std::shared_ptr<DBEvent> &event) const
45 QVariant eventData(int col, const CatalogueController::Event_ptr& event) const
46 46 {
47 switch (static_cast<Column>(col)) {
47 switch (static_cast<Column>(col))
48 {
48 49 case CatalogueEventsModel::Column::Name:
49 return event->getName();
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 : QVariant{};
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 : QVariant{};
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 : eventProducts) {
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 tags = event->getTags();
71 for (auto tag : tags) {
72 tagList += tag.getName();
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 std::shared_ptr<DBEvent> &event)
90 void parseEventProduct(const CatalogueController::Event_ptr& event)
89 91 {
90 for (auto product : event->getEventProducts()) {
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 int nbEventProducts(const std::shared_ptr<DBEvent> &event) const
98 std::size_t nbEventProducts(const CatalogueController::Event_ptr& event) const
96 99 {
97 auto eventProductsIt = m_EventProducts.find(event.get());
98 if (eventProductsIt != m_EventProducts.cend()) {
99 return m_EventProducts.at(event.get()).count();
100 if (event)
101 {
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 std::shared_ptr<DBEventProduct> &eventProduct) const
110 QVariant eventProductData(int col, const CatalogueController::Product_t& eventProduct) const
107 111 {
108 switch (static_cast<Column>(col)) {
112 switch (static_cast<Column>(col))
113 {
109 114 case CatalogueEventsModel::Column::Name:
110 return eventProduct->getProductId();
115 return QString::fromStdString(eventProduct.name);
111 116 case CatalogueEventsModel::Column::TStart:
112 return DateUtils::dateTime(eventProduct->getTStart())
117 return DateUtils::dateTime(eventProduct.startTime)
113 118 .toString(DATETIME_FORMAT_ONE_LINE);
114 119 case CatalogueEventsModel::Column::TEnd:
115 return DateUtils::dateTime(eventProduct->getTEnd())
120 return DateUtils::dateTime(eventProduct.stopTime)
116 121 .toString(DATETIME_FORMAT_ONE_LINE);
117 122 case CatalogueEventsModel::Column::Product:
118 return eventProduct->getProductId();
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 void refreshChildrenOfIndex(CatalogueEventsModel *model, const QModelIndex &index) const
136 void refreshChildrenOfIndex(CatalogueEventsModel* model, const QModelIndex& index) const
132 137 {
133 138 auto childCount = model->rowCount(index);
134 139 auto colCount = model->columnCount();
135 emit model->dataChanged(model->index(0, 0, index),
136 model->index(childCount, colCount, index));
140 emit model->dataChanged(
141 model->index(0, 0, index), model->index(childCount, colCount, index));
137 142 }
138 143 };
139 144
140 CatalogueEventsModel::CatalogueEventsModel(QObject *parent)
141 : QAbstractItemModel(parent), impl{spimpl::make_unique_impl<CatalogueEventsModelPrivate>()}
145 CatalogueEventsModel::CatalogueEventsModel(QObject* parent)
146 : QAbstractItemModel(parent)
147 , impl { spimpl::make_unique_impl<CatalogueEventsModelPrivate>() }
142 148 {
143 149 }
144 150
145 151 void CatalogueEventsModel::setSourceCatalogues(
146 const QVector<std::shared_ptr<DBCatalogue> > &catalogues)
152 const QVector<std::shared_ptr<DBCatalogue>>& catalogues)
147 153 {
148 impl->m_SourceCatalogue = catalogues;
154 // impl->m_SourceCatalogue = catalogues;
149 155 }
150 156
151 void CatalogueEventsModel::setEvents(const QVector<std::shared_ptr<DBEvent> > &events)
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 std::shared_ptr<DBEvent> CatalogueEventsModel::getEvent(const QModelIndex &index) const
166 CatalogueController::Event_ptr CatalogueEventsModel::getEvent(const QModelIndex& index) const
165 167 {
166 if (itemTypeOf(index) == CatalogueEventsModel::ItemType::Event) {
167 return impl->m_Events.value(index.row());
168 if (itemTypeOf(index) == CatalogueEventsModel::ItemType::Event)
169 {
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 std::shared_ptr<DBEvent> CatalogueEventsModel::getParentEvent(const QModelIndex &index) const
178 CatalogueController::Event_ptr CatalogueEventsModel::getParentEvent(const QModelIndex& index) const
175 179 {
176 if (itemTypeOf(index) == CatalogueEventsModel::ItemType::EventProduct) {
180 if (itemTypeOf(index) == CatalogueEventsModel::ItemType::EventProduct)
181 {
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 void CatalogueEventsModel::addEvent(const std::shared_ptr<DBEvent> &event)
204 void CatalogueEventsModel::addEvent(const std::shared_ptr<DBEvent>& event)
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();
202
203 // Also refreshes its children event products
204 auto eventIndex = index(impl->m_Events.count(), 0);
205 impl->refreshChildrenOfIndex(this, eventIndex);
206 // beginInsertRows(QModelIndex(), impl->m_Events.count(), impl->m_Events.count());
207 // impl->m_Events.append(event);
208 // impl->parseEventProduct(event);
209 // endInsertRows();
210
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 void CatalogueEventsModel::removeEvent(const std::shared_ptr<DBEvent> &event)
216 void CatalogueEventsModel::removeEvent(const std::shared_ptr<DBEvent>& event)
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_EventProducts.erase(event.get());
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 QVector<std::shared_ptr<DBEvent> > CatalogueEventsModel::events() const
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(const std::shared_ptr<DBEvent> &event,
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 std::shared_ptr<DBEvent> &event) const
251 QModelIndex CatalogueEventsModel::indexOf(const CatalogueController::Event_ptr& event) const
266 252 {
267 auto row = impl->m_Events.indexOf(event);
268 if (row >= 0) {
269 return index(row, 0);
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())
256 {
257 return index(pos, 0);
270 258 }
271 259
272 260 return QModelIndex();
273 261 }
274 262
275 QModelIndex CatalogueEventsModel::index(int row, int column, const QModelIndex &parent) const
263 QModelIndex CatalogueEventsModel::index(int row, int column, const QModelIndex& parent) const
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 QModelIndex CatalogueEventsModel::parent(const QModelIndex &index) const
288 QModelIndex CatalogueEventsModel::parent(const QModelIndex& index) const
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; });
305
306 if (it != impl->m_Events.cend()) {
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(); });
298
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 int CatalogueEventsModel::rowCount(const QModelIndex &parent) const
319 int CatalogueEventsModel::rowCount(const QModelIndex& parent) const
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.count();
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 impl->m_EventProducts[event.get()].count();
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 int CatalogueEventsModel::columnCount(const QModelIndex &parent) const
344 int CatalogueEventsModel::columnCount(const QModelIndex& parent) const
347 345 {
348 346 return static_cast<int>(CatalogueEventsModel::Column::NbColumn);
349 347 }
350 348
351 Qt::ItemFlags CatalogueEventsModel::flags(const QModelIndex &index) const
349 Qt::ItemFlags CatalogueEventsModel::flags(const QModelIndex& index) const
352 350 {
353 351 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;
354 352 }
355 353
356 QVariant CatalogueEventsModel::data(const QModelIndex &index, int role) const
354 QVariant CatalogueEventsModel::data(const QModelIndex& index, int role) const
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 switch (role) {
372 case Qt::DisplayRole:
373 return impl->eventProductData(index.column(), product);
374 break;
373 if (product)
374 {
375 switch (role)
376 {
377 case Qt::DisplayRole:
378 return impl->eventProductData(index.column(), *product);
379 break;
380 }
375 381 }
376 382 }
377 383 }
378 384
379 return QVariant{};
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 [this, column, order](auto e1, auto e2) {
396 auto data1 = impl->sortData(column, e1);
397 auto data2 = impl->sortData(column, e2);
401 std::sort(
402 impl->m_Events.begin(), impl->m_Events.end(), [this, column, order](auto e1, auto e2) {
403 auto data1 = impl->sortData(column, e1);
404 auto data2 = impl->sortData(column, e2);
398 405
399 auto result = data1.toString() < data2.toString();
406 auto result = data1.toString() < data2.toString();
400 407
401 return order == Qt::AscendingOrder ? result : !result;
402 });
408 return order == Qt::AscendingOrder ? result : !result;
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 return {MIME_TYPE_EVENT_LIST, MIME_TYPE_SOURCE_CATALOGUE_LIST, MIME_TYPE_TIME_RANGE};
422 return { MIME_TYPE_EVENT_LIST, MIME_TYPE_SOURCE_CATALOGUE_LIST, MIME_TYPE_TIME_RANGE };
416 423 }
417 424
418 QMimeData *CatalogueEventsModel::mimeData(const QModelIndexList &indexes) const
425 QMimeData* CatalogueEventsModel::mimeData(const QModelIndexList& indexes) const
419 426 {
420 427 auto mimeData = new QMimeData;
421 428
422 bool isFirst = true;
423
424 QVector<std::shared_ptr<DBEvent> > eventList;
425 QVector<std::shared_ptr<DBEventProduct> > eventProductList;
426
427 DateTimeRange firstTimeRange;
428 for (const auto &index : indexes) {
429 if (index.column() == 0) { // only the first column
430
431 auto type = itemTypeOf(index);
432 if (type == ItemType::Event) {
433 auto event = getEvent(index);
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 CatalogueEventsModel::ItemType CatalogueEventsModel::itemTypeOf(const QModelIndex &index) const
488 CatalogueEventsModel::ItemType CatalogueEventsModel::itemTypeOf(const QModelIndex& index) const
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 m_PlotInterractionMode(SqpApplication::PlotsInteractionMode::None),
23 m_PlotCursorMode(SqpApplication::PlotsCursorMode::NoCursor)
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());
36 });
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 });
37 37
38 38 // VariableController <-> VisualizationController
39 // connect(m_VariableController.get(),
40 // SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)),
41 // m_VisualizationController.get(),
42 // SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)), Qt::DirectConnection);
39 // connect(m_VariableController.get(),
40 // SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)),
41 // m_VisualizationController.get(),
42 // SIGNAL(variableAboutToBeDeleted(std::shared_ptr<Variable>)),
43 // Qt::DirectConnection);
43 44
44 // connect(m_VariableController.get(),
45 // SIGNAL(rangeChanged(std::shared_ptr<Variable>, const DateTimeRange &)),
46 // m_VisualizationController.get(),
47 // SIGNAL(rangeChanged(std::shared_ptr<Variable>, const DateTimeRange &)));
45 // connect(m_VariableController.get(),
46 // SIGNAL(rangeChanged(std::shared_ptr<Variable>, const DateTimeRange &)),
47 // m_VisualizationController.get(),
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 //m_VariableController->setTimeController(m_TimeController.get());
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 SqpApplication::SqpApplication(int &argc, char **argv)
93 : QApplication{argc, argv}, impl{spimpl::make_unique_impl<SqpApplicationPrivate>()}
93 SqpApplication::SqpApplication(int& argc, char** argv)
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 &impl->m_DataSourceController, &DataSourceController::initialize);
101 connect(&impl->m_DataSourceControllerThread, &QThread::finished,
102 &impl->m_DataSourceController, &DataSourceController::finalize);
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 &NetworkController::initialize);
106 &NetworkController::initialize);
106 107 connect(&impl->m_NetworkControllerThread, &QThread::finished, &impl->m_NetworkController,
107 &NetworkController::finalize);
108 &NetworkController::finalize);
108 109
109 110 connect(&impl->m_VisualizationControllerThread, &QThread::started,
110 &impl->m_VisualizationController, &VisualizationController::initialize);
111 &impl->m_VisualizationController, &VisualizationController::initialize);
111 112 connect(&impl->m_VisualizationControllerThread, &QThread::finished,
112 &impl->m_VisualizationController, &VisualizationController::finalize);
113 &impl->m_VisualizationController, &VisualizationController::finalize);
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 DataSourceController &SqpApplication::dataSourceController() noexcept
125 DataSourceController& SqpApplication::dataSourceController() noexcept
129 126 {
130 127 return impl->m_DataSourceController;
131 128 }
132 129
133 NetworkController &SqpApplication::networkController() noexcept
130 NetworkController& SqpApplication::networkController() noexcept
134 131 {
135 132 return impl->m_NetworkController;
136 133 }
137 134
138 TimeController &SqpApplication::timeController() noexcept
135 TimeController& SqpApplication::timeController() noexcept
139 136 {
140 137 return impl->m_TimeController;
141 138 }
142 139
143 VariableController2 &SqpApplication::variableController() noexcept
140 VariableController2& SqpApplication::variableController() noexcept
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 //VariableModel2 &SqpApplication::variableModel() noexcept
150 // VariableModel2 &SqpApplication::variableModel() noexcept
154 151 //{
155 152 // return impl->m_VariableModel;
156 153 //}
157 154
158 VisualizationController &SqpApplication::visualizationController() noexcept
155 VisualizationController& SqpApplication::visualizationController() noexcept
159 156 {
160 157 return impl->m_VisualizationController;
161 158 }
162 159
163 CatalogueController &SqpApplication::catalogueController() noexcept
160 CatalogueController& SqpApplication::catalogueController() noexcept
164 161 {
165 162 return impl->m_CatalogueController;
166 163 }
167 164
168 DragDropGuiController &SqpApplication::dragDropGuiController() noexcept
165 DragDropGuiController& SqpApplication::dragDropGuiController() noexcept
169 166 {
170 167 return impl->m_DragDropGuiController;
171 168 }
172 169
173 ActionsGuiController &SqpApplication::actionsGuiController() noexcept
170 ActionsGuiController& SqpApplication::actionsGuiController() noexcept
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 <QPoint>
5 #include <QCoreApplication>
6 6 #include <QCursor>
7 #include <QDesktopWidget>
7 8 #include <QMouseEvent>
8 #include <QCoreApplication>
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 return QPoint{widget->width()/2,widget->height()/2};
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 static inline constexpr bool is_QWidgetOrDerived = std::is_base_of<QWidget,T>::value;
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 template<typename T>
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 if constexpr(has_viewport<T>)
38 if constexpr (has_viewport<T>)
38 39 {
39 if constexpr(is_QWidgetOrDerived<viewport_type<T>>)
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 if constexpr(has_viewport<T>)
60 if constexpr (has_viewport<T>)
60 61 {
61 if constexpr(is_QWidgetOrDerived<viewport_type<T>>)
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 if constexpr(has_topLevelItem<T>)
80 if constexpr (has_topLevelItem<T>)
80 81 {
81 return widget->topLevelItem(itemIndex);
82 return widget->topLevelItem(itemIndex);
82 83 }
83 84 else
84 85 {
85 return widget->item(itemIndex);
86 return widget->item(itemIndex);
86 87 }
87 88 }
88 89
89 #define SELECT_ITEM(widget, itemIndex, item)\
90 auto item = getItem(widget, itemIndex);\
91 {\
92 auto itemCenterPos = widget->visualItemRect(item).center();\
93 QTest::mouseClick(widget->viewport(), Qt::LeftButton, Qt::NoModifier, itemCenterPos);\
94 QVERIFY(widget->selectedItems().size() > 0);\
95 QVERIFY(widget->selectedItems().contains(item));\
90 #define SELECT_ITEM(widget, itemIndex, item) \
91 auto item = getItem(widget, itemIndex); \
92 { \
93 auto itemCenterPos = widget->visualItemRect(item).center(); \
94 QTest::mouseClick(widget->viewport(), Qt::LeftButton, Qt::NoModifier, itemCenterPos); \
95 QVERIFY(widget->selectedItems().size() > 0); \
96 QVERIFY(widget->selectedItems().contains(item)); \
96 97 }
97 98
98 99
99 #define GET_CHILD_WIDGET_FOR_GUI_TESTS(parent, child, childType, childName)\
100 childType* child = parent.findChild<childType*>(childName); \
101 QVERIFY(child!=Q_NULLPTR); \
100 #define GET_CHILD_WIDGET_FOR_GUI_TESTS(parent, child, childType, childName) \
101 childType* child = parent.findChild<childType*>(childName); \
102 QVERIFY(child != Q_NULLPTR); \
102 103 setMouseTracking(child);
103 104
104 template<typename T1, typename T2, typename T3, typename T4=void>
105 void dragnDropItem(T1* sourceWidget, T2* destWidget, T3* item, T4* destItem=Q_NULLPTR)
105 template <typename T1, typename T2, typename T3, typename T4 = void>
106 void dragnDropItem(T1* sourceWidget, T2* destWidget, T3* item, T4* destItem = Q_NULLPTR)
106 107 {
107 108 auto itemCenterPos = sourceWidget->visualItemRect(item).center();
108 if constexpr(has_viewport<T1>)
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 mouseMove(sourceWidget,itemCenterPos, Qt::LeftButton);
117 itemCenterPos+=QPoint(0,-10);
118 QTimer::singleShot(100,[destWidget,destItem](){
119 mouseMove(destWidget, destWidget->rect().center(),Qt::LeftButton);
120 mouseMove(destWidget, destWidget->rect().center()+QPoint(0,-10),Qt::LeftButton);
121 if constexpr(!std::is_same_v<void, T4>)
117 mouseMove(sourceWidget, itemCenterPos, Qt::LeftButton);
118 itemCenterPos += QPoint(0, -10);
119 QTimer::singleShot(100, [destWidget, destItem]() {
120 mouseMove(destWidget, destWidget->rect().center(), Qt::LeftButton);
121 mouseMove(destWidget, destWidget->rect().center() + QPoint(0, -10), Qt::LeftButton);
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 else if constexpr(has_viewport<T2>)
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 mouseMove(sourceWidget,itemCenterPos,Qt::LeftButton);
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 mouseMove(w, {cent.x() + dx, cent.y()}, Qt::LeftButton);
145 mouseMove(w, { cent.x() + dx, cent.y() }, Qt::LeftButton);
145 146 QTest::mouseRelease(w, Qt::LeftButton);
146 147 }
147 148
148 ALIAS_TEMPLATE_FUNCTION(isReady, static_cast<SqpApplication *>(qApp)->variableController().isReady)
149 ALIAS_TEMPLATE_FUNCTION(isReady, static_cast<SqpApplication*>(qApp)->variableController().isReady)
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 template<typename T>
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 #define GET_CHILD_WIDGET_FOR_GUI_TESTS(parent, child, childType, childName)\
167 childType* child = parent.findChild<childType*>(childName); \
168 QVERIFY(child!=Q_NULLPTR); \
167 #define GET_CHILD_WIDGET_FOR_GUI_TESTS(parent, child, childType, childName) \
168 childType* child = parent.findChild<childType*>(childName); \
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