20 #include "tdemdimainfrm.h"
21 #include "tdemdidockcontainer.h"
22 #include "tdemdidockcontainer.moc"
24 #include "kdockwidget_private.h"
26 #include <tqwidgetstack.h>
29 #include <tqtooltip.h>
30 #include <tdemultitabbar.h>
31 #include <tdeglobalsettings.h>
34 #include <kiconloader.h>
35 #include <tdeapplication.h>
36 #include <tdeconfig.h>
37 #include <tdelocale.h>
40 static const char*
const tdemdi_not_close_xpm[] =
52 KMdiDockContainer::KMdiDockContainer( TQWidget *parent, TQWidget *win,
int position,
int flags )
53 : TQWidget( parent ), KDockContainer()
55 m_tabSwitching =
false;
61 m_position = position;
63 m_separatorPos = 18000;
64 m_movingState = NotMoving;
66 kdDebug( 760 ) << k_funcinfo << endl;
69 m_horizontal = ( ( position == KDockWidget::DockTop ) || ( position == KDockWidget::DockBottom ) );
73 l =
new TQVBoxLayout(
this );
75 l =
new TQHBoxLayout(
this );
77 l->setAutoAdd(
false );
79 m_tb =
new KMultiTabBar( m_horizontal ? KMultiTabBar::Horizontal : KMultiTabBar::Vertical,
this );
81 m_tb->setStyle( KMultiTabBar::KMultiTabBarStyle( flags ) );
82 m_tb->showActiveTabTexts(
true );
84 KMultiTabBar::KMultiTabBarPosition kmtbPos;
87 case KDockWidget::DockLeft:
88 kmtbPos = KMultiTabBar::Left;
90 case KDockWidget::DockRight:
91 kmtbPos = KMultiTabBar::Right;
93 case KDockWidget::DockTop:
94 kmtbPos = KMultiTabBar::Top;
96 case KDockWidget::DockBottom:
97 kmtbPos = KMultiTabBar::Bottom;
100 kmtbPos = KMultiTabBar::Right;
103 m_tb->setPosition( kmtbPos );
105 m_ws =
new TQWidgetStack(
this );
107 m_ws->setSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Expanding ) );
110 if ( position == KDockWidget::DockLeft || position == KDockWidget::DockTop )
128 void KMdiDockContainer::setStyle(
int style )
131 m_tb->setStyle( KMultiTabBar::KMultiTabBarStyle( style ) );
134 KMdiDockContainer::~KMdiDockContainer()
136 TQMap<KDockWidget*, int>::iterator it;
137 while ( m_map.count() )
140 KDockWidget *w = it.key();
141 if ( m_overlapButtons.contains( w ) )
143 ( ::tqt_cast<KDockWidgetHeader*>( w->getHeader() ) )->removeButton( m_overlapButtons[w] );
144 m_overlapButtons.remove( w );
153 void KMdiDockContainer::init()
155 bool overlap = isOverlapMode();
156 kdDebug( 760 ) << k_funcinfo << endl;
159 kdDebug( 760 ) << k_funcinfo <<
"Horizontal tabbar. Setting forced fixed width." << endl;
160 parentDockWidget()->setForcedFixedWidth( m_tb->width() );
161 activateOverlapMode( m_tb->width() );
165 kdDebug( 760 ) << k_funcinfo <<
"Vertical tabbar. Setting forced fixed height." << endl;
166 parentDockWidget()->setForcedFixedHeight( m_tb->height() );
167 activateOverlapMode( m_tb->height() );
170 if (!overlap) deactivateOverlapMode();
173 if ( parentDockWidget() && parentDockWidget()->parent() )
175 KDockSplitter * sp = ::tqt_cast<KDockSplitter*>( parentDockWidget()->parent() );
177 sp->setSeparatorPosX( m_separatorPos );
181 KDockWidget* KMdiDockContainer::parentDockWidget()
183 return ( ( KDockWidget* ) parent() );
186 void KMdiDockContainer::insertWidget ( KDockWidget *dwdg, TQPixmap pixmap,
const TQString &text,
int & )
188 kdDebug( 760 ) << k_funcinfo <<
"Adding a dockwidget to the dock container" << endl;
189 KDockWidget* w = dwdg;
191 bool alreadyThere = m_map.contains( w );
196 if ( m_ws->addWidget( w, tab ) != tab )
197 kdDebug( 760 ) <<
"ERROR COULDN'T READD WIDGET" << endl;
199 kdDebug( 760 ) << k_funcinfo <<
"Readded widget " << dwdg << endl;
203 tab = m_ws->addWidget( w );
204 m_map.insert( w, tab );
205 m_revMap.insert( tab, w );
207 if ( ( ( KDockWidget* ) parentWidget() ) ->mayBeShow() )
208 ( ( KDockWidget* ) parentWidget() ) ->dockBack();
210 if ( ::tqt_cast<KDockWidgetHeader*>(w->getHeader()) )
212 kdDebug( 760 ) << k_funcinfo <<
"The dockwidget we're adding has a header" << endl;
213 kdDebug( 760 ) << k_funcinfo <<
"Adding our overlap mode button to it" << endl;
215 KDockWidgetHeader *hdr = ::tqt_cast<KDockWidgetHeader*>( w->getHeader() );
216 KDockButton_Private *btn =
new KDockButton_Private( hdr,
"OverlapButton" );
218 TQToolTip::add( btn, i18n(
"Switch between overlap and side by side mode",
"Overlap" ) );
220 btn->setToggleButton(
true );
221 btn->setPixmap(
const_cast< const char**
>( tdemdi_not_close_xpm ) );
222 hdr->addButton( btn );
223 m_overlapButtons.insert( w, btn );
224 btn->setOn( !isOverlapMode() );
226 connect( btn, TQ_SIGNAL( clicked() ),
this, TQ_SLOT( changeOverlapMode() ) );
229 m_tb->appendTab( pixmap.isNull() ? SmallIcon(
"misc" ) : pixmap, tab, w->tabPageLabel() );
230 m_tb->tab( tab )->installEventFilter(
this );
231 kdDebug( 760 ) << k_funcinfo <<
"Added tab with label " << w->tabPageLabel() <<
232 " to the tabbar" << endl;
234 connect( m_tb->tab( tab ), TQ_SIGNAL( clicked(
int ) ),
this, TQ_SLOT( tabClicked(
int ) ) );
239 KDockContainer::insertWidget( w, pixmap, text, dummy );
240 itemNames.append( w->name() );
241 tabCaptions.insert( w->name(), w->tabPageLabel() );
242 tabTooltips.insert( w->name(), w->toolTipString() );
249 bool KMdiDockContainer::eventFilter( TQObject *obj, TQEvent *event )
251 switch ( event->type() )
253 case TQEvent::MouseButtonPress:
255 KMultiTabBarTab* kmtbTab =
dynamic_cast<KMultiTabBarTab*
>( obj );
258 kdDebug(760) << k_funcinfo <<
"Got a mouse button press but we have no tab" << endl;
262 KDockWidget* w = m_revMap[ kmtbTab->id() ];
265 kdDebug(760) << k_funcinfo <<
"Got a mouse button press but we have no widget" << endl;
269 if ( !w->getHeader() )
271 kdDebug(760) << k_funcinfo <<
"Got a mouse button press but we have no header" << endl;
275 KDockWidgetHeader *hdr = ::tqt_cast<KDockWidgetHeader*>( w->getHeader() );
278 kdDebug(760) <<
"Wrong header type in KMdiDockContainer::eventFilter" << endl;
282 m_dockManager = w->dockManager();
283 m_dragPanel = hdr->dragPanel();
286 m_movingState = WaitingForMoveStart;
289 m_startEvent =
new TQMouseEvent( * ( ( TQMouseEvent* ) event ) );
292 case TQEvent::MouseButtonRelease:
293 if ( m_movingState == Moving )
295 m_movingState = NotMoving;
296 TQApplication::postEvent( m_dragPanel,
new TQMouseEvent( * ( ( TQMouseEvent* ) event ) ) );
300 case TQEvent::MouseMove:
301 if ( m_movingState == WaitingForMoveStart )
303 TQPoint p( ( ( TQMouseEvent* ) event )->pos() - m_startEvent->pos() );
304 if ( p.manhattanLength() > TDEGlobalSettings::dndEventDelay() )
306 m_dockManager->eventFilter( m_dragPanel,
static_cast<TQEvent*
>(m_startEvent) );
307 m_dockManager->eventFilter( m_dragPanel, event );
308 m_movingState = Moving;
311 else if ( m_movingState == Moving )
312 m_dockManager->eventFilter( m_dragPanel, event );
323 void KMdiDockContainer::showWidget( KDockWidget *w )
325 if ( !m_map.contains( w ) )
329 m_tb->setTab(
id,
true );
333 void KMdiDockContainer::changeOverlapMode()
335 const KDockButton_Private * btn =
dynamic_cast<const KDockButton_Private*
>( sender() );
342 kdDebug( 760 ) << k_funcinfo <<
"Activating overlap mode" << endl;
344 activateOverlapMode( m_tb->width() );
346 activateOverlapMode( m_tb->height() );
351 kdDebug( 760 ) << k_funcinfo <<
"Deactivating overlap mode" << endl;
352 deactivateOverlapMode();
355 TQMap<KDockWidget*, KDockButton_Private*>::iterator it;
356 for ( it = m_overlapButtons.begin(); it != m_overlapButtons.end(); ++it )
357 it.data()->setOn( !isOverlapMode() );
360 void KMdiDockContainer::hideIfNeeded()
362 if ( itemNames.count() == 0 )
364 kdDebug( 760 ) << k_funcinfo <<
"Hiding the dock container" << endl;
365 ( ( KDockWidget* ) parentWidget() )->undock();
369 void KMdiDockContainer::removeWidget( KDockWidget* dwdg )
371 KDockWidget * w = dwdg;
372 if ( !m_map.contains( w ) )
375 kdDebug( 760 ) << k_funcinfo << endl;
378 if ( m_tb->isTabRaised(
id ) )
380 m_tb->setTab(
id,
false );
384 m_tb->removeTab(
id );
385 m_ws->removeWidget( w );
387 m_revMap.remove(
id );
388 if ( m_overlapButtons.contains( w ) )
390 ( ::tqt_cast<KDockWidgetHeader*>( w->getHeader() ) )->removeButton( m_overlapButtons[ w ] );
391 m_overlapButtons.remove( w );
393 KDockContainer::removeWidget( w );
394 itemNames.remove( w->name() );
395 tabCaptions.remove( w->name() );
396 tabTooltips.remove( w->name() );
400 void KMdiDockContainer::undockWidget( KDockWidget *dwdg )
402 KDockWidget * w = dwdg;
404 if ( !m_map.contains( w ) )
408 if ( m_tb->isTabRaised(
id ) )
410 kdDebug( 760 ) << k_funcinfo <<
"Widget has been undocked, setting tab down" << endl;
411 m_tb->setTab(
id,
false );
416 void KMdiDockContainer::tabClicked(
int t )
418 bool call_makeVisible = !m_tabSwitching;
419 m_tabSwitching =
true;
420 if ( m_tb->isTabRaised( t ) )
422 kdDebug( 760 ) << k_funcinfo <<
"Tab " << t <<
" was just activated" << endl;
423 if ( m_ws->isHidden() )
425 kdDebug( 760 ) << k_funcinfo <<
"Showing widgetstack for tab just clicked" << endl;
427 parentDockWidget()->restoreFromForcedFixedSize();
430 if ( !m_ws->widget( t ) )
432 kdDebug( 760 ) << k_funcinfo <<
"Widget tab was clicked for is not in our stack" << endl;
433 kdDebug( 760 ) << k_funcinfo <<
"Docking it back in" << endl;
434 m_revMap[t]->manualDock( parentDockWidget(), KDockWidget::DockCenter, 20 );
435 if ( call_makeVisible )
436 m_revMap[t]->makeDockVisible();
437 m_tabSwitching =
false;
438 emit activated(
this );
442 if ( m_ws->widget( t ) )
444 m_ws->raiseWidget( t );
445 KDockWidget * tmpDw = ::tqt_cast<KDockWidget*>( m_ws->widget( t ) );
448 if ( tmpDw->getWidget() )
449 tmpDw->getWidget()->setFocus();
452 kdDebug( 760 ) << k_funcinfo <<
"Something really weird is going on" << endl;
455 kdDebug( 760 ) << k_funcinfo <<
"We have no widget to handle in our stack." << endl;
458 m_tb->setTab( oldtab,
false );
460 m_tabSwitching =
true;
462 emit activated(
this );
466 kdDebug( 760 ) << k_funcinfo <<
"Tab " << t <<
" was just deactiviated" << endl;
468 if ( parentDockWidget() && parentDockWidget()->parent() )
470 KDockSplitter * sp = ::tqt_cast<KDockSplitter*>( parentDockWidget()->parent() );
472 m_separatorPos = sp->separatorPos();
478 emit deactivated(
this );
480 if ( m_ws->widget( t ) )
488 kdDebug( 760 ) << k_funcinfo <<
"Fixed Width:" << m_tb->width() << endl;
490 parentDockWidget()->setForcedFixedWidth( m_tb->width() );
492 parentDockWidget()->setForcedFixedHeight( m_tb->height() );
494 m_tabSwitching =
false;
497 void KMdiDockContainer::setToolTip ( KDockWidget* w, TQString &s )
499 kdDebug( 760 ) << k_funcinfo <<
"Setting tooltip '" << s <<
"' for widget " << w << endl;
500 int tabId = m_map[w];
501 KMultiTabBarTab *mbTab = m_tb->tab( tabId );
502 TQToolTip::remove( mbTab );
503 TQToolTip::add( mbTab, s );
506 void KMdiDockContainer::setPixmap( KDockWidget* widget ,
const TQPixmap& pixmap )
508 int id = m_ws->id( widget );
511 KMultiTabBarTab *tab = m_tb->tab(
id );
512 tab->setIcon( pixmap.isNull() ? SmallIcon(
"misc" ) : pixmap );
515 void KMdiDockContainer::save( TQDomElement& dockEl )
517 TQDomDocument doc = dockEl.ownerDocument();
519 el = doc.createElement(
"name" );
520 el.appendChild( doc.createTextNode( TQString(
"%1" ).arg( parent() ->name() ) ) );
521 dockEl.appendChild( el );
522 el = doc.createElement(
"overlapMode" );
523 el.appendChild( doc.createTextNode( isOverlapMode() ?
"true" :
"false" ) );
524 dockEl.appendChild( el );
525 TQPtrList<KMultiTabBarTab>* tl = m_tb->tabs();
526 TQPtrListIterator<KMultiTabBarTab> it( *tl );
527 TQStringList::Iterator it2 = itemNames.begin();
529 for ( ;it.current() != 0;++it, ++it2 )
531 el = doc.createElement(
"child" );
532 el.setAttribute(
"pos", TQString(
"%1" ).arg( i ) );
533 TQString s = tabCaptions[ *it2 ];
536 el.setAttribute(
"tabCaption", s );
538 s = tabTooltips[ *it2 ];
541 el.setAttribute(
"tabTooltip", s );
543 el.appendChild( doc.createTextNode( *it2 ) );
544 dockEl.appendChild( el );
545 if ( m_tb->isTabRaised( it.current() ->id() ) )
547 TQDomElement el2 = doc.createElement(
"raised" );
548 el2.appendChild( doc.createTextNode( m_ws->widget( it.current() ->id() ) ->name() ) );
549 el.appendChild( el2 );
557 void KMdiDockContainer::load( TQDomElement& dockEl )
561 for ( TQDomNode n = dockEl.firstChild();!n.isNull();n = n.nextSibling() )
563 TQDomElement el = n.toElement();
566 if ( el.tagName() ==
"overlapMode" )
568 if ( el.attribute(
"overlapMode" ) !=
"false" )
569 activateOverlapMode( m_horizontal?m_tb->height():m_tb->width() );
571 deactivateOverlapMode();
573 else if ( el.tagName() ==
"child" )
575 KDockWidget * dw = ( ( KDockWidget* ) parent() ) ->dockManager() ->getDockWidgetFromName( el.text() );
578 if ( el.hasAttribute(
"tabCaption" ) )
580 dw->setTabPageLabel( el.attribute(
"tabCaption" ) );
582 if ( el.hasAttribute(
"tabTooltip" ) )
584 dw->setToolTipString( el.attribute(
"tabTooltip" ) );
586 dw->manualDock( ( KDockWidget* ) parent(), KDockWidget::DockCenter );
591 TQPtrList<KMultiTabBarTab>* tl = m_tb->tabs();
592 TQPtrListIterator<KMultiTabBarTab> it1( *tl );
595 parentDockWidget()->setForcedFixedWidth( m_tb->width() );
597 parentDockWidget()->setForcedFixedHeight( m_tb->height() );
599 for ( ;it1.current() != 0;++it1 )
600 m_tb->setTab( it1.current() ->id(),
false );
605 for ( TQMap<KDockWidget*, KDockButton_Private*>::iterator it = m_overlapButtons.begin();
606 it != m_overlapButtons.end();++it )
607 it.data() ->setOn( !isOverlapMode() );
609 if ( !
raise.isEmpty() )
611 for ( TQMap<KDockWidget*, int>::iterator it = m_map.begin();it != m_map.end();++it )
613 if ( it.key() ->name() ==
raise )
615 m_delayedRaise = it.data();
616 TQTimer::singleShot( 0,
this, TQ_SLOT( delayedRaise() ) );
617 kdDebug( 760 ) << k_funcinfo <<
"raising " << it.key()->name() << endl;
623 if ( m_delayedRaise == -1 )
624 TQTimer::singleShot( 0,
this, TQ_SLOT( init() ) );
627 void KMdiDockContainer::save( TDEConfig* cfg,
const TQString& group_or_prefix )
629 TQString grp = cfg->group();
630 cfg->deleteGroup( group_or_prefix + TQString(
"::%1" ).arg( parent() ->name() ) );
631 cfg->setGroup( group_or_prefix + TQString(
"::%1" ).arg( parent() ->name() ) );
633 if ( isOverlapMode() )
634 cfg->writeEntry(
"overlapMode",
"true" );
636 cfg->writeEntry(
"overlapMode",
"false" );
639 if ( parentDockWidget() && parentDockWidget() ->parent() )
641 KDockSplitter * sp = ::tqt_cast<KDockSplitter*>( parentDockWidget() -> parent() );
643 cfg->writeEntry(
"separatorPosition", m_separatorPos );
646 TQPtrList<KMultiTabBarTab>* tl = m_tb->tabs();
647 TQPtrListIterator<KMultiTabBarTab> it( *tl );
648 TQStringList::Iterator it2 = itemNames.begin();
650 for ( ;it.current() != 0;++it, ++it2 )
653 cfg->writeEntry( TQString(
"widget%1" ).arg( i ), ( *it2 ) );
654 TQString s = tabCaptions[ *it2 ];
657 cfg->writeEntry( TQString(
"widget%1-tabCaption" ).arg( i ), s );
659 s = tabTooltips[ *it2 ];
662 cfg->writeEntry( TQString(
"widget%1-tabTooltip" ).arg( i ), s );
665 if ( m_tb->isTabRaised( it.current() ->id() ) )
666 cfg->writeEntry( m_ws->widget( it.current() ->id() ) ->name(),
true );
670 cfg->setGroup( grp );
674 void KMdiDockContainer::load( TDEConfig* cfg,
const TQString& group_or_prefix )
676 TQString grp = cfg->group();
677 cfg->setGroup( group_or_prefix + TQString(
"::%1" ).arg( parent() ->name() ) );
679 if ( cfg->readEntry(
"overlapMode" ) !=
"false" )
680 activateOverlapMode( m_horizontal?m_tb->height():m_tb->width() );
682 deactivateOverlapMode();
684 m_separatorPos = cfg->readNumEntry(
"separatorPosition", 18000 );
690 TQString dwn = cfg->readEntry( TQString(
"widget%1" ).arg( i ) );
693 kdDebug( 760 ) << k_funcinfo <<
"configuring dockwidget :" << dwn << endl;
694 KDockWidget *dw = ( ( KDockWidget* ) parent() ) ->dockManager() ->getDockWidgetFromName( dwn );
697 TQString s = cfg->readEntry( TQString(
"widget%1-tabCaption" ).arg( i ) );
700 dw->setTabPageLabel( s );
702 s = cfg->readEntry( TQString(
"widget%1-tabTooltip" ).arg( i ) );
705 dw->setToolTipString( s );
707 dw->manualDock( ( KDockWidget* ) parent(), KDockWidget::DockCenter );
709 if ( cfg->readBoolEntry( dwn,
false ) )
715 TQPtrList<KMultiTabBarTab>* tl = m_tb->tabs();
716 TQPtrListIterator<KMultiTabBarTab> it1( *tl );
719 parentDockWidget() ->setForcedFixedWidth( m_tb->width() );
721 parentDockWidget() ->setForcedFixedHeight( m_tb->height() );
722 for ( ;it1.current() != 0;++it1 )
724 m_tb->setTab( it1.current() ->id(),
false );
729 for ( TQMap<KDockWidget*, KDockButton_Private*>::iterator it = m_overlapButtons.begin();
730 it != m_overlapButtons.end();++it )
731 it.data() ->setOn( !isOverlapMode() );
733 if ( !
raise.isEmpty() )
735 for ( TQMap<KDockWidget*, int>::iterator it = m_map.begin();it != m_map.end();++it )
737 if ( it.key() ->name() ==
raise )
746 m_delayedRaise = it.data();
747 TQTimer::singleShot( 0,
this, TQ_SLOT( delayedRaise() ) );
748 kdDebug( 760 ) << k_funcinfo <<
"raising" << it.key() ->name() << endl;
754 if ( m_delayedRaise == -1 )
755 TQTimer::singleShot( 0,
this, TQ_SLOT( init() ) );
756 cfg->setGroup( grp );
760 void KMdiDockContainer::delayedRaise()
762 m_tb->setTab( m_delayedRaise,
true );
763 tabClicked( m_delayedRaise );
766 void KMdiDockContainer::collapseOverlapped()
769 if ( m_tabSwitching )
772 if ( isOverlapMode() )
774 TQPtrList<KMultiTabBarTab>* tl = m_tb->tabs();
775 TQPtrListIterator<KMultiTabBarTab> it( *tl );
776 for ( ;it.current();++it )
778 if ( it.current()->isOn() )
780 kdDebug( 760 ) << k_funcinfo <<
"lowering tab with id " << ( *it )->id() << endl;
781 it.current()->setState(
false );
782 tabClicked( ( *it )->id() );
788 void KMdiDockContainer::toggle()
790 kdDebug( 760 ) << k_funcinfo << endl;
792 if ( m_tb->isTabRaised( oldtab ) )
794 kdDebug( 760 ) << k_funcinfo <<
"lowering tab" << endl;
795 m_tb->setTab( oldtab,
false );
796 tabClicked( oldtab );
803 kdDebug( 760 ) << k_funcinfo <<
"raising tab" << endl;
804 if ( m_tb->tab( m_previousTab ) == 0 )
806 if ( m_tb->tabs() ->count() == 0 )
809 m_previousTab = m_tb->tabs() ->getFirst() ->id();
811 m_tb->setTab( m_previousTab,
true );
812 tabClicked( m_previousTab );
816 void KMdiDockContainer::prevToolView()
818 kdDebug( 760 ) << k_funcinfo << endl;
819 TQPtrList<KMultiTabBarTab>* tabs = m_tb->tabs();
820 int pos = tabs->findRef( m_tb->tab( oldtab ) );
827 pos = tabs->count() - 1;
829 KMultiTabBarTab *tab = tabs->at( pos );
833 m_tb->setTab( tab->id(),
true );
834 tabClicked( tab->id() );
837 void KMdiDockContainer::nextToolView()
839 kdDebug( 760 ) << k_funcinfo << endl;
840 TQPtrList<KMultiTabBarTab>* tabs = m_tb->tabs();
841 int pos = tabs->findRef( m_tb->tab( oldtab ) );
847 if ( pos >= (
int ) tabs->count() )
850 KMultiTabBarTab *tab = tabs->at( pos );
854 m_tb->setTab( tab->id(),
true );
855 tabClicked( tab->id() );
Base class for all your special main frames.
KMdiChildView * activeWindow()
Returns the focused attached MDI view.