From 864ca20be3b99dfb98984edeb28f8dd0ecf5ef17 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Wed, 11 Nov 2015 04:53:21 +0100 Subject: [PATCH] refs #507, improvements on frameless window base class * handle minimized / normal in window base class * removed initial on top flag and project * executable names * version number check (for launcher) --- src/blackgui/enableforframelesswindow.cpp | 86 +++++++++++++++++++---- src/blackgui/enableforframelesswindow.h | 35 +++++---- src/blackmisc/project.cpp | 76 +++++++++++++++++--- src/blackmisc/project.h | 21 +++++- src/swiftdata/main.cpp | 2 +- src/swiftdata/swiftdata.cpp | 2 +- src/swiftguistandard/main.cpp | 2 +- src/swiftguistandard/swiftguistd.cpp | 50 ++----------- src/swiftguistandard/swiftguistd_init.cpp | 2 +- src/swiftlauncher/introwindow.cpp | 2 +- 10 files changed, 189 insertions(+), 89 deletions(-) diff --git a/src/blackgui/enableforframelesswindow.cpp b/src/blackgui/enableforframelesswindow.cpp index f1d6b0d59..93fef85bc 100644 --- a/src/blackgui/enableforframelesswindow.cpp +++ b/src/blackgui/enableforframelesswindow.cpp @@ -10,8 +10,10 @@ #include "enableforframelesswindow.h" #include "blackmisc/icons.h" #include "blackmisc/blackmiscfreefunctions.h" +#include "blackmisc/worker.h" #include #include +#include using namespace BlackMisc; @@ -41,6 +43,20 @@ namespace BlackGui setMode(frameless ? WindowFrameless : WindowTool); } + void CEnableForFramelessWindow::alwaysOnTop(bool onTop) + { + Qt::WindowFlags flags = this->m_widget->windowFlags(); + if (onTop) + { + flags |= Qt::WindowStaysOnTopHint; + } + else + { + flags &= ~Qt::WindowStaysOnTopHint; + } + this->m_widget->setWindowFlags(flags); + } + CEnableForFramelessWindow::WindowMode CEnableForFramelessWindow::stringToWindowMode(const QString &s) { QString ws(s.trimmed().toLower()); @@ -96,16 +112,16 @@ namespace BlackGui } } - bool CEnableForFramelessWindow::handleMouseMoveEvent(QMouseEvent *event) + void CEnableForFramelessWindow::showMinimizedModeChecked() { - Q_ASSERT(this->m_widget); - if (this->m_windowMode == WindowFrameless && event->buttons() & Qt::LeftButton) - { - this->m_widget->move(event->globalPos() - this->m_framelessDragPosition); - event->accept(); - return true; - } - return false; + if (m_windowMode == CEnableForFramelessWindow::WindowTool) { this->toolToNormalWindow(); } + this->m_widget->showMinimized(); + } + + void CEnableForFramelessWindow::showNormalModeChecked() + { + if (m_windowMode == CEnableForFramelessWindow::WindowTool) { this->normalToToolWindow(); } + this->m_widget->showMinimized(); } bool CEnableForFramelessWindow::handleMousePressEvent(QMouseEvent *event) @@ -120,6 +136,48 @@ namespace BlackGui return false; } + bool CEnableForFramelessWindow::handleMouseMoveEvent(QMouseEvent *event) + { + Q_ASSERT(this->m_widget); + if (this->m_windowMode == WindowFrameless && event->buttons() & Qt::LeftButton) + { + this->m_widget->move(event->globalPos() - this->m_framelessDragPosition); + event->accept(); + return true; + } + return false; + } + + bool CEnableForFramelessWindow::handleChangeEvent(QEvent *event) + { + if (event->type() != QEvent::WindowStateChange) { return false; } + if (m_windowMode != WindowTool) { return false; } + + // make sure a tool window is changed to Normal window so it is show in taskbar + // here we are already in transition state, so isMinimized means will be minimize right now + // this check here is needed if minimized is called from somewhere else than ps_showMinimized + if (m_widget->isMinimized()) + { + // still tool, force normal window + // decouple, otherwise we end up in infinite loop as it triggers a new changeEvent + BlackMisc::singleShot(0, QThread::currentThread(), [ = ]() + { + this->showMinimizedModeChecked(); + }); + } + else + { + // not tool, force tool window + // decouple, otherwise we end up in infinite loop as it triggers a new changeEvent + BlackMisc::singleShot(0, QThread::currentThread(), [ = ]() + { + this->showNormalModeChecked(); + }); + } + event->accept(); + return true; + } + void CEnableForFramelessWindow::addFramelessSizeGripToStatusBar(QStatusBar *statusBar) { if (!statusBar) { return; } @@ -183,14 +241,14 @@ namespace BlackGui switch (mode) { case WindowFrameless: - return (Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); + return (Qt::Window | Qt::FramelessWindowHint); case WindowTool: - // tool window and minimized not supported on windows - // tool window always with close button on windows - return (Qt::Tool | Qt::WindowStaysOnTopHint | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); + // tool window and minimized not supported on Windows + // tool window always with close button on Windows + return (Qt::Tool | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); case WindowNormal: default: - return (Qt::Window | Qt::WindowStaysOnTopHint | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); + return (Qt::Window | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); } } diff --git a/src/blackgui/enableforframelesswindow.h b/src/blackgui/enableforframelesswindow.h index 12823daba..e991a6d8d 100644 --- a/src/blackgui/enableforframelesswindow.h +++ b/src/blackgui/enableforframelesswindow.h @@ -53,6 +53,9 @@ namespace BlackGui //! The main application bool isMainApplicationWindow() const { return m_mainApplicationWindow; } + //! Always on top? + void alwaysOnTop(bool onTop); + //! Corresponding QMainWindow QWidget *getWidget() const { return m_widget; } @@ -63,6 +66,14 @@ namespace BlackGui static QString windowModeToString(WindowMode m); protected: + QPoint m_framelessDragPosition; //!< position, if moving is handled with frameless window */ + QPushButton *m_framelessCloseButton = nullptr; //!< close button + WindowMode m_windowMode = WindowNormal; //!< Window mode, \sa WindowMode + bool m_mainApplicationWindow = false; //!< is the main application window (only 1) + QWidget *m_widget = nullptr; //!< corresponding main window or dock widget + QSizeGrip *m_framelessSizeGrip = nullptr; //!< size grip object + QByteArray m_framelessPropertyName; //!< property name for frameless widgets + //! Resize grip handle void addFramelessSizeGripToStatusBar(QStatusBar *statusBar); @@ -87,24 +98,24 @@ namespace BlackGui //! Tool window bool isToolWindow() const; - //! Translate mode - static Qt::WindowFlags modeToWindowFlags(WindowMode mode); - - QPoint m_framelessDragPosition; //!< position, if moving is handled with frameless window */ - QPushButton *m_framelessCloseButton = nullptr; //!< close button - WindowMode m_windowMode = WindowTool; //!< Window mode, \sa WindowMode - bool m_mainApplicationWindow = false; //!< is the main application window (only 1) - QWidget *m_widget = nullptr; //!< corresponding main window or dock widget - QSizeGrip *m_framelessSizeGrip = nullptr; //!< size grip object - QByteArray m_framelessPropertyName; //!< property name for frameless widgets - //! Mouse press, required for frameless window bool handleMousePressEvent(QMouseEvent *event); //! Mouse moving, required for frameless window bool handleMouseMoveEvent(QMouseEvent *event); - }; + //! Mouse window change event + bool handleChangeEvent(QEvent *event); + + //! Check mode and then show minimized + void showMinimizedModeChecked(); + + //! Check mode and then show normal + void showNormalModeChecked(); + + //! Translate mode + static Qt::WindowFlags modeToWindowFlags(WindowMode mode); + }; } // namespace #endif // guard diff --git a/src/blackmisc/project.cpp b/src/blackmisc/project.cpp index b3e336f61..c3fd21502 100644 --- a/src/blackmisc/project.cpp +++ b/src/blackmisc/project.cpp @@ -127,15 +127,28 @@ namespace BlackMisc const QString &CProject::swiftVersionString() { - static const QString s(QString("swift %1").arg(version())); + static const QString s(QString("swift %1").arg(versionStringDevBetaInfo())); return s; } - const QString &CProject::swiftVersionStringDevInfo() + const QString &CProject::versionStringDevBetaInfo() { - if (!isRunningInDeveloperEnvironment()) { return swiftVersionString(); } - static const QString s(swiftVersionString() + " [DEV]"); - return s; + if (isRunningInDeveloperEnvironment() && isBetaTest()) + { + static const QString s(version() + " [DEV, BETA]"); + return s; + } + if (isRunningInDeveloperEnvironment()) + { + static const QString s(version() + " [DEV]"); + return s; + } + if (isBetaTest()) + { + static const QString s(version() + " [BETA]"); + return s; + } + return version(); } const char *CProject::swiftVersionChar() @@ -154,6 +167,20 @@ namespace BlackMisc return getMajorMinor(1); } + bool CProject::isNewerVersion(const QString &versionString) + { + if (versionString.isEmpty()) { return false; } + QList newer(getVersionParts(versionString)); + QList current(getVersionParts(version())); + for (int i = 0; i < current.length(); i++) + { + if (newer.length() <= i) { return false; } + if (current.at(i) > newer.at(i)) { return false; } + if (current.at(i) < newer.at(i)) { return true; } + } + return true; + } + bool CProject::isDebugBuild() { #ifdef QT_DEBUG @@ -213,13 +240,24 @@ namespace BlackMisc return isBetaTest() || isRunningInDeveloperEnvironment(); } + QList CProject::getVersionParts(const QString &versionString) + { + QStringList parts = versionString.split('.'); + QList partsInt; + for (const QString &p : parts) + { + bool ok = false; + int pInt = p.toInt(&ok); + partsInt.append(ok ? pInt : -1); + } + return partsInt; + } + int CProject::getMajorMinor(int index) { - QString v = version(); - if (v.isEmpty() || !v.contains(".")) return -1; - bool ok; - int vi = v.split(".")[index].toInt(&ok); - return ok ? vi : -1; + QList partsInt(getVersionParts(version())); + if (index >= partsInt.length()) { return -1; } + return partsInt[index]; } const QString &CProject::envVarDevelopment() @@ -239,6 +277,24 @@ namespace BlackMisc return s; } + const QString &CProject::swiftGuiExecutableName() + { + static const QString s("swiftguistd"); + return s; + } + + const QString &CProject::swiftCoreExecutableName() + { + static const QString s("swiftcore"); + return s; + } + + const QString &CProject::swiftDataExecutableName() + { + static const QString s("swiftdata"); + return s; + } + QString CProject::envVarPrivateSetupDirValue() { return QProcessEnvironment::systemEnvironment().value(envVarPrivateSetupDir()); diff --git a/src/blackmisc/project.h b/src/blackmisc/project.h index 437c42049..3ccd5139a 100644 --- a/src/blackmisc/project.h +++ b/src/blackmisc/project.h @@ -66,18 +66,21 @@ namespace BlackMisc //! System's name and version static const QString &swiftVersionString(); - //! System's name and version + info if dev.environemnt - static const QString &swiftVersionStringDevInfo(); - //! System's name and version static const char *swiftVersionChar(); + //! System's name and version + info if dev.environment / beta + static const QString &versionStringDevBetaInfo(); + //! Version major static int versionMajor(); //! Version minor static int versionMinor(); + //! Is the given string representing a newer version? + static bool isNewerVersion(const QString &versionString); + //! Debug build? static bool isDebugBuild(); @@ -132,10 +135,22 @@ namespace BlackMisc //! Environment variable private resources directory static const QString &envVarPrivateSetupDir(); + //! Executable name for swift GUI, no(!) appendix + static const QString &swiftGuiExecutableName(); + + //! Executable name for swift core, no(!) appendix + static const QString &swiftCoreExecutableName(); + + //! Executable name for swift data, no(!) appendix + static const QString &swiftDataExecutableName(); + private: //! Constructor CProject() {} + //! Parts of version string 1.0.2 + static QList getVersionParts(const QString &versionString); + //! Split version static int getMajorMinor(int index); diff --git a/src/swiftdata/main.cpp b/src/swiftdata/main.cpp index 4dc024729..63d9068a0 100644 --- a/src/swiftdata/main.cpp +++ b/src/swiftdata/main.cpp @@ -28,7 +28,7 @@ using namespace BlackGui; int main(int argc, char *argv[]) { QApplication a(argc, argv); - CGuiUtility::initSwiftGuiApplication(a, "swiftdata", CIcons::swiftDatabase24()); + CGuiUtility::initSwiftGuiApplication(a, "swift mapping tool", CIcons::swiftDatabase24()); CSwiftData w; w.show(); diff --git a/src/swiftdata/swiftdata.cpp b/src/swiftdata/swiftdata.cpp index 20853ffd9..af99ef065 100644 --- a/src/swiftdata/swiftdata.cpp +++ b/src/swiftdata/swiftdata.cpp @@ -77,7 +77,7 @@ void CSwiftData::ps_onStyleSheetsChanged() void CSwiftData::init() { this->setWindowIcon(CIcons::swiftDatabase24()); - this->setWindowTitle(QString("Mapping tool %1").arg(CProject::swiftVersionStringDevInfo())); + this->setWindowTitle(QCoreApplication::instance()->applicationName() + " " + CProject::versionStringDevBetaInfo()); this->setObjectName("CSwiftData"); this->initStyleSheet(); this->initLogDisplay(); diff --git a/src/swiftguistandard/main.cpp b/src/swiftguistandard/main.cpp index 8c8435263..fc87720ab 100644 --- a/src/swiftguistandard/main.cpp +++ b/src/swiftguistandard/main.cpp @@ -102,7 +102,7 @@ int main(int argc, char *argv[]) { QApplication a(argc, argv); const QString appName("swift pilot client GUI"); - a.setApplicationVersion(CProject::swiftVersionString()); + a.setApplicationVersion(CProject::version()); a.setApplicationName(appName); // Process the actual command line arguments given by the user diff --git a/src/swiftguistandard/swiftguistd.cpp b/src/swiftguistandard/swiftguistd.cpp index 7021ac564..678aa2067 100644 --- a/src/swiftguistandard/swiftguistd.cpp +++ b/src/swiftguistandard/swiftguistd.cpp @@ -55,18 +55,12 @@ SwiftGuiStd::~SwiftGuiStd() void SwiftGuiStd::mouseMoveEvent(QMouseEvent *event) { - if (!handleMouseMoveEvent(event)) - { - QMainWindow::mouseMoveEvent(event); - } + if (!handleMousePressEvent(event)) { QMainWindow::mouseMoveEvent(event); } } void SwiftGuiStd::mousePressEvent(QMouseEvent *event) { - if (!handleMousePressEvent(event)) - { - QMainWindow::mousePressEvent(event); - } + if (!handleMousePressEvent(event)) { QMainWindow::mousePressEvent(event); } } void SwiftGuiStd::performGracefulShutdown() @@ -121,39 +115,7 @@ void SwiftGuiStd::closeEvent(QCloseEvent *event) void SwiftGuiStd::changeEvent(QEvent *event) { - if (event->type() == QEvent::WindowStateChange) - { - // make sure a tool window is changed to Normal window so it is show in taskbar - // here we are already in transition state, so isMinimized means will be minimize right now - // this check here is needed if minimized is called from somewhere else than ps_showMinimized - if (!this->isFrameless()) - { - bool toolWindow(this->isToolWindow()); - if (isMinimized()) - { - if (toolWindow) - { - // still tool, force normal window - BlackMisc::singleShot(0, QThread::currentThread(), [ = ]() - { - this->ps_showMinimized(); - }); - } - } - else - { - if (!toolWindow) - { - // not tool, force tool window - BlackMisc::singleShot(0, QThread::currentThread(), [ = ]() - { - this->ps_showNormal(); - }); - } - } - } // frameless? - } - QMainWindow::changeEvent(event); + if (!CEnableForFramelessWindow::handleChangeEvent(event)) { QMainWindow::changeEvent(event); } } QAction *SwiftGuiStd::getWindowMinimizeAction(QObject *parent) @@ -396,14 +358,12 @@ void SwiftGuiStd::ps_onChangedMainInfoAreaFloating(bool floating) void SwiftGuiStd::ps_showMinimized() { - if (m_windowMode == CEnableForFramelessWindow::WindowTool) { this->toolToNormalWindow(); } - this->showMinimized(); + this->showMinimizedModeChecked(); } void SwiftGuiStd::ps_showNormal() { - if (m_windowMode == CEnableForFramelessWindow::WindowTool) { this->normalToToolWindow(); } - this->showNormal(); + this->showNormalModeChecked(); } void SwiftGuiStd::playNotifcationSound(CNotificationSounds::Notification notification) const diff --git a/src/swiftguistandard/swiftguistd_init.cpp b/src/swiftguistandard/swiftguistd_init.cpp index 9ee264a10..28e5dc8f7 100644 --- a/src/swiftguistandard/swiftguistd_init.cpp +++ b/src/swiftguistandard/swiftguistd_init.cpp @@ -38,7 +38,7 @@ void SwiftGuiStd::init(const CRuntimeConfig &runtimeConfig) // init window this->setWindowIcon(CIcons::swift24()); - this->setWindowTitle(CProject::swiftVersionStringDevInfo()); + this->setWindowTitle(CProject::versionStringDevBetaInfo()); this->setObjectName("SwiftGuiStd"); this->initStyleSheet(); QPoint pos = CGuiUtility::introWindowPosition(); diff --git a/src/swiftlauncher/introwindow.cpp b/src/swiftlauncher/introwindow.cpp index dda9a52a5..a7fe8b784 100644 --- a/src/swiftlauncher/introwindow.cpp +++ b/src/swiftlauncher/introwindow.cpp @@ -33,7 +33,7 @@ CIntroWindow::CIntroWindow(QWidget *parent) : ui(new Ui::CIntroWindow) { ui->setupUi(this); - this->setWindowTitle(CProject::swiftVersionStringDevInfo()); + this->setWindowTitle(CProject::versionStringDevBetaInfo()); this->layout()->setSizeConstraint(QLayout::SetFixedSize); this->ui->cb_DBusServer->addItem(CDBusServer::sessionDBusServer()); this->ui->cb_DBusServer->addItem(CDBusServer::systemDBusServer());