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)
This commit is contained in:
Klaus Basan
2015-11-11 04:53:21 +01:00
committed by Mathew Sutcliffe
parent 63e1695e3b
commit 864ca20be3
10 changed files with 189 additions and 89 deletions

View File

@@ -10,8 +10,10 @@
#include "enableforframelesswindow.h" #include "enableforframelesswindow.h"
#include "blackmisc/icons.h" #include "blackmisc/icons.h"
#include "blackmisc/blackmiscfreefunctions.h" #include "blackmisc/blackmiscfreefunctions.h"
#include "blackmisc/worker.h"
#include <QStatusBar> #include <QStatusBar>
#include <QPushButton> #include <QPushButton>
#include <QThread>
using namespace BlackMisc; using namespace BlackMisc;
@@ -41,6 +43,20 @@ namespace BlackGui
setMode(frameless ? WindowFrameless : WindowTool); 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) CEnableForFramelessWindow::WindowMode CEnableForFramelessWindow::stringToWindowMode(const QString &s)
{ {
QString ws(s.trimmed().toLower()); 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 (m_windowMode == CEnableForFramelessWindow::WindowTool) { this->toolToNormalWindow(); }
if (this->m_windowMode == WindowFrameless && event->buttons() & Qt::LeftButton) this->m_widget->showMinimized();
{ }
this->m_widget->move(event->globalPos() - this->m_framelessDragPosition);
event->accept(); void CEnableForFramelessWindow::showNormalModeChecked()
return true; {
} if (m_windowMode == CEnableForFramelessWindow::WindowTool) { this->normalToToolWindow(); }
return false; this->m_widget->showMinimized();
} }
bool CEnableForFramelessWindow::handleMousePressEvent(QMouseEvent *event) bool CEnableForFramelessWindow::handleMousePressEvent(QMouseEvent *event)
@@ -120,6 +136,48 @@ namespace BlackGui
return false; 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) void CEnableForFramelessWindow::addFramelessSizeGripToStatusBar(QStatusBar *statusBar)
{ {
if (!statusBar) { return; } if (!statusBar) { return; }
@@ -183,14 +241,14 @@ namespace BlackGui
switch (mode) switch (mode)
{ {
case WindowFrameless: case WindowFrameless:
return (Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); return (Qt::Window | Qt::FramelessWindowHint);
case WindowTool: case WindowTool:
// tool window and minimized not supported on windows // tool window and minimized not supported on Windows
// tool window always with close button on windows // tool window always with close button on Windows
return (Qt::Tool | Qt::WindowStaysOnTopHint | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); return (Qt::Tool | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint);
case WindowNormal: case WindowNormal:
default: default:
return (Qt::Window | Qt::WindowStaysOnTopHint | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint); return (Qt::Window | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint);
} }
} }

View File

@@ -53,6 +53,9 @@ namespace BlackGui
//! The main application //! The main application
bool isMainApplicationWindow() const { return m_mainApplicationWindow; } bool isMainApplicationWindow() const { return m_mainApplicationWindow; }
//! Always on top?
void alwaysOnTop(bool onTop);
//! Corresponding QMainWindow //! Corresponding QMainWindow
QWidget *getWidget() const { return m_widget; } QWidget *getWidget() const { return m_widget; }
@@ -63,6 +66,14 @@ namespace BlackGui
static QString windowModeToString(WindowMode m); static QString windowModeToString(WindowMode m);
protected: 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 //! Resize grip handle
void addFramelessSizeGripToStatusBar(QStatusBar *statusBar); void addFramelessSizeGripToStatusBar(QStatusBar *statusBar);
@@ -87,24 +98,24 @@ namespace BlackGui
//! Tool window //! Tool window
bool isToolWindow() const; 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 //! Mouse press, required for frameless window
bool handleMousePressEvent(QMouseEvent *event); bool handleMousePressEvent(QMouseEvent *event);
//! Mouse moving, required for frameless window //! Mouse moving, required for frameless window
bool handleMouseMoveEvent(QMouseEvent *event); 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 } // namespace
#endif // guard #endif // guard

View File

