DockWindowManager.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2007 Werner Mayer <wmayer[at]users.sourceforge.net>     *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 
00024 #include "PreCompiled.h"
00025 #ifndef _PreComp_
00026 # include <QPointer>
00027 # include <QDockWidget>
00028 # include <QAction>
00029 # include <QMap>
00030 #endif
00031 
00032 #include "DockWindowManager.h"
00033 #include "MainWindow.h"
00034 #include <App/Application.h>
00035 
00036 using namespace Gui;
00037 
00038 DockWindowItems::DockWindowItems()
00039 {
00040 }
00041 
00042 DockWindowItems::~DockWindowItems()
00043 {
00044 }
00045 
00046 void DockWindowItems::addDockWidget(const char* name, Qt::DockWidgetArea pos, bool visibility, bool tabbed)
00047 {
00048     DockWindowItem item;
00049     item.name = QString::fromAscii(name);
00050     item.pos = pos;
00051     item.visibility = visibility;
00052     item.tabbed = tabbed;
00053     _items << item;
00054 }
00055 
00056 void DockWindowItems::setDockingArea(const char* name, Qt::DockWidgetArea pos)
00057 {
00058     for (QList<DockWindowItem>::iterator it = _items.begin(); it != _items.end(); ++it) {
00059         if (it->name == QLatin1String(name)) {
00060             it->pos = pos;
00061             break;
00062         }
00063     }
00064 }
00065 
00066 void DockWindowItems::setVisibility(const char* name, bool v)
00067 {
00068     for (QList<DockWindowItem>::iterator it = _items.begin(); it != _items.end(); ++it) {
00069         if (it->name == QLatin1String(name)) {
00070             it->visibility = v;
00071             break;
00072         }
00073     }
00074 }
00075 
00076 void DockWindowItems::setVisibility(bool v)
00077 {
00078     for (QList<DockWindowItem>::iterator it = _items.begin(); it != _items.end(); ++it) {
00079         it->visibility = v;
00080     }
00081 }
00082 
00083 const QList<DockWindowItem>& DockWindowItems::dockWidgets() const
00084 {
00085     return this->_items;
00086 }
00087 
00088 // -----------------------------------------------------------
00089 
00090 namespace Gui {
00091 struct DockWindowManagerP
00092 {
00093     QList<QDockWidget*> _dockedWindows;
00094     QMap<QString, QPointer<QWidget> > _dockWindows;
00095     DockWindowItems _dockWindowItems;
00096 };
00097 } // namespace Gui
00098 
00099 DockWindowManager* DockWindowManager::_instance = 0;
00100 
00101 DockWindowManager* DockWindowManager::instance()
00102 {
00103     if ( _instance == 0 )
00104         _instance = new DockWindowManager;
00105     return _instance;
00106 }
00107 
00108 void DockWindowManager::destruct()
00109 {
00110     delete _instance;
00111     _instance = 0;
00112 }
00113 
00114 DockWindowManager::DockWindowManager()
00115 {
00116     d = new DockWindowManagerP;
00117 }
00118 
00119 DockWindowManager::~DockWindowManager()
00120 {
00121     d->_dockedWindows.clear();
00122     delete d;
00123 }
00124 
00128 QDockWidget* DockWindowManager::addDockWindow(const char* name, QWidget* widget, Qt::DockWidgetArea pos)
00129 {
00130     // creates the dock widget as container to embed this widget
00131     MainWindow* mw = getMainWindow();
00132     QDockWidget* dw = new QDockWidget(mw);
00133     // Note: By default all dock widgets are hidden but the user can show them manually in the view menu.
00134     // First, hide immediately the dock widget to avoid flickering, after setting up the dock widgets
00135     // MainWindow::loadLayoutSettings() is called to restore the layout.
00136     dw->hide();
00137     switch (pos) {
00138     case Qt::LeftDockWidgetArea:
00139     case Qt::RightDockWidgetArea:
00140     case Qt::TopDockWidgetArea:
00141     case Qt::BottomDockWidgetArea:
00142         mw->addDockWidget(pos, dw);
00143     default:
00144         break;
00145     }
00146     connect(dw, SIGNAL(destroyed(QObject*)),
00147             this, SLOT(onDockWidgetDestroyed(QObject*)));
00148     connect(widget, SIGNAL(destroyed(QObject*)),
00149             this, SLOT(onWidgetDestroyed(QObject*)));
00150 
00151     // add the widget to the dock widget
00152     widget->setParent(dw);
00153     dw->setWidget(widget);
00154 
00155     // set object name and window title needed for i18n stuff
00156     dw->setObjectName(QLatin1String(name));
00157     dw->setWindowTitle(QDockWidget::trUtf8(name));
00158     dw->setFeatures(QDockWidget::AllDockWidgetFeatures);
00159 
00160     d->_dockedWindows.push_back(dw);
00161     return dw;
00162 }
00163 
00168 QWidget* DockWindowManager::getDockWindow(const char* name) const
00169 {
00170     for (QList<QDockWidget*>::ConstIterator it = d->_dockedWindows.begin(); it != d->_dockedWindows.end(); ++it) {
00171         if ((*it)->objectName() == QLatin1String(name))
00172             return (*it)->widget();
00173     }
00174 
00175     return 0;
00176 }
00177 
00181 QList<QWidget*> DockWindowManager::getDockWindows() const
00182 {
00183     QList<QWidget*> docked;
00184     for (QList<QDockWidget*>::ConstIterator it = d->_dockedWindows.begin(); it != d->_dockedWindows.end(); ++it)
00185         docked.push_back((*it)->widget());
00186     return docked;
00187 }
00188 
00192 QWidget* DockWindowManager::removeDockWindow(const char* name)
00193 {
00194     QWidget* widget=0;
00195     for (QList<QDockWidget*>::Iterator it = d->_dockedWindows.begin(); it != d->_dockedWindows.end(); ++it) {
00196         if ((*it)->objectName() == QLatin1String(name)) {
00197             QDockWidget* dw = *it;
00198             d->_dockedWindows.erase(it);
00199             getMainWindow()->removeDockWidget(dw);
00200             // avoid to destruct the embedded widget
00201             widget = dw->widget();
00202             widget->setParent(0);
00203             dw->setWidget(0);
00204             disconnect(dw, SIGNAL(destroyed(QObject*)),
00205                        this, SLOT(onDockWidgetDestroyed(QObject*)));
00206             disconnect(widget, SIGNAL(destroyed(QObject*)),
00207                        this, SLOT(onWidgetDestroyed(QObject*)));
00208             delete dw; // destruct the QDockWidget, i.e. the parent of the widget
00209             break;
00210         }
00211     }
00212 
00213     return widget;
00214 }
00215 
00220 void DockWindowManager::removeDockWindow(QWidget* widget)
00221 {
00222     for (QList<QDockWidget*>::Iterator it = d->_dockedWindows.begin(); it != d->_dockedWindows.end(); ++it) {
00223         if ((*it)->widget() == widget) {
00224             QDockWidget* dw = *it;
00225             d->_dockedWindows.erase(it);
00226             getMainWindow()->removeDockWidget(dw);
00227             // avoid to destruct the embedded widget
00228             widget->setParent(0);
00229             dw->setWidget(0);
00230             disconnect(dw, SIGNAL(destroyed(QObject*)),
00231                        this, SLOT(onDockWidgetDestroyed(QObject*)));
00232             disconnect(widget, SIGNAL(destroyed(QObject*)),
00233                        this, SLOT(onWidgetDestroyed(QObject*)));
00234             delete dw; // destruct the QDockWidget, i.e. the parent of the widget
00235             break;
00236         }
00237     }
00238 }
00239 
00243 void DockWindowManager::retranslate()
00244 {
00245     for (QList<QDockWidget*>::Iterator it = d->_dockedWindows.begin(); it != d->_dockedWindows.end(); ++it) {
00246         (*it)->setWindowTitle(QDockWidget::tr((*it)->objectName().toAscii()));
00247     }
00248 }
00249 
00269 bool DockWindowManager::registerDockWindow(const char* name, QWidget* widget)
00270 {
00271     QMap<QString, QPointer<QWidget> >::Iterator it = d->_dockWindows.find(QLatin1String(name));
00272     if (it != d->_dockWindows.end() || !widget)
00273         return false;
00274     d->_dockWindows[QLatin1String(name)] = widget;
00275     widget->hide(); // hide the widget if not used
00276     return true;
00277 }
00278 
00280 void DockWindowManager::setup(DockWindowItems* items)
00281 {
00282     // save state of current dock windows
00283     saveState();
00284     d->_dockWindowItems = *items;
00285 
00286     ParameterGrp::handle hPref = App::GetApplication().GetUserParameter().GetGroup("BaseApp")
00287                                ->GetGroup("MainWindow")->GetGroup("DockWindows");
00288     QList<QDockWidget*> docked = d->_dockedWindows;
00289     const QList<DockWindowItem>& dws = items->dockWidgets();
00290     QList<QDockWidget*> areas[4];
00291     for (QList<DockWindowItem>::ConstIterator it = dws.begin(); it != dws.end(); ++it) {
00292         QDockWidget* dw = findDockWidget(docked, it->name);
00293         QByteArray dockName = it->name.toAscii();
00294         bool visible = hPref->GetBool(dockName.constData(), it->visibility);
00295 
00296         if (!dw) {
00297             QMap<QString, QPointer<QWidget> >::ConstIterator jt = d->_dockWindows.find(it->name);
00298             if (jt != d->_dockWindows.end()) {
00299                 dw = addDockWindow(jt.value()->objectName().toUtf8(), jt.value(), it->pos);
00300                 jt.value()->show();
00301                 dw->toggleViewAction()->setData(it->name);
00302                 dw->setVisible(visible);
00303             }
00304         }
00305         else {
00306             dw->setVisible(visible);
00307             dw->toggleViewAction()->setVisible(true);
00308             int index = docked.indexOf(dw);
00309             docked.removeAt(index);
00310         }
00311 
00312         if (it->tabbed && dw) {
00313             Qt::DockWidgetArea pos = getMainWindow()->dockWidgetArea(dw);
00314             switch (pos) {
00315                 case Qt::LeftDockWidgetArea:
00316                     areas[0] << dw;
00317                     break;
00318                 case Qt::RightDockWidgetArea:
00319                     areas[1] << dw;
00320                     break;
00321                 case Qt::TopDockWidgetArea:
00322                     areas[2] << dw;
00323                     break;
00324                 case Qt::BottomDockWidgetArea:
00325                     areas[3] << dw;
00326                     break;
00327                 default:
00328                     break;
00329             }
00330         }
00331     }
00332 
00333 #if 0 // FIXME: don't tabify always after switching the workbench
00334     // tabify dock widgets for which "tabbed" is true and which have the same position
00335     for (int i=0; i<4; i++) {
00336         const QList<QDockWidget*>& dws = areas[i];
00337         for (QList<QDockWidget*>::ConstIterator it = dws.begin(); it != dws.end(); ++it) {
00338             if (*it != dws.front()) {
00339                 getMainWindow()->tabifyDockWidget(dws.front(), *it);
00340             }
00341         }
00342     }
00343 #endif
00344 
00345 #if 0
00346     // hide all dock windows which we don't need for the moment
00347     for (QList<QDockWidget*>::Iterator it = docked.begin(); it != docked.end(); ++it) {
00348         QByteArray dockName = (*it)->toggleViewAction()->data().toByteArray();
00349         hPref->SetBool(dockName.constData(), (*it)->isVisible());
00350         (*it)->hide();
00351         (*it)->toggleViewAction()->setVisible(false);
00352     }
00353 #endif
00354 }
00355 
00356 void DockWindowManager::saveState()
00357 {
00358     ParameterGrp::handle hPref = App::GetApplication().GetUserParameter().GetGroup("BaseApp")
00359                                ->GetGroup("MainWindow")->GetGroup("DockWindows");
00360 
00361     const QList<DockWindowItem>& dockItems = d->_dockWindowItems.dockWidgets();
00362     for (QList<DockWindowItem>::ConstIterator it = dockItems.begin(); it != dockItems.end(); ++it) {
00363         QDockWidget* dw = findDockWidget(d->_dockedWindows, it->name);
00364         if (dw) {
00365             QByteArray dockName = dw->toggleViewAction()->data().toByteArray();
00366             hPref->SetBool(dockName.constData(), dw->isVisible());
00367         }
00368     }
00369 }
00370 
00371 QDockWidget* DockWindowManager::findDockWidget(const QList<QDockWidget*>& dw, const QString& name) const
00372 {
00373     for (QList<QDockWidget*>::ConstIterator it = dw.begin(); it != dw.end(); ++it) {
00374         if ((*it)->toggleViewAction()->data().toString() == name)
00375             return *it;
00376     }
00377 
00378     return 0;
00379 }
00380 
00381 void DockWindowManager::onDockWidgetDestroyed(QObject* dw)
00382 {
00383     for (QList<QDockWidget*>::Iterator it = d->_dockedWindows.begin(); it != d->_dockedWindows.end(); ++it) {
00384         if (*it == dw) {
00385             d->_dockedWindows.erase(it);
00386             break;
00387         }
00388     }
00389 }
00390 
00391 void DockWindowManager::onWidgetDestroyed(QObject* widget)
00392 {
00393     for (QList<QDockWidget*>::Iterator it = d->_dockedWindows.begin(); it != d->_dockedWindows.end(); ++it) {
00394         // make sure that the dock widget is not about to being deleted
00395         if ((*it)->metaObject() != &QDockWidget::staticMetaObject) {
00396             disconnect(*it, SIGNAL(destroyed(QObject*)),
00397                        this, SLOT(onDockWidgetDestroyed(QObject*)));
00398             d->_dockedWindows.erase(it);
00399             break;
00400         }
00401 
00402         if ((*it)->widget() == widget) {
00403             // Delete the widget if not used anymore
00404             QDockWidget* dw = *it;
00405             dw->deleteLater();
00406             break;
00407         }
00408     }
00409 }
00410 
00411 #include "moc_DockWindowManager.cpp"

Generated on Wed Nov 23 19:00:07 2011 for FreeCAD by  doxygen 1.6.1