From 5dd5f367dfcecab75077c3cb4ca1f01113fc1561 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Enar=20V=C3=A4ikene?= Date: Thu, 1 Dec 2011 16:08:19 +0200 Subject: [PATCH] In the process of creating a more generic document interface manager (or window manager) interface. * Now adds panels instead of windows - one becomes part of the main windows; others act as separate windows. * Can manage multiple windows - when the main window is closed, closes all the other managed windows; - when the main window is minimized/restores, does the same for all the other managed windows. * XML file attribute 'mainPanelName' is used to set the main panel; if no attribute is set, uses the first panel. * Panels can be deleted externally; a garbage collector makes sure that the list of managed windows does not grow forever if somebody decides to add/delete millions of panels. --- src/plugins/SdiWindow/isdiwindow.h | 31 ++++- src/plugins/SdiWindow/sdiwindow.cpp | 199 +++++++++++++++++++++++----- src/plugins/SdiWindow/sdiwindow.h | 45 ++++++- src/plugins/SdiWindow/version.h | 4 +- 4 files changed, 238 insertions(+), 41 deletions(-) diff --git a/src/plugins/SdiWindow/isdiwindow.h b/src/plugins/SdiWindow/isdiwindow.h index 13b9903..4e0e43d 100644 --- a/src/plugins/SdiWindow/isdiwindow.h +++ b/src/plugins/SdiWindow/isdiwindow.h @@ -31,7 +31,7 @@ class QLayout; namespace eVaf { namespace Gui { - class Window; + class Panel; } // namespace eVaf::Gui namespace SdiWindow { @@ -54,12 +54,33 @@ struct SDIWINDOW_EXPORT iSdiWindow static iSdiWindow * instance(); /** - * Adds the window to the main SDI window - * @param window The window + * Adds a panel to the SDI window manager + * @param name Name of the panel + * @param panel The panel * - * This function adds a window to the main SDI layout. + * This function adds a panel to the SDI window manager. The ownership of the panel + * is transferred to the window manager and it is the responsibility of the window + * manager to delete it. */ - virtual void addWindow(Gui::Window * window) = 0; + virtual void addPanel(QString const & name, Gui::Panel * panel) = 0; + + /** + * Returns a panel by the name + * @param name Name of the panel + * @return Pointer to the panel or 0 if failed + * + * This function returns a panel identified by the name. + */ + virtual Gui::Panel * panel(QString const & name) const = 0; + + /** + * Shows a panel + * @param name Name of the panel + * @return True if succeeded; false if not + * + * This function shows the panel. + */ + virtual bool showPanel(QString const & name) = 0; }; diff --git a/src/plugins/SdiWindow/sdiwindow.cpp b/src/plugins/SdiWindow/sdiwindow.cpp index aa264de..c0e3587 100644 --- a/src/plugins/SdiWindow/sdiwindow.cpp +++ b/src/plugins/SdiWindow/sdiwindow.cpp @@ -23,8 +23,10 @@ #include #include #include +#include #include +#include namespace eVaf { namespace SdiWindow { @@ -40,28 +42,25 @@ using namespace eVaf; //------------------------------------------------------------------- -using namespace eVaf::SdiWindow; - -iSdiWindow * iSdiWindow::instance() +SdiWindow::iSdiWindow * SdiWindow::iSdiWindow::instance() { - return Internal::mSdiWindow; + return SdiWindow::Internal::mSdiWindow; } //------------------------------------------------------------------- -using namespace eVaf::SdiWindow::Internal; - -MainWindow::MainWindow(QWidget * parent, Qt::WindowFlags flags) +SdiWindow::Internal::MainWindow::MainWindow(QWidget * parent, Qt::WindowFlags flags) : QWidget(parent, flags) , mReady(false) + , mTimerId(0) { setObjectName(QString("%1-%2").arg(VER_MODULE_NAME_STR).arg(__FUNCTION__)); // Restore geometry restoreSettings(); - // Apply the size specified in a) properties; or b) on the command line + // Apply the size specified in a) properties; or b) on the command line (overwrites stored geometry) setWindowSize(); // Create the default layout @@ -73,7 +72,7 @@ MainWindow::MainWindow(QWidget * parent, Qt::WindowFlags flags) EVAF_INFO("%s created", qPrintable(objectName())); } -MainWindow::~MainWindow() +SdiWindow::Internal::MainWindow::~MainWindow() { mSdiWindow = 0; @@ -83,14 +82,30 @@ MainWindow::~MainWindow() EVAF_INFO("%s destroyed", qPrintable(objectName())); } -bool MainWindow::init(QString const & args) +QString SdiWindow::Internal::MainWindow::getMainPanelName(QString const & args) const +{ + QXmlStreamReader xml(args); + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement() && xml.name() == "attributes") { + if (xml.attributes().hasAttribute("mainPanelName")) + return xml.attributes().value("mainPanelName").toString(); + } + } + return QString(); +} + +bool SdiWindow::Internal::MainWindow::init(QString const & args) { - Q_UNUSED(args); + mMainPanelName = getMainPanelName(args); Common::iRegistry::instance()->registerInterface("iSdiWindow", this); setWindowTitle(Common::iApp::instance()->name()); + // Start the garbage collector timer + mTimerId = startTimer(60 * 1000); + show(); mReady = true; @@ -100,29 +115,73 @@ bool MainWindow::init(QString const & args) return true; } -void MainWindow::done() +void SdiWindow::Internal::MainWindow::done() { mReady = false; close(); - // Delete the window - if (mWindow) - delete mWindow.data(); + if (mTimerId) { + killTimer(mTimerId); + mTimerId = 0; + } + + // Delete all the panels + for (int i = mPanels.size() - 1; i >= 0; --i) { + QWeakPointer p = mPanels.at(i); + if (p) + delete p.data(); + } + mPanels.clear(); + mMinimizedPanels.clear(); + mPanelNames.clear(); + mMainPanel.clear(); + mMainPanelName.clear(); EVAF_INFO("%s finalized", qPrintable(objectName())); } -void MainWindow::addWindow(Gui::Window * window) +void SdiWindow::Internal::MainWindow::addPanel(QString const & name, Gui::Panel * panel) +{ + mPanels.append(panel); + mPanelNames.insert(name, panel); + + // If this is the predefined main panel, add it to this window + if (!mMainPanelName.isEmpty()) { + if (name == mMainPanelName) { + mMainPanel = panel; + mLayout->addWidget(panel); + } + } + + // If the predefined main panel name is not set, use the first panel + else { + if (!mMainPanel) { + mMainPanel = panel; + mLayout->addWidget(panel); + } + } +} + +Gui::Panel * SdiWindow::Internal::MainWindow::panel(QString const & name) const +{ + QHash >::const_iterator it = mPanelNames.constFind(name); + if (it != mPanelNames.constEnd()) + return it.value().data(); + return 0; +} + +bool SdiWindow::Internal::MainWindow::showPanel(QString const & name) { - // Delete the existing window - if (mWindow) - delete mWindow.data(); - mLayout->addWidget(window); - mWindow = window; + Gui::Panel * p = panel(name); + if (p) { + p->show(); + return true; + } + return false; } -void MainWindow::saveSettings() +void SdiWindow::Internal::MainWindow::saveSettings() { static int ver[4] = {VER_FILE_VERSION}; QSettings settings(VER_COMPANY_NAME_STR, Common::iApp::instance()->name()); @@ -131,7 +190,7 @@ void MainWindow::saveSettings() settings.setValue(QString("%1/geometry").arg(objectName()), saveGeometry()); } -void MainWindow::restoreSettings() +void SdiWindow::Internal::MainWindow::restoreSettings() { static int ver[4] = {VER_FILE_VERSION}; QSettings settings(VER_COMPANY_NAME_STR, Common::iApp::instance()->name()); @@ -149,11 +208,11 @@ void MainWindow::restoreSettings() restoreGeometry(settings.value(QString("%1/geometry").arg(objectName())).toByteArray()); } -void MainWindow::setWindowSize() +void SdiWindow::Internal::MainWindow::setWindowSize() { // a) Get window size from properties - int w = 0; - int h = 0; + int w = Common::iProp::instance()->getValue("windowWidth", 0).toInt(); + int h = Common::iProp::instance()->getValue("windowHeight", 0).toInt(); // b) Use command line arguments QStringList args = QApplication::arguments(); @@ -184,10 +243,90 @@ void MainWindow::setWindowSize() } } +void SdiWindow::Internal::MainWindow::closeEvent(QCloseEvent * e) +{ + // Try to close all the managed panels; ignore the event if one of the managed panels refuses to close + foreach (QWeakPointer p, mPanels) { + if (p) { + if (!p.data()->close()) { + e->ignore(); + return; + } + } + } + + QWidget::closeEvent(e); +} + +void SdiWindow::Internal::MainWindow::changeEvent(QEvent * e) +{ + if (e->type() == QEvent::WindowStateChange) { + QWindowStateChangeEvent * wse = static_cast(e); + + if (windowState() == Qt::WindowNoState && wse->oldState() == Qt::WindowMinimized) { + + // Restore all the managed panels that were previously minimized + foreach (QWeakPointer p, mMinimizedPanels) { + if (p && p.data()->isVisible()) + p.data()->showNormal(); + } + mMinimizedPanels.clear(); + } + + else if (windowState() == Qt::WindowMinimized && wse->oldState() != Qt::WindowMinimized) { + + // Minimize all the managed panels that are not minimized yet + mMinimizedPanels.clear(); + foreach (QWeakPointer p, mPanels) { + if (!p) + continue; + + if (p.data()->windowState() != Qt::WindowMinimized && p.data()->isVisible()) { + mMinimizedPanels.append(p); + p.data()->showMinimized(); + } + } + } + } + QWidget::changeEvent(e); +} + +void SdiWindow::Internal::MainWindow::timerEvent(QTimerEvent * e) +{ + if (e->timerId() == mTimerId) { + + // Remove panels that are deleted + { + QList >::iterator it = mPanels.begin(); + while (it != mPanels.end()) { + QWeakPointer p = *it; + if (!p) + it = mPanels.erase(it); + else + ++it; + } + } + + // Do the same with panel names + { + QHash >::iterator it = mPanelNames.begin(); + while (it != mPanelNames.end()) { + QWeakPointer p = it.value(); + if (!p) + it = mPanelNames.erase(it); + else + ++it; + } + } + } + else + QWidget::timerEvent(e); +} + //------------------------------------------------------------------- -SdiWindowPlugin::SdiWindowPlugin() +SdiWindow::Internal::SdiWindowPlugin::SdiWindowPlugin() : Plugins::iPlugin() { setObjectName(VER_MODULE_NAME_STR); @@ -197,14 +336,14 @@ SdiWindowPlugin::SdiWindowPlugin() EVAF_INFO("%s created", qPrintable(objectName())); } -SdiWindowPlugin::~SdiWindowPlugin() +SdiWindow::Internal::SdiWindowPlugin::~SdiWindowPlugin() { delete mWindow; EVAF_INFO("%s destroyed", qPrintable(objectName())); } -bool SdiWindowPlugin::init(const QString & args) +bool SdiWindow::Internal::SdiWindowPlugin::init(const QString & args) { if (!mWindow->init(args)) return false; @@ -214,7 +353,7 @@ bool SdiWindowPlugin::init(const QString & args) return true; } -void SdiWindowPlugin::done() +void SdiWindow::Internal::SdiWindowPlugin::done() { mWindow->done(); diff --git a/src/plugins/SdiWindow/sdiwindow.h b/src/plugins/SdiWindow/sdiwindow.h index f884255..757ed28 100644 --- a/src/plugins/SdiWindow/sdiwindow.h +++ b/src/plugins/SdiWindow/sdiwindow.h @@ -23,12 +23,14 @@ #include "isdiwindow.h" #include -#include +#include #include #include #include #include +#include +#include #include class QVBoxLayout; @@ -57,7 +59,21 @@ public: virtual bool isReady() { return mReady; } - virtual void addWindow(Gui::Window * window); + virtual void addPanel(QString const & name, Gui::Panel * panel); + + virtual Gui::Panel * panel(QString const & name) const; + + virtual bool showPanel(QString const & name); + + virtual void changeEvent(QEvent * e); + + virtual void closeEvent(QCloseEvent * e); + + +protected: // Methods + + /// Garbage collector timer + virtual void timerEvent(QTimerEvent * e); private: // Methods @@ -77,8 +93,29 @@ private: // Members /// The layout of the main window QVBoxLayout * mLayout; - /// eVaf GUI window implementing the main window - QWeakPointer mWindow; + /// Name of the main panel that becomes part of this window + QString mMainPanelName; + + /// List of GUI::Panel objects added to the manager + QList > mPanels; + + /// List of minimized GUI::Panel objects + QVector > mMinimizedPanels; + + /// Hash with panel names + QHash > mPanelNames; + + /// Current main panel added to this window + QWeakPointer mMainPanel; + + /// Garbage collector timer ID + int mTimerId; + + +private: // Methods + + /// Gets the main panel name from module attributes + QString getMainPanelName(QString const & args) const; }; diff --git a/src/plugins/SdiWindow/version.h b/src/plugins/SdiWindow/version.h index f3fedec..c47549d 100644 --- a/src/plugins/SdiWindow/version.h +++ b/src/plugins/SdiWindow/version.h @@ -25,12 +25,12 @@ /** * Module/library version number in the form major,minor,release,build */ -#define VER_FILE_VERSION 0,3,1,6 +#define VER_FILE_VERSION 0,4,1,7 /** * Module/library version number in the string format (shall end with \0) */ -#define VER_FILE_VERSION_STR "0.3.1.6\0" +#define VER_FILE_VERSION_STR "0.4.1.7\0" /** * Module/library name (shall end with \0) -- 2.45.0