/** * @file SdiWindow/sdiwindow.cpp * @brief SdiWindow module's implementation * @author Enar Vaikene * * Copyright (c) 2011 Enar Vaikene * * This file is part of the eVaf C++ cross-platform application development framework. * * This file can be used under the terms of the GNU General Public License * version 3.0 as published by the Free Software Foundation and appearing in * the file LICENSE included in the packaging of this file. Please review the * the following information to ensure the GNU General Public License version * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html. * * Alternatively, this file may be used in accordance with the Commercial License * Agreement provided with the Software. */ #include "sdiwindow.h" #include "version.h" #include #include #include #include #include #include namespace eVaf { namespace SdiWindow { namespace Internal { /// iSdiWindow interface instance singleton static iSdiWindow * mSdiWindow = 0; } // namespace eVaf::SdiWindow::Internal } // namespace eVaf::SdiWindow } // namespace eVaf using namespace eVaf; //------------------------------------------------------------------- SdiWindow::iSdiWindow * SdiWindow::iSdiWindow::instance() { return SdiWindow::Internal::mSdiWindow; } //------------------------------------------------------------------- SdiWindow::Internal::MainWindow::MainWindow(QWidget * parent, Qt::WindowFlags flags) : QWidget(parent, flags) , mReady(false) , mMainPanel(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 (overwrites stored geometry) setWindowSize(); // Create the default layout mLayout = new QVBoxLayout; setLayout(mLayout); mSdiWindow = this; EVAF_INFO("%s created", qPrintable(objectName())); } SdiWindow::Internal::MainWindow::~MainWindow() { mSdiWindow = 0; // Save geometry saveSettings(); EVAF_INFO("%s destroyed", qPrintable(objectName())); } 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) { mMainPanelName = getMainPanelName(args); Common::iRegistry::instance()->registerInterface("iSdiWindow", this); setWindowTitle(Common::iApp::instance()->name()); show(); mReady = true; EVAF_INFO("%s initialized", qPrintable(objectName())); return true; } void SdiWindow::Internal::MainWindow::done() { mReady = false; close(); // Delete all the panels for (int i = mPanels.size() - 1; i >= 0; --i) { disconnect(mPanels.at(i), SIGNAL(destroyed(QObject *)), this, SLOT(panelDestroyed(QObject *))); delete mPanels.at(i); } mPanels.clear(); mMinimizedPanels.clear(); mPanelNames.clear(); mMainPanel = 0; mMainPanelName.clear(); EVAF_INFO("%s finalized", qPrintable(objectName())); } void SdiWindow::Internal::MainWindow::addPanel(QString const & name, Gui::Panel * panel) { connect(panel, SIGNAL(destroyed(QObject *)), this, SLOT(panelDestroyed(QObject*))); 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(); return 0; } bool SdiWindow::Internal::MainWindow::showPanel(QString const & name) { Gui::Panel * p = panel(name); if (p) { p->show(); return true; } return false; } void SdiWindow::Internal::MainWindow::saveSettings() { static int ver[4] = {VER_FILE_VERSION}; QSettings settings(VER_COMPANY_NAME_STR, Common::iApp::instance()->name()); settings.setValue(QString("%1/version/major").arg(objectName()), ver[0]); settings.setValue(QString("%1/version/minor").arg(objectName()), ver[1]); settings.setValue(QString("%1/geometry").arg(objectName()), saveGeometry()); } void SdiWindow::Internal::MainWindow::restoreSettings() { static int ver[4] = {VER_FILE_VERSION}; QSettings settings(VER_COMPANY_NAME_STR, Common::iApp::instance()->name()); // Ignore saved settings if the version number is not the same // More intelligent checks can be implemented to allow upgrading from previous versions QVariant v = settings.value(QString("%1/version/major").arg(objectName())); if (!v.isValid() || v.toInt() != ver[0]) return; v = settings.value(QString("%1/version/minor").arg(objectName())); if (!v.isValid() || v.toInt() != ver[1]) return; // Restore the geometry restoreGeometry(settings.value(QString("%1/geometry").arg(objectName())).toByteArray()); } void SdiWindow::Internal::MainWindow::setWindowSize() { // a) Get window size from properties 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(); for (int i = 1; i < args.size(); ++i) { QStringList arg = args.at(i).simplified().split('='); if (QRegExp("-[-]?w[idth]?").exactMatch(arg.at(0)) && arg.size() > 1) { bool ok; int v = arg.at(1).toInt(&ok); if (ok) w = v; } if (QRegExp("-[-]?h[eight]?").exactMatch(arg.at(0)) && arg.size() > 1) { bool ok; int v = arg.at(1).toInt(&ok); if (ok) h = v; } } // Resize the window if (w > 0 || h > 0) { QSize sz = sizeHint(); if (w > 0) sz.setWidth(w); if (h > 0) sz.setHeight(h); resize(sz); } } 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 (Gui::Panel * p, mPanels) { if (!p->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 (Gui::Panel * p, mMinimizedPanels) { if (p->isVisible()) p->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 (Gui::Panel * p, mPanels) { if (p->windowState() != Qt::WindowMinimized && p->isVisible()) { mMinimizedPanels.append(p); p->showMinimized(); } } } } QWidget::changeEvent(e); } void SdiWindow::Internal::MainWindow::panelDestroyed(QObject * obj) { // Remove panels that are deleted { QList::iterator it = mPanels.begin(); while (it != mPanels.end()) { if (*it == obj) { it = mPanels.erase(it); } else { ++it; } } } // Do the same with panel names { QHash::iterator it = mPanelNames.begin(); while (it != mPanelNames.end()) { if (it.value() == obj) { it = mPanelNames.erase(it); } else { ++it; } } } if (mMainPanel == obj) { mMainPanel = 0; } } //------------------------------------------------------------------- SdiWindow::Internal::SdiWindowPlugin::SdiWindowPlugin() : Plugins::iPlugin() { setObjectName(VER_MODULE_NAME_STR); mWindow = new MainWindow; EVAF_INFO("%s created", qPrintable(objectName())); } SdiWindow::Internal::SdiWindowPlugin::~SdiWindowPlugin() { delete mWindow; EVAF_INFO("%s destroyed", qPrintable(objectName())); } bool SdiWindow::Internal::SdiWindowPlugin::init(const QString & args) { if (!mWindow->init(args)) return false; EVAF_INFO("%s initialized", qPrintable(objectName())); return true; } void SdiWindow::Internal::SdiWindowPlugin::done() { mWindow->done(); EVAF_INFO("%s finalized", qPrintable(objectName())); }