1
2/* This file is part of the KDE libraries
3 Copyright (C) 2000 Max Judin <novaprint@mtu-net.ru>
4 Copyright (C) 2002,2003 Joseph Wenninger <jowenn@kde.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License version 2 as published by the Free Software Foundation.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20#include "k3dockwidget.h"
21#include "k3dockwidget_p.h"
22#include "k3dockwidget_private.h"
23
24#include <QtGui/QApplication>
25#include <QtGui/QLayout>
26#include <QtGui/QPainter>
27#include <Qt3Support/Q3StrIList>
28#include <QtGui/QCursor>
29#include <QtGui/QWidget>
30#include <QtGui/QTabWidget>
31
32#include <QtGui/QStyle>
33#include <QMouseEvent>
34#include <QObject>
35#include <QStylePainter>
36#include <QStyleOption>
37
38#ifndef NO_KDE2
39#include <kconfiggroup.h>
40#include <kglobal.h>
41#include <klocale.h>
42#include <ktoolbar.h>
43#include <k3popupmenu.h>
44#include <kwindowsystem.h>
45#include <kdebug.h>
46#include <kglobalsettings.h>
47
48#include <config.h>
49#ifdef Q_WS_X11
50#include <X11/X.h>
51#include <X11/Xlib.h>
52#include <qx11info_x11.h>
53#endif
54#else
55#include <q3toolbar.h>
56#include <q3popupmenu.h>
57#endif
58
59#include <stdlib.h>
60
61#undef BORDERLESS_WINDOWS
62
63#define DOCK_CONFIG_VERSION "0.0.5"
64
65static const char* const dockback_xpm[]={
66"6 6 2 1",
67"# c black",
68". c None",
69"......",
70".#....",
71"..#..#",
72"...#.#",
73"....##",
74"..####"};
75
76static const char* const todesktop_xpm[]={
77"5 5 2 1",
78"# c black",
79". c None",
80"####.",
81"##...",
82"#.#..",
83"#..#.",
84"....#"};
85
86static const char* const not_close_xpm[]={
87"5 5 2 1",
88"# c black",
89". c None",
90"#####",
91"#...#",
92"#...#",
93"#...#",
94"#####"};
95
96/**
97 * A special kind of KMainWindow that is able to have dockwidget child widgets.
98 *
99 * The main widget should be a dockwidget where other dockwidgets can be docked to
100 * the left, right, top, bottom or to the middle.
101 * Furthermore, the K3DockMainWindow has got the KDocManager and some data about the dock states.
102 *
103 * @author Max Judin.
104*/
105K3DockMainWindow::K3DockMainWindow( QWidget* parent, const char *name, Qt::WindowFlags f)
106 : KXmlGuiWindow( parent, f )
107{
108 setObjectName( name );
109 QString new_name = QString(name) + QString("_DockManager");
110 dockManager = new K3DockManager( this, new_name.toLatin1().constData() );
111 mainDockWidget = 0L;
112 setAttribute( Qt::WA_DeleteOnClose );
113}
114
115K3DockMainWindow::~K3DockMainWindow()
116{
117 delete dockManager;
118}
119
120K3DockManager* K3DockMainWindow::manager() const
121{
122 return dockManager;
123}
124
125void K3DockMainWindow::setMainDockWidget( K3DockWidget* mdw )
126{
127 if ( mainDockWidget == mdw ) return;
128 mainDockWidget = mdw;
129 dockManager->setMainDockWidget2(mdw);
130}
131
132K3DockWidget* K3DockMainWindow::getMainDockWidget() const
133{
134 return mainDockWidget;
135}
136
137void K3DockMainWindow::setView( QWidget *view )
138{
139 if ( view->isA("K3DockWidget") ){
140 if ( view->parent() != this ) ((K3DockWidget*)view)->applyToWidget( this );
141 }
142
143#ifndef NO_KDE2
144 KXmlGuiWindow::setCentralWidget(view);
145#else
146 Q3MainWindow::setCentralWidget(view);
147#endif
148}
149
150K3DockWidget* K3DockMainWindow::createDockWidget( const QString& name, const QPixmap &pixmap, QWidget* parent, const QString& strCaption, const QString& strTabPageLabel)
151{
152 return new K3DockWidget( dockManager, name.toLatin1().constData(), pixmap, parent, strCaption, strTabPageLabel );
153}
154
155void K3DockMainWindow::activateDock()
156{
157 dockManager->activate();
158}
159
160Q3PopupMenu* K3DockMainWindow::dockHideShowMenu() const
161{
162 return dockManager->dockHideShowMenu();
163}
164
165void K3DockMainWindow::makeDockVisible( K3DockWidget* dock )
166{
167 if ( dock )
168 dock->makeDockVisible();
169}
170
171void K3DockMainWindow::makeDockInvisible( K3DockWidget* dock )
172{
173 if ( dock )
174 dock->undock();
175}
176
177void K3DockMainWindow::makeWidgetDockVisible( QWidget* widget )
178{
179 makeDockVisible( dockManager->findWidgetParentDock(widget) );
180}
181
182void K3DockMainWindow::writeDockConfig(QDomElement &base)
183{
184 dockManager->writeConfig(base);
185}
186
187void K3DockMainWindow::readDockConfig(QDomElement &base)
188{
189 dockManager->readConfig(base);
190}
191
192#ifndef NO_KDE2
193void K3DockMainWindow::writeDockConfig( KConfig* c, const QString &group )
194{
195 dockManager->writeConfig( c, group );
196}
197
198void K3DockMainWindow::readDockConfig( KConfig* c, const QString &group )
199{
200 dockManager->readConfig( c, group );
201}
202#endif
203
204void K3DockMainWindow::slotDockWidgetUndocked()
205{
206 QObject* pSender = (QObject*) sender();
207 if (!pSender->inherits("K3DockWidget")) return;
208 K3DockWidget* pDW = (K3DockWidget*) pSender;
209 emit dockWidgetHasUndocked( pDW);
210}
211
212/*************************************************************************/
213K3DockWidgetAbstractHeaderDrag::K3DockWidgetAbstractHeaderDrag( K3DockWidgetAbstractHeader* parent, K3DockWidget* dock, const char* name )
214:QFrame( parent, name )
215{
216 dw = dock;
217 installEventFilter( dock->dockManager() );
218}
219
220K3DockWidgetAbstractHeaderDrag::~K3DockWidgetAbstractHeaderDrag()
221{
222}
223
224K3DockWidget* K3DockWidgetAbstractHeaderDrag::dockWidget() const
225{
226 return dw;
227}
228/*************************************************************************/
229K3DockWidgetHeaderDrag::K3DockWidgetHeaderDrag( K3DockWidgetAbstractHeader* parent, K3DockWidget* dock, const char* name )
230:K3DockWidgetAbstractHeaderDrag( parent, dock, name )
231{
232}
233
234K3DockWidgetHeaderDrag::~K3DockWidgetHeaderDrag()
235{
236}
237
238void K3DockWidgetHeaderDrag::paintEvent( QPaintEvent* )
239{
240 QStylePainter paint;
241
242 paint.begin( this );
243 QStyleOption qso;
244 qso.initFrom( this );
245 paint.drawPrimitive( QStyle::PE_IndicatorToolBarHandle, qso );
246
247 paint.end();
248}
249/*************************************************************************/
250K3DockWidgetAbstractHeader::K3DockWidgetAbstractHeader( K3DockWidget* parent, const char* name )
251:QFrame( parent, name )
252{
253}
254/*************************************************************************/
255K3DockWidgetHeader::K3DockWidgetHeader( K3DockWidget* parent, const char* name )
256:K3DockWidgetAbstractHeader( parent, name )
257{
258#ifdef BORDERLESS_WINDOWS
259 setCursor(QCursor(Qt::ArrowCursor));
260#endif
261 d = new K3DockWidgetHeaderPrivate( this );
262
263 layout = new QHBoxLayout( this );
264 layout->setSizeConstraint( QLayout::Minimum );
265
266 drag = new K3DockWidgetHeaderDrag( this, parent );
267
268 // Auxillary pixmap (to create the dock buttons)
269 QPixmap auxPix;
270
271 closeButton = new K3DockButton_Private( this, "DockCloseButton" );
272 closeButton->setToolTip( i18n("Close") );
273 auxPix = style()->standardPixmap( QStyle::SP_DockWidgetCloseButton );
274 closeButton->setIcon( QIcon( auxPix ) );
275 closeButton->setFixedSize( auxPix.size() );
276 connect( closeButton, SIGNAL(clicked()), parent, SIGNAL(headerCloseButtonClicked()));
277 connect( closeButton, SIGNAL(clicked()), parent, SLOT(undock()));
278
279 stayButton = new K3DockButton_Private( this, "DockStayButton" );
280 stayButton->setToolTip( i18nc("Freeze the window geometry", "Freeze") );
281 stayButton->setCheckable( true );
282 auxPix = QPixmap( not_close_xpm );
283 stayButton->setIcon( QIcon( auxPix ) );
284 stayButton->setFixedSize( auxPix.size() );
285 connect( stayButton, SIGNAL(clicked()), this, SLOT(slotStayClicked()));
286
287 dockbackButton = new K3DockButton_Private( this, "DockbackButton" );
288 dockbackButton->setToolTip( i18nc("Dock this window", "Dock") );
289 auxPix = QPixmap( dockback_xpm );
290 dockbackButton->setIcon( QIcon( auxPix ) );
291 dockbackButton->setFixedSize( auxPix.size() );
292 connect( dockbackButton, SIGNAL(clicked()), parent, SIGNAL(headerDockbackButtonClicked()));
293 connect( dockbackButton, SIGNAL(clicked()), parent, SLOT(dockBack()));
294
295 d->toDesktopButton = new K3DockButton_Private( this, "ToDesktopButton" );
296 d->toDesktopButton->setToolTip( i18n("Detach") );
297 auxPix = QPixmap( todesktop_xpm );
298 d->toDesktopButton->setIcon( QIcon( auxPix ) );
299 d->toDesktopButton->setFixedSize( auxPix.size() );
300 connect( d->toDesktopButton, SIGNAL(clicked()), parent, SLOT(toDesktop()));
301 stayButton->hide();
302
303 d->dummy = new QWidget( this );
304 d->dummy->setFixedSize( 1, closeButton->height() );
305
306
307 layout->addWidget( drag );
308 layout->addWidget( dockbackButton );
309 layout->addWidget( d->toDesktopButton );
310 layout->addWidget( d->dummy);
311 layout->addWidget( stayButton );
312 layout->addWidget( closeButton );
313 layout->activate();
314 d->dummy->hide();
315#if 1
316 drag->setFixedHeight( closeButton->height() );
317#else
318 drag->setFixedHeight( layout->minimumSize().height() );
319#endif
320}
321
322K3DockWidgetHeader::~K3DockWidgetHeader()
323{
324}
325
326void K3DockWidgetHeader::setTopLevel( bool isTopLevel )
327{
328 d->topLevel = isTopLevel;
329 if ( isTopLevel ){
330 K3DockWidget* par = (K3DockWidget*)parent();
331 if( par && par->isDockBackPossible() )
332 dockbackButton->show();
333 else
334 dockbackButton->hide();
335
336 stayButton->hide();
337 closeButton->hide();
338 d->toDesktopButton->hide();
339 drag->setEnabled( true );
340 } else {
341 dockbackButton->hide();
342 stayButton->hide();
343 if (!d->forceCloseButtonHidden) closeButton->show();
344 if( d->showToDesktopButton )
345 d->toDesktopButton->show();
346 }
347 layout->activate();
348
349 bool dontShowDummy=drag->isVisibleTo(this) || dockbackButton->isVisibleTo(this) ||
350 d->toDesktopButton->isVisibleTo(this) || stayButton->isVisibleTo(this) ||
351 closeButton->isVisibleTo(this);
352 for (Q3PtrListIterator<K3DockButton_Private> it( d->btns );it.current();++it) {
353 dontShowDummy=dontShowDummy || (it.current()->isVisibleTo(this));
354 }
355 if (dontShowDummy) d->dummy->hide(); else d->dummy->show();
356
357 updateGeometry();
358}
359
360void K3DockWidgetHeader::forceCloseButtonHidden(bool hidden) {
361 d->forceCloseButtonHidden=hidden;
362 if (hidden) closeButton->hide();
363 else closeButton->show();
364}
365
366K3DockWidgetHeaderDrag *K3DockWidgetHeader::dragPanel() {
367 return drag;
368}
369
370void K3DockWidgetHeader::setDragPanel( K3DockWidgetHeaderDrag* nd )
371{
372 if ( !nd ) return;
373
374 delete layout;
375 layout = new QHBoxLayout( this );
376 layout->setSizeConstraint( QLayout::Minimum );
377
378 delete drag;
379 drag = nd;
380 if (drag->parentWidget()!=this) {
381 drag->setParent(this);
382 drag->move(0,0);
383 }
384
385
386 layout->addWidget( drag );
387 layout->addWidget( dockbackButton );
388 layout->addWidget( d->dummy );
389 layout->addWidget( d->toDesktopButton );
390 layout->addWidget( stayButton );
391 bool dontShowDummy=drag->isVisibleTo(this) || dockbackButton->isVisibleTo(this) ||
392 d->toDesktopButton->isVisibleTo(this) || stayButton->isVisibleTo(this) ||
393 closeButton->isVisibleTo(this);
394 for (Q3PtrListIterator<K3DockButton_Private> it( d->btns );it.current();++it) {
395 layout->addWidget(it.current());
396 dontShowDummy=dontShowDummy || (it.current()->isVisibleTo(this));
397 }
398 if (dontShowDummy) d->dummy->hide(); else d->dummy->show();
399 layout->addWidget( closeButton );
400 layout->activate();
401 kDebug(282)<<"KdockWidgetHeader::setDragPanel:minimum height="<<layout->minimumSize().height();
402 //FIXME somebody left this here, but we don't know what the hell it's for.
403 drag->setFixedHeight( closeButton->height()); // /*layout->minimumS*/sizeHint().height() );
404}
405
406void K3DockWidgetHeader::addButton(K3DockButton_Private* btn) {
407 if (!btn) return;
408
409 if (btn->parentWidget()!=this) {
410 btn->setParent(this);
411 }
412 btn->setFixedSize( closeButton->size() );
413 if (!d->btns.containsRef(btn)) d->btns.append(btn);
414
415 btn->show();
416
417 delete layout;
418 layout = new QHBoxLayout( this );
419 layout->setSizeConstraint( QLayout::Minimum );
420
421 layout->addWidget( drag );
422 layout->addWidget( dockbackButton );
423 layout->addWidget( d->toDesktopButton );
424 layout->addWidget( d->dummy);
425 layout->addWidget( stayButton );
426 bool dontShowDummy=drag->isVisibleTo(this) || dockbackButton->isVisibleTo(this) ||
427 d->toDesktopButton->isVisibleTo(this) || stayButton->isVisibleTo(this) ||
428 closeButton->isVisibleTo(this);
429 for (Q3PtrListIterator<K3DockButton_Private> it( d->btns );it.current();++it) {
430 layout->addWidget(it.current());
431 dontShowDummy=dontShowDummy || (it.current()->isVisibleTo(this));
432 }
433 if (dontShowDummy) d->dummy->hide(); else d->dummy->show();
434 layout->addWidget( closeButton );
435 layout->activate();
436 drag->setFixedHeight( layout->minimumSize().height() );
437}
438
439void K3DockWidgetHeader::removeButton(K3DockButton_Private* btn) {
440 if (btn->parentWidget()==this) {
441 if (d->btns.containsRef(btn)) d->btns.removeRef(btn);
442 delete btn;
443 }
444}
445
446
447void K3DockWidgetHeader::slotStayClicked()
448{
449 setDragEnabled(!stayButton->isChecked());
450}
451
452bool K3DockWidgetHeader::dragEnabled() const
453{
454 return drag->isEnabled();
455}
456
457void K3DockWidgetHeader::showUndockButton(bool show)
458{
459 kDebug(282)<<"K3DockWidgetHeader::showUndockButton("<<show<<")";
460 if( d->showToDesktopButton == show )
461 return;
462
463 d->showToDesktopButton = show;
464 if( !show || d->topLevel )
465 d->toDesktopButton->hide( );
466 else
467 d->toDesktopButton->show( );
468}
469
470void K3DockWidgetHeader::setDragEnabled(bool b)
471{
472 stayButton->setChecked(!b);
473 closeButton->setEnabled(b);
474 drag->setEnabled(b);
475}
476
477#ifndef NO_KDE2
478void K3DockWidgetHeader::saveConfig( KConfigGroup* cg )
479{
480 cg->writeEntry( QString("%1:stayButton").arg(parent()->name()), stayButton->isChecked() );
481}
482
483void K3DockWidgetHeader::loadConfig( KConfigGroup* cg )
484{
485 setDragEnabled( !cg->readEntry( QString("%1:stayButton").arg(parent()->name()), false ) );
486}
487#endif
488
489/*************************************************************************/
490
491class K3DockManager::K3DockManagerPrivate
492{
493public:
494 /**
495 * This rectangle is used to highlight the current dockposition. It stores global screen coordinates.
496 */
497 QRect dragRect;
498
499 /**
500 * This rectangle is used to erase the previously highlighted dockposition. It stores global screen coordinates.
501 */
502 QRect oldDragRect;
503
504 /**
505 * This flag stores the information if dragging is ready to start. Used between mousePress and mouseMove event.
506 */
507 bool readyToDrag;
508
509 /**
510 * This variable stores the offset of the mouse cursor to the upper left edge of the current drag widget.
511 */
512 QPoint dragOffset;
513
514 /**
515 * These flags store information about the splitter behavior
516 */
517 bool splitterOpaqueResize;
518 bool splitterKeepSize;
519 bool splitterHighResolution;
520
521 QPointer<K3DockWidget> mainDockWidget;
522
523 QList<QObject*> containerDocks;
524
525 QPointer<K3DockWidget> leftContainer;
526 QPointer<K3DockWidget> topContainer;
527 QPointer<K3DockWidget> rightContainer;
528 QPointer<K3DockWidget> bottomContainer;
529 int m_readDockConfigMode;
530};
531
532
533/*************************************************************************/
534K3DockWidget::K3DockWidget( K3DockManager* dockManager, const char* name, const QPixmap &pixmap, QWidget* parent, const QString& strCaption, const QString& strTabPageLabel, Qt::WindowFlags f)
535#ifdef BORDERLESS_WINDOWS
536: QWidget( parent, name, f )//| WType_Dialog | WStyle_Customize | WStyle_NoBorder )
537#else
538: QWidget( parent, name, f )
539#endif
540 ,formerBrotherDockWidget(0L)
541 ,currentDockPos(DockNone)
542 ,formerDockPos(DockNone)
543 ,widget(0L)
544 ,pix(new QPixmap(pixmap))
545 ,prevSideDockPosBeforeDrag(DockNone)
546 ,isGroup(false)
547{
548 d = new K3DockWidgetPrivate(); // create private data
549
550 d->_parent = parent;
551
552 layout = new QVBoxLayout( this );
553 layout->setSizeConstraint( QLayout::Minimum );
554
555 manager = dockManager;
556 manager->childDock->append( this );
557 installEventFilter( manager );
558
559 eDocking = DockFullDocking;
560 sDocking = DockFullSite;
561
562 header = 0L;
563 setHeader( new K3DockWidgetHeader( this, "AutoCreatedDockHeader" ) );
564
565 if( strCaption.isNull() )
566 setWindowTitle( name );
567 else
568 setWindowTitle( strCaption);
569
570 if( strTabPageLabel == " ")
571 setTabPageLabel( windowTitle());
572 else
573 setTabPageLabel( strTabPageLabel);
574
575 isTabGroup = false;
576 d->isContainer =false;
577 setIcon( pixmap);
578 widget = 0L;
579
580 QObject::connect(this, SIGNAL(hasUndocked()), manager->main, SLOT(slotDockWidgetUndocked()) );
581 applyToWidget( parent, QPoint(0,0) );
582}
583
584void K3DockWidget::setPixmap(const QPixmap& pixmap) {
585 delete pix;
586 pix=new QPixmap(pixmap);
587 setIcon(*pix);
588 K3DockTabGroup *dtg=parentDockTabGroup();
589 if (dtg)
590 dtg->changeTab(this,pixmap,dtg->tabLabel(this));
591 QWidget *contWid=parentDockContainer();
592 if (contWid) {
593 K3DockContainer *x = dynamic_cast<K3DockContainer*>(contWid);
594 if (x) {
595 x->setPixmap(this,pixmap);
596 }
597 }
598}
599
600const QPixmap& K3DockWidget::pixmap() const {
601 return *pix;
602}
603
604K3DockWidget::~K3DockWidget()
605{
606 d->pendingDtor = true;
607 if ( !manager->undockProcess ){
608 d->blockHasUndockedSignal = true;
609 undock();
610 d->blockHasUndockedSignal = false;
611 }
612
613 if (latestK3DockContainer()) {
614 K3DockContainer *x = dynamic_cast<K3DockContainer*>(latestK3DockContainer());
615 if (x) {
616 x->removeWidget(this);
617 }
618 }
619 emit iMBeingClosed();
620 if (manager->d) manager->d->containerDocks.removeAll(this);
621 manager->childDock->removeAll( this );
622 delete pix;
623 delete d; // destroy private data
624 d=0;
625}
626
627void K3DockWidget::paintEvent(QPaintEvent* pe)
628{
629 QWidget::paintEvent(pe);
630 QPainter paint;
631 paint.begin( this );
632 QStyleOption option;
633 option.init(this);
634 option.rect = QRect( 0, 0, width(), height() );
635 style()->drawPrimitive (QStyle::PE_FrameDockWidget, &option, &paint, this);
636 paint.end();
637}
638
639void K3DockWidget::leaveEvent(QEvent *e)
640{
641 QWidget::leaveEvent(e);
642#ifdef BORDERLESS_WINDOWS
643 if (parent()) return;
644// setCursor(QCursor(ArrowCursor));
645#endif
646}
647
648void K3DockWidget::mousePressEvent(QMouseEvent* mme)
649{
650#ifdef BORDERLESS_WINDOWS
651 if (!parent())
652 {
653 kDebug(282)<<"K3DockWidget::mousePressEvent";
654
655 bool bbottom;
656 bool bleft;
657 bool bright;
658 bool btop;
659 int styleheight;
660 QPoint mp;
661 mp=mme->pos();
662 styleheight=2*style().pixelMetric(QStyle::PM_DefaultFrameWidth,this);
663 bbottom=mp.y()>=height()-styleheight;
664 btop=mp.y()<=styleheight;
665 bleft=mp.x()<=styleheight;
666 bright=mp.x()>=width()-styleheight;
667 kDebug(282)<<"mousemovevent";
668 d->resizing=true;
669 if (bright)
670 {
671 if (btop)
672 {
673 d->resizeMode=K3DockWidgetPrivate::ResizeTopRight;
674 d->resizePos=QPoint(width(),0)-mme->pos();
675
676 }
677 else
678 {
679 d->resizePos=QPoint(width(),height())-mme->pos();
680 if (bbottom) d->resizeMode=K3DockWidgetPrivate::ResizeBottomRight;
681 else d->resizeMode=K3DockWidgetPrivate::ResizeRight;
682 }
683 }
684 else if (bleft)
685 {
686 if (btop) setCursor(QCursor(Qt::SizeFDiagCursor));
687 else
688 if (bbottom) setCursor(QCursor(Qt::SizeBDiagCursor));
689 else setCursor(QCursor(Qt::SizeHorCursor));
690 }
691 else
692 if (bbottom)
693 {
694 d->resizeMode=K3DockWidgetPrivate::ResizeBottom;
695 d->resizePos=QPoint(0,height())-mme->pos();
696 }
697 else
698 if (btop) setCursor(QCursor(Qt::SizeVerCursor));
699 else d->resizing=false;
700
701 if (d->resizing) grabMouse(cursor());
702
703 }
704#endif
705 QWidget::mousePressEvent(mme);
706}
707
708void K3DockWidget::mouseReleaseEvent(QMouseEvent* ev)
709{
710#ifdef BORDERLESS_WINDOWS
711 d->resizing=false;
712 releaseMouse();
713#endif
714 QWidget::mouseReleaseEvent(ev);
715}
716
717void K3DockWidget::mouseMoveEvent(QMouseEvent* mme)
718{
719 QWidget::mouseMoveEvent(mme);
720#ifdef BORDERLESS_WINDOWS
721 if (parent()) return;
722
723 if (d->resizing)
724 {
725 switch (d->resizeMode)
726 {
727 case K3DockWidgetPrivate::ResizeRight:
728 resize(mme->pos().x()+d->resizePos.x(),height());
729 break;
730 case K3DockWidgetPrivate::ResizeBottomRight:
731 resize(mme->pos().x()+d->resizePos.x(),mme->pos().y()+d->resizePos.y());
732 break;
733 case K3DockWidgetPrivate::ResizeBottom:
734 resize(width(),mme->pos().y()+d->resizePos.y());
735 break;
736 default:
737 break;
738 }
739 return;
740 }
741
742
743 bool bbottom;
744 bool bleft;
745 bool bright;
746 bool btop;
747 int styleheight;
748 QPoint mp;
749 mp=mme->pos();
750 styleheight=2*style().pixelMetric(QStyle::PM_DefaultFrameWidth,this);
751 bbottom=mp.y()>=height()-styleheight;
752 btop=mp.y()<=styleheight;
753 bleft=mp.x()<=styleheight;
754 bright=mp.x()>=width()-styleheight;
755 kDebug(282)<<"mousemovevent";
756 if (bright)
757 {
758 if (btop) setCursor(QCursor(Qt::SizeBDiagCursor));
759 else
760 if (bbottom) setCursor(QCursor(Qt::SizeFDiagCursor));
761 else setCursor(QCursor(Qt::SizeHorCursor));
762 }
763 else if (bleft)
764 {
765 if (btop) setCursor(QCursor(Qt::SizeFDiagCursor));
766 else
767 if (bbottom) setCursor(QCursor(Qt::SizeBDiagCursor));
768 else setCursor(QCursor(Qt::SizeHorCursor));
769 }
770 else
771 if (bbottom || btop) setCursor(QCursor(Qt::SizeVerCursor));
772 else setCursor(QCursor(Qt::ArrowCursor));
773#endif
774}
775
776void K3DockWidget::setLatestK3DockContainer(QWidget* container)
777{
778 if (container)
779 {
780 if (dynamic_cast<K3DockContainer*>(container))
781 d->container=container;
782 else
783 d->container=0;
784 }
785}
786
787QWidget* K3DockWidget::latestK3DockContainer()
788{
789 if (!(d->container)) return 0;
790 if (dynamic_cast<K3DockContainer*>(d->container.operator->())) return d->container;
791 return 0;
792}
793
794
795
796K3DockWidgetAbstractHeader *K3DockWidget::getHeader() {
797 return header;
798}
799
800void K3DockWidget::setHeader( K3DockWidgetAbstractHeader* h )
801{
802 if ( !h ) return;
803
804 if ( header ){
805 delete header;
806 delete layout;
807 header = h;
808 layout = new QVBoxLayout( this );
809 layout->setSizeConstraint( QLayout::Minimum );
810 layout->addWidget( header );
811 setWidget( widget );
812 } else {
813 header = h;
814 layout->addWidget( header );
815 }
816// kDebug(282)<<windowTitle()<<": K3DockWidget::setHeader";
817 setEnableDocking(eDocking);
818}
819
820void K3DockWidget::setEnableDocking( int pos )
821{
822 eDocking = pos;
823 if( header ) {
824 if ( header->inherits( "K3DockWidgetHeader" ) )
825 ( ( K3DockWidgetHeader* ) header )->showUndockButton( pos & DockDesktop );
826 updateHeader();
827 }
828}
829
830int K3DockWidget::enableDocking() const
831{
832 return eDocking;
833}
834
835void K3DockWidget::setDockSite( int pos )
836{
837 sDocking = pos;
838}
839
840int K3DockWidget::dockSite() const
841{
842 return sDocking;
843}
844
845void K3DockWidget::updateHeader()
846{
847 if ( parent() ){
848#ifdef BORDERLESS_WINDOWS
849 layout->setMargin(0);
850 setMouseTracking(false);
851 setCursor(QCursor(Qt::ArrowCursor));
852#endif
853
854 if ( (parent() == manager->main) || isGroup || (eDocking == K3DockWidget::DockNone) ){
855 header->hide();
856 } else {
857 header->setTopLevel( false );
858 if (widget && dynamic_cast<K3DockContainer*>(widget))
859 header->hide();
860 else
861 header->show();
862 }
863 } else {
864 header->setTopLevel( true );
865 header->show();
866#ifdef BORDERLESS_WINDOWS
867 layout->setMargin(2*style().pixelMetric(QStyle::PM_DefaultFrameWidth,this));
868 setMouseTracking(true);
869#endif
870 }
871}
872
873void K3DockWidget::applyToWidget( QWidget* s, const QPoint& p )
874{
875 if ( parent() != s )
876 {
877 hide();
878 setParent(s);
879 move(0,0);
880 }
881
882 if ( s && s->inherits("K3DockMainWindow") ){
883 ((K3DockMainWindow*)s)->setView( this );
884 }
885
886 if ( manager && s == manager->main ){
887 setGeometry( QRect(QPoint(0,0), manager->main->geometry().size()) );
888 }
889
890 if ( !s )
891 {
892 move(p);
893
894#ifndef NO_KDE2
895#ifdef Q_WS_X11
896 if (d->transient && d->_parent)
897 XSetTransientForHint( QX11Info::display(), winId(), d->_parent->winId() );
898
899#ifdef BORDERLESS_WINDOWS
900 KWindowSystem::setType( winId(), NET::Override); //d->windowType );
901// setWFlags(WStyle_Customize | WStyle_NoBorder | WStyle_Tool);
902#else
903 KWindowSystem::setType( winId(), d->windowType );
904#endif // BORDERLESS_WINDOW
905#endif // Q_WS_X11
906#endif
907
908 }
909 updateHeader();
910
911 setIcon(*pix);
912}
913
914void K3DockWidget::show()
915{
916 if ( parent() || manager->main->isVisible() ) {
917 if ( !parent() ){
918 emit manager->setDockDefaultPos( this );
919 emit setDockDefaultPos();
920 if ( parent() ){
921 makeDockVisible();
922 } else {
923 QWidget::show();
924 }
925 } else {
926 QWidget::show();
927 }
928 }
929}
930
931#ifndef NO_KDE2
932
933void K3DockWidget::setDockWindowType (NET::WindowType windowType)
934{
935 d->windowType = windowType;
936 applyToWidget( parentWidget(), QPoint(0,0) );
937}
938
939#endif
940
941void K3DockWidget::setDockWindowTransient (QWidget *parent, bool transientEnabled)
942{
943 d->_parent = parent;
944 d->transient = transientEnabled;
945 applyToWidget( parentWidget(), QPoint(0,0) );
946}
947
948QWidget *K3DockWidget::transientTo() {
949 if (d->transient && d->_parent) return d->_parent; else return 0;
950}
951
952bool K3DockWidget::event( QEvent *event )
953{
954 switch ( event->type() )
955 {
956 #undef FocusIn
957 case QEvent::FocusIn:
958 if (widget && !d->pendingFocusInEvent) {
959 d->pendingFocusInEvent = true;
960 widget->setFocus();
961 }
962 d->pendingFocusInEvent = false;
963 break;
964 case QEvent::ChildRemoved:
965 if ( widget == ((QChildEvent*)event)->child() ) widget = 0L;
966 break;
967 case QEvent::Show:
968 if ( widget ) widget->show();
969 emit manager->change();
970 break;
971 case QEvent::Hide:
972 if ( widget ) widget->hide();
973 emit manager->change();
974 break;
975 case QEvent::WindowTitleChange:
976 if ( parentWidget() ){
977 if ( parent()->inherits("K3DockSplitter") ){
978 ((K3DockSplitter*)(parent()))->updateName();
979 }
980 if ( parentDockTabGroup() ){
981 setDockTabName( parentDockTabGroup() );
982 parentDockTabGroup()->setTabLabel( this, tabPageLabel() );
983 }
984 }
985 break;
986 case QEvent::Close:
987 emit iMBeingClosed();
988 break;
989 default:
990 break;
991 }
992 return QWidget::event( event );
993}
994
995K3DockWidget *K3DockWidget::findNearestDockWidget(DockPosition pos)
996{
997 if (!parent()) return 0;
998 if (!parent()->inherits("K3DockSplitter")) return 0;
999 Qt::Orientation orientation= ( ( pos == K3DockWidget::DockLeft) ||
1000 ( pos == K3DockWidget::DockRight ) ) ? Qt::Vertical : Qt::Horizontal;
1001 if (((K3DockSplitter*)(parent()))->orientation() == orientation)
1002 {
1003 K3DockWidget *neighbor=
1004 ( ( pos == K3DockWidget::DockLeft ) || ( pos == K3DockWidget::DockTop ) ) ?
1005 static_cast<K3DockWidget*>( ( ( K3DockSplitter* )( parent() ) )->getFirst() ) :
1006 static_cast<K3DockWidget*>( ( ( K3DockSplitter* )( parent() ) )->getLast() );
1007
1008 if (neighbor==this)
1009 return (static_cast<K3DockWidget*>(parent()->parent())->findNearestDockWidget(pos));
1010 else
1011 if (neighbor->getWidget() && qobject_cast<K3DockTabGroup*>(neighbor->getWidget()))
1012 return (K3DockWidget*)(((K3DockTabGroup*)neighbor->getWidget())->page(0));
1013 else
1014 return neighbor;
1015 }
1016 else
1017 return (static_cast<K3DockWidget*>(parent()->parent())->findNearestDockWidget(pos));
1018
1019 return 0;
1020}
1021
1022
1023K3DockWidget* K3DockWidget::manualDock( K3DockWidget* target, DockPosition dockPos, int spliPos, QPoint pos, bool check, int tabIndex )
1024{
1025 if (this == target)
1026 return 0L; // docking to itself not possible
1027
1028// kDebug(282)<<"manualDock called ";
1029 bool success = true; // tested flag
1030
1031 // Check to make sure that we can dock in to the position wee
1032 // were told to dock in to
1033 if ( !(eDocking & (int)dockPos) ){
1034 success = false;
1035// kDebug(282)<<"K3DockWidget::manualDock(): success = false (1)";
1036 }
1037
1038 // fix for apps which use a value > 100%. The splitter position must be between 0..100
1039 // The old behavior on high resolution was 0..10000. So likely the value is >100.
1040 if (spliPos > 100) {
1041 spliPos = spliPos / 100;
1042 kDebug(282) << "K3DockWidget::manualDock(): fix splitter position: " << spliPos;
1043 }
1044
1045 K3DockWidget *tmpTarget = 0;
1046 switch (dockPos) {
1047 case K3DockWidget::DockLeft:
1048 tmpTarget=dockManager()->d->leftContainer;
1049 break;
1050 case K3DockWidget::DockRight:
1051 tmpTarget=dockManager()->d->rightContainer;
1052 break;
1053 case K3DockWidget::DockBottom:
1054 tmpTarget=dockManager()->d->bottomContainer;
1055 break;
1056 case K3DockWidget::DockTop:
1057 tmpTarget=dockManager()->d->topContainer;
1058 break;
1059 default:
1060 tmpTarget = 0;
1061 }
1062
1063 //If we're not the target, and the target is our dock manager's main window
1064 //dock into the temp target as chosen above
1065 if ( tmpTarget && target && this != tmpTarget && target == dockManager()->d->mainDockWidget )
1066 return manualDock(tmpTarget,DockCenter,spliPos,pos,check,tabIndex);
1067
1068 // check if the target allows us to oock into the requested position
1069 if ( target && !(target->sDocking & (int)dockPos) ){
1070 success = false;
1071// kDebug(282)<<"K3DockWidget::manualDock(): success = false (2)";
1072 }
1073
1074 /* if we have a parent, and it's not a K3DockSplitter, and we don't have a parent
1075 * dock tab group, and our parent isn't a K3DockContainer, and we have no explicit
1076 * parent dock container...we can't do much yet */
1077 if ( parent() && !parent()->inherits("K3DockSplitter") && !parentDockTabGroup() &&
1078 !(dynamic_cast<K3DockContainer*>(parent())) && !parentDockContainer()){
1079// kDebug(282)<<"K3DockWidget::manualDock(): success = false (3)";
1080// kDebug(282)<<parent()->name();
1081 success = false;
1082 }
1083
1084 /* If all of our attempts to dock back so far have failed and we have a target
1085 * and we're not being called recursively (i guess that's what check is for)
1086 * then attempt to dock back to ourselves. */
1087 if ( !success ){
1088 // try to make another manualDock
1089 K3DockWidget* dock_result = 0L;
1090 if ( target && !check ){
1091 K3DockWidget::DockPosition another__dockPos = K3DockWidget::DockNone;
1092 switch ( dockPos ){
1093 case K3DockWidget::DockLeft : another__dockPos = K3DockWidget::DockRight ; break;
1094 case K3DockWidget::DockRight : another__dockPos = K3DockWidget::DockLeft ; break;
1095 case K3DockWidget::DockTop : another__dockPos = K3DockWidget::DockBottom; break;
1096 case K3DockWidget::DockBottom: another__dockPos = K3DockWidget::DockTop ; break;
1097 default: break;
1098 }
1099 dock_result = target->manualDock( this, another__dockPos, spliPos, pos, true, tabIndex );
1100 }
1101 return dock_result;
1102 }
1103 // end check block
1104
1105 d->blockHasUndockedSignal = true;
1106 undock();
1107 d->blockHasUndockedSignal = false;
1108
1109 //we have no docking target, so we're undocking
1110 if ( !target ){
1111 move( pos );
1112 show();
1113 emit manager->change();
1114 return this;
1115 }
1116
1117// kDebug(282)<<"Looking for K3DockTabGroup";
1118 K3DockTabGroup* parentTab = target->parentDockTabGroup();
1119 if ( parentTab ){
1120 // add to existing TabGroup
1121 applyToWidget( parentTab );
1122 parentTab->insertTab( this, icon() ? *icon() : QPixmap(),
1123 tabPageLabel(), tabIndex );
1124
1125 QWidget *wantTransient=parentTab->transientTo();
1126 target->setDockWindowTransient(wantTransient,wantTransient);
1127
1128 setDockTabName( parentTab );
1129 if( !toolTipStr.isEmpty())
1130 parentTab->setTabToolTip( this, toolTipStr);
1131
1132 currentDockPos = K3DockWidget::DockCenter;
1133 emit manager->change();
1134 return (K3DockWidget*)parentTab->parent();
1135 }
1136 else
1137 {
1138// kDebug(282)<<"Looking for K3DockContainer";
1139 QWidget *contWid=target->parentDockContainer();
1140 if (!contWid) contWid=target->widget;
1141 if (contWid)
1142 {
1143 K3DockContainer *cont=dynamic_cast<K3DockContainer*>(contWid);
1144 if (cont)
1145 {
1146 if (latestK3DockContainer() && (latestK3DockContainer()!=contWid)) {
1147 K3DockContainer* dc = dynamic_cast<K3DockContainer*>(latestK3DockContainer());
1148 if (dc) {
1149 dc->removeWidget(this);
1150 }
1151 }
1152// kDebug(282)<<"K3DockContainerFound";
1153 applyToWidget( contWid );
1154 cont->insertWidget( this, icon() ? *icon() : QPixmap(),
1155 tabPageLabel(), tabIndex );
1156 setLatestK3DockContainer(contWid);
1157// setDockTabName( parentTab );
1158 if( !toolTipStr.isEmpty())
1159 cont->setToolTip( this, toolTipStr);
1160
1161 currentDockPos = K3DockWidget::DockCenter;
1162 emit manager->change();
1163 return (K3DockWidget*)(cont->parentDockWidget());
1164
1165 }
1166 }
1167 }
1168
1169 // create a new dockwidget that will contain the target and this
1170 QWidget* parentDock = target->parentWidget();
1171 K3DockWidget* newDock = new K3DockWidget( manager, "tempName", QPixmap(""), parentDock );
1172 newDock->currentDockPos = target->currentDockPos;
1173
1174 if ( dockPos == K3DockWidget::DockCenter ){
1175 newDock->isTabGroup = true;
1176 } else {
1177 newDock->isGroup = true;
1178 }
1179 newDock->eDocking = (target->eDocking & eDocking) & (~(int)K3DockWidget::DockCenter);
1180
1181 newDock->applyToWidget( parentDock );
1182
1183 if ( !parentDock ){
1184 // dock to a toplevel dockwidget means newDock is toplevel now
1185 newDock->move( target->frameGeometry().topLeft() );
1186 newDock->resize( target->geometry().size() );
1187 if ( target->isVisibleToTLW() ) newDock->show();
1188 }
1189
1190 // redirect the dockback button to the new dockwidget
1191 if( target->formerBrotherDockWidget ) {
1192 newDock->setFormerBrotherDockWidget(target->formerBrotherDockWidget);
1193 if( formerBrotherDockWidget )
1194 target->loseFormerBrotherDockWidget();
1195 }
1196 newDock->formerDockPos = target->formerDockPos;
1197
1198
1199 // HERE SOMETING CREATING CONTAINERS SHOULD BE ADDED !!!!!
1200 if ( dockPos == K3DockWidget::DockCenter )
1201 {
1202 K3DockTabGroup* tab = new K3DockTabGroup( newDock );
1203 tab->setObjectName( QLatin1String( "_dock_tab" ) );
1204 QObject::connect(tab, SIGNAL(currentChanged(QWidget*)), d, SLOT(slotFocusEmbeddedWidget(QWidget*)));
1205 newDock->setWidget( tab );
1206
1207 target->applyToWidget( tab );
1208 applyToWidget( tab );
1209
1210
1211 tab->insertTab( target, target->icon() ? *(target->icon()) : QPixmap(),
1212 target->tabPageLabel() );
1213
1214
1215
1216 if( !target->toolTipString().isEmpty())
1217 tab->setTabToolTip( target, target->toolTipString());
1218
1219 tab->insertTab( this, icon() ? *icon() : QPixmap(),
1220 tabPageLabel(), tabIndex );
1221
1222 QRect geom=newDock->geometry();
1223 QWidget *wantTransient=tab->transientTo();
1224 newDock->setDockWindowTransient(wantTransient,wantTransient);
1225 newDock->setGeometry(geom);
1226
1227 if( !toolTipString().isEmpty())
1228 tab->setTabToolTip( this, toolTipString());
1229
1230 setDockTabName( tab );
1231 tab->show();
1232
1233 currentDockPos = DockCenter;
1234 target->formerDockPos = target->currentDockPos;
1235 target->currentDockPos = DockCenter;
1236 }
1237 else {
1238 // if to dock not to the center of the target dockwidget,
1239 // dock to newDock
1240 K3DockSplitter* panner = 0L;
1241 if ( dockPos == K3DockWidget::DockTop || dockPos == K3DockWidget::DockBottom ) panner = new K3DockSplitter( newDock, "_dock_split_", Qt::Horizontal, spliPos );
1242 if ( dockPos == K3DockWidget::DockLeft || dockPos == K3DockWidget::DockRight ) panner = new K3DockSplitter( newDock, "_dock_split_", Qt::Vertical , spliPos );
1243 newDock->setWidget( panner );
1244
1245 panner->setOpaqueResize(manager->splitterOpaqueResize());
1246 panner->setKeepSize(manager->splitterKeepSize());
1247 panner->setFocusPolicy( Qt::NoFocus );
1248 target->applyToWidget( panner );
1249 applyToWidget( panner );
1250 target->formerDockPos = target->currentDockPos;
1251 if ( dockPos == K3DockWidget::DockRight) {
1252 panner->activate( target, this );
1253 currentDockPos = K3DockWidget::DockRight;
1254 target->currentDockPos = K3DockWidget::DockLeft;
1255 }
1256 else if( dockPos == K3DockWidget::DockBottom) {
1257 panner->activate( target, this );
1258 currentDockPos = K3DockWidget::DockBottom;
1259 target->currentDockPos = K3DockWidget::DockTop;
1260 }
1261 else if( dockPos == K3DockWidget::DockTop) {
1262 panner->activate( this, target );
1263 currentDockPos = K3DockWidget::DockTop;
1264 target->currentDockPos = K3DockWidget::DockBottom;
1265 }
1266 else if( dockPos == K3DockWidget::DockLeft) {
1267 panner->activate( this, target );
1268 currentDockPos = K3DockWidget::DockLeft;
1269 target->currentDockPos = K3DockWidget::DockRight;
1270 }
1271 target->show();
1272 show();
1273 panner->show();
1274 }
1275
1276 if ( parentDock ){
1277 if ( parentDock->inherits("K3DockSplitter") ){
1278 K3DockSplitter* sp = (K3DockSplitter*)parentDock;
1279 sp->deactivate();
1280 if ( sp->getFirst() == target )
1281 sp->activate( newDock, 0L );
1282 else
1283 sp->activate( 0L, newDock );
1284 }
1285 }
1286
1287 newDock->show();
1288 emit target->docking( this, dockPos );
1289 emit manager->replaceDock( target, newDock );
1290 emit manager->change();
1291
1292 return newDock;
1293}
1294
1295K3DockTabGroup* K3DockWidget::parentDockTabGroup() const
1296{
1297 if ( !parent() ) return 0L;
1298 QWidget* candidate = parentWidget()->parentWidget();
1299 if ( candidate && candidate->inherits("K3DockTabGroup") ) return (K3DockTabGroup*)candidate;
1300 return 0L;
1301}
1302
1303QWidget *K3DockWidget::parentDockContainer() const
1304{
1305 if (!parent()) return 0L;
1306 QWidget* candidate = parentWidget()->parentWidget();
1307 if (candidate && dynamic_cast<K3DockContainer*>(candidate)) return candidate;
1308 return 0L;
1309}
1310
1311
1312void K3DockWidget::setForcedFixedWidth(int w)
1313{
1314 d->forcedWidth=w;
1315 setFixedWidth(w);
1316 if (!parent()) return;
1317 if (parent()->inherits("K3DockSplitter"))
1318 qobject_cast<K3DockSplitter*>(parent())->setForcedFixedWidth(this,w);
1319}
1320
1321void K3DockWidget::setForcedFixedHeight(int h)
1322{
1323 d->forcedHeight=h;
1324 setFixedHeight(h);
1325 if (!parent()) return;
1326 if (parent()->inherits("K3DockSplitter"))
1327 qobject_cast<K3DockSplitter*>(parent())->setForcedFixedHeight(this,h);
1328}
1329
1330int K3DockWidget::forcedFixedWidth()
1331{
1332 return d->forcedWidth;
1333}
1334
1335int K3DockWidget::forcedFixedHeight()
1336{
1337 return d->forcedHeight;
1338}
1339
1340void K3DockWidget::restoreFromForcedFixedSize()
1341{
1342 d->forcedWidth=-1;
1343 d->forcedHeight=-1;
1344 setMinimumWidth(0);
1345 setMaximumWidth(32000);
1346 setMinimumHeight(0);
1347 setMaximumHeight(32000);
1348 if (!parent()) return;
1349 if (parent()->inherits("K3DockSplitter"))
1350 qobject_cast<K3DockSplitter*>(parent())->restoreFromForcedFixedSize(this);
1351}
1352
1353void K3DockWidget::toDesktop()
1354{
1355 QPoint p = mapToGlobal( QPoint( -30, -30 ) );
1356 if( p.x( ) < 0 )
1357 p.setX( 0 );
1358 if( p.y( ) < 0 )
1359 p.setY( 0 );
1360 manualDock( 0, DockDesktop, 50, p );
1361}
1362
1363K3DockWidget::DockPosition K3DockWidget::currentDockPosition() const
1364{
1365 return currentDockPos;
1366}
1367
1368void K3DockWidget::undock()
1369{
1370 // kDebug(282) << "K3DockWidget::undock : undocking " << name();
1371
1372 manager->d->dragRect = QRect ();
1373 manager->drawDragRectangle ();
1374
1375 QWidget* parentW = parentWidget();
1376 if ( !parentW ){
1377 hide();
1378 if (!d->blockHasUndockedSignal)
1379 emit hasUndocked();
1380 return;
1381 }
1382
1383 formerDockPos = currentDockPos;
1384 currentDockPos = K3DockWidget::DockDesktop;
1385
1386 manager->blockSignals(true);
1387 manager->undockProcess = true;
1388
1389 bool isV = parentW->isVisibleToTLW();
1390
1391 //UNDOCK HAS TO BE IMPLEMENTED CORRECTLY :)
1392 K3DockTabGroup* parentTab = parentDockTabGroup();
1393 if ( parentTab ){
1394 d->index = parentTab->indexOf( this); // memorize the page position in the tab widget
1395 parentTab->removePage( this );
1396/*
1397 QWidget *wantTransient=parentTab->transientTo();
1398 target->setDockWindowTransient(wantTransient,wantTransient);
1399 */
1400 setFormerBrotherDockWidget((K3DockWidget*)parentTab->page(0));
1401 applyToWidget( 0L );
1402 if ( parentTab->count() == 1 ){
1403
1404 // last subdock widget in the tab control
1405 K3DockWidget* lastTab = (K3DockWidget*)parentTab->page(0);
1406 parentTab->removePage( lastTab );
1407/* QWidget *wantTransient=parentTab->transientTo();
1408 target->setDockWindowTransient(wantTransient,wantTransient);*/
1409
1410 lastTab->applyToWidget( 0L );
1411 lastTab->move( parentTab->mapToGlobal(parentTab->frameGeometry().topLeft()) );
1412
1413 // K3DockTabGroup always have a parent that is a K3DockWidget
1414 K3DockWidget* parentOfTab = (K3DockWidget*)parentTab->parent();
1415 delete parentTab; // K3DockTabGroup
1416
1417 QWidget* parentOfDockWidget = parentOfTab->parentWidget();
1418 if ( !parentOfDockWidget ){
1419 if ( isV ) lastTab->show();
1420 } else {
1421 if ( parentOfDockWidget->inherits("K3DockSplitter") ){
1422 K3DockSplitter* split = (K3DockSplitter*)parentOfDockWidget;
1423 lastTab->applyToWidget( split );
1424 split->deactivate();
1425 if ( split->getFirst() == parentOfTab ){
1426 split->activate( lastTab );
1427 if ( ((K3DockWidget*)split->parent())->splitterOrientation == Qt::Vertical )
1428 emit ((K3DockWidget*)split->getAnother(parentOfTab))->docking( parentOfTab, K3DockWidget::DockLeft );
1429 else
1430 emit ((K3DockWidget*)split->getAnother(parentOfTab))->docking( parentOfTab, K3DockWidget::DockTop );
1431 } else {
1432 split->activate( 0L, lastTab );
1433 if ( ((K3DockWidget*)split->parent())->splitterOrientation == Qt::Vertical )
1434 emit ((K3DockWidget*)split->getAnother(parentOfTab))->docking( parentOfTab, K3DockWidget::DockRight );
1435 else
1436 emit ((K3DockWidget*)split->getAnother(parentOfTab))->docking( parentOfTab, K3DockWidget::DockBottom );
1437 }
1438 split->show();
1439 } else {
1440 lastTab->applyToWidget( parentOfDockWidget );
1441 }
1442 lastTab->show();
1443 }
1444 manager->blockSignals(false);
1445 emit manager->replaceDock( parentOfTab, lastTab );
1446 lastTab->currentDockPos = parentOfTab->currentDockPos;
1447 emit parentOfTab->iMBeingClosed();
1448 manager->blockSignals(true);
1449 delete parentOfTab;
1450
1451 } else {
1452 setDockTabName( parentTab );
1453 }
1454 } else {
1455 /*********************************************************************************************/
1456 //QWidget* containerWidget = (QWidget*)parent();
1457 bool undockedFromContainer=false;
1458 if (d->container)
1459 {
1460// kDebug(282)<<"undocked from dockcontainer";
1461 undockedFromContainer=true;
1462 K3DockContainer* dc = dynamic_cast<K3DockContainer*>(d->container.operator->());
1463 if (dc) {
1464 dc->undockWidget(this);
1465 setFormerBrotherDockWidget(dc->parentDockWidget());
1466 }
1467 applyToWidget( 0L );
1468 }
1469 if (!undockedFromContainer) {
1470/*********************************************************************************************/
1471 if ( parentW->inherits("K3DockSplitter") ){
1472 K3DockSplitter* parentSplitterOfDockWidget = (K3DockSplitter*)parentW;
1473 d->splitPosInPercent = parentSplitterOfDockWidget->separatorPosInPercent();
1474
1475 K3DockWidget* secondWidget = (K3DockWidget*)parentSplitterOfDockWidget->getAnother( this );
1476 K3DockWidget* group = (K3DockWidget*)parentSplitterOfDockWidget->parentWidget();
1477 setFormerBrotherDockWidget(secondWidget);
1478 applyToWidget( 0L );
1479 group->hide();
1480
1481 if ( !group->parentWidget() ){
1482 secondWidget->applyToWidget( 0L, group->frameGeometry().topLeft() );
1483 secondWidget->resize( group->width(), group->height() );
1484 } else {
1485 QWidget* obj = group->parentWidget();
1486 secondWidget->applyToWidget( obj );
1487 if ( obj->inherits("K3DockSplitter") ){
1488 K3DockSplitter* parentOfGroup = (K3DockSplitter*)obj;
1489 parentOfGroup->deactivate();
1490
1491 if ( parentOfGroup->getFirst() == group )
1492 parentOfGroup->activate( secondWidget );
1493 else
1494 parentOfGroup->activate( 0L, secondWidget );
1495 }
1496 }
1497 secondWidget->currentDockPos = group->currentDockPos;
1498 secondWidget->formerDockPos = group->formerDockPos;
1499 delete parentSplitterOfDockWidget;
1500 manager->blockSignals(false);
1501 emit manager->replaceDock( group, secondWidget );
1502 emit group->iMBeingClosed();
1503 manager->blockSignals(true);
1504 delete group;
1505
1506 if ( isV ) secondWidget->show();
1507 } else {
1508 if (!d->pendingDtor) {
1509 // don't reparent in the dtor of this
1510 applyToWidget( 0L );
1511 }
1512 }
1513/*********************************************************************************************/
1514 }
1515 }
1516 manager->blockSignals(false);
1517 if (!d->blockHasUndockedSignal)
1518 emit manager->change();
1519 manager->undockProcess = false;
1520
1521 if (!d->blockHasUndockedSignal)
1522 emit hasUndocked();
1523}
1524
1525void K3DockWidget::setWidget( QWidget* mw )
1526{
1527 if ( !mw ) return;
1528
1529 if ( mw->parent() != this ){
1530 mw->setParent(this);
1531 mw->move(0,0);
1532 }
1533
1534#ifdef BORDERLESS_WINDOWS
1535 if (!mw->ownCursor()) mw->setCursor(QCursor(Qt::ArrowCursor));
1536#endif
1537 widget = mw;
1538 delete layout;
1539
1540 /*
1541 * Qt 4.1 does not fill the background if not asked so explicitly.
1542 * However code from Qt3/KDE3 could except that the background is filled.
1543 */
1544 widget->setAutoFillBackground( true );
1545
1546 layout = new QVBoxLayout( this );
1547 layout->setSizeConstraint( QLayout::Minimum );
1548
1549 K3DockContainer* dc = dynamic_cast<K3DockContainer*>(widget);
1550 if (dc)
1551 {
1552 d->isContainer=true;
1553 manager->d->containerDocks.append(this);
1554 }
1555 else
1556 {
1557 d->isContainer=false;
1558 }
1559
1560 {
1561 header->show();
1562 layout->addWidget( header );
1563 layout->addWidget( widget,1 );
1564 }
1565 updateHeader();
1566 emit widgetSet(mw);
1567}
1568
1569QWidget* K3DockWidget::getWidget() const
1570{
1571 return widget;
1572}
1573
1574void K3DockWidget::setDockTabName( K3DockTabGroup* tab )
1575{
1576 QString listOfName;
1577 QString listOfCaption;
1578 for ( int i = 0; i < tab->count(); ++i ) {
1579 QWidget *w = tab->page( i );
1580 listOfCaption.append( w->windowTitle() ).append(",");
1581 listOfName.append( w->name() ).append(",");
1582 }
1583 listOfCaption.remove( listOfCaption.length()-1, 1 );
1584 listOfName.remove( listOfName.length()-1, 1 );
1585
1586 tab->parentWidget()->setName( listOfName.toUtf8() );
1587 tab->parentWidget()->setWindowTitle( listOfCaption );
1588
1589 tab->parentWidget()->repaint(); // K3DockWidget->repaint
1590 if ( tab->parentWidget()->parent() )
1591 if ( tab->parentWidget()->parent()->inherits("K3DockSplitter") )
1592 ((K3DockSplitter*)(tab->parentWidget()->parent()))->updateName();
1593}
1594
1595bool K3DockWidget::mayBeHide() const
1596{
1597 bool f = (parent() != manager->main);
1598 return ( !isGroup && !isTabGroup && f && isVisible() && ( eDocking != (int)K3DockWidget::DockNone ) );
1599}
1600
1601bool K3DockWidget::mayBeShow() const
1602{
1603 bool f = (parent() != manager->main);
1604 return ( !isGroup && !isTabGroup && f && !isVisible() );
1605}
1606
1607K3DockManager* K3DockWidget::dockManager() const
1608{
1609 return manager;
1610}
1611
1612void K3DockWidget::setToolTipString(const QString& ttStr)
1613{
1614 toolTipStr = ttStr;
1615}
1616
1617const QString& K3DockWidget::toolTipString() const
1618{
1619 return toolTipStr;
1620}
1621
1622void K3DockWidget::changeHideShowState()
1623{
1624 if ( mayBeHide() ){
1625 undock();
1626 return;
1627 }
1628
1629 if ( mayBeShow() ){
1630 if ( manager->main->inherits("K3DockMainWindow") ){
1631 ((K3DockMainWindow*)manager->main)->makeDockVisible(this);
1632 } else {
1633 makeDockVisible();
1634 }
1635 }
1636}
1637
1638void K3DockWidget::makeDockVisible()
1639{
1640 if ( parentDockTabGroup() ){
1641 parentDockTabGroup()->showPage( this );
1642 }
1643 if (parentDockContainer()) {
1644 QWidget *contWid=parentDockContainer();
1645 K3DockContainer *x = dynamic_cast<K3DockContainer*>(contWid);
1646 if (x) {
1647 x->showWidget(this);
1648 }
1649 }
1650 if ( isVisible() ) return;
1651
1652 QWidget* p = parentWidget();
1653 while ( p ){
1654 if ( !p->isVisible() )
1655 p->show();
1656 p = p->parentWidget();
1657 }
1658 if( !parent() ) // is undocked
1659 dockBack();
1660 show();
1661}
1662
1663void K3DockWidget::setFormerBrotherDockWidget(K3DockWidget *dockWidget)
1664{
1665 formerBrotherDockWidget = dockWidget;
1666 if( formerBrotherDockWidget )
1667 QObject::connect( formerBrotherDockWidget, SIGNAL(iMBeingClosed()),
1668 this, SLOT(loseFormerBrotherDockWidget()) );
1669}
1670
1671void K3DockWidget::loseFormerBrotherDockWidget()
1672{
1673 if( formerBrotherDockWidget )
1674 QObject::disconnect( formerBrotherDockWidget, SIGNAL(iMBeingClosed()),
1675 this, SLOT(loseFormerBrotherDockWidget()) );
1676 formerBrotherDockWidget = 0L;
1677 repaint();
1678}
1679
1680void K3DockWidget::dockBack()
1681{
1682 if( formerBrotherDockWidget) {
1683 // search all children if it tries to dock back to a child
1684 bool found = false;
1685 QList<K3DockWidget *> cl = findChildren<K3DockWidget *>();
1686 foreach ( K3DockWidget *obj, cl ) {
1687 while ( !found && obj!= 0 ) {
1688 QWidget* widg = qobject_cast<QWidget*>(obj);
1689 if( widg == formerBrotherDockWidget)
1690 found = true;
1691 }
1692 }
1693
1694 if( !found) {
1695 // can dock back to the former brother dockwidget
1696 manualDock( formerBrotherDockWidget, formerDockPos, d->splitPosInPercent, QPoint(0,0), false, d->index);
1697 formerBrotherDockWidget = 0L;
1698 makeDockVisible();
1699 return;
1700 }
1701 }
1702
1703 // else dockback to the dockmainwindow (default behavior)
1704 manualDock( ((K3DockMainWindow*)manager->main)->getMainDockWidget(), formerDockPos, d->splitPosInPercent, QPoint(0,0), false, d->index);
1705 formerBrotherDockWidget = 0L;
1706 if (parent())
1707 makeDockVisible();
1708}
1709
1710bool K3DockWidget::isDockBackPossible() const
1711{
1712 if( !(formerBrotherDockWidget) || !(formerBrotherDockWidget->dockSite() & formerDockPos))
1713 return false;
1714 else
1715 return true;
1716}
1717
1718void K3DockWidget::setTabPageLabel( const QString& label)
1719{
1720 tabPageTitle = label;
1721}
1722
1723const QString& K3DockWidget::tabPageLabel() const
1724{
1725 return tabPageTitle;
1726}
1727
1728/**************************************************************************************/
1729
1730
1731K3DockManager::K3DockManager( QWidget* mainWindow , const char* name )
1732:QObject( mainWindow, name )
1733 ,main(mainWindow)
1734 ,currentDragWidget(0L)
1735 ,currentMoveWidget(0L)
1736 ,childDockWidgetList(0L)
1737 ,autoCreateDock(0L)
1738 ,storeW(0)
1739 ,storeH(0)
1740 ,dragging(false)
1741 ,undockProcess(false)
1742 ,dropCancel(true)
1743{
1744 d = new K3DockManagerPrivate;
1745
1746 d->readyToDrag = false;
1747 d->mainDockWidget=0;
1748
1749#ifndef NO_KDE2
1750 d->splitterOpaqueResize = KGlobalSettings::opaqueResize();
1751#else
1752 d->splitterOpaqueResize = false;
1753#endif
1754
1755 d->splitterKeepSize = false;
1756 d->splitterHighResolution = false;
1757 d->m_readDockConfigMode = WrapExistingWidgetsOnly; // default as before
1758
1759 main->installEventFilter( this );
1760
1761 undockProcess = false;
1762
1763 menuData = new Q3PtrList<MenuDockData>;
1764 menuData->setAutoDelete( true );
1765 menuData->setAutoDelete( true );
1766
1767#ifndef NO_KDE2
1768 menu = new K3PopupMenu();
1769#else
1770 menu = new Q3PopupMenu();
1771#endif
1772
1773 connect( menu, SIGNAL(aboutToShow()), SLOT(slotMenuPopup()) );
1774 connect( menu, SIGNAL(activated(int)), SLOT(slotMenuActivated(int)) );
1775
1776 childDock = new QList<QObject*>();
1777}
1778
1779
1780void K3DockManager::setMainDockWidget2(K3DockWidget *w)
1781{
1782 d->mainDockWidget=w;
1783}
1784
1785K3DockManager::~K3DockManager()
1786{
1787 delete menuData;
1788 delete menu;
1789
1790 // ### FIXME: this seems to crash but why? (KDE4)
1791 K3DockWidget * obj;
1792 Q_FOREACH ( QObject *o, *childDock ) {
1793 obj = (K3DockWidget*) ( o );
1794 delete obj;
1795 }
1796
1797 delete childDock;
1798 delete d;
1799 d=0;
1800}
1801
1802void K3DockManager::activate()
1803{
1804 K3DockWidget * obj;
1805 foreach ( QObject *o, *childDock ) {
1806 obj=(K3DockWidget*)o;
1807 if ( obj->widget ) obj->widget->show();
1808 if ( !obj->parentDockTabGroup() ){
1809 obj->show();
1810 }
1811 }
1812 if ( !main->inherits("QDialog") ) main->show();
1813}
1814
1815bool K3DockManager::eventFilter( QObject *obj, QEvent *event )
1816{
1817
1818 if ( obj->inherits("K3DockWidgetAbstractHeaderDrag") ){
1819 K3DockWidget* pDockWdgAtCursor = 0L;
1820 K3DockWidget* curdw = ((K3DockWidgetAbstractHeaderDrag*)obj)->dockWidget();
1821 switch ( event->type() ){
1822 case QEvent::MouseButtonDblClick:
1823 if (curdw->currentDockPos == K3DockWidget::DockDesktop) curdw->dockBack();
1824 else
1825 {
1826 curdw->toDesktop();
1827 // curdw->manualDock (0, K3DockWidget::DockDesktop);
1828 }
1829 break;
1830
1831 case QEvent::MouseButtonPress:
1832 if ( ((QMouseEvent*)event)->button() == Qt::LeftButton ){
1833 if ( curdw->eDocking != (int)K3DockWidget::DockNone ){
1834 dropCancel = true;
1835 curdw->setFocus();
1836 qApp->processOneEvent();
1837
1838 currentDragWidget = curdw;
1839 currentMoveWidget = 0L;
1840 childDockWidgetList = new QWidgetList();
1841 childDockWidgetList->append( curdw );
1842 findChildDockWidget( curdw, childDockWidgetList );
1843
1844 //d->oldDragRect = QRect(); should fix rectangle not erased problem
1845 d->dragRect = QRect(curdw->geometry());
1846 QPoint p = curdw->mapToGlobal(QPoint(0,0));
1847 d->dragRect.moveTopLeft(p);
1848 drawDragRectangle();
1849 d->readyToDrag = true;
1850
1851 d->dragOffset = QCursor::pos()-currentDragWidget->mapToGlobal(QPoint(0,0));
1852 }
1853
1854 }
1855 break;
1856 case QEvent::MouseButtonRelease:
1857 if ( ((QMouseEvent*)event)->button() == Qt::LeftButton ){
1858 if ( dragging ){
1859 if ( !dropCancel )
1860 drop();
1861 else
1862 cancelDrop();
1863 }
1864 if (d->readyToDrag) {
1865 d->readyToDrag = false;
1866 //d->oldDragRect = QRect(); should fix rectangle not erased problem
1867 d->dragRect = QRect(curdw->geometry());
1868 QPoint p = curdw->mapToGlobal(QPoint(0,0));
1869 d->dragRect.moveTopLeft(p);
1870 drawDragRectangle();
1871 currentDragWidget = 0L;
1872 delete childDockWidgetList;
1873 childDockWidgetList = 0L;
1874 }
1875 dragging = false;
1876 dropCancel = true;
1877 }
1878 break;
1879 case QEvent::MouseMove:
1880 if ( dragging ) {
1881
1882#ifdef BORDERLESS_WINDOWS
1883//BEGIN TEST
1884 K3DockWidget *oldMoveWidget;
1885 if (!curdw->parent())
1886 {
1887 curdw->move(QCursor::pos()-d->dragOffset);
1888 pDockWdgAtCursor = findDockWidgetAt( QCursor::pos()-QPoint(0,d->dragOffset.y()+3) );
1889 oldMoveWidget = currentMoveWidget;
1890 }
1891 else
1892 {
1893 pDockWdgAtCursor = findDockWidgetAt( QCursor::pos() );
1894 oldMoveWidget = currentMoveWidget;
1895 }
1896//END TEST
1897#else
1898 pDockWdgAtCursor = findDockWidgetAt( QCursor::pos() );
1899 K3DockWidget* oldMoveWidget = currentMoveWidget;
1900#endif
1901
1902 if ( currentMoveWidget && pDockWdgAtCursor == currentMoveWidget ) { //move
1903 dragMove( currentMoveWidget, currentMoveWidget->mapFromGlobal( QCursor::pos() ) );
1904 break;
1905 } else {
1906 if (dropCancel && curdw) {
1907 d->dragRect = QRect(curdw->geometry());
1908 QPoint p = curdw->mapToGlobal(QPoint(0,0));
1909 d->dragRect.moveTopLeft(p);
1910 }else
1911 d->dragRect = QRect();
1912
1913 drawDragRectangle();
1914 }
1915
1916 if ( !pDockWdgAtCursor && !(curdw->eDocking & (int)K3DockWidget::DockDesktop) ){
1917 // just moving at the desktop
1918 currentMoveWidget = pDockWdgAtCursor;
1919 curPos = K3DockWidget::DockDesktop;
1920 } else {
1921 if ( oldMoveWidget && pDockWdgAtCursor != currentMoveWidget ) { //leave
1922 currentMoveWidget = pDockWdgAtCursor;
1923 curPos = K3DockWidget::DockDesktop;
1924 }
1925 }
1926
1927 if ( oldMoveWidget != pDockWdgAtCursor && pDockWdgAtCursor ) { //enter pDockWdgAtCursor
1928 currentMoveWidget = pDockWdgAtCursor;
1929 curPos = K3DockWidget::DockDesktop;
1930 }
1931 } else {
1932 if (d->readyToDrag) {
1933 d->readyToDrag = false;
1934 }
1935 if ( (((QMouseEvent*)event)->state() == Qt::LeftButton) &&
1936 (curdw->eDocking != (int)K3DockWidget::DockNone) ) {
1937 startDrag( curdw);
1938 }
1939 }
1940 break;
1941 default:
1942 break;
1943 }
1944 }
1945 return QObject::eventFilter( obj, event );
1946}
1947
1948K3DockWidget* K3DockManager::findDockWidgetAt( const QPoint& pos )
1949{
1950 dropCancel = true;
1951
1952 if (!currentDragWidget)
1953 return 0L; // pointer access safety
1954
1955 if (currentDragWidget->eDocking == (int)K3DockWidget::DockNone ) return 0L;
1956
1957 QWidget* p = QApplication::topLevelAt( pos );
1958 if ( !p ) {
1959 dropCancel = false;
1960 return 0L;
1961 }
1962#if defined(_OS_WIN32_) || defined(Q_OS_WIN32)
1963 p = p->topLevelWidget();
1964#endif
1965 QWidget* w = 0L;
1966 findChildDockWidget( w, p, p->mapFromGlobal(pos) );
1967 if ( !w ){
1968 if ( !p->inherits("K3DockWidget") ) {
1969 return 0L;
1970 }
1971 w = p;
1972 }
1973 if ( findChild<K3DockSplitter*>("_dock_split_")) return 0L;
1974 if ( findChild<K3DockTabGroup*>( "_dock_tab" )) return 0L;
1975 if (dynamic_cast<K3DockContainer*>(w)) return 0L;
1976
1977 if (!childDockWidgetList) return 0L;
1978 if ( childDockWidgetList->indexOf(w) != -1 ) return 0L;
1979 if ( currentDragWidget->isGroup && ((K3DockWidget*)w)->parentDockTabGroup() ) return 0L;
1980
1981 K3DockWidget* www = (K3DockWidget*)w;
1982 if ( www->sDocking == (int)K3DockWidget::DockNone ) return 0L;
1983 if( !www->widget )
1984 return 0L;
1985
1986 K3DockWidget::DockPosition curPos = K3DockWidget::DockDesktop;
1987 QPoint cpos = www->mapFromGlobal( pos );
1988
1989 int ww = www->widget->width() / 3;
1990 int hh = www->widget->height() / 3;
1991
1992 if ( cpos.y() <= hh ){
1993 curPos = K3DockWidget::DockTop;
1994 } else
1995 if ( cpos.y() >= 2*hh ){
1996 curPos = K3DockWidget::DockBottom;
1997 } else
1998 if ( cpos.x() <= ww ){
1999 curPos = K3DockWidget::DockLeft;
2000 } else
2001 if ( cpos.x() >= 2*ww ){
2002 curPos = K3DockWidget::DockRight;
2003 } else
2004 curPos = K3DockWidget::DockCenter;
2005
2006 if ( !(www->sDocking & (int)curPos) ) return 0L;
2007 if ( !(currentDragWidget->eDocking & (int)curPos) ) return 0L;
2008 if ( www->manager != this ) return 0L;
2009
2010 dropCancel = false;
2011 return www;
2012}
2013
2014void K3DockManager::findChildDockWidget( QWidget*& ww, const QWidget* p, const QPoint& pos )
2015{
2016 if ( !p->children().isEmpty() ) {
2017 QWidget *w;
2018 foreach( QObject* o, p->children() )
2019 {
2020 if ( o->isWidgetType() ) {
2021 w = (QWidget*)o;
2022 if ( w->isVisible() && w->geometry().contains(pos) ) {
2023 if ( w->inherits("K3DockWidget") ) ww = w;
2024 findChildDockWidget( ww, w, w->mapFromParent(pos) );
2025 return;
2026 }
2027 }
2028 }
2029 }
2030 return;
2031}
2032
2033void K3DockManager::findChildDockWidget( const QWidget* p, QWidgetList*& list )
2034{
2035 if ( !p->children().isEmpty() ) {
2036 QWidget *w;
2037 foreach( QObject* o, p->children() )
2038 {
2039 if ( o->isWidgetType() ) {
2040 w = (QWidget*)o;
2041 if ( w->isVisible() ) {
2042 if ( w->inherits("K3DockWidget") ) list->append( w );
2043 findChildDockWidget( w, list );
2044 }
2045 }
2046 }
2047 }
2048 return;
2049}
2050
2051void K3DockManager::startDrag( K3DockWidget* w )
2052{
2053 if(( w->currentDockPos == K3DockWidget::DockLeft) || ( w->currentDockPos == K3DockWidget::DockRight)
2054 || ( w->currentDockPos == K3DockWidget::DockTop) || ( w->currentDockPos == K3DockWidget::DockBottom)) {
2055 w->prevSideDockPosBeforeDrag = w->currentDockPos;
2056
2057 if ( w->parentWidget()->inherits("K3DockSplitter") ){
2058 K3DockSplitter* parentSplitterOfDockWidget = (K3DockSplitter*)(w->parentWidget());
2059 w->d->splitPosInPercent = parentSplitterOfDockWidget->separatorPosInPercent();
2060 }
2061 }
2062
2063 curPos = K3DockWidget::DockDesktop;
2064 dragging = true;
2065
2066 QApplication::setOverrideCursor(QCursor(Qt::SizeAllCursor));
2067}
2068
2069void K3DockManager::dragMove( K3DockWidget* dw, QPoint pos )
2070{
2071 QPoint p = dw->mapToGlobal( dw->widget->pos() );
2072 K3DockWidget::DockPosition oldPos = curPos;
2073
2074 QSize r = dw->widget->size();
2075 if ( dw->parentDockTabGroup() ){
2076 curPos = K3DockWidget::DockCenter;
2077 if ( oldPos != curPos ) {
2078 d->dragRect.setRect( p.x()+2, p.y()+2, r.width()-4, r.height()-4 );
2079 }
2080 return;
2081 }
2082
2083 int w = r.width() / 3;
2084 int h = r.height() / 3;
2085
2086 if ( pos.y() <= h ){
2087 curPos = K3DockWidget::DockTop;
2088 w = r.width();
2089 } else
2090 if ( pos.y() >= 2*h ){
2091 curPos = K3DockWidget::DockBottom;
2092 p.setY( p.y() + 2*h );
2093 w = r.width();
2094 } else
2095 if ( pos.x() <= w ){
2096 curPos = K3DockWidget::DockLeft;
2097 h = r.height();
2098 } else
2099 if ( pos.x() >= 2*w ){
2100 curPos = K3DockWidget::DockRight;
2101 p.setX( p.x() + 2*w );
2102 h = r.height();
2103 } else
2104 {
2105 curPos = K3DockWidget::DockCenter;
2106 p.setX( p.x() + w );
2107 p.setY( p.y() + h );
2108 }
2109
2110 if ( oldPos != curPos ) {
2111 d->dragRect.setRect( p.x(), p.y(), w, h );
2112 drawDragRectangle();
2113 }
2114}
2115
2116
2117void K3DockManager::cancelDrop()
2118{
2119 QApplication::restoreOverrideCursor();
2120
2121 delete childDockWidgetList;
2122 childDockWidgetList = 0L;
2123
2124 d->dragRect = QRect(); // cancel drawing
2125 drawDragRectangle(); // only the old rect will be deleted
2126}
2127
2128
2129void K3DockManager::drop()
2130{
2131 d->dragRect = QRect(); // cancel drawing
2132 drawDragRectangle(); // only the old rect will be deleted
2133
2134 QApplication::restoreOverrideCursor();
2135
2136 delete childDockWidgetList;
2137 childDockWidgetList = 0L;
2138
2139 if ( dropCancel ) return;
2140 if ( !currentMoveWidget && (!(currentDragWidget->eDocking & (int)K3DockWidget::DockDesktop)) ) {
2141 d->dragRect = QRect(); // cancel drawing
2142 drawDragRectangle(); // only the old rect will be deleted
2143 return;
2144 }
2145 if ( !currentMoveWidget && !currentDragWidget->parent() ) {
2146 currentDragWidget->move( QCursor::pos() - d->dragOffset );
2147 }
2148 else {
2149 // curPos is the current target DockPosition.
2150 // currentDragWidget->prevSideDockPosBeforeDrag is where the dockwidget comes from.
2151 // currentDragWidget->formerDockPos is the position *before* the dockwidget was in
2152 // position currentDragWidget->prevSideDockPosBeforeDrag.
2153 int splitPos = currentDragWidget->d->splitPosInPercent;
2154 K3DockWidget::DockPosition previousPosition = currentDragWidget->prevSideDockPosBeforeDrag;
2155
2156// kDebug() << splitPos;
2157// kDebug() << "curPos: " << curPos;
2158// kDebug() << "formerDockPos: " << currentDragWidget->formerDockPos;
2159// kDebug() << "prevSideDockPosBeforeDrag: " << currentDragWidget->prevSideDockPosBeforeDrag;
2160
2161 // Now we *need* to "invert" the procentual value, if the dockwidget moves from top/left
2162 // to bottom/right or vice versa. This keeps the dockwidget's size on its new position.
2163 // A special case is, when the dock position was DockNone, then we have to look for the
2164 // formerDockPos to get things right.
2165 if( (curPos != previousPosition)
2166 && (curPos != K3DockWidget::DockCenter) && (curPos != K3DockWidget::DockDesktop)) {
2167
2168 if (previousPosition == K3DockWidget::DockNone)
2169 previousPosition = currentDragWidget->formerDockPos;
2170
2171 switch( previousPosition ) {
2172 case K3DockWidget::DockLeft:
2173 if(curPos != K3DockWidget::DockTop && curPos != K3DockWidget::DockLeft)
2174 splitPos = 100 - splitPos;
2175 break;
2176
2177 case K3DockWidget::DockRight:
2178 if(curPos != K3DockWidget::DockBottom && curPos != K3DockWidget::DockRight)
2179 splitPos = 100 - splitPos;
2180 break;
2181
2182 case K3DockWidget::DockTop:
2183 if(curPos != K3DockWidget::DockLeft && curPos != K3DockWidget::DockTop )
2184 splitPos = 100 - splitPos;
2185 break;
2186
2187 case K3DockWidget::DockBottom:
2188 if(curPos != K3DockWidget::DockRight && curPos != K3DockWidget::DockBottom )
2189 splitPos = 100 - splitPos;
2190 break;
2191
2192 default: break;
2193 }
2194 }
2195 // set new prevSideDockPosBeforeDrag
2196 currentDragWidget->prevSideDockPosBeforeDrag = curPos;
2197 currentDragWidget->manualDock( currentMoveWidget, curPos , splitPos, QCursor::pos() - d->dragOffset );
2198 currentDragWidget->makeDockVisible();
2199 }
2200}
2201
2202
2203static QDomElement createStringEntry(QDomDocument &doc, const QString &tagName, const QString &str)
2204{
2205 QDomElement el = doc.createElement(tagName);
2206
2207 el.appendChild(doc.createTextNode(str));
2208 return el;
2209}
2210
2211
2212static QDomElement createBoolEntry(QDomDocument &doc, const QString &tagName, bool b)
2213{
2214 return createStringEntry(doc, tagName, QLatin1String(b? "true" : "false"));
2215}
2216
2217
2218static QDomElement createNumberEntry(QDomDocument &doc, const QString &tagName, int n)
2219{
2220 return createStringEntry(doc, tagName, QString::number(n));
2221}
2222
2223
2224static QDomElement createRectEntry(QDomDocument &doc, const QString &tagName, const QRect &rect)
2225{
2226 QDomElement el = doc.createElement(tagName);
2227
2228 QDomElement xel = doc.createElement("x");
2229 xel.appendChild(doc.createTextNode(QString::number(rect.x())));
2230 el.appendChild(xel);
2231 QDomElement yel = doc.createElement("y");
2232 yel.appendChild(doc.createTextNode(QString::number(rect.y())));
2233 el.appendChild(yel);
2234 QDomElement wel = doc.createElement("width");
2235 wel.appendChild(doc.createTextNode(QString::number(rect.width())));
2236 el.appendChild(wel);
2237 QDomElement hel = doc.createElement("height");
2238 hel.appendChild(doc.createTextNode(QString::number(rect.height())));
2239 el.appendChild(hel);
2240
2241 return el;
2242}
2243
2244
2245static QDomElement createListEntry(QDomDocument &doc, const QString &tagName,
2246 const QString &subTagName, const QStringList &list)
2247{
2248 QDomElement el = doc.createElement(tagName);
2249
2250 foreach( const QString &s, list )
2251 {
2252 QDomElement subel = doc.createElement(subTagName);
2253 subel.appendChild(doc.createTextNode(s));
2254 el.appendChild(subel);
2255 }
2256
2257 return el;
2258}
2259
2260
2261static QString stringEntry(QDomElement &base, const QString &tagName)
2262{
2263 return base.namedItem(tagName).firstChild().toText().data();
2264}
2265
2266
2267static bool boolEntry(QDomElement &base, const QString &tagName)
2268{
2269 return base.namedItem(tagName).firstChild().toText().data() == "true";
2270}
2271
2272
2273static int numberEntry(QDomElement &base, const QString &tagName)
2274{
2275 return stringEntry(base, tagName).toInt();
2276}
2277
2278
2279static QRect rectEntry(QDomElement &base, const QString &tagName)
2280{
2281 QDomElement el = base.namedItem(tagName).toElement();
2282
2283 int x = numberEntry(el, "x");
2284 int y = numberEntry(el, "y");
2285 int width = numberEntry(el, "width");
2286 int height = numberEntry(el, "height");
2287
2288 return QRect(x, y, width, height);
2289}
2290
2291
2292static Q3StrList listEntry(QDomElement &base, const QString &tagName, const QString &subTagName)
2293{
2294 Q3StrList list;
2295
2296 for( QDomNode n = base.namedItem(tagName).firstChild(); !n.isNull(); n = n.nextSibling() )
2297 {
2298 QDomElement subel = n.toElement();
2299 if (subel.tagName() == subTagName)
2300 list.append(subel.firstChild().toText().data().toLatin1().constData());
2301 }
2302
2303 return list;
2304}
2305
2306
2307void K3DockManager::writeConfig(QDomElement &base)
2308{
2309 // First of all, clear the tree under base
2310 while (!base.firstChild().isNull())
2311 base.removeChild(base.firstChild());
2312 QDomDocument doc = base.ownerDocument();
2313
2314 QStringList nameList;
2315 QString mainWidgetStr;
2316
2317 // collect widget names
2318 QStringList nList;
2319 Q_FOREACH( QObject *o, *childDock )
2320 {
2321#ifdef __GNUC__ // ### KDE4
2322# warning "Can dw be 0 and what should we do in the case that it is?"
2323#endif
2324 K3DockWidget* dw = qobject_cast<K3DockWidget*> ( o );
2325 if ( !dw )
2326 continue;
2327 if ( dw->parent() == main )
2328 mainWidgetStr = dw->objectName();
2329 nList.append( dw->objectName() );
2330 }
2331
2332 for (QObjectList::iterator it = d->containerDocks.begin();it != d->containerDocks.end();++it)
2333 {
2334 K3DockContainer* dc = dynamic_cast<K3DockContainer*>(((K3DockWidget*)(*it))->widget);
2335 if (dc) {
2336 dc->prepareSave(nList);
2337 }
2338 }
2339
2340 QStringList::Iterator nListIt=nList.begin();
2341 while ( nListIt!=nList.end() ) {
2342 K3DockWidget *obj = getDockWidgetFromName( *nListIt);
2343 if ((obj->isGroup && (!obj->d->isContainer)) && (nameList.indexOf( obj->firstName) == -1
2344 || nameList.indexOf(obj->lastName) == -1)) {
2345 // Skip until children are saved (why?)
2346 ++nListIt;
2347// nList.next();
2348//falk? if ( !nList.current() ) nList.first();
2349 continue;
2350 }
2351
2352 QDomElement groupEl;
2353 if (obj->d->isContainer) {
2354 K3DockContainer* x = dynamic_cast<K3DockContainer*>(obj->widget);
2355 if (x) {
2356 groupEl=doc.createElement("dockContainer");
2357 x->save(groupEl);
2358 }
2359 } else
2360 if (obj->isGroup) {
2361 //// Save a group
2362 groupEl = doc.createElement("splitGroup");
2363
2364 groupEl.appendChild(createStringEntry(doc, "firstName", obj->firstName));
2365 groupEl.appendChild(createStringEntry(doc, "secondName", obj->lastName));
2366 groupEl.appendChild(createNumberEntry(doc, "orientation", (int)obj->splitterOrientation));
2367 groupEl.appendChild(createNumberEntry(doc, "separatorPos", ((K3DockSplitter*)obj->widget)->separatorPosInPercent()));
2368 } else if (obj->isTabGroup) {
2369 //// Save a tab group
2370 groupEl = doc.createElement("tabGroup");
2371
2372 QStringList list;
2373 for ( int i = 0; i < ((K3DockTabGroup*)obj->widget)->count(); ++i )
2374 list.append( ((K3DockTabGroup*)obj->widget)->page( i )->name() );
2375 groupEl.appendChild(createListEntry(doc, "tabs", "tab", list));
2376 groupEl.appendChild(createNumberEntry(doc, "currentTab", ((K3DockTabGroup*)obj->widget)->currentPageIndex()));
2377 if (!obj->parent()) {
2378 groupEl.appendChild(createStringEntry(doc, "dockBackTo", obj->formerBrotherDockWidget ? obj->formerBrotherDockWidget->name() : ""));
2379 groupEl.appendChild(createNumberEntry(doc, "dockBackToPos", obj->formerDockPos));
2380 }
2381 } else {
2382 //// Save an ordinary dock widget
2383 groupEl = doc.createElement("dock");
2384 groupEl.appendChild(createStringEntry(doc, "tabCaption", obj->tabPageLabel()));
2385 groupEl.appendChild(createStringEntry(doc, "tabToolTip", obj->toolTipString()));
2386 if (!obj->parent()) {
2387 groupEl.appendChild(createStringEntry(doc, "dockBackTo", obj->formerBrotherDockWidget ? obj->formerBrotherDockWidget->name() : ""));
2388 groupEl.appendChild(createNumberEntry(doc, "dockBackToPos", obj->formerDockPos));
2389 }
2390 }
2391
2392 groupEl.appendChild(createStringEntry(doc, "name", QLatin1String(obj->name())));
2393 groupEl.appendChild(createBoolEntry(doc, "hasParent", obj->parent()));
2394 if ( !obj->parent() ) {
2395 groupEl.appendChild(createRectEntry(doc, "geometry", QRect(main->frameGeometry().topLeft(), main->size())));
2396 groupEl.appendChild(createBoolEntry(doc, "visible", obj->isVisible()));
2397 }
2398 if (obj->header && obj->header->inherits("K3DockWidgetHeader")) {
2399 K3DockWidgetHeader *h = static_cast<K3DockWidgetHeader*>(obj->header);
2400 groupEl.appendChild(createBoolEntry(doc, "dragEnabled", h->dragEnabled()));
2401 }
2402
2403 base.appendChild(groupEl);
2404 nameList.append(obj->name());
2405 nList.erase(nListIt);
2406 nListIt=nList.begin();
2407 }
2408
2409 if (main->inherits("K3DockMainWindow")) {
2410 K3DockMainWindow *dmain = (K3DockMainWindow*)main;
2411 QString centralWidgetStr = QString(dmain->centralWidget()? dmain->centralWidget()->name() : "");
2412 base.appendChild(createStringEntry(doc, "centralWidget", centralWidgetStr));
2413 QString mainDockWidgetStr = QString(dmain->getMainDockWidget()? dmain->getMainDockWidget()->name() : "");
2414 base.appendChild(createStringEntry(doc, "mainDockWidget", mainDockWidgetStr));
2415 } else {
2416 base.appendChild(createStringEntry(doc, "mainWidget", mainWidgetStr));
2417 }
2418
2419 base.appendChild(createRectEntry(doc, "geometry", QRect(main->frameGeometry().topLeft(), main->size())));
2420}
2421
2422
2423void K3DockManager::readConfig(QDomElement &base)
2424{
2425 if (base.namedItem("group").isNull()
2426 && base.namedItem("tabgroup").isNull()
2427 && base.namedItem("dock").isNull()
2428 && base.namedItem("dockContainer").isNull()) {
2429 activate();
2430 return;
2431 }
2432
2433 autoCreateDock = new QObjectList;
2434
2435 bool isMainVisible = main->isVisible();
2436 main->hide();
2437
2438 QObjectList::iterator it = childDock->begin();
2439 K3DockWidget *obj1;
2440 while ( it != childDock->end() ) {
2441 obj1=(K3DockWidget*)(*it);
2442 if ( !obj1->isGroup && !obj1->isTabGroup ) {
2443 if ( obj1->parent() )
2444 obj1->undock();
2445 else
2446 obj1->hide();
2447 }
2448 ++it;
2449 }
2450
2451 // firstly, recreate all common dockwidgets
2452 for( QDomNode n = base.firstChild(); !n.isNull(); n = n.nextSibling() )
2453 {
2454 QDomElement childEl = n.toElement();
2455 if (childEl.tagName() != "dock") continue;
2456
2457 // Read an ordinary dock widget
2458 K3DockWidget *obj = getDockWidgetFromName(stringEntry(childEl, "name"));
2459 obj->setTabPageLabel(stringEntry(childEl, "tabCaption"));
2460 obj->setToolTipString(stringEntry(childEl, "tabToolTip"));
2461
2462 if (!boolEntry(childEl, "hasParent")) {
2463 QRect r = rectEntry(childEl, "geometry");
2464 obj = getDockWidgetFromName(stringEntry(childEl, "name"));
2465 obj->applyToWidget(0);
2466 obj->setGeometry(r);
2467 if (boolEntry(childEl, "visible"))
2468 obj->QWidget::show();
2469 }
2470
2471 if (obj && obj->header && obj->header->inherits("K3DockWidgetHeader")) {
2472 K3DockWidgetHeader *h = static_cast<K3DockWidgetHeader*>(obj->header);
2473 h->setDragEnabled(boolEntry(childEl, "dragEnabled"));
2474 }
2475 }
2476
2477 // secondly, now iterate again and create the groups and tabwidgets, apply the dockwidgets to them
2478 for( QDomNode n = base.firstChild(); !n.isNull(); n = n.nextSibling() )
2479 {
2480 QDomElement childEl = n.toElement();
2481 if (childEl.isNull()) continue;
2482
2483 K3DockWidget *obj = 0;
2484
2485 if (childEl.tagName() == "dockContainer") {
2486
2487 K3DockWidget *cont=getDockWidgetFromName(stringEntry(childEl, "name"));
2488 kDebug(282)<<"dockContainer: "<<stringEntry(childEl,"name");
2489 if (!(cont->d->isContainer)) {
2490 kDebug(282)<<"restoration of dockContainer is only supported for already existing dock containers";
2491 } else {
2492 K3DockContainer *dc=dynamic_cast<K3DockContainer*>(cont->getWidget());
2493 if (!dc) kDebug(282)<<"Error while trying to handle dockcontainer configuration restoration";
2494 else {
2495 dc->load(childEl);
2496 removeFromAutoCreateList(cont);
2497 }
2498
2499 }
2500 }
2501 else
2502 if (childEl.tagName() == "splitGroup") {
2503 // Read a group
2504 QString name = stringEntry(childEl, "name");
2505 QString firstName = stringEntry(childEl, "firstName");
2506 QString secondName = stringEntry(childEl, "secondName");
2507 int orientation = numberEntry(childEl, "orientation");
2508 int separatorPos = numberEntry(childEl, "separatorPos");
2509
2510 K3DockWidget *first = getDockWidgetFromName(firstName);
2511 K3DockWidget *second = getDockWidgetFromName(secondName);
2512 if (first && second) {
2513 obj = first->manualDock(second,
2514 (orientation == (int)Qt::Vertical)? K3DockWidget::DockLeft : K3DockWidget::DockTop,
2515 separatorPos);
2516 if (obj)
2517 obj->setName(name.toLatin1().constData());
2518 }
2519 } else if (childEl.tagName() == "tabGroup") {
2520 // Read a tab group
2521 QString name = stringEntry(childEl, "name");
2522 Q3StrList list = listEntry(childEl, "tabs", "tab");
2523
2524 K3DockWidget *d1 = getDockWidgetFromName( list.first() );
2525 list.next();
2526 K3DockWidget *d2 = getDockWidgetFromName( list.current() );
2527
2528 K3DockWidget *obj = d2->manualDock( d1, K3DockWidget::DockCenter );
2529 if (obj) {
2530 K3DockTabGroup *tab = (K3DockTabGroup*)obj->widget;
2531 list.next();
2532 while (list.current() && obj) {
2533 K3DockWidget *tabDock = getDockWidgetFromName(list.current());
2534 obj = tabDock->manualDock(d1, K3DockWidget::DockCenter);
2535 list.next();
2536 }
2537 if (obj) {
2538 obj->setName(name.toLatin1().constData());
2539 tab->showPage(tab->page(numberEntry(childEl, "currentTab")));
2540 }
2541 }
2542 } else {
2543 continue;
2544 }
2545
2546 if (!boolEntry(childEl, "hasParent")) {
2547 QRect r = rectEntry(childEl, "geometry");
2548 obj = getDockWidgetFromName(stringEntry(childEl, "name"));
2549 obj->applyToWidget(0);
2550 obj->setGeometry(r);
2551 if (boolEntry(childEl, "visible"))
2552 obj->QWidget::show();
2553 }
2554
2555 if (obj && obj->header && obj->header->inherits("K3DockWidgetHeader")) {
2556 K3DockWidgetHeader *h = static_cast<K3DockWidgetHeader*>(obj->header);
2557 h->setDragEnabled(boolEntry(childEl, "dragEnabled"));
2558 }
2559 }
2560
2561 // thirdly, now that all ordinary dockwidgets are created,
2562 // iterate them again and link them with their corresponding dockwidget for the dockback action
2563 for( QDomNode n = base.firstChild(); !n.isNull(); n = n.nextSibling() )
2564 {
2565 QDomElement childEl = n.toElement();
2566
2567 if (childEl.tagName() != "dock" && childEl.tagName() != "tabGroup")
2568 continue;
2569
2570 K3DockWidget *obj = 0;
2571
2572 if (!boolEntry(childEl, "hasParent")) {
2573 // Read a common toplevel dock widget
2574 obj = getDockWidgetFromName(stringEntry(childEl, "name"));
2575 QString name = stringEntry(childEl, "dockBackTo");
2576 if (!name.isEmpty()) {
2577 obj->setFormerBrotherDockWidget(getDockWidgetFromName(name));
2578 }
2579 obj->formerDockPos = K3DockWidget::DockPosition(numberEntry(childEl, "dockBackToPos"));
2580 obj->updateHeader();
2581 }
2582 }
2583
2584 if (main->inherits("K3DockMainWindow")) {
2585 K3DockMainWindow *dmain = (K3DockMainWindow*)main;
2586
2587 QString mv = stringEntry(base, "centralWidget");
2588 if (!mv.isEmpty() && getDockWidgetFromName(mv) ) {
2589 K3DockWidget *mvd = getDockWidgetFromName(mv);
2590 mvd->applyToWidget(dmain);
2591 mvd->show();
2592 dmain->setCentralWidget(mvd);
2593 }
2594 QString md = stringEntry(base, "mainDockWidget");
2595 if (!md.isEmpty() && getDockWidgetFromName(md)) {
2596 K3DockWidget *mvd = getDockWidgetFromName(md);
2597 dmain->setMainDockWidget(mvd);
2598 }
2599 } else {
2600 QString mv = stringEntry(base, "mainWidget");
2601 if (!mv.isEmpty() && getDockWidgetFromName(mv)) {
2602 K3DockWidget *mvd = getDockWidgetFromName(mv);
2603 mvd->applyToWidget(main);
2604 mvd->show();
2605 }
2606
2607 // only resize + move non-mainwindows
2608 QRect mr = rectEntry(base, "geometry");
2609 main->move(mr.topLeft());
2610 main->resize(mr.size());
2611 }
2612
2613 if (isMainVisible)
2614 main->show();
2615
2616 if (d->m_readDockConfigMode == WrapExistingWidgetsOnly) {
2617 finishReadDockConfig(); // remove empty dockwidgets
2618 }
2619}
2620
2621void K3DockManager::removeFromAutoCreateList(K3DockWidget* pDockWidget)
2622{
2623 if (!autoCreateDock) return;
2624 autoCreateDock->removeAt(autoCreateDock->indexOf(pDockWidget));
2625}
2626
2627void K3DockManager::finishReadDockConfig()
2628{
2629 delete autoCreateDock;
2630 autoCreateDock = 0;
2631}
2632
2633void K3DockManager::setReadDockConfigMode(int mode)
2634{
2635 d->m_readDockConfigMode = mode;
2636}
2637
2638#ifndef NO_KDE2
2639void K3DockManager::writeConfig( KConfig* c, const QString &_group )
2640{
2641 //debug("BEGIN Write Config");
2642 if (!c) {
2643 c = KGlobal::config().data();
2644 }
2645 QString group = _group.isEmpty() ? "dock_setting_default" : _group;
2646
2647 KConfigGroup cg(c, group);
2648 cg.writeEntry( "Version", DOCK_CONFIG_VERSION );
2649
2650 QStringList nameList;
2651 QStringList findList;
2652 K3DockWidget* obj;
2653
2654 // collect K3DockWidget's name
2655 QStringList nList;
2656 Q_FOREACH( QObject* o, *childDock )
2657 {
2658#ifdef __GNUC__ // ### KDE4
2659# warning "Can obj be 0 and what should we do in the case that it is?"
2660#endif
2661 obj = qobject_cast<K3DockWidget*> ( o );
2662 if ( !obj )
2663 continue;
2664 //debug(" +Add subdock %s", obj->objectName());
2665 nList.append( obj->objectName() );
2666 if ( obj->parent() == main )
2667 cg.writeEntry( "Main:view", obj->objectName() );
2668 }
2669
2670// kDebug(282)<<QString("list size: %1").arg(nList.count());
2671 for (QObjectList::iterator it = d->containerDocks.begin() ;it != d->containerDocks.end(); ++it)
2672 {
2673 K3DockContainer* dc = dynamic_cast<K3DockContainer*>(((K3DockWidget*)(*it))->widget);
2674 if (dc) {
2675 dc->prepareSave(nList);
2676 }
2677 }
2678// kDebug(282)<<QString("new list size: %1").arg(nList.count());
2679
2680 QStringList::Iterator nListIt=nList.begin();
2681 while ( nListIt!=nList.end() ){
2682 //debug(" -Try to save %s", nList.current());
2683 obj = getDockWidgetFromName( *nListIt );
2684 QString cname = obj->name();
2685 if ( obj->header ){
2686 obj->header->saveConfig( &cg );
2687 }
2688 if (obj->d->isContainer) {
2689 K3DockContainer* x = dynamic_cast<K3DockContainer*>(obj->widget);
2690 if (x) {
2691 x->save(c,group);
2692 }
2693 }
2694/*************************************************************************************************/
2695 if ( obj->isGroup ){
2696 if ( (findList.indexOf( obj->firstName ) != -1) && (findList.indexOf( obj->lastName ) != -1 )){
2697
2698 cg.writeEntry( cname+":type", "GROUP");
2699 if ( !obj->parent() ){
2700 cg.writeEntry( cname+":parent", "___null___");
2701 cg.writeEntry( cname+":geometry", QRect(obj->frameGeometry().topLeft(), obj->size()) );
2702 cg.writeEntry( cname+":visible", QVariant(obj->isVisible()) );
2703 } else {
2704 cg.writeEntry( cname+":parent", "yes");
2705 }
2706 cg.writeEntry( cname+":first_name", obj->firstName );
2707 cg.writeEntry( cname+":last_name", obj->lastName );
2708 cg.writeEntry( cname+":orientation", QVariant(obj->splitterOrientation) );
2709 cg.writeEntry( cname+":sepPos", QVariant(((K3DockSplitter*)obj->widget)->separatorPosInPercent()) );
2710
2711 nameList.append( obj->name() );
2712 findList.append( obj->name() );
2713 //debug(" Save %s", nList.current());
2714 nList.erase(nListIt);
2715 nListIt=nList.begin(); //nList.first();
2716 } else {
2717/*************************************************************************************************/
2718 //debug(" Skip %s", nList.current());
2719 //if ( findList.find( obj->firstName ) == -1 )
2720 // debug(" ? Not found %s", obj->firstName);
2721 //if ( findList.find( obj->lastName ) == -1 )
2722 // debug(" ? Not found %s", obj->lastName);
2723 ++nListIt;
2724 // if ( !nList.current() ) nList.first();
2725 if (nListIt==nList.end()) nListIt=nList.begin();
2726 }
2727 } else {
2728/*************************************************************************************************/
2729 if ( obj->isTabGroup){
2730 cg.writeEntry( cname+":type", "TAB_GROUP");
2731 if ( !obj->parent() ){
2732 cg.writeEntry( cname+":parent", "___null___");
2733 cg.writeEntry( cname+":geometry", QRect(obj->frameGeometry().topLeft(), obj->size()) );
2734 cg.writeEntry( cname+":visible", QVariant(obj->isVisible()) );
2735 cg.writeEntry( cname+":dockBackTo", obj->formerBrotherDockWidget ? obj->formerBrotherDockWidget->name() : "");
2736 cg.writeEntry( cname+":dockBackToPos", QVariant(obj->formerDockPos) );
2737 } else {
2738 cg.writeEntry( cname+":parent", "yes");
2739 }
2740 QStringList list;
2741 for ( int i = 0; i < ((K3DockTabGroup*)obj->widget)->count(); ++i )
2742 list.append( ((K3DockTabGroup*)obj->widget)->page( i )->name() );
2743 cg.writeEntry( cname+":tabNames", list );
2744 cg.writeEntry( cname+":curTab", QVariant(((K3DockTabGroup*)obj->widget)->currentPageIndex()) );
2745
2746 nameList.append( obj->name() );
2747 findList.append( obj->name() ); // not really need !!!
2748 //debug(" Save %s", nList.current());
2749 nList.erase(nListIt);
2750 nListIt=nList.begin();
2751 } else {
2752/*************************************************************************************************/
2753 cg.writeEntry( cname+":tabCaption", obj->tabPageLabel());
2754 cg.writeEntry( cname+":tabToolTip", obj->toolTipString());
2755 if ( !obj->parent() ){
2756 cg.writeEntry( cname+":type", "NULL_DOCK");
2757 cg.writeEntry( cname+":geometry", QRect(obj->frameGeometry().topLeft(), obj->size()) );
2758 cg.writeEntry( cname+":visible", QVariant(obj->isVisible()) );
2759 cg.writeEntry( cname+":dockBackTo", obj->formerBrotherDockWidget ? obj->formerBrotherDockWidget->name() : "");
2760 cg.writeEntry( cname+":dockBackToPos", QVariant(obj->formerDockPos) );
2761 } else {
2762 cg.writeEntry( cname+":type", "DOCK");
2763 }
2764 nameList.append( cname.toLatin1().constData() );
2765 //debug(" Save %s", nList.current());
2766 findList.append( obj->name() );
2767 nList.erase(nListIt);
2768 nListIt=nList.begin();
2769 }
2770 }
2771 }
2772 cg.writeEntry( "NameList", nameList );
2773
2774 cg.writeEntry( "Main:Geometry", QRect(main->frameGeometry().topLeft(), main->size()) );
2775 cg.writeEntry( "Main:visible", QVariant(main->isVisible()) ); // curently nou use
2776
2777 if ( main->inherits("K3DockMainWindow") ){
2778 K3DockMainWindow* dmain = (K3DockMainWindow*)main;
2779 // for K3DockMainWindow->setView() in readConfig()
2780 cg.writeEntry( "Main:view", dmain->centralWidget() ? dmain->centralWidget()->name():"" );
2781 cg.writeEntry( "Main:dock", dmain->getMainDockWidget() ? dmain->getMainDockWidget()->name() :"" );
2782 }
2783
2784 c->sync();
2785 //debug("END Write Config");
2786}
2787#include <qmessagebox.h>
2788void K3DockManager::readConfig( KConfig* c, const QString &_group )
2789{
2790 if (!c) {
2791 c = KGlobal::config().data();
2792 }
2793 QString group = _group.isEmpty() ? "dock_setting_default" : _group;
2794
2795 KConfigGroup cg(c, group );
2796 QStringList nameList;
2797 nameList = cg.readEntry( "NameList", QStringList() );
2798 QString ver = cg.readEntry( "Version", "0.0.1" );
2799 if ( nameList.isEmpty() || ver != DOCK_CONFIG_VERSION ){
2800 activate();
2801 return;
2802 }
2803
2804 autoCreateDock = new QObjectList();
2805
2806 bool isMainVisible = main->isVisible();
2807 // if (isMainVisible) // CCC
2808 //QMessageBox::information(0,"","hallo");
2809//COMMENTED4TESTING main->hide();
2810
2811 QObjectList::iterator it = childDock->begin();
2812 K3DockWidget * obj;
2813
2814 while ( it != childDock->end() ){
2815 obj = (K3DockWidget*)(*it);
2816 ++it;
2817 if ( !obj->isGroup && !obj->isTabGroup ) {
2818 if ( obj->parent() ) obj->undock(); else obj->hide();
2819 }
2820 }
2821
2822 // firstly, only the common dockwidgets,
2823 // they must be restored before e.g. tabgroups are restored
2824 foreach( const QString &oname, nameList )
2825 {
2826 cg = KConfigGroup( c, group );
2827 QString type = cg.readEntry( oname + ":type", QString() );
2828 obj = 0L;
2829
2830 if ( type == "NULL_DOCK" || cg.readEntry( oname + ":parent", QString() ) == "___null___" ){
2831 QRect r = cg.readEntry( oname + ":geometry",QRect() );
2832 obj = getDockWidgetFromName( oname );
2833 obj->applyToWidget( 0L );
2834 obj->setGeometry(r);
2835
2836 cg = KConfigGroup( c, group );
2837 obj->setTabPageLabel(cg.readEntry( oname + ":tabCaption", QString() ));
2838 obj->setToolTipString(cg.readEntry( oname + ":tabToolTip", QString() ));
2839 if ( cg.readEntry( oname + ":visible",QVariant(false) ).toBool() ){
2840 obj->QWidget::show();
2841 }
2842 }
2843
2844 if ( type == "DOCK" ){
2845 obj = getDockWidgetFromName( oname );
2846 obj->setTabPageLabel(cg.readEntry( oname + ":tabCaption", QString() ));
2847 obj->setToolTipString(cg.readEntry( oname + ":tabToolTip", QString() ));
2848 }
2849
2850 if (obj && obj->d->isContainer) {
2851 dynamic_cast<K3DockContainer*>(obj->widget)->load(c,group);
2852 removeFromAutoCreateList(obj);
2853 }
2854 if ( obj && obj->header){
2855 obj->header->loadConfig( &cg );
2856 }
2857 }
2858
2859 // secondly, after the common dockwidgets, restore the groups and tabgroups
2860 foreach( const QString &oname, nameList )
2861 {
2862 cg = KConfigGroup( c, group );
2863 QString type = cg.readEntry( oname + ":type", QString() );
2864 obj = 0L;
2865
2866 if ( type == "GROUP" ){
2867 K3DockWidget* first = getDockWidgetFromName( cg.readEntry( oname + ":first_name", QString() ) );
2868 K3DockWidget* last = getDockWidgetFromName( cg.readEntry( oname + ":last_name", QString() ) );
2869 int sepPos = cg.readEntry( oname + ":sepPos",0 );
2870
2871 Qt::Orientation p = (Qt::Orientation)cg.readEntry( oname + ":orientation",0 );
2872 if ( first && last ){
2873 obj = first->manualDock( last, ( p == Qt::Vertical ) ? K3DockWidget::DockLeft : K3DockWidget::DockTop, sepPos );
2874 if (obj){
2875 obj->setName( oname.toLatin1().constData() );
2876 }
2877 }
2878 }
2879
2880 if ( type == "TAB_GROUP" ){
2881 K3DockWidget* tabDockGroup = 0L;
2882 const QStringList list = cg.readEntry( oname+":tabNames",QStringList() );
2883 QStringList::const_iterator listit = list.begin();
2884 K3DockWidget* d1 = getDockWidgetFromName( *listit++ );
2885 K3DockWidget* d2 = getDockWidgetFromName( *listit++ );
2886 tabDockGroup = d2->manualDock( d1, K3DockWidget::DockCenter );
2887 if ( tabDockGroup ){
2888 K3DockTabGroup* tab = dynamic_cast<K3DockTabGroup*>(tabDockGroup->widget);
2889 while ( listit != list.end() && tabDockGroup ){
2890 K3DockWidget* tabDock = getDockWidgetFromName( *listit++ );
2891 tabDockGroup = tabDock->manualDock( d1, K3DockWidget::DockCenter );
2892 }
2893 if ( tabDockGroup ){
2894 tabDockGroup->setName( oname.toLatin1().constData() );
2895 cg = KConfigGroup( c, group );
2896 if (tab)
2897 tab->showPage( tab->page( cg.readEntry( oname+":curTab",0 ) ) );
2898 }
2899 }
2900 obj = tabDockGroup;
2901 }
2902
2903 if (obj && obj->d->isContainer) dynamic_cast<K3DockContainer*>(obj->widget)->load(c,group);
2904 if ( obj && obj->header){
2905 obj->header->loadConfig( &cg );
2906 }
2907 }
2908
2909 // thirdly, now that all ordinary dockwidgets are created,
2910 // iterate them again and link the toplevel ones of them with their corresponding dockwidget for the dockback action
2911 foreach( const QString &oname, nameList )
2912 {
2913 cg = KConfigGroup( c, group );
2914 QString type = cg.readEntry( oname + ":type", QString() );
2915 obj = 0L;
2916
2917 if ( type == "NULL_DOCK" || cg.readEntry( oname + ":parent", QString() ) == "___null___" ){
2918 obj = getDockWidgetFromName( oname );
2919 cg = KConfigGroup( c, group );
2920 QString name = cg.readEntry( oname + ":dockBackTo", QString() );
2921 if (!name.isEmpty()) {
2922 obj->setFormerBrotherDockWidget(getDockWidgetFromName( name ));
2923 }
2924 obj->formerDockPos = K3DockWidget::DockPosition(cg.readEntry( oname + ":dockBackToPos",0 ));
2925 }
2926 }
2927
2928 if ( main->inherits("K3DockMainWindow") ){
2929 K3DockMainWindow* dmain = (K3DockMainWindow*)main;
2930
2931 cg = KConfigGroup( c, group );
2932 QString mv = cg.readEntry( "Main:view" );
2933 if ( !mv.isEmpty() && getDockWidgetFromName( mv ) ){
2934 K3DockWidget* mvd = getDockWidgetFromName( mv );
2935 mvd->applyToWidget( dmain );
2936 mvd->show();
2937 dmain->setView( mvd );
2938 }
2939 cg = KConfigGroup( c, group );
2940 QString md = cg.readEntry( "Main:dock" );
2941 if ( !md.isEmpty() && getDockWidgetFromName( md ) ){
2942 K3DockWidget* mvd = getDockWidgetFromName( md );
2943 dmain->setMainDockWidget( mvd );
2944 }
2945 } else {
2946 cg = KConfigGroup( c, group );
2947 QString mv = cg.readEntry( "Main:view" );
2948 if ( !mv.isEmpty() && getDockWidgetFromName( mv ) ){
2949 K3DockWidget* mvd = getDockWidgetFromName( mv );
2950 mvd->applyToWidget( main );
2951 mvd->show();
2952 }
2953
2954 }
2955
2956 // delete all autocreate dock
2957 if (d->m_readDockConfigMode == WrapExistingWidgetsOnly) {
2958 finishReadDockConfig(); // remove empty dockwidgets
2959 }
2960
2961 cg = KConfigGroup( c, group );
2962
2963 QRect mr = cg.readEntry("Main:Geometry", QRect());
2964
2965 if (!main->inherits("K3DockMainWindow"))
2966 main->move(mr.topLeft());
2967
2968 main->resize(mr.size());
2969
2970 if ( isMainVisible ) main->show();
2971}
2972#endif
2973
2974
2975void K3DockManager::dumpDockWidgets() {
2976 QObjectList::iterator it = childDock->begin();
2977 K3DockWidget * obj;
2978 while ( it != childDock->end() ) {
2979 obj = (K3DockWidget*)(*it);
2980 ++it;
2981 kDebug(282) << "K3DockManager::dumpDockWidgets:" << obj->name();
2982 }
2983
2984}
2985
2986K3DockWidget* K3DockManager::getDockWidgetFromName( const QString& dockName )
2987{
2988 QObjectList::iterator it = childDock->begin();
2989 K3DockWidget * obj;
2990 while ( it != childDock->end() ) {
2991 obj=(K3DockWidget*)(*it);
2992 ++it;
2993 if ( obj->objectName() == dockName ) return obj;
2994 }
2995
2996 K3DockWidget* autoCreate = 0L;
2997 if ( autoCreateDock ){
2998 kDebug(282)<<"Autocreating dock: "<<dockName;
2999 autoCreate = new K3DockWidget( this, dockName.toLatin1().constData(), QPixmap("") );
3000 autoCreateDock->append( autoCreate );
3001 }
3002 return autoCreate;
3003}
3004void K3DockManager::setSplitterOpaqueResize(bool b)
3005{
3006 d->splitterOpaqueResize = b;
3007}
3008
3009bool K3DockManager::splitterOpaqueResize() const
3010{
3011 return d->splitterOpaqueResize;
3012}
3013
3014void K3DockManager::setSplitterKeepSize(bool b)
3015{
3016 d->splitterKeepSize = b;
3017}
3018
3019bool K3DockManager::splitterKeepSize() const
3020{
3021 return d->splitterKeepSize;
3022}
3023
3024void K3DockManager::setSplitterHighResolution(bool b)
3025{
3026 d->splitterHighResolution = b;
3027}
3028
3029bool K3DockManager::splitterHighResolution() const
3030{
3031 return d->splitterHighResolution;
3032}
3033
3034void K3DockManager::slotMenuPopup()
3035{
3036 menu->clear();
3037 menuData->clear();
3038
3039 QObjectList::iterator it = childDock->begin();
3040 K3DockWidget * obj;
3041 while ( it != childDock->end() ) {
3042 obj=(K3DockWidget*)(*it);
3043 ++it;
3044 if ( obj->mayBeHide() ) {
3045 menu->insertItem( i18n("Hide %1", obj->windowTitle()));
3046 menuData->append( new MenuDockData( obj, true ) );
3047 }
3048
3049 if ( obj->mayBeShow() ) {
3050 menu->insertItem( i18n("Show %1", obj->windowTitle()));
3051 menuData->append( new MenuDockData( obj, false ) );
3052 }
3053 }
3054}
3055
3056void K3DockManager::slotMenuActivated( int id )
3057{
3058 MenuDockData* data = menuData->at( id );
3059 data->dock->changeHideShowState();
3060}
3061
3062K3DockWidget* K3DockManager::findWidgetParentDock( QWidget* w ) const
3063{
3064 QObjectList::iterator it = childDock->begin();
3065 K3DockWidget * dock;
3066 K3DockWidget * found = 0L;
3067
3068 while (it != childDock->end() ) {
3069 dock=(K3DockWidget*)(*it);
3070 ++it;
3071 if ( dock->widget == w ){ found = dock; break; }
3072 }
3073 return found;
3074}
3075
3076void K3DockManager::makeWidgetDockVisible( QWidget* w )
3077{
3078 findWidgetParentDock(w)->makeDockVisible();
3079}
3080
3081Q3PopupMenu* K3DockManager::dockHideShowMenu() const
3082{
3083 return menu;
3084}
3085
3086void K3DockManager::drawDragRectangle()
3087{
3088#ifdef BORDERLESS_WINDOWS
3089 return
3090#endif
3091 if (d->oldDragRect == d->dragRect)
3092 return;
3093
3094 int i;
3095 QRect oldAndNewDragRect[2];
3096 oldAndNewDragRect[0] = d->oldDragRect;
3097 oldAndNewDragRect[1] = d->dragRect;
3098
3099 // 2 calls, one for the old and one for the new drag rectangle
3100 for (i = 0; i <= 1; i++) {
3101 if (oldAndNewDragRect[i].isEmpty())
3102 continue;
3103
3104 K3DockWidget* pDockWdgAtRect = (K3DockWidget*) QApplication::widgetAt( oldAndNewDragRect[i].topLeft() );
3105 if (!pDockWdgAtRect)
3106 continue;
3107
3108 bool isOverMainWdg = false;
3109 //bool unclipped;
3110 K3DockMainWindow* pMain = 0L;
3111 K3DockWidget* pTLDockWdg = 0L;
3112 QWidget* topWdg;
3113 if (pDockWdgAtRect->topLevelWidget() == main) {
3114 isOverMainWdg = true;
3115 topWdg = pMain = (K3DockMainWindow*) main;
3116 //unclipped = pMain->testWFlags( WPaintUnclipped );
3117 //pMain->setWFlags( WPaintUnclipped );
3118 }
3119 else {
3120 topWdg = pTLDockWdg = (K3DockWidget*) pDockWdgAtRect->topLevelWidget();
3121 //unclipped = pTLDockWdg->testWFlags( WPaintUnclipped );
3122 //pTLDockWdg->setWFlags( WPaintUnclipped );
3123 }
3124
3125 // draw the rectangle unclipped over the main dock window
3126 QPainter p;
3127 p.begin( topWdg );
3128 /*
3129 if ( !unclipped ) {
3130 if (isOverMainWdg)
3131 pMain->clearWFlags(WPaintUnclipped);
3132 else
3133 pTLDockWdg->clearWFlags(WPaintUnclipped);
3134 }
3135 */
3136 // draw the rectangle
3137 //p.setRasterOp(Qt::NotXorROP);
3138 QRect r = oldAndNewDragRect[i];
3139 r.moveTopLeft( r.topLeft() - topWdg->mapToGlobal(QPoint(0,0)) );
3140 p.drawRect(r.x(), r.y(), r.width(), r.height());
3141 p.end();
3142 }
3143
3144 // memorize the current rectangle for later removing
3145 d->oldDragRect = d->dragRect;
3146}
3147
3148void K3DockManager::setSpecialLeftDockContainer(K3DockWidget* container) {
3149 d->leftContainer=container;
3150}
3151
3152void K3DockManager::setSpecialTopDockContainer(K3DockWidget* container) {
3153 d->topContainer=container;
3154}
3155
3156void K3DockManager::setSpecialRightDockContainer(K3DockWidget* container) {
3157 d->rightContainer=container;
3158
3159}
3160
3161void K3DockManager::setSpecialBottomDockContainer(K3DockWidget* container) {
3162 d->bottomContainer=container;
3163}
3164
3165
3166K3DockArea::K3DockArea( QWidget* parent, const char *name)
3167:QWidget( parent, name)
3168{
3169 QString new_name = QString(name) + QString("_DockManager");
3170 dockManager = new K3DockManager( this, new_name.toLatin1().constData() );
3171 mainDockWidget = 0L;
3172}
3173
3174K3DockArea::~K3DockArea()
3175{
3176 delete dockManager;
3177}
3178
3179K3DockManager* K3DockArea::manager()
3180{
3181 return dockManager;
3182}
3183
3184K3DockWidget* K3DockArea::createDockWidget( const QString& name, const QPixmap &pixmap, QWidget* parent, const QString& strCaption, const QString& strTabPageLabel)
3185{
3186 return new K3DockWidget( dockManager, name.toLatin1().constData(), pixmap, parent, strCaption, strTabPageLabel );
3187}
3188
3189void K3DockArea::activateDock()
3190{
3191 dockManager->activate();
3192}
3193
3194Q3PopupMenu* K3DockArea::dockHideShowMenu()
3195{
3196 return dockManager->dockHideShowMenu();
3197}
3198
3199void K3DockArea::makeDockVisible( K3DockWidget* dock )
3200{
3201 if ( dock )
3202 dock->makeDockVisible();
3203}
3204
3205void K3DockArea::makeDockInvisible( K3DockWidget* dock )
3206{
3207 if ( dock )
3208 dock->undock();
3209}
3210
3211void K3DockArea::makeWidgetDockVisible( QWidget* widget )
3212{
3213 makeDockVisible( dockManager->findWidgetParentDock(widget) );
3214}
3215
3216void K3DockArea::writeDockConfig(QDomElement &base)
3217{
3218 dockManager->writeConfig(base);
3219}
3220
3221void K3DockArea::readDockConfig(QDomElement &base)
3222{
3223 dockManager->readConfig(base);
3224}
3225
3226void K3DockArea::slotDockWidgetUndocked()
3227{
3228 QObject* pSender = (QObject*) sender();
3229 if (!pSender->inherits("K3DockWidget")) return;
3230 K3DockWidget* pDW = (K3DockWidget*) pSender;
3231 emit dockWidgetHasUndocked( pDW);
3232}
3233
3234void K3DockArea::resizeEvent(QResizeEvent *rsize)
3235{
3236 QWidget::resizeEvent(rsize);
3237 if (!children().isEmpty()){
3238#ifndef NO_KDE2
3239// kDebug(282)<<"K3DockArea::resize";
3240#endif
3241 QList<QWidget *> list = findChildren<QWidget*>();
3242
3243 foreach( QWidget *w, list )
3244 {
3245 w->setGeometry(QRect(QPoint(0,0),size()));
3246 }
3247#if 0
3248 K3DockSplitter *split;
3249// for (unsigned int i=0;i<children()->count();i++)
3250 {
3251// QPtrList<QObject> list(children());
3252// QObject *obj=((QPtrList<QObject*>)children())->at(i);
3253 QObject *obj=children()->getFirst();
3254 if (split = dynamic_cast<K3DockSplitter*>(obj))
3255 {
3256 split->setGeometry( QRect(QPoint(0,0), size() ));
3257// break;
3258 }
3259 }
3260#endif
3261 }
3262}
3263
3264#ifndef NO_KDE2
3265void K3DockArea::writeDockConfig( KConfig* c, const QString &group )
3266{
3267 dockManager->writeConfig( c, group );
3268}
3269
3270void K3DockArea::readDockConfig( KConfig* c, const QString &group )
3271{
3272 dockManager->readConfig( c, group );
3273}
3274#endif
3275
3276void K3DockArea::setMainDockWidget( K3DockWidget* mdw )
3277{
3278 if ( mainDockWidget == mdw ) return;
3279 mainDockWidget = mdw;
3280 mdw->applyToWidget(this);
3281}
3282
3283K3DockWidget* K3DockArea::getMainDockWidget()
3284{
3285 return mainDockWidget;
3286}
3287
3288
3289
3290// KDOCKCONTAINER - AN ABSTRACTION OF THE KDOCKTABWIDGET
3291K3DockContainer::K3DockContainer(){m_overlapMode=false; m_childrenListBegin=0; m_childrenListEnd=0;}
3292K3DockContainer::~K3DockContainer(){
3293
3294 if (m_childrenListBegin)
3295 {
3296 struct ListItem *tmp=m_childrenListBegin;
3297 while (tmp)
3298 {
3299 struct ListItem *tmp2=tmp->next;
3300 free(tmp->data);
3301 delete tmp;
3302 tmp=tmp2;
3303 }
3304 m_childrenListBegin=0;
3305 m_childrenListEnd=0;
3306 }
3307
3308}
3309
3310void K3DockContainer::activateOverlapMode(int nonOverlapSize) {
3311 m_nonOverlapSize=nonOverlapSize;
3312 m_overlapMode=true;
3313 if (parentDockWidget() && parentDockWidget()->parent()) {
3314 kDebug(282)<<"K3DockContainer::activateOverlapMode: recalculating sizes";
3315 K3DockSplitter *sp= qobject_cast<K3DockSplitter*>(parentDockWidget()->parent());
3316 if (sp)
3317 sp->resizeEvent(0);
3318 }
3319}
3320
3321void K3DockContainer::deactivateOverlapMode() {
3322 if (!m_overlapMode) return;
3323 m_overlapMode=false;
3324 if (parentDockWidget() && parentDockWidget()->parent()) {
3325 kDebug(282)<<"K3DockContainer::deactivateOverlapMode: recalculating sizes";
3326 K3DockSplitter *sp= qobject_cast<K3DockSplitter*>(parentDockWidget()->parent());
3327 if (sp)
3328 sp->resizeEvent(0);
3329 }
3330}
3331
3332bool K3DockContainer::isOverlapMode() {
3333 return m_overlapMode;
3334}
3335
3336
3337bool K3DockContainer::dockDragEnter(K3DockWidget*, QMouseEvent *) { return false;}
3338bool K3DockContainer::dockDragMove(K3DockWidget*, QMouseEvent *) { return false;}
3339bool K3DockContainer::dockDragLeave(K3DockWidget*, QMouseEvent *) { return false;}
3340
3341
3342K3DockWidget *K3DockContainer::parentDockWidget(){return 0;}
3343
3344QStringList K3DockContainer::containedWidgets() const {
3345 QStringList tmp;
3346 for (struct ListItem *it=m_childrenListBegin;it;it=it->next) {
3347 tmp<<QString(it->data);
3348 }
3349
3350 return tmp;
3351}
3352
3353void K3DockContainer::showWidget(K3DockWidget *) {
3354}
3355
3356void K3DockContainer::insertWidget (K3DockWidget *dw, const QPixmap &, const QString &, int &)
3357 {
3358 struct ListItem *it=new struct ListItem;
3359 it->data=strdup(dw->name());
3360 it->next=0;
3361
3362 if (m_childrenListEnd)
3363 {
3364 m_childrenListEnd->next=it;
3365 it->prev=m_childrenListEnd;
3366 m_childrenListEnd=it;
3367 }
3368 else
3369 {
3370 it->prev=0;
3371 m_childrenListEnd=it;
3372 m_childrenListBegin=it;
3373 }
3374 }
3375void K3DockContainer::removeWidget (K3DockWidget *dw){
3376 for (struct ListItem *tmp=m_childrenListBegin;tmp;tmp=tmp->next)
3377 {
3378 if (!strcmp(tmp->data,dw->name()))
3379 {
3380 free(tmp->data);
3381 if (tmp->next) tmp->next->prev=tmp->prev;
3382 if (tmp->prev) tmp->prev->next=tmp->next;
3383 if (tmp==m_childrenListBegin) m_childrenListBegin=tmp->next;
3384 if (tmp==m_childrenListEnd) m_childrenListEnd=tmp->prev;
3385 delete tmp;
3386 break;
3387 }
3388 }
3389}
3390
3391//m_children.remove(dw->name());}
3392void K3DockContainer::undockWidget (K3DockWidget *){;}
3393void K3DockContainer::setToolTip(K3DockWidget *, QString &){;}
3394void K3DockContainer::setPixmap(K3DockWidget*,const QPixmap&){;}
3395void K3DockContainer::load (KConfig*, const QString&){;}
3396void K3DockContainer::save (KConfig*, const QString&){;}
3397void K3DockContainer::load (QDomElement&){;}
3398void K3DockContainer::save (QDomElement&){;}
3399void K3DockContainer::prepareSave(QStringList &names)
3400{
3401
3402 for (struct ListItem *tmp=m_childrenListBegin;tmp; tmp=tmp->next)
3403 names.removeAll(tmp->data);
3404// for (uint i=0;i<m_children.count();i++)
3405// {
3406// names.remove(m_children.at(i));
3407// }
3408}
3409
3410
3411K3DockTabGroup::K3DockTabGroup( QWidget *parent, const char *name )
3412 :QTabWidget( parent )
3413{
3414 setObjectName( QLatin1String(name) );
3415}
3416
3417K3DockTabGroup::~K3DockTabGroup()
3418{
3419}
3420
3421QWidget *K3DockTabGroup::transientTo() {
3422 QWidget *tT=0;
3423 for (int i=0;i<count();i++) {
3424 K3DockWidget *dw=qobject_cast<K3DockWidget*>(page(i));
3425 QWidget *tmp;
3426 if ((tmp=dw->transientTo())) {
3427 if (!tT) tT=tmp;
3428 else {
3429 if (tT!=tmp) {
3430 kDebug(282)<<"K3DockTabGroup::transientTo: widget mismatch";
3431 return 0;
3432 }
3433 }
3434 }
3435 }
3436
3437 kDebug(282)<<"K3DockTabGroup::transientTo: "<<(tT?"YES":"NO");
3438
3439 return tT;
3440}
3441
3442void K3DockWidgetAbstractHeader::virtual_hook( int, void* )
3443{ /*BASE::virtual_hook( id, data );*/ }
3444
3445void K3DockWidgetAbstractHeaderDrag::virtual_hook( int, void* )
3446{ /*BASE::virtual_hook( id, data );*/ }
3447
3448void K3DockWidgetHeaderDrag::virtual_hook( int id, void* data )
3449{ K3DockWidgetAbstractHeaderDrag::virtual_hook( id, data ); }
3450
3451void K3DockWidgetHeader::virtual_hook( int id, void* data )
3452{ K3DockWidgetAbstractHeader::virtual_hook( id, data ); }
3453
3454void K3DockTabGroup::virtual_hook( int, void* )
3455{ /*BASE::virtual_hook( id, data );*/ }
3456
3457void K3DockWidget::virtual_hook( int, void* )
3458{ /*BASE::virtual_hook( id, data );*/ }
3459
3460void K3DockManager::virtual_hook( int, void* )
3461{ /*BASE::virtual_hook( id, data );*/ }
3462
3463void K3DockMainWindow::virtual_hook( int, void* )
3464{ /* KMainWindow::virtual_hook( id, data ); */ }
3465
3466void K3DockArea::virtual_hook( int, void* )
3467{ /*KMainWindow::virtual_hook( id, data );*/ }
3468
3469
3470#ifndef NO_INCLUDE_MOCFILES // for Qt-only projects, because tmake doesn't take this name
3471#include "k3dockwidget.moc"
3472#endif
3473
3474//kate: indent-mode csands; space-indent on; indent-width 2;
3475