@@ -127,15 +127,28 @@ namespace BlackMisc
const QString &CProject::swiftVersionString() const QString &CProject::swiftVersionString()
{ {
static const QString s(QString("swift %1").arg(version())); static const QString s(QString("swift %1").arg(versionStringDevBetaInfo()));
return s; return s;
} }
const QString &CProject::swiftVersionStringDevInfo() const QString &CProject::versionStringDevBetaInfo()
{ {
if (!isRunningInDeveloperEnvironment()) { return swiftVersionString(); } if (isRunningInDeveloperEnvironment() && isBetaTest())
static const QString s(swiftVersionString() + " [DEV]"); {
return s; 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() const char *CProject::swiftVersionChar()
@@ -154,6 +167,20 @@ namespace BlackMisc
return getMajorMinor(1); return getMajorMinor(1);
} }
bool CProject::isNewerVersion(const QString &versionString)
{
if (versionString.isEmpty()) { return false; }
QList<int> newer(getVersionParts(versionString));
QList<int> 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() bool CProject::isDebugBuild()
{ {
#ifdef QT_DEBUG #ifdef QT_DEBUG
@@ -213,13 +240,24 @@ namespace BlackMisc
return isBetaTest() || isRunningInDeveloperEnvironment(); return isBetaTest() || isRunningInDeveloperEnvironment();
} }
QList<int> CProject::getVersionParts(const QString &versionString)
{
QStringList parts = versionString.split('.');
QList<int> 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) int CProject::getMajorMinor(int index)
{ {
QString v = version(); QList<int> partsInt(getVersionParts(version()));
if (v.isEmpty() || !v.contains(".")) return -1; if (index >= partsInt.length()) { return -1; }
bool ok; return partsInt[index];
int vi = v.split(".")[index].toInt(&ok);
return ok ? vi : -1;
} }
const QString &CProject::envVarDevelopment() const QString &CProject::envVarDevelopment()
@@ -239,6 +277,24 @@ namespace BlackMisc
return s; 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() QString CProject::envVarPrivateSetupDirValue()
{ {
return QProcessEnvironment::systemEnvironment().value(envVarPrivateSetupDir()); return QProcessEnvironment::systemEnvironment().value(envVarPrivateSetupDir());

View File

@@ -66,18 +66,21 @@ namespace BlackMisc
//! System's name and version //! System's name and version
static const QString &swiftVersionString(); static const QString &swiftVersionString();
//! System's name and version + info if dev.environemnt
static const QString &swiftVersionStringDevInfo();
//! System's name and version //! System's name and version
static const char *swiftVersionChar(); static const char *swiftVersionChar();
//! System's name and version + info if dev.environment / beta
static const QString &versionStringDevBetaInfo();
//! Version major //! Version major
static int versionMajor(); static int versionMajor();
//! Version minor //! Version minor
static int versionMinor(); static int versionMinor();
//! Is the given string representing a newer version?
static bool isNewerVersion(const QString &versionString);
//! Debug build? //! Debug build?
static bool isDebugBuild(); static bool isDebugBuild();
@@ -132,10 +135,22 @@ namespace BlackMisc
//! Environment variable private resources directory //! Environment variable private resources directory
static const QString &envVarPrivateSetupDir(); 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: private:
//! Constructor //! Constructor
CProject() {} CProject() {}
//! Parts of version string 1.0.2
static QList<int> getVersionParts(const QString &versionString);
//! Split version //! Split version
static int getMajorMinor(int index); static int getMajorMinor(int index);

View File

@@ -28,7 +28,7 @@ using namespace BlackGui;
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QApplication a(argc, argv); QApplication a(argc, argv);
CGuiUtility::initSwiftGuiApplication(a, "swiftdata", CIcons::swiftDatabase24()); CGuiUtility::initSwiftGuiApplication(a, "swift mapping tool", CIcons::swiftDatabase24());
CSwiftData w; CSwiftData w;
w.show(); w.show();

View File

@@ -77,7 +77,7 @@ void CSwiftData::ps_onStyleSheetsChanged()
void CSwiftData::init() void CSwiftData::init()
{ {
this->setWindowIcon(CIcons::swiftDatabase24()); this->setWindowIcon(CIcons::swiftDatabase24());
this->setWindowTitle(QString("Mapping tool %1").arg(CProject::swiftVersionStringDevInfo())); this->setWindowTitle(QCoreApplication::instance()->applicationName() + " " + CProject::versionStringDevBetaInfo());
this->setObjectName("CSwiftData"); this->setObjectName("CSwiftData");
this->initStyleSheet(); this->initStyleSheet();
this->initLogDisplay(); this->initLogDisplay();

View File

@@ -102,7 +102,7 @@ int main(int argc, char *argv[])
{ {
QApplication a(argc, argv); QApplication a(argc, argv);
const QString appName("swift pilot client GUI"); const QString appName("swift pilot client GUI");
a.setApplicationVersion(CProject::swiftVersionString()); a.setApplicationVersion(CProject::version());
a.setApplicationName(appName); a.setApplicationName(appName);
// Process the actual command line arguments given by the user // Process the actual command line arguments given by the user

View File

@@ -55,18 +55,12 @@ SwiftGuiStd::~SwiftGuiStd()
void SwiftGuiStd::mouseMoveEvent(QMouseEvent *event) void SwiftGuiStd::mouseMoveEvent(QMouseEvent *event)
{ {
if (!handleMouseMoveEvent(event)) if (!handleMousePressEvent(event)) { QMainWindow::mouseMoveEvent(event); }
{
QMainWindow::mouseMoveEvent(event);
}
} }
void SwiftGuiStd::mousePressEvent(QMouseEvent *event) void SwiftGuiStd::mousePressEvent(QMouseEvent *event)
{ {
if (!handleMousePressEvent(event)) if (!handleMousePressEvent(event)) { QMainWindow::mousePressEvent(event); }
{
QMainWindow::mousePressEvent(event);
}
} }
void SwiftGuiStd::performGracefulShutdown() void SwiftGuiStd::performGracefulShutdown()
@@ -121,39 +115,7 @@ void SwiftGuiStd::closeEvent(QCloseEvent *event)
void SwiftGuiStd::changeEvent(QEvent *event) void SwiftGuiStd::changeEvent(QEvent *event)
{ {
if (event->type() == QEvent::WindowStateChange) if (!CEnableForFramelessWindow::handleChangeEvent(event)) { QMainWindow::changeEvent(event); }
{
// 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);
} }
QAction *SwiftGuiStd::getWindowMinimizeAction(QObject *parent) QAction *SwiftGuiStd::getWindowMinimizeAction(QObject *parent)
@@ -396,14 +358,12 @@ void SwiftGuiStd::ps_onChangedMainInfoAreaFloating(bool floating)
void SwiftGuiStd::ps_showMinimized() void SwiftGuiStd::ps_showMinimized()
{ {
if (m_windowMode == CEnableForFramelessWindow::WindowTool) { this->toolToNormalWindow(); } this->showMinimizedModeChecked();
this->showMinimized();
} }
void SwiftGuiStd::ps_showNormal() void SwiftGuiStd::ps_showNormal()
{ {
if (m_windowMode == CEnableForFramelessWindow::WindowTool) { this->normalToToolWindow(); } this->showNormalModeChecked();
this->showNormal();
} }
void SwiftGuiStd::playNotifcationSound(CNotificationSounds::Notification notification) const void SwiftGuiStd::playNotifcationSound(CNotificationSounds::Notification notification) const

View File

@@ -38,7 +38,7 @@ void SwiftGuiStd::init(const CRuntimeConfig &runtimeConfig)
// init window // init window
this->setWindowIcon(CIcons::swift24()); this->setWindowIcon(CIcons::swift24());
this->setWindowTitle(CProject::swiftVersionStringDevInfo()); this->setWindowTitle(CProject::versionStringDevBetaInfo());
this->setObjectName("SwiftGuiStd"); this->setObjectName("SwiftGuiStd");
this->initStyleSheet(); this->initStyleSheet();
QPoint pos = CGuiUtility::introWindowPosition(); QPoint pos = CGuiUtility::introWindowPosition();

View File

@@ -33,7 +33,7 @@ CIntroWindow::CIntroWindow(QWidget *parent) :
ui(new Ui::CIntroWindow) ui(new Ui::CIntroWindow)
{ {
ui->setupUi(this); ui->setupUi(this);
this->setWindowTitle(CProject::swiftVersionStringDevInfo()); this->setWindowTitle(CProject::versionStringDevBetaInfo());
this->layout()->setSizeConstraint(QLayout::SetFixedSize); this->layout()->setSizeConstraint(QLayout::SetFixedSize);
this->ui->cb_DBusServer->addItem(CDBusServer::sessionDBusServer()); this->ui->cb_DBusServer->addItem(CDBusServer::sessionDBusServer());
this->ui->cb_DBusServer->addItem(CDBusServer::systemDBusServer()); this->ui->cb_DBusServer->addItem(CDBusServer::systemDBusServer());