From a891c5e907d5971052c6bbe9c05c0788e32d939a Mon Sep 17 00:00:00 2001 From: Neil Horne Date: Fri, 27 Oct 2023 19:31:17 +1100 Subject: [PATCH] chore(cpn): Fetch maxlibqt from forked repo at compile time (#4249) Co-authored-by: raphaelcoeffic <1050031+raphaelcoeffic@users.noreply.github.com> --- cmake/FetchMaxLibQt.cmake | 17 ++ companion/src/CMakeLists.txt | 9 +- companion/src/appdebugmessagehandler.cpp | 163 ---------- companion/src/appdebugmessagehandler.h | 142 --------- companion/src/companion.cpp | 3 +- companion/src/generaledit/CMakeLists.txt | 2 +- companion/src/modeledit/CMakeLists.txt | 1 + companion/src/shared/CMakeLists.txt | 2 +- companion/src/simulation/debugoutput.cpp | 2 +- companion/src/simulation/simulatorwidget.cpp | 3 +- companion/src/simulation/widgets/lcdwidget.h | 2 +- companion/src/simulator.cpp | 3 +- .../maxlibqt/src/widgets/CMakeLists.txt | 31 -- .../maxlibqt/src/widgets/ExportableTableView | 1 - .../src/widgets/ExportableTableView.cpp | 242 --------------- .../src/widgets/ExportableTableView.h | 99 ------ .../thirdparty/maxlibqt/src/widgets/TimerEdit | 1 - .../maxlibqt/src/widgets/TimerEdit.cpp | 281 ------------------ .../maxlibqt/src/widgets/TimerEdit.h | 103 ------- 19 files changed, 33 insertions(+), 1074 deletions(-) create mode 100644 cmake/FetchMaxLibQt.cmake delete mode 100644 companion/src/appdebugmessagehandler.cpp delete mode 100644 companion/src/appdebugmessagehandler.h delete mode 100644 companion/src/thirdparty/maxlibqt/src/widgets/CMakeLists.txt delete mode 100644 companion/src/thirdparty/maxlibqt/src/widgets/ExportableTableView delete mode 100644 companion/src/thirdparty/maxlibqt/src/widgets/ExportableTableView.cpp delete mode 100644 companion/src/thirdparty/maxlibqt/src/widgets/ExportableTableView.h delete mode 100644 companion/src/thirdparty/maxlibqt/src/widgets/TimerEdit delete mode 100644 companion/src/thirdparty/maxlibqt/src/widgets/TimerEdit.cpp delete mode 100644 companion/src/thirdparty/maxlibqt/src/widgets/TimerEdit.h diff --git a/cmake/FetchMaxLibQt.cmake b/cmake/FetchMaxLibQt.cmake new file mode 100644 index 000000000..2bbe1ec55 --- /dev/null +++ b/cmake/FetchMaxLibQt.cmake @@ -0,0 +1,17 @@ +# Fetch maxLibQt source code from Github + +include(FetchContent) + +FetchContent_Declare( + maxLibQt + GIT_REPOSITORY https://github.com/edgetx/maxLibQt + GIT_TAG b5418f76cc4891e09f4e21276175d39dbb130f66 +) + +FetchContent_MakeAvailable(maxLibQt) + +message("Fetched maxLibQt source code from Github: ${maxLibQt_SOURCE_DIR}") +include_directories( + ${maxLibQt_SOURCE_DIR} + ${maxLibQt_BINARY_DIR} +) diff --git a/companion/src/CMakeLists.txt b/companion/src/CMakeLists.txt index 22eac3554..e31e6408a 100644 --- a/companion/src/CMakeLists.txt +++ b/companion/src/CMakeLists.txt @@ -142,7 +142,6 @@ endif() ############# Common lib ############### set(common_SRCS - appdebugmessagehandler.cpp customdebug.cpp helpers.cpp translations.cpp @@ -151,7 +150,6 @@ set(common_SRCS ) set(common_MOC_HDRS - appdebugmessagehandler.h helpers.h modeledit/node.h ) @@ -170,7 +168,7 @@ target_link_libraries(common firmwares storage simulation - maxLibQtWidgets + maxLibQt Qt5::Core Qt5::Xml Qt5::Widgets @@ -185,6 +183,8 @@ set(CPN_COMMON_LIB common) include(FetchMiniz) +include(FetchMaxLibQt) + add_subdirectory(datamodels) add_subdirectory(firmwares) add_subdirectory(shared) @@ -193,7 +193,6 @@ add_subdirectory(generaledit) add_subdirectory(simulation) add_subdirectory(storage) add_subdirectory(thirdparty/qcustomplot) -add_subdirectory(thirdparty/maxlibqt/src/widgets) add_subdirectory(updates) set(YAML_CPP_BUILD_TESTS OFF CACHE BOOL "Enable testing" FORCE) @@ -204,6 +203,8 @@ add_subdirectory(thirdparty/yaml-cpp) ############# Companion ############### +include_directories(${maxLibQt_SOURCE_DIR}/widgets) + set(companion_SRCS helpers_html.cpp mdichild.cpp diff --git a/companion/src/appdebugmessagehandler.cpp b/companion/src/appdebugmessagehandler.cpp deleted file mode 100644 index 0a75d7949..000000000 --- a/companion/src/appdebugmessagehandler.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) OpenTX - * - * Based on code named - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "appdebugmessagehandler.h" - -#include - -AppDebugMessageHandler::AppDebugMessageHandler(QObject * parent) : - QObject(parent), - m_appDebugOutputLevel(APP_DBG_HANDLER_DEFAULT_LEVEL), - m_showSourcePath(APP_DBG_HANDLER_SHOW_SRC_PATH), - m_showFunctionDeclarations(APP_DBG_HANDLER_SHOW_FUNCTION_DECL) -{ - m_srcPathFilter = QRegularExpression("^" APP_DBG_HANDLER_SRC_PATH "[\\\\\\/](.*?)$", QRegularExpression::InvertedGreedinessOption); - m_functionFilter = QRegularExpression("^.+?(\\w+\\().+$"); -} - -AppDebugMessageHandler * AppDebugMessageHandler::instance() -{ - static AppDebugMessageHandler * _instance = NULL; -#if APP_DBG_HANDLER_ENABLE - if(_instance == NULL && !qApp->closingDown()) - _instance = new AppDebugMessageHandler(qApp); // Ensure this object is cleaned up when the QApplication exits. -#endif - return _instance; -} - -void AppDebugMessageHandler::setAppDebugOutputLevel(const quint8 & appDebugOutputLevel) -{ - m_appDebugOutputLevel = appDebugOutputLevel; -} - -void AppDebugMessageHandler::setShowSourcePath(bool showSourcePath) -{ - m_showSourcePath = showSourcePath; -} - -void AppDebugMessageHandler::setShowFunctionDeclarations(bool showFunctionDeclarations) -{ - m_showFunctionDeclarations = showFunctionDeclarations; -} - -void AppDebugMessageHandler::addOutputDevice(QIODevice * device) -{ - if (device && !m_outputDevices.contains(device)) - m_outputDevices.append(device); -} - -void AppDebugMessageHandler::removeOutputDevice(QIODevice * device) -{ - if (device) { - // no QVector::removeAll() in Qt < 5.4 - int i = 0; - foreach (QIODevice * d, m_outputDevices) { - if (d == device) - m_outputDevices.remove(i); - ++i; - } - } -} - -void AppDebugMessageHandler::installAppMessageHandler() -{ - m_defaultHandler = qInstallMessageHandler(g_appDebugMessageHandler); -} - -void AppDebugMessageHandler::messageHandler(QtMsgType type, const QMessageLogContext & context, const QString & msg) -{ - static const char symbols[] = { 'D', 'W', 'E', 'X', 'I' }; // correspond to QtMsgType enum - // normalize types, QtDebugMsg stays 0, QtInfoMsg becomes 1, rest are QtMsgType + 1 - quint8 lvl = type; - if (type == QtInfoMsg) - lvl = 1; - else if (type > QtDebugMsg) - ++lvl; - - if (lvl < m_appDebugOutputLevel && type != QtFatalMsg) - return; - -#if defined(Q_OS_LINUX) && (QT_VERSION < QT_VERSION_CHECK(5, 3, 0)) - // Filter out lots of QPainter warnings from undocked QDockWidgets... hackish but effective (only workaround found so far) - if (lvl == 2 && QString(context.function).contains("QPainter::")) - return; -#endif - - QString msgPattern = QString("[%1] ").arg(symbols[type]); - - if (m_showSourcePath) { - QString file = QString("%1::").arg(context.file); - file.replace(m_srcPathFilter, "\\1"); - msgPattern.append(file); - } - if (m_showFunctionDeclarations) - msgPattern.append(context.function); - else - msgPattern.append("%{function}()"); - - msgPattern.append(":%{line} -%{if-category} [%{category}]%{endif} %{message}"); - - if (type == QtFatalMsg) - msgPattern.append("\nBACKTRACE:\n%{backtrace depth=12 separator=\"\n\"}"); - - qSetMessagePattern(msgPattern); - - if (!m_defaultHandler || m_outputDevices.size() || receivers(SIGNAL(messageOutput(quint8, const QString &)))) { -#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)) - msgPattern = qFormatLogMessage(type, context, msg); -#else - msgPattern.replace("%{line}", QString::number(context.line)); - msgPattern.replace("%{if-category} [%{category}]%{endif}", QString(context.category)); - msgPattern.replace("%{message}", msg); - if (!m_showFunctionDeclarations) { - QString func = context.function; - msgPattern.replace("%{function}", func.replace(m_functionFilter, "\\1)")); - } -#endif - - emit messageOutput(lvl, msgPattern); - - foreach (QIODevice * d, m_outputDevices) { - if (d && d->isWritable() && (!d->property("level").isValid() || d->property("level").toInt() <= lvl)) { - d->write(qPrintable(msgPattern % "\n")); - if (QFileDevice * fd = qobject_cast(d)) - fd->flush(); - } - } - } - - // if (QThread::currentThread() == qApp->thread()) // gui thread - - if (m_defaultHandler) { - m_defaultHandler(type, context, msg); - } - else { - fprintf(stderr, "%s", qPrintable(msgPattern)); - if (type == QtFatalMsg) - abort(); - } -} - -// Message handler which is installed using qInstallMessageHandler. This needs to be global. -void g_appDebugMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) -{ - if (AppDebugMessageHandler::instance()) - AppDebugMessageHandler::instance()->messageHandler(type, context, msg); -} diff --git a/companion/src/appdebugmessagehandler.h b/companion/src/appdebugmessagehandler.h deleted file mode 100644 index 7ea682899..000000000 --- a/companion/src/appdebugmessagehandler.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) OpenTX - * - * Based on code named - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef APPDEBUGMESSAGEHANDLER_H -#define APPDEBUGMESSAGEHANDLER_H - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -/* - * Custom debug/message handler class to work in conjunction with qDebug() family of functions. - * Formats all stderr output generated by the application in a consistent manner. - * It can also be used by other event listeners to intercept messages they may be interested in (connect to messageOutput() signal). - * - * Include this header to use qInfo() safely with Qt < v5.5 (qInfo becomes alias for qDebug). - * - * Note that the default message format can still be overriden by setting QT_MESSAGE_PATTERN environment variable at _runtime_. - * see: https://doc.qt.io/qt-5/qtglobal.html#qSetMessagePattern - * - * This is an app-wide "global" thread-safe singleton class, use it with AppDebugMessageHandler::instance(). - * For example, at start of application: - * - * QApplication app(argc, argv); - * AppDebugMessageHandler::instance()->installAppMessageHandler(); - * - * To connect to a signal: - * - * connect(AppDebugMessageHandler::instance(), &AppDebugMessageHandler::messageOutput, this, &DebugOutput::onAppDebugMessage); - * - * This singleton will self-destruct upon QApplication termination. - * - */ - -#if defined(QT_DEBUG) || defined(DEBUG) - #define APP_DBG_HANDLER_IS_DBG_BUILD 1 -#else - #define APP_DBG_HANDLER_IS_DBG_BUILD 0 -#endif - -// Enable/disable this custom handler handler entirely -#ifndef APP_DBG_HANDLER_ENABLE - #define APP_DBG_HANDLER_ENABLE 1 -#endif - -// Default log level (can also be set with setAppDebugOutputLevel()): -// 0 = debug+; 1 = info+; 2 = warn+; 3 = critical+; 4 = fatal only -#ifndef APP_DBG_HANDLER_DEFAULT_LEVEL - #define APP_DBG_HANDLER_DEFAULT_LEVEL 0 -#endif - -// Include source file path/name in output (filtered with APP_DBG_HANDLER_SRC_PATH) -#ifndef APP_DBG_HANDLER_SHOW_SRC_PATH - #define APP_DBG_HANDLER_SHOW_SRC_PATH APP_DBG_HANDLER_IS_DBG_BUILD -#endif - -// Show just the function Class::name vs. full declaration with return and param types -#ifndef APP_DBG_HANDLER_SHOW_FUNCTION_DECL - #define APP_DBG_HANDLER_SHOW_FUNCTION_DECL 0 -#endif - -// base path for source file name filter, everything after this is kept; RegEx, non-greedy -#ifndef APP_DBG_HANDLER_SRC_PATH - #define APP_DBG_HANDLER_SRC_PATH ".*src" -#endif - -// Make sure to include this header if using qInfo() -#if (QT_VERSION < QT_VERSION_CHECK(5, 5, 0)) - #if defined(QT_NO_INFO_OUTPUT) - #define qInfo QT_NO_QDEBUG_MACRO - #else - #define qInfo qDebug - #endif - #define QtInfoMsg QtMsgType(4) -#endif - -class AppDebugMessageHandler : public QObject -{ - Q_OBJECT - - public: - // This class implements the singleton design pattern and is therefore publicly accessible only through instance(). - static AppDebugMessageHandler * instance(); - AppDebugMessageHandler(AppDebugMessageHandler const &) = delete; - void operator = (AppDebugMessageHandler const &) = delete; - - void setAppDebugOutputLevel(const quint8 & appDebugOutputLevel); - void setShowSourcePath(bool showSourcePath); - void setShowFunctionDeclarations(bool showFunctionDeclarations); - void addOutputDevice(QIODevice * device); - void removeOutputDevice(QIODevice * device); - - void installAppMessageHandler(); - void messageHandler(QtMsgType type, const QMessageLogContext & context, const QString & msg); - - private: - // This class implements the singleton design pattern and therefore has only a private constructor. - explicit AppDebugMessageHandler(QObject * parent = Q_NULLPTR); - ~AppDebugMessageHandler() { } - - QtMessageHandler m_defaultHandler; - QRegularExpression m_srcPathFilter; - QRegularExpression m_functionFilter; - quint8 m_appDebugOutputLevel; - QVector m_outputDevices; - bool m_showSourcePath; - bool m_showFunctionDeclarations; - - signals: - void messageOutput(quint8 level, const QString & msg); -}; - -// Message handler which is installed using qInstallMessageHandler. This needs to be global. -// Use AppDebugMessageHandler::instance()->installAppMessageHandler(); -// instead of installing this function directly (it will verify this handler is enabled, etc). -void g_appDebugMessageHandler(QtMsgType, const QMessageLogContext &, const QString &); - -#endif // APPDEBUGMESSAGEHANDLER_H diff --git a/companion/src/companion.cpp b/companion/src/companion.cpp index 7f93f1645..1f367ae1e 100644 --- a/companion/src/companion.cpp +++ b/companion/src/companion.cpp @@ -29,7 +29,8 @@ #undef main #endif -#include "appdebugmessagehandler.h" +#include + #include "customdebug.h" #include "mainwindow.h" #include "version.h" diff --git a/companion/src/generaledit/CMakeLists.txt b/companion/src/generaledit/CMakeLists.txt index 6821321dc..fe8660dc3 100644 --- a/companion/src/generaledit/CMakeLists.txt +++ b/companion/src/generaledit/CMakeLists.txt @@ -1,4 +1,4 @@ -include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) +include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${maxLibQt_SOURCE_DIR}/widgets) set(generaledit_NAMES generaledit diff --git a/companion/src/modeledit/CMakeLists.txt b/companion/src/modeledit/CMakeLists.txt index 9d85dc671..0a792e8f6 100644 --- a/companion/src/modeledit/CMakeLists.txt +++ b/companion/src/modeledit/CMakeLists.txt @@ -2,6 +2,7 @@ include_directories( ${CMAKE_SOURCE_DIR} ${COMPANION_SRC_DIRECTORY} ${CMAKE_CURRENT_BINARY_DIR} + ${maxLibQt_SOURCE_DIR}/widgets ) set(modeledit_NAMES diff --git a/companion/src/shared/CMakeLists.txt b/companion/src/shared/CMakeLists.txt index 5f9c47ee2..20829486f 100644 --- a/companion/src/shared/CMakeLists.txt +++ b/companion/src/shared/CMakeLists.txt @@ -1,4 +1,4 @@ -include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) +include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${maxLibQt_SOURCE_DIR}/widgets) set(shared_NAMES genericpanel diff --git a/companion/src/simulation/debugoutput.cpp b/companion/src/simulation/debugoutput.cpp index c8434eef7..d4c268ee7 100644 --- a/companion/src/simulation/debugoutput.cpp +++ b/companion/src/simulation/debugoutput.cpp @@ -21,10 +21,10 @@ #include "debugoutput.h" #include "ui_debugoutput.h" -#include "appdebugmessagehandler.h" #include "appdata.h" #include "filteredtextbuffer.h" +#include #include #include #include diff --git a/companion/src/simulation/simulatorwidget.cpp b/companion/src/simulation/simulatorwidget.cpp index 987304c85..7312c255c 100644 --- a/companion/src/simulation/simulatorwidget.cpp +++ b/companion/src/simulation/simulatorwidget.cpp @@ -21,7 +21,7 @@ #include "simulatorwidget.h" #include "ui_simulatorwidget.h" -#include "appdebugmessagehandler.h" +#include "appdata.h" #include "radiofaderwidget.h" #include "radiokeywidget.h" #include "radioknobwidget.h" @@ -37,6 +37,7 @@ #include "joystickdialog.h" #endif +#include #include #include #include diff --git a/companion/src/simulation/widgets/lcdwidget.h b/companion/src/simulation/widgets/lcdwidget.h index 07e2945c1..66cd3789d 100644 --- a/companion/src/simulation/widgets/lcdwidget.h +++ b/companion/src/simulation/widgets/lcdwidget.h @@ -29,9 +29,9 @@ #include #include #include +#include #include "appdata.h" -#include "appdebugmessagehandler.h" #define LCD_WIDGET_REFRESH_PERIOD 16 // [ms] 16 = 62.5fps diff --git a/companion/src/simulator.cpp b/companion/src/simulator.cpp index 70990795e..583127619 100644 --- a/companion/src/simulator.cpp +++ b/companion/src/simulator.cpp @@ -29,8 +29,9 @@ #undef main #endif +#include + #include "appdata.h" -#include "appdebugmessagehandler.h" #include "constants.h" #include "customdebug.h" #include "eeprominterface.h" diff --git a/companion/src/thirdparty/maxlibqt/src/widgets/CMakeLists.txt b/companion/src/thirdparty/maxlibqt/src/widgets/CMakeLists.txt deleted file mode 100644 index 7a9bf77f1..000000000 --- a/companion/src/thirdparty/maxlibqt/src/widgets/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -cmake_minimum_required(VERSION 2.8.12) -cmake_policy(SET CMP0020 NEW) - -find_package(Qt5Core) -find_package(Qt5Widgets) - -project(maxLibQtWidgets) - -set(SRCS - "${CMAKE_CURRENT_LIST_DIR}/ExportableTableView.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/ScrollableMessageBox.cpp" - "${CMAKE_CURRENT_LIST_DIR}/TimerEdit.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/TreeComboBox.cpp" -) - -set(HDRS - "${CMAKE_CURRENT_LIST_DIR}/ExportableTableView.h" -# "${CMAKE_CURRENT_LIST_DIR}/ScrollableMessageBox.h" - "${CMAKE_CURRENT_LIST_DIR}/TimerEdit.h" -# "${CMAKE_CURRENT_LIST_DIR}/TreeComboBox.h" -) - -qt5_wrap_cpp(SRCS ${HDRS}) - -add_library(${PROJECT_NAME} ${SRCS} ${HDRS}) -target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Core Qt5::Widgets) -target_compile_definitions(${PROJECT_NAME} PRIVATE QT_USE_QSTRINGBUILDER) -target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC "${CMAKE_CURRENT_LIST_DIR}") - -# need to push this upstream -set(BUILT_LIBRARIES ${BUILT_LIBRARIES} ${PROJECT_NAME} PARENT_SCOPE) diff --git a/companion/src/thirdparty/maxlibqt/src/widgets/ExportableTableView b/companion/src/thirdparty/maxlibqt/src/widgets/ExportableTableView deleted file mode 100644 index 97eac83d9..000000000 --- a/companion/src/thirdparty/maxlibqt/src/widgets/ExportableTableView +++ /dev/null @@ -1 +0,0 @@ -#include "ExportableTableView.h" diff --git a/companion/src/thirdparty/maxlibqt/src/widgets/ExportableTableView.cpp b/companion/src/thirdparty/maxlibqt/src/widgets/ExportableTableView.cpp deleted file mode 100644 index b384a44ea..000000000 --- a/companion/src/thirdparty/maxlibqt/src/widgets/ExportableTableView.cpp +++ /dev/null @@ -1,242 +0,0 @@ -/* - ExportableTableView - - COPYRIGHT: (c)2017 Maxim Paperno; All Right Reserved. - Contact: http://www.WorldDesign.com/contact - - LICENSE: - - Commercial License Usage - Licensees holding valid commercial licenses may use this file in - accordance with the terms contained in a written agreement between - you and the copyright holder. - - GNU General Public License Usage - Alternatively, this file may be used under the terms of the GNU - General Public License as published by the Free Software Foundation, - either version 3 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - A copy of the GNU General Public License is available at . -*/ - -#include "ExportableTableView.h" - -ExportableTableView::ExportableTableView(QWidget *parent) : QTableView(parent) -{ - setContextMenuPolicy(Qt::CustomContextMenu); - setHtmlTemplate(getDefaultHtmlTemplate()); - - QAction * selAll = new QAction(tr("Select All"), this); - selAll->setShortcut(QKeySequence::SelectAll); - addAction(selAll); - - QAction * cpyTab = new QAction(tr("Copy selection as TAB-delimited text"), this); - cpyTab->setShortcut(QKeySequence::Copy); - cpyTab->setProperty("delim", "\t"); - addAction(cpyTab); - - QAction * cpyCsv = new QAction(tr("Copy selection as cooma-delimited text (CSV)"), this); - cpyCsv->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_C); - cpyCsv->setProperty("delim", ", "); - addAction(cpyCsv); - - QAction * cpyPipe = new QAction(tr("Copy selection as pipe-delimited text"), this); - cpyPipe->setShortcut(Qt::CTRL + Qt::ALT + Qt::Key_C); - cpyPipe->setProperty("delim", " | "); - addAction(cpyPipe); - - QAction * cpyHtml = new QAction(tr("Copy selection as HTML"), this); - cpyHtml->setProperty("delim", "html"); - addAction(cpyHtml); - - QAction * saveFile = new QAction(tr("Save selection to file"), this); - saveFile->setShortcut(QKeySequence::Save); - addAction(saveFile); - - connect(selAll, &QAction::triggered, this, &QTableView::selectAll); - connect(cpyTab, &QAction::triggered, this, &ExportableTableView::copy); - connect(cpyCsv, &QAction::triggered, this, &ExportableTableView::copy); - connect(cpyPipe, &QAction::triggered, this, &ExportableTableView::copy); - connect(cpyHtml, &QAction::triggered, this, &ExportableTableView::copy); - connect(saveFile, &QAction::triggered, this, &ExportableTableView::save); - connect(this, &QTableView::customContextMenuRequested, this, &ExportableTableView::onCustomContextMenuRequested); -} - -QString ExportableTableView::getDefaultHtmlTemplate() -{ - return "\n\n\n\n" \ - "\n" \ - "%1" \ - "
\n" \ - ""; -} - -void ExportableTableView::setHtmlTemplate(const QString &value) -{ - m_htmlTemplate = value; -} - -QString ExportableTableView::toPlainText(const QModelIndexList &indexList, const QString &delim) const -{ - QString ret, header; - const QChar rowDelim = '\n'; - bool firstRow = true; - for (int i = 0; i < indexList.count(); ++i) { - const QModelIndex & idx = indexList.at(i); - - if (firstRow) - header.append(model()->headerData(idx.column(), Qt::Horizontal).toString()); - - ret.append(idx.data(Qt::DisplayRole).toString()); - - if (i + 1 == indexList.count() || indexList.at(i+1).row() != idx.row()) { - ret.append(rowDelim); - if (firstRow && !header.isEmpty()) - header.append(rowDelim); - firstRow = false; - } - else { - ret.append(delim); - if (firstRow && !header.isEmpty()) - header.append(delim); - } - } - if (!header.isEmpty()) - ret.prepend(header); - - return ret; -} - -QString ExportableTableView::toHtml(const QModelIndexList &indexList) const -{ - QString ret, header, row; - bool firstRow = true; - - for (int i = 0; i < indexList.count(); ++i) { - const QModelIndex & idx = indexList.at(i); - const int algn = (idx.data(Qt::TextAlignmentRole).isValid() ? idx.data(Qt::TextAlignmentRole).toInt() : (Qt::AlignLeft | Qt::AlignVCenter)); - const QString fg = (idx.data(Qt::ForegroundRole).isValid() ? idx.data(Qt::ForegroundRole).value().color().name(QColor::HexRgb) : "initial"); - const QString bg = (idx.data(Qt::BackgroundRole).isValid() ? idx.data(Qt::BackgroundRole).value().color().name(QColor::HexRgb) : "initial"); - const QString ttl = (idx.data(Qt::ToolTipRole).isValid() ? idx.data(Qt::ToolTipRole).toString().replace("\"", "\"\"") : QString()); - - QString fnt; - if (idx.data(Qt::FontRole).isValid()) { - const QFont font = idx.data(Qt::FontRole).value(); - fnt = "font: \"" % font.family() % "\" " % QString::number(font.pointSize()) % "pt;"; - } - - if (firstRow) - header.append(QString("%1\n").arg(model()->headerData(idx.column(), Qt::Horizontal).toString())); - - row.append("%1\n"); // cell template - row = row.arg(idx.data(Qt::DisplayRole).toString()).arg(fg).arg(bg).arg(fnt); - row = row.arg((algn & Qt::AlignRight) ? "right" : (algn & Qt::AlignHCenter) ? "center" : "left"); - row = row.arg((algn & Qt::AlignTop) ? "top" : (algn & Qt::AlignBottom) ? "bottom" : "middle"); - row = row.arg(ttl.isEmpty() ? ttl : QString("title=\"%1\"").arg(ttl)); - - if (i + 1 == indexList.count() || indexList.at(i+1).row() != idx.row()) { - ret.append(QString("\n%1\n").arg(row)); - row.clear(); - firstRow = false; - } - } - - ret = QString("\n%1\n").arg(ret); - if (!header.isEmpty()) - ret.prepend(QString("\n\n%1\n\n").arg(header)); - ret = m_htmlTemplate.arg(ret); - - return ret; -} - -bool ExportableTableView::saveToFile(const QModelIndexList &indexList, const QString &fileName) -{ - static QString lastDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); - - if (indexList.isEmpty()) - return false; - - QString fname = fileName; - if (fname.isEmpty()) { - QString types = tr("Tab-delimited text") % " (*.tab);;" % tr("Comma-delimited text") % " (*.csv);;" % tr("Pipe-delimited text") % " (*.txt);;" % tr("HTML") % " (*.html)"; - fname = QFileDialog::getSaveFileName(this, tr("Save to file"), lastDir, types); - } - - if (fname.isEmpty()) - return false; - - QFile file(fname); - QFileInfo fi(file); - lastDir = fi.absolutePath(); - - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) - return false; - - if (fi.suffix() == "html") - file.write(toHtml(indexList).toUtf8()); - else - file.write(toPlainText(indexList, (fi.suffix() == "tab" ? "\t" : fi.suffix() == "csv" ? ", " : " | ")).toUtf8()); - file.close(); - - return true; -} - -QSize ExportableTableView::sizeHint() const -{ - int w = 0; - for (int i = 0; i < model()->columnCount(); ++i) - w += sizeHintForColumn(i); - return QSize(w + verticalScrollBar()->sizeHint().width() + 60, sizeHintForRow(0) * model()->rowCount()); -} - -void ExportableTableView::copyText(const QString &delim) -{ - QApplication::clipboard()->setText(toPlainText(getSelectedOrAll(), delim)); -} - -void ExportableTableView::copyHtml() -{ - QMimeData * mdata = new QMimeData; - mdata->setHtml(toHtml(getSelectedOrAll())); - QApplication::clipboard()->setMimeData(mdata); -} - -void ExportableTableView::copy() -{ - QString delim = "\t"; - if (sender() && sender()->property("delim").isValid()) - delim = sender()->property("delim").toString(); - if (delim == "html") - copyHtml(); - else - copyText(delim); -} - -void ExportableTableView::save() -{ - saveToFile(getSelectedOrAll()); -} - -QModelIndexList ExportableTableView::getSelectedOrAll() -{ - QModelIndexList sel = selectionModel()->selectedIndexes(); - if (sel.isEmpty()) { - selectAll(); - sel = selectionModel()->selectedIndexes(); - } - return sel; -} - -void ExportableTableView::onCustomContextMenuRequested(const QPoint & pos) -{ - QMenu menu; - menu.addActions(actions()); - menu.exec(mapToGlobal(pos)); -} diff --git a/companion/src/thirdparty/maxlibqt/src/widgets/ExportableTableView.h b/companion/src/thirdparty/maxlibqt/src/widgets/ExportableTableView.h deleted file mode 100644 index e6569fe30..000000000 --- a/companion/src/thirdparty/maxlibqt/src/widgets/ExportableTableView.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - ExportableTableView - https://github.com/mpaperno/maxLibQt - - COPYRIGHT: (c)2017 Maxim Paperno; All Right Reserved. - Contact: http://www.WorldDesign.com/contact - - LICENSE: - - Commercial License Usage - Licensees holding valid commercial licenses may use this file in - accordance with the terms contained in a written agreement between - you and the copyright holder. - - GNU General Public License Usage - Alternatively, this file may be used under the terms of the GNU - General Public License as published by the Free Software Foundation, - either version 3 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - A copy of the GNU General Public License is available at . -*/ - -#ifndef EXPORTABLETABLEVIEW_H -#define EXPORTABLETABLEVIEW_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** - \class ExportableTableView - \version 1.0.0 - - \brief The ExportableTableView class provides a regular QTableView but with features to export the data - as plain text or HTML. - - Any selection of data can be exported. The horizontal headings, if any, are included in the export. - The export functions are available to the user via a custom context menu or keyboard shortcuts. - 3 field delimiter choices are available for plain-text export (tab, comma, or pipe). - Data can be saved to the clipboard or to a file. - - The export functions can also be accessed programmatically via \c toPlainText(), \c toHtml(), - and \c saveToFile(). - - The overall HTML template can be customized by setting \c setHtmlTemplate(). The data itself is always - formatted as a basic HTML table and then inserted into the template at the \c %1 placeholder. - HTML version tries to preserve many data role attributes of the model items: - - \li \c Qt::FontRole - \li \c Qt::ForegroundRole - \li \c Qt::BackgroundRole - \li \c Qt::TextAlignmentRole - \li \c Qt::ToolTipRole - - Note that \c Qt::EditRole data is not specifically preserved (unless it already matches \c Qt::DisplayRole ). - - */ -class ExportableTableView : public QTableView -{ - Q_OBJECT - - public: - ExportableTableView(QWidget *parent = Q_NULLPTR); - - static QString getDefaultHtmlTemplate(); - void setHtmlTemplate(const QString &value); - - QString toPlainText(const QModelIndexList &indexList, const QString &delim = "\t") const; - QString toHtml(const QModelIndexList &indexList) const; - bool saveToFile(const QModelIndexList &indexList, const QString &fileName = QString()); - - QSize sizeHint() const Q_DECL_OVERRIDE; - - public slots: - void copyText(const QString &delim = QString("\t")); - void copyHtml(); - void copy(); - void save(); - QModelIndexList getSelectedOrAll(); - - protected: - void onCustomContextMenuRequested(const QPoint &pos); - - QString m_htmlTemplate; -}; - -#endif // EXPORTABLETABLEVIEW_H diff --git a/companion/src/thirdparty/maxlibqt/src/widgets/TimerEdit b/companion/src/thirdparty/maxlibqt/src/widgets/TimerEdit deleted file mode 100644 index f1aabbabc..000000000 --- a/companion/src/thirdparty/maxlibqt/src/widgets/TimerEdit +++ /dev/null @@ -1 +0,0 @@ -#include "TimerEdit.h" diff --git a/companion/src/thirdparty/maxlibqt/src/widgets/TimerEdit.cpp b/companion/src/thirdparty/maxlibqt/src/widgets/TimerEdit.cpp deleted file mode 100644 index ec7fef683..000000000 --- a/companion/src/thirdparty/maxlibqt/src/widgets/TimerEdit.cpp +++ /dev/null @@ -1,281 +0,0 @@ -/* - TimerEdit - - COPYRIGHT: (c)2017 Maxim Paperno; All Right Reserved. - Contact: http://www.WorldDesign.com/contact - - LICENSE: - - Commercial License Usage - Licensees holding valid commercial licenses may use this file in - accordance with the terms contained in a written agreement between - you and the copyright holder. - - GNU General Public License Usage - Alternatively, this file may be used under the terms of the GNU - General Public License as published by the Free Software Foundation, - either version 3 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - A copy of the GNU General Public License is available at . -*/ - -#include "TimerEdit.h" -#include - -TimerEdit::TimerEdit(QWidget *parent) : - QLineEdit(parent), - m_showSeconds(true), - m_minTime(0), - m_maxTime(24 * 3600 - 1), - m_singleStep(1), - m_pageStep(60), - m_hourDigits(2), - m_validator(new QRegularExpressionValidator(this)) -{ - setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); - setupFormat(); - setToolTip(tr("Use mouse scroll or UP/DOWN arrow keys to change time in small steps.\nCTRL + scroll or PAGE UP/DOWN keys to change time in larger steps.")); - connect(this, &TimerEdit::textEdited, this, &TimerEdit::textEditedHandler); -} - -int TimerEdit::timeInSeconds() const -{ - int ret = 0; - - ret += timepart(text(), TimeParts::Hours) * 3600; - ret += timepart(text(), TimeParts::Minutes) * 60; - ret += timepart(text(), TimeParts::Seconds); - ret *= timepart(text(), TimeParts::Polarity); - - return ret; -} - -int TimerEdit::timepart(const QString &input, TimerEdit::TimeParts part) const -{ - int ret = 0; - QRegularExpressionMatch match = m_validator->regularExpression().match(input, 0, QRegularExpression::NormalMatch); - - if (match.hasMatch()) { - switch (part) { - case Hours: - if (!match.captured("hrs").isEmpty()) - ret = match.captured("hrs").toInt(); - break; - - case Minutes: - if (!match.captured("mins").isEmpty()) - ret = match.captured("mins").toInt(); - break; - - case Seconds: - if (!match.captured("secs").isEmpty()) - ret = match.captured("secs").toInt(); - break; - - case Polarity: - if (!match.captured("pol").isEmpty() && !match.captured("pol").compare("-")) - ret = -1; - else - ret = 1; - break; - - default: - break; - } - } - - return ret; -} - - -//// Slots //// - -void TimerEdit::setTime(int seconds) -{ - if (seconds > m_maxTime) - seconds = m_maxTime; - else if (seconds < m_minTime) - seconds = m_minTime; - - div_t qrM = div(abs(seconds), 60); - div_t qrH = div(qrM.quot, 60); - - QString val = QString("%1").arg(qrH.rem, 2, 10, QChar('0')); - - if (m_hourDigits) - val.prepend(QString("%1:").arg(qrH.quot, m_hourDigits, 10, QChar('0'))); - - if (m_showSeconds) - val.append(QString(":%1").arg(qrM.rem, 2, 10, QChar('0'))); - - if (m_minTime < 0) { - if (seconds < 0) - val.prepend("-"); - else - val.prepend(" "); - } - - if (text().compare(val)) { - setText(val); - } -} - -void TimerEdit::incrDecr(int seconds) -{ - if (!seconds) - return; - - const int cs = timeInSeconds(); - int s = seconds + cs; - if (s < m_minTime) - s = m_minTime; - if (s > m_maxTime) - s = m_maxTime; - if (s != cs) { - setTime(s); - emitValueChanged(); - } -} - -void TimerEdit::setTimeRange(int minSeconds, int maxSeconds) -{ - if (minSeconds <= maxSeconds && (m_minTime != minSeconds || m_maxTime != maxSeconds)) { - int digits = 0; - if (maxSeconds >= 3600) - digits = floorf(logf(round(maxSeconds / 3600)) / logf(10.0f)) + 1; - - bool mod = (m_hourDigits != digits || std::signbit((float)m_minTime) != std::signbit((float)minSeconds)); - - m_minTime = minSeconds; - m_maxTime = maxSeconds; - m_hourDigits = digits; - - if (mod) - setupFormat(); - } -} - -void TimerEdit::setMinimumTime(int minSeconds) -{ - setTimeRange(minSeconds, (m_maxTime > minSeconds ? m_maxTime : minSeconds)); -} - -void TimerEdit::setMaximumTime(int maxSeconds) -{ - setTimeRange((m_minTime < maxSeconds ? m_minTime : maxSeconds), maxSeconds); -} - -void TimerEdit::setShowSeconds(bool showSeconds) -{ - if (m_showSeconds != showSeconds) { - m_showSeconds = showSeconds; - setupFormat(); - } -} - - -//// Protected //// - -void TimerEdit::textEditedHandler() -{ - int sec = timeInSeconds(); - if (sec < m_minTime) - setTime(m_minTime); - else if (sec > m_maxTime) - setTime(m_maxTime); - else - return; - - emitValueChanged(); -} - -void TimerEdit::setupFormat() -{ - QString inputRe = "(?[0-5][0-9])"; - QString inputMsk = "99"; - QString suffx = "\\" % tr("m") % "\\" % tr("m"); - - if (m_hourDigits) { - inputRe.prepend("(?[0-9]*[0-9]):"); - inputMsk.prepend(":"); - suffx.prepend(":"); - for (int i=0; i < m_hourDigits; ++i) { - inputMsk.prepend("9"); - suffx.prepend("\\" % tr("h")); - } - } - if (m_showSeconds) { - inputRe.append(":(?[0-5][0-9])"); - inputMsk.append(":99"); - suffx.append(":\\" % tr("s") % "\\" % tr("s")); - } - if (m_minTime < 0) { - inputRe.prepend("(?-|\\+|\\s)?"); - inputMsk.prepend("#"); - } - - inputRe.prepend("^"); - inputRe.append("\\s?\\[[^\\]]+\\]$"); - inputMsk.append(" \\[" % suffx % "\\]"); - - m_validator->setRegularExpression(QRegularExpression(inputRe)); - - setInputMask(inputMsk); - setValidator(m_validator); -} - -void TimerEdit::emitValueChanged() -{ - emit QLineEdit::textEdited(text()); -} - -void TimerEdit::keyPressEvent(QKeyEvent *event) -{ - switch (event->key()) { - case Qt::Key_Up: - incrDecr(m_singleStep); - break; - - case Qt::Key_Down: - incrDecr(-(int)m_singleStep); - break; - - case Qt::Key_PageUp: - incrDecr(m_pageStep); - break; - - case Qt::Key_PageDown: - incrDecr(-(int)m_pageStep); - break; - - case Qt::Key_Plus: - case Qt::Key_Equal: - case Qt::Key_Minus: - if (m_minTime < 0) { - setTime(-timeInSeconds()); - emitValueChanged(); - } - break; - - default: - QLineEdit::keyPressEvent(event); - break; - } -} - -void TimerEdit::wheelEvent(QWheelEvent *event) -{ - if (event->angleDelta().isNull()) { - event->ignore(); - return; - } - int numSteps = -event->angleDelta().y() / 8 / 15 * -1; // one step per 15deg - numSteps *= (event->modifiers() & Qt::ControlModifier) ? m_pageStep : m_singleStep; - incrDecr(numSteps); - event->accept(); -} diff --git a/companion/src/thirdparty/maxlibqt/src/widgets/TimerEdit.h b/companion/src/thirdparty/maxlibqt/src/widgets/TimerEdit.h deleted file mode 100644 index b4536786b..000000000 --- a/companion/src/thirdparty/maxlibqt/src/widgets/TimerEdit.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - TimerEdit - https://github.com/mpaperno/maxLibQt - - COPYRIGHT: (c)2017 Maxim Paperno; All Right Reserved. - Contact: http://www.WorldDesign.com/contact - - LICENSE: - - Commercial License Usage - Licensees holding valid commercial licenses may use this file in - accordance with the terms contained in a written agreement between - you and the copyright holder. - - GNU General Public License Usage - Alternatively, this file may be used under the terms of the GNU - General Public License as published by the Free Software Foundation, - either version 3 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - A copy of the GNU General Public License is available at . -*/ - -#ifndef TIMEREDIT_H -#define TIMEREDIT_H - -#include -#include -#include -#include -#include - -/** - \class TimerEdit - \version 1.0.0 - - \brief A time value line editor which accepts negative and large times (> 23:59:59), suitable for a timer, etc. - - Qt's \c QTimeEdit has a limitation in that it can only accept "valid" times, in the range of 0:00:00 to 23:59:59. - The TimerEdit control aims to address that. It allows any amount of time to be entered, as well as negative times. - It provides a mask for data entry, a validator with settable min/max times, and increment/decrement via keyboard - or mouse wheel in configurable steps. - - Data I/O is in seconds only, that is you set the time value in total seconds and also read it back in seconds - (there is no conversion from/to a \e QTime object). - -*/ -class TimerEdit : public QLineEdit -{ - Q_OBJECT - Q_PROPERTY(int minimumTime READ minimumTime WRITE setMinimumTime) - Q_PROPERTY(int maximumTime READ maximumTime WRITE setMaximumTime) - Q_PROPERTY(bool showSeconds READ showSeconds WRITE setShowSeconds) - Q_PROPERTY(unsigned int singleStep READ singleStep WRITE setSingleStep) - Q_PROPERTY(unsigned int pageStep READ pageStep WRITE setPageStep) - - - public: - enum TimeParts {Whole, Polarity, Hours, Minutes, Seconds}; - - TimerEdit(QWidget *parent = Q_NULLPTR); - - int timeInSeconds() const; - int timepart(const QString &input, TimeParts part) const; - - bool showSeconds() const { return m_showSeconds; } - int minimumTime() const { return m_minTime; } - int maximumTime() const { return m_maxTime; } - unsigned int singleStep() const { return m_singleStep; } - unsigned int pageStep() const { return m_pageStep; } - - public slots: - void setTime(int seconds); - void incrDecr(int seconds); - void setTimeRange(int minSeconds, int maxSeconds); - void setMinimumTime(int minSeconds); - void setMaximumTime(int maxSeconds); - void setShowSeconds(bool showSeconds); - - void setSingleStep(unsigned int step) { m_singleStep = step; } - void setPageStep(unsigned int pageStep) { m_pageStep = pageStep; } - - protected: - void textEditedHandler(); - virtual void setupFormat(); - void emitValueChanged(); - void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; - void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; - - bool m_showSeconds; - int m_minTime; // seconds - int m_maxTime; // seconds - unsigned m_singleStep; // seconds - unsigned m_pageStep; // seconds - short m_hourDigits; - QRegularExpressionValidator * m_validator; -}; - -#endif // TIMEREDIT_H