refs #693, integrated GUI close dialog

* utility function in CGuiApplication containing the logic (dialog needed, ..)
* closeEvent function
This commit is contained in:
Klaus Basan
2016-06-30 03:12:59 +02:00
parent 6650f18e57
commit 18112a0394
8 changed files with 125 additions and 26 deletions

View File

@@ -217,6 +217,8 @@ namespace BlackCore
CLogMessage::preformatted(m);
}
// Settings are distributed via DBus. So only one application is responsible for saving. `enableLocalSave()` means
// "this is the application responsible for saving". If swiftgui requests a setting to be saved, it is sent to swiftcore and saved by swiftcore.
CSettingsCache::instance()->enableLocalSave();
}
@@ -344,6 +346,34 @@ namespace BlackCore
return env;
}
bool CApplication::hasUnsavedSettings() const
{
return !this->getAllUnsavedSettings().isEmpty();
}
void CApplication::setSettingsAutoSave(bool autoSave)
{
this->m_autoSaveSettings = autoSave;
}
QStringList CApplication::getAllUnsavedSettings() const
{
return CSettingsCache::instance()->getAllUnsavedKeys();
}
CStatusMessage CApplication::saveSettingsByKey(const QStringList &keys)
{
if (keys.isEmpty()) { return CStatusMessage(); }
if (this->supportsContexts())
{
return this->getIContextApplication()->saveSettingsByKey(keys);
}
else
{
return CSettingsCache::instance()->saveToStore(keys);
}
}
QString CApplication::getInfoString(const QString &separator) const
{
QString str(CVersion::version());
@@ -604,7 +634,7 @@ namespace BlackCore
CStatusMessage m;
if (this->m_parsed)
{
if (this->supportsContexts())
if (this->supportsContexts() && this->m_autoSaveSettings)
{
// this will eventually also call saveToStore
m = this->getIContextApplication()->saveSettings();
@@ -698,9 +728,9 @@ namespace BlackCore
return l;
}
// ---------------------------------------------------------------------------------
// Parsing
// ---------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------
// Parsing
// ---------------------------------------------------------------------------------
bool CApplication::addParserOption(const QCommandLineOption &option)
{
@@ -824,9 +854,9 @@ namespace BlackCore
printf("%s %s\n", qPrintable(QCoreApplication::applicationName()), qPrintable(QCoreApplication::applicationVersion()));
}
// ---------------------------------------------------------------------------------
// Contexts
// ---------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------
// Contexts
// ---------------------------------------------------------------------------------
bool CApplication::supportsContexts() const
{
@@ -896,9 +926,9 @@ namespace BlackCore
return this->m_coreFacade->getIContextSimulator();
}
// ---------------------------------------------------------------------------------
// Setup
// ---------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------
// Setup
// ---------------------------------------------------------------------------------
CUrlList CApplication::getVatsimMetarUrls() const
{

View File

@@ -161,6 +161,18 @@ namespace BlackCore
//! To string
QString getInfoString(const QString &separator) const;
//! Unsaved settings
bool hasUnsavedSettings() const;
//! Automatically and always save settings
void setSettingsAutoSave(bool autoSave);
//! All unsave settings
QStringList getAllUnsavedSettings() const;
//! Save all settings
BlackMisc::CStatusMessage saveSettingsByKey(const QStringList &keys);
//! Run event loop
static int exec();
@@ -226,6 +238,8 @@ namespace BlackCore
//! @{
//! Supports contexts
//! \remark checks the real availability of the contexts, so it can happen that we want to use contexts, and they are not yet initialized (false here)
//! \sa m_useContexts we use or we will use contexts
bool supportsContexts() const;
//! Init the contexts part and start core facade
@@ -402,6 +416,8 @@ namespace BlackCore
bool m_signalStartup = true; //!< signal startup automatically
bool m_devEnv = false; //!< dev. environment
bool m_unitTest = false; //!< is UNIT test
bool m_autoSaveSettings = true;//!< automatically saving all settings
};
} // namespace

View File

@@ -10,6 +10,7 @@
#include "blackconfig/buildconfig.h"
#include "blackcore/data/globalsetup.h"
#include "blackcore/data/updateinfo.h"
#include "blackgui/components/applicationclosedialog.h"
#include "blackgui/guiapplication.h"
#include "blackgui/guiutility.h"
#include "blackgui/registermetadata.h"
@@ -23,6 +24,7 @@
#include "blackmisc/verify.h"
#include <QAction>
#include <QCloseEvent>
#include <QApplication>
#include <QCommandLineParser>
#include <QCoreApplication>
@@ -40,11 +42,13 @@
#include <QStyle>
#include <QUrl>
#include <QWidget>
#include <QMainWindow>
#include <QtGlobal>
using namespace BlackConfig;
using namespace BlackMisc;
using namespace BlackMisc::Network;
using namespace BlackGui::Components;
using namespace BlackCore::Data;
BlackGui::CGuiApplication *sGui = nullptr; // set by constructor
@@ -486,12 +490,33 @@ namespace BlackGui
return m_styleSheetUtility.updateFonts(fontFamily, fontSize, fontStyle, fontWeight, fontColor);
}
QDialog::DialogCode CGuiApplication::showCloseDialog(QMainWindow *mainWindow, QCloseEvent *closeEvent)
{
bool needsDialog = this->hasUnsavedSettings();
if (!needsDialog) { return QDialog::Accepted; }
if (!this->m_closeDialog)
{
this->m_closeDialog = new CApplicationCloseDialog(mainWindow);
if (mainWindow && !mainWindow->windowTitle().isEmpty())
{
this->setSettingsAutoSave(false); // will be handled by dialog
this->m_closeDialog->setWindowTitle(mainWindow->windowTitle());
this->m_closeDialog->setModal(true);
}
}
const QDialog::DialogCode c = static_cast<QDialog::DialogCode>(this->m_closeDialog->exec());
if (c == QDialog::Rejected)
{
if (closeEvent) { closeEvent->ignore(); }
}
return c;
}
void CGuiApplication::cmdLineHelpMessage()
{
if (CBuildConfig::isRunningOnWindowsNtPlatform())
{
QMessageBox::information(nullptr,
QGuiApplication::applicationDisplayName(),
QMessageBox::information(nullptr, QGuiApplication::applicationDisplayName(),
"<html><head/><body><pre>" + this->m_parser.helpText() + "</pre></body></html>");
}
else
@@ -504,8 +529,7 @@ namespace BlackGui
{
if (CBuildConfig::isRunningOnWindowsNtPlatform())
{
QMessageBox::information(nullptr,
QGuiApplication::applicationDisplayName(),
QMessageBox::information(nullptr, QGuiApplication::applicationDisplayName(),
QGuiApplication::applicationDisplayName() + ' ' + QCoreApplication::applicationVersion());
}
else
@@ -518,5 +542,4 @@ namespace BlackGui
{
return true;
}
} // ns

View File

@@ -21,6 +21,7 @@
#include "blackmisc/statusmessage.h"
#include <QCommandLineOption>
#include <QDialog>
#include <QObject>
#include <QPixmap>
#include <QScopedPointer>
@@ -30,9 +31,10 @@
class QMenu;
class QSplashScreen;
class QWidget;
class QMainWindow;
namespace BlackMisc { class CLogCategoryList; }
namespace BlackGui { namespace Components { class CApplicationCloseDialog; }}
namespace BlackGui
{
/*!
@@ -138,6 +140,9 @@ namespace BlackGui
//! Update the fonts
bool updateFonts(const QString &fontFamily, const QString &fontSize, const QString &fontStyle, const QString &fontWeight, const QString &fontColor);
//! Show close dialog
QDialog::DialogCode showCloseDialog(QMainWindow *mainWindow, QCloseEvent *closeEvent);
//! Set icon
//! \note Pixmap requires a valid QApplication, so it cannot be passed as constructor parameter
static void setWindowIcon(const QPixmap &icon);
@@ -184,8 +189,9 @@ namespace BlackGui
QCommandLineOption m_cmdWindowStateMinimized { "empty" }; //!< window state (minimized)
QCommandLineOption m_cmdWindowMode { "empty" }; //!< window mode (flags: frameless ...)
CStyleSheetUtility m_styleSheetUtility{{}, this}; //!< style sheet utility
QScopedPointer<QSplashScreen> m_splashScreen; //!< splash screen
bool m_uiSetupCompleted = false; //!< ui setup completed
QScopedPointer<QSplashScreen> m_splashScreen; //!< splash screen
BlackGui::Components::CApplicationCloseDialog *m_closeDialog = nullptr; //!< close dialog (no QScopedPointer because I need to set parent)
//! Qt help message to formatted HTML
static QString beautifyHelpMessage(const QString &helpText);

View File

@@ -58,6 +58,16 @@ void CSwiftData::initStyleSheet()
CSwiftData::~CSwiftData()
{ }
void CSwiftData::closeEvent(QCloseEvent *event)
{
if (sGui)
{
// save settings
if (sGui->showCloseDialog(this, event) == QDialog::Rejected) { return; }
}
this->performGracefulShutdown();
}
void CSwiftData::ps_appendLogMessage(const CStatusMessage &message)
{
CLogComponent *logComponent = ui->comp_MainInfoArea->getLogComponent();

View File

@@ -46,6 +46,12 @@ public:
//! Destructor
~CSwiftData();
protected:
//! \name QMainWindow events
//! @[
virtual void closeEvent(QCloseEvent *event) override;
//! @}
private slots:
//! Append log message
void ps_appendLogMessage(const BlackMisc::CStatusMessage &message);

View File

@@ -131,9 +131,20 @@ void SwiftGuiStd::performGracefulShutdown()
void SwiftGuiStd::closeEvent(QCloseEvent *event)
{
Q_UNUSED(event);
if (sGui)
{
if (sGui->getIContextNetwork() && sGui->getIContextNetwork()->isConnected())
{
// we do not just logoff, but give the user a chance to respond
event->ignore();
QTimer::singleShot(500, this, &SwiftGuiStd::ps_loginRequested);
return;
}
// save settings
if (sGui->showCloseDialog(this, event) == QDialog::Rejected) { return; }
}
this->performGracefulShutdown();
CGuiApplication::exit();
}
void SwiftGuiStd::changeEvent(QEvent *event)

View File

@@ -80,17 +80,14 @@ signals:
void currentMainInfoAreaChanged(const QWidget *currentWidget);
protected:
//! \copydoc QMainWindow::mouseMoveEvent
//! \name QMainWindow events
//! @[
virtual void mouseMoveEvent(QMouseEvent *event) override;
//! \copydoc QMainWindow::mousePressEvent
virtual void mousePressEvent(QMouseEvent *event) override;
//! \copydoc QMainWindow::closeEvent
virtual void closeEvent(QCloseEvent *event) override;
//! \copydoc QMainWindow::changeEvent
virtual void changeEvent(QEvent *event) override;
//! @}
//! Get a minimize action which minimizes the window
QAction *getWindowMinimizeAction(QObject *parent);