mainwindow.cpp

00001 /* This file is part of the KDE libraries
00002    Copyright (C) 2004 Christoph Cullmann <cullmann@kde.org>
00003    Copyright (C) 2002,2003 Joseph Wenninger <jowenn@kde.org>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018    Boston, MA 02110-1301, USA.
00019 
00020    Based on:
00021 
00022    //----------------------------------------------------------------------------
00023    //    Project              : KDE MDI extension
00024    //
00025    //    begin                : 07/1999       by Szymon Stefanek as part of kvirc
00026    //                                         (an IRC application)
00027    //    changes              : 09/1999       by Falk Brettschneider to create an
00028    //                           - 06/2000     stand-alone Qt extension set of
00029    //                                         classes and a Qt-based library
00030    //                         : 02/2000       by Massimo Morin (mmorin@schedsys.com)
00031    //                           2000-2003     maintained by the KDevelop project
00032    //    patches              : -/2000        by Lars Beikirch (Lars.Beikirch@gmx.net)
00033    //                         : 01/2003       by Jens Zurheide (jens.zurheide@gmx.de)
00034    //
00035    //    copyright            : (C) 1999-2003 by Falk Brettschneider
00036    //                                         and
00037    //                                         Szymon Stefanek (stefanek@tin.it)
00038    //    email                :  falkbr@kdevelop.org (Falk Brettschneider)
00039    //----------------------------------------------------------------------------
00040 */
00041 
00042 #include "config.h"
00043 
00044 #include "tabwidget.h"
00045 
00046 #include <assert.h>
00047 
00048 #include <qcursor.h>
00049 #include <qclipboard.h>
00050 #include <qobjectlist.h>
00051 #include <qpopupmenu.h>
00052 #include <qmenubar.h>
00053 
00054 #include <kmenubar.h>
00055 #include <kapplication.h>
00056 #include <kdebug.h>
00057 #include <kdeversion.h>
00058 #include <qtabwidget.h>
00059 #include <klocale.h>
00060 
00061 #include <kiconloader.h>
00062 #include "dockcontainer.h"
00063 #include "mainwindow.moc"
00064 
00065 
00066 #include <qtoolbutton.h>
00067 #include <qlayout.h>
00068 #include <qstring.h>
00069 #include <qmap.h>
00070 #include <qvaluelist.h>
00071 
00072 #include "mainwindow.h"
00073 #include "dockcontainer.h"
00074 #include "toolviewaccessor_p.h"
00075 
00076 #include "guiclient.h"
00077 
00078 namespace KMDIPrivate
00079 {
00080   class MainWindowPrivate {
00081     public:
00082       MainWindowPrivate() {
00083         for (int i=0;i<4;i++) {
00084           activeDockPriority[i]=0;
00085           m_styleIDEAlMode = 0;
00086           m_toolviewStyle = 0;
00087         }
00088       }
00089       ~MainWindowPrivate() {}
00090       KMDI::DockContainer* activeDockPriority[4];
00091       int m_styleIDEAlMode;
00092       int m_toolviewStyle;
00093   };
00094 }
00095 
00096 namespace KMDI
00097 {
00098 
00099 //============ constructor ============//
00100 MainWindow::MainWindow(QWidget* parentWidget, const char* name)
00101  : KParts::DockMainWindow( parentWidget, name)
00102  , m_toolViews (new QMap<QWidget*,KMDI::ToolViewAccessor*>)
00103  , d(new KMDIPrivate::MainWindowPrivate())
00104 {
00105   // setup main dock stuff
00106   setupMainDock ();
00107 
00108   // setup the sidebar framework
00109   setupToolViews ();
00110 
00111   // setup all menu entries
00112   setupGUIClient ();
00113 }
00114 
00115 //============ ~MainWindow ============//
00116 MainWindow::~MainWindow()
00117 {
00118   delete m_toolViews;
00119   m_toolViews=0;
00120 
00121   delete d;
00122   d=0;
00123 }
00124 
00125 void MainWindow::setupMainDock ()
00126 {
00127   // cover KMdi's childarea by a dockwidget
00128   KDockWidget *dw = createDockWidget( "mdiAreaCover", QPixmap(), 0L, "mdi_area_cover");
00129   dw->setDockWindowTransient(this,true);
00130   dw->setEnableDocking(KDockWidget::DockNone);
00131   dw->setDockSite(KDockWidget::DockCorner);
00132 
00133   // setup tab widget
00134   m_tabWidget = new KMDI::TabWidget (dw);
00135   dw->setWidget(m_tabWidget);
00136 
00137   // set this dock to main view
00138   setView(dw);
00139   setMainDockWidget(dw);
00140 
00141   // connect signals to collapse sidebars
00142   connect(m_tabWidget,SIGNAL(focusInEvent()),this,SIGNAL(collapseOverlapContainers()));
00143 }
00144 
00145 void MainWindow::setupToolViews ()
00146 {
00147   m_leftContainer = createDockWidget("KMdiDock::leftDock",SmallIcon("misc"),0L,"Left Dock");
00148   m_rightContainer = createDockWidget("KMdiDock::rightDock",SmallIcon("misc"),0L,"Right Dock");
00149   m_topContainer = createDockWidget("KMdiDock::topDock",SmallIcon("misc"),0L,"Top Dock");
00150   m_bottomContainer = createDockWidget("KMdiDock::bottomDock",SmallIcon("misc"),0L,"Bottom Dock");
00151 
00152   KDockWidget *mainDock=getMainDockWidget();
00153   KDockWidget *w=mainDock;
00154 
00155   if (mainDock->parentDockTabGroup()) {
00156     w=static_cast<KDockWidget*>(mainDock->parentDockTabGroup()->parent());
00157   }
00158 
00159   QPtrList<KDockWidget> leftReparentWidgets;
00160   QPtrList<KDockWidget> rightReparentWidgets;
00161   QPtrList<KDockWidget> bottomReparentWidgets;
00162   QPtrList<KDockWidget> topReparentWidgets;
00163 
00164   if (mainDock->parentDockTabGroup()) {
00165     mainDock=static_cast<KDockWidget*>(mainDock->parentDockTabGroup()->parent());
00166   }
00167 
00168   findToolViewsDockedToMain(&leftReparentWidgets,KDockWidget::DockLeft);
00169   findToolViewsDockedToMain(&rightReparentWidgets,KDockWidget::DockRight);
00170   findToolViewsDockedToMain(&bottomReparentWidgets,KDockWidget::DockBottom);
00171   findToolViewsDockedToMain(&topReparentWidgets,KDockWidget::DockTop);
00172 
00173   mainDock->setEnableDocking(KDockWidget::DockNone); //::DockCorner);
00174   mainDock->setDockSite(KDockWidget::DockCorner);
00175 
00176 
00177   DockContainer *tmpDC;
00178   m_leftContainer->setWidget(tmpDC=new DockContainer(m_leftContainer, this, KDockWidget::DockLeft, d->m_styleIDEAlMode));
00179   m_leftContainer->setEnableDocking(KDockWidget::DockLeft);
00180   m_leftContainer->manualDock(mainDock, KDockWidget::DockLeft,20);
00181   tmpDC->init();
00182 
00183   connect (this,SIGNAL(toggleLeft()),tmpDC,SLOT(toggle()));
00184   connect(this,SIGNAL(collapseOverlapContainers()),tmpDC,SLOT(collapseOverlapped()));
00185   connect(tmpDC,SIGNAL(activated(DockContainer*)),this,SLOT(setActiveToolDock(DockContainer*)));
00186   connect(tmpDC,SIGNAL(deactivated(DockContainer*)),this,SLOT(removeFromActiveDockList(DockContainer*)));
00187 
00188   m_rightContainer->setWidget(tmpDC=new DockContainer(m_rightContainer, this, KDockWidget::DockRight, d->m_styleIDEAlMode));
00189   m_rightContainer->setEnableDocking(KDockWidget::DockRight);
00190   m_rightContainer->manualDock(mainDock, KDockWidget::DockRight,80);
00191   tmpDC->init();
00192 
00193   connect (this,SIGNAL(toggleRight()),tmpDC,SLOT(toggle()));
00194   connect(this,SIGNAL(collapseOverlapContainers()),tmpDC,SLOT(collapseOverlapped()));
00195   connect(tmpDC,SIGNAL(activated(DockContainer*)),this,SLOT(setActiveToolDock(DockContainer*)));
00196   connect(tmpDC,SIGNAL(deactivated(DockContainer*)),this,SLOT(removeFromActiveDockList(DockContainer*)));
00197 
00198   m_topContainer->setWidget(tmpDC=new DockContainer(m_topContainer, this, KDockWidget::DockTop, d->m_styleIDEAlMode));
00199   m_topContainer->setEnableDocking(KDockWidget::DockTop);
00200   m_topContainer->manualDock(mainDock, KDockWidget::DockTop,20);
00201   tmpDC->init();
00202 
00203   connect (this,SIGNAL(toggleTop()),tmpDC,SLOT(toggle()));
00204   connect(this,SIGNAL(collapseOverlapContainers()),tmpDC,SLOT(collapseOverlapped()));
00205   connect(tmpDC,SIGNAL(activated(DockContainer*)),this,SLOT(setActiveToolDock(DockContainer*)));
00206   connect(tmpDC,SIGNAL(deactivated(DockContainer*)),this,SLOT(removeFromActiveDockList(DockContainer*)));
00207 
00208   m_bottomContainer->setWidget(tmpDC=new DockContainer(m_bottomContainer, this, KDockWidget::DockBottom, d->m_styleIDEAlMode));
00209   m_bottomContainer->setEnableDocking(KDockWidget::DockBottom);
00210   m_bottomContainer->manualDock(mainDock, KDockWidget::DockBottom,80);
00211   tmpDC->init();
00212 
00213   connect (this,SIGNAL(toggleBottom()),tmpDC,SLOT(toggle()));
00214   connect(this,SIGNAL(collapseOverlapContainers()),tmpDC,SLOT(collapseOverlapped()));
00215   connect(tmpDC,SIGNAL(activated(DockContainer*)),this,SLOT(setActiveToolDock(DockContainer*)));
00216   connect(tmpDC,SIGNAL(deactivated(DockContainer*)),this,SLOT(removeFromActiveDockList(DockContainer*)));
00217 
00218   m_leftContainer->setDockSite( KDockWidget::DockCenter );
00219   m_rightContainer->setDockSite( KDockWidget::DockCenter );
00220   m_topContainer->setDockSite( KDockWidget::DockCenter );
00221   m_bottomContainer->setDockSite( KDockWidget::DockCenter );
00222 
00223   dockToolViewsIntoContainers(leftReparentWidgets,m_leftContainer);
00224   dockToolViewsIntoContainers(rightReparentWidgets,m_rightContainer);
00225   dockToolViewsIntoContainers(bottomReparentWidgets,m_bottomContainer);
00226   dockToolViewsIntoContainers(topReparentWidgets,m_topContainer);
00227 
00228   dockManager->setSpecialLeftDockContainer(m_leftContainer);
00229   dockManager->setSpecialRightDockContainer(m_rightContainer);
00230   dockManager->setSpecialTopDockContainer(m_topContainer);
00231   dockManager->setSpecialBottomDockContainer(m_bottomContainer);
00232 
00233   ((DockContainer*) (m_leftContainer->getWidget()))->hideIfNeeded();
00234   ((DockContainer*) (m_rightContainer->getWidget()))->hideIfNeeded();
00235   ((DockContainer*) (m_topContainer->getWidget()))->hideIfNeeded();
00236   ((DockContainer*) (m_bottomContainer->getWidget()))->hideIfNeeded();
00237 }
00238 
00239 void MainWindow::setupGUIClient ()
00240 {
00241   m_guiClient = new KMDIPrivate::GUIClient (this);
00242 
00243   connect(m_guiClient,SIGNAL(toggleTop()),this,SIGNAL(toggleTop()));
00244   connect(m_guiClient,SIGNAL(toggleLeft()),this,SIGNAL(toggleLeft()));
00245   connect(m_guiClient,SIGNAL(toggleRight()),this,SIGNAL(toggleRight()));
00246   connect(m_guiClient,SIGNAL(toggleBottom()),this,SIGNAL(toggleBottom()));
00247 }
00248 
00249 TabWidget *MainWindow::tabWidget ()
00250 {
00251   return m_tabWidget;
00252 }
00253 
00254 ToolViewAccessor *MainWindow::createToolWindow()
00255 {
00256   return new KMDI::ToolViewAccessor(this);
00257 }
00258 
00259 KMDI::ToolViewAccessor *MainWindow::addToolWindow( QWidget* pWnd, KDockWidget::DockPosition pos, QWidget* pTargetWnd, int percent, const QString& tabToolTip, const QString& tabCaption)
00260 {
00261   QWidget *tvta=pWnd;
00262   KDockWidget* pDW = dockManager->getDockWidgetFromName(pWnd->name());
00263   if (pDW) {
00264     // probably readDockConfig already created the widgetContainer, use that
00265     pDW->setWidget(pWnd);
00266 
00267     if (pWnd->icon()) {
00268       pDW->setPixmap(*pWnd->icon());
00269     }
00270     pDW->setTabPageLabel((tabCaption==0)?pWnd->caption():tabCaption);
00271     pDW->setToolTipString(tabToolTip);
00272     dockManager->removeFromAutoCreateList(pDW);
00273     pWnd=pDW;
00274   }
00275 
00276   QRect r=pWnd->geometry();
00277 
00278   KMDI::ToolViewAccessor *mtva=new KMDI::ToolViewAccessor(this,pWnd,tabToolTip,(tabCaption==0)?pWnd->caption():tabCaption);
00279   m_toolViews->insert(tvta,mtva);
00280 
00281   if (pos == KDockWidget::DockNone) {
00282     mtva->d->widgetContainer->setEnableDocking(KDockWidget::DockNone);
00283     mtva->d->widgetContainer->reparent(this, Qt::WType_TopLevel | Qt::WType_Dialog, r.topLeft(), isVisible());
00284   } else {   // add (and dock) the toolview as DockWidget view
00285     //const QPixmap& wndIcon = pWnd->icon() ? *(pWnd->icon()) : QPixmap();
00286 
00287     //KDockWidget *pCover=mtva->d->widgetContainer;
00288 
00289     mtva->place(pos, pTargetWnd,percent);
00290   }
00291 
00292   return mtva;
00293 }
00294 
00295 void MainWindow::deleteToolWindow( KMDI::ToolViewAccessor *accessor)
00296 {
00297   delete accessor;
00298 }
00299 
00300 void MainWindow::deleteToolWindow( QWidget* pWnd)
00301 {
00302   if (!pWnd)
00303     return;
00304 
00305   if (m_toolViews->contains(pWnd)) {
00306     deleteToolWindow((*m_toolViews)[pWnd]);
00307   }
00308 }
00309 
00310 void MainWindow::setToolViewStyle(int flag)
00311 {
00312   d->m_styleIDEAlMode = flag; // see KMultiTabBar for the first 3 bits
00313 
00314   DockContainer *tmpL=(DockContainer*) (m_leftContainer->getWidget()->qt_cast("KMDI::DockContainer"));
00315   if (tmpL) tmpL->setStyle(flag);
00316 
00317   DockContainer *tmpR=(DockContainer*) (m_rightContainer->getWidget()->qt_cast("KMDI::DockContainer"));
00318   if (tmpR) tmpR->setStyle(flag);
00319 
00320   DockContainer *tmpT=(DockContainer*) (m_topContainer->getWidget()->qt_cast("KMDI::DockContainer"));
00321   if (tmpT) tmpT->setStyle(flag);
00322 
00323   DockContainer *tmpB=(DockContainer*) (m_bottomContainer->getWidget()->qt_cast("KMDI::DockContainer"));
00324   if (tmpB) tmpB->setStyle(flag);
00325 
00326   d->m_toolviewStyle = flag;
00327   bool toolviewExists = false;
00328   QMap<QWidget*,KMDI::ToolViewAccessor*>::Iterator it;
00329   for (it = m_toolViews->begin(); it != m_toolViews->end(); ++it) {
00330     KDockWidget *dockWidget = dynamic_cast<KDockWidget*>(it.data()->wrapperWidget());
00331     if (dockWidget) {
00332       if (flag == KMDI::IconOnly)
00333       {
00334         dockWidget->setTabPageLabel(" ");
00335         dockWidget->setPixmap(*(it.data()->wrappedWidget()->icon()));
00336       } else
00337       if (flag == KMDI::TextOnly)
00338       {
00339         dockWidget->setPixmap(); //FIXME: Does not hide the icon in the IDEAl mode.
00340         dockWidget->setTabPageLabel(it.data()->wrappedWidget()->caption());
00341       } else
00342       if (flag == KMDI::TextAndIcon)
00343       {
00344         dockWidget->setPixmap(*(it.data()->wrappedWidget()->icon()));
00345         dockWidget->setTabPageLabel(it.data()->wrappedWidget()->caption());
00346       }
00347       toolviewExists = true;
00348     }
00349   }
00350   if (toolviewExists)
00351   {
00352     //workaround for the above FIXME to make switching to TextOnly mode work in IDEAl as well. Be sure that this version of switch* is called.
00353     if (flag == KMDI::TextOnly)
00354     {
00355    /*   MainWindow::switchToTabPageMode();
00356       MainWindow::switchToIDEAlMode();*/ //TODO
00357     } else
00358     {
00359       writeDockConfig();
00360       readDockConfig();
00361     }
00362   }
00363 }
00364 
00365 void MainWindow::dockToolViewsIntoContainers(QPtrList<KDockWidget>& widgetsToReparent,KDockWidget *container) {
00366   for ( KDockWidget *dw = widgetsToReparent.first(); dw;
00367       dw=widgetsToReparent.next()){
00368     dw->manualDock(container,KDockWidget::DockCenter,20);
00369     dw->loseFormerBrotherDockWidget();
00370   }
00371 }
00372 
00373 void MainWindow::findToolViewsDockedToMain(QPtrList<KDockWidget>* list,KDockWidget::DockPosition dprtmw) {
00374   KDockWidget *mainDock=getMainDockWidget();
00375   if (mainDock->parentDockTabGroup()) {
00376     mainDock=dynamic_cast<KDockWidget*>(mainDock->parentDockTabGroup()->parent());
00377     // FIXME: will likely crash below due to unchecked cast
00378   }
00379 
00380   KDockWidget* widget=mainDock->findNearestDockWidget(dprtmw);
00381   if (widget) {
00382     if (widget->parentDockTabGroup()) {
00383       widget=static_cast<KDockWidget*>(widget->parentDockTabGroup()->parent());
00384     }
00385 
00386     if (widget) {
00387       KDockTabGroup *tg=dynamic_cast<KDockTabGroup*>(widget->
00388           getWidget());
00389       if (tg) {
00390         kdDebug(760)<<"KDockTabGroup found"<<endl;
00391         for (int i=0;i<tg->count();i++)
00392           list->append((KDockWidget*)static_cast<KDockWidget*>(
00393                 tg->page(i)));
00394       } else
00395         list->append((KDockWidget*)widget);
00396     } else
00397       kdDebug(760)<<"setupToolViewsForIDEALMode: no  widget found"<<endl;
00398   } else
00399     kdDebug(760)<<"No main dock widget found"<<endl;
00400 }
00401 
00402 void MainWindow::setActiveToolDock(DockContainer* td) {
00403   if (td==d->activeDockPriority[0]) return;
00404   if (d->activeDockPriority[0]==0) {
00405     d->activeDockPriority[0]=td;
00406     //        d->focusList=new KMdiFocusList(this);
00407     //        if (m_pMdi)  d->focusList->addWidgetTree(m_pMdi);
00408     //        if (m_documentTabWidget) d->focusList->addWidgetTree(m_documentTabWidget);
00409     return;
00410   }
00411   for (int dst=3,src=2;src>=0;dst--,src--) {
00412     if (d->activeDockPriority[src]==td) src--;
00413     if (src<0) break;
00414     d->activeDockPriority[dst]=d->activeDockPriority[src];
00415   }
00416   d->activeDockPriority[0]=td;
00417 }
00418 
00419 void MainWindow::removeFromActiveDockList(DockContainer* td) {
00420   for (int i=0;i<4;i++) {
00421     if (d->activeDockPriority[i]==td) {
00422       for (;i<3;i++)
00423         d->activeDockPriority[i]=d->activeDockPriority[i+1];
00424       d->activeDockPriority[3]=0;
00425       break;
00426     }
00427   }
00428   /*
00429         if (d->activeDockPriority[0]==0) {
00430         if (d->focusList) d->focusList->restore();
00431         delete d->focusList;
00432         d->focusList=0;
00433         }
00434    */
00435 }
00436 
00437 void MainWindow::prevToolViewInDock() {
00438   DockContainer* td=d->activeDockPriority[0];
00439   if (!td) return;
00440   td->prevToolView();
00441 }
00442 
00443 void MainWindow::nextToolViewInDock() {
00444   DockContainer* td=d->activeDockPriority[0];
00445   if (!td) return;
00446   td->nextToolView();
00447 }
00448 
00449 }
00450 
00451 // kate: space-indent on; indent-width 2; replace-tabs on;
KDE Home | KDE Accessibility Home | Description of Access Keys