kdeui Library API Documentation

kdockwidget.cpp

00001 
00002 /* This file is part of the KDE libraries
00003    Copyright (C) 2000 Max Judin <novaprint@mtu-net.ru>
00004    Copyright (C) 2002,2003 Joseph Wenninger <jowenn@kde.org>
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 version 2 as published by the Free Software Foundation.
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., 59 Temple Place - Suite 330,
00018    Boston, MA 02111-1307, USA.
00019 */
00020 #include "kdockwidget.h"
00021 #include "kdockwidget_private.h"
00022 #include "kdockwidget_p.h"
00023 
00024 #include <qapplication.h>
00025 #include <qlayout.h>
00026 #include <qpainter.h>
00027 #include <qobjectlist.h>
00028 #include <qstrlist.h>
00029 #include <qcursor.h>
00030 #include <qwidgetlist.h>
00031 #include <qtabwidget.h>
00032 #include <qtooltip.h>
00033 #include <qstyle.h>
00034 
00035 #ifndef NO_KDE2
00036 #include <kconfig.h>
00037 #include <kglobal.h>
00038 #include <klocale.h>
00039 #include <ktoolbar.h>
00040 #include <kpopupmenu.h>
00041 #include <kwin.h>
00042 #include <kdebug.h>
00043 #include <kglobalsettings.h>
00044 
00045 #include "config.h"
00046 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00047 #include <X11/X.h> // schroder
00048 #include <X11/Xlib.h> // schroder
00049 #endif
00050 
00051 #else
00052 #include <qtoolbar.h>
00053 #include <qpopupmenu.h>
00054 #endif
00055 
00056 #include <stdlib.h>
00057 
00058 #undef BORDERLESS_WINDOWS
00059 
00060 #define DOCK_CONFIG_VERSION "0.0.5"
00061 
00062 static const char* const dockback_xpm[]={
00063 "6 6 2 1",
00064 "# c black",
00065 ". c None",
00066 "......",
00067 ".#....",
00068 "..#..#",
00069 "...#.#",
00070 "....##",
00071 "..####"};
00072 
00073 static const char* const todesktop_xpm[]={
00074 "5 5 2 1",
00075 "# c black",
00076 ". c None",
00077 "####.",
00078 "##...",
00079 "#.#..",
00080 "#..#.",
00081 "....#"};
00082 
00083 static const char* const not_close_xpm[]={
00084 "5 5 2 1",
00085 "# c black",
00086 ". c None",
00087 "#####",
00088 "#...#",
00089 "#...#",
00090 "#...#",
00091 "#####"};
00092 
00102 KDockMainWindow::KDockMainWindow( QWidget* parent, const char *name, WFlags f)
00103 :KMainWindow( parent, name, f )
00104 {
00105   QString new_name = QString(name) + QString("_DockManager");
00106   dockManager = new KDockManager( this, new_name.latin1() );
00107   mainDockWidget = 0L;
00108 }
00109 
00110 KDockMainWindow::~KDockMainWindow()
00111 {
00112     delete dockManager;
00113 }
00114 
00115 void KDockMainWindow::setMainDockWidget( KDockWidget* mdw )
00116 {
00117   if ( mainDockWidget == mdw ) return;
00118   mainDockWidget = mdw;
00119   dockManager->setMainDockWidget2(mdw);
00120 }
00121 
00122 void KDockMainWindow::setView( QWidget *view )
00123 {
00124   if ( view->isA("KDockWidget") ){
00125     if ( view->parent() != this ) ((KDockWidget*)view)->applyToWidget( this );
00126   }
00127 
00128 #ifndef NO_KDE2
00129   KMainWindow::setCentralWidget(view);
00130 #else
00131   QMainWindow::setCentralWidget(view);
00132 #endif
00133 }
00134 
00135 KDockWidget* KDockMainWindow::createDockWidget( const QString& name, const QPixmap &pixmap, QWidget* parent, const QString& strCaption, const QString& strTabPageLabel)
00136 {
00137   return new KDockWidget( dockManager, name.latin1(), pixmap, parent, strCaption, strTabPageLabel );
00138 }
00139 
00140 void KDockMainWindow::makeDockVisible( KDockWidget* dock )
00141 {
00142   if ( dock != 0L)
00143     dock->makeDockVisible();
00144 }
00145 
00146 void KDockMainWindow::makeDockInvisible( KDockWidget* dock )
00147 {
00148   if ( dock != 0L)
00149     dock->undock();
00150 }
00151 
00152 void KDockMainWindow::makeWidgetDockVisible( QWidget* widget )
00153 {
00154   makeDockVisible( dockManager->findWidgetParentDock(widget) );
00155 }
00156 
00157 void KDockMainWindow::writeDockConfig(QDomElement &base)
00158 {
00159   dockManager->writeConfig(base);
00160 }
00161 
00162 void KDockMainWindow::readDockConfig(QDomElement &base)
00163 {
00164   dockManager->readConfig(base);
00165 }
00166 
00167 #ifndef NO_KDE2
00168 void KDockMainWindow::writeDockConfig( KConfig* c, QString group )
00169 {
00170   dockManager->writeConfig( c, group );
00171 }
00172 
00173 void KDockMainWindow::readDockConfig( KConfig* c, QString group )
00174 {
00175   dockManager->readConfig( c, group );
00176 }
00177 #endif
00178 
00179 void KDockMainWindow::slotDockWidgetUndocked()
00180 {
00181   QObject* pSender = (QObject*) sender();
00182   if (!pSender->inherits("KDockWidget")) return;
00183   KDockWidget* pDW = (KDockWidget*) pSender;
00184   emit dockWidgetHasUndocked( pDW);
00185 }
00186 
00187 /*************************************************************************/
00188 KDockWidgetAbstractHeaderDrag::KDockWidgetAbstractHeaderDrag( KDockWidgetAbstractHeader* parent, KDockWidget* dock, const char* name )
00189 :QFrame( parent, name )
00190 {
00191   dw = dock;
00192   installEventFilter( dock->dockManager() );
00193 }
00194 /*************************************************************************/
00195 KDockWidgetHeaderDrag::KDockWidgetHeaderDrag( KDockWidgetAbstractHeader* parent, KDockWidget* dock, const char* name )
00196 :KDockWidgetAbstractHeaderDrag( parent, dock, name )
00197 {
00198 }
00199 
00200 void KDockWidgetHeaderDrag::paintEvent( QPaintEvent* )
00201 {
00202   QPainter paint;
00203 
00204   paint.begin( this );
00205 
00206   style().drawPrimitive (QStyle::PE_DockWindowHandle, &paint, QRect(0,0,width(), height()), colorGroup());
00207 
00208   paint.end();
00209 }
00210 /*************************************************************************/
00211 KDockWidgetAbstractHeader::KDockWidgetAbstractHeader( KDockWidget* parent, const char* name )
00212 :QFrame( parent, name )
00213 {
00214 }
00215 /*************************************************************************/
00216 KDockWidgetHeader::KDockWidgetHeader( KDockWidget* parent, const char* name )
00217 :KDockWidgetAbstractHeader( parent, name )
00218 {
00219 #ifdef BORDERLESS_WINDOWS
00220   setCursor(QCursor(ArrowCursor));
00221 #endif
00222   d = new KDockWidgetHeaderPrivate( this );
00223 
00224   layout = new QHBoxLayout( this );
00225   layout->setResizeMode( QLayout::Minimum );
00226 
00227   drag = new KDockWidgetHeaderDrag( this, parent );
00228 
00229   closeButton = new KDockButton_Private( this, "DockCloseButton" );
00230   QToolTip::add( closeButton, i18n("Close") );
00231   closeButton->setPixmap( style().stylePixmap (QStyle::SP_TitleBarCloseButton , this));
00232   closeButton->setFixedSize(closeButton->pixmap()->width(),closeButton->pixmap()->height());
00233   connect( closeButton, SIGNAL(clicked()), parent, SIGNAL(headerCloseButtonClicked()));
00234   connect( closeButton, SIGNAL(clicked()), parent, SLOT(undock()));
00235 
00236   stayButton = new KDockButton_Private( this, "DockStayButton" );
00237   QToolTip::add( stayButton, i18n("Freeze the window geometry", "Freeze") );
00238   stayButton->setToggleButton( true );
00239   stayButton->setPixmap( const_cast< const char** >(not_close_xpm) );
00240   stayButton->setFixedSize(closeButton->pixmap()->width(),closeButton->pixmap()->height());
00241   connect( stayButton, SIGNAL(clicked()), this, SLOT(slotStayClicked()));
00242 
00243   dockbackButton = new KDockButton_Private( this, "DockbackButton" );
00244   QToolTip::add( dockbackButton, i18n("Dock this window", "Dock") );
00245   dockbackButton->setPixmap( const_cast< const char** >(dockback_xpm));
00246   dockbackButton->setFixedSize(closeButton->pixmap()->width(),closeButton->pixmap()->height());
00247   connect( dockbackButton, SIGNAL(clicked()), parent, SIGNAL(headerDockbackButtonClicked()));
00248   connect( dockbackButton, SIGNAL(clicked()), parent, SLOT(dockBack()));
00249 
00250   d->toDesktopButton = new KDockButton_Private( this, "ToDesktopButton" );
00251   QToolTip::add( d->toDesktopButton, i18n("Detach") );
00252   d->toDesktopButton->setPixmap( const_cast< const char** >(todesktop_xpm));
00253   d->toDesktopButton->setFixedSize(closeButton->pixmap()->width(),closeButton->pixmap()->height());
00254   connect( d->toDesktopButton, SIGNAL(clicked()), parent, SLOT(toDesktop()));
00255   stayButton->hide();
00256 
00257   d->dummy = new QWidget( this );
00258   d->dummy->setFixedSize( 1,closeButton->pixmap()->height() );
00259 
00260 
00261   layout->addWidget( drag );
00262   layout->addWidget( dockbackButton );
00263   layout->addWidget( d->toDesktopButton );
00264   layout->addWidget( d->dummy);
00265   layout->addWidget( stayButton );
00266   layout->addWidget( closeButton );
00267   layout->activate();
00268   d->dummy->hide();
00269   drag->setFixedHeight( layout->minimumSize().height() );
00270 }
00271 
00272 void KDockWidgetHeader::setTopLevel( bool isTopLevel )
00273 {
00274   d->topLevel = isTopLevel;
00275   if ( isTopLevel ){
00276     KDockWidget* par = (KDockWidget*)parent();
00277     if( par) {
00278       if( par->isDockBackPossible())
00279         dockbackButton->show();
00280       else
00281         dockbackButton->hide();
00282     }
00283     stayButton->hide();
00284     closeButton->hide();
00285     d->toDesktopButton->hide();
00286     drag->setEnabled( true );
00287   } else {
00288     dockbackButton->hide();
00289     stayButton->hide();
00290     if (!d->forceCloseButtonHidden) closeButton->show();
00291     if( d->showToDesktopButton )
00292       d->toDesktopButton->show();
00293   }
00294   layout->activate();
00295 
00296    bool dontShowDummy=drag->isVisibleTo(this) || dockbackButton->isVisibleTo(this) ||
00297         d->toDesktopButton->isVisibleTo(this) || stayButton->isVisibleTo(this) ||
00298         closeButton->isVisibleTo(this);
00299    for (QPtrListIterator<KDockButton_Private> it( d->btns );it.current()!=0;++it) {
00300         dontShowDummy=dontShowDummy || (it.current()->isVisibleTo(this));
00301    }
00302    if (dontShowDummy) d->dummy->hide(); else d->dummy->show();
00303 
00304   updateGeometry();
00305 }
00306 
00307 void KDockWidgetHeader::forceCloseButtonHidden(bool hidden) {
00308   d->forceCloseButtonHidden=hidden;
00309   if (hidden) closeButton->hide();
00310   else closeButton->show();
00311 }
00312 
00313 void KDockWidgetHeader::setDragPanel( KDockWidgetHeaderDrag* nd )
00314 {
00315   if ( !nd ) return;
00316 
00317   delete layout;
00318   layout = new QHBoxLayout( this );
00319   layout->setResizeMode( QLayout::Minimum );
00320 
00321   delete drag;
00322   drag = nd;
00323   if (drag->parentWidget()!=this) {
00324     drag->reparent(this,QPoint(0,0));
00325   }
00326 
00327 
00328   layout->addWidget( drag );
00329   layout->addWidget( dockbackButton );
00330   layout->addWidget( d->dummy );
00331   layout->addWidget( d->toDesktopButton );
00332   layout->addWidget( stayButton );
00333   bool dontShowDummy=drag->isVisibleTo(this) || dockbackButton->isVisibleTo(this) ||
00334     d->toDesktopButton->isVisibleTo(this) || stayButton->isVisibleTo(this) ||
00335     closeButton->isVisibleTo(this);
00336   for (QPtrListIterator<KDockButton_Private> it( d->btns );it.current()!=0;++it) {
00337       layout->addWidget(it.current());
00338     dontShowDummy=dontShowDummy || (it.current()->isVisibleTo(this));
00339   }
00340   if (dontShowDummy) d->dummy->hide(); else d->dummy->show();
00341   layout->addWidget( closeButton );
00342   layout->activate();
00343   kdDebug()<<"KdockWidgetHeader::setDragPanel:minimum height="<<layout->minimumSize().height()<<endl;
00344 #ifdef __GNUC__
00345 #warning FIXME
00346 #endif
00347   drag->setFixedHeight( closeButton->height()); // /*layout->minimumS*/sizeHint().height() );
00348 }
00349 
00350 void KDockWidgetHeader::addButton(KDockButton_Private* btn) {
00351     if (!btn) return;
00352 
00353     if (btn->parentWidget()!=this) {
00354         btn->reparent(this,QPoint(0,0));
00355     }
00356     btn->setFixedSize(closeButton->pixmap()->width(),closeButton->pixmap()->height());
00357     if (!d->btns.containsRef(btn)) d->btns.append(btn);
00358 
00359     btn->show();
00360 
00361     delete layout;
00362     layout = new QHBoxLayout( this );
00363     layout->setResizeMode( QLayout::Minimum );
00364 
00365     layout->addWidget( drag );
00366     layout->addWidget( dockbackButton );
00367     layout->addWidget( d->toDesktopButton );
00368     layout->addWidget( d->dummy);
00369     layout->addWidget( stayButton );
00370      bool dontShowDummy=drag->isVisibleTo(this) || dockbackButton->isVisibleTo(this) ||
00371             d->toDesktopButton->isVisibleTo(this) || stayButton->isVisibleTo(this) ||
00372             closeButton->isVisibleTo(this);
00373      for (QPtrListIterator<KDockButton_Private> it( d->btns );it.current()!=0;++it) {
00374             layout->addWidget(it.current());
00375         dontShowDummy=dontShowDummy || (it.current()->isVisibleTo(this));
00376     }
00377     if (dontShowDummy) d->dummy->hide(); else d->dummy->show();
00378     layout->addWidget( closeButton );
00379     layout->activate();
00380     drag->setFixedHeight( layout->minimumSize().height() );
00381 }
00382 
00383 void KDockWidgetHeader::removeButton(KDockButton_Private* btn) {
00384     if (btn->parentWidget()==this) {
00385         if (d->btns.containsRef(btn)) d->btns.removeRef(btn);
00386         delete btn;
00387     }
00388 }
00389 
00390 
00391 void KDockWidgetHeader::slotStayClicked()
00392 {
00393   setDragEnabled(!stayButton->isOn());
00394 }
00395 
00396 bool KDockWidgetHeader::dragEnabled() const
00397 {
00398   return drag->isEnabled();
00399 }
00400 
00401 void KDockWidgetHeader::showUndockButton(bool show)
00402 {
00403   kdDebug()<<"KDockWidgetHeader::showUndockButton("<<show<<")"<<endl;
00404   if( d->showToDesktopButton == show )
00405     return;
00406 
00407   d->showToDesktopButton = show;
00408   if( !show || d->topLevel )
00409     d->toDesktopButton->hide( );
00410   else
00411     d->toDesktopButton->show( );
00412 }
00413 
00414 void KDockWidgetHeader::setDragEnabled(bool b)
00415 {
00416   stayButton->setOn(!b);
00417   closeButton->setEnabled(b);
00418   drag->setEnabled(b);
00419 }
00420 
00421 #ifndef NO_KDE2
00422 void KDockWidgetHeader::saveConfig( KConfig* c )
00423 {
00424   c->writeEntry( QString("%1%2").arg(parent()->name()).arg(":stayButton"), stayButton->isOn() );
00425 }
00426 
00427 void KDockWidgetHeader::loadConfig( KConfig* c )
00428 {
00429   setDragEnabled( !c->readBoolEntry( QString("%1%2").arg(parent()->name()).arg(":stayButton"), false ) );
00430 }
00431 #endif
00432 
00433 /*************************************************************************/
00434 
00435 class KDockManager::KDockManagerPrivate
00436 {
00437 public:
00441   QRect dragRect;
00442 
00446   QRect oldDragRect;
00447 
00451   bool readyToDrag;
00452 
00456   QPoint dragOffset;
00457 
00461   bool splitterOpaqueResize;
00462   bool splitterKeepSize;
00463   bool splitterHighResolution;
00464 
00465   QGuardedPtr<KDockWidget> mainDockWidget;
00466 
00467   QObjectList containerDocks;
00468 
00469   QGuardedPtr<KDockWidget> leftContainer;
00470   QGuardedPtr<KDockWidget> topContainer;
00471   QGuardedPtr<KDockWidget> rightContainer;
00472   QGuardedPtr<KDockWidget> bottomContainer;
00473   int m_readDockConfigMode;
00474 };
00475 
00476 
00477 /*************************************************************************/
00478 KDockWidget::KDockWidget( KDockManager* dockManager, const char* name, const QPixmap &pixmap, QWidget* parent, const QString& strCaption, const QString& strTabPageLabel, WFlags f)
00479 #ifdef BORDERLESS_WINDOWS
00480 : QWidget( parent, name, f )//| WType_Dialog | WStyle_Customize | WStyle_NoBorder )
00481 #else
00482 : QWidget( parent, name, f )
00483 #endif
00484   ,formerBrotherDockWidget(0L)
00485   ,currentDockPos(DockNone)
00486   ,formerDockPos(DockNone)
00487   ,widget(0L)
00488   ,pix(new QPixmap(pixmap))
00489   ,prevSideDockPosBeforeDrag(DockNone)
00490   ,isGroup(false)
00491 {
00492   d = new KDockWidgetPrivate();  // create private data
00493 
00494   d->_parent = parent;
00495 
00496   layout = new QVBoxLayout( this );
00497   layout->setResizeMode( QLayout::Minimum );
00498 
00499   manager = dockManager;
00500   manager->childDock->append( this );
00501   installEventFilter( manager );
00502 
00503   eDocking = DockFullDocking;
00504   sDocking = DockFullSite;
00505 
00506   header = 0L;
00507   setHeader( new KDockWidgetHeader( this, "AutoCreatedDockHeader" ) );
00508 
00509   if( strCaption.isNull() )
00510     setCaption( name );
00511   else
00512     setCaption( strCaption);
00513 
00514   if( strTabPageLabel == " ")
00515     setTabPageLabel( caption());
00516   else
00517     setTabPageLabel( strTabPageLabel);
00518 
00519   isTabGroup = false;
00520   d->isContainer =false;
00521   setIcon( pixmap);
00522   widget = 0L;
00523 
00524   QObject::connect(this, SIGNAL(hasUndocked()), manager->main, SLOT(slotDockWidgetUndocked()) );
00525   applyToWidget( parent, QPoint(0,0) );
00526 }
00527 
00528 void KDockWidget::setPixmap(const QPixmap& pixmap) {
00529     delete pix;
00530     pix=new QPixmap(pixmap);
00531     setIcon(*pix);
00532     KDockTabGroup *dtg=parentDockTabGroup();
00533     if (dtg)
00534         dtg->changeTab(this,pixmap,dtg->tabLabel(this));
00535      QWidget *contWid=parentDockContainer();
00536          if (contWid) {
00537             KDockContainer *x = dynamic_cast<KDockContainer*>(contWid);
00538                 if (x) {
00539                         x->setPixmap(this,pixmap);
00540                 }
00541          }
00542 }
00543 
00544 const QPixmap& KDockWidget::pixmap() const {
00545     return *pix;
00546 }
00547 
00548 KDockWidget::~KDockWidget()
00549 {
00550   d->pendingDtor = true;
00551   if ( !manager->undockProcess ){
00552     d->blockHasUndockedSignal = true;
00553     undock();
00554     d->blockHasUndockedSignal = false;
00555   }
00556 
00557   if (latestKDockContainer()) {
00558     KDockContainer *x = dynamic_cast<KDockContainer*>(latestKDockContainer());
00559     if (x) {
00560       x->removeWidget(this);
00561     }
00562   }
00563   emit iMBeingClosed();
00564   if (manager->d) manager->d->containerDocks.remove(this);
00565   manager->childDock->remove( this );
00566   delete pix;
00567   delete d; // destroy private data
00568   d=0;
00569 }
00570 
00571 void KDockWidget::paintEvent(QPaintEvent* pe)
00572 {
00573     QWidget::paintEvent(pe);
00574         QPainter paint;
00575         paint.begin( this );
00576         style().drawPrimitive (QStyle::PE_Panel, &paint, QRect(0,0,width(), height()), colorGroup());
00577         paint.end();
00578 }
00579 
00580 void KDockWidget::leaveEvent(QEvent *e)
00581 {
00582     QWidget::leaveEvent(e);
00583 #ifdef BORDERLESS_WINDOWS
00584     if (parent()) return;
00585 //  setCursor(QCursor(ArrowCursor));
00586 #endif
00587 }
00588 
00589 void KDockWidget::mousePressEvent(QMouseEvent* mme)
00590 {
00591 #ifdef BORDERLESS_WINDOWS
00592     if (!parent())
00593     {
00594         kdDebug()<<"KDockWidget::mousePressEvent"<<endl;
00595 
00596         bool bbottom;
00597         bool bleft;
00598         bool bright;
00599         bool btop;
00600         int styleheight;
00601         QPoint mp;
00602         mp=mme->pos();
00603             styleheight=2*style().pixelMetric(QStyle::PM_DefaultFrameWidth,this);
00604         bbottom=mp.y()>=height()-styleheight;
00605         btop=mp.y()<=styleheight;
00606         bleft=mp.x()<=styleheight;
00607         bright=mp.x()>=width()-styleheight;
00608         kdDebug()<<"mousemovevent"<<endl;
00609         d->resizing=true;
00610         if (bright)
00611         {
00612             if (btop)
00613             {
00614                 d->resizeMode=KDockWidgetPrivate::ResizeTopRight;
00615                 d->resizePos=QPoint(width(),0)-mme->pos();
00616 
00617             }
00618             else
00619             {
00620                 d->resizePos=QPoint(width(),height())-mme->pos();
00621                 if (bbottom) d->resizeMode=KDockWidgetPrivate::ResizeBottomRight;
00622                 else d->resizeMode=KDockWidgetPrivate::ResizeRight;
00623             }
00624         }
00625         else if (bleft)
00626         {
00627             if (btop) setCursor(QCursor(SizeFDiagCursor));
00628             else
00629             if (bbottom) setCursor(QCursor(SizeBDiagCursor));
00630             else setCursor(QCursor(SizeHorCursor));
00631         }
00632         else
00633         if (bbottom)
00634         {
00635             d->resizeMode=KDockWidgetPrivate::ResizeBottom;
00636             d->resizePos=QPoint(0,height())-mme->pos();
00637         }
00638         else
00639         if  (btop) setCursor(QCursor(SizeVerCursor));
00640         else d->resizing=false;
00641 
00642         if (d->resizing) grabMouse(cursor());
00643 
00644     }
00645 #endif
00646     QWidget::mousePressEvent(mme);
00647 }
00648 
00649 void KDockWidget::mouseReleaseEvent(QMouseEvent* ev)
00650 {
00651 #ifdef BORDERLESS_WINDOWS
00652     d->resizing=false;
00653     releaseMouse();
00654 #endif
00655     QWidget::mouseReleaseEvent(ev);
00656 }
00657 
00658 void  KDockWidget::mouseMoveEvent(QMouseEvent* mme)
00659 {
00660     QWidget::mouseMoveEvent(mme);
00661 #ifdef BORDERLESS_WINDOWS
00662     if (parent()) return;
00663 
00664     if (d->resizing)
00665     {
00666         switch (d->resizeMode)
00667         {
00668             case KDockWidgetPrivate::ResizeRight:
00669                 resize(mme->pos().x()+d->resizePos.x(),height());
00670                 break;
00671             case KDockWidgetPrivate::ResizeBottomRight:
00672                 resize(mme->pos().x()+d->resizePos.x(),mme->pos().y()+d->resizePos.y());
00673                 break;
00674             case KDockWidgetPrivate::ResizeBottom:
00675                 resize(width(),mme->pos().y()+d->resizePos.y());
00676                 break;
00677             default:
00678                 break;
00679         }
00680         return;
00681     }
00682 
00683 
00684     bool bbottom;
00685     bool bleft;
00686     bool bright;
00687     bool btop;
00688     int styleheight;
00689     QPoint mp;
00690     mp=mme->pos();
00691         styleheight=2*style().pixelMetric(QStyle::PM_DefaultFrameWidth,this);
00692     bbottom=mp.y()>=height()-styleheight;
00693     btop=mp.y()<=styleheight;
00694     bleft=mp.x()<=styleheight;
00695     bright=mp.x()>=width()-styleheight;
00696     kdDebug()<<"mousemovevent"<<endl;
00697     if (bright)
00698     {
00699         if (btop) setCursor(QCursor(SizeBDiagCursor));
00700         else
00701         if (bbottom) setCursor(QCursor(SizeFDiagCursor));
00702         else setCursor(QCursor(SizeHorCursor));
00703     }
00704     else if (bleft)
00705     {
00706         if (btop) setCursor(QCursor(SizeFDiagCursor));
00707         else
00708         if (bbottom) setCursor(QCursor(SizeBDiagCursor));
00709         else setCursor(QCursor(SizeHorCursor));
00710     }
00711     else
00712     if (bbottom ||  btop) setCursor(QCursor(SizeVerCursor));
00713     else setCursor(QCursor(ArrowCursor));
00714 #endif
00715 }
00716 
00717 void KDockWidget::setLatestKDockContainer(QWidget* container)
00718 {
00719     if (container)
00720     {
00721         if (dynamic_cast<KDockContainer*>(container))
00722             d->container=container;
00723         else
00724             d->container=0;
00725     }
00726 }
00727 
00728 QWidget* KDockWidget::latestKDockContainer()
00729 {
00730     if (!(d->container)) return 0;
00731     if (dynamic_cast<KDockContainer*>(d->container.operator->())) return d->container;
00732     return 0;
00733 }
00734 
00735 
00736 
00737 KDockWidgetAbstractHeader *KDockWidget::getHeader() {
00738     return header;
00739 }
00740 
00741 void KDockWidget::setHeader( KDockWidgetAbstractHeader* h )
00742 {
00743   if ( !h ) return;
00744 
00745   if ( header ){
00746     delete header;
00747     delete layout;
00748     header = h;
00749     layout = new QVBoxLayout( this );
00750     layout->setResizeMode( QLayout::Minimum );
00751     layout->addWidget( header );
00752      setWidget( widget );
00753   } else {
00754     header = h;
00755     layout->addWidget( header );
00756   }
00757   kdDebug()<<caption()<<": KDockWidget::setHeader"<<endl;
00758   setEnableDocking(eDocking);
00759 }
00760 
00761 void KDockWidget::setEnableDocking( int pos )
00762 {
00763   eDocking = pos;
00764   if( header && header->inherits( "KDockWidgetHeader" ) )
00765      ( ( KDockWidgetHeader* ) header )->showUndockButton( pos & DockDesktop );
00766   updateHeader();
00767 }
00768 
00769 void KDockWidget::updateHeader()
00770 {
00771   if ( parent() ){
00772 #ifdef BORDERLESS_WINDOWS
00773       layout->setMargin(0);
00774       setMouseTracking(false);
00775       setCursor(QCursor(ArrowCursor));
00776 #endif
00777 
00778     if ( (parent() == manager->main) || isGroup || (eDocking == KDockWidget::DockNone) ){
00779       header->hide();
00780     } else {
00781       header->setTopLevel( false );
00782       if (widget && dynamic_cast<KDockContainer*>(widget))
00783         header->hide();
00784       else
00785         header->show();
00786     }
00787   } else {
00788     header->setTopLevel( true );
00789     header->show();
00790 #ifdef BORDERLESS_WINDOWS
00791       layout->setMargin(2*style().pixelMetric(QStyle::PM_DefaultFrameWidth,this));
00792       setMouseTracking(true);
00793 #endif
00794   }
00795 }
00796 
00797 void KDockWidget::applyToWidget( QWidget* s, const QPoint& p )
00798 {
00799   if ( parent() != s )
00800   {
00801     hide();
00802     reparent(s, 0, QPoint(0,0), false);
00803   }
00804 
00805   if ( s && s->inherits("KDockMainWindow") ){
00806     ((KDockMainWindow*)s)->setView( this );
00807   }
00808 
00809   if ( manager && s == manager->main ){
00810       setGeometry( QRect(QPoint(0,0), manager->main->geometry().size()) );
00811   }
00812 
00813   if ( !s )
00814   {
00815     move(p);
00816 
00817 #ifndef NO_KDE2
00818 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00819     if (d->transient && d->_parent)
00820       XSetTransientForHint( qt_xdisplay(), winId(), d->_parent->winId() );
00821 
00822 #ifdef BORDERLESS_WINDOWS
00823     KWin::setType( winId(), NET::Override); //d->windowType );
00824 //      setWFlags(WStyle_Customize | WStyle_NoBorder | WStyle_Tool);
00825 #else
00826     KWin::setType( winId(), d->windowType );
00827 #endif // BORDERLESS_WINDOW
00828 #endif // Q_WS_X11 && ! K_WS_QTONLY
00829 #endif
00830 
00831   }
00832   updateHeader();
00833 
00834   setIcon(*pix);
00835 }
00836 
00837 void KDockWidget::show()
00838 {
00839   if ( parent() || manager->main->isVisible() )
00840     if ( !parent() ){
00841      emit manager->setDockDefaultPos( this );
00842      emit setDockDefaultPos();
00843      if ( parent() ){
00844         makeDockVisible();
00845       } else {
00846         QWidget::show();
00847       }
00848     } else {
00849      QWidget::show();
00850     }
00851 }
00852 
00853 #ifndef NO_KDE2
00854 
00855 void KDockWidget::setDockWindowType (NET::WindowType windowType)
00856 {
00857   d->windowType = windowType;
00858   applyToWidget( parentWidget(), QPoint(0,0) );
00859 }
00860 
00861 #endif
00862 
00863 void KDockWidget::setDockWindowTransient (QWidget *parent, bool transientEnabled)
00864 {
00865   d->_parent = parent;
00866   d->transient = transientEnabled;
00867   applyToWidget( parentWidget(), QPoint(0,0) );
00868 }
00869 
00870 QWidget *KDockWidget::transientTo() {
00871     if (d->transient && d->_parent) return d->_parent; else return 0;
00872 }
00873 
00874 bool KDockWidget::event( QEvent *event )
00875 {
00876   switch ( event->type() )
00877   {
00878     #undef FocusIn
00879     case QEvent::FocusIn:
00880       if (widget && !d->pendingFocusInEvent) {
00881          d->pendingFocusInEvent = true;
00882          widget->setFocus();
00883       }
00884       d->pendingFocusInEvent = false;
00885       break;
00886     case QEvent::ChildRemoved:
00887       if ( widget == ((QChildEvent*)event)->child() ) widget = 0L;
00888       break;
00889     case QEvent::Show:
00890       if ( widget ) widget->show();
00891       emit manager->change();
00892       break;
00893     case QEvent::Hide:
00894       if ( widget ) widget->hide();
00895       emit manager->change();
00896       break;
00897     case QEvent::CaptionChange:
00898       if ( parentWidget() ){
00899         if ( parent()->inherits("KDockSplitter") ){
00900           ((KDockSplitter*)(parent()))->updateName();
00901         }
00902         if ( parentDockTabGroup() ){
00903           setDockTabName( parentDockTabGroup() );
00904           parentDockTabGroup()->setTabLabel( this, tabPageLabel() );
00905         }
00906       }
00907       break;
00908     case QEvent::Close:
00909       emit iMBeingClosed();
00910       break;
00911     default:
00912       break;
00913   }
00914   return QWidget::event( event );
00915 }
00916 
00917 KDockWidget *KDockWidget::findNearestDockWidget(DockPosition pos)
00918 {
00919     if (!parent()) return 0;
00920     if (!parent()->inherits("KDockSplitter")) return 0;
00921     Orientation orientation=((pos==DockLeft) || (pos==DockRight)) ? Vertical:Horizontal;
00922         if (((KDockSplitter*)(parent()))->orientation()==orientation)
00923         {
00924             KDockWidget *neighbor=
00925                 ((pos==DockLeft)||(pos==DockTop))?
00926                 static_cast<KDockWidget*>(((KDockSplitter*)(parent()))->getFirst()):
00927                 static_cast<KDockWidget*>(((KDockSplitter*)(parent()))->getLast());
00928 
00929             if (neighbor==this)
00930             return (static_cast<KDockWidget*>(parent()->parent())->findNearestDockWidget(pos));
00931             else
00932             if (neighbor->getWidget() && (neighbor->getWidget()->qt_cast("KDockTabGroup")))
00933                 return (KDockWidget*)(((KDockTabGroup*)neighbor->getWidget())->page(0));
00934             else
00935             return neighbor;
00936         }
00937         else
00938         return (static_cast<KDockWidget*>(parent()->parent())->findNearestDockWidget(pos));
00939 
00940     return 0;
00941 }
00942 
00943 
00944 KDockWidget* KDockWidget::manualDock( KDockWidget* target, DockPosition dockPos, int spliPos, QPoint pos, bool check, int tabIndex )
00945 {
00946   if (this == target)
00947     return 0L;  // docking to itself not possible
00948 //  kdDebug()<<"manualDock called "<<endl;
00949   bool succes = true; // tested flag
00950 
00951   // check allowed this dock submit this operations
00952   if ( !(eDocking & (int)dockPos) ){
00953     succes = false;
00954 //  kdDebug()<<"KDockWidget::manualDock(): success = false (1)"<<endl;
00955   }
00956 
00957   KDockWidget *tmpTarget;
00958   switch (dockPos) {
00959     case DockLeft:tmpTarget=dockManager()->d->leftContainer;
00960         break;
00961     case DockRight:tmpTarget=dockManager()->d->rightContainer;
00962         break;
00963     case DockBottom:tmpTarget=dockManager()->d->bottomContainer;
00964         break;
00965     case DockTop:tmpTarget=dockManager()->d->topContainer;
00966         break;
00967     default: tmpTarget=0;
00968   }
00969 
00970   if (this!=tmpTarget) {
00971     if (target && (target==dockManager()->d->mainDockWidget) && tmpTarget) {
00972     return manualDock(tmpTarget,DockCenter,spliPos,pos,check,tabIndex);
00973     }
00974   }
00975 
00976   // check allowed target submit this operations
00977   if ( target && !(target->sDocking & (int)dockPos) ){
00978     succes = false;
00979 //  kdDebug()<<"KDockWidget::manualDock(): success = false (2)"<<endl;
00980   }
00981 
00982   if ( parent() && !parent()->inherits("KDockSplitter") && !parentDockTabGroup() &&
00983     !(dynamic_cast<KDockContainer*>(parent())) && !parentDockContainer()){
00984 //  kdDebug()<<"KDockWidget::manualDock(): success = false (3)"<<endl;
00985 //  kdDebug()<<parent()->name()<<endl;
00986     succes = false;
00987   }
00988 
00989 //  kdDebug()<<"KDockWidget::manualDock(): success == false "<<endl;
00990   if ( !succes ){
00991     // try to make another manualDock
00992     KDockWidget* dock_result = 0L;
00993     if ( target && !check ){
00994       KDockWidget::DockPosition another__dockPos = KDockWidget::DockNone;
00995       switch ( dockPos ){
00996         case KDockWidget::DockLeft  : another__dockPos = KDockWidget::DockRight ; break;
00997         case KDockWidget::DockRight : another__dockPos = KDockWidget::DockLeft  ; break;
00998         case KDockWidget::DockTop   : another__dockPos = KDockWidget::DockBottom; break;
00999         case KDockWidget::DockBottom: another__dockPos = KDockWidget::DockTop   ; break;
01000         default: break;
01001       }
01002       dock_result = target->manualDock( this, another__dockPos, spliPos, pos, true, tabIndex );
01003     }
01004     return dock_result;
01005   }
01006   // end check block
01007 
01008   d->blockHasUndockedSignal = true;
01009   undock();
01010   d->blockHasUndockedSignal = false;
01011 
01012   if ( !target ){
01013     move( pos );
01014     show();
01015     emit manager->change();
01016     return this;
01017   }
01018 
01019 //  kdDebug()<<"Looking for  KDockTabGroup"<<endl;
01020   KDockTabGroup* parentTab = target->parentDockTabGroup();
01021   if ( parentTab ){
01022     // add to existing TabGroup
01023     applyToWidget( parentTab );
01024     parentTab->insertTab( this, icon() ? *icon() : QPixmap(),
01025                           tabPageLabel(), tabIndex );
01026 
01027     QWidget *wantTransient=parentTab->transientTo();
01028     target->setDockWindowTransient(wantTransient,wantTransient);
01029 
01030     setDockTabName( parentTab );
01031     if( !toolTipStr.isEmpty())
01032       parentTab->setTabToolTip( this, toolTipStr);
01033 
01034     currentDockPos = KDockWidget::DockCenter;
01035     emit manager->change();
01036     return (KDockWidget*)parentTab->parent();
01037   }
01038   else
01039   {
01040 //      kdDebug()<<"Looking for  KDockContainer"<<endl;
01041     QWidget *contWid=target->parentDockContainer();
01042       if (!contWid) contWid=target->widget;
01043       if (contWid)
01044       {
01045         KDockContainer *cont=dynamic_cast<KDockContainer*>(contWid);
01046           if (cont)
01047           {
01048             if (latestKDockContainer() && (latestKDockContainer()!=contWid)) {
01049                 KDockContainer* dc = dynamic_cast<KDockContainer*>(latestKDockContainer());
01050                 if (dc) {
01051                     dc->removeWidget(this);
01052                 }
01053             }
01054 //          kdDebug()<<"KDockContainerFound"<<endl;
01055             applyToWidget( contWid );
01056             cont->insertWidget( this, icon() ? *icon() : QPixmap(),
01057                         tabPageLabel(), tabIndex );
01058             setLatestKDockContainer(contWid);
01059 //          setDockTabName( parentTab );
01060             if( !toolTipStr.isEmpty())
01061             cont->setToolTip( this, toolTipStr);
01062 
01063             currentDockPos = KDockWidget::DockCenter;
01064             emit manager->change();
01065             return (KDockWidget*)(cont->parentDockWidget());
01066 
01067           }
01068       }
01069   }
01070 
01071   // create a new dockwidget that will contain the target and this
01072   QWidget* parentDock = target->parentWidget();
01073   KDockWidget* newDock = new KDockWidget( manager, "tempName", QPixmap(""), parentDock );
01074   newDock->currentDockPos = target->currentDockPos;
01075 
01076   if ( dockPos == KDockWidget::DockCenter ){
01077     newDock->isTabGroup = true;
01078   } else {
01079     newDock->isGroup = true;
01080   }
01081   newDock->eDocking = (target->eDocking & eDocking) & (~(int)KDockWidget::DockCenter);
01082 
01083   newDock->applyToWidget( parentDock );
01084 
01085   if ( !parentDock ){
01086     // dock to a toplevel dockwidget means newDock is toplevel now
01087     newDock->move( target->frameGeometry().topLeft() );
01088     newDock->resize( target->geometry().size() );
01089     if ( target->isVisibleToTLW() ) newDock->show();
01090   }
01091 
01092   // redirect the dockback button to the new dockwidget
01093   if( target->formerBrotherDockWidget != 0L) {
01094     newDock->setFormerBrotherDockWidget(target->formerBrotherDockWidget);
01095     if( formerBrotherDockWidget != 0L)
01096       target->loseFormerBrotherDockWidget();
01097     }
01098   newDock->formerDockPos = target->formerDockPos;
01099 
01100 
01101  // HERE SOMETING CREATING CONTAINERS SHOULD BE ADDED !!!!!
01102   if ( dockPos == KDockWidget::DockCenter )
01103   {
01104     KDockTabGroup* tab = new KDockTabGroup( newDock, "_dock_tab");
01105     QObject::connect(tab, SIGNAL(currentChanged(QWidget*)), d, SLOT(slotFocusEmbeddedWidget(QWidget*)));
01106     newDock->setWidget( tab );
01107 
01108     target->applyToWidget( tab );
01109     applyToWidget( tab );
01110 
01111 
01112     tab->insertTab( target, target->icon() ? *(target->icon()) : QPixmap(),
01113                     target->tabPageLabel() );
01114 
01115 
01116 
01117     if( !target->toolTipString().isEmpty())
01118      tab->setTabToolTip( target, target->toolTipString());
01119 
01120     tab->insertTab( this, icon() ? *icon() : QPixmap(),
01121                     tabPageLabel(), tabIndex );
01122 
01123     QRect geom=newDock->geometry();
01124     QWidget *wantTransient=tab->transientTo();
01125     newDock->setDockWindowTransient(wantTransient,wantTransient);
01126     newDock->setGeometry(geom);
01127 
01128     if( !toolTipString().isEmpty())
01129       tab->setTabToolTip( this, toolTipString());
01130 
01131     setDockTabName( tab );
01132     tab->show();
01133 
01134     currentDockPos = DockCenter;
01135     target->formerDockPos = target->currentDockPos;
01136     target->currentDockPos = DockCenter;
01137   }
01138   else {
01139     // if to dock not to the center of the target dockwidget,
01140     // dock to newDock
01141     KDockSplitter* panner = 0L;
01142     if ( dockPos == KDockWidget::DockTop  || dockPos == KDockWidget::DockBottom ) panner = new KDockSplitter( newDock, "_dock_split_", Horizontal, spliPos, manager->splitterHighResolution() );
01143     if ( dockPos == KDockWidget::DockLeft || dockPos == KDockWidget::DockRight  ) panner = new KDockSplitter( newDock, "_dock_split_", Vertical , spliPos, manager->splitterHighResolution() );
01144     newDock->setWidget( panner );
01145 
01146     panner->setOpaqueResize(manager->splitterOpaqueResize());
01147     panner->setKeepSize(manager->splitterKeepSize());
01148     panner->setFocusPolicy( NoFocus );
01149     target->applyToWidget( panner );
01150     applyToWidget( panner );
01151     target->formerDockPos = target->currentDockPos;
01152     if ( dockPos == KDockWidget::DockRight) {
01153       panner->activate( target, this );
01154       currentDockPos = KDockWidget::DockRight;
01155       target->currentDockPos = KDockWidget::DockLeft;
01156     }
01157     else if( dockPos == KDockWidget::DockBottom) {
01158       panner->activate( target, this );
01159       currentDockPos = KDockWidget::DockBottom;
01160       target->currentDockPos = KDockWidget::DockTop;
01161     }
01162     else if( dockPos == KDockWidget::DockTop) {
01163       panner->activate( this, target );
01164       currentDockPos = KDockWidget::DockTop;
01165       target->currentDockPos = KDockWidget::DockBottom;
01166     }
01167     else if( dockPos == KDockWidget::DockLeft) {
01168       panner->activate( this, target );
01169       currentDockPos = KDockWidget::DockLeft;
01170       target->currentDockPos = KDockWidget::DockRight;
01171     }
01172     target->show();
01173     show();
01174     panner->show();
01175   }
01176 
01177   if ( parentDock ){
01178     if ( parentDock->inherits("KDockSplitter") ){
01179       KDockSplitter* sp = (KDockSplitter*)parentDock;
01180       sp->deactivate();
01181       if ( sp->getFirst() == target )
01182         sp->activate( newDock, 0L );
01183       else
01184         sp->activate( 0L, newDock );
01185     }
01186   }
01187 
01188   newDock->show();
01189   emit target->docking( this, dockPos );
01190   emit manager->replaceDock( target, newDock );
01191   emit manager->change();
01192 
01193   return newDock;
01194 }
01195 
01196 KDockTabGroup* KDockWidget::parentDockTabGroup() const
01197 {
01198   if ( !parent() ) return 0L;
01199   QWidget* candidate = parentWidget()->parentWidget();
01200   if ( candidate && candidate->inherits("KDockTabGroup") ) return (KDockTabGroup*)candidate;
01201   return 0L;
01202 }
01203 
01204 QWidget *KDockWidget::parentDockContainer() const
01205 {
01206   if (!parent()) return 0L;
01207   QWidget* candidate = parentWidget()->parentWidget();
01208   if (candidate && dynamic_cast<KDockContainer*>(candidate)) return candidate;
01209   return 0L;
01210 }
01211 
01212 
01213 void KDockWidget::setForcedFixedWidth(int w)
01214 {
01215     d->forcedWidth=w;
01216     setFixedWidth(w);
01217     if (!parent()) return;
01218     if (parent()->inherits("KDockSplitter"))
01219         static_cast<KDockSplitter*>(parent()->qt_cast("KDockSplitter"))->setForcedFixedWidth(this,w);
01220 }
01221 
01222 void KDockWidget::setForcedFixedHeight(int h)
01223 {
01224     d->forcedHeight=h;
01225     setFixedHeight(h);
01226     if (!parent()) return;
01227     if (parent()->inherits("KDockSplitter"))
01228         static_cast<KDockSplitter*>(parent()->qt_cast("KDockSplitter"))->setForcedFixedHeight(this,h);
01229 }
01230 
01231 int KDockWidget::forcedFixedWidth()
01232 {
01233     return d->forcedWidth;
01234 }
01235 
01236 int KDockWidget::forcedFixedHeight()
01237 {
01238     return d->forcedHeight;
01239 }
01240 
01241 void KDockWidget::restoreFromForcedFixedSize()
01242 {
01243     d->forcedWidth=-1;
01244     setMinimumWidth(0);
01245     setMaximumWidth(32000);
01246     setMinimumHeight(0);
01247     setMaximumHeight(32000);
01248     if (!parent()) return;
01249     if (parent()->inherits("KDockSplitter"))
01250         static_cast<KDockSplitter*>(parent()->qt_cast("KDockSplitter"))->restoreFromForcedFixedSize(this);
01251 }
01252 
01253 void