00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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>
00048 #include <X11/Xlib.h>
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());
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 )
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();
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;
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
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);
00824
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;
00948
00949 bool succes = true;
00950
00951
00952 if ( !(eDocking & (int)dockPos) ){
00953 succes = false;
00954
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
00977 if ( target && !(target->sDocking & (int)dockPos) ){
00978 succes = false;
00979
00980 }
00981
00982 if ( parent() && !parent()->inherits("KDockSplitter") && !parentDockTabGroup() &&
00983 !(dynamic_cast<KDockContainer*>(parent())) && !parentDockContainer()){
00984
00985
00986 succes = false;
00987 }
00988
00989
00990 if ( !succes ){
00991
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
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
01020 KDockTabGroup* parentTab = target->parentDockTabGroup();
01021 if ( parentTab ){
01022
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
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
01055 applyToWidget( contWid );
01056 cont->insertWidget( this, icon() ? *icon() : QPixmap(),
01057 tabPageLabel(), tabIndex );
01058 setLatestKDockContainer(contWid);
01059
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
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
01087 newDock->move( target->frameGeometry().topLeft() );
01088 newDock->resize( target->geometry().size() );
01089 if ( target->isVisibleToTLW() ) newDock->show();
01090 }
01091
01092
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
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
01140
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