From 214142fb6f0f777c2b2b2bd556456fdc61f87b89 Mon Sep 17 00:00:00 2001 From: Florian Reimold <11774314+FlorianReimold@users.noreply.github.com> Date: Mon, 15 Jan 2024 10:31:04 +0100 Subject: [PATCH 01/20] eCAL Sys already compiles and runs with Qt6 --- CMakeLists.txt | 12 ++-- app/sys/sys_gui/CMakeLists.txt | 56 ++++++++++++++++--- app/sys/sys_gui/src/ecalsys_gui.cpp | 17 ++++-- .../src/widgets/groupwidget/group_widget.cpp | 2 +- .../import_from_cloud_widget.cpp | 11 ++-- .../import_from_cloud_window.cpp | 1 - .../widgets/runnerwidget/runner_window.cpp | 1 - .../src/widgets/taskwidget/task_widget.cpp | 2 +- .../group_state_min_task_state_tree_item.cpp | 2 +- .../treemodels/group_state_tree_item.cpp | 2 +- .../widgets/treemodels/group_tree_item.cpp | 2 +- .../widgets/treemodels/runner_tree_item.cpp | 2 +- .../src/widgets/treemodels/task_tree_item.cpp | 10 ++-- lib/CustomQt/CMakeLists.txt | 13 ++--- .../include/CustomQt/QAdvancedTreeView.h | 3 +- lib/CustomQt/src/QAdvancedTreeView.cpp | 9 +-- lib/CustomQt/src/QListMenuToolButton.cpp | 4 +- .../src/QMulticolumnSortFilterProxyModel.cpp | 19 ++++++- lib/QEcalParser/CMakeLists.txt | 24 +++++--- .../function_list_model.cpp | 6 +- .../ecal_parser_lineedit.cpp | 4 +- 21 files changed, 136 insertions(+), 66 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index af447a1a42..c8891d124f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,6 +70,7 @@ endif() # -------------------------------------------------------- option(HAS_HDF5 "Platform supports HDF5 library" ON) option(HAS_QT5 "Platform supports Qt 5 library" ON) +option(HAS_QT6 "Platform supports Qt 5 library" OFF) option(HAS_CURL "Build with CURL (i.e. upload support in the recorder app)" ON) option(HAS_CAPNPROTO "Platform supports Cap'n Proto library" OFF) option(HAS_FLATBUFFERS "Platform supports flatbuffers library" OFF) @@ -329,13 +330,13 @@ add_subdirectory(lib/ThreadingUtils) add_subdirectory(lib/CustomTclap) add_subdirectory(lib/ecal_utils) -if(HAS_QT5) +if(HAS_QT5 OR HAS_QT6) add_subdirectory(lib/CustomQt) endif() add_subdirectory(lib/EcalParser) -if(HAS_QT5) +if(HAS_QT5 OR HAS_QT6) add_subdirectory(lib/QEcalParser) -endif(HAS_QT5) +endif() # -------------------------------------------------------- # ecal mon plugin sdk @@ -422,8 +423,11 @@ endif() # -------------------------------------------------------- # qt applications # -------------------------------------------------------- -if(BUILD_APPS AND HAS_QT5) +if(BUILD_APPS AND HAS_QT6) add_subdirectory(app/sys/sys_gui) +endif() + +if(BUILD_APPS AND HAS_QT5) add_subdirectory(app/mon/mon_gui) if(WIN32) set(ECAL_MON_PLUGIN_DIR ecalmon_plugins) diff --git a/app/sys/sys_gui/CMakeLists.txt b/app/sys/sys_gui/CMakeLists.txt index 9f9608ff9f..2ae2010290 100644 --- a/app/sys/sys_gui/CMakeLists.txt +++ b/app/sys/sys_gui/CMakeLists.txt @@ -16,12 +16,19 @@ # # ========================= eCAL LICENSE ================================= +cmake_minimum_required(VERSION 3.14) + +# Allow the install command to use generator expressions +if(POLICY CMP0087) + cmake_policy(SET CMP0087 NEW) +endif() + set(PROJECT_NAME sys_gui) -find_package(Qt5 COMPONENTS - Core - Widgets -REQUIRED) +# Legacy Qt5 (pre 5.15) support as suggested by teh Qt Documentation: +# https://doc.qt.io/qt-6/cmake-qt5-and-qt6-compatibility.html#supporting-older-qt-5-versions +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets) find_package(tclap REQUIRED) find_package(Protobuf REQUIRED) @@ -145,8 +152,14 @@ if(UNIX) endif() # compile qt resource files and ui files -qt5_add_resources(autogen_resources ${qt_resource_files}) -qt5_wrap_ui (autogen_ui ${ui_files}) +if (${QT_VERSION_MAJOR} GREATER_EQUAL 6) + qt_add_resources(autogen_resources ${qt_resource_files}) + qt_wrap_ui (autogen_ui ${ui_files}) +else() + qt5_add_resources(autogen_resources ${qt_resource_files}) + qt5_wrap_ui (autogen_ui ${ui_files}) +endif() + # Add all files. The resource files and ui files are not necessary, but we want them to show up in the IDE ecal_add_app_qt(${PROJECT_NAME} @@ -162,7 +175,8 @@ ecal_add_app_qt(${PROJECT_NAME} create_targets_protobuf() target_link_libraries (${PROJECT_NAME} - Qt5::Widgets + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets CustomQt CustomTclap tclap::tclap @@ -190,10 +204,34 @@ endif() target_include_directories(${PROJECT_NAME} PRIVATE src) target_include_directories(${PROJECT_NAME} PRIVATE $) +if ((WIN32 OR APPLE) AND (${QT_VERSION_MAJOR} GREATER_EQUAL 6)) + + # Generate a script that will deploy all necessary Qt DLLs to the binary folder + # https://doc.qt.io/qt-6/qt-deploy-runtime-dependencies.html + # Available for Qt 6.3 and up (=> Not for Qt5!) + # Executing it requires CMake 3.14 and up, due to policy https://cmake.org/cmake/help/latest/policy/CMP0087.html + qt_generate_deploy_app_script( + TARGET ${PROJECT_NAME} + OUTPUT_SCRIPT qt_deploy_script + NO_COMPILER_RUNTIME + NO_UNSUPPORTED_PLATFORM_ERROR + ) + + # Add a postbuild script that will also execute the created script via cmake -P + # This is necessary to make the application startable / debuggable from the build directory. + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -DQT_DEPLOY_PREFIX=$ -DQT_DEPLOY_BIN_DIR=. -P ${qt_deploy_script} + ) -if(WIN32) + # Use the script for deploying the qt dlls in the install dir + install(SCRIPT ${qt_deploy_script}) + +elseif(WIN32) + + # For Qt5 we use our legacy script. # Deploy Qt DLLs in the binary folder. This is necessary for starting the application from whithin the IDE without having to copy QtCore.dll, QtWidgets.dll etc. by hand each time qt_add_windeployqt_postbuild(--no-system-d3d-compiler --no-compiler-runtime --no-opengl-sw --pdb "$") + endif() # Create a source tree that mirrors the filesystem @@ -227,4 +265,4 @@ if (UNIX) DESTINATION "${CMAKE_INSTALL_DATADIR}/icons/Humanity/scalable/mimetypes/") endif() -ecal_install_app(${PROJECT_NAME} START_MENU_NAME "eCAL Sys") +ecal_install_app(${PROJECT_NAME} START_MENU_NAME "eCAL Sys") \ No newline at end of file diff --git a/app/sys/sys_gui/src/ecalsys_gui.cpp b/app/sys/sys_gui/src/ecalsys_gui.cpp index 3c0c4dd150..800d6fcb41 100644 --- a/app/sys/sys_gui/src/ecalsys_gui.cpp +++ b/app/sys/sys_gui/src/ecalsys_gui.cpp @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -890,10 +889,18 @@ void EcalsysGui::menuEditRunnersTriggered() void EcalsysGui::menuViewResetLayoutTriggered() { - setTheme(Theme::Default); + setTheme(Theme::Dark); // Back when we saved the initial window geometry, the window-manager might not have positioned the window on the screen, yet - int screen_number = QApplication::desktop()->screenNumber(this); + + int screen_number = 0; + QScreen* current_screen = this->screen(); + if (current_screen) + { + screen_number = QApplication::screens().indexOf(current_screen); + if (screen_number < 0) + screen_number = 0; + } restoreGeometry(initial_geometry_); restoreState(initial_state_); @@ -901,10 +908,10 @@ void EcalsysGui::menuViewResetLayoutTriggered() move(QGuiApplication::screens().at(screen_number)->availableGeometry().center() - rect().center()); task_widget_ ->resetLayout(); - runner_window_ ->resetLayout(QApplication::desktop()->screenNumber(this)); + runner_window_ ->resetLayout(screen_number); group_widget_ ->resetLayout(); group_edit_widget_ ->resetLayout(); - import_from_cloud_window_->resetLayout(QApplication::desktop()->screenNumber(this)); + import_from_cloud_window_->resetLayout(screen_number); } void EcalsysGui::menuOptionsCheckTargetsReachableToggled(bool enabled) diff --git a/app/sys/sys_gui/src/widgets/groupwidget/group_widget.cpp b/app/sys/sys_gui/src/widgets/groupwidget/group_widget.cpp index 4112830645..461bd1896d 100644 --- a/app/sys/sys_gui/src/widgets/groupwidget/group_widget.cpp +++ b/app/sys/sys_gui/src/widgets/groupwidget/group_widget.cpp @@ -410,7 +410,7 @@ void GroupWidget::groupTreeContextMenu(const QPoint& pos) void GroupWidget::filterTextChanged(QString text) { group_sort_filter_proxy_model_->setFilterCaseSensitivity(Qt::CaseSensitivity::CaseInsensitive); - group_sort_filter_proxy_model_->setFilterRegExp(text); + group_sort_filter_proxy_model_->setFilterRegularExpression(text); } //////////////////////////////////////////////////////////////////////////////// diff --git a/app/sys/sys_gui/src/widgets/import_from_cloud_widget/import_from_cloud_widget.cpp b/app/sys/sys_gui/src/widgets/import_from_cloud_widget/import_from_cloud_widget.cpp index 82351c43fa..e2882fd2c3 100644 --- a/app/sys/sys_gui/src/widgets/import_from_cloud_widget/import_from_cloud_widget.cpp +++ b/app/sys/sys_gui/src/widgets/import_from_cloud_widget/import_from_cloud_widget.cpp @@ -21,6 +21,7 @@ #include #include +#include #include @@ -127,7 +128,7 @@ ImportFromCloudWidget::ImportFromCloudWidget(QWidget *parent) connect(ui_.auto_detect_runners_button, &QPushButton::clicked, [this]() {autoDetectRunnersFor(getCheckedTasks()); }); connect(ui_.cancel_button, SIGNAL(clicked()), this, SIGNAL(closeSignal())); connect(ui_.import_button, SIGNAL(clicked()), this, SLOT(import())); - connect(ui_.show_all_tasks_checkbox, &QCheckBox::toggled, [this](bool checked) { task_sort_filter_proxy_model_->setFilterRegExp(checked ? "" : "enabled"); }); + connect(ui_.show_all_tasks_checkbox, &QCheckBox::toggled, [this](bool checked) { task_sort_filter_proxy_model_->setFilterRegularExpression(checked ? "" : "enabled"); }); // connect the task-tree ui_.tasks_tree->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu); @@ -237,7 +238,7 @@ void ImportFromCloudWidget::reload() updateTaskTableHeaderCheckbox(); // Re-apply the filter - task_sort_filter_proxy_model_->setFilterRegExp(task_sort_filter_proxy_model_->filterRegExp()); + task_sort_filter_proxy_model_->setFilterRegularExpression(task_sort_filter_proxy_model_->filterRegularExpression()); } void ImportFromCloudWidget::setUpdateEnabled(bool enabled) @@ -778,7 +779,7 @@ void ImportFromCloudWidget::monitorUpdated() updateImportCheckboxEnabledStates(); updateTaskTableHeaderCheckbox(); updateButtons(); - task_sort_filter_proxy_model_->setFilterRegExp(task_sort_filter_proxy_model_->filterRegExp()); + task_sort_filter_proxy_model_->setFilterRegularExpression(task_sort_filter_proxy_model_->filterRegularExpression()); } void ImportFromCloudWidget::tasksChanged(std::vector>) @@ -786,7 +787,7 @@ void ImportFromCloudWidget::tasksChanged(std::vectorsetFilterRegExp(task_sort_filter_proxy_model_->filterRegExp()); + task_sort_filter_proxy_model_->setFilterRegularExpression(task_sort_filter_proxy_model_->filterRegularExpression()); } void ImportFromCloudWidget::ecalsysOptionsChanged() @@ -799,7 +800,7 @@ void ImportFromCloudWidget::configChanged() updateImportCheckboxEnabledStates(); updateTaskTableHeaderCheckbox(); updateButtons(); - task_sort_filter_proxy_model_->setFilterRegExp(task_sort_filter_proxy_model_->filterRegExp()); + task_sort_filter_proxy_model_->setFilterRegularExpression(task_sort_filter_proxy_model_->filterRegularExpression()); } void ImportFromCloudWidget::updateButtons() diff --git a/app/sys/sys_gui/src/widgets/import_from_cloud_widget/import_from_cloud_window.cpp b/app/sys/sys_gui/src/widgets/import_from_cloud_widget/import_from_cloud_window.cpp index e673b31df9..d7226110ba 100644 --- a/app/sys/sys_gui/src/widgets/import_from_cloud_widget/import_from_cloud_window.cpp +++ b/app/sys/sys_gui/src/widgets/import_from_cloud_widget/import_from_cloud_window.cpp @@ -19,7 +19,6 @@ #include "import_from_cloud_window.h" -#include #include ImportFromCloudWindow::ImportFromCloudWindow(QWidget *parent) diff --git a/app/sys/sys_gui/src/widgets/runnerwidget/runner_window.cpp b/app/sys/sys_gui/src/widgets/runnerwidget/runner_window.cpp index f34bad673b..4a91454c9c 100644 --- a/app/sys/sys_gui/src/widgets/runnerwidget/runner_window.cpp +++ b/app/sys/sys_gui/src/widgets/runnerwidget/runner_window.cpp @@ -21,7 +21,6 @@ #include #include -#include RunnerWindow::RunnerWindow(QWidget *parent) : QMainWindow(parent) diff --git a/app/sys/sys_gui/src/widgets/taskwidget/task_widget.cpp b/app/sys/sys_gui/src/widgets/taskwidget/task_widget.cpp index bf5cd9f449..6ace321b5b 100644 --- a/app/sys/sys_gui/src/widgets/taskwidget/task_widget.cpp +++ b/app/sys/sys_gui/src/widgets/taskwidget/task_widget.cpp @@ -329,7 +329,7 @@ void TaskWidget::setEditControlsVisibility(bool visibile) void TaskWidget::filterTextChanged(QString text) { task_tree_sort_filter_proxy_model_->setFilterCaseSensitivity(Qt::CaseSensitivity::CaseInsensitive); - task_tree_sort_filter_proxy_model_->setFilterRegExp(text); + task_tree_sort_filter_proxy_model_->setFilterRegularExpression(text); } //////////////////////////////////////////////////////////////////////////////// diff --git a/app/sys/sys_gui/src/widgets/treemodels/group_state_min_task_state_tree_item.cpp b/app/sys/sys_gui/src/widgets/treemodels/group_state_min_task_state_tree_item.cpp index f6822e5e73..50b854e781 100644 --- a/app/sys/sys_gui/src/widgets/treemodels/group_state_min_task_state_tree_item.cpp +++ b/app/sys/sys_gui/src/widgets/treemodels/group_state_min_task_state_tree_item.cpp @@ -148,7 +148,7 @@ QVariant GroupStateMinTaskStateTreeItem::data(Columns column, Qt::ItemDataRole r } } - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } bool GroupStateMinTaskStateTreeItem::setData(int column, const QVariant& data, Qt::ItemDataRole role) diff --git a/app/sys/sys_gui/src/widgets/treemodels/group_state_tree_item.cpp b/app/sys/sys_gui/src/widgets/treemodels/group_state_tree_item.cpp index 1abd1e62c0..f9cacffe57 100644 --- a/app/sys/sys_gui/src/widgets/treemodels/group_state_tree_item.cpp +++ b/app/sys/sys_gui/src/widgets/treemodels/group_state_tree_item.cpp @@ -78,7 +78,7 @@ QVariant GroupStateTreeItem::data(Columns column, Qt::ItemDataRole role) const return data(column, Qt::ItemDataRole::DisplayRole); } - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } std::shared_ptr GroupStateTreeItem::getGroupState() diff --git a/app/sys/sys_gui/src/widgets/treemodels/group_tree_item.cpp b/app/sys/sys_gui/src/widgets/treemodels/group_tree_item.cpp index 1bc479e6a8..2418a239b1 100644 --- a/app/sys/sys_gui/src/widgets/treemodels/group_tree_item.cpp +++ b/app/sys/sys_gui/src/widgets/treemodels/group_tree_item.cpp @@ -131,7 +131,7 @@ QVariant GroupTreeItem::data(Columns column, Qt::ItemDataRole role) const return data(column, Qt::ItemDataRole::DisplayRole); } - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } std::shared_ptr GroupTreeItem::getGroup() diff --git a/app/sys/sys_gui/src/widgets/treemodels/runner_tree_item.cpp b/app/sys/sys_gui/src/widgets/treemodels/runner_tree_item.cpp index 3b500dc23c..544526e19d 100644 --- a/app/sys/sys_gui/src/widgets/treemodels/runner_tree_item.cpp +++ b/app/sys/sys_gui/src/widgets/treemodels/runner_tree_item.cpp @@ -175,7 +175,7 @@ QVariant RunnerTreeItem::data(Columns column, Qt::ItemDataRole role) const return data(column, Qt::ItemDataRole::DisplayRole); } - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } diff --git a/app/sys/sys_gui/src/widgets/treemodels/task_tree_item.cpp b/app/sys/sys_gui/src/widgets/treemodels/task_tree_item.cpp index 0fef1d67c2..2ee4ab6fec 100644 --- a/app/sys/sys_gui/src/widgets/treemodels/task_tree_item.cpp +++ b/app/sys/sys_gui/src/widgets/treemodels/task_tree_item.cpp @@ -154,7 +154,7 @@ QVariant TaskTreeItem::data(Columns column, Qt::ItemDataRole role) const } else { - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } } @@ -210,7 +210,7 @@ QVariant TaskTreeItem::data(Columns column, Qt::ItemDataRole role) const case eCAL_Process_eSeverity::proc_sev_failed: return QColor(240, 20, 20); default: - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } } } @@ -229,7 +229,7 @@ QVariant TaskTreeItem::data(Columns column, Qt::ItemDataRole role) const } else { - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } } else if (options.use_localhost_for_all_tasks) @@ -242,7 +242,7 @@ QVariant TaskTreeItem::data(Columns column, Qt::ItemDataRole role) const } else { - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } } } @@ -323,7 +323,7 @@ QVariant TaskTreeItem::data(Columns column, Qt::ItemDataRole role) const } } - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } diff --git a/lib/CustomQt/CMakeLists.txt b/lib/CustomQt/CMakeLists.txt index 50c6ce6c27..0e93dba090 100644 --- a/lib/CustomQt/CMakeLists.txt +++ b/lib/CustomQt/CMakeLists.txt @@ -18,11 +18,10 @@ project(CustomQt) -find_package(Qt5 COMPONENTS - Core - Widgets -REQUIRED) - +# Legacy Qt5 (pre 5.15) support as suggested by teh Qt Documentation: +# https://doc.qt.io/qt-6/cmake-qt5-and-qt6-compatibility.html#supporting-older-qt-5-versions +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets) set(CMAKE_AUTOMOC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -75,8 +74,8 @@ target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) target_link_libraries(${PROJECT_NAME} - Qt5::Core - Qt5::Widgets + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets ) target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_14) diff --git a/lib/CustomQt/include/CustomQt/QAdvancedTreeView.h b/lib/CustomQt/include/CustomQt/QAdvancedTreeView.h index 830e1d7e30..4c6a102b7e 100644 --- a/lib/CustomQt/include/CustomQt/QAdvancedTreeView.h +++ b/lib/CustomQt/include/CustomQt/QAdvancedTreeView.h @@ -155,7 +155,8 @@ class QAdvancedTreeView : public QTreeView */ bool restoreState(const QByteArray& state, int32_t version = 0); - QStyleOptionViewItem viewOptions() const override; + // TODO: Add again or check why it existed in the first place + //QStyleOptionViewItem viewOptions() const override; protected: void keyPressEvent(QKeyEvent* key_event) override; diff --git a/lib/CustomQt/src/QAdvancedTreeView.cpp b/lib/CustomQt/src/QAdvancedTreeView.cpp index 99905650f2..9803f19bc3 100644 --- a/lib/CustomQt/src/QAdvancedTreeView.cpp +++ b/lib/CustomQt/src/QAdvancedTreeView.cpp @@ -284,7 +284,8 @@ bool QAdvancedTreeView::restoreState(const QByteArray& state, int32_t version) return true; } -QStyleOptionViewItem QAdvancedTreeView::viewOptions() const -{ - return QTreeView::viewOptions(); -} \ No newline at end of file +// TODO: Add again or check why it existed in the first place +//QStyleOptionViewItem QAdvancedTreeView::viewOptions() const +//{ +// return QTreeView::viewOptions(); +//} \ No newline at end of file diff --git a/lib/CustomQt/src/QListMenuToolButton.cpp b/lib/CustomQt/src/QListMenuToolButton.cpp index 54572893ec..e02c883ce3 100644 --- a/lib/CustomQt/src/QListMenuToolButton.cpp +++ b/lib/CustomQt/src/QListMenuToolButton.cpp @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -85,8 +84,7 @@ void QListMenuToolButton::showListMenu() } // Position on screen - int screen_number = QApplication::desktop()->screenNumber(this); - QRect screen_geometry = QApplication::screens()[screen_number]->geometry(); + QRect screen_geometry = this->screen()->geometry(); QRect global_button_geometry = QRect(mapToGlobal(QPoint(0, 0)), size()); QRect popup_geometry = QRect(global_button_geometry.bottomLeft(), QSize(target_width, target_height)); diff --git a/lib/CustomQt/src/QMulticolumnSortFilterProxyModel.cpp b/lib/CustomQt/src/QMulticolumnSortFilterProxyModel.cpp index 1e1646f3ab..4dd68ece6b 100644 --- a/lib/CustomQt/src/QMulticolumnSortFilterProxyModel.cpp +++ b/lib/CustomQt/src/QMulticolumnSortFilterProxyModel.cpp @@ -20,6 +20,7 @@ #include "CustomQt/QMulticolumnSortFilterProxyModel.h" #include +#include QMulticolumnSortFilterProxyModel::QMulticolumnSortFilterProxyModel(QObject* parent) : QStableSortFilterProxyModel(parent) @@ -56,7 +57,7 @@ QVector QMulticolumnSortFilterProxyModel::filterKeyColumns() const bool QMulticolumnSortFilterProxyModel::filterDirectAcceptsRow(int source_row, const QModelIndex &source_parent) const { - QRegExp filter_regexp = filterRegExp(); + QRegularExpression filter_regexp = filterRegularExpression(); for (int column : filter_columns_) { @@ -97,6 +98,9 @@ bool QMulticolumnSortFilterProxyModel::lessThan(const QModelIndex &left, const Q { // Don't fake the sort order, we have to follow the user-set one +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + return QPartialOrdering::Less == QVariant::compare(left_data, right_data); +#else // Pre Qt 6.0 // Qt Deprecation note: // // QVariant::operator< is deprecated since Qt 5.15, mainly because @@ -111,14 +115,27 @@ bool QMulticolumnSortFilterProxyModel::lessThan(const QModelIndex &left, const Q // // The operators still exist in Qt 6.0 beta. return (left_data < right_data); +#endif // QT_VERSION } else { // We want to ignore the user-set sort order, so we fake the less-than method if (sortOrder() == always_sorted_sort_order_) + { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + return QPartialOrdering::Less == QVariant::compare(left_data, right_data); +#else // Pre Qt 6.0 return (left_data < right_data); // Qt 5.15 Deprecation note: see above +#endif // QT_VERSION + } else + { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + return QPartialOrdering::Greater == QVariant::compare(left_data, right_data); +#else // Pre Qt 6.0 return (left_data > right_data); // Qt 5.15 Deprecation note: see above +#endif // QT_VERSION + } } } #ifdef _MSC_VER diff --git a/lib/QEcalParser/CMakeLists.txt b/lib/QEcalParser/CMakeLists.txt index d635906c83..9a5fda1be6 100644 --- a/lib/QEcalParser/CMakeLists.txt +++ b/lib/QEcalParser/CMakeLists.txt @@ -18,11 +18,10 @@ project(QEcalParser) -find_package(Qt5 COMPONENTS - Core - Widgets -REQUIRED) - +# Legacy Qt5 (pre 5.15) support as suggested by teh Qt Documentation: +# https://doc.qt.io/qt-6/cmake-qt5-and-qt6-compatibility.html#supporting-older-qt-5-versions +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC OFF) # Reason for being turned off: AutoUIC will prevent VS from detecting changes in .ui files @@ -56,8 +55,15 @@ set(qecalparser_resources ) # compile qt resource files and ui files -qt5_add_resources(autogen_resources ${qecalparser_resources}) -qt5_wrap_ui (autogen_ui ${qecalparser_ui}) + +if (${QT_VERSION_MAJOR} GREATER 5) + qt_add_resources(autogen_resources ${qecalparser_resources}) + qt_wrap_ui (autogen_ui ${qecalparser_ui}) +else() + qt5_add_resources(autogen_resources ${qecalparser_resources}) + qt5_wrap_ui (autogen_ui ${qecalparser_ui}) +endif() + add_library (${PROJECT_NAME} ${qecalparser_includes} @@ -75,8 +81,8 @@ target_include_directories(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME} PUBLIC - Qt5::Core - Qt5::Widgets + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets PRIVATE CustomQt EcalParser diff --git a/lib/QEcalParser/src/ecal_parser_editor/function_list_model.cpp b/lib/QEcalParser/src/ecal_parser_editor/function_list_model.cpp index f6856454db..2720a53328 100644 --- a/lib/QEcalParser/src/ecal_parser_editor/function_list_model.cpp +++ b/lib/QEcalParser/src/ecal_parser_editor/function_list_model.cpp @@ -50,7 +50,7 @@ FunctionListModel::~FunctionListModel() QVariant FunctionListModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) - return QVariant::Invalid; + return QVariant(); // Invalid QVariant const int row = index.row(); const Columns column = (Columns)index.column(); @@ -72,7 +72,7 @@ QVariant FunctionListModel::data(const QModelIndex &index, int role) const } } - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } QVariant FunctionListModel::headerData(int section, Qt::Orientation orientation, int role) const @@ -82,7 +82,7 @@ QVariant FunctionListModel::headerData(int section, Qt::Orientation orientation, { return column_labels_.at((Columns)section); } - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } QModelIndex FunctionListModel::index(int row, int column, const QModelIndex& /*parent*/) const diff --git a/lib/QEcalParser/src/ecal_parser_lineedit/ecal_parser_lineedit.cpp b/lib/QEcalParser/src/ecal_parser_lineedit/ecal_parser_lineedit.cpp index 97398f669e..fd9b9e5609 100644 --- a/lib/QEcalParser/src/ecal_parser_lineedit/ecal_parser_lineedit.cpp +++ b/lib/QEcalParser/src/ecal_parser_lineedit/ecal_parser_lineedit.cpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include QEcalParserLineEdit::QEcalParserLineEdit(QWidget *parent) : QEcalParserLineEdit("", parent) @@ -53,7 +53,7 @@ void QEcalParserLineEdit::openDialog() QEcalParserEditorDialog dialog(text(), this); if (dialog.exec() == QDialog::Accepted) { - setText(dialog.text().remove(QRegExp("[\\n\\r]"))); + setText(dialog.text().remove(QRegularExpression("[\\n\\r]"))); } } From b6792bc80b17d846d907fb6190e5468f7115d31c Mon Sep 17 00:00:00 2001 From: Florian Reimold <11774314+FlorianReimold@users.noreply.github.com> Date: Tue, 16 Jan 2024 13:15:16 +0100 Subject: [PATCH 02/20] Intermediate state while working on eCAL Mon GUI --- CMakeLists.txt | 6 +- app/mon/mon_gui/CMakeLists.txt | 125 +++++++++++------- app/mon/mon_gui/src/ecalmon.cpp | 10 +- .../ecalmon_tree_widget/process_widget.cpp | 2 +- .../ecalmon_tree_widget/service_widget.cpp | 2 +- .../ecalmon_tree_widget/topic_widget.cpp | 28 ++-- .../ecalmon_tree_widget/topic_widget.h | 4 +- .../src/widgets/models/group_tree_item.cpp | 4 +- .../src/widgets/models/group_tree_model.cpp | 17 +-- .../src/widgets/models/host_tree_item.cpp | 6 +- .../mon_gui/src/widgets/models/log_model.cpp | 2 +- .../src/widgets/models/process_tree_item.cpp | 6 +- .../src/widgets/models/service_tree_item.cpp | 6 +- .../models/topic_sort_filter_proxy_model.cpp | 10 +- .../models/topic_sort_filter_proxy_model.h | 8 +- .../src/widgets/models/topic_tree_item.cpp | 4 +- .../visualisation_window.cpp | 1 - app/mon/mon_plugin_lib/CMakeLists.txt | 14 +- app/sys/sys_gui/CMakeLists.txt | 4 +- 19 files changed, 153 insertions(+), 106 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c8891d124f..2ed73ae9d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -341,7 +341,7 @@ endif() # -------------------------------------------------------- # ecal mon plugin sdk # -------------------------------------------------------- -if(HAS_QT5) +if(HAS_QT5 OR HAS_QT6) add_subdirectory(app/mon/mon_plugin_lib) endif(HAS_QT5) @@ -423,12 +423,12 @@ endif() # -------------------------------------------------------- # qt applications # -------------------------------------------------------- -if(BUILD_APPS AND HAS_QT6) +if(BUILD_APPS AND (HAS_QT5 OR HAS_QT6)) add_subdirectory(app/sys/sys_gui) + add_subdirectory(app/mon/mon_gui) endif() if(BUILD_APPS AND HAS_QT5) - add_subdirectory(app/mon/mon_gui) if(WIN32) set(ECAL_MON_PLUGIN_DIR ecalmon_plugins) else() diff --git a/app/mon/mon_gui/CMakeLists.txt b/app/mon/mon_gui/CMakeLists.txt index 5c0af5f981..c142867bb3 100644 --- a/app/mon/mon_gui/CMakeLists.txt +++ b/app/mon/mon_gui/CMakeLists.txt @@ -16,12 +16,19 @@ # # ========================= eCAL LICENSE ================================= +cmake_minimum_required(VERSION 3.14) + +# Allow the install command to use generator expressions +if(POLICY CMP0087) + cmake_policy(SET CMP0087 NEW) +endif() + project(mon_gui) -find_package(Qt5 COMPONENTS - Core - Widgets -REQUIRED) +# Legacy Qt5 (pre 5.15) support as suggested by teh Qt Documentation: +# https://doc.qt.io/qt-6/cmake-qt5-and-qt6-compatibility.html#supporting-older-qt-5-versions +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets) find_package(Protobuf REQUIRED) @@ -171,8 +178,13 @@ endif(ECAL_NPCAP_SUPPORT) # compile qt resource files and ui files -qt5_add_resources(autogen_resources ${qt_resource_files}) -qt5_wrap_ui (autogen_ui ${ui_files}) +if (${QT_VERSION_MAJOR} GREATER_EQUAL 6) + qt_add_resources(autogen_resources ${qt_resource_files}) + qt_wrap_ui (autogen_ui ${ui_files}) +else() + qt5_add_resources(autogen_resources ${qt_resource_files}) + qt5_wrap_ui (autogen_ui ${ui_files}) +endif() # Add all files. The resource files and ui files are not necessary, but we want them to show up in the IDE ecal_add_app_qt(${PROJECT_NAME} @@ -190,7 +202,8 @@ target_link_libraries (${PROJECT_NAME} eCAL::core eCAL::core_pb eCAL::mon_plugin_lib - Qt5::Widgets + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets CustomQt ) @@ -217,9 +230,64 @@ target_include_directories(${PROJECT_NAME} PRIVATE src) target_include_directories(${PROJECT_NAME} PRIVATE $) -if(WIN32) +if ((WIN32 OR APPLE) AND (${QT_VERSION_MAJOR} GREATER_EQUAL 6)) + + # Generate a script that will deploy all necessary Qt DLLs to the binary folder + # https://doc.qt.io/qt-6/qt-deploy-runtime-dependencies.html + # Available for Qt 6.3 and up (=> Not for Qt5!) + # Executing it requires CMake 3.14 and up, due to policy https://cmake.org/cmake/help/latest/policy/CMP0087.html + qt_generate_deploy_app_script( + TARGET ${PROJECT_NAME} + OUTPUT_SCRIPT qt_deploy_script + NO_COMPILER_RUNTIME + NO_UNSUPPORTED_PLATFORM_ERROR + ) + + # Add a postbuild script that will also execute the created script via cmake -P + # This is necessary to make the application startable / debuggable from the build directory. + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -DQT_DEPLOY_PREFIX=$ -DQT_DEPLOY_BIN_DIR=. -P ${qt_deploy_script} + ) + + # Use the script for deploying the qt dlls in the install dir + install(SCRIPT ${qt_deploy_script}) + +elseif(WIN32) + + # For Qt5 we use our legacy script. # Deploy Qt DLLs in the binary folder. This is necessary for starting the application from whithin the IDE without having to copy QtCore.dll, QtWidgets.dll etc. by hand each time qt_add_windeployqt_postbuild(--no-system-d3d-compiler --no-compiler-runtime --no-opengl-sw --pdb "$") + + get_target_property(_qmake_executable Qt5::qmake IMPORTED_LOCATION) + get_filename_component(_qt_bin_dir "${_qmake_executable}" DIRECTORY) + find_program(WINDEPLOYQT_EXECUTABLE windeployqt HINTS "${_qt_bin_dir}") + install(CODE + " + set(_file ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release/ecal_mon_gui.exe) + execute_process( + COMMAND \"${CMAKE_COMMAND}\" -E + env PATH=\"${_qt_bin_dir}\" \"${WINDEPLOYQT_EXECUTABLE}\" + --dry-run + --no-compiler-runtime + --no-angle + --no-opengl-sw + --list mapping + \${_file} + OUTPUT_VARIABLE _output + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + separate_arguments(_files WINDOWS_COMMAND \${_output}) + while(_files) + list(GET _files 0 _src) + list(GET _files 1 _dest) + execute_process( + COMMAND \"${CMAKE_COMMAND}\" -E + copy \${_src} \"\${CMAKE_INSTALL_PREFIX}/bin/\${_dest}\" + ) + list(REMOVE_AT _files 0 1) + endwhile() + " +) endif() # Create a source tree that mirrors the filesystem @@ -244,43 +312,4 @@ source_group( autogen FILES set_property(TARGET ${PROJECT_NAME} PROPERTY FOLDER app/mon) -ecal_install_app(${PROJECT_NAME} START_MENU_NAME "eCAL Monitor") -get_target_property(_qmake_executable Qt5::qmake IMPORTED_LOCATION) -get_filename_component(_qt_bin_dir "${_qmake_executable}" DIRECTORY) -find_program(WINDEPLOYQT_EXECUTABLE windeployqt HINTS "${_qt_bin_dir}") - -# Running this with MSVC 2015 requires CMake 3.6+ -if((MSVC_VERSION VERSION_EQUAL 1900 OR MSVC_VERSION VERSION_GREATER 1900) - AND CMAKE_VERSION VERSION_LESS "3.6") - message(WARNING "Deploying with MSVC 2015+ requires CMake 3.6+") -endif() - -if(WIN32) -install(CODE - " - set(_file ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release/ecal_mon_gui.exe) - execute_process( - COMMAND \"${CMAKE_COMMAND}\" -E - env PATH=\"${_qt_bin_dir}\" \"${WINDEPLOYQT_EXECUTABLE}\" - --dry-run - --no-compiler-runtime - --no-angle - --no-opengl-sw - --list mapping - \${_file} - OUTPUT_VARIABLE _output - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - separate_arguments(_files WINDOWS_COMMAND \${_output}) - while(_files) - list(GET _files 0 _src) - list(GET _files 1 _dest) - execute_process( - COMMAND \"${CMAKE_COMMAND}\" -E - copy \${_src} \"\${CMAKE_INSTALL_PREFIX}/bin/\${_dest}\" - ) - list(REMOVE_AT _files 0 1) - endwhile() - " -) -endif() +ecal_install_app(${PROJECT_NAME} START_MENU_NAME "eCAL Monitor") \ No newline at end of file diff --git a/app/mon/mon_gui/src/ecalmon.cpp b/app/mon/mon_gui/src/ecalmon.cpp index aff5aae2a3..07903377ce 100644 --- a/app/mon/mon_gui/src/ecalmon.cpp +++ b/app/mon/mon_gui/src/ecalmon.cpp @@ -35,7 +35,6 @@ #include "plugin/plugin_manager.h" #include -#include #include #include #include @@ -698,7 +697,14 @@ void Ecalmon::resetLayout() setTheme(Theme::Dark); // Back when we saved the initial window geometry, the window-manager might not have positioned the window on the screen, yet - int screen_number = QApplication::desktop()->screenNumber(this); + int screen_number = 0; + QScreen* current_screen = this->screen(); + if (current_screen) + { + screen_number = QApplication::screens().indexOf(current_screen); + if (screen_number < 0) + screen_number = 0; + } restoreGeometry(initial_geometry_); restoreState(initial_state_); diff --git a/app/mon/mon_gui/src/widgets/ecalmon_tree_widget/process_widget.cpp b/app/mon/mon_gui/src/widgets/ecalmon_tree_widget/process_widget.cpp index 8f0a283d50..db59d3b994 100644 --- a/app/mon/mon_gui/src/widgets/ecalmon_tree_widget/process_widget.cpp +++ b/app/mon/mon_gui/src/widgets/ecalmon_tree_widget/process_widget.cpp @@ -129,7 +129,7 @@ void ProcessWidget::autoSizeColumns() //example_process_pb.set_tsync_mode(); ProcessTreeItem* example_process_item = new ProcessTreeItem(example_process_pb); - GroupTreeItem* example_group_item = new GroupTreeItem("HNAME00____", "", "", QVariant::Invalid, ""); + GroupTreeItem* example_group_item = new GroupTreeItem("HNAME00____", "", "", QVariant(), ""); process_tree_model_->insertItem(example_process_item); process_tree_model_->insertItem(example_group_item); diff --git a/app/mon/mon_gui/src/widgets/ecalmon_tree_widget/service_widget.cpp b/app/mon/mon_gui/src/widgets/ecalmon_tree_widget/service_widget.cpp index e4dac7e09d..bb2d7d9839 100644 --- a/app/mon/mon_gui/src/widgets/ecalmon_tree_widget/service_widget.cpp +++ b/app/mon/mon_gui/src/widgets/ecalmon_tree_widget/service_widget.cpp @@ -123,7 +123,7 @@ void ServiceWidget::autoSizeColumns() method->set_call_count(999999); ServiceTreeItem* example_topic_item = new ServiceTreeItem(example_service_pb, *method); - GroupTreeItem* example_group_item = new GroupTreeItem("__ / eCALRPCService____", "", "", QVariant::Invalid, ""); + GroupTreeItem* example_group_item = new GroupTreeItem("__ / eCALRPCService____", "", "", QVariant(), ""); service_tree_model_->insertItem(example_topic_item); service_tree_model_->insertItem(example_group_item); diff --git a/app/mon/mon_gui/src/widgets/ecalmon_tree_widget/topic_widget.cpp b/app/mon/mon_gui/src/widgets/ecalmon_tree_widget/topic_widget.cpp index fb8c3d7bcf..4cc3e28847 100644 --- a/app/mon/mon_gui/src/widgets/ecalmon_tree_widget/topic_widget.cpp +++ b/app/mon/mon_gui/src/widgets/ecalmon_tree_widget/topic_widget.cpp @@ -33,7 +33,7 @@ #include #include #include -#include +#include TopicWidget::TopicWidget(QWidget *parent) : EcalmonTreeWidget(parent) @@ -59,7 +59,7 @@ TopicWidget::TopicWidget(QWidget *parent) { if (state == Qt::CheckState::Checked) { - topic_sort_filter_proxy_model_->setRegExpLists(QList{}, QList{}); + topic_sort_filter_proxy_model_->setRegExpLists(QList{}, QList{}); } else { @@ -196,21 +196,21 @@ void TopicWidget::loadRegExpLists() // regular expression that properly uses a ",". We cannot do anything about // that without changing the ecal.ini specification. #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) - QList exclude_string_list = exclude_string.split(QRegExp("[\\,,;]"), Qt::SplitBehaviorFlags::SkipEmptyParts); - QList include_string_list = include_string.split(QRegExp("[\\,,;]"), Qt::SplitBehaviorFlags::SkipEmptyParts); + QList exclude_string_list = exclude_string.split(QRegularExpression("[\\,,;]"), Qt::SplitBehaviorFlags::SkipEmptyParts); + QList include_string_list = include_string.split(QRegularExpression("[\\,,;]"), Qt::SplitBehaviorFlags::SkipEmptyParts); #else // QT_VERSION - QList exclude_string_list = exclude_string.split(QRegExp("[\\,,;]"), QString::SplitBehavior::SkipEmptyParts); - QList include_string_list = include_string.split(QRegExp("[\\,,;]"), QString::SplitBehavior::SkipEmptyParts); + QList exclude_string_list = exclude_string.split(QRegularExpression("[\\,,;]"), QString::SplitBehavior::SkipEmptyParts); + QList include_string_list = include_string.split(QRegularExpression("[\\,,;]"), QString::SplitBehavior::SkipEmptyParts); #endif // QT_VERSION for (auto& s : exclude_string_list) { - topic_exclude_regexp_list_.push_back(QRegExp(s)); + topic_exclude_regexp_list_.push_back(QRegularExpression(s)); } for (auto& s : include_string_list) { - topic_include_regexp_list_.push_back(QRegExp(s)); + topic_include_regexp_list_.push_back(QRegularExpression(s)); } } @@ -240,7 +240,7 @@ void TopicWidget::autoSizeColumns() example_topic_pb.set_dfreq(999999); TopicTreeItem* example_topic_item = new TopicTreeItem(example_topic_pb); - GroupTreeItem* example_group_item = new GroupTreeItem("CameraSensorMapFusionCAF___", "", "", QVariant::Invalid, ""); + GroupTreeItem* example_group_item = new GroupTreeItem("CameraSensorMapFusionCAF___", "", "", QVariant(), ""); topic_tree_model_->insertItem(example_group_item); auto group_index = topic_tree_model_->index(example_group_item); @@ -378,7 +378,15 @@ void TopicWidget::resetLayout() settings.setValue("tree_state", QByteArray()); // Reset the settings, so new windows will open resetted settings.endGroup(); - int screen_number = QApplication::desktop()->screenNumber(this); + int screen_number = 0; + QScreen* current_screen = this->screen(); + if (current_screen) + { + screen_number = QApplication::screens().indexOf(current_screen); + if (screen_number < 0) + screen_number = 0; + } + for (auto reflection_window : visualisation_windows_.values()) { reflection_window->resetLayout(screen_number); diff --git a/app/mon/mon_gui/src/widgets/ecalmon_tree_widget/topic_widget.h b/app/mon/mon_gui/src/widgets/ecalmon_tree_widget/topic_widget.h index e83ae1a69d..3ab5a9e98f 100644 --- a/app/mon/mon_gui/src/widgets/ecalmon_tree_widget/topic_widget.h +++ b/app/mon/mon_gui/src/widgets/ecalmon_tree_widget/topic_widget.h @@ -51,8 +51,8 @@ public slots: TopicTreeModel* topic_tree_model_; TopicSortFilterProxyModel* topic_sort_filter_proxy_model_; - QList topic_exclude_regexp_list_; - QList topic_include_regexp_list_; + QList topic_exclude_regexp_list_; + QList topic_include_regexp_list_; QMap visualisation_windows_; diff --git a/app/mon/mon_gui/src/widgets/models/group_tree_item.cpp b/app/mon/mon_gui/src/widgets/models/group_tree_item.cpp index 9cd1de5228..1095a40824 100644 --- a/app/mon/mon_gui/src/widgets/models/group_tree_item.cpp +++ b/app/mon/mon_gui/src/widgets/models/group_tree_item.cpp @@ -58,10 +58,10 @@ QVariant GroupTreeItem::data(int column, Qt::ItemDataRole role) const case ItemDataRoles::GroupRole: return group_identifier_; default: - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } } - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } int GroupTreeItem::type() const diff --git a/app/mon/mon_gui/src/widgets/models/group_tree_model.cpp b/app/mon/mon_gui/src/widgets/models/group_tree_model.cpp index ce29f55c48..e4fda7ad65 100644 --- a/app/mon/mon_gui/src/widgets/models/group_tree_model.cpp +++ b/app/mon/mon_gui/src/widgets/models/group_tree_model.cpp @@ -17,15 +17,15 @@ * ========================= eCAL LICENSE ================================= */ -#ifdef _MSC_VER -// Disable Qt 5.15 Deprecation Warning about QVariant::operator<(), which is udsed by QMap -#pragma warning(push) -#pragma warning (disable : 4996) -#endif // _MSC_VER +//#ifdef _MSC_VER +//// Disable Qt 5.15 Deprecation Warning about QVariant::operator<(), which is udsed by QMap +//#pragma warning(push) +//#pragma warning (disable : 4996) +//#endif // _MSC_VER #include "group_tree_model.h" -#ifdef _MSC_VER -#pragma warning(pop) -#endif +//#ifdef _MSC_VER +//#pragma warning(pop) +//#endif #include "tree_item_type.h" #include "item_data_roles.h" @@ -42,6 +42,7 @@ #pragma warning(pop) #endif // _MSC_VER #endif // NDEBUG + GroupTreeModel::GroupTreeModel(const QVector& group_by_columns, QObject *parent) : QAbstractTreeModel(parent) , group_column_header_("Group") diff --git a/app/mon/mon_gui/src/widgets/models/host_tree_item.cpp b/app/mon/mon_gui/src/widgets/models/host_tree_item.cpp index 81296e4d24..15e084c5ef 100644 --- a/app/mon/mon_gui/src/widgets/models/host_tree_item.cpp +++ b/app/mon/mon_gui/src/widgets/models/host_tree_item.cpp @@ -141,16 +141,16 @@ QVariant HostTreeItem::data(Columns column, Qt::ItemDataRole role) const } else { - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } } else { - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } } - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } int HostTreeItem::type() const diff --git a/app/mon/mon_gui/src/widgets/models/log_model.cpp b/app/mon/mon_gui/src/widgets/models/log_model.cpp index edba25f660..f02c6a2162 100644 --- a/app/mon/mon_gui/src/widgets/models/log_model.cpp +++ b/app/mon/mon_gui/src/widgets/models/log_model.cpp @@ -149,7 +149,7 @@ QVariant LogModel::logLevelColor(int log_level) case eCAL_Logging_eLogLevel::log_level_fatal: return QColor(192, 0, 0); default: - return QVariant::Invalid; // Default color for "Debug x" + return QVariant(); // Invalid QVariant // Default color for "Debug x" } } diff --git a/app/mon/mon_gui/src/widgets/models/process_tree_item.cpp b/app/mon/mon_gui/src/widgets/models/process_tree_item.cpp index 7088052579..ec10163745 100644 --- a/app/mon/mon_gui/src/widgets/models/process_tree_item.cpp +++ b/app/mon/mon_gui/src/widgets/models/process_tree_item.cpp @@ -280,7 +280,7 @@ QVariant ProcessTreeItem::data(Columns column, Qt::ItemDataRole role) const case eCAL::pb::proc_sev_failed: return QColor(240, 20, 20); default: - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } } } @@ -301,7 +301,7 @@ QVariant ProcessTreeItem::data(Columns column, Qt::ItemDataRole role) const } else { - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } } @@ -326,7 +326,7 @@ QVariant ProcessTreeItem::data(Columns column, Qt::ItemDataRole role) const } } - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } int ProcessTreeItem::type() const diff --git a/app/mon/mon_gui/src/widgets/models/service_tree_item.cpp b/app/mon/mon_gui/src/widgets/models/service_tree_item.cpp index 923feb08f7..45bda0981e 100644 --- a/app/mon/mon_gui/src/widgets/models/service_tree_item.cpp +++ b/app/mon/mon_gui/src/widgets/models/service_tree_item.cpp @@ -194,16 +194,16 @@ QVariant ServiceTreeItem::data(Columns column, Qt::ItemDataRole role) const } else { - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } } else { - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } } - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } int ServiceTreeItem::type() const diff --git a/app/mon/mon_gui/src/widgets/models/topic_sort_filter_proxy_model.cpp b/app/mon/mon_gui/src/widgets/models/topic_sort_filter_proxy_model.cpp index 5f1a08f366..1e7e288db4 100644 --- a/app/mon/mon_gui/src/widgets/models/topic_sort_filter_proxy_model.cpp +++ b/app/mon/mon_gui/src/widgets/models/topic_sort_filter_proxy_model.cpp @@ -33,7 +33,7 @@ TopicSortFilterProxyModel::TopicSortFilterProxyModel(QObject* parent) TopicSortFilterProxyModel::~TopicSortFilterProxyModel() {} -void TopicSortFilterProxyModel::setRegExpLists(const QList& exclude_list, const QList& include_list) +void TopicSortFilterProxyModel::setRegExpLists(const QList& exclude_list, const QList& include_list) { exclude_regexp_list_ = exclude_list; include_regexp_list_ = include_list; @@ -57,9 +57,9 @@ bool TopicSortFilterProxyModel::filterDirectAcceptsRow(int source_row, const QMo } - for (const QRegExp& regexp : exclude_regexp_list_) + for (const QRegularExpression& regexp : exclude_regexp_list_) { - if (regexp.exactMatch(data)) + if (regexp.match(data).hasMatch()) // TODO: [2024-01-15] This was QRegExp::exactMatch() before, but QRegularExpression::exactMatch() does not exist. I don't know what this function is used for. { return false; } @@ -71,9 +71,9 @@ bool TopicSortFilterProxyModel::filterDirectAcceptsRow(int source_row, const QMo } else { - for (const QRegExp& regexp : include_regexp_list_) + for (const QRegularExpression& regexp : include_regexp_list_) { - if (regexp.exactMatch(data)) + if (regexp.match(data).hasMatch()) // TODO: [2024-01-15] This was QRegExp::exactMatch() before, but QRegularExpression::exactMatch() does not exist. I don't know what this function is used for. { return true; } diff --git a/app/mon/mon_gui/src/widgets/models/topic_sort_filter_proxy_model.h b/app/mon/mon_gui/src/widgets/models/topic_sort_filter_proxy_model.h index 6414fb27ba..02757d62e9 100644 --- a/app/mon/mon_gui/src/widgets/models/topic_sort_filter_proxy_model.h +++ b/app/mon/mon_gui/src/widgets/models/topic_sort_filter_proxy_model.h @@ -20,6 +20,8 @@ #pragma once #include +#include + class TopicSortFilterProxyModel : public QStableSortFilterProxyModel { @@ -28,11 +30,11 @@ class TopicSortFilterProxyModel : TopicSortFilterProxyModel(QObject* parent = 0); ~TopicSortFilterProxyModel(); - void setRegExpLists(const QList& exclude_list, const QList& include_list); + void setRegExpLists(const QList& exclude_list, const QList& include_list); private: - QList exclude_regexp_list_; - QList include_regexp_list_; + QList exclude_regexp_list_; + QList include_regexp_list_; bool filterDirectAcceptsRow(int source_row, const QModelIndex &source_parent) const override; }; diff --git a/app/mon/mon_gui/src/widgets/models/topic_tree_item.cpp b/app/mon/mon_gui/src/widgets/models/topic_tree_item.cpp index deab1a7cc4..46d215f160 100644 --- a/app/mon/mon_gui/src/widgets/models/topic_tree_item.cpp +++ b/app/mon/mon_gui/src/widgets/models/topic_tree_item.cpp @@ -384,10 +384,10 @@ QVariant TopicTreeItem::data(Columns column, Qt::ItemDataRole role) const } } - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } int TopicTreeItem::type() const diff --git a/app/mon/mon_gui/src/widgets/visualisation_widget/visualisation_window.cpp b/app/mon/mon_gui/src/widgets/visualisation_widget/visualisation_window.cpp index accc29e11e..8805580160 100644 --- a/app/mon/mon_gui/src/widgets/visualisation_widget/visualisation_window.cpp +++ b/app/mon/mon_gui/src/widgets/visualisation_widget/visualisation_window.cpp @@ -21,7 +21,6 @@ #include -#include #include #include diff --git a/app/mon/mon_plugin_lib/CMakeLists.txt b/app/mon/mon_plugin_lib/CMakeLists.txt index 7bda2283a8..bf817acdb3 100644 --- a/app/mon/mon_plugin_lib/CMakeLists.txt +++ b/app/mon/mon_plugin_lib/CMakeLists.txt @@ -16,12 +16,14 @@ # # ========================= eCAL LICENSE ================================= +cmake_minimum_required(VERSION 3.14) + project(mon_plugin_lib) -find_package(Qt5 COMPONENTS - Core - Widgets -REQUIRED) +# Legacy Qt5 (pre 5.15) support as suggested by teh Qt Documentation: +# https://doc.qt.io/qt-6/cmake-qt5-and-qt6-compatibility.html#supporting-older-qt-5-versions +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets) set(ecalmonpluginlib_src src/dummy.cpp @@ -43,8 +45,8 @@ target_include_directories(${PROJECT_NAME} PUBLIC target_link_libraries(${PROJECT_NAME} PUBLIC - Qt5::Core - Qt5::Widgets + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets ) target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_14) diff --git a/app/sys/sys_gui/CMakeLists.txt b/app/sys/sys_gui/CMakeLists.txt index 2ae2010290..85244107f6 100644 --- a/app/sys/sys_gui/CMakeLists.txt +++ b/app/sys/sys_gui/CMakeLists.txt @@ -20,7 +20,7 @@ cmake_minimum_required(VERSION 3.14) # Allow the install command to use generator expressions if(POLICY CMP0087) - cmake_policy(SET CMP0087 NEW) + cmake_policy(SET CMP0087 NEW) endif() set(PROJECT_NAME sys_gui) @@ -220,7 +220,7 @@ if ((WIN32 OR APPLE) AND (${QT_VERSION_MAJOR} GREATER_EQUAL 6)) # Add a postbuild script that will also execute the created script via cmake -P # This is necessary to make the application startable / debuggable from the build directory. add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD - COMMAND ${CMAKE_COMMAND} -DQT_DEPLOY_PREFIX=$ -DQT_DEPLOY_BIN_DIR=. -P ${qt_deploy_script} + COMMAND ${CMAKE_COMMAND} -DQT_DEPLOY_PREFIX=$ -DQT_DEPLOY_BIN_DIR=. -P ${qt_deploy_script} ) # Use the script for deploying the qt dlls in the install dir From b156bc159abf4b86a0f1c3ddb561cc41fb97dad1 Mon Sep 17 00:00:00 2001 From: Florian Reimold <11774314+FlorianReimold@users.noreply.github.com> Date: Tue, 16 Jan 2024 13:50:14 +0100 Subject: [PATCH 03/20] eCAL Mon builds and runs --- .../src/widgets/models/group_tree_model.cpp | 19 +++++++++++++++---- .../src/widgets/models/group_tree_model.h | 15 +++++++++++++-- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/app/mon/mon_gui/src/widgets/models/group_tree_model.cpp b/app/mon/mon_gui/src/widgets/models/group_tree_model.cpp index e4fda7ad65..f913cd4fc5 100644 --- a/app/mon/mon_gui/src/widgets/models/group_tree_model.cpp +++ b/app/mon/mon_gui/src/widgets/models/group_tree_model.cpp @@ -150,13 +150,13 @@ void GroupTreeModel::insertItemIntoGroups(QAbstractTreeItem* item) } GroupTreeItem* group_item; - - if (group_map_.contains(current_group_identifier)) + const auto current_group_it = group_map_.find(current_group_identifier); + if (current_group_it != group_map_.end()) { #ifndef NDEBUG qDebug().nospace() << "[" << metaObject()->className() << "]: Group " << current_group_name.toString() << " Exists already"; #endif // NDEBUG - group_item = group_map_.value(current_group_identifier); + group_item = current_group_it->second; } else { @@ -164,6 +164,7 @@ void GroupTreeModel::insertItemIntoGroups(QAbstractTreeItem* item) qDebug().nospace() << "[" << metaObject()->className() << "] Adding Group " << current_group_name.toString(); #endif // NDEBUG group_item = new GroupTreeItem(current_group_name, current_group_filter_role, current_group_sort_role, current_group_font_role, current_group_identifier); + group_map_[current_group_identifier] = group_item; insertItem(group_item); } @@ -225,7 +226,17 @@ void GroupTreeModel::removeItemFromGroups(QAbstractTreeItem* item, bool remove_e if (item_to_remove->parentItem() == root()) { - group_map_.remove(group_map_.key((GroupTreeItem*)item_to_remove)); + auto it = std::find_if(std::begin(group_map_), std::end(group_map_), + [item_to_remove](auto& p) { return p.second == (GroupTreeItem*)item_to_remove; }); + + if (it != std::end(group_map_)) + { + group_map_.erase(it); + } + else + { + qDebug() << "GroupTreeModel::removeItemFromGroups: Could not find group item in group map"; + } } removeItem(index(item_to_remove)); diff --git a/app/mon/mon_gui/src/widgets/models/group_tree_model.h b/app/mon/mon_gui/src/widgets/models/group_tree_model.h index 88bc1c74e3..558544c84d 100644 --- a/app/mon/mon_gui/src/widgets/models/group_tree_model.h +++ b/app/mon/mon_gui/src/widgets/models/group_tree_model.h @@ -32,7 +32,7 @@ #include "group_tree_item.h" -#include +#include #include #include @@ -64,7 +64,18 @@ class GroupTreeModel : public QAbstractTreeModel virtual int groupColumn() const = 0; private: - QMap group_map_; /*< group_identifier -> TreeItem mapping*/ + //std::list> group_map_; /*< group_identifier -> TreeItem mapping*/ + + struct cmp + { + bool operator()(const QVariant& lhs, const QVariant& rhs) const + { + return QVariant::compare(lhs, rhs) == QPartialOrdering::Less; + } + }; + std::map group_map_; + + QList items_list_; QVariant group_column_header_; From 605d76db03632a25791d9ef35209417b1c653390 Mon Sep 17 00:00:00 2001 From: Florian Reimold <11774314+FlorianReimold@users.noreply.github.com> Date: Tue, 16 Jan 2024 14:17:36 +0100 Subject: [PATCH 04/20] Fixed build issues with Qt 5.15 --- .../src/widgets/models/group_tree_model.h | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/app/mon/mon_gui/src/widgets/models/group_tree_model.h b/app/mon/mon_gui/src/widgets/models/group_tree_model.h index 558544c84d..f42f96b133 100644 --- a/app/mon/mon_gui/src/widgets/models/group_tree_model.h +++ b/app/mon/mon_gui/src/widgets/models/group_tree_model.h @@ -70,7 +70,28 @@ class GroupTreeModel : public QAbstractTreeModel { bool operator()(const QVariant& lhs, const QVariant& rhs) const { +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) return QVariant::compare(lhs, rhs) == QPartialOrdering::Less; +#else + + // deactivate warning about deprecated QVariant::compare + #ifdef _MSC_VER + #pragma warning(push) + #pragma warning (disable : 4996) + #elif __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" + #endif + + return lhs < rhs; + + #ifdef _MSC_VER + #pragma warning(pop) + #elif __GNUC__ + #pragma GCC diagnostic pop + #endif + +#endif } }; std::map group_map_; From f30a509328752e789ce97a4bf40a95c92d61c65a Mon Sep 17 00:00:00 2001 From: Florian Reimold <11774314+FlorianReimold@users.noreply.github.com> Date: Tue, 16 Jan 2024 14:52:05 +0100 Subject: [PATCH 05/20] Fixed compatibility with Qt 5.12 --- app/mon/mon_gui/src/ecalmon.cpp | 8 ++++++++ .../src/widgets/ecalmon_tree_widget/topic_widget.cpp | 8 ++++++++ app/sys/sys_gui/src/ecalsys_gui.cpp | 8 ++++++++ lib/CustomQt/src/QListMenuToolButton.cpp | 10 ++++++++++ 4 files changed, 34 insertions(+) diff --git a/app/mon/mon_gui/src/ecalmon.cpp b/app/mon/mon_gui/src/ecalmon.cpp index 07903377ce..e49e87cedd 100644 --- a/app/mon/mon_gui/src/ecalmon.cpp +++ b/app/mon/mon_gui/src/ecalmon.cpp @@ -42,6 +42,10 @@ #include #include +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) +#include +#endif // QT_VERSION < QT_VERSION_CHECK(5, 15, 0) + #ifndef NDEBUG #ifdef _MSC_VER #pragma warning(push) @@ -697,6 +701,9 @@ void Ecalmon::resetLayout() setTheme(Theme::Dark); // Back when we saved the initial window geometry, the window-manager might not have positioned the window on the screen, yet +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) + int screen_number = QApplication::desktop()->screenNumber(this); +#else int screen_number = 0; QScreen* current_screen = this->screen(); if (current_screen) @@ -705,6 +712,7 @@ void Ecalmon::resetLayout() if (screen_number < 0) screen_number = 0; } +#endif // QT_VERSION < QT_VERSION_CHECK(5, 15, 0) restoreGeometry(initial_geometry_); restoreState(initial_state_); diff --git a/app/mon/mon_gui/src/widgets/ecalmon_tree_widget/topic_widget.cpp b/app/mon/mon_gui/src/widgets/ecalmon_tree_widget/topic_widget.cpp index 4cc3e28847..22029711ee 100644 --- a/app/mon/mon_gui/src/widgets/ecalmon_tree_widget/topic_widget.cpp +++ b/app/mon/mon_gui/src/widgets/ecalmon_tree_widget/topic_widget.cpp @@ -35,6 +35,10 @@ #include #include +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) +#include +#endif // QT_VERSION < QT_VERSION_CHECK(5, 15, 0) + TopicWidget::TopicWidget(QWidget *parent) : EcalmonTreeWidget(parent) , parse_time_(true) @@ -378,6 +382,9 @@ void TopicWidget::resetLayout() settings.setValue("tree_state", QByteArray()); // Reset the settings, so new windows will open resetted settings.endGroup(); +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) + int screen_number = QApplication::desktop()->screenNumber(this); +#else int screen_number = 0; QScreen* current_screen = this->screen(); if (current_screen) @@ -386,6 +393,7 @@ void TopicWidget::resetLayout() if (screen_number < 0) screen_number = 0; } +#endif // QT_VERSION < QT_VERSION_CHECK(5, 15, 0) for (auto reflection_window : visualisation_windows_.values()) { diff --git a/app/sys/sys_gui/src/ecalsys_gui.cpp b/app/sys/sys_gui/src/ecalsys_gui.cpp index 800d6fcb41..09a6a5de4a 100644 --- a/app/sys/sys_gui/src/ecalsys_gui.cpp +++ b/app/sys/sys_gui/src/ecalsys_gui.cpp @@ -46,6 +46,10 @@ #include #include +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) +#include +#endif // QT_VERSION < QT_VERSION_CHECK(5, 15, 0) + #ifdef WIN32 #include #endif @@ -893,6 +897,9 @@ void EcalsysGui::menuViewResetLayoutTriggered() // Back when we saved the initial window geometry, the window-manager might not have positioned the window on the screen, yet +#if QT_VERSION <= QT_VERSION_CHECK(5, 15, 0) + int screen_number = QApplication::desktop()->screenNumber(this); +#else int screen_number = 0; QScreen* current_screen = this->screen(); if (current_screen) @@ -901,6 +908,7 @@ void EcalsysGui::menuViewResetLayoutTriggered() if (screen_number < 0) screen_number = 0; } +#endif // QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) restoreGeometry(initial_geometry_); restoreState(initial_state_); diff --git a/lib/CustomQt/src/QListMenuToolButton.cpp b/lib/CustomQt/src/QListMenuToolButton.cpp index e02c883ce3..b35ce7463e 100644 --- a/lib/CustomQt/src/QListMenuToolButton.cpp +++ b/lib/CustomQt/src/QListMenuToolButton.cpp @@ -25,6 +25,11 @@ #include #include +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) +#include +#endif // QT_VERSION < QT_VERSION_CHECK(5, 15, 0) + + QListMenuToolButton::QListMenuToolButton(QWidget* parent) : QToolButton(parent) , max_visible_items_(10) @@ -84,7 +89,12 @@ void QListMenuToolButton::showListMenu() } // Position on screen +#if QT_VERSION <= QT_VERSION_CHECK(5, 15, 0) + int screen_number = QApplication::desktop()->screenNumber(this); + QRect screen_geometry = QApplication::desktop()->screenGeometry(screen_number); +#else QRect screen_geometry = this->screen()->geometry(); +#endif // QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) QRect global_button_geometry = QRect(mapToGlobal(QPoint(0, 0)), size()); QRect popup_geometry = QRect(global_button_geometry.bottomLeft(), QSize(target_width, target_height)); From e28e7521bcb9938667e365b604f8cba775ebe058 Mon Sep 17 00:00:00 2001 From: Florian Reimold <11774314+FlorianReimold@users.noreply.github.com> Date: Tue, 16 Jan 2024 15:07:12 +0100 Subject: [PATCH 06/20] Fixed Release build issue --- app/mon/mon_gui/src/widgets/models/group_tree_model.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/mon/mon_gui/src/widgets/models/group_tree_model.cpp b/app/mon/mon_gui/src/widgets/models/group_tree_model.cpp index f913cd4fc5..0c2bfaca28 100644 --- a/app/mon/mon_gui/src/widgets/models/group_tree_model.cpp +++ b/app/mon/mon_gui/src/widgets/models/group_tree_model.cpp @@ -235,7 +235,9 @@ void GroupTreeModel::removeItemFromGroups(QAbstractTreeItem* item, bool remove_e } else { - qDebug() << "GroupTreeModel::removeItemFromGroups: Could not find group item in group map"; +#ifndef NDEBUG + qDebug().nospace() << "[" << metaObject()->className() << "] removeItemFromGroups: Could not find group item in group map"; +#endif // !NDEBUG } } From 9c59f9b5490bf7c84a85cd8ea6aef521f155c52f Mon Sep 17 00:00:00 2001 From: Florian Reimold <11774314+FlorianReimold@users.noreply.github.com> Date: Wed, 17 Jan 2024 09:40:01 +0100 Subject: [PATCH 07/20] eCAL Mon and all Plugins now compile and run with Qt6 --- CMakeLists.txt | 10 +- app/mon/mon_gui/src/util.h | 4 + .../mon_gui/src/widgets/models/log_model.cpp | 4 + .../capnproto_reflection/CMakeLists.txt | 25 +- .../monitor_tree_view/CMakeLists.txt | 12 +- .../src/monitor_tree_item.cpp | 6 +- .../plugin_template/CMakeLists.txt | 15 +- .../protobuf_reflection/CMakeLists.txt | 26 +- .../raw_data_reflection/CMakeLists.txt | 23 +- .../raw_data_reflection/src/plugin_widget.cpp | 2 +- .../signals_plotting/CMakeLists.txt | 27 +- .../signals_plotting/src/signal_tree_item.cpp | 2 +- .../mon_plugins/signals_plotting/src/util.h | 4 + .../string_reflection/CMakeLists.txt | 22 +- thirdparty/qwt/CMakeLists.txt | 379 +++++++++++++++--- thirdparty/qwt/qwt | 2 +- 16 files changed, 469 insertions(+), 94 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ed73ae9d4..af3bff9959 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,12 +113,12 @@ if(WIN32) option(ECAL_THIRDPARTY_BUILD_YAML-CPP "Build yaml-cpp with eCAL" ON) option(ECAL_THIRDPARTY_BUILD_CURL "Build CURL with eCAL" ON) option(ECAL_THIRDPARTY_BUILD_HDF5 "Build HDF5 with eCAL" ON) - cmake_dependent_option(ECAL_THIRDPARTY_BUILD_QWT "Build qwt::qwt with eCAL" ON "HAS_QT5" OFF) + cmake_dependent_option(ECAL_THIRDPARTY_BUILD_QWT "Build qwt::qwt with eCAL" ON "HAS_QT5 OR HAS_QT6" OFF) else() option(ECAL_THIRDPARTY_BUILD_PROTOBUF "Build protobuf with eCAL" OFF) option(ECAL_THIRDPARTY_BUILD_CURL "Build CURL with eCAL" OFF) option(ECAL_THIRDPARTY_BUILD_HDF5 "Build HDF5 with eCAL" OFF) - cmake_dependent_option(ECAL_THIRDPARTY_BUILD_QWT "Build qwt::qwt with eCAL" OFF "HAS_QT5" OFF) + cmake_dependent_option(ECAL_THIRDPARTY_BUILD_QWT "Build qwt::qwt with eCAL" OFF "HAS_QT5 OR HAS_QT6" OFF) option(ECAL_THIRDPARTY_BUILD_YAML-CPP "Build yaml-cpp with eCAL" OFF) endif() @@ -426,15 +426,15 @@ endif() if(BUILD_APPS AND (HAS_QT5 OR HAS_QT6)) add_subdirectory(app/sys/sys_gui) add_subdirectory(app/mon/mon_gui) -endif() - -if(BUILD_APPS AND HAS_QT5) if(WIN32) set(ECAL_MON_PLUGIN_DIR ecalmon_plugins) else() set(ECAL_MON_PLUGIN_DIR ecal/plugins/mon) endif() add_subdirectory(app/mon/mon_plugins) +endif() + +if(BUILD_APPS AND HAS_QT5) add_subdirectory(app/util/launcher) # -------------------------------------------------------- # qt applications using hdf5 diff --git a/app/mon/mon_gui/src/util.h b/app/mon/mon_gui/src/util.h index ce4f3467fb..08c10b2187 100644 --- a/app/mon/mon_gui/src/util.h +++ b/app/mon/mon_gui/src/util.h @@ -28,7 +28,11 @@ namespace QtUtil { inline QString variantToString(const QVariant& variant) { +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + switch (variant.typeId()) +#else switch ((QMetaType::Type)variant.type()) +#endif { case QMetaType::Bool: return variant.toBool() ? "True" : "False"; diff --git a/app/mon/mon_gui/src/widgets/models/log_model.cpp b/app/mon/mon_gui/src/widgets/models/log_model.cpp index f02c6a2162..a574998749 100644 --- a/app/mon/mon_gui/src/widgets/models/log_model.cpp +++ b/app/mon/mon_gui/src/widgets/models/log_model.cpp @@ -294,7 +294,11 @@ bool LogModel::dumpToCsv(const QString& path) { QVariant current_data = data(index(row, col), Qt::ItemDataRole::DisplayRole); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + switch (current_data.typeId()) +#else switch ((QMetaType::Type)current_data.type()) +#endif { case QMetaType::QString: stream << "\"" << current_data.toString().replace("\"", "\"\"") << "\""; diff --git a/app/mon/mon_plugins/capnproto_reflection/CMakeLists.txt b/app/mon/mon_plugins/capnproto_reflection/CMakeLists.txt index 00a4e17145..f948a3ac5b 100644 --- a/app/mon/mon_plugins/capnproto_reflection/CMakeLists.txt +++ b/app/mon/mon_plugins/capnproto_reflection/CMakeLists.txt @@ -18,10 +18,10 @@ project(mon_plugin_capnproto_reflection VERSION 0.1.0) -find_package(Qt5 COMPONENTS - Core - Widgets -REQUIRED) +# Legacy Qt5 (pre 5.15) support as suggested by teh Qt Documentation: +# https://doc.qt.io/qt-6/cmake-qt5-and-qt6-compatibility.html#supporting-older-qt-5-versions +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets) find_package(CapnProto REQUIRED) @@ -46,14 +46,27 @@ set(${PROJECT_NAME}_ui src/plugin_widget.ui ) -qt5_wrap_ui(autogen_ui ${${PROJECT_NAME}_ui}) +# compile qt resource files and ui files +if (${QT_VERSION_MAJOR} GREATER_EQUAL 6) + qt_wrap_ui(autogen_ui ${${PROJECT_NAME}_ui}) +else() + qt5_wrap_ui(autogen_ui ${${PROJECT_NAME}_ui}) +endif() ecal_add_mon_plugin(${PROJECT_NAME} SOURCES ${${PROJECT_NAME}_src} ${${PROJECT_NAME}_header} ${${PROJECT_NAME}_ui} ${autogen_ui} METADATA src/metadata.json ) -target_link_libraries (${PROJECT_NAME} Qt5::Widgets eCAL::core CapnProto::capnp CustomQt eCAL::mon_plugin_lib MonitorTreeView) +target_link_libraries (${PROJECT_NAME} + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets + eCAL::core + CapnProto::capnp + CustomQt + eCAL::mon_plugin_lib + MonitorTreeView +) target_link_options(${PROJECT_NAME} PRIVATE $<$:/ignore:4099>) target_include_directories(${PROJECT_NAME} PRIVATE src) diff --git a/app/mon/mon_plugins/monitor_tree_view/CMakeLists.txt b/app/mon/mon_plugins/monitor_tree_view/CMakeLists.txt index 6e9b5b5fe3..bd2f1c99a2 100644 --- a/app/mon/mon_plugins/monitor_tree_view/CMakeLists.txt +++ b/app/mon/mon_plugins/monitor_tree_view/CMakeLists.txt @@ -18,10 +18,10 @@ project(MonitorTreeView) -find_package(Qt5 - COMPONENTS Core Widgets - REQUIRED -) +# Legacy Qt5 (pre 5.15) support as suggested by teh Qt Documentation: +# https://doc.qt.io/qt-6/cmake-qt5-and-qt6-compatibility.html#supporting-older-qt-5-versions +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets) set(source_files src/item_data_roles.h @@ -41,7 +41,9 @@ add_library(eCAL::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) target_include_directories(${PROJECT_NAME} PUBLIC src) target_link_libraries(${PROJECT_NAME} - Qt5::Widgets CustomQt + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets + CustomQt ) target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_14) diff --git a/app/mon/mon_plugins/monitor_tree_view/src/monitor_tree_item.cpp b/app/mon/mon_plugins/monitor_tree_view/src/monitor_tree_item.cpp index 185b321dfb..e8a4f3e1b2 100644 --- a/app/mon/mon_plugins/monitor_tree_view/src/monitor_tree_item.cpp +++ b/app/mon/mon_plugins/monitor_tree_view/src/monitor_tree_item.cpp @@ -97,7 +97,11 @@ QByteArray asByteArrayBlob(const QByteArray& bytes) // Return crc16 checksum of the byte Array QString asChecksum(const QByteArray& bytes) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + quint16 crc16 = qChecksum(QByteArrayView(bytes)); +#else quint16 crc16 = qChecksum(bytes.data(), (uint)bytes.length()); +#endif return QString("%1 bytes (CRC16: %2)").arg(QString::number(bytes.length())).arg(QString::number(crc16, 16).toUpper(), 4, '0'); } @@ -159,7 +163,7 @@ QVariant MonitorTreeItem::data(Columns column, Qt::ItemDataRole role) const return data(column, Qt::ItemDataRole::DisplayRole); } - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } int MonitorTreeItem::type() const diff --git a/app/mon/mon_plugins/plugin_template/CMakeLists.txt b/app/mon/mon_plugins/plugin_template/CMakeLists.txt index ff285ce6f0..dd22d88b7e 100644 --- a/app/mon/mon_plugins/plugin_template/CMakeLists.txt +++ b/app/mon/mon_plugins/plugin_template/CMakeLists.txt @@ -18,10 +18,10 @@ project(mon_plugin_template VERSION 0.1.0) -find_package(Qt5 COMPONENTS - Core - Widgets -REQUIRED) +# Legacy Qt5 (pre 5.15) support as suggested by teh Qt Documentation: +# https://doc.qt.io/qt-6/cmake-qt5-and-qt6-compatibility.html#supporting-older-qt-5-versions +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC OFF) # Reason for being turned off: AutoUIC will prevent VS from detecting changes in .ui files @@ -43,7 +43,12 @@ ecal_add_mon_plugin(${PROJECT_NAME} METADATA src/metadata.json ) -target_link_libraries (${PROJECT_NAME} Qt5::Widgets eCAL::core eCAL::mon_plugin_lib) +target_link_libraries (${PROJECT_NAME} + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets + eCAL::core + eCAL::mon_plugin_lib +) target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_14) if(MSVC) diff --git a/app/mon/mon_plugins/protobuf_reflection/CMakeLists.txt b/app/mon/mon_plugins/protobuf_reflection/CMakeLists.txt index 43eb7aab09..bdc373ce39 100644 --- a/app/mon/mon_plugins/protobuf_reflection/CMakeLists.txt +++ b/app/mon/mon_plugins/protobuf_reflection/CMakeLists.txt @@ -18,10 +18,11 @@ project(mon_plugin_protobuf_reflection VERSION 0.1.0) -find_package(Qt5 COMPONENTS - Core - Widgets -REQUIRED) + +# Legacy Qt5 (pre 5.15) support as suggested by teh Qt Documentation: +# https://doc.qt.io/qt-6/cmake-qt5-and-qt6-compatibility.html#supporting-older-qt-5-versions +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets) find_package(Protobuf REQUIRED) @@ -46,7 +47,12 @@ set(${PROJECT_NAME}_ui src/plugin_widget.ui ) -qt5_wrap_ui(autogen_ui ${${PROJECT_NAME}_ui}) +# compile qt resource files and ui files +if (${QT_VERSION_MAJOR} GREATER_EQUAL 6) + qt_wrap_ui(autogen_ui ${${PROJECT_NAME}_ui}) +else() + qt5_wrap_ui(autogen_ui ${${PROJECT_NAME}_ui}) +endif() ecal_add_mon_plugin(${PROJECT_NAME} SOURCES ${${PROJECT_NAME}_src} ${${PROJECT_NAME}_header} ${${PROJECT_NAME}_ui} ${autogen_ui} @@ -54,7 +60,15 @@ ecal_add_mon_plugin(${PROJECT_NAME} ) create_targets_protobuf() -target_link_libraries (${PROJECT_NAME} Qt5::Widgets eCAL::core eCAL::app_pb protobuf::libprotobuf MonitorTreeView eCAL::mon_plugin_lib) +target_link_libraries (${PROJECT_NAME} + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets + eCAL::core + eCAL::app_pb + protobuf::libprotobuf + MonitorTreeView + eCAL::mon_plugin_lib +) target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_14) if(MSVC) diff --git a/app/mon/mon_plugins/raw_data_reflection/CMakeLists.txt b/app/mon/mon_plugins/raw_data_reflection/CMakeLists.txt index 3819643e95..20c0deca9a 100644 --- a/app/mon/mon_plugins/raw_data_reflection/CMakeLists.txt +++ b/app/mon/mon_plugins/raw_data_reflection/CMakeLists.txt @@ -18,10 +18,10 @@ project(mon_plugin_raw_data_reflection VERSION 0.1.0) -find_package(Qt5 COMPONENTS - Core - Widgets -REQUIRED) +# Legacy Qt5 (pre 5.15) support as suggested by teh Qt Documentation: +# https://doc.qt.io/qt-6/cmake-qt5-and-qt6-compatibility.html#supporting-older-qt-5-versions +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC OFF) # Reason for being turned off: AutoUIC will prevent VS from detecting changes in .ui files @@ -42,7 +42,12 @@ set(${PROJECT_NAME}_ui src/plugin_widget.ui ) -qt5_wrap_ui(autogen_ui ${${PROJECT_NAME}_ui}) +# compile qt resource files and ui files +if (${QT_VERSION_MAJOR} GREATER_EQUAL 6) + qt_wrap_ui(autogen_ui ${${PROJECT_NAME}_ui}) +else() + qt5_wrap_ui(autogen_ui ${${PROJECT_NAME}_ui}) +endif() ecal_add_mon_plugin(${PROJECT_NAME} SOURCES ${${PROJECT_NAME}_src} ${${PROJECT_NAME}_header} ${${PROJECT_NAME}_ui} ${autogen_ui} @@ -50,7 +55,13 @@ ecal_add_mon_plugin(${PROJECT_NAME} ) create_targets_protobuf() -target_link_libraries (${PROJECT_NAME} Qt5::Widgets eCAL::core eCAL::mon_plugin_lib) +target_link_libraries (${PROJECT_NAME} + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets + eCAL::core + eCAL::mon_plugin_lib +) + target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_14) if(MSVC) diff --git a/app/mon/mon_plugins/raw_data_reflection/src/plugin_widget.cpp b/app/mon/mon_plugins/raw_data_reflection/src/plugin_widget.cpp index 9249a7c8de..b3f5bc851b 100644 --- a/app/mon/mon_plugins/raw_data_reflection/src/plugin_widget.cpp +++ b/app/mon/mon_plugins/raw_data_reflection/src/plugin_widget.cpp @@ -146,7 +146,7 @@ void PluginWidget::updateRawMessageView() size_label_->setText(size_text); - QByteArray last_message_trimmed(last_message_.data(), std::min(last_message_.length(), 1024)); + QByteArray last_message_trimmed(last_message_.data(), std::min(static_cast(last_message_.length()), std::size_t(1024))); blob_text_edit_->setPlainText( #if QT_VERSION < QT_VERSION_CHECK(5, 9, 0) bytesToHex(last_message_trimmed, ' ') diff --git a/app/mon/mon_plugins/signals_plotting/CMakeLists.txt b/app/mon/mon_plugins/signals_plotting/CMakeLists.txt index 8ded07d509..69daf94a71 100644 --- a/app/mon/mon_plugins/signals_plotting/CMakeLists.txt +++ b/app/mon/mon_plugins/signals_plotting/CMakeLists.txt @@ -18,10 +18,10 @@ project(mon_plugin_signals_plotting VERSION 1.0.0) -find_package(Qt5 COMPONENTS - Core - Widgets -REQUIRED) +# Legacy Qt5 (pre 5.15) support as suggested by teh Qt Documentation: +# https://doc.qt.io/qt-6/cmake-qt5-and-qt6-compatibility.html#supporting-older-qt-5-versions +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets) find_package(Protobuf REQUIRED) find_package(qwt REQUIRED) @@ -58,7 +58,12 @@ set(${PROJECT_NAME}_ui src/chart_settings.ui ) -qt5_wrap_ui(autogen_ui ${${PROJECT_NAME}_ui}) +# compile qt resource files and ui files +if (${QT_VERSION_MAJOR} GREATER_EQUAL 6) + qt_wrap_ui(autogen_ui ${${PROJECT_NAME}_ui}) +else() + qt5_wrap_ui(autogen_ui ${${PROJECT_NAME}_ui}) +endif() ecal_add_mon_plugin(${PROJECT_NAME} SOURCES ${${PROJECT_NAME}_src} ${${PROJECT_NAME}_header} ${${PROJECT_NAME}_ui} ${autogen_ui} @@ -67,7 +72,17 @@ ecal_add_mon_plugin(${PROJECT_NAME} create_targets_protobuf() -target_link_libraries (${PROJECT_NAME} Qt5::Widgets Qt5::Core eCAL::core eCAL::app_pb protobuf::libprotobuf eCAL::mon_plugin_lib qwt::qwt CustomQt) +target_link_libraries (${PROJECT_NAME} + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets + eCAL::core + eCAL::app_pb + protobuf::libprotobuf + eCAL::mon_plugin_lib + qwt::qwt + CustomQt +) + target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_14) if(MSVC) diff --git a/app/mon/mon_plugins/signals_plotting/src/signal_tree_item.cpp b/app/mon/mon_plugins/signals_plotting/src/signal_tree_item.cpp index 1c26ffad6f..a55b05ab47 100644 --- a/app/mon/mon_plugins/signals_plotting/src/signal_tree_item.cpp +++ b/app/mon/mon_plugins/signals_plotting/src/signal_tree_item.cpp @@ -147,7 +147,7 @@ QVariant SignalTreeItem::data(Columns column, Qt::ItemDataRole role) const return background_color_.toQColor(); } } - return QVariant::Invalid; + return QVariant(); } Qt::ItemFlags SignalTreeItem::flags(int column) const diff --git a/app/mon/mon_plugins/signals_plotting/src/util.h b/app/mon/mon_plugins/signals_plotting/src/util.h index 24dbab3f4f..f9081f8965 100644 --- a/app/mon/mon_plugins/signals_plotting/src/util.h +++ b/app/mon/mon_plugins/signals_plotting/src/util.h @@ -32,7 +32,11 @@ namespace QtUtil { inline QString variantToString(const QVariant& variant) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + switch (variant.typeId()) +#else switch ((QMetaType::Type)variant.type()) +#endif { case QMetaType::Bool: return variant.toBool() ? "True" : "False"; diff --git a/app/mon/mon_plugins/string_reflection/CMakeLists.txt b/app/mon/mon_plugins/string_reflection/CMakeLists.txt index 4e4c3f5a82..836200ec19 100644 --- a/app/mon/mon_plugins/string_reflection/CMakeLists.txt +++ b/app/mon/mon_plugins/string_reflection/CMakeLists.txt @@ -18,10 +18,10 @@ project(mon_plugin_string_reflection VERSION 0.1.0) -find_package(Qt5 COMPONENTS - Core - Widgets -REQUIRED) +# Legacy Qt5 (pre 5.15) support as suggested by teh Qt Documentation: +# https://doc.qt.io/qt-6/cmake-qt5-and-qt6-compatibility.html#supporting-older-qt-5-versions +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC OFF) # Reason for being turned off: AutoUIC will prevent VS from detecting changes in .ui files @@ -42,7 +42,12 @@ set(${PROJECT_NAME}_ui src/plugin_widget.ui ) -qt5_wrap_ui(autogen_ui ${${PROJECT_NAME}_ui}) +# compile qt resource files and ui files +if (${QT_VERSION_MAJOR} GREATER_EQUAL 6) + qt_wrap_ui(autogen_ui ${${PROJECT_NAME}_ui}) +else() + qt5_wrap_ui(autogen_ui ${${PROJECT_NAME}_ui}) +endif() ecal_add_mon_plugin(${PROJECT_NAME} SOURCES ${${PROJECT_NAME}_src} ${${PROJECT_NAME}_header} ${${PROJECT_NAME}_ui} ${autogen_ui} @@ -50,7 +55,12 @@ ecal_add_mon_plugin(${PROJECT_NAME} ) create_targets_protobuf() -target_link_libraries (${PROJECT_NAME} Qt5::Widgets eCAL::core eCAL::mon_plugin_lib) +target_link_libraries (${PROJECT_NAME} + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets + eCAL::core + eCAL::mon_plugin_lib +) target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_14) if(MSVC) diff --git a/thirdparty/qwt/CMakeLists.txt b/thirdparty/qwt/CMakeLists.txt index 3c5c940496..822a768494 100644 --- a/thirdparty/qwt/CMakeLists.txt +++ b/thirdparty/qwt/CMakeLists.txt @@ -1,34 +1,294 @@ cmake_minimum_required(VERSION 3.13) project(qwt VERSION 6.2.0) -find_package(Qt5 REQUIRED COMPONENTS Widgets OpenGL Svg Concurrent PrintSupport) +# Legacy Qt5 (pre 5.15) support as suggested by teh Qt Documentation: +# https://doc.qt.io/qt-6/cmake-qt5-and-qt6-compatibility.html#supporting-older-qt-5-versions +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets OpenGL Svg Concurrent PrintSupport) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets OpenGL Svg Concurrent PrintSupport) + +# For Qt6, we need the OpenGLWidgets +if (${QT_VERSION_MAJOR} GREATER_EQUAL 6) + find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS OpenGLWidgets ) +endif() + set(CMAKE_AUTOMOC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) -file(GLOB_RECURSE qwt_headers - LIST_DIRECTORIES false - CONFIGURE_DEPENDS - ${CMAKE_CURRENT_SOURCE_DIR}/qwt/src/*.h +set(qwt_headers + qwt/src/qwt.h + qwt/src/qwt_abstract_legend.h + qwt/src/qwt_abstract_scale.h + qwt/src/qwt_abstract_scale_draw.h + qwt/src/qwt_abstract_slider.h + qwt/src/qwt_analog_clock.h + qwt/src/qwt_arrow_button.h + qwt/src/qwt_axis.h + qwt/src/qwt_axis_id.h + qwt/src/qwt_bezier.h + qwt/src/qwt_clipper.h + qwt/src/qwt_color_map.h + qwt/src/qwt_column_symbol.h + qwt/src/qwt_compass.h + qwt/src/qwt_compass_rose.h + qwt/src/qwt_counter.h + qwt/src/qwt_curve_fitter.h + qwt/src/qwt_date.h + qwt/src/qwt_date_scale_draw.h + qwt/src/qwt_date_scale_engine.h + qwt/src/qwt_dial.h + qwt/src/qwt_dial_needle.h + qwt/src/qwt_dyngrid_layout.h + qwt/src/qwt_event_pattern.h + qwt/src/qwt_global.h + qwt/src/qwt_graphic.h + qwt/src/qwt_interval.h + qwt/src/qwt_interval_symbol.h + qwt/src/qwt_knob.h + qwt/src/qwt_legend.h + qwt/src/qwt_legend_data.h + qwt/src/qwt_legend_label.h + qwt/src/qwt_magnifier.h + qwt/src/qwt_math.h + qwt/src/qwt_matrix_raster_data.h + qwt/src/qwt_null_paintdevice.h + qwt/src/qwt_painter.h + qwt/src/qwt_painter_command.h + qwt/src/qwt_panner.h + qwt/src/qwt_picker.h + qwt/src/qwt_picker_machine.h + qwt/src/qwt_pixel_matrix.h + qwt/src/qwt_plot.h + qwt/src/qwt_plot_abstract_barchart.h + qwt/src/qwt_plot_abstract_canvas.h + qwt/src/qwt_plot_barchart.h + qwt/src/qwt_plot_canvas.h + qwt/src/qwt_plot_curve.h + qwt/src/qwt_plot_dict.h + qwt/src/qwt_plot_directpainter.h + # qwt/src/qwt_plot_glcanvas.h # Not compatible with Qt6 + qwt/src/qwt_plot_graphicitem.h + qwt/src/qwt_plot_grid.h + qwt/src/qwt_plot_histogram.h + qwt/src/qwt_plot_intervalcurve.h + qwt/src/qwt_plot_item.h + qwt/src/qwt_plot_layout.h + qwt/src/qwt_plot_legenditem.h + qwt/src/qwt_plot_magnifier.h + qwt/src/qwt_plot_marker.h + qwt/src/qwt_plot_multi_barchart.h + qwt/src/qwt_plot_opengl_canvas.h + qwt/src/qwt_plot_panner.h + qwt/src/qwt_plot_picker.h + qwt/src/qwt_plot_rasteritem.h + qwt/src/qwt_plot_renderer.h + qwt/src/qwt_plot_rescaler.h + qwt/src/qwt_plot_scaleitem.h + qwt/src/qwt_plot_seriesitem.h + qwt/src/qwt_plot_shapeitem.h + qwt/src/qwt_plot_spectrocurve.h + qwt/src/qwt_plot_spectrogram.h + qwt/src/qwt_plot_svgitem.h + qwt/src/qwt_plot_textlabel.h + qwt/src/qwt_plot_tradingcurve.h + qwt/src/qwt_plot_vectorfield.h + qwt/src/qwt_plot_zoneitem.h + qwt/src/qwt_plot_zoomer.h + qwt/src/qwt_point_3d.h + qwt/src/qwt_point_data.h + qwt/src/qwt_point_mapper.h + qwt/src/qwt_point_polar.h + qwt/src/qwt_polar.h + qwt/src/qwt_polar_canvas.h + qwt/src/qwt_polar_curve.h + qwt/src/qwt_polar_fitter.h + qwt/src/qwt_polar_grid.h + qwt/src/qwt_polar_item.h + qwt/src/qwt_polar_itemdict.h + qwt/src/qwt_polar_layout.h + qwt/src/qwt_polar_magnifier.h + qwt/src/qwt_polar_marker.h + qwt/src/qwt_polar_panner.h + qwt/src/qwt_polar_picker.h + qwt/src/qwt_polar_plot.h + qwt/src/qwt_polar_renderer.h + qwt/src/qwt_polar_spectrogram.h + qwt/src/qwt_raster_data.h + qwt/src/qwt_round_scale_draw.h + qwt/src/qwt_samples.h + qwt/src/qwt_sampling_thread.h + qwt/src/qwt_scale_div.h + qwt/src/qwt_scale_draw.h + qwt/src/qwt_scale_engine.h + qwt/src/qwt_scale_map.h + qwt/src/qwt_scale_widget.h + qwt/src/qwt_series_data.h + qwt/src/qwt_series_store.h + qwt/src/qwt_slider.h + qwt/src/qwt_spline.h + qwt/src/qwt_spline_basis.h + qwt/src/qwt_spline_cubic.h + qwt/src/qwt_spline_curve_fitter.h + qwt/src/qwt_spline_local.h + qwt/src/qwt_spline_parametrization.h + qwt/src/qwt_spline_pleasing.h + qwt/src/qwt_spline_polynomial.h + qwt/src/qwt_symbol.h + qwt/src/qwt_system_clock.h + qwt/src/qwt_text.h + qwt/src/qwt_text_engine.h + qwt/src/qwt_text_label.h + qwt/src/qwt_thermo.h + qwt/src/qwt_transform.h + qwt/src/qwt_vectorfield_symbol.h + qwt/src/qwt_weeding_curve_fitter.h + qwt/src/qwt_wheel.h + qwt/src/qwt_widget_overlay.h ) -file(GLOB_RECURSE qwt_sources - LIST_DIRECTORIES false - CONFIGURE_DEPENDS - ${CMAKE_CURRENT_SOURCE_DIR}/qwt/src/*.cpp +set(qwt_sources + qwt/src/qwt.cpp + qwt/src/qwt_abstract_legend.cpp + qwt/src/qwt_abstract_scale.cpp + qwt/src/qwt_abstract_scale_draw.cpp + qwt/src/qwt_abstract_slider.cpp + qwt/src/qwt_analog_clock.cpp + qwt/src/qwt_arrow_button.cpp + qwt/src/qwt_bezier.cpp + qwt/src/qwt_clipper.cpp + qwt/src/qwt_color_map.cpp + qwt/src/qwt_column_symbol.cpp + qwt/src/qwt_compass.cpp + qwt/src/qwt_compass_rose.cpp + qwt/src/qwt_counter.cpp + qwt/src/qwt_curve_fitter.cpp + qwt/src/qwt_date.cpp + qwt/src/qwt_date_scale_draw.cpp + qwt/src/qwt_date_scale_engine.cpp + qwt/src/qwt_dial.cpp + qwt/src/qwt_dial_needle.cpp + qwt/src/qwt_dyngrid_layout.cpp + qwt/src/qwt_event_pattern.cpp + qwt/src/qwt_graphic.cpp + qwt/src/qwt_interval.cpp + qwt/src/qwt_interval_symbol.cpp + qwt/src/qwt_knob.cpp + qwt/src/qwt_legend.cpp + qwt/src/qwt_legend_data.cpp + qwt/src/qwt_legend_label.cpp + qwt/src/qwt_magnifier.cpp + qwt/src/qwt_math.cpp + qwt/src/qwt_matrix_raster_data.cpp + qwt/src/qwt_null_paintdevice.cpp + qwt/src/qwt_painter.cpp + qwt/src/qwt_painter_command.cpp + qwt/src/qwt_panner.cpp + qwt/src/qwt_picker.cpp + qwt/src/qwt_picker_machine.cpp + qwt/src/qwt_pixel_matrix.cpp + qwt/src/qwt_plot.cpp + qwt/src/qwt_plot_abstract_barchart.cpp + qwt/src/qwt_plot_abstract_canvas.cpp + qwt/src/qwt_plot_axis.cpp + qwt/src/qwt_plot_barchart.cpp + qwt/src/qwt_plot_canvas.cpp + qwt/src/qwt_plot_curve.cpp + qwt/src/qwt_plot_dict.cpp + qwt/src/qwt_plot_directpainter.cpp + # qwt/src/qwt_plot_glcanvas.cpp # Not compatible with Qt6 + qwt/src/qwt_plot_graphicitem.cpp + qwt/src/qwt_plot_grid.cpp + qwt/src/qwt_plot_histogram.cpp + qwt/src/qwt_plot_intervalcurve.cpp + qwt/src/qwt_plot_item.cpp + qwt/src/qwt_plot_layout.cpp + qwt/src/qwt_plot_legenditem.cpp + qwt/src/qwt_plot_magnifier.cpp + qwt/src/qwt_plot_marker.cpp + qwt/src/qwt_plot_multi_barchart.cpp + qwt/src/qwt_plot_opengl_canvas.cpp + qwt/src/qwt_plot_panner.cpp + qwt/src/qwt_plot_picker.cpp + qwt/src/qwt_plot_rasteritem.cpp + qwt/src/qwt_plot_renderer.cpp + qwt/src/qwt_plot_rescaler.cpp + qwt/src/qwt_plot_scaleitem.cpp + qwt/src/qwt_plot_seriesitem.cpp + qwt/src/qwt_plot_shapeitem.cpp + qwt/src/qwt_plot_spectrocurve.cpp + qwt/src/qwt_plot_spectrogram.cpp + qwt/src/qwt_plot_svgitem.cpp + qwt/src/qwt_plot_textlabel.cpp + qwt/src/qwt_plot_tradingcurve.cpp + qwt/src/qwt_plot_vectorfield.cpp + qwt/src/qwt_plot_zoneitem.cpp + qwt/src/qwt_plot_zoomer.cpp + qwt/src/qwt_point_3d.cpp + qwt/src/qwt_point_data.cpp + qwt/src/qwt_point_mapper.cpp + qwt/src/qwt_point_polar.cpp + qwt/src/qwt_polar_canvas.cpp + qwt/src/qwt_polar_curve.cpp + qwt/src/qwt_polar_fitter.cpp + qwt/src/qwt_polar_grid.cpp + qwt/src/qwt_polar_item.cpp + qwt/src/qwt_polar_itemdict.cpp + qwt/src/qwt_polar_layout.cpp + qwt/src/qwt_polar_magnifier.cpp + qwt/src/qwt_polar_marker.cpp + qwt/src/qwt_polar_panner.cpp + qwt/src/qwt_polar_picker.cpp + qwt/src/qwt_polar_plot.cpp + qwt/src/qwt_polar_renderer.cpp + qwt/src/qwt_polar_spectrogram.cpp + qwt/src/qwt_raster_data.cpp + qwt/src/qwt_round_scale_draw.cpp + qwt/src/qwt_sampling_thread.cpp + qwt/src/qwt_scale_div.cpp + qwt/src/qwt_scale_draw.cpp + qwt/src/qwt_scale_engine.cpp + qwt/src/qwt_scale_map.cpp + qwt/src/qwt_scale_widget.cpp + qwt/src/qwt_series_data.cpp + qwt/src/qwt_slider.cpp + qwt/src/qwt_spline.cpp + qwt/src/qwt_spline_basis.cpp + qwt/src/qwt_spline_cubic.cpp + qwt/src/qwt_spline_curve_fitter.cpp + qwt/src/qwt_spline_local.cpp + qwt/src/qwt_spline_parametrization.cpp + qwt/src/qwt_spline_pleasing.cpp + qwt/src/qwt_spline_polynomial.cpp + qwt/src/qwt_symbol.cpp + qwt/src/qwt_system_clock.cpp + qwt/src/qwt_text.cpp + qwt/src/qwt_text_engine.cpp + qwt/src/qwt_text_label.cpp + qwt/src/qwt_thermo.cpp + qwt/src/qwt_transform.cpp + qwt/src/qwt_vectorfield_symbol.cpp + qwt/src/qwt_weeding_curve_fitter.cpp + qwt/src/qwt_wheel.cpp + qwt/src/qwt_widget_overlay.cpp ) add_library(qwt SHARED ${qwt_headers} ${qwt_sources}) add_library(qwt::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) target_include_directories(qwt PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/qwt/src) -target_link_libraries(qwt PUBLIC Qt5::Widgets Qt5::OpenGL Qt5::Svg Qt5::Concurrent Qt5::PrintSupport) -target_compile_definitions(qwt PRIVATE QT_DLL QWT_DLL QWT_MAKEDLL QWT_MOC_INCLUDE) +target_link_libraries(qwt + PUBLIC + Qt${QT_VERSION_MAJOR}::Widgets + Qt${QT_VERSION_MAJOR}::OpenGL + Qt${QT_VERSION_MAJOR}::Svg + Qt${QT_VERSION_MAJOR}::Concurrent + Qt${QT_VERSION_MAJOR}::PrintSupport +) +if (${QT_VERSION_MAJOR} GREATER_EQUAL 6) + target_link_libraries(qwt PUBLIC Qt${QT_VERSION_MAJOR}::OpenGLWidgets) +endif() -if(WIN32) - # Deploy Qt DLLs in the binary folder. This is necessary for starting the application from whithin the IDE without having to copy QtCore.dll, QtWidgets.dll etc. by hand each time - qt_add_windeployqt_postbuild(--no-system-d3d-compiler --no-compiler-runtime --no-opengl-sw --pdb "$") -endif() +target_compile_definitions(qwt PRIVATE QT_DLL QWT_DLL QWT_MAKEDLL QWT_MOC_INCLUDE) # Export targets and install them install(TARGETS qwt @@ -36,36 +296,65 @@ install(TARGETS qwt RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT qwt_runtime ) -get_target_property(_qmake_executable Qt5::qmake IMPORTED_LOCATION) -get_filename_component(_qt_bin_dir "${_qmake_executable}" DIRECTORY) -find_program(WINDEPLOYQT_EXECUTABLE windeployqt HINTS "${_qt_bin_dir}") - -if(WIN32) -install(CODE - " - set(_file ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release/qwt.dll) - execute_process( - COMMAND \"${CMAKE_COMMAND}\" -E - env PATH=\"${_qt_bin_dir}\" \"${WINDEPLOYQT_EXECUTABLE}\" - --dry-run - --no-compiler-runtime - --no-angle - --no-opengl-sw - --list mapping - \${_file} - OUTPUT_VARIABLE _output - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - separate_arguments(_files WINDOWS_COMMAND \${_output}) - while(_files) - list(GET _files 0 _src) - list(GET _files 1 _dest) - execute_process( + +if ((WIN32 OR APPLE) AND (${QT_VERSION_MAJOR} GREATER_EQUAL 6)) + + # Generate a script that will deploy all necessary Qt DLLs to the binary folder + # https://doc.qt.io/qt-6/qt-deploy-runtime-dependencies.html + # Available for Qt 6.3 and up (=> Not for Qt5!) + # Executing it requires CMake 3.14 and up, due to policy https://cmake.org/cmake/help/latest/policy/CMP0087.html + qt_generate_deploy_app_script( + TARGET ${PROJECT_NAME} + OUTPUT_SCRIPT qt_deploy_script + NO_COMPILER_RUNTIME + NO_UNSUPPORTED_PLATFORM_ERROR + ) + + # Add a postbuild script that will also execute the created script via cmake -P + # This is necessary to make the application startable / debuggable from the build directory. + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -DQT_DEPLOY_PREFIX=$ -DQT_DEPLOY_BIN_DIR=. -P ${qt_deploy_script} + ) + + # Use the script for deploying the qt dlls in the install dir + install(SCRIPT ${qt_deploy_script}) + +elseif(WIN32) + + # For Qt5 we use our legacy script. + # Deploy Qt DLLs in the binary folder. This is necessary for starting the application from whithin the IDE without having to copy QtCore.dll, QtWidgets.dll etc. by hand each time + qt_add_windeployqt_postbuild(--no-system-d3d-compiler --no-compiler-runtime --no-opengl-sw --pdb "$") + + get_target_property(_qmake_executable Qt5::qmake IMPORTED_LOCATION) + get_filename_component(_qt_bin_dir "${_qmake_executable}" DIRECTORY) + find_program(WINDEPLOYQT_EXECUTABLE windeployqt HINTS "${_qt_bin_dir}") + + install(CODE + " + set(_file ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release/qwt.dll) + execute_process( COMMAND \"${CMAKE_COMMAND}\" -E - copy \${_src} \"\${CMAKE_INSTALL_PREFIX}/bin/\${_dest}\" + env PATH=\"${_qt_bin_dir}\" \"${WINDEPLOYQT_EXECUTABLE}\" + --dry-run + --no-compiler-runtime + --no-angle + --no-opengl-sw + --list mapping + \${_file} + OUTPUT_VARIABLE _output + OUTPUT_STRIP_TRAILING_WHITESPACE ) - list(REMOVE_AT _files 0 1) - endwhile() - " -) + separate_arguments(_files WINDOWS_COMMAND \${_output}) + while(_files) + list(GET _files 0 _src) + list(GET _files 1 _dest) + execute_process( + COMMAND \"${CMAKE_COMMAND}\" -E + copy \${_src} \"\${CMAKE_INSTALL_PREFIX}/bin/\${_dest}\" + ) + list(REMOVE_AT _files 0 1) + endwhile() + " + ) + endif() \ No newline at end of file diff --git a/thirdparty/qwt/qwt b/thirdparty/qwt/qwt index 985cf3fac8..6dc6c146c0 160000 --- a/thirdparty/qwt/qwt +++ b/thirdparty/qwt/qwt @@ -1 +1 @@ -Subproject commit 985cf3fac8210851ae4bffab87084ebd57086537 +Subproject commit 6dc6c146c0e9ef2b51f4001e787702bacb729002 From da7cad7fed8df95a4b9c176ac769ea7c76a167d8 Mon Sep 17 00:00:00 2001 From: Florian Reimold <11774314+FlorianReimold@users.noreply.github.com> Date: Wed, 17 Jan 2024 09:52:50 +0100 Subject: [PATCH 08/20] Made eCAL Launcher compatible with Qt6 --- CMakeLists.txt | 2 +- app/util/launcher/CMakeLists.txt | 53 +++++++++++++++++++++++++++----- thirdparty/qwt/CMakeLists.txt | 8 ++++- 3 files changed, 53 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index af3bff9959..19c45500b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -432,10 +432,10 @@ if(BUILD_APPS AND (HAS_QT5 OR HAS_QT6)) set(ECAL_MON_PLUGIN_DIR ecal/plugins/mon) endif() add_subdirectory(app/mon/mon_plugins) + add_subdirectory(app/util/launcher) endif() if(BUILD_APPS AND HAS_QT5) - add_subdirectory(app/util/launcher) # -------------------------------------------------------- # qt applications using hdf5 # -------------------------------------------------------- diff --git a/app/util/launcher/CMakeLists.txt b/app/util/launcher/CMakeLists.txt index cf1fd25cb4..678eb3b34b 100644 --- a/app/util/launcher/CMakeLists.txt +++ b/app/util/launcher/CMakeLists.txt @@ -16,13 +16,19 @@ # # ========================= eCAL LICENSE ================================= +cmake_minimum_required(VERSION 3.14) + project(launcher) -find_package(Qt5 COMPONENTS - Core - Widgets -REQUIRED) +# Allow the install command to use generator expressions +if(POLICY CMP0087) + cmake_policy(SET CMP0087 NEW) +endif() +# Legacy Qt5 (pre 5.15) support as suggested by teh Qt Documentation: +# https://doc.qt.io/qt-6/cmake-qt5-and-qt6-compatibility.html#supporting-older-qt-5-versions +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC OFF) # Reason for being turned off: AutoUIC will prevent VS from detecting changes in .ui files @@ -57,8 +63,13 @@ set(ui_files ) # compile qt resource files and ui files -qt5_add_resources(autogen_resources ${qt_resource_files}) -qt5_wrap_ui (autogen_ui ${ui_files}) +if (${QT_VERSION_MAJOR} GREATER_EQUAL 6) + qt_add_resources(autogen_resources ${qt_resource_files}) + qt_wrap_ui (autogen_ui ${ui_files}) +else() + qt5_add_resources(autogen_resources ${qt_resource_files}) + qt5_wrap_ui (autogen_ui ${ui_files}) +endif() # Add all files. The resource files and ui files are not necessary, but we want them to show up in the IDE ecal_add_app_qt(${PROJECT_NAME} @@ -72,7 +83,8 @@ ecal_add_app_qt(${PROJECT_NAME} ) target_link_libraries (${PROJECT_NAME} - Qt5::Widgets + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets eCAL::apps eCAL::core ) @@ -91,9 +103,34 @@ else() target_compile_definitions(${PROJECT_NAME} PRIVATE BUILDTIMEUSER="$ENV{USER}") endif() -if(WIN32) +if ((WIN32 OR APPLE) AND (${QT_VERSION_MAJOR} GREATER_EQUAL 6)) + + # Generate a script that will deploy all necessary Qt DLLs to the binary folder + # https://doc.qt.io/qt-6/qt-deploy-runtime-dependencies.html + # Available for Qt 6.3 and up (=> Not for Qt5!) + # Executing it requires CMake 3.14 and up, due to policy https://cmake.org/cmake/help/latest/policy/CMP0087.html + qt_generate_deploy_app_script( + TARGET ${PROJECT_NAME} + OUTPUT_SCRIPT qt_deploy_script + NO_COMPILER_RUNTIME + NO_UNSUPPORTED_PLATFORM_ERROR + ) + + # Add a postbuild script that will also execute the created script via cmake -P + # This is necessary to make the application startable / debuggable from the build directory. + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -DQT_DEPLOY_PREFIX=$ -DQT_DEPLOY_BIN_DIR=. -P ${qt_deploy_script} + ) + + # Use the script for deploying the qt dlls in the install dir + install(SCRIPT ${qt_deploy_script}) + +elseif(WIN32) + + # For Qt5 we use our legacy script. # Deploy Qt DLLs in the binary folder. This is necessary for starting the application from whithin the IDE without having to copy QtCore.dll, QtWidgets.dll etc. by hand each time qt_add_windeployqt_postbuild(--no-system-d3d-compiler --no-compiler-runtime --no-opengl-sw --pdb "$") + endif() # Create a source tree that mirrors the filesystem diff --git a/thirdparty/qwt/CMakeLists.txt b/thirdparty/qwt/CMakeLists.txt index 822a768494..576adf6c23 100644 --- a/thirdparty/qwt/CMakeLists.txt +++ b/thirdparty/qwt/CMakeLists.txt @@ -1,4 +1,10 @@ -cmake_minimum_required(VERSION 3.13) +cmake_minimum_required(VERSION 3.14) + +# Allow the install command to use generator expressions +if(POLICY CMP0087) + cmake_policy(SET CMP0087 NEW) +endif() + project(qwt VERSION 6.2.0) # Legacy Qt5 (pre 5.15) support as suggested by teh Qt Documentation: From f0f996570264c2ea98fccb85d603350b52959804 Mon Sep 17 00:00:00 2001 From: Florian Reimold <11774314+FlorianReimold@users.noreply.github.com> Date: Wed, 17 Jan 2024 11:52:32 +0100 Subject: [PATCH 09/20] eCAL Play and Rec now compile and run with Qt6 --- CMakeLists.txt | 18 +- app/mon/mon_gui/CMakeLists.txt | 1 - app/play/play_gui/CMakeLists.txt | 154 +++++++++++------ app/play/play_gui/src/ecal_play_gui.cpp | 62 ++++--- app/play/play_gui/src/ecal_play_gui.h | 19 ++- app/play/play_gui/src/q_ecal_play.cpp | 10 +- .../src/widgets/models/channel_tree_item.cpp | 2 +- .../player_time_slider.cpp | 4 +- .../scenario_widget/edit_button_delegate.cpp | 4 + .../scenario_widget/scenario_model.cpp | 2 +- app/rec/rec_gui/CMakeLists.txt | 159 +++++++++++------- app/rec/rec_gui/src/ecalrec_gui.cpp | 70 +++++--- app/rec/rec_gui/src/ecalrec_gui.h | 18 +- .../widgets/config_widget/config_widget.cpp | 2 +- .../recordermanager_widget/recorder_model.cpp | 12 +- .../job_history_model.cpp | 2 +- .../widgets/topic_widget/topic_list_model.cpp | 6 +- 17 files changed, 350 insertions(+), 195 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 19c45500b2..6eca86331e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -433,16 +433,14 @@ if(BUILD_APPS AND (HAS_QT5 OR HAS_QT6)) endif() add_subdirectory(app/mon/mon_plugins) add_subdirectory(app/util/launcher) -endif() - -if(BUILD_APPS AND HAS_QT5) -# -------------------------------------------------------- -# qt applications using hdf5 -# -------------------------------------------------------- -if(BUILD_APPS AND HAS_QT5 AND HAS_HDF5) - add_subdirectory(app/play/play_gui) - add_subdirectory(app/rec/rec_gui) -endif() + + # -------------------------------------------------------- + # qt applications using hdf5 + # -------------------------------------------------------- + if(HAS_HDF5) + add_subdirectory(app/play/play_gui) + add_subdirectory(app/rec/rec_gui) + endif() endif() # -------------------------------------------------------- diff --git a/app/mon/mon_gui/CMakeLists.txt b/app/mon/mon_gui/CMakeLists.txt index c142867bb3..ba84cabce4 100644 --- a/app/mon/mon_gui/CMakeLists.txt +++ b/app/mon/mon_gui/CMakeLists.txt @@ -176,7 +176,6 @@ if(ECAL_NPCAP_SUPPORT) ) endif(ECAL_NPCAP_SUPPORT) - # compile qt resource files and ui files if (${QT_VERSION_MAJOR} GREATER_EQUAL 6) qt_add_resources(autogen_resources ${qt_resource_files}) diff --git a/app/play/play_gui/CMakeLists.txt b/app/play/play_gui/CMakeLists.txt index 8fba5eade0..3dff50e5e9 100644 --- a/app/play/play_gui/CMakeLists.txt +++ b/app/play/play_gui/CMakeLists.txt @@ -16,17 +16,30 @@ # # ========================= eCAL LICENSE ================================= -project(play_gui) +cmake_minimum_required(VERSION 3.14) -find_package(Qt5 COMPONENTS - Core - Widgets -REQUIRED) +# Allow the install command to use generator expressions +if(POLICY CMP0087) + cmake_policy(SET CMP0087 NEW) +endif() -if(WIN32) - find_package(Qt5 COMPONENTS - WinExtras - REQUIRED) +project(play_gui) + +# Legacy Qt5 (pre 5.15) support as suggested by teh Qt Documentation: +# https://doc.qt.io/qt-6/cmake-qt5-and-qt6-compatibility.html#supporting-older-qt-5-versions +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets Concurrent) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets Concurrent) + +if (WIN32 AND (${QT_VERSION_MAJOR} EQUAL 5)) + # For Qt5 we find the WinExtras component. + # It enables those taskbar buttons on Windows 7 and up. + # Unfortunatelly, this functionality has been removed with Qt 6.0 and up. + # (2024-01-17, Current Qt Version: 6.6) + # + # Maybe we can re-enable the functionality with the following external lib: + # https://github.com/oblivioncth/Qx + # + find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS WinExtras) endif() find_package(tclap REQUIRED) @@ -103,12 +116,16 @@ set(ui_files src/widgets/player_controls_widget/player_controls_widget.ui src/widgets/scenario_widget/scenario_widget.ui src/widgets/settings_widget/settings_widget.ui - ) # compile qt resource files and ui files -qt5_add_resources(autogen_resources ${qt_resource_files}) -qt5_wrap_ui (autogen_ui ${ui_files}) +if (${QT_VERSION_MAJOR} GREATER_EQUAL 6) + qt_add_resources(autogen_resources ${qt_resource_files}) + qt_wrap_ui (autogen_ui ${ui_files}) +else() + qt5_add_resources(autogen_resources ${qt_resource_files}) + qt5_wrap_ui (autogen_ui ${ui_files}) +endif() # Add all files. The resource files and ui files are not necessary, but we want them to show up in the IDE ecal_add_app_qt(${PROJECT_NAME} @@ -126,14 +143,25 @@ target_link_libraries (${PROJECT_NAME} tclap::tclap CustomTclap eCAL::play_core - Qt5::Widgets + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets + Qt${QT_VERSION_MAJOR}::Concurrent CustomQt eCAL::core_pb eCAL::ecal-utils ) -if (WIN32) + +if (WIN32 AND (${QT_VERSION_MAJOR} EQUAL 5)) + # For Qt5 we link against the WinExtras component. + # It enables those taskbar buttons on Windows 7 and up. + # Unfortunatelly, this functionality has been removed with Qt 6.0 and up. + # (2024-01-17, Current Qt Version: 6.6) + # + # Maybe we can re-enable the functionality with the following external lib: + # https://github.com/oblivioncth/Qx + # target_link_libraries (${PROJECT_NAME} - Qt5::WinExtras + Qt${QT_VERSION_MAJOR}::WinExtras ) endif() @@ -151,10 +179,64 @@ endif() target_include_directories(${PROJECT_NAME} PRIVATE src) +if ((WIN32 OR APPLE) AND (${QT_VERSION_MAJOR} GREATER_EQUAL 6)) + + # Generate a script that will deploy all necessary Qt DLLs to the binary folder + # https://doc.qt.io/qt-6/qt-deploy-runtime-dependencies.html + # Available for Qt 6.3 and up (=> Not for Qt5!) + # Executing it requires CMake 3.14 and up, due to policy https://cmake.org/cmake/help/latest/policy/CMP0087.html + qt_generate_deploy_app_script( + TARGET ${PROJECT_NAME} + OUTPUT_SCRIPT qt_deploy_script + NO_COMPILER_RUNTIME + NO_UNSUPPORTED_PLATFORM_ERROR + ) -if(WIN32) + # Add a postbuild script that will also execute the created script via cmake -P + # This is necessary to make the application startable / debuggable from the build directory. + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -DQT_DEPLOY_PREFIX=$ -DQT_DEPLOY_BIN_DIR=. -P ${qt_deploy_script} + ) + + # Use the script for deploying the qt dlls in the install dir + install(SCRIPT ${qt_deploy_script}) + +elseif(WIN32) + + # For Qt5 we use our legacy script. # Deploy Qt DLLs in the binary folder. This is necessary for starting the application from whithin the IDE without having to copy QtCore.dll, QtWidgets.dll etc. by hand each time qt_add_windeployqt_postbuild(--no-system-d3d-compiler --no-compiler-runtime --no-opengl-sw --pdb "$") + + get_target_property(_qmake_executable Qt5::qmake IMPORTED_LOCATION) + get_filename_component(_qt_bin_dir "${_qmake_executable}" DIRECTORY) + find_program(WINDEPLOYQT_EXECUTABLE windeployqt HINTS "${_qt_bin_dir}") + install(CODE + " + set(_file ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release/ecal_mon_gui.exe) + execute_process( + COMMAND \"${CMAKE_COMMAND}\" -E + env PATH=\"${_qt_bin_dir}\" \"${WINDEPLOYQT_EXECUTABLE}\" + --dry-run + --no-compiler-runtime + --no-angle + --no-opengl-sw + --list mapping + \${_file} + OUTPUT_VARIABLE _output + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + separate_arguments(_files WINDOWS_COMMAND \${_output}) + while(_files) + list(GET _files 0 _src) + list(GET _files 1 _dest) + execute_process( + COMMAND \"${CMAKE_COMMAND}\" -E + copy \${_src} \"\${CMAKE_INSTALL_PREFIX}/bin/\${_dest}\" + ) + list(REMOVE_AT _files 0 1) + endwhile() + " +) endif() # Create a source tree that mirrors the filesystem @@ -183,46 +265,6 @@ set_property(TARGET ${PROJECT_NAME} PROPERTY FOLDER app/play) ecal_install_app(${PROJECT_NAME} START_MENU_NAME "eCAL Player") -get_target_property(_qmake_executable Qt5::qmake IMPORTED_LOCATION) -get_filename_component(_qt_bin_dir "${_qmake_executable}" DIRECTORY) -find_program(WINDEPLOYQT_EXECUTABLE windeployqt HINTS "${_qt_bin_dir}") - -# Running this with MSVC 2015 requires CMake 3.6+ -if((MSVC_VERSION VERSION_EQUAL 1900 OR MSVC_VERSION VERSION_GREATER 1900) - AND CMAKE_VERSION VERSION_LESS "3.6") - message(WARNING "Deploying with MSVC 2015+ requires CMake 3.6+") -endif() - -if(WIN32) -install(CODE - " - set(_file ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release/ecal_play_gui.exe) - execute_process( - COMMAND \"${CMAKE_COMMAND}\" -E - env PATH=\"${_qt_bin_dir}\" \"${WINDEPLOYQT_EXECUTABLE}\" - --dry-run - --no-compiler-runtime - --no-angle - --no-opengl-sw - --list mapping - \${_file} - OUTPUT_VARIABLE _output - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - separate_arguments(_files WINDOWS_COMMAND \${_output}) - while(_files) - list(GET _files 0 _src) - list(GET _files 1 _dest) - execute_process( - COMMAND \"${CMAKE_COMMAND}\" -E - copy \${_src} \"\${CMAKE_INSTALL_PREFIX}/bin/\${_dest}\" - ) - list(REMOVE_AT _files 0 1) - endwhile() - " -) -endif() - # install files required for linux mimetypes and icon if (UNIX) INSTALL (FILES "${CMAKE_CURRENT_LIST_DIR}/mimetype/ecal-play.xml" diff --git a/app/play/play_gui/src/ecal_play_gui.cpp b/app/play/play_gui/src/ecal_play_gui.cpp index 35db553fb1..884613e76b 100644 --- a/app/play/play_gui/src/ecal_play_gui.cpp +++ b/app/play/play_gui/src/ecal_play_gui.cpp @@ -23,20 +23,27 @@ #include #include #include -#include + +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) + #include +#endif // QT_VERSION < QT_VERSION_CHECK(5, 15, 0) + #include #include #include #include #include +#if((defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))) + #include + #include +#endif + #ifdef WIN32 -#include -#include -#define WIN32_LEAN_AND_MEAN -#define NOMINMAX -#include -#endif // WIN32 + #define WIN32_LEAN_AND_MEAN + #define NOMINMAX + #include +#endif #include "q_ecal_play.h" @@ -53,7 +60,7 @@ EcalplayGui::EcalplayGui(QWidget *parent) , measurement_loaded_ (false) , measurement_boundaries_ (eCAL::Time::ecal_clock::time_point(eCAL::Time::ecal_clock::duration(0)), eCAL::Time::ecal_clock::time_point(eCAL::Time::ecal_clock::duration(0))) , measurement_frame_count_ (0) -#ifdef WIN32 +#if((defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))) , taskbar_play_icon_ (":ecalicons/TASKBAR_PLAY") , taskbar_play_icon_disabled_ (":ecalicons/TASKBAR_PLAY_DISABLED") , taskbar_pause_icon_ (":ecalicons/TASKBAR_PAUSE") @@ -64,7 +71,7 @@ EcalplayGui::EcalplayGui(QWidget *parent) , taskbar_step_icon_disabled_ (":ecalicons/TASKBAR_PLAY_NEXT_DISABLED") , taskbar_step_channel_icon_ (":ecalicons/TASKBAR_FORWARD_TO") , taskbar_step_channel_icon_disabled_ (":ecalicons/TASKBAR_FORWARD_TO_DISABLED") -#endif // WIN32 +#endif { ui_.setupUi(this); splitDockWidget(ui_.scenario_dockwidget, ui_.description_dockwidget, Qt::Orientation::Vertical); @@ -227,6 +234,8 @@ EcalplayGui::EcalplayGui(QWidget *parent) connect(ui_.menu_recent_measurement, &QMenu::aboutToShow, this, &EcalplayGui::populateRecentMeasurementsMenu); #ifdef WIN32 + +#if(QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) ////////////////////////////////////////////////////////////////////////////// //// Windows Taskbar //// ////////////////////////////////////////////////////////////////////////////// @@ -273,6 +282,7 @@ EcalplayGui::EcalplayGui(QWidget *parent) thumbnail_toolbar_->addButton(thumbnail_stop_button_); thumbnail_toolbar_->addButton(thumbnail_step_button_); thumbnail_toolbar_->addButton(thumbnail_step_channel_button_); +#endif // QT_VERSION < QT_VERSION_CHECK(6, 0, 0) // Special show-console button for Windows ui_.action_debug_console->setChecked(GetConsoleWindow()); @@ -308,7 +318,7 @@ void EcalplayGui::showEvent(QShowEvent* /*event*/) { if (first_show_event_) { -#ifdef WIN32 +#if (defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) taskbar_button_ ->setWindow(this->windowHandle()); thumbnail_toolbar_->setWindow(this->windowHandle()); #endif // WIN32 @@ -368,7 +378,7 @@ void EcalplayGui::measurementLoaded(const QString& path) measurement_path_label_->setText(" " + QDir::toNativeSeparators(path) + " "); addRecentMeasurement(path); -#ifdef WIN32 +#if((defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))) thumbnail_play_pause_button_ ->setEnabled(true); thumbnail_play_pause_button_ ->setIcon(play_pause_button_state_is_play_ ? taskbar_play_icon_ : taskbar_pause_icon_); @@ -403,7 +413,7 @@ void EcalplayGui::measurementClosed() setWindowFilePath(""); measurement_path_label_->setText(tr(" No measurement loaded ")); -#ifdef WIN32 +#if((defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))) thumbnail_play_pause_button_ ->setEnabled(false); thumbnail_play_pause_button_ ->setIcon(play_pause_button_state_is_play_ ? taskbar_play_icon_disabled_ : taskbar_pause_icon_disabled_); @@ -493,7 +503,7 @@ void EcalplayGui::stepReferenceChannelChanged(const QString& step_reference_chan { ui_.action_step_channel->setText("Step channel"); ui_.action_step_channel->setEnabled(false); -#ifdef WIN32 +#if((defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))) thumbnail_step_channel_button_->setEnabled(false); thumbnail_step_channel_button_->setToolTip("Step channel"); thumbnail_step_channel_button_->setIcon(taskbar_step_channel_icon_disabled_); @@ -508,7 +518,7 @@ void EcalplayGui::stepReferenceChannelChanged(const QString& step_reference_chan { QString description = tr("Step") + " \"" + target_channel_it->second.c_str() + "\""; ui_.action_step_channel->setText(tr("Step") + " \"" + target_channel_it->second.c_str() + "\""); -#ifdef WIN32 +#if((defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))) thumbnail_step_channel_button_->setToolTip(description); #endif //WIN32 } @@ -516,13 +526,13 @@ void EcalplayGui::stepReferenceChannelChanged(const QString& step_reference_chan { QString description = tr("Step") + " \"" + step_reference_channel + "\""; ui_.action_step_channel->setText(description); -#ifdef WIN32 +#if((defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))) thumbnail_step_channel_button_->setToolTip(description); #endif //WIN32 } ui_.action_step_channel->setEnabled(true); -#ifdef WIN32 +#if((defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))) thumbnail_step_channel_button_->setEnabled(true); thumbnail_step_channel_button_->setIcon(taskbar_step_channel_icon_); #endif //WIN32 @@ -564,7 +574,7 @@ void EcalplayGui::setPlayPauseActionToPlay() ui_.action_play->setIcon(QPixmap(":/ecalicons/START")); play_pause_button_state_is_play_ = true; -#ifdef WIN32 +#if((defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))) thumbnail_play_pause_button_->setToolTip("Play"); thumbnail_play_pause_button_->setIcon(thumbnail_play_pause_button_->isEnabled() ? taskbar_play_icon_ : taskbar_pause_icon_disabled_); #endif // WIN32 @@ -579,7 +589,7 @@ void EcalplayGui::setPlayPauseActionToPause() ui_.action_play->setIcon(QPixmap(":/ecalicons/PAUSE")); play_pause_button_state_is_play_ = false; -#ifdef WIN32 +#if((defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))) thumbnail_play_pause_button_->setToolTip("Pause"); thumbnail_play_pause_button_->setIcon(thumbnail_play_pause_button_->isEnabled() ? taskbar_pause_icon_ : taskbar_pause_icon_disabled_); #endif // WIN32 @@ -761,7 +771,19 @@ void EcalplayGui::resetLayout() channel_widget_ ->resetLayout(); scenario_widget_ ->resetLayout(); +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) int screen_number = QApplication::desktop()->screenNumber(this); +#else + int screen_number = 0; + QScreen* current_screen = this->screen(); + if (current_screen) + { + screen_number = QApplication::screens().indexOf(current_screen); + if (screen_number < 0) + screen_number = 0; + } +#endif // QT_VERSION < QT_VERSION_CHECK(5, 15, 0) + restoreGeometry(initial_geometry_); restoreState(initial_state_); move(QGuiApplication::screens().at(screen_number)->availableGeometry().center() - rect().center()); @@ -940,7 +962,7 @@ void EcalplayGui::dropEvent(QDropEvent* event) QWidget::dropEvent(event); } -#ifdef WIN32 +#if((defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))) //////////////////////////////////////////////////////////////////////////////// //// Windows Taskbar //// //////////////////////////////////////////////////////////////////////////////// @@ -976,7 +998,9 @@ void EcalplayGui::updateTaskbarProgressRange() progress->setMinimum(0); progress->setMaximum(std::chrono::duration_cast(measurement_boundaries_.second - measurement_boundaries_.first).count()); } +#endif +#ifdef WIN32 void EcalplayGui::showConsole(bool show) { if (show) diff --git a/app/play/play_gui/src/ecal_play_gui.h b/app/play/play_gui/src/ecal_play_gui.h index a323b06bda..e2f445fdb1 100644 --- a/app/play/play_gui/src/ecal_play_gui.h +++ b/app/play/play_gui/src/ecal_play_gui.h @@ -21,11 +21,11 @@ #include -#ifdef WIN32 +#if((defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))) #include #include #include -#endif // WIN32 +#endif #include @@ -138,13 +138,12 @@ private slots: bool askToSaveScenarios(); -#ifdef WIN32 +#if((defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))) //////////////////////////////////////////////////////////////////////////////// -//// Windows specific //// +//// Windows taskbar button //// //////////////////////////////////////////////////////////////////////////////// -private slots: +private: void updateTaskbarProgress(const EcalPlayState& current_state); - void showConsole(bool show); private: QWinTaskbarButton* taskbar_button_; @@ -166,5 +165,13 @@ private slots: QIcon taskbar_step_channel_icon_disabled_; void updateTaskbarProgressRange(); +#endif + +#ifdef WIN32 +//////////////////////////////////////////////////////////////////////////////// +//// Windows specific //// +//////////////////////////////////////////////////////////////////////////////// +private slots: + void showConsole(bool show); #endif // WIN32 }; diff --git a/app/play/play_gui/src/q_ecal_play.cpp b/app/play/play_gui/src/q_ecal_play.cpp index 8511fddb28..bde68eadfb 100644 --- a/app/play/play_gui/src/q_ecal_play.cpp +++ b/app/play/play_gui/src/q_ecal_play.cpp @@ -32,15 +32,15 @@ #include #include #include -#include +#include #include #include #include #include "ecal_play_logger.h" -#ifdef WIN32 -#include +#if((defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))) + #include #endif //WIN32 QEcalPlay::QEcalPlay() @@ -370,7 +370,7 @@ bool QEcalPlay::loadMeasurement(const QString& path, bool suppress_blocking_dial dlg.setValue(0); dlg.setValue(1); - QFuture success_future = QtConcurrent::run(&ecal_play_, &EcalPlay::LoadMeasurement, path.toStdString()); + QFuture success_future = QtConcurrent::run([this, path]() -> bool { return this->ecal_play_.LoadMeasurement(path.toStdString()); }); while (!success_future.isFinished()) { @@ -585,7 +585,7 @@ void QEcalPlay::calculateChannelsCumulativeEstimatedSize() const dlg.setValue(0); dlg.setValue(1); - QFuture success_future = QtConcurrent::run(&ecal_play_, &EcalPlay::CalculateEstimatedSizeForChannels); + QFuture success_future = QtConcurrent::run([this]() -> void { this->ecal_play_.CalculateEstimatedSizeForChannels(); }); while (!success_future.isFinished()) { diff --git a/app/play/play_gui/src/widgets/models/channel_tree_item.cpp b/app/play/play_gui/src/widgets/models/channel_tree_item.cpp index bf5f0261d7..04bc8aa871 100644 --- a/app/play/play_gui/src/widgets/models/channel_tree_item.cpp +++ b/app/play/play_gui/src/widgets/models/channel_tree_item.cpp @@ -247,7 +247,7 @@ QVariant ChannelTreeItem::data(Columns column, Qt::ItemDataRole role) const } - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } bool ChannelTreeItem::setData(int column, const QVariant& data, Qt::ItemDataRole role) diff --git a/app/play/play_gui/src/widgets/player_controls_widget/player_time_slider.cpp b/app/play/play_gui/src/widgets/player_controls_widget/player_time_slider.cpp index b30837c2bb..61abcd1d34 100644 --- a/app/play/play_gui/src/widgets/player_controls_widget/player_time_slider.cpp +++ b/app/play/play_gui/src/widgets/player_controls_widget/player_time_slider.cpp @@ -31,7 +31,7 @@ void PlayerTimeSlider::mousePressEvent(QMouseEvent* ev) if (orientation() == Qt::Vertical) { double half_handle_height = (0.5 * slider_handle_rect.height()) + 0.5; // Correct rounding - int adapted_pos_y = ev->y(); + int adapted_pos_y = ev->pos().y(); if (adapted_pos_y < half_handle_height) adapted_pos_y = half_handle_height; @@ -47,7 +47,7 @@ void PlayerTimeSlider::mousePressEvent(QMouseEvent* ev) else { double half_handle_width = (0.5 * slider_handle_rect.width()) + 0.5; // Correct rounding - int adapted_pos_x = ev->x(); + int adapted_pos_x = ev->pos().x(); if (adapted_pos_x < half_handle_width) adapted_pos_x = half_handle_width; diff --git a/app/play/play_gui/src/widgets/scenario_widget/edit_button_delegate.cpp b/app/play/play_gui/src/widgets/scenario_widget/edit_button_delegate.cpp index 728f2d912b..102dfa39af 100644 --- a/app/play/play_gui/src/widgets/scenario_widget/edit_button_delegate.cpp +++ b/app/play/play_gui/src/widgets/scenario_widget/edit_button_delegate.cpp @@ -288,7 +288,11 @@ bool EditButtonDelegate::eventFilter(QObject* obj, QEvent *event) { const QAbstractItemView* item_view = static_cast(parent()); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QPoint mouse_pos = static_cast(event)->globalPos(); +#else + QPoint mouse_pos = static_cast(event)->globalPosition().toPoint(); +#endif QPoint p = item_view->viewport()->mapFromGlobal(mouse_pos); // QModelIndex current_index = item_view->indexAt(p); diff --git a/app/play/play_gui/src/widgets/scenario_widget/scenario_model.cpp b/app/play/play_gui/src/widgets/scenario_widget/scenario_model.cpp index 523163ce33..c2e9ef7409 100644 --- a/app/play/play_gui/src/widgets/scenario_widget/scenario_model.cpp +++ b/app/play/play_gui/src/widgets/scenario_widget/scenario_model.cpp @@ -53,7 +53,7 @@ QVariant ScenarioModel::headerData(int section, Qt::Orientation orientation, int } else { - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } } diff --git a/app/rec/rec_gui/CMakeLists.txt b/app/rec/rec_gui/CMakeLists.txt index 4aee47ff77..537a235e80 100644 --- a/app/rec/rec_gui/CMakeLists.txt +++ b/app/rec/rec_gui/CMakeLists.txt @@ -16,18 +16,31 @@ # # ========================= eCAL LICENSE ================================= -set(PROJECT_NAME rec_gui) +cmake_minimum_required(VERSION 3.14) -find_package(Qt5 COMPONENTS - Core - Widgets -REQUIRED) +# Allow the install command to use generator expressions +if(POLICY CMP0087) + cmake_policy(SET CMP0087 NEW) +endif() -if(WIN32) - find_package(Qt5 COMPONENTS - WinExtras - REQUIRED) -endif(WIN32) +project(rec_gui) + +# Legacy Qt5 (pre 5.15) support as suggested by teh Qt Documentation: +# https://doc.qt.io/qt-6/cmake-qt5-and-qt6-compatibility.html#supporting-older-qt-5-versions +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets) + +if (WIN32 AND (${QT_VERSION_MAJOR} EQUAL 5)) + # For Qt5 we find the WinExtras component. + # It enables those taskbar buttons on Windows 7 and up. + # Unfortunatelly, this functionality has been removed with Qt 6.0 and up. + # (2024-01-17, Current Qt Version: 6.6) + # + # Maybe we can re-enable the functionality with the following external lib: + # https://github.com/oblivioncth/Qx + # + find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS WinExtras) +endif() find_package(tclap REQUIRED) find_package(Protobuf REQUIRED) @@ -137,8 +150,13 @@ set(ui_files ) # compile qt resource files and ui files -qt5_add_resources(autogen_resources ${qt_resource_files}) -qt5_wrap_ui (autogen_ui ${ui_files}) +if (${QT_VERSION_MAJOR} GREATER_EQUAL 6) + qt_add_resources(autogen_resources ${qt_resource_files}) + qt_wrap_ui (autogen_ui ${ui_files}) +else() + qt5_add_resources(autogen_resources ${qt_resource_files}) + qt5_wrap_ui (autogen_ui ${ui_files}) +endif() # Add all files. The resource files and ui files are not necessary, but we want them to show up in the IDE ecal_add_app_qt(${PROJECT_NAME} @@ -158,7 +176,8 @@ target_link_libraries (${PROJECT_NAME} eCAL::core eCAL::app_pb eCAL::rec_server_core - Qt5::Widgets + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets CustomQt CustomTclap eCAL::ecal-utils @@ -166,11 +185,20 @@ target_link_libraries (${PROJECT_NAME} QEcalParser ThreadingUtils ) -if (WIN32) + +if (WIN32 AND (${QT_VERSION_MAJOR} EQUAL 5)) + # For Qt5 we link against the WinExtras component. + # It enables those taskbar buttons on Windows 7 and up. + # Unfortunatelly, this functionality has been removed with Qt 6.0 and up. + # (2024-01-17, Current Qt Version: 6.6) + # + # Maybe we can re-enable the functionality with the following external lib: + # https://github.com/oblivioncth/Qx + # target_link_libraries (${PROJECT_NAME} - Qt5::WinExtras + Qt${QT_VERSION_MAJOR}::WinExtras ) -endif(WIN32) +endif() target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_14) @@ -187,10 +215,65 @@ ENDIF(MSVC) target_include_directories(${PROJECT_NAME} PRIVATE src) -if(WIN32) +if ((WIN32 OR APPLE) AND (${QT_VERSION_MAJOR} GREATER_EQUAL 6)) + + # Generate a script that will deploy all necessary Qt DLLs to the binary folder + # https://doc.qt.io/qt-6/qt-deploy-runtime-dependencies.html + # Available for Qt 6.3 and up (=> Not for Qt5!) + # Executing it requires CMake 3.14 and up, due to policy https://cmake.org/cmake/help/latest/policy/CMP0087.html + qt_generate_deploy_app_script( + TARGET ${PROJECT_NAME} + OUTPUT_SCRIPT qt_deploy_script + NO_COMPILER_RUNTIME + NO_UNSUPPORTED_PLATFORM_ERROR + ) + + # Add a postbuild script that will also execute the created script via cmake -P + # This is necessary to make the application startable / debuggable from the build directory. + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -DQT_DEPLOY_PREFIX=$ -DQT_DEPLOY_BIN_DIR=. -P ${qt_deploy_script} + ) + + # Use the script for deploying the qt dlls in the install dir + install(SCRIPT ${qt_deploy_script}) + +elseif(WIN32) + + # For Qt5 we use our legacy script. # Deploy Qt DLLs in the binary folder. This is necessary for starting the application from whithin the IDE without having to copy QtCore.dll, QtWidgets.dll etc. by hand each time qt_add_windeployqt_postbuild(--no-system-d3d-compiler --no-compiler-runtime --no-opengl-sw --pdb "$") -endif(WIN32) + + get_target_property(_qmake_executable Qt5::qmake IMPORTED_LOCATION) + get_filename_component(_qt_bin_dir "${_qmake_executable}" DIRECTORY) + find_program(WINDEPLOYQT_EXECUTABLE windeployqt HINTS "${_qt_bin_dir}") + install(CODE + " + set(_file ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release/ecal_mon_gui.exe) + execute_process( + COMMAND \"${CMAKE_COMMAND}\" -E + env PATH=\"${_qt_bin_dir}\" \"${WINDEPLOYQT_EXECUTABLE}\" + --dry-run + --no-compiler-runtime + --no-angle + --no-opengl-sw + --list mapping + \${_file} + OUTPUT_VARIABLE _output + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + separate_arguments(_files WINDOWS_COMMAND \${_output}) + while(_files) + list(GET _files 0 _src) + list(GET _files 1 _dest) + execute_process( + COMMAND \"${CMAKE_COMMAND}\" -E + copy \${_src} \"\${CMAKE_INSTALL_PREFIX}/bin/\${_dest}\" + ) + list(REMOVE_AT _files 0 1) + endwhile() + " +) +endif() # Create a source tree that mirrors the filesystem source_group(TREE "${CMAKE_CURRENT_LIST_DIR}" @@ -218,46 +301,6 @@ set_property(TARGET ${PROJECT_NAME} PROPERTY FOLDER app/rec) ecal_install_app(${PROJECT_NAME} START_MENU_NAME "eCAL Recorder") -get_target_property(_qmake_executable Qt5::qmake IMPORTED_LOCATION) -get_filename_component(_qt_bin_dir "${_qmake_executable}" DIRECTORY) -find_program(WINDEPLOYQT_EXECUTABLE windeployqt HINTS "${_qt_bin_dir}") - -# Running this with MSVC 2015 requires CMake 3.6+ -if((MSVC_VERSION VERSION_EQUAL 1900 OR MSVC_VERSION VERSION_GREATER 1900) - AND CMAKE_VERSION VERSION_LESS "3.6") - message(WARNING "Deploying with MSVC 2015+ requires CMake 3.6+") -endif() - -if(WIN32) -install(CODE - " - set(_file ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release/ecal_rec_gui.exe) - execute_process( - COMMAND \"${CMAKE_COMMAND}\" -E - env PATH=\"${_qt_bin_dir}\" \"${WINDEPLOYQT_EXECUTABLE}\" - --dry-run - --no-compiler-runtime - --no-angle - --no-opengl-sw - --list mapping - \${_file} - OUTPUT_VARIABLE _output - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - separate_arguments(_files WINDOWS_COMMAND \${_output}) - while(_files) - list(GET _files 0 _src) - list(GET _files 1 _dest) - execute_process( - COMMAND \"${CMAKE_COMMAND}\" -E - copy \${_src} \"\${CMAKE_INSTALL_PREFIX}/bin/\${_dest}\" - ) - list(REMOVE_AT _files 0 1) - endwhile() - " -) -endif() - # install files required for linux mimetypes and icon if (UNIX) INSTALL (FILES "${CMAKE_CURRENT_LIST_DIR}/mimetype/ecal-rec.xml" diff --git a/app/rec/rec_gui/src/ecalrec_gui.cpp b/app/rec/rec_gui/src/ecalrec_gui.cpp index fda4f2a5e2..5fbbd6ab6d 100644 --- a/app/rec/rec_gui/src/ecalrec_gui.cpp +++ b/app/rec/rec_gui/src/ecalrec_gui.cpp @@ -26,19 +26,27 @@ #include #include #include -#include +#include + +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) + #include +#endif // QT_VERSION < QT_VERSION_CHECK(5, 15, 0) + #include #include #include #include +#if (defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) + #include + #include +#endif + #ifdef WIN32 -#include -#include -#define WIN32_LEAN_AND_MEAN -#define NOMINMAX -#include + #define WIN32_LEAN_AND_MEAN + #define NOMINMAX + #include #endif // WIN32 #include @@ -53,7 +61,7 @@ EcalRecGui::EcalRecGui(QWidget *parent) , connect_to_ecal_action_state_is_connect_ (true) , record_action_state_is_record_ (true) , first_show_event_ (true) -#ifdef WIN32 +#if (defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) , taskbar_activate_icon_ (":/ecalicons/TASKBAR_POWER_ON") , taskbar_deactivate_icon_ (":/ecalicons/TASKBAR_POWER_OFF") , taskbar_record_icon_ (":/ecalicons/TASKBAR_RECORD") @@ -203,7 +211,7 @@ EcalRecGui::EcalRecGui(QWidget *parent) ui_.action_debug_console->setVisible(false); #endif // WIN32 -#ifdef WIN32 +#if (defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) ///////////////////////////////////////////// // Windows taskbar ///////////////////////////////////////////// @@ -389,7 +397,7 @@ void EcalRecGui::showEvent(QShowEvent* /*event*/) { if (first_show_event_) { -#ifdef WIN32 +#if (defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) registerTaskbarButtons(); #endif // WIN32 @@ -480,7 +488,19 @@ void EcalRecGui::resetLayout() recorder_manager_widget_->resetLayout(); recording_history_widget_->resetLayout(); +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) int screen_number = QApplication::desktop()->screenNumber(this); +#else + int screen_number = 0; + QScreen* current_screen = this->screen(); + if (current_screen) + { + screen_number = QApplication::screens().indexOf(current_screen); + if (screen_number < 0) + screen_number = 0; + } +#endif // QT_VERSION < QT_VERSION_CHECK(5, 15, 0) + restoreGeometry(initial_geometry_); restoreState(initial_state_); move(QGuiApplication::screens().at(screen_number)->availableGeometry().center() - rect().center()); @@ -595,7 +615,7 @@ void EcalRecGui::updateActivateActionAndAdvancedMenu() ui_.action_activate->setToolTip(tr("Activate clients and start pre-buffering")); activate_action_state_is_activate_ = true; -#ifdef WIN32 +#if (defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) taskbar_activate_button_->setIcon(taskbar_activate_icon_); taskbar_activate_button_->setToolTip(tr("Activate / Prepare")); #endif // WIN32 @@ -608,7 +628,7 @@ void EcalRecGui::updateActivateActionAndAdvancedMenu() ui_.action_activate->setToolTip(tr("De-activate clients and stop pre-buffering")); activate_action_state_is_activate_ = false; -#ifdef WIN32 +#if (defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) taskbar_activate_button_->setIcon(taskbar_deactivate_icon_); taskbar_activate_button_->setToolTip(tr("De-activate")); #endif // WIN32 @@ -656,7 +676,7 @@ void EcalRecGui::updateRecordAction() ui_.action_start_recording->setEnabled(true); record_action_state_is_record_ = false; -#ifdef WIN32 +#if (defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) taskbar_record_button_->setIcon(QIcon(":/ecalicons/TASKBAR_STOP")); taskbar_record_button_->setToolTip(tr("Stop recording")); taskbar_record_button_->setEnabled(true); @@ -671,7 +691,7 @@ void EcalRecGui::updateRecordAction() ui_.action_start_recording->setToolTip(tr("Start recording")); record_action_state_is_record_ = true; -#ifdef WIN32 +#if (defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) taskbar_record_button_->setIcon(QIcon(":/ecalicons/TASKBAR_RECORD")); taskbar_record_button_->setToolTip(tr("Start recording")); #endif // WIN32 @@ -679,7 +699,7 @@ void EcalRecGui::updateRecordAction() bool enabled = (QEcalRec::instance()->enabledRecClients().size() > 0); ui_.action_start_recording->setEnabled(enabled); -#ifdef WIN32 +#if (defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) taskbar_record_button_->setEnabled(enabled); taskbar_record_button_->setIcon(enabled ? taskbar_record_icon_ : taskbar_record_icon_disabled_); #endif // WIN32 @@ -694,7 +714,7 @@ void EcalRecGui::updateSaveBufferAction() && QEcalRec::instance()->enabledRecClients().size() > 0); ui_.action_save_pre_buffer->setEnabled(enabled); -#ifdef WIN32 +#if (defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) taskbar_save_buffer_button_->setEnabled(enabled); taskbar_save_buffer_button_->setIcon(enabled ? taskbar_save_buffer_icon_ : taskbar_save_buffer_icon_disabled_); #endif // WIN32 @@ -1112,12 +1132,6 @@ void EcalRecGui::showUploadSettingsDialog() //////////////////////////////////////////// // Windows specific //////////////////////////////////////////// -void EcalRecGui::registerTaskbarButtons() -{ - taskbar_button_ ->setWindow(this->windowHandle()); - thumbnail_toolbar_->setWindow(this->windowHandle()); -} - void EcalRecGui::showConsole(bool show) { if (show) @@ -1147,6 +1161,18 @@ void EcalRecGui::showConsole(bool show) ui_.action_debug_console->setChecked(GetConsoleWindow()); ui_.action_debug_console->blockSignals(false); } +#endif + +#if (defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) +//////////////////////////////////////////// +// Windows taskbar +//////////////////////////////////////////// + +void EcalRecGui::registerTaskbarButtons() +{ + taskbar_button_ ->setWindow(this->windowHandle()); + thumbnail_toolbar_->setWindow(this->windowHandle()); +} void EcalRecGui::updateTaskbarButton(const eCAL::rec_server::RecorderStatusMap_T& recorder_statuses) { @@ -1188,4 +1214,4 @@ void EcalRecGui::updateTaskbarButton(const eCAL::rec_server::RecorderStatusMap_T } } -#endif // WIN32 +#endif diff --git a/app/rec/rec_gui/src/ecalrec_gui.h b/app/rec/rec_gui/src/ecalrec_gui.h index bd0b358d4d..c0edc49a9b 100644 --- a/app/rec/rec_gui/src/ecalrec_gui.h +++ b/app/rec/rec_gui/src/ecalrec_gui.h @@ -31,12 +31,12 @@ #include -#ifdef WIN32 +#if (defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) #include #include #include #include -#endif // WIN32 +#endif class EcalRecGui : public QMainWindow { @@ -146,15 +146,15 @@ private slots: QStyle* initial_style_; QString initial_style_sheet_; -#ifdef WIN32 + +#if (defined WIN32) && (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) //////////////////////////////////////////// -// Windows specific +// Windows taskbar //////////////////////////////////////////// private: void registerTaskbarButtons(); private slots: - void showConsole(bool show); void updateTaskbarButton(const eCAL::rec_server::RecorderStatusMap_T& recorder_statuses); private: @@ -172,5 +172,13 @@ private slots: QIcon taskbar_save_buffer_icon_; QIcon taskbar_save_buffer_icon_disabled_; +#endif + +#ifdef WIN32 +//////////////////////////////////////////// +// Windows specific +//////////////////////////////////////////// +private slots: + void showConsole(bool show); #endif // WIN32 }; diff --git a/app/rec/rec_gui/src/widgets/config_widget/config_widget.cpp b/app/rec/rec_gui/src/widgets/config_widget/config_widget.cpp index 5cff17a768..6778b14d26 100644 --- a/app/rec/rec_gui/src/widgets/config_widget/config_widget.cpp +++ b/app/rec/rec_gui/src/widgets/config_widget/config_widget.cpp @@ -144,7 +144,7 @@ void ConfigWidget::userRecPathButtonPressed() if (root.exists() && !parsed_meas_root.isEmpty()) { - if (parsed_meas_root[parsed_meas_root.size() - 1] != "\\" && parsed_meas_root[parsed_meas_root.size() - 1] != "/") + if (parsed_meas_root[parsed_meas_root.size() - 1] != '\\' && parsed_meas_root[parsed_meas_root.size() - 1] != '/') root_path = parsed_meas_root + "/"; else root_path = parsed_meas_root; diff --git a/app/rec/rec_gui/src/widgets/recordermanager_widget/recorder_model.cpp b/app/rec/rec_gui/src/widgets/recordermanager_widget/recorder_model.cpp index af959a1bcb..99018269a5 100644 --- a/app/rec/rec_gui/src/widgets/recordermanager_widget/recorder_model.cpp +++ b/app/rec/rec_gui/src/widgets/recordermanager_widget/recorder_model.cpp @@ -21,7 +21,11 @@ #include #include -#include + +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) + #include +#endif // QT_VERSION < QT_VERSION_CHECK(5, 15, 0) + #include #include #include @@ -101,7 +105,7 @@ RecorderModel::~RecorderModel() QVariant RecorderModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) - return QVariant::Invalid; + return QVariant(); // Invalid QVariant const int row = index.row(); const Columns column = (Columns)index.column(); @@ -583,7 +587,7 @@ QVariant RecorderModel::data(const QModelIndex &index, int role) const return data(index, Qt::ItemDataRole::DisplayRole); } - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } bool RecorderModel::setData(const QModelIndex &index, const QVariant &value, int role) @@ -720,7 +724,7 @@ QVariant RecorderModel::headerData(int section, Qt::Orientation orientation, int { return column_labels_.at((Columns)section); } - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } QModelIndex RecorderModel::index(int row, int column, const QModelIndex& /*parent*/) const diff --git a/app/rec/rec_gui/src/widgets/recording_history_widget/job_history_model.cpp b/app/rec/rec_gui/src/widgets/recording_history_widget/job_history_model.cpp index 847989f8d4..006c496bed 100644 --- a/app/rec/rec_gui/src/widgets/recording_history_widget/job_history_model.cpp +++ b/app/rec/rec_gui/src/widgets/recording_history_widget/job_history_model.cpp @@ -50,7 +50,7 @@ QVariant JobHistoryModel::headerData(int section, Qt::Orientation orientation, i { return column_labels_.at((Columns)section); } - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } int JobHistoryModel::columnCount(const QModelIndex &/*parent*/) const diff --git a/app/rec/rec_gui/src/widgets/topic_widget/topic_list_model.cpp b/app/rec/rec_gui/src/widgets/topic_widget/topic_list_model.cpp index ce9824f558..073f66b24e 100644 --- a/app/rec/rec_gui/src/widgets/topic_widget/topic_list_model.cpp +++ b/app/rec/rec_gui/src/widgets/topic_widget/topic_list_model.cpp @@ -40,7 +40,7 @@ TopicListModel::~TopicListModel() QVariant TopicListModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) - return QVariant::Invalid; + return QVariant(); // Invalid QVariant const int row = index.row(); const Columns column = (Columns)index.column(); @@ -208,7 +208,7 @@ QVariant TopicListModel::data(const QModelIndex &index, int role) const // Fallback to the display role return data(index, Qt::ItemDataRole::DisplayRole); } - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } QVariant TopicListModel::headerData(int section, Qt::Orientation orientation, int role) const @@ -218,7 +218,7 @@ QVariant TopicListModel::headerData(int section, Qt::Orientation orientation, in { return column_labels_.at((Columns)section); } - return QVariant::Invalid; + return QVariant(); // Invalid QVariant } QModelIndex TopicListModel::index(int row, int column, const QModelIndex& /*parent*/) const From 7e31dd25edeff2c02f932cb7319e531d0acbe584 Mon Sep 17 00:00:00 2001 From: Florian Reimold <11774314+FlorianReimold@users.noreply.github.com> Date: Wed, 17 Jan 2024 12:23:07 +0100 Subject: [PATCH 10/20] Samples now compile with Qt6 --- CMakeLists.txt | 4 +- samples/CMakeLists.txt | 8 +-- .../ecalplayer_gui_client/CMakeLists.txt | 53 ++++++++++++++---- .../rec_client_service_gui/CMakeLists.txt | 55 ++++++++++++++---- .../rec_server_service_gui/CMakeLists.txt | 56 +++++++++++++++---- 5 files changed, 135 insertions(+), 41 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6eca86331e..65e8a38cbb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -343,7 +343,7 @@ endif() # -------------------------------------------------------- if(HAS_QT5 OR HAS_QT6) add_subdirectory(app/mon/mon_plugin_lib) -endif(HAS_QT5) +endif() # -------------------------------------------------------- # ecal rec addon sdk @@ -483,7 +483,7 @@ if(BUILD_ECAL_TESTS) # ------------------------------------------------------ # test apps # ------------------------------------------------------ - if (HAS_HDF5 AND HAS_QT5) + if (HAS_HDF5 AND HAS_QT5 OR HAS_QT6) add_subdirectory(app/rec/rec_tests/rec_rpc_tests) endif() endif() diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 9a67fc8058..8a01458d7b 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -115,9 +115,9 @@ add_subdirectory(cpp/pubsub/string/minimal_snd) # services add_subdirectory(cpp/services/ecalplayer_client) -if(HAS_QT5) +if(HAS_QT5 OR HAS_QT6) add_subdirectory(cpp/services/ecalplayer_gui_client) -endif(HAS_QT5) +endif() add_subdirectory(cpp/services/ecalsys_client) add_subdirectory(cpp/services/latency_client) add_subdirectory(cpp/services/latency_server) @@ -130,10 +130,10 @@ add_subdirectory(cpp/services/ping_client_dyn) add_subdirectory(cpp/services/ping_server) add_subdirectory(cpp/services/player_stepper) add_subdirectory(cpp/services/rec_client_service_cli) -if(HAS_QT5) +if(HAS_QT5 OR HAS_QT6) add_subdirectory(cpp/services/rec_client_service_gui) add_subdirectory(cpp/services/rec_server_service_gui) -endif(HAS_QT5) +endif() # -------------------------------------------------------- # python samples diff --git a/samples/cpp/services/ecalplayer_gui_client/CMakeLists.txt b/samples/cpp/services/ecalplayer_gui_client/CMakeLists.txt index de06b7a4be..b5bf9141af 100644 --- a/samples/cpp/services/ecalplayer_gui_client/CMakeLists.txt +++ b/samples/cpp/services/ecalplayer_gui_client/CMakeLists.txt @@ -16,17 +16,23 @@ # # ========================= eCAL LICENSE ================================= -cmake_minimum_required(VERSION 3.10) +cmake_minimum_required(VERSION 3.14) + +# Allow the install command to use generator expressions +if(POLICY CMP0087) + cmake_policy(SET CMP0087 NEW) +endif() set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON) project(ecalplayer_gui_client) find_package(eCAL REQUIRED) -find_package(Qt5 COMPONENTS - Core - Widgets -REQUIRED) + +# Legacy Qt5 (pre 5.15) support as suggested by teh Qt Documentation: +# https://doc.qt.io/qt-6/cmake-qt5-and-qt6-compatibility.html#supporting-older-qt-5-versions +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC OFF) # Reason for being turned off: AutoUIC will prevent VS from detecting changes in .ui files @@ -46,8 +52,13 @@ set(ui_files ) # compile qt resource files and ui files -qt5_add_resources(autogen_resources ${qt_resource_files}) -qt5_wrap_ui (autogen_ui ${ui_files}) +if (${QT_VERSION_MAJOR} GREATER_EQUAL 6) + qt_add_resources(autogen_resources ${qt_resource_files}) + qt_wrap_ui (autogen_ui ${ui_files}) +else() + qt5_add_resources(autogen_resources ${qt_resource_files}) + qt5_wrap_ui (autogen_ui ${ui_files}) +endif() ecal_add_sample (${PROJECT_NAME} ${source_files} @@ -70,16 +81,36 @@ target_include_directories(${PROJECT_NAME} PRIVATE src) target_link_libraries(${PROJECT_NAME} eCAL::core eCAL::app_pb - Qt5::Widgets + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets ) target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_14) create_targets_protobuf() -if(WIN32) - # Deploy Qt DLLs in the binary folder. This is necessary for starting the application from whithin the IDE without having to copy QtCore.dll, QtWidgets.dll etc. by hand each time - qt_add_windeployqt_postbuild(--no-system-d3d-compiler --no-compiler-runtime --no-opengl-sw --pdb "$") +if ((WIN32 OR APPLE) AND (${QT_VERSION_MAJOR} GREATER_EQUAL 6)) + + # Generate a script that will deploy all necessary Qt DLLs to the binary folder + # https://doc.qt.io/qt-6/qt-deploy-runtime-dependencies.html + # Available for Qt 6.3 and up (=> Not for Qt5!) + # Executing it requires CMake 3.14 and up, due to policy https://cmake.org/cmake/help/latest/policy/CMP0087.html + qt_generate_deploy_app_script( + TARGET ${PROJECT_NAME} + OUTPUT_SCRIPT qt_deploy_script + NO_COMPILER_RUNTIME + NO_UNSUPPORTED_PLATFORM_ERROR + ) + + # Add a postbuild script that will also execute the created script via cmake -P + # This is necessary to make the application startable / debuggable from the build directory. + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -DQT_DEPLOY_PREFIX=$ -DQT_DEPLOY_BIN_DIR=. -P ${qt_deploy_script} + ) + + # Use the script for deploying the qt dlls in the install dir + install(SCRIPT ${qt_deploy_script}) + endif() if(MSVC) diff --git a/samples/cpp/services/rec_client_service_gui/CMakeLists.txt b/samples/cpp/services/rec_client_service_gui/CMakeLists.txt index 4f55604db0..c68c8d43d9 100644 --- a/samples/cpp/services/rec_client_service_gui/CMakeLists.txt +++ b/samples/cpp/services/rec_client_service_gui/CMakeLists.txt @@ -16,17 +16,23 @@ # # ========================= eCAL LICENSE ================================= -cmake_minimum_required(VERSION 3.10) +cmake_minimum_required(VERSION 3.14) + +# Allow the install command to use generator expressions +if(POLICY CMP0087) + cmake_policy(SET CMP0087 NEW) +endif() set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON) project(rec_client_service_gui) find_package(eCAL REQUIRED) -find_package(Qt5 COMPONENTS - Core - Widgets -REQUIRED) + +# Legacy Qt5 (pre 5.15) support as suggested by teh Qt Documentation: +# https://doc.qt.io/qt-6/cmake-qt5-and-qt6-compatibility.html#supporting-older-qt-5-versions +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC OFF) # Reason for being turned off: AutoUIC will prevent VS from detecting changes in .ui files @@ -46,8 +52,13 @@ set(ui_files ) # compile qt resource files and ui files -qt5_add_resources(autogen_resources ${qt_resource_files}) -qt5_wrap_ui (autogen_ui ${ui_files}) +if (${QT_VERSION_MAJOR} GREATER_EQUAL 6) + qt_add_resources(autogen_resources ${qt_resource_files}) + qt_wrap_ui (autogen_ui ${ui_files}) +else() + qt5_add_resources(autogen_resources ${qt_resource_files}) + qt5_wrap_ui (autogen_ui ${ui_files}) +endif() ecal_add_sample (${PROJECT_NAME} ${source_files} @@ -69,17 +80,37 @@ target_include_directories(${PROJECT_NAME} PRIVATE src) target_link_libraries(${PROJECT_NAME} eCAL::core eCAL::app_pb - Qt5::Widgets + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets ) target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_14) create_targets_protobuf() -if(WIN32) - # Deploy Qt DLLs in the binary folder. This is necessary for starting the application from whithin the IDE without having to copy QtCore.dll, QtWidgets.dll etc. by hand each time - qt_add_windeployqt_postbuild(--no-system-d3d-compiler --no-compiler-runtime --no-opengl-sw --pdb "$") -endif(WIN32) +if ((WIN32 OR APPLE) AND (${QT_VERSION_MAJOR} GREATER_EQUAL 6)) + + # Generate a script that will deploy all necessary Qt DLLs to the binary folder + # https://doc.qt.io/qt-6/qt-deploy-runtime-dependencies.html + # Available for Qt 6.3 and up (=> Not for Qt5!) + # Executing it requires CMake 3.14 and up, due to policy https://cmake.org/cmake/help/latest/policy/CMP0087.html + qt_generate_deploy_app_script( + TARGET ${PROJECT_NAME} + OUTPUT_SCRIPT qt_deploy_script + NO_COMPILER_RUNTIME + NO_UNSUPPORTED_PLATFORM_ERROR + ) + + # Add a postbuild script that will also execute the created script via cmake -P + # This is necessary to make the application startable / debuggable from the build directory. + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -DQT_DEPLOY_PREFIX=$ -DQT_DEPLOY_BIN_DIR=. -P ${qt_deploy_script} + ) + + # Use the script for deploying the qt dlls in the install dir + install(SCRIPT ${qt_deploy_script}) + +endif() if(MSVC) set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "/wd4127 /wd4714") diff --git a/samples/cpp/services/rec_server_service_gui/CMakeLists.txt b/samples/cpp/services/rec_server_service_gui/CMakeLists.txt index 5519e9c117..47b5604ca4 100644 --- a/samples/cpp/services/rec_server_service_gui/CMakeLists.txt +++ b/samples/cpp/services/rec_server_service_gui/CMakeLists.txt @@ -16,17 +16,23 @@ # # ========================= eCAL LICENSE ================================= -cmake_minimum_required(VERSION 3.10) +cmake_minimum_required(VERSION 3.14) + +# Allow the install command to use generator expressions +if(POLICY CMP0087) + cmake_policy(SET CMP0087 NEW) +endif() set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON) project(rec_server_service_gui) find_package(eCAL REQUIRED) -find_package(Qt5 COMPONENTS - Core - Widgets -REQUIRED) + +# Legacy Qt5 (pre 5.15) support as suggested by teh Qt Documentation: +# https://doc.qt.io/qt-6/cmake-qt5-and-qt6-compatibility.html#supporting-older-qt-5-versions +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC OFF) # Reason for being turned off: AutoUIC will prevent VS from detecting changes in .ui files @@ -46,8 +52,14 @@ set(ui_files ) # compile qt resource files and ui files -qt5_add_resources(autogen_resources ${qt_resource_files}) -qt5_wrap_ui (autogen_ui ${ui_files}) +if (${QT_VERSION_MAJOR} GREATER_EQUAL 6) + qt_add_resources(autogen_resources ${qt_resource_files}) + qt_wrap_ui (autogen_ui ${ui_files}) +else() + qt5_add_resources(autogen_resources ${qt_resource_files}) + qt5_wrap_ui (autogen_ui ${ui_files}) +endif() + ecal_add_sample (${PROJECT_NAME} ${source_files} @@ -72,17 +84,37 @@ target_link_libraries(${PROJECT_NAME} eCAL::core eCAL::core_pb eCAL::app_pb - Qt5::Widgets + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets ) target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_14) create_targets_protobuf() -if(WIN32) - # Deploy Qt DLLs in the binary folder. This is necessary for starting the application from whithin the IDE without having to copy QtCore.dll, QtWidgets.dll etc. by hand each time - qt_add_windeployqt_postbuild(--no-system-d3d-compiler --no-compiler-runtime --no-opengl-sw --pdb "$") -endif(WIN32) +if ((WIN32 OR APPLE) AND (${QT_VERSION_MAJOR} GREATER_EQUAL 6)) + + # Generate a script that will deploy all necessary Qt DLLs to the binary folder + # https://doc.qt.io/qt-6/qt-deploy-runtime-dependencies.html + # Available for Qt 6.3 and up (=> Not for Qt5!) + # Executing it requires CMake 3.14 and up, due to policy https://cmake.org/cmake/help/latest/policy/CMP0087.html + qt_generate_deploy_app_script( + TARGET ${PROJECT_NAME} + OUTPUT_SCRIPT qt_deploy_script + NO_COMPILER_RUNTIME + NO_UNSUPPORTED_PLATFORM_ERROR + ) + + # Add a postbuild script that will also execute the created script via cmake -P + # This is necessary to make the application startable / debuggable from the build directory. + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -DQT_DEPLOY_PREFIX=$ -DQT_DEPLOY_BIN_DIR=. -P ${qt_deploy_script} + ) + + # Use the script for deploying the qt dlls in the install dir + install(SCRIPT ${qt_deploy_script}) + +endif() # Create a source tree that mirrors the filesystem source_group(TREE "${CMAKE_CURRENT_LIST_DIR}" From f7c5dfdb3c7852112efb4e0015e40277f98e197d Mon Sep 17 00:00:00 2001 From: Florian Reimold <11774314+FlorianReimold@users.noreply.github.com> Date: Wed, 17 Jan 2024 18:12:56 +0100 Subject: [PATCH 11/20] Introduces version-less HAS_QT cmake option --- CMakeLists.txt | 39 +++--- samples/CMakeLists.txt | 4 +- .../cmake_functions/cmake_functions.cmake | 1 - .../cmake_functions/qt/qt_msvc_path.cmake | 119 ------------------ 4 files changed, 18 insertions(+), 145 deletions(-) delete mode 100644 thirdparty/cmakefunctions/cmake_functions/qt/qt_msvc_path.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 65e8a38cbb..f126e0f173 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,8 +69,14 @@ endif() # use it that way cmake .. -DBUILD_APPS=ON -DBUILD_SAMPLES=ON # -------------------------------------------------------- option(HAS_HDF5 "Platform supports HDF5 library" ON) -option(HAS_QT5 "Platform supports Qt 5 library" ON) -option(HAS_QT6 "Platform supports Qt 5 library" OFF) +option(HAS_QT "Platform supports Qt 5 6 library." ON) + +# If the user set the legacy HAS_QT5 option, but didn't set the new HAS_QT option, set it to the value of HAS_QT5 +if(DEFINED HAS_QT5 AND NOT DEFINED HAS_QT) + set(HAS_QT ${HAS_QT5}) + message(WARNING "The option HAS_QT5 is deprecated and may be removed at any time. Please use HAS_QT instead.") +endif() + option(HAS_CURL "Build with CURL (i.e. upload support in the recorder app)" ON) option(HAS_CAPNPROTO "Platform supports Cap'n Proto library" OFF) option(HAS_FLATBUFFERS "Platform supports flatbuffers library" OFF) @@ -113,12 +119,12 @@ if(WIN32) option(ECAL_THIRDPARTY_BUILD_YAML-CPP "Build yaml-cpp with eCAL" ON) option(ECAL_THIRDPARTY_BUILD_CURL "Build CURL with eCAL" ON) option(ECAL_THIRDPARTY_BUILD_HDF5 "Build HDF5 with eCAL" ON) - cmake_dependent_option(ECAL_THIRDPARTY_BUILD_QWT "Build qwt::qwt with eCAL" ON "HAS_QT5 OR HAS_QT6" OFF) + cmake_dependent_option(ECAL_THIRDPARTY_BUILD_QWT "Build qwt::qwt with eCAL" ON "HAS_QT" OFF) else() option(ECAL_THIRDPARTY_BUILD_PROTOBUF "Build protobuf with eCAL" OFF) option(ECAL_THIRDPARTY_BUILD_CURL "Build CURL with eCAL" OFF) option(ECAL_THIRDPARTY_BUILD_HDF5 "Build HDF5 with eCAL" OFF) - cmake_dependent_option(ECAL_THIRDPARTY_BUILD_QWT "Build qwt::qwt with eCAL" OFF "HAS_QT5 OR HAS_QT6" OFF) + cmake_dependent_option(ECAL_THIRDPARTY_BUILD_QWT "Build qwt::qwt with eCAL" OFF "HAS_QT" OFF) option(ECAL_THIRDPARTY_BUILD_YAML-CPP "Build yaml-cpp with eCAL" OFF) endif() @@ -214,19 +220,6 @@ endif() find_package(CMakeFunctions REQUIRED) -# -------------------------------------------------------- -# detect qt library -# -------------------------------------------------------- -if(MSVC) - if (HAS_QT5) - find_package(Qt5 COMPONENTS Core QUIET) - if (NOT "${Qt5_FOUND}") - autodetect_qt5_msvc_dir() - endif() - endif() -endif() - - git_revision_information(DEFAULT ${ECAL_BUILD_VERSION}) set(eCAL_VERSION_MAJOR ${GIT_REVISION_MAJOR}) set(eCAL_VERSION_MINOR ${GIT_REVISION_MINOR}) @@ -330,18 +323,18 @@ add_subdirectory(lib/ThreadingUtils) add_subdirectory(lib/CustomTclap) add_subdirectory(lib/ecal_utils) -if(HAS_QT5 OR HAS_QT6) +if(HAS_QT) add_subdirectory(lib/CustomQt) endif() add_subdirectory(lib/EcalParser) -if(HAS_QT5 OR HAS_QT6) +if(HAS_QT) add_subdirectory(lib/QEcalParser) endif() # -------------------------------------------------------- # ecal mon plugin sdk # -------------------------------------------------------- -if(HAS_QT5 OR HAS_QT6) +if(HAS_QT) add_subdirectory(app/mon/mon_plugin_lib) endif() @@ -423,7 +416,7 @@ endif() # -------------------------------------------------------- # qt applications # -------------------------------------------------------- -if(BUILD_APPS AND (HAS_QT5 OR HAS_QT6)) +if(BUILD_APPS AND (HAS_QT)) add_subdirectory(app/sys/sys_gui) add_subdirectory(app/mon/mon_gui) if(WIN32) @@ -483,7 +476,7 @@ if(BUILD_ECAL_TESTS) # ------------------------------------------------------ # test apps # ------------------------------------------------------ - if (HAS_HDF5 AND HAS_QT5 OR HAS_QT6) + if (HAS_HDF5 AND HAS_QT) add_subdirectory(app/rec/rec_tests/rec_rpc_tests) endif() endif() @@ -554,7 +547,7 @@ message(STATUS "Build Options:") message(STATUS "--------------------------------------------------------------------------------") message(STATUS "CMAKE_EXPORT_COMPILE_COMMANDS : ${CMAKE_EXPORT_COMPILE_COMMANDS}") message(STATUS "HAS_HDF5 : ${HAS_HDF5}") -message(STATUS "HAS_QT5 : ${HAS_QT5}") +message(STATUS "HAS_QT : ${HAS_QT}") message(STATUS "HAS_CURL : ${HAS_CURL}") message(STATUS "HAS_CAPNPROTO : ${HAS_CAPNPROTO}") message(STATUS "HAS_FLATBUFFERS : ${HAS_FLATBUFFERS}") diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 8a01458d7b..ccdfaacff2 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -115,7 +115,7 @@ add_subdirectory(cpp/pubsub/string/minimal_snd) # services add_subdirectory(cpp/services/ecalplayer_client) -if(HAS_QT5 OR HAS_QT6) +if(HAS_QT) add_subdirectory(cpp/services/ecalplayer_gui_client) endif() add_subdirectory(cpp/services/ecalsys_client) @@ -130,7 +130,7 @@ add_subdirectory(cpp/services/ping_client_dyn) add_subdirectory(cpp/services/ping_server) add_subdirectory(cpp/services/player_stepper) add_subdirectory(cpp/services/rec_client_service_cli) -if(HAS_QT5 OR HAS_QT6) +if(HAS_QT) add_subdirectory(cpp/services/rec_client_service_gui) add_subdirectory(cpp/services/rec_server_service_gui) endif() diff --git a/thirdparty/cmakefunctions/cmake_functions/cmake_functions.cmake b/thirdparty/cmakefunctions/cmake_functions/cmake_functions.cmake index 0c3659e5c8..a053b06e66 100644 --- a/thirdparty/cmakefunctions/cmake_functions/cmake_functions.cmake +++ b/thirdparty/cmakefunctions/cmake_functions/cmake_functions.cmake @@ -7,7 +7,6 @@ set (file_list_include if(WIN32) list(APPEND file_list_include - qt/qt_msvc_path.cmake qt/qt_windeployqt.cmake ) endif() diff --git a/thirdparty/cmakefunctions/cmake_functions/qt/qt_msvc_path.cmake b/thirdparty/cmakefunctions/cmake_functions/qt/qt_msvc_path.cmake deleted file mode 100644 index 51494fb814..0000000000 --- a/thirdparty/cmakefunctions/cmake_functions/qt/qt_msvc_path.cmake +++ /dev/null @@ -1,119 +0,0 @@ -# ========================= eCAL LICENSE ================================= -# -# Copyright (C) 2016 - 2019 Continental Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# ========================= eCAL LICENSE ================================= - -macro(autodetect_qt5_msvc_dir) - SET(QT_MISSING True) - # msvc only; mingw will need different logic - IF(MSVC) - message(STATUS "Trying to auto-detect best Qt5 Version") - # look for user-registry pointing to qtcreator - GET_FILENAME_COMPONENT(QTCREATOR_BIN [HKEY_CURRENT_USER\\Software\\Classes\\Applications\\QtProject.QtCreator.pro\\shell\\Open\\Command] DIRECTORY) - # get root path so we can search for 5.3, 5.4, 5.5, etc - STRING(REPLACE "/Tools" ";" QT_BIN "${QTCREATOR_BIN}") - - LIST(GET QT_BIN 0 QT_INSTALL_DIRECTORY) - - # Collect all Qt5 directories - FILE(GLOB QT_VERSION_DIRECTORIES "${QT_INSTALL_DIRECTORY}/5.*") - - # Compute the MSVC Version as year (e.g. 2015, 2017, 2019...) and aim for upwards compatibility - if (MSVC_VERSION LESS 1900) - message(FATAL_ERROR "ERROR: MSVC_VERSION is $MSVC_VERSION, which indicates Visual Studio < 2015. Only Visual Studio 2015 and up are supported.") - endif() - - if (MSVC_VERSION LESS_EQUAL "1909") - set(MSVC_YEAR "2015") - elseif (MSVC_VERSION LESS_EQUAL "1919") - set(MSVC_YEAR "2017") - elseif (MSVC_VERSION LESS_EQUAL "1929") - set(MSVC_YEAR "2019") - elseif (MSVC_VERSION LESS_EQUAL "1939") - set(MSVC_YEAR "2022") - else () # Assume each 2 years a new Visual Studio Version with a range of 10 MSVC_VERSIONs - MATH(EXPR MSVC_YEAR "2022 + ((${MSVC_VERSION} - 1930) / 10) * 2") - endif () - - message(STATUS "Detected Visual Studio ${MSVC_YEAR} (from MSVC_VERSION ${MSVC_VERSION})") - - # Iterate over all Qt Versions and pick the best - set(BEST_QT_DIRECTORY "") - set(BEST_QT_MSVC_YEAR 0) - set(BEST_QT_MAJOR 0) - set(BEST_QT_MINOR 0) - set(BEST_QT_PATCH 0) - - foreach (QT_DIRECTORY ${QT_VERSION_DIRECTORIES}) - # Get last component of path, which is the qt version - get_filename_component(QT_VERSION_STRING "${QT_DIRECTORY}" NAME) - - # Split the string, to get the major, minor and patch - STRING(REPLACE "." ";" QT_VERSION_COMPONENT_LIST "${QT_VERSION_STRING}") - - LIST(GET QT_VERSION_COMPONENT_LIST 0 QT_MAJOR) - LIST(GET QT_VERSION_COMPONENT_LIST 1 QT_MINOR) - LIST(GET QT_VERSION_COMPONENT_LIST 2 QT_PATCH) - - # Check if there is an installation we can use - if (CMAKE_CL_64) - FILE(GLOB QT_MSVC_DIRECTORIES "${QT_DIRECTORY}/msvc20[0-9][0-9]_64") - else () - FILE(GLOB QT_MSVC_DIRECTORIES "${QT_DIRECTORY}/msvc20[0-9][0-9]") - endif() - - # Iterate over all msvc directories and check for the best matching one - foreach (QT_MSVC_DIR ${QT_MSVC_DIRECTORIES}) - STRING(REPLACE "//" "/" QT_MSVC_DIR "${QT_MSVC_DIR}") - get_filename_component(QT_MSVC_DIR_NAME "${QT_MSVC_DIR}" NAME) - - STRING(REPLACE "msvc" "" QT_MSVC_YEAR "${QT_MSVC_DIR_NAME}") - if (CMAKE_CL_64) - STRING(REPLACE "_64" "" QT_MSVC_YEAR "${QT_MSVC_YEAR}") - endif() - - if (("${QT_MSVC_YEAR}" LESS_EQUAL "${MSVC_YEAR}") AND (${QT_MSVC_YEAR} GREATER_EQUAL "2015")) - # At this point we have found a version that should be usable. Let's check if it is better than the last one we found! - message(STATUS "Found Qt5 candidate at ${QT_MSVC_DIR}") - if ( ("${QT_MAJOR}" GREATER "${BEST_QT_MAJOR}") OR - (("${QT_MAJOR}" EQUAL "${BEST_QT_MAJOR}") AND ("${QT_MINOR}" GREATER "${BEST_QT_MINOR}")) OR - (("${QT_MAJOR}" EQUAL "${BEST_QT_MAJOR}") AND ("${QT_MINOR}" EQUAL "${BEST_QT_MINOR}") AND ("${QT_PATCH}" GREATER "${BEST_QT_PATCH}")) OR - (("${QT_MAJOR}" EQUAL "${BEST_QT_MAJOR}") AND ("${QT_MINOR}" EQUAL "${BEST_QT_MINOR}") AND ("${QT_PATCH}" EQUAL "${BEST_QT_PATCH}") AND ("${QT_MSVC_YEAR}" GREATER "${BEST_QT_MSVC_YEAR}")) - ) - - set(BEST_QT_DIRECTORY "${QT_MSVC_DIR}") - set(BEST_QT_MSVC_YEAR "${QT_MSVC_YEAR}") - set(BEST_QT_MAJOR "${QT_MAJOR}") - set(BEST_QT_MINOR "${QT_MINOR}") - set(BEST_QT_PATCH "${QT_PATCH}") - - endif() - - endif() - - endforeach() - endforeach() - - if ("${BEST_QT_DIRECTORY}" STREQUAL "") - message(FATAL_ERROR "ERROR: Unable to find any usable Qt5 installation. Please install Qt5 or manually set the CMAKE_PREFIX_PATH.") - endif() - - message(STATUS "Using Qt ${BEST_QT_MAJOR}.${BEST_QT_MINOR}.${BEST_QT_PATCH} MSVC ${BEST_QT_MSVC_YEAR} from ${BEST_QT_DIRECTORY}") - SET(Qt5_DIR "${BEST_QT_DIRECTORY}/lib/cmake/Qt5/") - SET(Qt5Test_DIR "${BEST_QT_DIRECTORY}/lib/cmake/Qt5Test") - - endif() -endmacro() From 76529404abca573e8871a9a3ce8a322312dc7cb2 Mon Sep 17 00:00:00 2001 From: Florian Reimold <11774314+FlorianReimold@users.noreply.github.com> Date: Wed, 17 Jan 2024 18:17:28 +0100 Subject: [PATCH 12/20] Modified gh actions. the windows gh action should now build with qt6 --- .github/workflows/build-ubuntu-20.yml | 2 +- .github/workflows/build-ubuntu-22.yml | 2 +- .github/workflows/build-windows.yml | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-ubuntu-20.yml b/.github/workflows/build-ubuntu-20.yml index 2a3431e952..f56f5e574e 100644 --- a/.github/workflows/build-ubuntu-20.yml +++ b/.github/workflows/build-ubuntu-20.yml @@ -60,7 +60,7 @@ jobs: cmake $GITHUB_WORKSPACE -G "Ninja" \ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ -DHAS_HDF5=ON \ - -DHAS_QT5=ON \ + -DHAS_QT=ON \ -DHAS_CURL=ON \ -DHAS_CAPNPROTO=ON \ -DHAS_FTXUI=ON \ diff --git a/.github/workflows/build-ubuntu-22.yml b/.github/workflows/build-ubuntu-22.yml index 97eb142087..24b6903dcc 100644 --- a/.github/workflows/build-ubuntu-22.yml +++ b/.github/workflows/build-ubuntu-22.yml @@ -60,7 +60,7 @@ jobs: cmake $GITHUB_WORKSPACE -G "Ninja" \ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ -DHAS_HDF5=ON \ - -DHAS_QT5=ON \ + -DHAS_QT=ON \ -DHAS_CURL=ON \ -DHAS_CAPNPROTO=ON \ -DHAS_FTXUI=ON \ diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index a438226bc2..ba2b72a918 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -22,9 +22,9 @@ jobs: uses: jurplel/install-qt-action@v3 with: setup-python: 'false' - version: '5.15.2' + version: '6.6.1' target: 'desktop' - arch: 'win64_msvc2015_64' + arch: 'win64_msvc2019_64' # Downgrading nuget is required as of 2021-04-23, as nuget 5.9.1.111 fails installing protobuf # https://github.com/actions/virtual-environments/issues/3240 @@ -91,7 +91,7 @@ jobs: cmake %GITHUB_WORKSPACE% -G "Visual Studio 16 2019" -A x64 -T v142 ^ -DHAS_HDF5=ON ^ - -DHAS_QT5=ON ^ + -DHAS_QT=ON ^ -DHAS_CURL=OFF ^ -DHAS_CAPNPROTO=OFF ^ -DHAS_FTXUI=ON ^ @@ -131,7 +131,7 @@ jobs: cd "${{ runner.workspace }}/_build/complete" cmake %GITHUB_WORKSPACE% -G "Visual Studio 16 2019" -A x64 -T v142 ^ -DHAS_HDF5=ON ^ - -DHAS_QT5=ON ^ + -DHAS_QT=ON ^ -DHAS_CURL=ON ^ -DHAS_CAPNPROTO=OFF ^ -DHAS_FTXUI=ON ^ From 1d0e1e5e72f0831819a94862c5354bef65ea8238 Mon Sep 17 00:00:00 2001 From: Florian Reimold <11774314+FlorianReimold@users.noreply.github.com> Date: Thu, 18 Jan 2024 09:32:16 +0100 Subject: [PATCH 13/20] Brought back the qt_msvc_path.cmake script --- CMakeLists.txt | 13 ++ .../cmake_functions/cmake_functions.cmake | 1 + .../cmake_functions/qt/qt_msvc_path.cmake | 119 ++++++++++++++++++ 3 files changed, 133 insertions(+) create mode 100644 thirdparty/cmakefunctions/cmake_functions/qt/qt_msvc_path.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index f126e0f173..2eb945cb06 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -220,6 +220,19 @@ endif() find_package(CMakeFunctions REQUIRED) +# -------------------------------------------------------- +# detect qt library +# -------------------------------------------------------- +if(MSVC) + if (HAS_QT) + find_package(QT NAMES Qt6 Qt5 COMPONENTS Core QUIET) + if (NOT "${QT_FOUND}") + autodetect_qt_msvc_dir() + endif() + endif() +endif() + + git_revision_information(DEFAULT ${ECAL_BUILD_VERSION}) set(eCAL_VERSION_MAJOR ${GIT_REVISION_MAJOR}) set(eCAL_VERSION_MINOR ${GIT_REVISION_MINOR}) diff --git a/thirdparty/cmakefunctions/cmake_functions/cmake_functions.cmake b/thirdparty/cmakefunctions/cmake_functions/cmake_functions.cmake index a053b06e66..0c3659e5c8 100644 --- a/thirdparty/cmakefunctions/cmake_functions/cmake_functions.cmake +++ b/thirdparty/cmakefunctions/cmake_functions/cmake_functions.cmake @@ -7,6 +7,7 @@ set (file_list_include if(WIN32) list(APPEND file_list_include + qt/qt_msvc_path.cmake qt/qt_windeployqt.cmake ) endif() diff --git a/thirdparty/cmakefunctions/cmake_functions/qt/qt_msvc_path.cmake b/thirdparty/cmakefunctions/cmake_functions/qt/qt_msvc_path.cmake new file mode 100644 index 0000000000..3d3db952ad --- /dev/null +++ b/thirdparty/cmakefunctions/cmake_functions/qt/qt_msvc_path.cmake @@ -0,0 +1,119 @@ +# ========================= eCAL LICENSE ================================= +# +# Copyright (C) 2016 - 2019 Continental Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ========================= eCAL LICENSE ================================= + +macro(autodetect_qt_msvc_dir) + SET(QT_MISSING True) + # msvc only; mingw will need different logic + IF(MSVC) + message(STATUS "Trying to auto-detect best Qt Version") + # look for user-registry pointing to qtcreator + GET_FILENAME_COMPONENT(QTCREATOR_BIN [HKEY_CURRENT_USER\\Software\\Classes\\Applications\\QtProject.QtCreator.pro\\shell\\Open\\Command] DIRECTORY) + # get root path so we can search for 5.3, 5.4, 5.5, etc + STRING(REPLACE "/Tools" ";" QT_BIN "${QTCREATOR_BIN}") + + LIST(GET QT_BIN 0 QT_INSTALL_DIRECTORY) + + # Collect all Qt5 and Qt6 directories + FILE(GLOB QT_VERSION_DIRECTORIES "${QT_INSTALL_DIRECTORY}/[5-6].*") + + # Compute the MSVC Version as year (e.g. 2015, 2017, 2019...) and aim for upwards compatibility + if (MSVC_VERSION LESS 1900) + message(FATAL_ERROR "ERROR: MSVC_VERSION is $MSVC_VERSION, which indicates Visual Studio < 2015. Only Visual Studio 2015 and up are supported.") + endif() + + if (MSVC_VERSION LESS_EQUAL "1909") + set(MSVC_YEAR "2015") + elseif (MSVC_VERSION LESS_EQUAL "1919") + set(MSVC_YEAR "2017") + elseif (MSVC_VERSION LESS_EQUAL "1929") + set(MSVC_YEAR "2019") + elseif (MSVC_VERSION LESS_EQUAL "1939") + set(MSVC_YEAR "2022") + else () # Assume each 2 years a new Visual Studio Version with a range of 10 MSVC_VERSIONs + MATH(EXPR MSVC_YEAR "2022 + ((${MSVC_VERSION} - 1930) / 10) * 2") + endif () + + message(STATUS "Detected Visual Studio ${MSVC_YEAR} (from MSVC_VERSION ${MSVC_VERSION})") + + # Iterate over all Qt Versions and pick the best + set(BEST_QT_DIRECTORY "") + set(BEST_QT_MSVC_YEAR 0) + set(BEST_QT_MAJOR 0) + set(BEST_QT_MINOR 0) + set(BEST_QT_PATCH 0) + + foreach (QT_DIRECTORY ${QT_VERSION_DIRECTORIES}) + # Get last component of path, which is the qt version + get_filename_component(QT_VERSION_STRING "${QT_DIRECTORY}" NAME) + + # Split the string, to get the major, minor and patch + STRING(REPLACE "." ";" QT_VERSION_COMPONENT_LIST "${QT_VERSION_STRING}") + + LIST(GET QT_VERSION_COMPONENT_LIST 0 QT_MAJOR) + LIST(GET QT_VERSION_COMPONENT_LIST 1 QT_MINOR) + LIST(GET QT_VERSION_COMPONENT_LIST 2 QT_PATCH) + + # Check if there is an installation we can use + if (CMAKE_CL_64) + FILE(GLOB QT_MSVC_DIRECTORIES "${QT_DIRECTORY}/msvc20[0-9][0-9]_64") + else () + FILE(GLOB QT_MSVC_DIRECTORIES "${QT_DIRECTORY}/msvc20[0-9][0-9]") + endif() + + # Iterate over all msvc directories and check for the best matching one + foreach (QT_MSVC_DIR ${QT_MSVC_DIRECTORIES}) + STRING(REPLACE "//" "/" QT_MSVC_DIR "${QT_MSVC_DIR}") + get_filename_component(QT_MSVC_DIR_NAME "${QT_MSVC_DIR}" NAME) + + STRING(REPLACE "msvc" "" QT_MSVC_YEAR "${QT_MSVC_DIR_NAME}") + if (CMAKE_CL_64) + STRING(REPLACE "_64" "" QT_MSVC_YEAR "${QT_MSVC_YEAR}") + endif() + + if (("${QT_MSVC_YEAR}" LESS_EQUAL "${MSVC_YEAR}") AND (${QT_MSVC_YEAR} GREATER_EQUAL "2015")) + # At this point we have found a version that should be usable. Let's check if it is better than the last one we found! + message(STATUS "Found Qt candidate at ${QT_MSVC_DIR}") + if ( ("${QT_MAJOR}" GREATER "${BEST_QT_MAJOR}") OR + (("${QT_MAJOR}" EQUAL "${BEST_QT_MAJOR}") AND ("${QT_MINOR}" GREATER "${BEST_QT_MINOR}")) OR + (("${QT_MAJOR}" EQUAL "${BEST_QT_MAJOR}") AND ("${QT_MINOR}" EQUAL "${BEST_QT_MINOR}") AND ("${QT_PATCH}" GREATER "${BEST_QT_PATCH}")) OR + (("${QT_MAJOR}" EQUAL "${BEST_QT_MAJOR}") AND ("${QT_MINOR}" EQUAL "${BEST_QT_MINOR}") AND ("${QT_PATCH}" EQUAL "${BEST_QT_PATCH}") AND ("${QT_MSVC_YEAR}" GREATER "${BEST_QT_MSVC_YEAR}")) + ) + + set(BEST_QT_DIRECTORY "${QT_MSVC_DIR}") + set(BEST_QT_MSVC_YEAR "${QT_MSVC_YEAR}") + set(BEST_QT_MAJOR "${QT_MAJOR}") + set(BEST_QT_MINOR "${QT_MINOR}") + set(BEST_QT_PATCH "${QT_PATCH}") + + endif() + + endif() + + endforeach() + endforeach() + + if ("${BEST_QT_DIRECTORY}" STREQUAL "") + message(FATAL_ERROR "ERROR: Unable to find any usable Qt5 or Qt6 installation. Please install Qt or manually set the CMAKE_PREFIX_PATH.") + endif() + + message(STATUS "Using Qt ${BEST_QT_MAJOR}.${BEST_QT_MINOR}.${BEST_QT_PATCH} MSVC ${BEST_QT_MSVC_YEAR} from ${BEST_QT_DIRECTORY}") + SET(Qt${BEST_QT_MAJOR}_DIR "${BEST_QT_DIRECTORY}/lib/cmake/Qt${BEST_QT_MAJOR}/") + SET(Qt${BEST_QT_MAJOR}Test_DIR "${BEST_QT_DIRECTORY}/lib/cmake/Qt${BEST_QT_MAJOR}Test") + + endif() +endmacro() From 348def2b107d89279eb9263adba41571cc0ef38e Mon Sep 17 00:00:00 2001 From: Florian Reimold <11774314+FlorianReimold@users.noreply.github.com> Date: Thu, 18 Jan 2024 18:21:30 +0100 Subject: [PATCH 14/20] Fixed Qt6 deprecation warnings --- .../src/widgets/models/topic_tree_item.cpp | 4 ++++ .../src/monitor_tree_item.cpp | 10 ++++++++- .../mon_plugins/monitor_tree_view/src/util.h | 4 ++++ .../raw_data_reflection/src/plugin_widget.cpp | 8 ++++++- .../signals_plotting/src/signal_tree_item.cpp | 22 ++++++++++++++++++- .../src/signal_tree_model.cpp | 4 ++++ app/util/launcher/src/main_window.cpp | 8 +++++++ 7 files changed, 57 insertions(+), 3 deletions(-) diff --git a/app/mon/mon_gui/src/widgets/models/topic_tree_item.cpp b/app/mon/mon_gui/src/widgets/models/topic_tree_item.cpp index 46d215f160..7b41c1fe04 100644 --- a/app/mon/mon_gui/src/widgets/models/topic_tree_item.cpp +++ b/app/mon/mon_gui/src/widgets/models/topic_tree_item.cpp @@ -213,7 +213,11 @@ QVariant TopicTreeItem::data(Columns column, Qt::ItemDataRole role) const if (!raw_data.empty()) { +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) const quint16 crc16 = qChecksum(raw_data.data(), static_cast(raw_data.length())); +#else + const quint16 crc16 = qChecksum(raw_data); +#endif const QString crc16_string = QString("%1").arg(QString::number(crc16, 16).toUpper(), 4, '0'); const QString size_text = QString::number(raw_data.size()) + " byte" + (raw_data.size() != 1 ? "s" : "") diff --git a/app/mon/mon_plugins/monitor_tree_view/src/monitor_tree_item.cpp b/app/mon/mon_plugins/monitor_tree_view/src/monitor_tree_item.cpp index e8a4f3e1b2..2e063a0b4d 100644 --- a/app/mon/mon_plugins/monitor_tree_view/src/monitor_tree_item.cpp +++ b/app/mon/mon_plugins/monitor_tree_view/src/monitor_tree_item.cpp @@ -98,7 +98,7 @@ QByteArray asByteArrayBlob(const QByteArray& bytes) QString asChecksum(const QByteArray& bytes) { #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - quint16 crc16 = qChecksum(QByteArrayView(bytes)); + quint16 crc16 = qChecksum(bytes); #else quint16 crc16 = qChecksum(bytes.data(), (uint)bytes.length()); #endif @@ -262,7 +262,11 @@ void MonitorTreeItem::setAccessed(bool accessed) QVariant MonitorTreeItem::getDisplayValue() const { +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) if (data_.type() == QVariant::Type::ByteArray) +#else + if (data_.typeId() == QMetaType::QByteArray) +#endif { //TODO QByteArray bytes = data_.toByteArray(); @@ -275,7 +279,11 @@ QVariant MonitorTreeItem::getDisplayValue() const return asChecksum(bytes); } } +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) else if (data_.userType() == QMetaType::type("StringEnum")) +#else + else if (data_.metaType() == QMetaType::fromName("StringEnum")) +#endif { StringEnum string_enum = data_.value(); return string_enum.name + "(" + QString::number(string_enum.value) + ")"; diff --git a/app/mon/mon_plugins/monitor_tree_view/src/util.h b/app/mon/mon_plugins/monitor_tree_view/src/util.h index ce4f3467fb..08c10b2187 100644 --- a/app/mon/mon_plugins/monitor_tree_view/src/util.h +++ b/app/mon/mon_plugins/monitor_tree_view/src/util.h @@ -28,7 +28,11 @@ namespace QtUtil { inline QString variantToString(const QVariant& variant) { +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + switch (variant.typeId()) +#else switch ((QMetaType::Type)variant.type()) +#endif { case QMetaType::Bool: return variant.toBool() ? "True" : "False"; diff --git a/app/mon/mon_plugins/raw_data_reflection/src/plugin_widget.cpp b/app/mon/mon_plugins/raw_data_reflection/src/plugin_widget.cpp index b3f5bc851b..63df66a162 100644 --- a/app/mon/mon_plugins/raw_data_reflection/src/plugin_widget.cpp +++ b/app/mon/mon_plugins/raw_data_reflection/src/plugin_widget.cpp @@ -140,7 +140,13 @@ void PluginWidget::updateRawMessageView() { std::lock_guard message_lock(message_mutex_); - quint16 crc16 = qChecksum(last_message_.data(), last_message_.length()); + +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + const quint16 crc16 = qChecksum(last_message_.data(), last_message_.length()); +#else + const quint16 crc16 = qChecksum(last_message_); +#endif + QString crc16_string = QString("%1").arg(QString::number(crc16, 16).toUpper(), 4, '0'); QString size_text = tr("Binary data of ") + QString::number(last_message_.size()) + tr(" bytes (CRC16: ") + crc16_string + ")"; diff --git a/app/mon/mon_plugins/signals_plotting/src/signal_tree_item.cpp b/app/mon/mon_plugins/signals_plotting/src/signal_tree_item.cpp index a55b05ab47..4a9698f3c9 100644 --- a/app/mon/mon_plugins/signals_plotting/src/signal_tree_item.cpp +++ b/app/mon/mon_plugins/signals_plotting/src/signal_tree_item.cpp @@ -90,7 +90,11 @@ QByteArray asByteArrayBlob(const QByteArray& bytes) // Return crc16 checksum of the byte Array QString asChecksum(const QByteArray& bytes) { - quint16 crc16 = qChecksum(bytes.data(), (uint)bytes.length()); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + const quint16 crc16 = qChecksum(bytes.data(), (uint)bytes.length()); +#else + const quint16 crc16 = qChecksum(bytes); +#endif return QString("%1").arg(QString::number(crc16, 16).toUpper(), 4, '0'); } @@ -161,11 +165,19 @@ Qt::ItemFlags SignalTreeItem::flags(int column) const case (int)Columns::SINGLE: if (data_.isValid()) { +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) if (data_.userType() == QMetaType::type("StringEnum")) +#else + if (data_.metaType() == QMetaType::fromName("StringEnum")) +#endif { return check_flags; } +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) switch ((QMetaType::Type)data_.type()) +#else + switch (data_.typeId()) +#endif { case QMetaType::Int: case QMetaType::UInt: @@ -322,12 +334,20 @@ void SignalTreeItem::setAccessed(bool accessed) QVariant SignalTreeItem::getDisplayValue() const { +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) if (data_.type() == QVariant::Type::ByteArray) +#else + if (data_.typeId() == QMetaType::QByteArray) +#endif { QByteArray bytes = data_.toByteArray(); return asChecksum(bytes); } +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) else if (data_.userType() == QMetaType::type("StringEnum")) +#else + else if (data_.metaType() == QMetaType::fromName("StringEnum")) +#endif { StringEnum string_enum = data_.value(); return string_enum.name + "(" + QString::number(string_enum.value) + ")"; diff --git a/app/mon/mon_plugins/signals_plotting/src/signal_tree_model.cpp b/app/mon/mon_plugins/signals_plotting/src/signal_tree_model.cpp index 523ae596aa..16772875c0 100644 --- a/app/mon/mon_plugins/signals_plotting/src/signal_tree_model.cpp +++ b/app/mon/mon_plugins/signals_plotting/src/signal_tree_model.cpp @@ -166,7 +166,11 @@ void SignalTreeModel::removeItemChecked(const QString& full_signal_name, int mod void SignalTreeModel::slt_itemValueChanged(SignalTreeItem* item) { QString item_value; +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) if (item->getValue().userType() == QMetaType::type("StringEnum")) +#else + if (item->getValue().metaType() == QMetaType::fromName("StringEnum")) +#endif { StringEnum string_enum = item->getValue().value(); item_value = QString::number(string_enum.value); diff --git a/app/util/launcher/src/main_window.cpp b/app/util/launcher/src/main_window.cpp index e70cad1f48..93099ceb5e 100644 --- a/app/util/launcher/src/main_window.cpp +++ b/app/util/launcher/src/main_window.cpp @@ -59,7 +59,11 @@ bool MainWindow::eventFilter(QObject *watched, QEvent *event) if (mouse_event == nullptr) return false; if (mouse_event->button() == Qt::LeftButton) { +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) _dragPosition = mouse_event->globalPos() - frameGeometry().topLeft(); +#else + _dragPosition = mouse_event->globalPosition().toPoint() - frameGeometry().topLeft(); +#endif return false; } } @@ -69,7 +73,11 @@ bool MainWindow::eventFilter(QObject *watched, QEvent *event) if (mouse_event == nullptr) return false; if (mouse_event->buttons() & Qt::LeftButton) { +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) move(mouse_event->globalPos() - _dragPosition); +#else + move(mouse_event->globalPosition().toPoint() - _dragPosition); +#endif return false; } } From c08bb312b62a436b27e8f79364682f06ee3da4fa Mon Sep 17 00:00:00 2001 From: Florian Reimold <11774314+FlorianReimold@users.noreply.github.com> Date: Fri, 19 Jan 2024 08:57:23 +0100 Subject: [PATCH 15/20] Fixed Mon exclude regular expression --- .../src/widgets/ecalmon_tree_widget/topic_widget.cpp | 6 +++--- .../src/widgets/models/topic_sort_filter_proxy_model.cpp | 7 +++---- .../src/widgets/models/topic_sort_filter_proxy_model.h | 2 +- doc/rst/configuration/options.rst | 2 +- ecal/core/cfg/ecal.ini | 4 ++-- ecal/core/src/ecal_def.h | 2 +- 6 files changed, 11 insertions(+), 12 deletions(-) diff --git a/app/mon/mon_gui/src/widgets/ecalmon_tree_widget/topic_widget.cpp b/app/mon/mon_gui/src/widgets/ecalmon_tree_widget/topic_widget.cpp index 22029711ee..4aa8d25ec5 100644 --- a/app/mon/mon_gui/src/widgets/ecalmon_tree_widget/topic_widget.cpp +++ b/app/mon/mon_gui/src/widgets/ecalmon_tree_widget/topic_widget.cpp @@ -54,7 +54,7 @@ TopicWidget::TopicWidget(QWidget *parent) topic_sort_filter_proxy_model_->setSortRole(ItemDataRoles::SortRole); topic_sort_filter_proxy_model_->setFilterKeyColumn((int)TopicTreeModel::Columns::TOPIC_NAME); topic_sort_filter_proxy_model_->setRecursiveFilteringEnabled(true); - topic_sort_filter_proxy_model_->setRegExpLists(topic_exclude_regexp_list_, topic_include_regexp_list_); + topic_sort_filter_proxy_model_->setRegularExpressionLists(topic_exclude_regexp_list_, topic_include_regexp_list_); topic_sort_filter_proxy_model_->setSortCaseSensitivity(Qt::CaseSensitivity::CaseInsensitive); setAdditionalProxyModel(topic_sort_filter_proxy_model_); @@ -63,11 +63,11 @@ TopicWidget::TopicWidget(QWidget *parent) { if (state == Qt::CheckState::Checked) { - topic_sort_filter_proxy_model_->setRegExpLists(QList{}, QList{}); + topic_sort_filter_proxy_model_->setRegularExpressionLists(QList{}, QList{}); } else { - topic_sort_filter_proxy_model_->setRegExpLists(topic_exclude_regexp_list_, topic_include_regexp_list_); + topic_sort_filter_proxy_model_->setRegularExpressionLists(topic_exclude_regexp_list_, topic_include_regexp_list_); } }); diff --git a/app/mon/mon_gui/src/widgets/models/topic_sort_filter_proxy_model.cpp b/app/mon/mon_gui/src/widgets/models/topic_sort_filter_proxy_model.cpp index 1e7e288db4..b18b992d33 100644 --- a/app/mon/mon_gui/src/widgets/models/topic_sort_filter_proxy_model.cpp +++ b/app/mon/mon_gui/src/widgets/models/topic_sort_filter_proxy_model.cpp @@ -33,7 +33,7 @@ TopicSortFilterProxyModel::TopicSortFilterProxyModel(QObject* parent) TopicSortFilterProxyModel::~TopicSortFilterProxyModel() {} -void TopicSortFilterProxyModel::setRegExpLists(const QList& exclude_list, const QList& include_list) +void TopicSortFilterProxyModel::setRegularExpressionLists(const QList& exclude_list, const QList& include_list) { exclude_regexp_list_ = exclude_list; include_regexp_list_ = include_list; @@ -56,10 +56,9 @@ bool TopicSortFilterProxyModel::filterDirectAcceptsRow(int source_row, const QMo return false; } - for (const QRegularExpression& regexp : exclude_regexp_list_) { - if (regexp.match(data).hasMatch()) // TODO: [2024-01-15] This was QRegExp::exactMatch() before, but QRegularExpression::exactMatch() does not exist. I don't know what this function is used for. + if (regexp.match(data).hasMatch()) { return false; } @@ -73,7 +72,7 @@ bool TopicSortFilterProxyModel::filterDirectAcceptsRow(int source_row, const QMo { for (const QRegularExpression& regexp : include_regexp_list_) { - if (regexp.match(data).hasMatch()) // TODO: [2024-01-15] This was QRegExp::exactMatch() before, but QRegularExpression::exactMatch() does not exist. I don't know what this function is used for. + if (regexp.match(data).hasMatch()) { return true; } diff --git a/app/mon/mon_gui/src/widgets/models/topic_sort_filter_proxy_model.h b/app/mon/mon_gui/src/widgets/models/topic_sort_filter_proxy_model.h index 02757d62e9..d0b353079b 100644 --- a/app/mon/mon_gui/src/widgets/models/topic_sort_filter_proxy_model.h +++ b/app/mon/mon_gui/src/widgets/models/topic_sort_filter_proxy_model.h @@ -30,7 +30,7 @@ class TopicSortFilterProxyModel : TopicSortFilterProxyModel(QObject* parent = 0); ~TopicSortFilterProxyModel(); - void setRegExpLists(const QList& exclude_list, const QList& include_list); + void setRegularExpressionLists(const QList& exclude_list, const QList& include_list); private: QList exclude_regexp_list_; diff --git a/doc/rst/configuration/options.rst b/doc/rst/configuration/options.rst index 68481d21b7..dfb49e97c7 100644 --- a/doc/rst/configuration/options.rst +++ b/doc/rst/configuration/options.rst @@ -274,7 +274,7 @@ Monitor settings are listed in the section ``monitoring`` topics blacklist as regular expression (will not be monitored) Per default includes all eCAL internal topics. - default = ``__.*`` + default = ``^__.*$`` .. option:: filter_incl diff --git a/ecal/core/cfg/ecal.ini b/ecal/core/cfg/ecal.ini index ae17840c4e..2a3b42304c 100644 --- a/ecal/core/cfg/ecal.ini +++ b/ecal/core/cfg/ecal.ini @@ -158,7 +158,7 @@ protocol_v1 = 1 ; MONITORING SETTINGS ; -------------------------------------------------- ; timeout = 1000 + (x * 1000) Timeout for topic monitoring in ms -; filter_excl = __.* Topics blacklist as regular expression (will not be monitored) +; filter_excl = ^__.*$ Topics blacklist as regular expression (will not be monitored) ; filter_incl = Topics whitelist as regular expression (will be monitored only) ; filter_log_con = info, warning, error, fatal Log messages logged to console (all, info, warning, error, fatal, debug1, debug2, debug3, debug4) ; filter_log_file = Log messages to logged into file system @@ -166,7 +166,7 @@ protocol_v1 = 1 ; -------------------------------------------------- [monitoring] timeout = 5000 -filter_excl = __.* +filter_excl = ^__.*$ filter_incl = filter_log_con = info, warning, error, fatal filter_log_file = diff --git a/ecal/core/src/ecal_def.h b/ecal/core/src/ecal_def.h index 5a07639c4a..34e8d00e8e 100644 --- a/ecal/core/src/ecal_def.h +++ b/ecal/core/src/ecal_def.h @@ -43,7 +43,7 @@ /* timeout for automatic removing monitoring topics in ms */ #define MON_TIMEOUT 5000 /* topics blacklist as regular expression (will not be monitored) */ -#define MON_FILTER_EXCL "_.*" +#define MON_FILTER_EXCL "^__.*$" /* topics whitelist as regular expression (will be monitored only) */ #define MON_FILTER_INCL "" From a6888b2551c0bb1c8cd8033282dba3461dde4b85 Mon Sep 17 00:00:00 2001 From: Florian Reimold <11774314+FlorianReimold@users.noreply.github.com> Date: Fri, 19 Jan 2024 09:04:13 +0100 Subject: [PATCH 16/20] Solved a few TODOs --- lib/CustomQt/include/CustomQt/QAdvancedTreeView.h | 3 --- lib/CustomQt/src/QAdvancedTreeView.cpp | 8 +------- lib/EcalParser/src/EcalParser.cpp | 2 +- .../src/ecal_parser_textedit/ecal_parser_textedit.cpp | 3 --- 4 files changed, 2 insertions(+), 14 deletions(-) diff --git a/lib/CustomQt/include/CustomQt/QAdvancedTreeView.h b/lib/CustomQt/include/CustomQt/QAdvancedTreeView.h index 4c6a102b7e..62bf37825e 100644 --- a/lib/CustomQt/include/CustomQt/QAdvancedTreeView.h +++ b/lib/CustomQt/include/CustomQt/QAdvancedTreeView.h @@ -155,9 +155,6 @@ class QAdvancedTreeView : public QTreeView */ bool restoreState(const QByteArray& state, int32_t version = 0); - // TODO: Add again or check why it existed in the first place - //QStyleOptionViewItem viewOptions() const override; - protected: void keyPressEvent(QKeyEvent* key_event) override; diff --git a/lib/CustomQt/src/QAdvancedTreeView.cpp b/lib/CustomQt/src/QAdvancedTreeView.cpp index 9803f19bc3..b1ccad2447 100644 --- a/lib/CustomQt/src/QAdvancedTreeView.cpp +++ b/lib/CustomQt/src/QAdvancedTreeView.cpp @@ -282,10 +282,4 @@ bool QAdvancedTreeView::restoreState(const QByteArray& state, int32_t version) } return true; -} - -// TODO: Add again or check why it existed in the first place -//QStyleOptionViewItem QAdvancedTreeView::viewOptions() const -//{ -// return QTreeView::viewOptions(); -//} \ No newline at end of file +} \ No newline at end of file diff --git a/lib/EcalParser/src/EcalParser.cpp b/lib/EcalParser/src/EcalParser.cpp index d45ab33ebe..c2ba55d837 100644 --- a/lib/EcalParser/src/EcalParser.cpp +++ b/lib/EcalParser/src/EcalParser.cpp @@ -340,7 +340,7 @@ namespace EcalParser { "OS", new EcalParser::FunctionOs() }, { "OSSELECT", new EcalParser::FunctionOsselect() }, { "TIME", new EcalParser::FunctionTime()}, - { "USERNAME", new EcalParser::FunctionUsername()}, + { "USERNAME", new EcalParser::FunctionUsername()}, }; return functions; diff --git a/lib/QEcalParser/src/ecal_parser_textedit/ecal_parser_textedit.cpp b/lib/QEcalParser/src/ecal_parser_textedit/ecal_parser_textedit.cpp index cda0a11ad7..495949fe32 100644 --- a/lib/QEcalParser/src/ecal_parser_textedit/ecal_parser_textedit.cpp +++ b/lib/QEcalParser/src/ecal_parser_textedit/ecal_parser_textedit.cpp @@ -30,9 +30,6 @@ #include #include -// TODO: REmove -#include - QEcalParserTextEdit::QEcalParserTextEdit(QWidget *parent) : QEcalParserTextEdit("", parent) { From 51e6047360d1ef6b202386fb5f52090980b4c5bc Mon Sep 17 00:00:00 2001 From: Florian Reimold <11774314+FlorianReimold@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:18:57 +0100 Subject: [PATCH 17/20] Improved documentation --- CMakeLists.txt | 2 +- .../development/building_ecal_from_source.rst | 115 ++++++------------ doc/rst/development/ecal_cmake_options.rst | 111 ++++++++++++----- 3 files changed, 118 insertions(+), 110 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2eb945cb06..8d8207a34e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,7 +69,7 @@ endif() # use it that way cmake .. -DBUILD_APPS=ON -DBUILD_SAMPLES=ON # -------------------------------------------------------- option(HAS_HDF5 "Platform supports HDF5 library" ON) -option(HAS_QT "Platform supports Qt 5 6 library." ON) +option(HAS_QT "Platform supports Qt 5 / 6 library." ON) # If the user set the legacy HAS_QT5 option, but didn't set the new HAS_QT option, set it to the value of HAS_QT5 if(DEFINED HAS_QT5 AND NOT DEFINED HAS_QT) diff --git a/doc/rst/development/building_ecal_from_source.rst b/doc/rst/development/building_ecal_from_source.rst index 17fa7e4887..89db9fc312 100644 --- a/doc/rst/development/building_ecal_from_source.rst +++ b/doc/rst/development/building_ecal_from_source.rst @@ -7,12 +7,19 @@ Building eCAL from source ========================= If you want to build eCAL yourself, this tutorial may help you with that. -To build eCAL, you will need a C++14 compliant compiler, such as Visual Studio 2015 or newer, or GCC 5 or newer. + +To build eCAL, you will need: + +- A **C++17 compliant compiler**, such as Visual Studio 2019 or newer, or GCC 8 or newer. + + *A C++14 compliant compiler is sufficient, if you only want to build the eCAL Core Library.* + +- **Qt 5.12 or newer** (Qt6 is supported, too, since eCAL 5.13) for building the eCAL Qt based applications. Currently, we support: * Windows 10 / 11 -* Ubuntu 22.04 / 20.04 / 18.04 +* Ubuntu 22.04 / 20.04 .. seealso:: @@ -38,16 +45,24 @@ First check out the eCAL repository and all of the submodules: #. Download and install the build-dependencies - * CMake (https://cmake.org) - * Qt5 (>= 5.5 / 64-bit) (https://www.qt.io/download) + * **Visual Studio** (2019 or newer / Toolset ≥ v142) (https://visualstudio.microsoft.com/downloads/) + + * **CMake** (https://cmake.org) + + * **Qt** (Qt6 ≥ 6.5 or Qt5 ≥ 5.12) (https://www.qt.io/download) + + *Choose the appropriate version for your compiler, e.g. msvc2019_64 for Visual Studio 2019.* .. note:: - If you have multiple Versions of Qt installed, eCAL will try to pick the latest match for your Visual Studio Version. + - Qt 6 is supported since eCAL 5.13. + + - If you have multiple Versions of Qt installed, eCAL will try to pick the latest match for your Visual Studio Version. + + If this fails (e.g. as you have copied the qt directory without properly installing it) or if you want to use a specific Qt Version, you may have to manually set the ``CMAKE_PREFIX_PATH`` or ``QT_DIR``. - If this fails (e.g. as you have copied the qt directory without properly installing it) or if you want to use a specific Qt5 Version, you may have to manually set the ``CMAKE_PREFIX_PATH`` or ``Qt5_DIR``. -#. Optional: Install additional dependendencies +#. Optional: Install additional dependendencies (not required for the simple build) * `Python for Windows `_ (64 Bit, Version 3.9): To build the python extensions and the documentation * `Doxygen `_: To build the documentation @@ -56,55 +71,27 @@ First check out the eCAL repository and all of the submodules: |fa-windows| Windows build -------------------------- -* **To just compile eCAL**: - - .. code-block:: batch - - mkdir _build\complete - cd _build\complete - - cmake ../.. -A x64 -DCMAKE_INSTALL_PREFIX=_install -DBUILD_SHARED_LIBS=OFF - cmake --build . --parallel --config Release - - This will create a :file:`_build\\complete\\` directory in your eCAL root folder and build eCAL there. - -* **To build a complete setup**: - - #. For creating a setup, you have to also build the documentation and build the debug SDK binaries. - - To build the eCAL QT based applications, you will need to install additionally: - - - Qt5 as ``msvc2015_64`` (Or manually override it by setting ``Qt5_DIR``) - - Execute the following batch files to create the Visual Studio 2019 solution and build it. - - .. code-block:: batch - - build_win\win_make_cmake.bat - build_win\win_make_build.bat - - This will create a :file:`_build\\` directory in your eCAL root folder and build eCAL in two configurations, there. - - #. Run the following batch files to create an eCAL setup as .exe installer: +.. seealso:: - .. code-block:: batch + The build described here is a very simple (yet complete and fully functional) build that differs from our "official" binaries, e.g. it does not contain the documentation and is not packaged as an installer. + If your goal is to replicate the official build, you should apply the CMake Options exactly as we do. + You can grab those from our GitHub Action build scripts: - build_win\win_make_setup.bat + - `build-windows.yml `_ - You will find the .exe installer in the :file:`_build\\complete\\_deploy\\` directory. +.. code-block:: batch - #. Optional: If you configured CMake to build the python extension by setting `BUILD_PY_BINDING` to `ON` you can create the eCAL python wheel by calling + mkdir _build\complete + cd _build\complete + + rem Replace with your Qt installation path: + set "CMAKE_PREFIX_PATH=C:/Qt/5.15.2/msvc2019_64" - .. code-block:: batch - - build_win\win_make_python_wheel.bat + cmake ../.. -A x64 -DCMAKE_INSTALL_PREFIX=_install -DBUILD_SHARED_LIBS=OFF + cmake --build . --parallel --config Release - Afterwards you will find the python eCAL wheel in the :file:`_build\\_deploy\\` directory. - Install the extension by +This will create a :file:`_build\\complete\\` directory in your eCAL root folder and build eCAL there. - .. code-block:: batch - - pip install ecal-...-win_amd64.whl |fa-ubuntu| Building eCAL on Ubuntu =================================== @@ -119,7 +106,6 @@ We support building on currently supported Ubuntu LTS releases. - `Ubuntu 22.04 `_ - `Ubuntu 20.04 `_ - - `Ubuntu 18.04 `_ |fa-ubuntu| Build dependencies ------------------------------ @@ -156,33 +142,8 @@ We support building on currently supported Ubuntu LTS releases. sudo apt-get install python3.8-dev python3-pip python3 -m pip install setuptools - .. tab:: Ubuntu 18.04 - - #. Add the `official CMake repository `_, as eCAL needs CMake >= 3.15: - - .. code-block:: bash - - wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | sudo tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null - echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ bionic main' | sudo tee /etc/apt/sources.list.d/kitware.list >/dev/null - sudo apt-get -y update - sudo rm /usr/share/keyrings/kitware-archive-keyring.gpg - sudo apt-get install kitware-archive-keyring - - #. Install the dependencies from the ordinary Ubuntu 18.04 repositories: - - .. code-block:: bash - - sudo apt-get install git cmake doxygen graphviz build-essential zlib1g-dev qtbase5-dev libhdf5-dev libprotobuf-dev libprotoc-dev protobuf-compiler libcurl4-openssl-dev libqwt-qt5-dev libyaml-cpp-dev - - #. If you plan to create the eCAL python language extension: - - .. code-block:: bash - - sudo apt-get install python3.6-dev python3-pip - python3 -m pip install setuptools - -|fa-ubuntu| Ubuntu 22/20/18 build ---------------------------------- +|fa-ubuntu| Ubuntu 22.04 / 20.04 build +-------------------------------------- #. Compile eCAL with the following options (additional set `BUILD_PY_BINDING` to `ON` if plan to build the python extension): diff --git a/doc/rst/development/ecal_cmake_options.rst b/doc/rst/development/ecal_cmake_options.rst index dcaec2bac0..4100834a91 100644 --- a/doc/rst/development/ecal_cmake_options.rst +++ b/doc/rst/development/ecal_cmake_options.rst @@ -18,38 +18,85 @@ There are a few addional options which do not fit in these categories, but they All options can be passed on the command line cmake ``-D