kmdidockcontainer.cpp

00001 /* This file is part of the KDE project
00002  Copyright (C) 2002 Christoph Cullmann <cullmann@kde.org>
00003  Copyright (C) 2002,2003 Joseph Wenninger <jowenn@kde.org>
00004 
00005  This library is free software; you can redistribute it and/or
00006  modify it under the terms of the GNU Library General Public
00007  License version 2 as published by the Free Software Foundation.
00008 
00009  This library is distributed in the hope that it will be useful,
00010  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  Library General Public License for more details.
00013 
00014  You should have received a copy of the GNU Library General Public License
00015  along with this library; see the file COPYING.LIB.  If not, write to
00016  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "kmdimainfrm.h"
00021 #include "kmdidockcontainer.h"
00022 #include "kmdidockcontainer.moc"
00023 
00024 #include "kdockwidget_private.h"
00025 
00026 #include <qwidgetstack.h>
00027 #include <qlayout.h>
00028 #include <qtimer.h>
00029 #include <qtooltip.h>
00030 #include <kmultitabbar.h>
00031 #include <kglobalsettings.h>
00032 
00033 #include <kdebug.h>
00034 #include <kiconloader.h>
00035 #include <kapplication.h>
00036 #include <kconfig.h>
00037 #include <klocale.h>
00038 
00039 //TODO: Well, this is already defined in kdeui/kdockwidget.cpp
00040 static const char* const kmdi_not_close_xpm[] =
00041     {
00042         "5 5 2 1",
00043         "# c black",
00044         ". c None",
00045         "#####",
00046         "#...#",
00047         "#...#",
00048         "#...#",
00049         "#####"
00050     };
00051 
00052 KMdiDockContainer::KMdiDockContainer( QWidget *parent, QWidget *win, int position, int flags )
00053         : QWidget( parent ), KDockContainer()
00054 {
00055     m_tabSwitching = false;
00056     m_block = false;
00057     m_inserted = -1;
00058     m_mainWin = win;
00059     oldtab = -1;
00060     mTabCnt = 0;
00061     m_position = position;
00062     m_previousTab = -1;
00063     m_separatorPos = 18000;
00064     m_movingState = NotMoving;
00065     m_startEvent = 0;
00066     kdDebug( 760 ) << k_funcinfo << endl;
00067 
00068     QBoxLayout *l;
00069     m_horizontal = ( ( position == KDockWidget::DockTop ) || ( position == KDockWidget::DockBottom ) );
00070 
00071 
00072     if ( m_horizontal )
00073         l = new QVBoxLayout( this ); //vertical layout for top and bottom docks
00074     else
00075         l = new QHBoxLayout( this ); //horizontal layout for left and right docks
00076 
00077     l->setAutoAdd( false );
00078 
00079     m_tb = new KMultiTabBar( m_horizontal ? KMultiTabBar::Horizontal : KMultiTabBar::Vertical, this );
00080 
00081     m_tb->setStyle( KMultiTabBar::KMultiTabBarStyle( flags ) );
00082     m_tb->showActiveTabTexts( true );
00083 
00084     KMultiTabBar::KMultiTabBarPosition kmtbPos;
00085     switch( position )
00086     {
00087     case KDockWidget::DockLeft:
00088         kmtbPos = KMultiTabBar::Left;
00089         break;
00090     case KDockWidget::DockRight:
00091         kmtbPos = KMultiTabBar::Right;
00092         break;
00093     case KDockWidget::DockTop:
00094         kmtbPos = KMultiTabBar::Top;
00095         break;
00096     case KDockWidget::DockBottom:
00097         kmtbPos = KMultiTabBar::Bottom;
00098         break;
00099     default:
00100         kmtbPos = KMultiTabBar::Right;
00101         break;
00102     }
00103     m_tb->setPosition( kmtbPos );
00104 
00105     m_ws = new QWidgetStack( this );
00106 
00107     m_ws->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
00108 
00109     //layout the tabbar
00110     if ( position == KDockWidget::DockLeft || position == KDockWidget::DockTop )
00111     {
00112         //add the tabbar then the widget stack
00113         l->add( m_tb );
00114         l->add( m_ws );
00115     }
00116     else
00117     {
00118         //add the widget stack then the tabbar
00119         l->add( m_ws );
00120         l->add( m_tb );
00121     }
00122 
00123     l->activate();
00124     m_ws->hide();
00125 
00126 }
00127 
00128 void KMdiDockContainer::setStyle( int style )
00129 {
00130     if ( m_tb )
00131         m_tb->setStyle( KMultiTabBar::KMultiTabBarStyle( style ) );
00132 }
00133 
00134 KMdiDockContainer::~KMdiDockContainer()
00135 {
00136     QMap<KDockWidget*, int>::iterator it;
00137     while ( m_map.count() )
00138     {
00139         it = m_map.begin();
00140         KDockWidget *w = it.key();
00141         if ( m_overlapButtons.contains( w ) )
00142         {
00143             ( static_cast<KDockWidgetHeader*>( w->getHeader()->qt_cast( "KDockWidgetHeader" ) ) )->removeButton( m_overlapButtons[w] );
00144             m_overlapButtons.remove( w );
00145         }
00146         m_map.remove( w );
00147         w->undock();
00148     }
00149     deactivated( this );
00150 }
00151 
00152 
00153 void KMdiDockContainer::init()
00154 {
00155     bool overlap = isOverlapMode();
00156     kdDebug( 760 ) << k_funcinfo << endl;
00157     if ( !m_horizontal )
00158     {
00159         kdDebug( 760 ) << k_funcinfo << "Horizontal tabbar. Setting forced fixed width." << endl;
00160         parentDockWidget()->setForcedFixedWidth( m_tb->width() );
00161         activateOverlapMode( m_tb->width() );
00162     }
00163     else
00164     {
00165         kdDebug( 760 ) << k_funcinfo << "Vertical tabbar. Setting forced fixed height." << endl;
00166         parentDockWidget()->setForcedFixedHeight( m_tb->height() );
00167         activateOverlapMode( m_tb->height() );
00168     }
00169 
00170     if (!overlap) deactivateOverlapMode();
00171 
00172     // try to restore splitter size
00173     if ( parentDockWidget() && parentDockWidget()->parent() )
00174     {
00175         KDockSplitter * sp = static_cast<KDockSplitter*>( parentDockWidget()->parent()->qt_cast( "KDockSplitter" ) );
00176         if ( sp )
00177             sp->setSeparatorPosX( m_separatorPos );
00178     }
00179 }
00180 
00181 KDockWidget* KMdiDockContainer::parentDockWidget()
00182 {
00183     return ( ( KDockWidget* ) parent() );
00184 }
00185 
00186 void KMdiDockContainer::insertWidget ( KDockWidget *dwdg, QPixmap pixmap, const QString &text, int & )
00187 {
00188     kdDebug( 760 ) << k_funcinfo << "Adding a dockwidget to the dock container" << endl;
00189     KDockWidget* w = dwdg;
00190     int tab;
00191     bool alreadyThere = m_map.contains( w );
00192 
00193     if ( alreadyThere )
00194     {
00195         tab = m_map[ w ];
00196         if ( m_ws->addWidget( w, tab ) != tab )
00197             kdDebug( 760 ) << "ERROR COULDN'T READD WIDGET" << endl;
00198 
00199         kdDebug( 760 ) << k_funcinfo << "Readded widget " << dwdg << endl;
00200     }
00201     else
00202     {
00203         tab = m_ws->addWidget( w );
00204         m_map.insert( w, tab );
00205         m_revMap.insert( tab, w );
00206 
00207         if ( ( ( KDockWidget* ) parentWidget() ) ->mayBeShow() )
00208             ( ( KDockWidget* ) parentWidget() ) ->dockBack();
00209 
00210         if ( w->getHeader()->qt_cast( "KDockWidgetHeader" ) )
00211         {
00212             kdDebug( 760 ) << k_funcinfo << "The dockwidget we're adding has a header" << endl;
00213             kdDebug( 760 ) << k_funcinfo << "Adding our overlap mode button to it" << endl;
00214 
00215             KDockWidgetHeader *hdr = static_cast<KDockWidgetHeader*>( w->getHeader()->qt_cast( "KDockWidgetHeader" ) );
00216             KDockButton_Private *btn = new KDockButton_Private( hdr, "OverlapButton" );
00217 
00218             QToolTip::add( btn, i18n( "Switch between overlap and side by side mode", "Overlap" ) );
00219 
00220             btn->setToggleButton( true );
00221             btn->setPixmap( const_cast< const char** >( kmdi_not_close_xpm ) );
00222             hdr->addButton( btn );
00223             m_overlapButtons.insert( w, btn );
00224             btn->setOn( !isOverlapMode() );
00225 
00226             connect( btn, SIGNAL( clicked() ), this, SLOT( changeOverlapMode() ) );
00227         }
00228 
00229         m_tb->appendTab( pixmap.isNull() ? SmallIcon( "misc" ) : pixmap, tab, w->tabPageLabel() );
00230         m_tb->tab( tab )->installEventFilter( this );
00231         kdDebug( 760 ) << k_funcinfo << "Added tab with label " << w->tabPageLabel() <<
00232             " to the tabbar" << endl;
00233 
00234         connect( m_tb->tab( tab ), SIGNAL( clicked( int ) ), this, SLOT( tabClicked( int ) ) );
00235 
00236         mTabCnt++;
00237         m_inserted = tab;
00238         int dummy = 0;
00239         KDockContainer::insertWidget( w, pixmap, text, dummy );
00240         itemNames.append( w->name() );
00241         tabCaptions.insert( w->name(), w->tabPageLabel() );
00242         tabTooltips.insert( w->name(), w->toolTipString() );
00243     }
00244 
00245     //FB  m_ws->raiseWidget(tab);
00246 }
00247 
00248 
00249 bool KMdiDockContainer::eventFilter( QObject *obj, QEvent *event )
00250 {
00251     switch ( event->type() )
00252     {
00253     case QEvent::MouseButtonPress:
00254     {
00255         KMultiTabBarTab* kmtbTab = dynamic_cast<KMultiTabBarTab*>( obj );
00256         if ( !kmtbTab )
00257         {
00258             kdDebug(760) << k_funcinfo << "Got a mouse button press but we have no tab" << endl;
00259             break;
00260         }
00261 
00262         KDockWidget* w = m_revMap[ kmtbTab->id() ];
00263         if ( !w )
00264         {
00265             kdDebug(760) << k_funcinfo << "Got a mouse button press but we have no widget" << endl;
00266             break;
00267         }
00268 
00269         if ( !w->getHeader() )
00270         {
00271             kdDebug(760) << k_funcinfo << "Got a mouse button press but we have no header" << endl;
00272             break;
00273         }
00274 
00275         KDockWidgetHeader *hdr = static_cast<KDockWidgetHeader*>( w->getHeader()->qt_cast( "KDockWidgetHeader" ) );
00276         if ( !hdr )
00277         {
00278             kdDebug(760) << "Wrong header type in KMdiDockContainer::eventFilter" << endl;
00279             break;
00280         }
00281 
00282         m_dockManager = w->dockManager();
00283         m_dragPanel = hdr->dragPanel();
00284 
00285         if ( m_dragPanel )
00286             m_movingState = WaitingForMoveStart;
00287 
00288         delete m_startEvent;
00289         m_startEvent = new QMouseEvent( * ( ( QMouseEvent* ) event ) );
00290     }
00291     break;
00292     case QEvent::MouseButtonRelease:
00293         if ( m_movingState == Moving )
00294         {
00295             m_movingState = NotMoving;
00296             QApplication::postEvent( m_dragPanel, new QMouseEvent( * ( ( QMouseEvent* ) event ) ) );
00297             delete m_startEvent;
00298             m_startEvent = 0;
00299         }
00300     case QEvent::MouseMove:
00301         if ( m_movingState == WaitingForMoveStart )
00302         {
00303             QPoint p( ( ( QMouseEvent* ) event )->pos() - m_startEvent->pos() );
00304             if ( p.manhattanLength() > KGlobalSettings::dndEventDelay() )
00305             {
00306                 m_dockManager->eventFilter( m_dragPanel, m_startEvent );
00307                 m_dockManager->eventFilter( m_dragPanel, event );
00308                 m_movingState = Moving;
00309             }
00310         }
00311         else if ( m_movingState == Moving )
00312             m_dockManager->eventFilter( m_dragPanel, event );
00313 
00314         break;
00315     default:
00316         break;
00317 
00318     }
00319     return false;
00320 
00321 }
00322 
00323 void KMdiDockContainer::showWidget( KDockWidget *w )
00324 {
00325     if ( !m_map.contains( w ) )
00326         return ;
00327 
00328     int id = m_map[ w ];
00329     m_tb->setTab( id, true );
00330     tabClicked( id );
00331 }
00332 
00333 void KMdiDockContainer::changeOverlapMode()
00334 {
00335     const KDockButton_Private * btn = dynamic_cast<const KDockButton_Private*>( sender() );
00336 
00337     if ( !btn )
00338         return ;
00339 
00340     if ( !btn->isOn() )
00341     {
00342         kdDebug( 760 ) << k_funcinfo << "Activating overlap mode" << endl;
00343         if ( !m_horizontal )
00344             activateOverlapMode( m_tb->width() );
00345         else
00346             activateOverlapMode( m_tb->height() );
00347 
00348     }
00349     else
00350     {
00351         kdDebug( 760 ) << k_funcinfo << "Deactivating overlap mode" << endl;
00352         deactivateOverlapMode();
00353     }
00354 
00355     QMap<KDockWidget*, KDockButton_Private*>::iterator it;
00356     for ( it = m_overlapButtons.begin(); it != m_overlapButtons.end(); ++it )
00357         it.data()->setOn( !isOverlapMode() );
00358 }
00359 
00360 void KMdiDockContainer::hideIfNeeded()
00361 {
00362     if ( itemNames.count() == 0 )
00363     {
00364         kdDebug( 760 ) << k_funcinfo << "Hiding the dock container" << endl;
00365         ( ( KDockWidget* ) parentWidget() )->undock();
00366     }
00367 }
00368 
00369 void KMdiDockContainer::removeWidget( KDockWidget* dwdg )
00370 {
00371     KDockWidget * w = dwdg;
00372     if ( !m_map.contains( w ) )
00373         return; //we don't have this widget in our container
00374 
00375     kdDebug( 760 ) << k_funcinfo << endl;
00376     //lower the tab. ( TODO: needed? )
00377     int id = m_map[ w ];
00378     if ( m_tb->isTabRaised( id ) )
00379     {
00380         m_tb->setTab( id, false );
00381         tabClicked( id );
00382     }
00383 
00384     m_tb->removeTab( id );
00385     m_ws->removeWidget( w );
00386     m_map.remove( w );
00387     m_revMap.remove( id );
00388     if ( m_overlapButtons.contains( w ) )
00389     {
00390         ( static_cast<KDockWidgetHeader*>( w->getHeader() ->qt_cast( "KDockWidgetHeader" ) ) )->removeButton( m_overlapButtons[ w ] );
00391         m_overlapButtons.remove( w );
00392     }
00393     KDockContainer::removeWidget( w );
00394     itemNames.remove( w->name() );
00395     tabCaptions.remove( w->name() );
00396     tabTooltips.remove( w->name() );
00397     hideIfNeeded();
00398 }
00399 
00400 void KMdiDockContainer::undockWidget( KDockWidget *dwdg )
00401 {
00402     KDockWidget * w = dwdg;
00403 
00404     if ( !m_map.contains( w ) )
00405         return ;
00406 
00407     int id = m_map[ w ];
00408     if ( m_tb->isTabRaised( id ) )
00409     {
00410         kdDebug( 760 ) << k_funcinfo << "Widget has been undocked, setting tab down" << endl;
00411         m_tb->setTab( id, false );
00412         tabClicked( id );
00413     }
00414 }
00415 
00416 void KMdiDockContainer::tabClicked( int t )
00417 {
00418     bool call_makeVisible = !m_tabSwitching;
00419     m_tabSwitching = true;
00420     if ( m_tb->isTabRaised( t ) )
00421     {
00422         kdDebug( 760 ) << k_funcinfo << "Tab " << t << " was just activated" << endl;
00423         if ( m_ws->isHidden() )
00424         {
00425             kdDebug( 760 ) << k_funcinfo << "Showing widgetstack for tab just clicked" << endl;
00426             m_ws->show();
00427             parentDockWidget()->restoreFromForcedFixedSize();
00428         }
00429 
00430         if ( !m_ws->widget( t ) )
00431         {
00432             kdDebug( 760 ) << k_funcinfo << "Widget tab was clicked for is not in our stack" << endl;
00433             kdDebug( 760 ) << k_funcinfo << "Docking it back in" << endl;
00434             m_revMap[t]->manualDock( parentDockWidget(), KDockWidget::DockCenter, 20 );
00435             if ( call_makeVisible )
00436                 m_revMap[t]->makeDockVisible();
00437             m_tabSwitching = false;
00438             emit activated( this );
00439             return ;
00440         }
00441 
00442         if ( m_ws->widget( t ) )
00443         {
00444             m_ws->raiseWidget( t );
00445             KDockWidget * tmpDw = static_cast<KDockWidget*>( m_ws->widget( t )->qt_cast( "KDockWidget" ) );
00446             if ( tmpDw )
00447             {
00448                 if ( tmpDw->getWidget() )
00449                     tmpDw->getWidget()->setFocus();
00450             }
00451             else
00452                 kdDebug( 760 ) << k_funcinfo << "Something really weird is going on" << endl;
00453         }
00454         else
00455             kdDebug( 760 ) << k_funcinfo << "We have no widget to handle in our stack." << endl;
00456 
00457         if ( oldtab != t )
00458             m_tb->setTab( oldtab, false );
00459 
00460         m_tabSwitching = true;
00461         oldtab = t;
00462         emit activated( this );
00463     }
00464     else
00465     {
00466         kdDebug( 760 ) << k_funcinfo << "Tab " << t << " was just deactiviated" << endl;
00467         // try save splitter position
00468         if ( parentDockWidget() && parentDockWidget()->parent() )
00469         {
00470             KDockSplitter * sp = static_cast<KDockSplitter*>( parentDockWidget()->parent()->qt_cast( "KDockSplitter" ) );
00471             if ( sp )
00472                 m_separatorPos = sp->separatorPos();
00473         }
00474         m_previousTab = t;
00475         //    oldtab=-1;
00476         if ( m_block )
00477             return ;
00478         emit deactivated( this );
00479         m_block = true;
00480         if ( m_ws->widget( t ) )
00481         {
00482             //    ((KDockWidget*)m_ws->widget(t))->undock();
00483         }
00484         m_block = false;
00485         m_ws->hide ();
00486 
00487 
00488         kdDebug( 760 ) << k_funcinfo << "Fixed Width:" << m_tb->width() << endl;
00489         if ( !m_horizontal )
00490             parentDockWidget()->setForcedFixedWidth( m_tb->width() ); // strange why it worked before at all
00491         else
00492             parentDockWidget()->setForcedFixedHeight( m_tb->height() ); // strange why it worked before at all
00493     }
00494     m_tabSwitching = false;
00495 }
00496 
00497 void KMdiDockContainer::setToolTip ( KDockWidget* w, QString &s )
00498 {
00499     kdDebug( 760 ) << k_funcinfo << "Setting tooltip '" << s << "' for widget " << w << endl;
00500     int tabId = m_map[w];
00501     KMultiTabBarTab *mbTab = m_tb->tab( tabId );
00502     QToolTip::remove( mbTab );
00503     QToolTip::add( mbTab, s );
00504 }
00505 
00506 void KMdiDockContainer::setPixmap( KDockWidget* widget , const QPixmap& pixmap )
00507 {
00508     int id = m_ws->id( widget );
00509     if ( id == -1 )
00510         return ;
00511     KMultiTabBarTab *tab = m_tb->tab( id );
00512     tab->setIcon( pixmap.isNull() ? SmallIcon( "misc" ) : pixmap );
00513 }
00514 
00515 void KMdiDockContainer::save( QDomElement& dockEl )
00516 {
00517     QDomDocument doc = dockEl.ownerDocument();
00518     QDomElement el;
00519     el = doc.createElement( "name" );
00520     el.appendChild( doc.createTextNode( QString( "%1" ).arg( parent() ->name() ) ) );
00521     dockEl.appendChild( el );
00522     el = doc.createElement( "overlapMode" );
00523     el.appendChild( doc.createTextNode( isOverlapMode() ? "true" : "false" ) );
00524     dockEl.appendChild( el );
00525     QPtrList<KMultiTabBarTab>* tl = m_tb->tabs();
00526     QPtrListIterator<KMultiTabBarTab> it( *tl );
00527     QStringList::Iterator it2 = itemNames.begin();
00528     int i = 0;
00529     for ( ;it.current() != 0;++it, ++it2 )
00530     {
00531         el = doc.createElement( "child" );
00532         el.setAttribute( "pos", QString( "%1" ).arg( i ) );
00533         QString s = tabCaptions[ *it2 ];
00534         if ( !s.isEmpty() )
00535         {
00536             el.setAttribute( "tabCaption", s );
00537         }
00538         s = tabTooltips[ *it2 ];
00539         if ( !s.isEmpty() )
00540         {
00541             el.setAttribute( "tabTooltip", s );
00542         }
00543         el.appendChild( doc.createTextNode( *it2 ) );
00544         dockEl.appendChild( el );
00545         if ( m_tb->isTabRaised( it.current() ->id() ) )
00546         {
00547             QDomElement el2 = doc.createElement( "raised" );
00548             el2.appendChild( doc.createTextNode( m_ws->widget( it.current() ->id() ) ->name() ) );
00549             el.appendChild( el2 );
00550         }
00551         ++i;
00552     }
00553 
00554 
00555 }
00556 
00557 void KMdiDockContainer::load( QDomElement& dockEl )
00558 {
00559     QString raise;
00560 
00561     for ( QDomNode n = dockEl.firstChild();!n.isNull();n = n.nextSibling() )
00562     {
00563         QDomElement el = n.toElement();
00564         if ( el.isNull() )
00565             continue;
00566         if ( el.tagName() == "overlapMode" )
00567         {
00568             if ( el.attribute( "overlapMode" ) != "false" )
00569                 activateOverlapMode( m_horizontal?m_tb->height():m_tb->width() );
00570             else
00571                 deactivateOverlapMode();
00572         }
00573         else if ( el.tagName() == "child" )
00574         {
00575             KDockWidget * dw = ( ( KDockWidget* ) parent() ) ->dockManager() ->getDockWidgetFromName( el.text() );
00576             if ( dw )
00577             {
00578                 if ( el.hasAttribute( "tabCaption" ) )
00579                 {
00580                     dw->setTabPageLabel( el.attribute( "tabCaption" ) );
00581                 }
00582                 if ( el.hasAttribute( "tabTooltip" ) )
00583                 {
00584                     dw->setToolTipString( el.attribute( "tabTooltip" ) );
00585                 }
00586                 dw->manualDock( ( KDockWidget* ) parent(), KDockWidget::DockCenter );
00587             }
00588         }
00589     }
00590 
00591     QPtrList<KMultiTabBarTab>* tl = m_tb->tabs();
00592     QPtrListIterator<KMultiTabBarTab> it1( *tl );
00593     m_ws->hide();
00594     if ( !m_horizontal )
00595         parentDockWidget()->setForcedFixedWidth( m_tb->width() );
00596     else
00597         parentDockWidget()->setForcedFixedHeight( m_tb->height() );
00598 
00599     for ( ;it1.current() != 0;++it1 )
00600         m_tb->setTab( it1.current() ->id(), false );
00601 
00602     kapp->syncX();
00603     m_delayedRaise = -1;
00604 
00605     for ( QMap<KDockWidget*, KDockButton_Private*>::iterator it = m_overlapButtons.begin();
00606             it != m_overlapButtons.end();++it )
00607         it.data() ->setOn( !isOverlapMode() );
00608 
00609     if ( !raise.isEmpty() )
00610     {
00611         for ( QMap<KDockWidget*, int>::iterator it = m_map.begin();it != m_map.end();++it )
00612         {
00613             if ( it.key() ->name() == raise )
00614             {
00615                 m_delayedRaise = it.data();
00616                 QTimer::singleShot( 0, this, SLOT( delayedRaise() ) );
00617                 kdDebug( 760 ) << k_funcinfo << "raising " << it.key()->name() << endl;
00618                 break;
00619             }
00620         }
00621 
00622     }
00623     if ( m_delayedRaise == -1 )
00624         QTimer::singleShot( 0, this, SLOT( init() ) );
00625 }
00626 
00627 void KMdiDockContainer::save( KConfig* cfg, const QString& group_or_prefix )
00628 {
00629     QString grp = cfg->group();
00630     cfg->deleteGroup( group_or_prefix + QString( "::%1" ).arg( parent() ->name() ) );
00631     cfg->setGroup( group_or_prefix + QString( "::%1" ).arg( parent() ->name() ) );
00632 
00633     if ( isOverlapMode() )
00634         cfg->writeEntry( "overlapMode", "true" );
00635     else
00636         cfg->writeEntry( "overlapMode", "false" );
00637 
00638     // try to save the splitter position
00639     if ( parentDockWidget() && parentDockWidget() ->parent() )
00640     {
00641         KDockSplitter * sp = static_cast<KDockSplitter*>( parentDockWidget() ->
00642                              parent() ->qt_cast( "KDockSplitter" ) );
00643         if ( sp )
00644             cfg->writeEntry( "separatorPosition", m_separatorPos );
00645     }
00646 
00647     QPtrList<KMultiTabBarTab>* tl = m_tb->tabs();
00648     QPtrListIterator<KMultiTabBarTab> it( *tl );
00649     QStringList::Iterator it2 = itemNames.begin();
00650     int i = 0;
00651     for ( ;it.current() != 0;++it, ++it2 )
00652     {
00653         //    cfg->writeEntry(QString("widget%1").arg(i),m_ws->widget(it.current()->id())->name());
00654         cfg->writeEntry( QString( "widget%1" ).arg( i ), ( *it2 ) );
00655         QString s = tabCaptions[ *it2 ];
00656         if ( !s.isEmpty() )
00657         {
00658             cfg->writeEntry( QString( "widget%1-tabCaption" ).arg( i ), s );
00659         }
00660         s = tabTooltips[ *it2 ];
00661         if ( !s.isEmpty() )
00662         {
00663             cfg->writeEntry( QString( "widget%1-tabTooltip" ).arg( i ), s );
00664         }
00665         //    kdDebug(760)<<"****************************************Saving: "<<m_ws->widget(it.current()->id())->name()<<endl;
00666         if ( m_tb->isTabRaised( it.current() ->id() ) )
00667             cfg->writeEntry( m_ws->widget( it.current() ->id() ) ->name(), true );
00668         ++i;
00669     }
00670     cfg->sync();
00671     cfg->setGroup( grp );
00672 
00673 }
00674 
00675 void KMdiDockContainer::load( KConfig* cfg, const QString& group_or_prefix )
00676 {
00677     QString grp = cfg->group();
00678     cfg->setGroup( group_or_prefix + QString( "::%1" ).arg( parent() ->name() ) );
00679 
00680     if ( cfg->readEntry( "overlapMode" ) != "false" )
00681         activateOverlapMode( m_horizontal?m_tb->height():m_tb->width() );
00682     else
00683         deactivateOverlapMode();
00684 
00685     m_separatorPos = cfg->readNumEntry( "separatorPosition", 18000 );
00686 
00687     int i = 0;
00688     QString raise;
00689     while ( true )
00690     {
00691         QString dwn = cfg->readEntry( QString( "widget%1" ).arg( i ) );
00692         if ( dwn.isEmpty() )
00693             break;
00694         kdDebug( 760 ) << k_funcinfo << "configuring dockwidget :" << dwn << endl;
00695         KDockWidget *dw = ( ( KDockWidget* ) parent() ) ->dockManager() ->getDockWidgetFromName( dwn );
00696         if ( dw )
00697         {
00698             QString s = cfg->readEntry( QString( "widget%1-tabCaption" ).arg( i ) );
00699             if ( !s.isEmpty() )
00700             {
00701                 dw->setTabPageLabel( s );
00702             }
00703             s = cfg->readEntry( QString( "widget%1-tabTooltip" ).arg( i ) );
00704             if ( !s.isEmpty() )
00705             {
00706                 dw->setToolTipString( s );
00707             }
00708             dw->manualDock( ( KDockWidget* ) parent(), KDockWidget::DockCenter );
00709         }
00710         if ( cfg->readBoolEntry( dwn, false ) )
00711             raise = dwn;
00712         i++;
00713 
00714     }
00715 
00716     QPtrList<KMultiTabBarTab>* tl = m_tb->tabs();
00717     QPtrListIterator<KMultiTabBarTab> it1( *tl );
00718     m_ws->hide();
00719     if ( !m_horizontal )
00720         parentDockWidget() ->setForcedFixedWidth( m_tb->width() );
00721     else
00722         parentDockWidget() ->setForcedFixedHeight( m_tb->height() );
00723     for ( ;it1.current() != 0;++it1 )
00724     {
00725         m_tb->setTab( it1.current() ->id(), false );
00726     }
00727     kapp->syncX();
00728     m_delayedRaise = -1;
00729 
00730     for ( QMap<KDockWidget*, KDockButton_Private*>::iterator it = m_overlapButtons.begin();
00731             it != m_overlapButtons.end();++it )
00732         it.data() ->setOn( !isOverlapMode() );
00733 
00734     if ( !raise.isEmpty() )
00735     {
00736         for ( QMap<KDockWidget*, int>::iterator it = m_map.begin();it != m_map.end();++it )
00737         {
00738             if ( it.key() ->name() == raise )
00739             {
00740                 /*        tabClicked(it.data());
00741                         m_tb->setTab(it.data(),true);
00742                         tabClicked(it.data());
00743                         m_ws->raiseWidget(it.key());
00744                         kapp->sendPostedEvents();
00745                         kapp->syncX();*/
00746 
00747                 m_delayedRaise = it.data();
00748                 QTimer::singleShot( 0, this, SLOT( delayedRaise() ) );
00749                 kdDebug( 760 ) << k_funcinfo << "raising" << it.key() ->name() << endl;
00750                 break;
00751             }
00752         }
00753 
00754     }
00755     if ( m_delayedRaise == -1 )
00756         QTimer::singleShot( 0, this, SLOT( init() ) );
00757     cfg->setGroup( grp );
00758 
00759 }
00760 
00761 void KMdiDockContainer::delayedRaise()
00762 {
00763     m_tb->setTab( m_delayedRaise, true );
00764     tabClicked( m_delayedRaise );
00765 }
00766 
00767 void KMdiDockContainer::collapseOverlapped()
00768 {
00769     //don't collapse if we're switching tabs
00770     if ( m_tabSwitching )
00771         return;
00772 
00773     if ( isOverlapMode() )
00774     {
00775         QPtrList<KMultiTabBarTab>* tl = m_tb->tabs();
00776         QPtrListIterator<KMultiTabBarTab> it( *tl );
00777         for ( ;it.current();++it )
00778         {
00779             if ( it.current()->isOn() )
00780             {
00781                 kdDebug( 760 ) << k_funcinfo << "lowering tab with id " << ( *it )->id() << endl;
00782                 it.current()->setState( false );
00783                 tabClicked( ( *it )->id() );
00784             }
00785         }
00786     }
00787 }
00788 
00789 void KMdiDockContainer::toggle()
00790 {
00791     kdDebug( 760 ) << k_funcinfo << endl;
00792 
00793     if ( m_tb->isTabRaised( oldtab ) )
00794     {
00795         kdDebug( 760 ) << k_funcinfo << "lowering tab" << endl;
00796         m_tb->setTab( oldtab, false );
00797         tabClicked( oldtab );
00798         KMdiMainFrm *mainFrm = dynamic_cast<KMdiMainFrm*>( m_mainWin );
00799         if ( mainFrm && mainFrm->activeWindow() )
00800             mainFrm->activeWindow()->setFocus();
00801     }
00802     else
00803     {
00804         kdDebug( 760 ) << k_funcinfo << "raising tab" << endl;
00805         if ( m_tb->tab( m_previousTab ) == 0 )
00806         {
00807             if ( m_tb->tabs() ->count() == 0 )
00808                 return ;
00809 
00810             m_previousTab = m_tb->tabs() ->getFirst() ->id();
00811         }
00812         m_tb->setTab( m_previousTab, true );
00813         tabClicked( m_previousTab );
00814     }
00815 }
00816 
00817 void KMdiDockContainer::prevToolView()
00818 {
00819     kdDebug( 760 ) << k_funcinfo << endl;
00820     QPtrList<KMultiTabBarTab>* tabs = m_tb->tabs();
00821     int pos = tabs->findRef( m_tb->tab( oldtab ) );
00822 
00823     if ( pos == -1 )
00824         return ;
00825 
00826     pos--;
00827     if ( pos < 0 )
00828         pos = tabs->count() - 1;
00829 
00830     KMultiTabBarTab *tab = tabs->at( pos );
00831     if ( !tab )
00832         return ; //can never happen here, but who knows
00833 
00834     m_tb->setTab( tab->id(), true );
00835     tabClicked( tab->id() );
00836 }
00837 
00838 void KMdiDockContainer::nextToolView()
00839 {
00840     kdDebug( 760 ) << k_funcinfo << endl;
00841     QPtrList<KMultiTabBarTab>* tabs = m_tb->tabs();
00842     int pos = tabs->findRef( m_tb->tab( oldtab ) );
00843 
00844     if ( pos == -1 )
00845         return ;
00846 
00847     pos++;
00848     if ( pos >= ( int ) tabs->count() )
00849         pos = 0;
00850 
00851     KMultiTabBarTab *tab = tabs->at( pos );
00852     if ( !tab )
00853         return ; //can never happen here, but who knows
00854 
00855     m_tb->setTab( tab->id(), true );
00856     tabClicked( tab->id() );
00857 }
00858 
00859 // kate: space-indent off; tab-width 4; replace-tabs off; indent-mode csands;
KDE Home | KDE Accessibility Home | Description of Access Keys