summaryrefslogtreecommitdiffstats
path: root/kmdi/kmdimainfrm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kmdi/kmdimainfrm.cpp')
-rw-r--r--kmdi/kmdimainfrm.cpp2937
1 files changed, 2937 insertions, 0 deletions
diff --git a/kmdi/kmdimainfrm.cpp b/kmdi/kmdimainfrm.cpp
new file mode 100644
index 000000000..e4afce397
--- /dev/null
+++ b/kmdi/kmdimainfrm.cpp
@@ -0,0 +1,2937 @@
+//----------------------------------------------------------------------------
+// filename : kmdimainfrm.cpp
+//----------------------------------------------------------------------------
+// Project : KDE MDI extension
+//
+// begin : 07/1999 by Szymon Stefanek as part of kvirc
+// (an IRC application)
+// changes : 09/1999 by Falk Brettschneider to create an
+// - 06/2000 stand-alone Qt extension set of
+// classes and a Qt-based library
+// 2000-2003 maintained by the KDevelop project
+// patches : 02/2000 by Massimo Morin (mmorin@schedsys.com)
+// */2000 by Lars Beikirch (Lars.Beikirch@gmx.net)
+// 01/2003 by Jens Zurheide (jens.zurheide@gmx.de)
+//
+// copyright : (C) 1999-2003 by Szymon Stefanek (stefanek@tin.it)
+// and
+// Falk Brettschneider
+// email : falkbr@kdevelop.org (Falk Brettschneider)
+//----------------------------------------------------------------------------
+//
+//----------------------------------------------------------------------------
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Library General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+//----------------------------------------------------------------------------
+
+
+/*
+ * ATTENTION: please do you part to try to make this file legible. It's
+ * extremely hard to read already. Especially follow the indenting rules.
+ */
+#include "config.h"
+
+#include <assert.h>
+
+#include <qcursor.h>
+#include <qclipboard.h>
+#include <qobjectlist.h>
+#include <qpopupmenu.h>
+#include <qmenubar.h>
+
+#include <kmenubar.h>
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kdeversion.h>
+#include <qtabwidget.h>
+#include <klocale.h>
+#include <kstdaccel.h>
+
+#include <kiconloader.h>
+#include <kmdidockcontainer.h>
+
+
+#include <qtoolbutton.h>
+#include <qdockarea.h>
+#include <qlayout.h>
+#include <qtimer.h>
+#include <qtextstream.h>
+#include <qstring.h>
+#include <qmap.h>
+#include <qvaluelist.h>
+
+#include "kmdimainfrm.h"
+#include "kmditaskbar.h"
+#include "kmdichildfrm.h"
+#include "kmdichildarea.h"
+#include "kmdichildview.h"
+#include "kmdidockcontainer.h"
+#include "kmditoolviewaccessor_p.h"
+#include "kmdifocuslist.h"
+#include "kmdidocumentviewtabwidget.h"
+#include "kmdiguiclient.h"
+
+#include "win_undockbutton.xpm"
+#include "win_minbutton.xpm"
+#include "win_restorebutton.xpm"
+#include "win_closebutton.xpm"
+#include "kde_undockbutton.xpm"
+#include "kde_minbutton.xpm"
+#include "kde_restorebutton.xpm"
+#include "kde_closebutton.xpm"
+#include "kde2_undockbutton.xpm"
+#include "kde2_minbutton.xpm"
+#include "kde2_restorebutton.xpm"
+#include "kde2_closebutton.xpm"
+#include "kde2laptop_undockbutton.xpm"
+#include "kde2laptop_minbutton.xpm"
+#include "kde2laptop_restorebutton.xpm"
+#include "kde2laptop_closebutton.xpm"
+#include "kde2laptop_closebutton_menu.xpm"
+
+#ifdef Q_WS_X11
+#ifndef NO_KDE
+#include <X11/X.h> // schroder
+#include <X11/Xlib.h> // schroder
+#endif
+
+#ifdef KeyRelease
+/* I hate the defines in the X11 header files. Get rid of one of them */
+#undef KeyRelease
+#endif
+
+#ifdef KeyPress
+/* I hate the defines in the X11 header files. Get rid of one of them */
+#undef KeyPress
+#endif
+#endif // Q_WS_X11 && ! K_WS_QTONLY
+
+using namespace KParts;
+
+KMdi::FrameDecor KMdiMainFrm::m_frameDecoration = KMdi::KDELook;
+
+class KMdiMainFrmPrivate
+{
+public:
+ KMdiMainFrmPrivate() : focusList( 0 )
+ {
+ for ( int i = 0;i < 4;i++ )
+ {
+ activeDockPriority[ i ] = 0;
+ m_styleIDEAlMode = 0;
+ m_toolviewStyle = 0;
+ }
+ }
+ ~KMdiMainFrmPrivate()
+ {}
+ KMdiDockContainer* activeDockPriority[ 4 ];
+ KMdiFocusList *focusList;
+ int m_styleIDEAlMode;
+ int m_toolviewStyle;
+ KAction *closeWindowAction;
+};
+
+//============ constructor ============//
+KMdiMainFrm::KMdiMainFrm( QWidget* parentWidget, const char* name, KMdi::MdiMode mdiMode, WFlags flags )
+ : KParts::DockMainWindow( parentWidget, name, flags )
+ , m_mdiMode( KMdi::UndefinedMode )
+ , m_pMdi( 0L )
+ , m_pTaskBar( 0L )
+ , m_pDocumentViews( 0L )
+ , m_pCurrentWindow( 0L )
+ , m_pWindowPopup( 0L )
+ , m_pTaskBarPopup( 0L )
+ , m_pWindowMenu( 0L )
+ , m_pDockMenu( 0L )
+ , m_pMdiModeMenu( 0L )
+ , m_pPlacingMenu( 0L )
+ , m_pMainMenuBar( 0L )
+ , m_pUndockButtonPixmap( 0L )
+ , m_pMinButtonPixmap( 0L )
+ , m_pRestoreButtonPixmap( 0L )
+ , m_pCloseButtonPixmap( 0L )
+ , m_pUndock( 0L )
+ , m_pMinimize( 0L )
+ , m_pRestore( 0L )
+ , m_pClose( 0L )
+ , m_bMaximizedChildFrmMode( false )
+ , m_oldMainFrmHeight( 0 )
+ , m_oldMainFrmMinHeight( 0 )
+ , m_oldMainFrmMaxHeight( 0 )
+ , m_bSDIApplication( false )
+ , m_pDockbaseAreaOfDocumentViews( 0L )
+ , m_pTempDockSession( 0L )
+ , m_bClearingOfWindowMenuBlocked( false )
+ , m_pDragEndTimer( 0L )
+ , m_bSwitching( false )
+ , m_leftContainer( 0 )
+ , m_rightContainer( 0 )
+ , m_topContainer( 0 )
+ , m_bottomContainer( 0 )
+ , d( new KMdiMainFrmPrivate() )
+ , m_mdiGUIClient( 0 )
+ , m_managedDockPositionMode( false )
+ , m_documentTabWidget( 0 )
+{
+ kdDebug(760) << k_funcinfo << endl;
+ // Create the local lists of windows
+ m_pDocumentViews = new QPtrList<KMdiChildView>;
+ m_pDocumentViews->setAutoDelete( false );
+ m_pToolViews = new QMap<QWidget*, KMdiToolViewAccessor*>;
+
+ // This seems to be needed (re-check it after Qt2.0 comed out)
+ setFocusPolicy( ClickFocus );
+
+ // create the central widget
+ createMdiManager();
+
+ // cover KMdi's childarea by a dockwidget
+ m_pDockbaseAreaOfDocumentViews = createDockWidget( "mdiAreaCover", QPixmap(), 0L, "mdi_area_cover" );
+ m_pDockbaseAreaOfDocumentViews->setDockWindowTransient( this, true );
+ m_pDockbaseAreaOfDocumentViews->setEnableDocking( KDockWidget::DockNone );
+ m_pDockbaseAreaOfDocumentViews->setDockSite( KDockWidget::DockCorner );
+ m_pDockbaseAreaOfDocumentViews->setWidget( m_pMdi );
+ // set this dock to main view
+ setView( m_pDockbaseAreaOfDocumentViews );
+ setMainDockWidget( m_pDockbaseAreaOfDocumentViews );
+
+ // Apply options for the MDI manager
+ applyOptions();
+
+ m_pTaskBarPopup = new QPopupMenu( this, "taskbar_popup_menu" );
+ m_pWindowPopup = new QPopupMenu( this, "window_popup_menu" );
+
+ m_pWindowMenu = new QPopupMenu( this, "window_menu" );
+ m_pWindowMenu->setCheckable( true );
+ QObject::connect( m_pWindowMenu, SIGNAL( aboutToShow() ), this, SLOT( fillWindowMenu() ) );
+
+ m_pDockMenu = new QPopupMenu( this, "dock_menu" );
+ m_pDockMenu->setCheckable( true );
+
+ m_pMdiModeMenu = new QPopupMenu( this, "mdimode_menu" );
+ m_pMdiModeMenu->setCheckable( true );
+
+ m_pPlacingMenu = new QPopupMenu( this, "placing_menu" );
+
+ d->closeWindowAction = new KAction(i18n("&Close"), KStdAccel::close(),
+ this, SLOT(closeActiveView()), actionCollection(), "window_close");
+
+ // the MDI view taskbar
+ createTaskBar();
+
+ // this is only a hack, but prevents us from crash because the buttons are otherwise
+ // not created before we switch the modes where we need them !!!
+ setMenuForSDIModeSysButtons( menuBar() );
+
+ switch ( mdiMode )
+ {
+ case KMdi::IDEAlMode:
+ kdDebug(760) << k_funcinfo << "Switching to IDEAl mode" << endl;
+ switchToIDEAlMode();
+ break;
+ case KMdi::TabPageMode:
+ kdDebug(760) << k_funcinfo << "Switching to tab page mode" << endl;
+ switchToTabPageMode();
+ break;
+ case KMdi::ToplevelMode:
+ kdDebug(760) << k_funcinfo << "Switching to top level mode" << endl;
+ switchToToplevelMode();
+ break;
+ default:
+ m_mdiMode = KMdi::ChildframeMode;
+ kdDebug(760) << k_funcinfo << "Switching to child frame mode" << endl;
+ break;
+ }
+
+ // drag end timer
+ m_pDragEndTimer = new QTimer();
+ connect( m_pDragEndTimer, SIGNAL( timeout() ), this, SLOT( dragEndTimeOut() ) );
+ connect( guiFactory(), SIGNAL( clientAdded( KXMLGUIClient* ) ),
+ this, SLOT( verifyToplevelHeight() ) );
+ connect( guiFactory(), SIGNAL( clientRemoved( KXMLGUIClient* ) ),
+ this, SLOT( verifyToplevelHeight() ) );
+}
+
+void KMdiMainFrm::verifyToplevelHeight()
+{
+ if ( m_mdiMode != KMdi::ToplevelMode )
+ return;
+
+ //kdDebug(760) << k_funcinfo << endl;
+ int topDockHeight = topDock() ? topDock()->height() : 0;
+ int menuBarHeight = hasMenuBar() ? menuBar()->height() : 0;
+ setFixedHeight( topDockHeight + menuBarHeight );
+ resize( width(), height() );
+}
+
+void KMdiMainFrm::setStandardMDIMenuEnabled( bool showModeMenu )
+{
+ m_mdiGUIClient = new KMDIPrivate::KMDIGUIClient( this, showModeMenu );
+ connect( m_mdiGUIClient, SIGNAL( toggleTop() ), this, SIGNAL( toggleTop() ) );
+ connect( m_mdiGUIClient, SIGNAL( toggleLeft() ), this, SIGNAL( toggleLeft() ) );
+ connect( m_mdiGUIClient, SIGNAL( toggleRight() ), this, SIGNAL( toggleRight() ) );
+ connect( m_mdiGUIClient, SIGNAL( toggleBottom() ), this, SIGNAL( toggleBottom() ) );
+
+ if ( m_mdiMode == KMdi::IDEAlMode )
+ {
+ if ( m_topContainer )
+ connect( this, SIGNAL( toggleTop() ), m_topContainer->getWidget(), SLOT( toggle() ) );
+ if ( m_leftContainer )
+ connect( this, SIGNAL( toggleLeft() ), m_leftContainer->getWidget(), SLOT( toggle() ) );
+ if ( m_rightContainer )
+ connect( this, SIGNAL( toggleRight() ), m_rightContainer->getWidget(), SLOT( toggle() ) );
+ if ( m_bottomContainer )
+ connect( this, SIGNAL( toggleBottom() ), m_bottomContainer->getWidget(), SLOT( toggle() ) );
+ }
+
+ emit mdiModeHasBeenChangedTo( m_mdiMode );
+}
+
+//============ ~KMdiMainFrm ============//
+KMdiMainFrm::~KMdiMainFrm()
+{
+ //save the children first to a list, as removing invalidates our iterator
+ QValueList<KMdiChildView*> children;
+ for ( KMdiChildView * w = m_pDocumentViews->first();w;w = m_pDocumentViews->next() )
+ children.append( w );
+
+ // safely close the windows so properties are saved...
+ QValueListIterator<KMdiChildView*> childIt;
+ for ( childIt = children.begin(); childIt != children.end(); ++childIt )
+ {
+ closeWindow( *childIt, false ); // without re-layout taskbar!
+ }
+
+ emit lastChildViewClosed();
+ delete m_pDocumentViews;
+ delete m_pToolViews;
+ m_pToolViews = 0;
+ delete m_pDragEndTimer;
+
+ delete m_pUndockButtonPixmap;
+ delete m_pMinButtonPixmap;
+ delete m_pRestoreButtonPixmap;
+ delete m_pCloseButtonPixmap;
+
+ //deletes added for Release-Version-Pop-Up-WinMenu-And-Go-Out-Problem
+ delete m_pDockMenu;
+ delete m_pMdiModeMenu;
+ delete m_pPlacingMenu;
+ delete m_pTaskBarPopup;
+ delete m_pWindowPopup;
+ delete m_pWindowMenu;
+ delete m_mdiGUIClient;
+ delete m_pTempDockSession;
+ m_mdiGUIClient = 0;
+ delete d;
+ d = 0;
+}
+
+//============ applyOptions ============//
+//FIXME something wrong with this function. dunno what though
+void KMdiMainFrm::applyOptions()
+{
+ QPtrListIterator<KMdiChildView> it( *m_pDocumentViews );
+ for ( ; ( *it ); ++it )
+ {
+ QWidget* childFrame = 0L;
+ if ( ( *it )->mdiParent() )
+ {
+ kdDebug(760) << k_funcinfo << "using child view's mdi parent for resize hack" << endl;
+ childFrame = ( *it )->mdiParent();
+ }
+ else
+ {
+ kdDebug(760) << k_funcinfo << "using child view for resize hack" << endl;
+ childFrame = ( *it );
+ }
+
+ int w = childFrame->width();
+ int h = childFrame->height();
+ childFrame->resize( w + 1, h + 1 );
+ childFrame->resize( w - 1, h - 1 );
+ }
+}
+
+//============ createMdiManager ============//
+void KMdiMainFrm::createMdiManager()
+{
+ kdDebug(760) << k_funcinfo << "creating MDI manager" << endl;
+ m_pMdi = new KMdiChildArea( this );
+ setCentralWidget( m_pMdi );
+ QObject::connect( m_pMdi, SIGNAL( nowMaximized( bool ) ),
+ this, SLOT( setEnableMaximizedChildFrmMode( bool ) ) );
+ QObject::connect( m_pMdi, SIGNAL( noMaximizedChildFrmLeft( KMdiChildFrm* ) ),
+ this, SLOT( switchOffMaximizeModeForMenu( KMdiChildFrm* ) ) );
+ QObject::connect( m_pMdi, SIGNAL( sysButtonConnectionsMustChange( KMdiChildFrm*, KMdiChildFrm* ) ),
+ this, SLOT( updateSysButtonConnections( KMdiChildFrm*, KMdiChildFrm* ) ) );
+ QObject::connect( m_pMdi, SIGNAL( popupWindowMenu( QPoint ) ),
+ this, SLOT( popupWindowMenu( QPoint ) ) );
+ QObject::connect( m_pMdi, SIGNAL( lastChildFrmClosed() ),
+ this, SIGNAL( lastChildFrmClosed() ) );
+}
+
+//============ createTaskBar ==============//
+void KMdiMainFrm::createTaskBar()
+{
+ m_pTaskBar = new KMdiTaskBar( this, QMainWindow::DockBottom );
+ m_pTaskBar->installEventFilter( this );
+}
+
+void KMdiMainFrm::slot_toggleTaskBar()
+{
+ if ( !m_pTaskBar )
+ return;
+ m_pTaskBar->switchOn( !m_pTaskBar->isSwitchedOn() );
+}
+
+void KMdiMainFrm::resizeEvent( QResizeEvent *e )
+{
+ if ( ( m_mdiMode == KMdi::ToplevelMode ) && !parentWidget() )
+ {
+ if ( e->oldSize().height() != e->size().height() )
+ return ;
+ }
+ KParts::DockMainWindow::resizeEvent( e );
+ if ( !m_mdiGUIClient )
+ return ;
+ setSysButtonsAtMenuPosition();
+}
+
+//================ setMinimumSize ===============//
+
+void KMdiMainFrm::setMinimumSize( int minw, int minh )
+{
+ if ( ( m_mdiMode == KMdi::ToplevelMode ) && !parentWidget() )
+ return ;
+ DockMainWindow::setMinimumSize( minw, minh );
+}
+
+//================ wrapper ===============//
+
+KMdiChildView* KMdiMainFrm::createWrapper( QWidget *view, const QString& name, const QString& shortName )
+{
+ Q_ASSERT( view ); // if this assert fails, then some part didn't return a widget. Fix the part ;)
+
+ KMdiChildView* pMDICover = new KMdiChildView( name /*caption*/, 0L /*parent*/,
+ name.latin1() );
+ QBoxLayout* pLayout = new QHBoxLayout( pMDICover, 0, -1, "layout" );
+ view->reparent( pMDICover, QPoint( 0, 0 ) );
+ pLayout->addWidget( view );
+ // pMDICover->setName(name);
+ pMDICover->setTabCaption( shortName );
+ pMDICover->setCaption( name );
+
+ const QPixmap* wndIcon = view->icon();
+ if ( wndIcon )
+ pMDICover->setIcon( *wndIcon );
+
+ pMDICover->trackIconAndCaptionChanges( view );
+ return pMDICover;
+}
+
+//================ addWindow ===============//
+
+void KMdiMainFrm::addWindow( KMdiChildView* pWnd, int flags )
+{
+ addWindow( pWnd, flags, -1 );
+}
+
+void KMdiMainFrm::addWindow( KMdiChildView* pWnd, int flags, int index )
+{
+ if ( windowExists( pWnd, AnyView ) ) //already added
+ return;
+
+ if ( flags & KMdi::ToolWindow )
+ {
+ addToolWindow( pWnd );
+ // some kind of cascading
+ pWnd->move( m_pMdi->mapToGlobal( m_pMdi->getCascadePoint() ) );
+
+ return ;
+ }
+
+ d->closeWindowAction->setEnabled(true);
+
+ // common connections used when under MDI control
+ QObject::connect( pWnd, SIGNAL( clickedInWindowMenu( int ) ), this, SLOT( windowMenuItemActivated( int ) ) );
+ QObject::connect( pWnd, SIGNAL( focusInEventOccurs( KMdiChildView* ) ), this, SLOT( activateView( KMdiChildView* ) ) );
+ QObject::connect( pWnd, SIGNAL( childWindowCloseRequest( KMdiChildView* ) ), this, SLOT( childWindowCloseRequest( KMdiChildView* ) ) );
+ QObject::connect( pWnd, SIGNAL( attachWindow( KMdiChildView*, bool ) ), this, SLOT( attachWindow( KMdiChildView*, bool ) ) );
+ QObject::connect( pWnd, SIGNAL( detachWindow( KMdiChildView*, bool ) ), this, SLOT( detachWindow( KMdiChildView*, bool ) ) );
+ QObject::connect( pWnd, SIGNAL( clickedInDockMenu( int ) ), this, SLOT( dockMenuItemActivated( int ) ) );
+ QObject::connect( pWnd, SIGNAL( activated( KMdiChildView* ) ), this, SIGNAL( viewActivated( KMdiChildView* ) ) );
+ QObject::connect( pWnd, SIGNAL( deactivated( KMdiChildView* ) ), this, SIGNAL( viewDeactivated( KMdiChildView* ) ) );
+
+ if ( index == -1 )
+ m_pDocumentViews->append( pWnd );
+ else
+ m_pDocumentViews->insert( index, pWnd );
+
+ if ( m_pTaskBar )
+ {
+ KMdiTaskBarButton* but = m_pTaskBar->addWinButton( pWnd );
+ QObject::connect( pWnd, SIGNAL( tabCaptionChanged( const QString& ) ), but, SLOT( setNewText( const QString& ) ) );
+ }
+
+ // embed the view depending on the current MDI mode
+ if ( m_mdiMode == KMdi::TabPageMode || m_mdiMode == KMdi::IDEAlMode )
+ {
+ QPixmap pixmap;
+ if ( pWnd->icon() )
+ pixmap = *( pWnd->icon() );
+
+ m_documentTabWidget->insertTab( pWnd, pixmap, pWnd->tabCaption(), index );
+
+ connect( pWnd, SIGNAL( iconUpdated( QWidget*, QPixmap ) ), m_documentTabWidget, SLOT( updateIconInView( QWidget*, QPixmap ) ) );
+ connect( pWnd, SIGNAL( captionUpdated( QWidget*, const QString& ) ), m_documentTabWidget, SLOT( updateCaptionInView( QWidget*, const QString& ) ) );
+ }
+ else
+ {
+ if ( ( flags & KMdi::Detach ) || ( m_mdiMode == KMdi::ToplevelMode ) )
+ {
+ detachWindow( pWnd, !( flags & KMdi::Hide ) );
+ emit childViewIsDetachedNow( pWnd ); // fake it because detach won't call it in this case of addWindow-to-MDI
+ }
+ else
+ attachWindow( pWnd, !( flags & KMdi::Hide ), flags & KMdi::UseKMdiSizeHint );
+
+ if ( ( m_bMaximizedChildFrmMode && ( !m_bSDIApplication && ( flags & KMdi::Detach ) )
+ && m_mdiMode != KMdi::ToplevelMode ) || ( flags & KMdi::Maximize ) )
+ {
+ if ( !pWnd->isMaximized() )
+ pWnd->maximize();
+ }
+
+ if ( !m_bSDIApplication || ( flags & KMdi::Detach ) )
+ {
+ if ( flags & KMdi::Minimize )
+ pWnd->minimize();
+
+ if ( !( flags & KMdi::Hide ) )
+ {
+ if ( pWnd->isAttached() )
+ pWnd->mdiParent()->show();
+ else
+ pWnd->show();
+ }
+ }
+ }
+}
+
+//============ addWindow ============//
+void KMdiMainFrm::addWindow( KMdiChildView* pWnd, QRect rectNormal, int flags )
+{
+ addWindow( pWnd, flags );
+ if ( m_bMaximizedChildFrmMode && pWnd->isAttached() )
+ pWnd->setRestoreGeometry( rectNormal );
+ else
+ pWnd->setGeometry( rectNormal );
+}
+
+//============ addWindow ============//
+void KMdiMainFrm::addWindow( KMdiChildView* pWnd, QPoint pos, int flags )
+{
+ addWindow( pWnd, flags );
+ if ( m_bMaximizedChildFrmMode && pWnd->isAttached() )
+ pWnd->setRestoreGeometry( QRect( pos, pWnd->restoreGeometry().size() ) );
+ else
+ pWnd->move( pos );
+}
+
+
+
+KMdiToolViewAccessor *KMdiMainFrm::createToolWindow()
+{
+ return new KMdiToolViewAccessor( this );
+}
+
+
+void KMdiMainFrm::deleteToolWindow( QWidget* pWnd )
+{
+ if ( m_pToolViews->contains( pWnd ) )
+ deleteToolWindow( ( *m_pToolViews ) [ pWnd ] );
+}
+
+void KMdiMainFrm::deleteToolWindow( KMdiToolViewAccessor *accessor )
+{
+ delete accessor;
+}
+
+//============ addWindow ============//
+KMdiToolViewAccessor *KMdiMainFrm::addToolWindow( QWidget* pWnd, KDockWidget::DockPosition pos, QWidget* pTargetWnd,
+ int percent, const QString& tabToolTip, const QString& tabCaption )
+{
+ QWidget* tvta = pWnd;
+ KDockWidget* pDW = dockManager->getDockWidgetFromName( pWnd->name() );
+ if ( pDW )
+ {
+ // probably readDockConfig already created the widgetContainer, use that
+ pDW->setWidget( pWnd );
+
+ if ( pWnd->icon() )
+ pDW->setPixmap( *pWnd->icon() );
+
+ pDW->setTabPageLabel( ( tabCaption == 0 ) ? pWnd->caption() : tabCaption );
+ pDW->setToolTipString( tabToolTip );
+ dockManager->removeFromAutoCreateList( pDW );
+ pWnd = pDW;
+ }
+
+ QRect r = pWnd->geometry();
+
+ KMdiToolViewAccessor *mtva = new KMdiToolViewAccessor( this, pWnd, tabToolTip, ( tabCaption == 0 ) ? pWnd->caption() : tabCaption );
+ m_pToolViews->insert( tvta, mtva );
+
+ if ( pos == KDockWidget::DockNone )
+ {
+ mtva->d->widgetContainer->setEnableDocking( KDockWidget::DockNone );
+ mtva->d->widgetContainer->reparent( this, Qt::WType_TopLevel | Qt::WType_Dialog, r.topLeft(), true ); //pToolView->isVisible());
+ }
+ else //add and dock the toolview as a dockwidget view
+ mtva->place( pos, pTargetWnd, percent );
+
+
+ return mtva;
+}
+
+//============ attachWindow ============//
+void KMdiMainFrm::attachWindow( KMdiChildView *pWnd, bool bShow, bool bAutomaticResize )
+{
+ pWnd->installEventFilter( this );
+
+ // decide whether window shall be cascaded
+ bool bCascade = false;
+ QApplication::sendPostedEvents();
+ QRect frameGeo = pWnd->frameGeometry();
+ QPoint topLeftScreen = pWnd->mapToGlobal( QPoint( 0, 0 ) );
+ QPoint topLeftMdiChildArea = m_pMdi->mapFromGlobal( topLeftScreen );
+ QRect childAreaGeo = m_pMdi->geometry();
+ if ( topLeftMdiChildArea.x() < 0 || topLeftMdiChildArea.y() < 0 ||
+ ( topLeftMdiChildArea.x() + frameGeo.width() > childAreaGeo.width() ) ||
+ ( topLeftMdiChildArea.y() + frameGeo.height() > childAreaGeo.height() ) )
+ {
+ bCascade = true;
+ }
+
+ // create frame and insert child view
+ KMdiChildFrm *lpC = new KMdiChildFrm( m_pMdi );
+ pWnd->hide();
+ if ( !bCascade )
+ lpC->move( topLeftMdiChildArea );
+
+ lpC->setClient( pWnd, bAutomaticResize );
+ lpC->setFocus();
+ pWnd->youAreAttached( lpC );
+ if ( ( m_mdiMode == KMdi::ToplevelMode ) && !parentWidget() )
+ {
+ setMinimumHeight( m_oldMainFrmMinHeight );
+ setMaximumHeight( m_oldMainFrmMaxHeight );
+ resize( width(), m_oldMainFrmHeight );
+ m_oldMainFrmHeight = 0;
+ switchToChildframeMode();
+ }
+
+ m_pMdi->manageChild( lpC, false, bCascade );
+ if ( m_pMdi->topChild() && m_pMdi->topChild() ->isMaximized() )
+ {
+ QRect r = lpC->geometry();
+ lpC->setGeometry( -lpC->m_pClient->x(), -lpC->m_pClient->y(),
+ m_pMdi->width() + KMDI_CHILDFRM_DOUBLE_BORDER,
+ m_pMdi->height() + lpC->captionHeight() + KMDI_CHILDFRM_SEPARATOR + KMDI_CHILDFRM_DOUBLE_BORDER );
+ lpC->setRestoreGeometry( r );
+ }
+
+ if ( bShow )
+ {
+ lpC->show();
+ }
+
+#undef FocusIn
+ QFocusEvent fe( QEvent::FocusIn );
+ QApplication::sendEvent( pWnd, &fe );
+
+ m_pCurrentWindow = pWnd; // required for checking the active item
+}
+
+//============= detachWindow ==============//
+void KMdiMainFrm::detachWindow( KMdiChildView *pWnd, bool bShow )
+{
+ if ( pWnd->isAttached() )
+ {
+ pWnd->removeEventFilter( this );
+ pWnd->youAreDetached();
+ // this is only if it was attached and you want to detach it
+ if ( pWnd->parent() )
+ {
+ KMdiChildFrm * lpC = pWnd->mdiParent();
+ if ( lpC )
+ {
+ if ( lpC->icon() )
+ {
+ QPixmap pixm( *( lpC->icon() ) );
+ pWnd->setIcon( pixm );
+ }
+ QString capt( lpC->caption() );
+ if ( !bShow )
+ lpC->hide();
+ lpC->unsetClient( m_undockPositioningOffset );
+ m_pMdi->destroyChildButNotItsView( lpC, false ); //Do not focus the new top child , we loose focus...
+ pWnd->setCaption( capt );
+ }
+ }
+ }
+ else
+ {
+ if ( pWnd->size().isEmpty() || ( pWnd->size() == QSize( 1, 1 ) ) )
+ {
+ if ( m_pCurrentWindow )
+ {
+ pWnd->setGeometry( QRect( m_pMdi->getCascadePoint( m_pDocumentViews->count() - 1 ), m_pCurrentWindow->size() ) );
+ }
+ else
+ {
+ pWnd->setGeometry( QRect( m_pMdi->getCascadePoint( m_pDocumentViews->count() - 1 ), defaultChildFrmSize() ) );
+ }
+ }
+#ifdef Q_WS_X11
+ if ( mdiMode() == KMdi::ToplevelMode )
+ {
+ XSetTransientForHint( qt_xdisplay(), pWnd->winId(), topLevelWidget() ->winId() );
+ }
+#endif
+
+ return ;
+ }
+
+#ifdef Q_WS_X11
+ if ( mdiMode() == KMdi::ToplevelMode )
+ {
+ XSetTransientForHint( qt_xdisplay(), pWnd->winId(), topLevelWidget() ->winId() );
+ }
+#endif
+
+ // this will show it...
+ if ( bShow )
+ {
+ activateView( pWnd );
+ }
+
+ emit childViewIsDetachedNow( pWnd );
+}
+
+//============== removeWindowFromMdi ==============//
+void KMdiMainFrm::removeWindowFromMdi( KMdiChildView *pWnd )
+{
+ Q_UNUSED( pWnd );
+ //Closes a child window. sends no close event : simply deletes it
+ //FIXME something wrong with this, but nobody knows whatcart
+#if 0
+ if ( !( m_pWinList->removeRef( pWnd ) ) )
+ return ;
+ if ( m_pWinList->count() == 0 )
+ m_pCurrentWindow = 0L;
+
+ QObject::disconnect( pWnd, SIGNAL( attachWindow( KMdiChildView*, bool ) ), this, SLOT( attachWindow( KMdiChildView*, bool ) ) );
+ QObject::disconnect( pWnd, SIGNAL( detachWindow( KMdiChildView*, bool ) ), this, SLOT( detachWindow( KMdiChildView*, bool ) ) );
+ QObject::disconnect( pWnd, SIGNAL( focusInEventOccurs( KMdiChildView* ) ), this, SLOT( activateView( KMdiChildView* ) ) );
+ QObject::disconnect( pWnd, SIGNAL( childWindowCloseRequest( KMdiChildView* ) ), this, SLOT( childWindowCloseRequest( KMdiChildView* ) ) );
+ QObject::disconnect( pWnd, SIGNAL( clickedInWindowMenu( int ) ), this, SLOT( windowMenuItemActivated( int ) ) );
+ QObject::disconnect( pWnd, SIGNAL( clickedInDockMenu( int ) ), this, SLOT( dockMenuItemActivated( int ) ) );
+
+ if ( m_pTaskBar )
+ {
+ KMdiTaskBarButton * but = m_pTaskBar->getButton( pWnd );
+ if ( but != 0L )
+ {
+ QObject::disconnect( pWnd, SIGNAL( tabCaptionChanged( const QString& ) ), but, SLOT( setNewText( const QString& ) ) );
+ }
+ m_pTaskBar->removeWinButton( pWnd );
+ }
+
+ if ( m_mdiMode == KMdi::TabPageMode )
+ {
+ if ( m_pWinList->count() == 0 )
+ {
+ if ( !m_pDockbaseAreaOfDocumentViews )
+ {
+ m_pDockbaseAreaOfDocumentViews = createDockWidget( "mdiAreaCover", QPixmap(), 0L, "mdi_area_cover" );
+ m_pDockbaseAreaOfDocumentViews->setDockWindowTransient( this, true );
+
+ m_pDockbaseAreaOfDocumentViews->setWidget( m_pMdi );
+ setMainDockWidget( m_pDockbaseAreaOfDocumentViews );
+ }
+ m_pDockbaseOfTabPage->setDockSite( KDockWidget::DockFullSite );
+ m_pDockbaseAreaOfDocumentViews->setEnableDocking( KDockWidget::DockCenter );
+ m_pDockbaseAreaOfDocumentViews->manualDock( m_pDockbaseOfTabPage, KDockWidget::DockCenter );
+ m_pDockbaseAreaOfDocumentViews->setEnableDocking( KDockWidget::DockNone );
+ m_pDockbaseOfTabPage = m_pDockbaseAreaOfDocumentViews;
+ m_pClose->hide();
+ }
+ KDockWidget* pDockW = ( KDockWidget* ) pWnd->parentWidget();
+ pWnd->reparent( 0L, QPoint( 0, 0 ) );
+ pDockW->setWidget( 0L );
+ if ( pDockW == m_pDockbaseOfTabPage )
+ {
+ QTabWidget * pTab = ( QTabWidget* ) pDockW->parentWidget() ->parentWidget();
+ int cnt = pTab->count();
+ m_pDockbaseOfTabPage = ( KDockWidget* ) pTab->page( cnt - 2 );
+ if ( pDockW == m_pDockbaseOfTabPage )
+ {
+ m_pDockbaseOfTabPage = ( KDockWidget* ) pTab->page( cnt - 1 ); // different to the one deleted next
+ }
+ }
+ delete pDockW;
+ if ( m_pWinList->count() == 1 )
+ {
+ m_pWinList->last() ->activate(); // all other views are activated by tab switch
+ }
+ }
+ else if ( pWnd->isAttached() )
+ {
+ pWnd->mdiParent() ->hide();
+ m_pMdi->destroyChildButNotItsView( pWnd->mdiParent() );
+ }
+ else
+ {
+ // is not attached
+ if ( m_pMdi->getVisibleChildCount() > 0 )
+ {
+ setActiveWindow();
+ m_pCurrentWindow = 0L;
+ KMdiChildView* pView = m_pMdi->topChild() ->m_pClient;
+ if ( pView )
+ {
+ pView->activate();
+ }
+ }
+ else if ( m_pWinList->count() > 0 )
+ {
+ //crash? m_pWinList->last()->activate();
+ //crash? m_pWinList->last()->setFocus();
+ }
+ }
+
+ if ( pWnd->isToolView() )
+ pWnd->m_bToolView = false;
+
+ if ( !m_pCurrentWindow )
+ emit lastChildViewClosed();
+#endif
+}
+
+//============== closeWindow ==============//
+void KMdiMainFrm::closeWindow( KMdiChildView *pWnd, bool layoutTaskBar )
+{
+ if ( !pWnd )
+ return ;
+ //Closes a child window. sends no close event : simply deletes it
+ m_pDocumentViews->removeRef( pWnd );
+ if ( m_pDocumentViews->count() == 0 )
+ m_pCurrentWindow = 0L;
+
+ if ( m_pTaskBar )
+ {
+ m_pTaskBar->removeWinButton( pWnd, layoutTaskBar );
+ }
+
+ if ( ( m_mdiMode == KMdi::TabPageMode ) || ( m_mdiMode == KMdi::IDEAlMode ) )
+ {
+ if ( !m_documentTabWidget )
+ return ; //oops
+ if ( m_pDocumentViews->count() == 0 )
+ m_pClose->hide();
+ pWnd->reparent( 0L, QPoint( 0, 0 ) );
+ kdDebug(760) << "-------- 1" << endl;
+ if ( m_pDocumentViews->count() == 1 )
+ {
+ m_pDocumentViews->last() ->activate(); // all other views are activated by tab switch
+ }
+ }
+ if ( ( m_mdiMode == KMdi::TabPageMode ) || ( m_mdiMode == KMdi::IDEAlMode ) )
+ {
+ if ( m_pDocumentViews->count() == 0 )
+ {
+ if ( !m_pDockbaseAreaOfDocumentViews )
+ {
+ m_pDockbaseAreaOfDocumentViews = createDockWidget( "mdiAreaCover", QPixmap(), 0L, "mdi_area_cover" );
+ m_pDockbaseAreaOfDocumentViews->setDockWindowTransient( this, true );
+ m_pDockbaseAreaOfDocumentViews->setWidget( m_pMdi );
+ setMainDockWidget( m_pDockbaseAreaOfDocumentViews );
+ }
+#if 0
+ m_pDockbaseOfTabPage->setDockSite( KDockWidget::DockFullSite );
+ m_pDockbaseAreaOfDocumentViews->setEnableDocking( KDockWidget::DockCenter );
+ m_pDockbaseAreaOfDocumentViews->manualDock( m_pDockbaseOfTabPage, KDockWidget::DockCenter );
+ m_pDockbaseAreaOfDocumentViews->setEnableDocking( KDockWidget::DockNone );
+ m_pDockbaseOfTabPage = m_pDockbaseAreaOfDocumentViews;
+#endif
+
+ m_pClose->hide();
+ }
+#if 0
+ KDockWidget* pDockW = ( KDockWidget* ) pWnd->parentWidget();
+ pWnd->reparent( 0L, QPoint( 0, 0 ) );
+ pDockW->setWidget( 0L );
+ if ( pDockW == m_pDockbaseOfTabPage )
+ {
+ QTabWidget * pTab = ( QTabWidget* ) pDockW->parentWidget() ->parentWidget();
+ int cnt = pTab->count();
+ m_pDockbaseOfTabPage = ( KDockWidget* ) pTab->page( cnt - 2 );
+ if ( pDockW == m_pDockbaseOfTabPage )
+ {
+ m_pDockbaseOfTabPage = ( KDockWidget* ) pTab->page( cnt - 1 ); // different to the one deleted next
+ }
+ }
+ delete pDockW;
+#endif
+
+ delete pWnd;
+ if ( m_pDocumentViews->count() == 1 )
+ {
+ m_pDocumentViews->last() ->activate(); // all other views are activated by tab switch
+ }
+ }
+ else if ( pWnd->isAttached() )
+ {
+ m_pMdi->destroyChild( pWnd->mdiParent() );
+ }
+ else
+ {
+ delete pWnd;
+ // is not attached
+ if ( m_pMdi->getVisibleChildCount() > 0 )
+ {
+ setActiveWindow();
+ m_pCurrentWindow = 0L;
+ KMdiChildView* pView = m_pMdi->topChild() ->m_pClient;
+ if ( pView )
+ {
+ pView->activate();
+ }
+ }
+ else if ( m_pDocumentViews->count() > 0 )
+ {
+ if ( m_pDocumentViews->current() )
+ {
+ m_pDocumentViews->current() ->activate();
+ m_pDocumentViews->current() ->setFocus();
+ }
+ else
+ {
+ m_pDocumentViews->last() ->activate();
+ m_pDocumentViews->last() ->setFocus();
+ }
+ }
+ }
+
+ if ( !m_pCurrentWindow )
+ {
+ d->closeWindowAction->setEnabled(false);
+ emit lastChildViewClosed();
+ }
+}
+
+//================== findWindow =================//
+KMdiChildView* KMdiMainFrm::findWindow( const QString& caption )
+{
+ QPtrListIterator<KMdiChildView> it( *m_pDocumentViews );
+ for ( ; ( *it ); ++it )
+ {
+ if ( ( *it )->caption() == caption )
+ return ( *it );
+ }
+ return 0L;
+}
+
+//================== activeWindow ===================//
+KMdiChildView* KMdiMainFrm::activeWindow()
+{
+ return m_pCurrentWindow;
+}
+
+//================== windowExists ? =================//
+bool KMdiMainFrm::windowExists( KMdiChildView *pWnd, ExistsAs as )
+{
+ if ( ( as == ToolView ) || ( as == AnyView ) )
+ {
+ if ( m_pToolViews->contains( pWnd ) )
+ return true;
+ if ( as == ToolView )
+ return false;
+ }
+
+ if ( m_pDocumentViews->findRef( pWnd ) != -1 )
+ return true;
+
+ return false;
+}
+
+QPopupMenu * KMdiMainFrm::windowPopup( KMdiChildView * pWnd, bool bIncludeTaskbarPopup )
+{
+ m_pWindowPopup->clear();
+ if ( bIncludeTaskbarPopup )
+ {
+ m_pWindowPopup->insertItem( i18n( "Window" ), taskBarPopup( pWnd, false ) );
+ m_pWindowPopup->insertSeparator();
+ }
+ return m_pWindowPopup;
+}
+
+//================ taskBarPopup =================//
+QPopupMenu* KMdiMainFrm::taskBarPopup( KMdiChildView *pWnd, bool /*bIncludeWindowPopup*/ )
+{
+ //returns the g_pTaskBarPopup filled according to the KMdiChildView state
+ m_pTaskBarPopup->clear();
+ if ( pWnd->isAttached() )
+ {
+ m_pTaskBarPopup->insertItem( i18n( "Undock" ), pWnd, SLOT( detach() ) );
+ m_pTaskBarPopup->insertSeparator();
+ if ( pWnd->isMinimized() || pWnd->isMaximized() )
+ m_pTaskBarPopup->insertItem( i18n( "Restore" ), pWnd, SLOT( restore() ) );
+ if ( !pWnd->isMaximized() )
+ m_pTaskBarPopup->insertItem( i18n( "Maximize" ), pWnd, SLOT( maximize() ) );
+ if ( !pWnd->isMinimized() )
+ m_pTaskBarPopup->insertItem( i18n( "Minimize" ), pWnd, SLOT( minimize() ) );
+ }
+ else
+ m_pTaskBarPopup->insertItem( i18n( "Dock" ), pWnd, SLOT( attach() ) );
+ m_pTaskBarPopup->insertSeparator();
+ m_pTaskBarPopup->insertItem( i18n( "Close" ), pWnd, SLOT( close() ) );
+ // the window has a view...get the window popup
+ m_pTaskBarPopup->insertSeparator();
+ m_pTaskBarPopup->insertItem( i18n( "Operations" ), windowPopup( pWnd, false ) ); //alvoid recursion
+ return m_pTaskBarPopup;
+}
+
+void KMdiMainFrm::slotDocCurrentChanged( QWidget* pWidget )
+{
+ KMdiChildView * pWnd = static_cast<KMdiChildView*>( pWidget );
+ pWnd->m_bMainframesActivateViewIsPending = true;
+
+ bool bActivateNecessary = true;
+ if ( m_pCurrentWindow != pWnd )
+ m_pCurrentWindow = pWnd;
+
+ if ( m_pTaskBar )
+ m_pTaskBar->setActiveButton( pWnd );
+
+ if ( m_documentTabWidget && ( m_mdiMode == KMdi::TabPageMode || m_mdiMode == KMdi::IDEAlMode ) )
+ {
+ m_documentTabWidget->showPage( pWnd );
+ pWnd->activate();
+ }
+ else
+ {
+ if ( pWnd->isAttached() )
+ {
+ if ( bActivateNecessary && ( m_pMdi->topChild() == pWnd->mdiParent() ) )
+ pWnd->activate();
+
+ pWnd->mdiParent()->raiseAndActivate();
+ }
+ if ( !pWnd->isAttached() )
+ {
+ if ( bActivateNecessary )
+ pWnd->activate();
+
+ m_pMdi->setTopChild( 0L ); // lose focus in the mainframe window
+ if ( !pWnd->isActiveWindow() )
+ pWnd->setActiveWindow();
+
+ pWnd->raise();
+ }
+ }
+ if ( !switching() )
+ activeWindow()->updateTimeStamp();
+ emit collapseOverlapContainers();
+ pWnd->m_bMainframesActivateViewIsPending = false;
+}
+
+
+void KMdiMainFrm::activateView( KMdiChildView* pWnd )
+{
+ pWnd->m_bMainframesActivateViewIsPending = true;
+
+ bool bActivateNecessary = true;
+ if ( m_pCurrentWindow != pWnd )
+ m_pCurrentWindow = pWnd;
+ else
+ {
+ bActivateNecessary = false;
+ // if this method is called as answer to view->activate(),
+ // interrupt it because it's not necessary
+ pWnd->m_bInterruptActivation = true;
+ }
+
+ if ( m_pTaskBar )
+ m_pTaskBar->setActiveButton( pWnd );
+
+ if ( m_documentTabWidget && m_mdiMode == KMdi::TabPageMode || m_mdiMode == KMdi::IDEAlMode )
+ {
+ m_documentTabWidget->showPage( pWnd );
+ pWnd->activate();
+ }
+ else
+ {
+ if ( pWnd->isAttached() )
+ {
+ if ( bActivateNecessary && ( m_pMdi->topChild() == pWnd->mdiParent() ) )
+ pWnd->activate();
+
+ pWnd->mdiParent() ->raiseAndActivate();
+ }
+ if ( !pWnd->isAttached() )
+ {
+ if ( bActivateNecessary )
+ pWnd->activate();
+
+ m_pMdi->setTopChild( 0L ); // lose focus in the mainframe window
+ if ( !pWnd->isActiveWindow() )
+ pWnd->setActiveWindow();
+
+ pWnd->raise();
+ }
+ }
+
+ emit collapseOverlapContainers();
+
+ pWnd->m_bMainframesActivateViewIsPending = false;
+}
+
+void KMdiMainFrm::taskbarButtonRightClicked( KMdiChildView *pWnd )
+{
+ activateView( pWnd ); // set focus
+ //QApplication::sendPostedEvents();
+ taskBarPopup( pWnd, true ) ->popup( QCursor::pos() );
+}
+
+void KMdiMainFrm::childWindowCloseRequest( KMdiChildView *pWnd )
+{
+ KMdiViewCloseEvent * ce = new KMdiViewCloseEvent( pWnd );
+ QApplication::postEvent( this, ce );
+}
+
+bool KMdiMainFrm::event( QEvent* e )
+{
+ if ( e->type() == QEvent::User )
+ {
+ KMdiChildView * pWnd = ( KMdiChildView* ) ( ( KMdiViewCloseEvent* ) e )->data();
+ if ( pWnd != 0L )
+ closeWindow( pWnd );
+ return true;
+ // A little hack: If MDI child views are moved implicietly by moving
+ // the main widget they should know this too. Unfortunately there seems to
+ // be no way to catch the move start / move stop situations for the main
+ // widget in a clean way. (There is no MouseButtonPress/Release or
+ // something like that.) Therefore we do the following: When we get the
+ // "first" move event we start a timer and interprete it as "drag begin".
+ // If we get the next move event and the timer is running we restart the
+ // timer and don't do anything else. If the timer elapses (this meens we
+ // haven't had any move event for a while) we interprete this as "drag
+ // end". If the moving didn't stop actually, we will later get another
+ // "drag begin", so we get a drag end too much, but this would be the same
+ // as if the user would stop moving for a little while.
+ // Actually we seem to be lucky that the timer does not elapse while we
+ // are moving -> so we have no obsolete drag end / begin
+ }
+ else if ( isVisible() && e->type() == QEvent::Move )
+ {
+ if ( m_pDragEndTimer->isActive() )
+ {
+ // this is not the first move -> stop old timer
+ m_pDragEndTimer->stop();
+ }
+ else
+ {
+ // this is the first move -> send the drag begin to all concerned views
+ QPtrListIterator<KMdiChildView> it( *m_pDocumentViews );
+ for ( ; ( *it ); ++it )
+ {
+ KMdiChildFrmDragBeginEvent dragBeginEvent( 0L );
+ QApplication::sendEvent( ( *it ), &dragBeginEvent );
+ }
+ }
+ m_pDragEndTimer->start( 200, true ); // single shot after 200 ms
+ }
+
+ return DockMainWindow::event( e );
+}
+
+bool KMdiMainFrm::eventFilter( QObject * /*obj*/, QEvent *e )
+{
+ if ( e->type() == QEvent::Resize && m_mdiMode == KMdi::ToplevelMode )
+ {
+ verifyToplevelHeight();
+ return false; //let the rest of the resize magic do its work
+ }
+
+ if ( e->type() == QEvent::FocusIn )
+ {
+ QFocusEvent * pFE = ( QFocusEvent* ) e;
+ if ( pFE->reason() == QFocusEvent::ActiveWindow )
+ {
+ if ( m_pCurrentWindow && !m_pCurrentWindow->isHidden() &&
+ !m_pCurrentWindow->isAttached() && m_pMdi->topChild() )
+ {
+ return true; // eat the event
+ }
+ }
+ if ( m_pMdi )
+ {
+ static bool focusTCIsPending = false;
+ if ( !focusTCIsPending && m_mdiMode == KMdi::ChildframeMode )
+ {
+ focusTCIsPending = true;
+ m_pMdi->focusTopChild();
+ focusTCIsPending = false;
+ }
+ }
+ }
+ else if ( e->type() == QEvent::KeyRelease )
+ {
+ if ( switching() )
+ {
+ KAction * a = actionCollection() ->action( "view_last_window" ) ;
+ if ( a )
+ {
+ const KShortcut cut( a->shortcut() );
+ const KKeySequence& seq = cut.seq( 0 );
+ const KKey& key = seq.key( 0 );
+ int modFlags = key.modFlags();
+ int state = ( ( QKeyEvent * ) e ) ->state();
+ KKey key2( ( QKeyEvent * ) e );
+
+ /** these are quite some assumptions:
+ * The key combination uses exactly one modifier key
+ * The WIN button in KDE is the meta button in Qt
+ **/
+ if ( state != ( ( QKeyEvent * ) e ) ->stateAfter() &&
+ ( ( modFlags & KKey::CTRL ) > 0 ) == ( ( state & Qt::ControlButton ) > 0 ) &&
+ ( ( modFlags & KKey::ALT ) > 0 ) == ( ( state & Qt::AltButton ) > 0 ) &&
+ ( ( modFlags & KKey::WIN ) > 0 ) == ( ( state & Qt::MetaButton ) > 0 ) )
+ {
+ activeWindow() ->updateTimeStamp();
+ setSwitching( false );
+ }
+ return true;
+ }
+ else
+ {
+ kdDebug(760) << "KAction( \"view_last_window\") not found." << endl;
+ }
+ }
+ }
+ return false; // standard event processing
+}
+
+/**
+ * close all views
+ */
+void KMdiMainFrm::closeAllViews()
+{
+ //save the children first to a list, as removing invalidates our iterator
+ QValueList<KMdiChildView*> children;
+ for ( KMdiChildView * w = m_pDocumentViews->first();w;w = m_pDocumentViews->next() )
+ {
+ children.append( w );
+ }
+ QValueListIterator<KMdiChildView *> childIt;
+ for ( childIt = children.begin(); childIt != children.end(); ++childIt )
+ {
+ ( *childIt )->close();
+ }
+}
+
+
+/**
+ * iconify all views
+ */
+void KMdiMainFrm::iconifyAllViews()
+{
+ kdDebug(760) << k_funcinfo << "minimizing all the views" << endl;
+ QPtrListIterator<KMdiChildView> it( *m_pDocumentViews );
+ for ( ; ( *it ); ++it )
+ ( *it )->minimize();
+}
+
+/**
+ * closes the view of the active (topchild) window
+ */
+void KMdiMainFrm::closeActiveView()
+{
+ kdDebug(760) << k_funcinfo << "closing the active view" << endl;
+ if ( m_pCurrentWindow )
+ m_pCurrentWindow->close();
+}
+
+/** find the root dockwidgets and store their geometry */
+void KMdiMainFrm::findRootDockWidgets( QPtrList<KDockWidget>* rootDockWidgetList, QValueList<QRect>* positionList )
+{
+ //nothing is valid
+ if ( !rootDockWidgetList && !positionList )
+ return ;
+
+ // since we set some windows to toplevel, we must consider the window manager's window frame
+ const int frameBorderWidth = 7; // @todo: Can we / do we need to ask the window manager?
+ const int windowTitleHeight = 10; // @todo: -"-
+
+ QObjectList* pObjList = queryList( "KDockWidget" );
+ if ( pObjList->isEmpty() )
+ pObjList = queryList( "KDockWidget_Compat::KDockWidget" );
+
+ QObjectListIt it( *pObjList );
+ // for all dockwidgets (which are children of this mainwindow)
+ while ( ( *it ) )
+ {
+ KDockWidget* dockWindow = 0L; /* pDockW */
+ KDockWidget* rootDockWindow = 0L; /* pRootDockWindow */
+ KDockWidget* undockCandidate = 0L; /* pUndockCandidate */
+ QWidget* pW = static_cast<QWidget*>( ( *it ) );
+
+ // find the oldest ancestor of the current dockwidget that can be undocked
+ while ( !pW->isTopLevel() )
+ {
+ if ( ::qt_cast<KDockWidget*>( pW ) || pW->inherits( "KDockWidget_Compat::KDockWidget" ) )
+ {
+ undockCandidate = static_cast<KDockWidget*>( pW );
+ if ( undockCandidate->enableDocking() != KDockWidget::DockNone )
+ rootDockWindow = undockCandidate;
+ }
+ pW = pW->parentWidget();
+ }
+
+ if ( rootDockWindow )
+ {
+ // if that oldest ancestor is not already in the list, append it
+ bool found = false;
+ if ( !rootDockWidgetList->isEmpty() )
+ {
+ QPtrListIterator<KDockWidget> it2( *rootDockWidgetList );
+ for ( ; it2.current() && !found; ++it2 )
+ {
+ dockWindow = it2.current();
+ if ( dockWindow == rootDockWindow )
+ found = true;
+ }
+ }
+
+ if ( !found || rootDockWidgetList->isEmpty() )
+ {
+ rootDockWidgetList->append( dockWindow );
+ kdDebug(760) << k_funcinfo << "Appending " << rootDockWindow << " to our list of " <<
+ "root dock windows" << endl;
+ QPoint p = rootDockWindow->mapToGlobal( rootDockWindow->pos() ) - rootDockWindow->pos();
+ QRect r( p.x(), p.y() + m_undockPositioningOffset.y(),
+ rootDockWindow->width() - windowTitleHeight - frameBorderWidth * 2,
+ rootDockWindow->height() - windowTitleHeight - frameBorderWidth * 2 );
+ positionList->append( r );
+ }
+ }
+ ++it;
+ }
+ delete pObjList;
+}
+
+/**
+ * undocks all view windows (unix-like)
+ */
+void KMdiMainFrm::switchToToplevelMode()
+{
+ if ( m_mdiMode == KMdi::ToplevelMode )
+ {
+ emit mdiModeHasBeenChangedTo( KMdi::ToplevelMode );
+ return ;
+ }
+
+ KMdi::MdiMode oldMdiMode = m_mdiMode;
+
+ const int frameBorderWidth = 7; // @todo: Can we / do we need to ask the window manager?
+ setUndockPositioningOffset( QPoint( 0, ( m_pTaskBar ? m_pTaskBar->height() : 0 ) + frameBorderWidth ) );
+
+ // 1.) select the dockwidgets to be undocked and store their geometry
+ QPtrList<KDockWidget> rootDockWidgetList;
+ QValueList<QRect> positionList;
+
+ // 2.) undock the MDI views of KMDI
+ switch( oldMdiMode )
+ {
+ case KMdi::ChildframeMode:
+ finishChildframeMode();
+ break;
+ case KMdi::TabPageMode:
+ finishTabPageMode();
+ break;
+ case KMdi::IDEAlMode:
+ finishIDEAlMode();
+ findRootDockWidgets( &rootDockWidgetList, &positionList );
+ break;
+ default:
+ break; //do nothing
+ }
+
+ // 3.) undock all these found oldest ancestors (being KDockWidgets)
+ QPtrListIterator<KDockWidget> kdwit( rootDockWidgetList );
+ for ( ; ( *kdwit ); ++kdwit )
+ ( *kdwit )->undock();
+
+ // 4.) recreate the MDI childframe area and hide it
+ if ( oldMdiMode == KMdi::TabPageMode || oldMdiMode == KMdi::IDEAlMode )
+ {
+ if ( !m_pDockbaseAreaOfDocumentViews )
+ {
+ m_pDockbaseAreaOfDocumentViews = createDockWidget( "mdiAreaCover", QPixmap(), 0L, "mdi_area_cover" );
+ m_pDockbaseAreaOfDocumentViews->setDockWindowTransient( this, true );
+ m_pDockbaseAreaOfDocumentViews->setEnableDocking( KDockWidget::DockNone );
+ m_pDockbaseAreaOfDocumentViews->setDockSite( KDockWidget::DockCorner );
+ m_pDockbaseAreaOfDocumentViews->setWidget( m_pMdi );
+ }
+ // set this dock to main view
+ setView( m_pDockbaseAreaOfDocumentViews );
+ setMainDockWidget( m_pDockbaseAreaOfDocumentViews );
+ }
+ // QApplication::sendPostedEvents(); //why do we need to empty the event queue?
+ if ( !parentWidget() )
+ {
+ //if we don't have a parent widget ( which i expect we wouldn't )
+ //make sure we take into account the size of the docks provided by
+ //QMainWindow
+ int topDockHeight = topDock() ? topDock()->height() : 0;
+ int bottomDockHeight = bottomDock() ? bottomDock()->height() : 0;
+ int menuBarHeight = hasMenuBar() ? menuBar()->height() : 0;
+ if ( m_pDocumentViews->count() != 0 )
+ setFixedHeight( height() - m_pDockbaseAreaOfDocumentViews->height() );
+ else
+ {
+ kdDebug(760) << k_funcinfo << "height is: " << height() << endl;
+ kdDebug(760) << k_funcinfo << "top dock height: " << topDockHeight << endl;
+ kdDebug(760) << k_funcinfo << "bottom dock height: " << bottomDockHeight << endl;
+ kdDebug(760) << k_funcinfo << "menu bar height: " << menuBarHeight << endl;
+ kdDebug(760) << k_funcinfo << "dock base area height: " << m_pDockbaseAreaOfDocumentViews->height() << endl;
+ setFixedHeight( topDockHeight + menuBarHeight );
+ }
+ }
+
+ //FIXME although i don't know what to fix
+ // 5. show the child views again
+ QPtrListIterator<KMdiChildView> kmdicvit( *m_pDocumentViews );
+ for ( kmdicvit.toFirst(); ( *kmdicvit ); ++kmdicvit )
+ {
+#ifdef Q_WS_X11
+ XSetTransientForHint( qt_xdisplay(), ( *kmdicvit )->winId(), winId() );
+#endif
+ ( *kmdicvit )->show();
+ }
+
+ // 6.) reset all memorized positions of the undocked ones and show them again
+ QValueList<QRect>::Iterator qvlqrit;
+ QValueList<QRect>::Iterator qvlEnd = positionList.end();
+ for ( kmdicvit.toFirst(), qvlqrit = positionList.begin() ; ( *kmdicvit ) && qvlqrit != qvlEnd; ++kmdicvit, ++qvlqrit )
+ {
+ ( *kmdicvit )->setGeometry( ( *qvlqrit ) );
+ ( *kmdicvit )->show();
+ }
+
+ m_pDockbaseAreaOfDocumentViews->setDockSite( KDockWidget::DockNone );
+ m_mdiMode = KMdi::ToplevelMode;
+
+ kdDebug(760) << k_funcinfo << "Switch to toplevel mode completed" << endl;
+ emit mdiModeHasBeenChangedTo( KMdi::ToplevelMode );
+
+}
+
+void KMdiMainFrm::finishToplevelMode()
+{
+ m_pDockbaseAreaOfDocumentViews->setDockSite( KDockWidget::DockCorner );
+}
+
+/**
+ * docks all view windows (Windows-like)
+ */
+void KMdiMainFrm::switchToChildframeMode()
+{
+ if ( m_mdiMode == KMdi::ChildframeMode )
+ {
+ emit mdiModeHasBeenChangedTo( KMdi::ChildframeMode );
+ return ;
+ }
+
+ QPtrList<KDockWidget> rootDockWidgetList;
+ QValueList<QRect> positionList;
+
+ if ( m_mdiMode == KMdi::TabPageMode )
+ {
+ kdDebug(760) << k_funcinfo << "finishing tab page mode" << endl;
+ // select the dockwidgets to be undocked and store their geometry
+ findRootDockWidgets( &rootDockWidgetList, &positionList );
+ kdDebug(760) << k_funcinfo << "Found " << rootDockWidgetList.count() << " widgets to undock" << endl;
+
+ // undock all these found oldest ancestors (being KDockWidgets)
+ QPtrListIterator<KDockWidget> it( rootDockWidgetList );
+ for ( ; ( *it ) ; ++it )
+ ( *it )->undock();
+
+ finishTabPageMode();
+ }
+ else if ( m_mdiMode == KMdi::ToplevelMode )
+ {
+ finishToplevelMode();
+ }
+ else if ( m_mdiMode == KMdi::IDEAlMode )
+ {
+ kdDebug(760) << k_funcinfo << "finishing ideal mode" << endl;
+ finishIDEAlMode( false );
+
+ // select the dockwidgets to be undocked and store their geometry
+ findRootDockWidgets( &rootDockWidgetList, &positionList );
+ kdDebug(760) << k_funcinfo << "Found " << rootDockWidgetList.count() << " widgets to undock" << endl;
+
+ // undock all these found oldest ancestors (being KDockWidgets)
+ QPtrListIterator<KDockWidget> it( rootDockWidgetList );
+ for ( ; ( *it ) ; ++it )
+ ( *it )->undock();
+
+ m_mdiMode = KMdi::TabPageMode;
+ finishTabPageMode();
+ m_mdiMode = KMdi::IDEAlMode;
+ }
+
+ if ( !m_pDockbaseAreaOfDocumentViews )
+ {
+ // cover KMdi's childarea by a dockwidget
+ m_pDockbaseAreaOfDocumentViews = createDockWidget( "mdiAreaCover", QPixmap(), 0L, "mdi_area_cover" );
+ m_pDockbaseAreaOfDocumentViews->setDockWindowTransient( this, true );
+ m_pDockbaseAreaOfDocumentViews->setEnableDocking( KDockWidget::DockNone );
+ m_pDockbaseAreaOfDocumentViews->setDockSite( KDockWidget::DockCorner );
+ m_pDockbaseAreaOfDocumentViews->setWidget( m_pMdi );
+ kdDebug(760) << k_funcinfo << "childarea is now covered by a dockwidget" << endl;
+ }
+
+ if ( m_pDockbaseAreaOfDocumentViews->isTopLevel() )
+ {
+ // set this dock to main view
+ setView( m_pDockbaseAreaOfDocumentViews );
+ setMainDockWidget( m_pDockbaseAreaOfDocumentViews );
+ m_pDockbaseAreaOfDocumentViews->setEnableDocking( KDockWidget::DockNone );
+ m_pDockbaseAreaOfDocumentViews->setDockSite( KDockWidget::DockCorner );
+ kdDebug(760) << k_funcinfo << "Dock base area has been set to the main view" << endl;
+ }
+ m_pDockbaseAreaOfDocumentViews->setWidget( m_pMdi ); //JW
+ m_pDockbaseAreaOfDocumentViews->show();
+
+ if ( ( m_mdiMode == KMdi::TabPageMode ) || ( m_mdiMode == KMdi::IDEAlMode ) )
+ {
+ kdDebug(760) << k_funcinfo << "trying to dock back the undock toolviews" << endl;
+ QPtrListIterator<KDockWidget> it( rootDockWidgetList );
+ for ( ; ( *it ); ++it )
+ ( *it )->dockBack();
+ }
+
+ if ( m_mdiMode == KMdi::ToplevelMode && m_pTempDockSession )
+ {
+ // restore the old dock scenario which we memorized at the time we switched to toplevel mode
+ kdDebug(760) << k_funcinfo << "Restoring old dock scenario memorized from toplevel mode" << endl;
+ QDomElement oldDockState = m_pTempDockSession->namedItem( "cur_dock_state" ).toElement();
+ readDockConfig( oldDockState );
+ }
+
+ KMdi::MdiMode oldMdiMode = m_mdiMode;
+ m_mdiMode = KMdi::ChildframeMode;
+
+ //FIXME although i don't know what to fix.
+ QPtrListIterator<KMdiChildView> it( *m_pDocumentViews );
+ for ( ; ( *it ); ++it )
+ {
+ KMdiChildView* pView = ( *it );
+ if ( !pView->isToolView() && pView->isAttached() )
+ attachWindow( pView, true );
+ }
+ for ( it.toFirst(); ( *it ); ++it )
+ {
+ KMdiChildView* pView = ( *it );
+ if ( !pView->isToolView() )
+ pView->show();
+ }
+ if ( ( oldMdiMode == KMdi::ToplevelMode ) && !parentWidget() )
+ {
+ setMinimumHeight( m_oldMainFrmMinHeight );
+ setMaximumHeight( m_oldMainFrmMaxHeight );
+ resize( width(), m_oldMainFrmHeight );
+ m_oldMainFrmHeight = 0;
+ kdDebug(760) << k_funcinfo << "left top level mode completely" << endl;
+ emit leftTopLevelMode();
+ }
+ emit mdiModeHasBeenChangedTo( KMdi::ChildframeMode );
+}
+
+void KMdiMainFrm::finishChildframeMode()
+{
+ // save the old dock scenario of the dockwidget-like tool views to a DOM tree
+ kdDebug(760) << k_funcinfo << "saving the current dock scenario" << endl;
+ delete m_pTempDockSession;
+ m_pTempDockSession = new QDomDocument( "docksession" );
+ QDomElement curDockState = m_pTempDockSession->createElement( "cur_dock_state" );
+ m_pTempDockSession->appendChild( curDockState );
+ writeDockConfig( curDockState );
+
+ // detach all non-tool-views to toplevel
+ kdDebug(760) << k_funcinfo << "detaching all document views and moving them to toplevel" << endl;
+ QPtrListIterator<KMdiChildView> it( *m_pDocumentViews );
+ for ( ; ( *it ); ++it )
+ {
+ KMdiChildView* pView = ( *it );
+ if ( pView->isToolView() )
+ continue;
+ if ( pView->isAttached() )
+ {
+ if ( pView->isMaximized() )
+ pView->mdiParent()->setGeometry( 0, 0, m_pMdi->width(), m_pMdi->height() );
+ detachWindow( pView, false );
+ }
+ }
+}
+
+/**
+ * Docks all view windows (Windows-like)
+ */
+void KMdiMainFrm::switchToTabPageMode()
+{
+ if ( m_mdiMode == KMdi::TabPageMode )
+ {
+ emit mdiModeHasBeenChangedTo( KMdi::TabPageMode );
+ return ; // nothing need to be done
+ }
+
+ switch( m_mdiMode )
+ {
+ case KMdi::ChildframeMode:
+ finishChildframeMode();
+ break;
+ case KMdi::ToplevelMode:
+ finishToplevelMode();
+ break;
+ case KMdi::IDEAlMode:
+ finishIDEAlMode( false );
+ emit mdiModeHasBeenChangedTo( KMdi::TabPageMode );
+ m_mdiMode = KMdi::TabPageMode;
+ return;
+ break;
+ default:
+ break;
+ }
+
+ setupTabbedDocumentViewSpace();
+ m_mdiMode = KMdi::TabPageMode;
+ if ( m_pCurrentWindow )
+ m_pCurrentWindow->setFocus();
+
+ m_pTaskBar->switchOn( false );
+
+ if ( m_pClose )
+ {
+ QObject::connect( m_pClose, SIGNAL( clicked() ), this, SLOT( closeViewButtonPressed() ) );
+ if ( m_pDocumentViews->count() > 0 )
+ m_pClose->show();
+ }
+ else
+ kdDebug(760) << "close button nonexistant. strange things might happen" << endl;
+
+ kdDebug(760) << "Switch to tab page mode complete" << endl;
+ emit mdiModeHasBeenChangedTo( KMdi::TabPageMode );
+}
+
+void KMdiMainFrm::finishTabPageMode()
+{
+ // if tabified, release all views from their docking covers
+ if ( m_mdiMode == KMdi::TabPageMode )
+ {
+ m_pClose->hide();
+ QObject::disconnect( m_pClose, SIGNAL( clicked() ), this, SLOT( closeViewButtonPressed() ) );
+
+ QPtrListIterator<KMdiChildView> it( *m_pDocumentViews );
+ for ( ; it.current(); ++it )
+ {
+ KMdiChildView* pView = it.current();
+ if ( pView->isToolView() )
+ continue;
+ kdDebug(760) << "KMdiMainFrm::finishTabPageMode: in loop" << endl;
+ QSize mins = pView->minimumSize();
+ QSize maxs = pView->maximumSize();
+ QSize sz = pView->size();
+ QWidget* pParent = pView->parentWidget();
+ QPoint p( pParent->mapToGlobal( pParent->pos() ) - pParent->pos() + m_undockPositioningOffset );
+ m_documentTabWidget->removePage( pView );
+ pView->reparent( 0, 0, p );
+ // pView->reparent(0,0,p);
+ pView->resize( sz );
+ pView->setMinimumSize( mins.width(), mins.height() );
+ pView->setMaximumSize( maxs.width(), maxs.height() );
+ // ((KDockWidget*)pParent)->undock(); // this destroys the dockwiget cover, too
+ // pParent->close();
+ // delete pParent;
+ // if (centralWidget() == pParent) {
+ // setCentralWidget(0L); // avoid dangling pointer
+ // }
+ }
+ delete m_documentTabWidget;
+ m_documentTabWidget = 0;
+ m_pTaskBar->switchOn( true );
+ }
+}
+
+
+
+void KMdiMainFrm::setupTabbedDocumentViewSpace()
+{
+ // resize to childframe mode size of the mainwindow if we were in toplevel mode
+ if ( ( m_mdiMode == KMdi::ToplevelMode ) && !parentWidget() )
+ {
+ setMinimumHeight( m_oldMainFrmMinHeight );
+ setMaximumHeight( m_oldMainFrmMaxHeight );
+ resize( width(), m_oldMainFrmHeight );
+ m_oldMainFrmHeight = 0;
+ //qDebug("TopLevelMode off");
+ emit leftTopLevelMode();
+ QApplication::sendPostedEvents();
+
+ // restore the old dock szenario which we memorized at the time we switched to toplevel mode
+ if ( m_pTempDockSession )
+ {
+ QDomElement oldDockState = m_pTempDockSession->namedItem( "cur_dock_state" ).toElement();
+ readDockConfig( oldDockState );
+ }
+ }
+
+#if 0
+ if ( m_pDockbaseOfTabPage != m_pDockbaseAreaOfDocumentViews )
+ {
+ delete m_pDockbaseOfTabPage;
+ m_pDockbaseOfTabPage = m_pDockbaseAreaOfDocumentViews;
+ }
+#endif
+ delete m_documentTabWidget;
+ m_documentTabWidget = new KMdiDocumentViewTabWidget( m_pDockbaseAreaOfDocumentViews );
+ connect( m_documentTabWidget, SIGNAL( currentChanged( QWidget* ) ), this, SLOT( slotDocCurrentChanged( QWidget* ) ) );
+ m_pDockbaseAreaOfDocumentViews->setWidget( m_documentTabWidget );
+ m_documentTabWidget->show();
+ QPtrListIterator<KMdiChildView> it4( *m_pDocumentViews );
+ for ( ; it4.current(); ++it4 )
+ {
+ KMdiChildView* pView = it4.current();
+ m_documentTabWidget->addTab( pView, pView->icon() ? *( pView->icon() ) : QPixmap(), pView->tabCaption() );
+ /*
+ connect(pView,SIGNAL(iconOrCaptionUdpated(QWidget*,QPixmap,const QString&)),
+ m_documentTabWidget,SLOT(updateView(QWidget*,QPixmap,const QString&)));
+ */
+ connect( pView, SIGNAL( iconUpdated( QWidget*, QPixmap ) ), m_documentTabWidget, SLOT( updateIconInView( QWidget*, QPixmap ) ) );
+ connect( pView, SIGNAL( captionUpdated( QWidget*, const QString& ) ), m_documentTabWidget, SLOT( updateCaptionInView( QWidget*, const QString& ) ) );
+
+ }
+}
+
+
+void KMdiMainFrm::setIDEAlModeStyle( int flags )
+{
+ d->m_styleIDEAlMode = flags; // see KMultiTabBar for the first 3 bits
+ if ( m_leftContainer )
+ {
+ KMdiDockContainer * tmpL = ( KMdiDockContainer* ) ( m_leftContainer->getWidget()->qt_cast( "KMdiDockContainer" ) );
+ if ( tmpL )
+ tmpL->setStyle( flags );
+ }
+
+ if ( m_rightContainer )
+ {
+ KMdiDockContainer * tmpR = ( KMdiDockContainer* ) ( m_rightContainer->getWidget()->qt_cast( "KMdiDockContainer" ) );
+ if ( tmpR )
+ tmpR->setStyle( flags );
+ }
+
+ if ( m_topContainer )
+ {
+ KMdiDockContainer * tmpT = ( KMdiDockContainer* ) ( m_topContainer->getWidget()->qt_cast( "KMdiDockContainer" ) );
+ if ( tmpT )
+ tmpT->setStyle( flags );
+ }
+
+ if ( m_bottomContainer )
+ {
+ KMdiDockContainer * tmpB = ( KMdiDockContainer* ) ( m_bottomContainer->getWidget()->qt_cast( "KMdiDockContainer" ) );
+ if ( tmpB )
+ tmpB->setStyle( flags );
+ }
+}
+
+void KMdiMainFrm::setToolviewStyle( int flag )
+{
+ if ( m_mdiMode == KMdi::IDEAlMode )
+ {
+ setIDEAlModeStyle( flag );
+ }
+ d->m_toolviewStyle = flag;
+ bool toolviewExists = false;
+ QMap<QWidget*, KMdiToolViewAccessor*>::Iterator it;
+ for ( it = m_pToolViews->begin(); it != m_pToolViews->end(); ++it )
+ {
+ KDockWidget *dockWidget = dynamic_cast<KDockWidget*>( it.data()->wrapperWidget() );
+ if ( dockWidget )
+ {
+ switch ( flag )
+ {
+ case KMdi::IconOnly:
+ dockWidget->setTabPageLabel( QString::null );
+ dockWidget->setPixmap( *( it.data()->wrappedWidget()->icon() ) );
+ break;
+ case KMdi::TextOnly:
+ dockWidget->setPixmap(); //FIXME: Does not hide the icon in the IDEAl mode.
+ dockWidget->setTabPageLabel( it.data()->wrappedWidget()->caption() );
+ break;
+ case KMdi::TextAndIcon:
+ dockWidget->setPixmap( *( it.data()->wrappedWidget()->icon() ) );
+ dockWidget->setTabPageLabel( it.data()->wrappedWidget()->caption() );
+ default:
+ break;
+ }
+ toolviewExists = true;
+ }
+ }
+
+ if ( toolviewExists )
+ {
+ //workaround for the above FIXME to make switching to TextOnly mode work in IDEAl as well. Be sure that this version of switch* is called.
+ if ( m_mdiMode == KMdi::IDEAlMode && flag == KMdi::TextOnly )
+ {
+ KMdiMainFrm::switchToTabPageMode();
+ KMdiMainFrm::switchToIDEAlMode();
+ }
+ else
+ {
+ writeDockConfig();
+ readDockConfig();
+ }
+ }
+}
+
+/**
+ * Docks all view windows (Windows-like)
+ */
+void KMdiMainFrm::switchToIDEAlMode()
+{
+ kdDebug(760) << k_funcinfo << "switching to IDEAl mode" << endl;
+
+ if ( m_mdiMode == KMdi::IDEAlMode )
+ {
+ emit mdiModeHasBeenChangedTo( KMdi::IDEAlMode );
+ return ; // nothing need to be done
+ }
+
+ switch( m_mdiMode )
+ {
+ case KMdi::ChildframeMode:
+ finishChildframeMode();
+ break;
+ case KMdi::ToplevelMode:
+ finishToplevelMode();
+ break;
+ case KMdi::TabPageMode:
+ m_mdiMode = KMdi::IDEAlMode;
+ setupToolViewsForIDEALMode();
+ emit mdiModeHasBeenChangedTo( KMdi::IDEAlMode );
+ return;
+ break;
+ default:
+ break;
+ }
+
+ setupTabbedDocumentViewSpace();
+ m_mdiMode = KMdi::IDEAlMode;
+ setupToolViewsForIDEALMode();
+
+ if ( m_pCurrentWindow )
+ m_pCurrentWindow->setFocus();
+
+ m_pTaskBar->switchOn( false );
+
+ if ( m_pClose )
+ {
+ QObject::connect( m_pClose, SIGNAL( clicked() ), this, SLOT( closeViewButtonPressed() ) );
+ if ( m_pDocumentViews->count() > 0 )
+ m_pClose->show();
+ }
+ else
+ kdWarning(760) << k_funcinfo << "close button pointer does not exist!" << endl;
+
+ kdDebug(760) << k_funcinfo << "switch to IDEAl mode complete" << endl;
+
+ emit mdiModeHasBeenChangedTo( KMdi::IDEAlMode );
+}
+
+
+void KMdiMainFrm::dockToolViewsIntoContainers( QPtrList<KDockWidget>& widgetsToReparent, KDockWidget *container )
+{
+ QPtrListIterator<KDockWidget> it( widgetsToReparent );
+ for ( ; ( *it ); ++it )
+ {
+ ( *it )->manualDock( container, KDockWidget::DockCenter, 20 );
+ ( *it )->loseFormerBrotherDockWidget();
+ }
+}
+
+void KMdiMainFrm::findToolViewsDockedToMain( QPtrList<KDockWidget>* list, KDockWidget::DockPosition dprtmw )
+{
+ KDockWidget* mainDock = getMainDockWidget();
+ if ( mainDock->parentDockTabGroup() )
+ {
+ mainDock = dynamic_cast<KDockWidget*>( mainDock->parentDockTabGroup()->parent() );
+ // FIXME: will likely crash below due to unchecked cast
+ }
+
+ if ( !mainDock )
+ {
+ kdDebug(760) << k_funcinfo << "mainDock invalid. No main dock widget found." << endl;
+ return;
+ }
+
+ KDockWidget* widget = mainDock->findNearestDockWidget( dprtmw );
+ if ( widget && widget->parentDockTabGroup() )
+ {
+ widget = static_cast<KDockWidget*>( widget->parentDockTabGroup() ->parent() );
+
+ if ( widget )
+ {
+ KDockTabGroup* tg = dynamic_cast<KDockTabGroup*>( widget->getWidget() );
+ if ( tg )
+ {
+ kdDebug(760) << k_funcinfo << "KDockTabGroup found" << endl;
+ for ( int i = 0;i < tg->count();i++ )
+ list->append( static_cast<KDockWidget*>( tg->page( i ) ) );
+ }
+ else
+ list->append( widget );
+ }
+ else
+ kdDebug(760) << k_funcinfo << "no widget found" << endl;
+ }
+ else
+ kdDebug(760) << "No main dock widget found" << endl;
+}
+
+
+void KMdiMainFrm::setupToolViewsForIDEALMode()
+{
+ m_leftContainer = createDockWidget( "KMdiDock::leftDock", SmallIcon( "misc" ), 0L, "Left Dock" );
+ m_rightContainer = createDockWidget( "KMdiDock::rightDock", SmallIcon( "misc" ), 0L, "Right Dock" );
+ m_topContainer = createDockWidget( "KMdiDock::topDock", SmallIcon( "misc" ), 0L, "Top Dock" );
+ m_bottomContainer = createDockWidget( "KMdiDock::bottomDock", SmallIcon( "misc" ), 0L, "Bottom Dock" );
+
+ KDockWidget *mainDock = getMainDockWidget();
+ KDockWidget *w = mainDock;
+ if ( mainDock->parentDockTabGroup() )
+ w = static_cast<KDockWidget*>( mainDock->parentDockTabGroup()->parent() );
+
+ QPtrList<KDockWidget> leftReparentWidgets;
+ QPtrList<KDockWidget> rightReparentWidgets;
+ QPtrList<KDockWidget> bottomReparentWidgets;
+ QPtrList<KDockWidget> topReparentWidgets;
+
+ if ( mainDock->parentDockTabGroup() )
+ mainDock = static_cast<KDockWidget*>( mainDock->parentDockTabGroup() ->parent() );
+
+ findToolViewsDockedToMain( &leftReparentWidgets, KDockWidget::DockLeft );
+ findToolViewsDockedToMain( &rightReparentWidgets, KDockWidget::DockRight );
+ findToolViewsDockedToMain( &bottomReparentWidgets, KDockWidget::DockBottom );
+ findToolViewsDockedToMain( &topReparentWidgets, KDockWidget::DockTop );
+
+ mainDock->setEnableDocking( KDockWidget::DockNone ); //::DockCorner);
+ mainDock->setDockSite( KDockWidget::DockCorner );
+
+
+ KMdiDockContainer *tmpDC;
+ m_leftContainer->setWidget( tmpDC = new KMdiDockContainer( m_leftContainer, this, KDockWidget::DockLeft, d->m_styleIDEAlMode ) );
+ m_leftContainer->setEnableDocking( KDockWidget::DockLeft );
+ m_leftContainer->manualDock( mainDock, KDockWidget::DockLeft, 20 );
+ tmpDC->init();
+ if ( m_mdiGUIClient )
+ connect ( this, SIGNAL( toggleLeft() ), tmpDC, SLOT( toggle() ) );
+ connect( this, SIGNAL( collapseOverlapContainers() ), tmpDC, SLOT( collapseOverlapped() ) );
+ connect( tmpDC, SIGNAL( activated( KMdiDockContainer* ) ), this, SLOT( setActiveToolDock( KMdiDockContainer* ) ) );
+ connect( tmpDC, SIGNAL( deactivated( KMdiDockContainer* ) ), this, SLOT( removeFromActiveDockList( KMdiDockContainer* ) ) );
+
+ m_rightContainer->setWidget( tmpDC = new KMdiDockContainer( m_rightContainer, this, KDockWidget::DockRight, d->m_styleIDEAlMode ) );
+ m_rightContainer->setEnableDocking( KDockWidget::DockRight );
+ m_rightContainer->manualDock( mainDock, KDockWidget::DockRight, 80 );
+ tmpDC->init();
+ if ( m_mdiGUIClient )
+ connect ( this, SIGNAL( toggleRight() ), tmpDC, SLOT( toggle() ) );
+ connect( this, SIGNAL( collapseOverlapContainers() ), tmpDC, SLOT( collapseOverlapped() ) );
+ connect( tmpDC, SIGNAL( activated( KMdiDockContainer* ) ), this, SLOT( setActiveToolDock( KMdiDockContainer* ) ) );
+ connect( tmpDC, SIGNAL( deactivated( KMdiDockContainer* ) ), this, SLOT( removeFromActiveDockList( KMdiDockContainer* ) ) );
+
+ m_topContainer->setWidget( tmpDC = new KMdiDockContainer( m_topContainer, this, KDockWidget::DockTop, d->m_styleIDEAlMode ) );
+ m_topContainer->setEnableDocking( KDockWidget::DockTop );
+ m_topContainer->manualDock( mainDock, KDockWidget::DockTop, 20 );
+ tmpDC->init();
+ if ( m_mdiGUIClient )
+ connect ( this, SIGNAL( toggleTop() ), tmpDC, SLOT( toggle() ) );
+ connect( this, SIGNAL( collapseOverlapContainers() ), tmpDC, SLOT( collapseOverlapped() ) );
+ connect( tmpDC, SIGNAL( activated( KMdiDockContainer* ) ), this, SLOT( setActiveToolDock( KMdiDockContainer* ) ) );
+ connect( tmpDC, SIGNAL( deactivated( KMdiDockContainer* ) ), this, SLOT( removeFromActiveDockList( KMdiDockContainer* ) ) );
+
+ m_bottomContainer->setWidget( tmpDC = new KMdiDockContainer( m_bottomContainer, this, KDockWidget::DockBottom, d->m_styleIDEAlMode ) );
+ m_bottomContainer->setEnableDocking( KDockWidget::DockBottom );
+ m_bottomContainer->manualDock( mainDock, KDockWidget::DockBottom, 80 );
+ tmpDC->init();
+ if ( m_mdiGUIClient )
+ connect ( this, SIGNAL( toggleBottom() ), tmpDC, SLOT( toggle() ) );
+ connect( this, SIGNAL( collapseOverlapContainers() ), tmpDC, SLOT( collapseOverlapped() ) );
+ connect( tmpDC, SIGNAL( activated( KMdiDockContainer* ) ), this, SLOT( setActiveToolDock( KMdiDockContainer* ) ) );
+ connect( tmpDC, SIGNAL( deactivated( KMdiDockContainer* ) ), this, SLOT( removeFromActiveDockList( KMdiDockContainer* ) ) );
+
+ m_leftContainer->setDockSite( KDockWidget::DockCenter );
+ m_rightContainer->setDockSite( KDockWidget::DockCenter );
+ m_topContainer->setDockSite( KDockWidget::DockCenter );
+ m_bottomContainer->setDockSite( KDockWidget::DockCenter );
+
+ dockToolViewsIntoContainers( leftReparentWidgets, m_leftContainer );
+ dockToolViewsIntoContainers( rightReparentWidgets, m_rightContainer );
+ dockToolViewsIntoContainers( bottomReparentWidgets, m_bottomContainer );
+ dockToolViewsIntoContainers( topReparentWidgets, m_topContainer );
+
+
+ dockManager->setSpecialLeftDockContainer( m_leftContainer );
+ dockManager->setSpecialRightDockContainer( m_rightContainer );
+ dockManager->setSpecialTopDockContainer( m_topContainer );
+ dockManager->setSpecialBottomDockContainer( m_bottomContainer );
+
+
+ ( ( KMdiDockContainer* ) ( m_leftContainer->getWidget() ) ) ->hideIfNeeded();
+ ( ( KMdiDockContainer* ) ( m_rightContainer->getWidget() ) ) ->hideIfNeeded();
+ ( ( KMdiDockContainer* ) ( m_topContainer->getWidget() ) ) ->hideIfNeeded();
+ ( ( KMdiDockContainer* ) ( m_bottomContainer->getWidget() ) ) ->hideIfNeeded();
+
+}
+
+
+
+void KMdiMainFrm::finishIDEAlMode( bool full )
+{
+ // if tabified, release all views from their docking covers
+ if ( m_mdiMode == KMdi::IDEAlMode )
+ {
+ assert( m_pClose );
+ m_pClose->hide();
+ QObject::disconnect( m_pClose, SIGNAL( clicked() ), this, SLOT( closeViewButtonPressed() ) );
+
+
+ QStringList leftNames;
+ leftNames = prepareIdealToTabs( m_leftContainer );
+ int leftWidth = m_leftContainer->width();
+
+ QStringList rightNames;
+ rightNames = prepareIdealToTabs( m_rightContainer );
+ int rightWidth = m_rightContainer->width();
+
+ QStringList topNames;
+ topNames = prepareIdealToTabs( m_topContainer );
+ int topHeight = m_topContainer->height();
+
+ QStringList bottomNames;
+ bottomNames = prepareIdealToTabs( m_bottomContainer );
+ int bottomHeight = m_bottomContainer->height();
+
+
+ kdDebug(760) << "leftNames" << leftNames << endl;
+ kdDebug(760) << "rightNames" << rightNames << endl;
+ kdDebug(760) << "topNames" << topNames << endl;
+ kdDebug(760) << "bottomNames" << bottomNames << endl;
+
+ delete m_leftContainer;
+ m_leftContainer = 0;
+ delete m_rightContainer;
+ m_rightContainer = 0;
+ delete m_bottomContainer;
+ m_bottomContainer = 0;
+ delete m_topContainer;
+ m_topContainer = 0;
+
+
+ idealToolViewsToStandardTabs( bottomNames, KDockWidget::DockBottom, bottomHeight );
+ idealToolViewsToStandardTabs( leftNames, KDockWidget::DockLeft, leftWidth );
+ idealToolViewsToStandardTabs( rightNames, KDockWidget::DockRight, rightWidth );
+ idealToolViewsToStandardTabs( topNames, KDockWidget::DockTop, topHeight );
+
+ QApplication::sendPostedEvents();
+
+ if ( !full )
+ return ;
+
+ QPtrListIterator<KMdiChildView> it( *m_pDocumentViews );
+ for ( ; it.current(); ++it )
+ {
+ KMdiChildView* pView = it.current();
+ if ( pView->isToolView() )
+ continue;
+ QSize mins = pView->minimumSize();
+ QSize maxs = pView->maximumSize();
+ QSize sz = pView->size();
+ QWidget* pParent = pView->parentWidget();
+ QPoint p( pParent->mapToGlobal( pParent->pos() ) - pParent->pos() + m_undockPositioningOffset );
+ pView->reparent( 0, 0, p );
+ pView->reparent( 0, 0, p );
+ pView->resize( sz );
+ pView->setMinimumSize( mins.width(), mins.height() );
+ pView->setMaximumSize( maxs.width(), maxs.height() );
+ KDockWidget* pDockW = 0L;
+ // find the oldest ancestor of the current dockwidget that can be undocked
+ do
+ {
+ if ( pParent->inherits( "KDockWidget" ) || pParent->inherits( "KDockWidget_Compat::KDockWidget" ) )
+ {
+ pDockW = ( KDockWidget* ) pParent;
+ pDockW->undock(); // this destroys the dockwiget cover, too
+ if ( pParent != m_pDockbaseAreaOfDocumentViews )
+ {
+ pParent->close();
+ delete pParent;
+ }
+ }
+ else
+ {
+ pParent = pParent->parentWidget();
+ }
+ }
+ while ( pParent && !pDockW );
+ if ( centralWidget() == pParent )
+ {
+ setCentralWidget( 0L ); // avoid dangling pointer
+ }
+ }
+ m_pTaskBar->switchOn( true );
+
+ }
+
+}
+
+QStringList KMdiMainFrm::prepareIdealToTabs( KDockWidget* container )
+{
+ KDockContainer * pDW = dynamic_cast<KDockContainer*>( container->getWidget() );
+ QStringList widgetNames = ( ( KMdiDockContainer* ) pDW ) ->containedWidgets();
+ for ( QStringList::iterator it = widgetNames.begin();it != widgetNames.end();++it )
+ {
+ KDockWidget* dw = ( KDockWidget* ) manager() ->getDockWidgetFromName( *it );
+ dw->undock();
+ dw->setLatestKDockContainer( 0 );
+ dw->loseFormerBrotherDockWidget();
+ }
+ return widgetNames;
+}
+
+void KMdiMainFrm::idealToolViewsToStandardTabs( QStringList widgetNames, KDockWidget::DockPosition pos, int size )
+{
+ Q_UNUSED( size )
+
+ KDockWidget * mainDock = getMainDockWidget();
+ if ( mainDock->parentDockTabGroup() )
+ {
+ mainDock = static_cast<KDockWidget*>( mainDock->parentDockTabGroup() ->parent() );
+ }
+
+ if ( widgetNames.count() > 0 )
+ {
+ QStringList::iterator it = widgetNames.begin();
+ KDockWidget *dwpd = manager() ->getDockWidgetFromName( *it );
+ if ( !dwpd )
+ {
+ kdDebug(760) << "Fatal error in finishIDEAlMode" << endl;
+ return ;
+ }
+ dwpd->manualDock( mainDock, pos, 20 );
+ ++it;
+ for ( ;it != widgetNames.end();++it )
+ {
+ KDockWidget *tmpdw = manager() ->getDockWidgetFromName( *it );
+ if ( !tmpdw )
+ {
+ kdDebug(760) << "Fatal error in finishIDEAlMode" << endl;
+ return ;
+ }
+ tmpdw->manualDock( dwpd, KDockWidget::DockCenter, 20 );
+ }
+
+#if 0
+ QWidget *wid = dwpd->parentDockTabGroup();
+ if ( !wid )
+ wid = dwpd;
+ wid->setGeometry( 0, 0, 20, 20 );
+ /* wid->resize(
+ ((pos==KDockWidget::DockLeft) || (pos==KDockWidget::DockRight))?size:wid->width(),
+ ((pos==KDockWidget::DockLeft) || (pos==KDockWidget::DockRight))?wid->height():size);
+ */
+#endif
+
+ }
+
+}
+
+
+/**
+ * redirect the signal for insertion of buttons to an own slot
+ * that means: If the menubar (where the buttons should be inserted) is given,
+ * QextMDI can insert them automatically.
+ * Otherwise only signals can be emitted to tell the outside that
+ * someone must do this job itself.
+ */
+void KMdiMainFrm::setMenuForSDIModeSysButtons( KMenuBar* pMenuBar )
+{
+ if ( m_bSDIApplication ) // there are no buttons in the menubar in this mode (although the view is always maximized)
+ return ;
+
+ m_pMainMenuBar = pMenuBar;
+ if ( m_pMainMenuBar == 0L )
+ return ; // use setMenuForSDIModeSysButtons( 0L) for unsetting the external main menu!
+
+ if ( !m_pUndock )
+ m_pUndock = new QToolButton( pMenuBar );
+ if ( !m_pRestore )
+ m_pRestore = new QToolButton( pMenuBar );
+ if ( !m_pMinimize )
+ m_pMinimize = new QToolButton( pMenuBar );
+ if ( !m_pClose )
+ m_pClose = new QToolButton( pMenuBar );
+ m_pUndock->setAutoRaise( false );
+ m_pMinimize->setAutoRaise( false );
+ m_pRestore->setAutoRaise( false );
+ m_pClose->setAutoRaise( false );
+
+ setSysButtonsAtMenuPosition();
+
+ delete m_pUndockButtonPixmap;
+ delete m_pMinButtonPixmap;
+ delete m_pRestoreButtonPixmap;
+ delete m_pCloseButtonPixmap;
+ // create the decoration pixmaps
+ if ( frameDecorOfAttachedViews() == KMdi::Win95Look )
+ {
+ m_pUndockButtonPixmap = new QPixmap( win_undockbutton );
+ m_pMinButtonPixmap = new QPixmap( win_minbutton );
+ m_pRestoreButtonPixmap = new QPixmap( win_restorebutton );
+ m_pCloseButtonPixmap = new QPixmap( win_closebutton );
+ }
+ else if ( frameDecorOfAttachedViews() == KMdi::KDE1Look )
+ {
+ m_pUndockButtonPixmap = new QPixmap( kde_undockbutton );
+ m_pMinButtonPixmap = new QPixmap( kde_minbutton );
+ m_pRestoreButtonPixmap = new QPixmap( kde_restorebutton );
+ m_pCloseButtonPixmap = new QPixmap( kde_closebutton );
+ m_pUndock->setAutoRaise( true );
+ m_pMinimize->setAutoRaise( true );
+ m_pRestore->setAutoRaise( true );
+ m_pClose->setAutoRaise( true );
+ }
+ else if ( frameDecorOfAttachedViews() == KMdi::KDELook )
+ {
+ m_pUndockButtonPixmap = new QPixmap( kde2_undockbutton );
+ m_pMinButtonPixmap = new QPixmap( kde2_minbutton );
+ m_pRestoreButtonPixmap = new QPixmap( kde2_restorebutton );
+ m_pCloseButtonPixmap = new QPixmap( kde2_closebutton );
+ }
+ else
+ { // kde2laptop look
+ m_pUndockButtonPixmap = new QPixmap( kde2laptop_undockbutton );
+ m_pMinButtonPixmap = new QPixmap( kde2laptop_minbutton );
+ m_pRestoreButtonPixmap = new QPixmap( kde2laptop_restorebutton );
+ m_pCloseButtonPixmap = new QPixmap( kde2laptop_closebutton );
+ }
+
+ m_pUndock->hide();
+ m_pMinimize->hide();
+ m_pRestore->hide();
+ m_pClose->hide();
+
+ m_pUndock->setPixmap( *m_pUndockButtonPixmap );
+ m_pMinimize->setPixmap( *m_pMinButtonPixmap );
+ m_pRestore->setPixmap( *m_pRestoreButtonPixmap );
+ m_pClose->setPixmap( *m_pCloseButtonPixmap );
+}
+
+void KMdiMainFrm::setSysButtonsAtMenuPosition()
+{
+ if ( m_pMainMenuBar == 0L )
+ return ;
+ if ( m_pMainMenuBar->parentWidget() == 0L )
+ return ;
+
+ int menuW = m_pMainMenuBar->parentWidget() ->width();
+ int h;
+ int y;
+ if ( frameDecorOfAttachedViews() == KMdi::Win95Look )
+ h = 16;
+ else if ( frameDecorOfAttachedViews() == KMdi::KDE1Look )
+ h = 20;
+ else if ( frameDecorOfAttachedViews() == KMdi::KDELook )
+ h = 16;
+ else
+ h = 14;
+ y = m_pMainMenuBar->height() / 2 - h / 2;
+
+ if ( frameDecorOfAttachedViews() == KMdi::KDELaptopLook )
+ {
+ int w = 27;
+ m_pUndock->setGeometry( ( menuW - ( w * 3 ) - 5 ), y, w, h );
+ m_pMinimize->setGeometry( ( menuW - ( w * 2 ) - 5 ), y, w, h );
+ m_pRestore->setGeometry( ( menuW - w - 5 ), y, w, h );
+ }
+ else
+ {
+ m_pUndock->setGeometry( ( menuW - ( h * 4 ) - 5 ), y, h, h );
+ m_pMinimize->setGeometry( ( menuW - ( h * 3 ) - 5 ), y, h, h );
+ m_pRestore->setGeometry( ( menuW - ( h * 2 ) - 5 ), y, h, h );
+ m_pClose->setGeometry( ( menuW - h - 5 ), y, h, h );
+ }
+}
+
+/** Activates the next open view */
+void KMdiMainFrm::activateNextWin()
+{
+ KMdiIterator<KMdiChildView*>* it = createIterator();
+ KMdiChildView* aWin = activeWindow();
+ for ( it->first(); !it->isDone(); it->next() )
+ {
+ if ( it->currentItem() == aWin )
+ {
+ it->next();
+ if ( !it->currentItem() )
+ {
+ it->first();
+ }
+ if ( it->currentItem() )
+ {
+ activateView( it->currentItem() );
+ }
+ break;
+ }
+ }
+ delete it;
+}
+
+/** Activates the previous open view */
+void KMdiMainFrm::activatePrevWin()
+{
+ KMdiIterator<KMdiChildView*>* it = createIterator();
+ KMdiChildView* aWin = activeWindow();
+ for ( it->first(); !it->isDone(); it->next() )
+ {
+ if ( it->currentItem() == aWin )
+ {
+ it->prev();
+ if ( !it->currentItem() )
+ {
+ it->last();
+ }
+ if ( it->currentItem() )
+ {
+ activateView( it->currentItem() );
+ }
+ break;
+ }
+ }
+ delete it;
+}
+
+/** Activates the view we accessed the most time ago */
+void KMdiMainFrm::activateFirstWin()
+{
+ m_bSwitching= true; // flag that we are currently switching between windows
+ KMdiIterator<KMdiChildView*>* it = createIterator();
+ QMap<QDateTime, KMdiChildView*> m;
+ for ( it->first(); !it->isDone(); it->next() )
+ {
+ m.insert( it->currentItem() ->getTimeStamp(), it->currentItem() );
+ }
+
+ if ( !activeWindow() )
+ return ;
+
+ QDateTime current = activeWindow() ->getTimeStamp();
+ QMap<QDateTime, KMdiChildView*>::iterator pos( m.find( current ) );
+ QMap<QDateTime, KMdiChildView*>::iterator newPos = pos;
+ if ( pos != m.end() )
+ {
+ ++newPos;
+ }
+ if ( newPos != m.end() )
+ { // look ahead
+ ++pos;
+ }
+ else
+ {
+ pos = m.begin();
+ }
+ activateView( pos.data() );
+ delete it;
+}
+
+/** Activates the previously accessed view before this one was activated */
+void KMdiMainFrm::activateLastWin()
+{
+ m_bSwitching= true; // flag that we are currently switching between windows
+ KMdiIterator<KMdiChildView*>* it = createIterator();
+ QMap<QDateTime, KMdiChildView*> m;
+ for ( it->first(); !it->isDone(); it->next() )
+ {
+ m.insert( it->currentItem() ->getTimeStamp(), it->currentItem() );
+ }
+
+ if ( !activeWindow() )
+ return ;
+
+ QDateTime current = activeWindow() ->getTimeStamp();
+ QMap<QDateTime, KMdiChildView*>::iterator pos( m.find( current ) );
+ if ( pos != m.begin() )
+ {
+ --pos;
+ }
+ else
+ {
+ pos = m.end();
+ --pos;
+ }
+ activateView( pos.data() );
+ delete it;
+}
+
+/** Activates the view with a certain index (TabPage mode only) */
+void KMdiMainFrm::activateView( int index )
+{
+ KMdiChildView * pView = m_pDocumentViews->first();
+ for ( int i = 0; pView && ( i < index ); i++ )
+ {
+ pView = m_pDocumentViews->next();
+ }
+ if ( pView )
+ {
+ pView->activate();
+ }
+}
+
+/** turns the system buttons for maximize mode (SDI mode) on, and connects them with the current child frame */
+void KMdiMainFrm::setEnableMaximizedChildFrmMode( bool enableMaxChildFrameMode )
+{
+ if ( enableMaxChildFrameMode )
+ {
+ kdDebug(760) << k_funcinfo << "Turning on maximized child frame mode" << endl;
+ m_bMaximizedChildFrmMode = true;
+
+ KMdiChildFrm* pCurrentChild = m_pMdi->topChild();
+
+ //If we have no child or there is no menubar, we do nothing
+ if ( !pCurrentChild || !m_pMainMenuBar )
+ return ;
+
+ QObject::connect( m_pUndock, SIGNAL( clicked() ), pCurrentChild, SLOT( undockPressed() ) );
+ QObject::connect( m_pMinimize, SIGNAL( clicked() ), pCurrentChild, SLOT( minimizePressed() ) );
+ QObject::connect( m_pRestore, SIGNAL( clicked() ), pCurrentChild, SLOT( maximizePressed() ) );
+ m_pMinimize->show();
+ m_pUndock->show();
+ m_pRestore->show();
+
+ if ( frameDecorOfAttachedViews() == KMdi::KDELaptopLook )
+ {
+ m_pMainMenuBar->insertItem( QPixmap( kde2laptop_closebutton_menu ), m_pMdi->topChild(), SLOT( closePressed() ), 0, -1, 0 );
+ }
+ else
+ {
+ m_pMainMenuBar->insertItem( *pCurrentChild->icon(), pCurrentChild->systemMenu(), -1, 0 );
+ if ( m_pClose )
+ {
+ QObject::connect( m_pClose, SIGNAL( clicked() ), pCurrentChild, SLOT( closePressed() ) );
+ m_pClose->show();
+ }
+ else
+ kdDebug(760) << k_funcinfo << "no close button. things won't behave correctly" << endl;
+ }
+ }
+ else
+ {
+ if ( !m_bMaximizedChildFrmMode )
+ return ; // already set, nothing to do
+
+ kdDebug(760) << k_funcinfo << "Turning off maximized child frame mode" << endl;
+ m_bMaximizedChildFrmMode = false;
+
+ KMdiChildFrm* pFrmChild = m_pMdi->topChild();
+ if ( pFrmChild && pFrmChild->m_pClient && pFrmChild->state() == KMdiChildFrm::Maximized )
+ {
+ pFrmChild->m_pClient->restore();
+ switchOffMaximizeModeForMenu( pFrmChild );
+ }
+ }
+}
+
+/** turns the system buttons for maximize mode (SDI mode) off, and disconnects them */
+void KMdiMainFrm::switchOffMaximizeModeForMenu( KMdiChildFrm* oldChild )
+{
+ // if there is no menubar given, those system buttons aren't possible
+ if ( !m_pMainMenuBar )
+ return ;
+
+ m_pMainMenuBar->removeItem( m_pMainMenuBar->idAt( 0 ) );
+
+ if ( oldChild )
+ {
+ Q_ASSERT( m_pClose );
+ QObject::disconnect( m_pUndock, SIGNAL( clicked() ), oldChild, SLOT( undockPressed() ) );
+ QObject::disconnect( m_pMinimize, SIGNAL( clicked() ), oldChild, SLOT( minimizePressed() ) );
+ QObject::disconnect( m_pRestore, SIGNAL( clicked() ), oldChild, SLOT( maximizePressed() ) );
+ QObject::disconnect( m_pClose, SIGNAL( clicked() ), oldChild, SLOT( closePressed() ) );
+ }
+ m_pUndock->hide();
+ m_pMinimize->hide();
+ m_pRestore->hide();
+ m_pClose->hide();
+}
+
+/** reconnects the system buttons form maximize mode (SDI mode) with the new child frame */
+void KMdiMainFrm::updateSysButtonConnections( KMdiChildFrm* oldChild, KMdiChildFrm* newChild )
+{
+ //qDebug("updateSysButtonConnections");
+ // if there is no menubar given, those system buttons aren't possible
+ if ( !m_pMainMenuBar )
+ return ;
+
+ if ( newChild )
+ {
+ if ( frameDecorOfAttachedViews() == KMdi::KDELaptopLook )
+ m_pMainMenuBar->insertItem( QPixmap( kde2laptop_closebutton_menu ), newChild, SLOT( closePressed() ), 0, -1, 0 );
+ else
+ m_pMainMenuBar->insertItem( *newChild->icon(), newChild->systemMenu(), -1, 0 );
+ }
+
+ if ( oldChild )
+ {
+ m_pMainMenuBar->removeItem( m_pMainMenuBar->idAt( 1 ) );
+ Q_ASSERT( m_pClose );
+ QObject::disconnect( m_pUndock, SIGNAL( clicked() ), oldChild, SLOT( undockPressed() ) );
+ QObject::disconnect( m_pMinimize, SIGNAL( clicked() ), oldChild, SLOT( minimizePressed() ) );
+ QObject::disconnect( m_pRestore, SIGNAL( clicked() ), oldChild, SLOT( maximizePressed() ) );
+ QObject::disconnect( m_pClose, SIGNAL( clicked() ), oldChild, SLOT( closePressed() ) );
+ }
+ if ( newChild )
+ {
+ Q_ASSERT( m_pClose );
+ QObject::connect( m_pUndock, SIGNAL( clicked() ), newChild, SLOT( undockPressed() ) );
+ QObject::connect( m_pMinimize, SIGNAL( clicked() ), newChild, SLOT( minimizePressed() ) );
+ QObject::connect( m_pRestore, SIGNAL( clicked() ), newChild, SLOT( maximizePressed() ) );
+ QObject::connect( m_pClose, SIGNAL( clicked() ), newChild, SLOT( closePressed() ) );
+ }
+}
+
+/** Shows the view taskbar. This should be connected with your "View" menu. */
+bool KMdiMainFrm::isViewTaskBarOn()
+{
+ if ( m_pTaskBar )
+ return m_pTaskBar->isSwitchedOn();
+ else
+ return false;
+}
+
+/** Shows the view taskbar. This should be connected with your "View" menu. */
+void KMdiMainFrm::showViewTaskBar()
+{
+ if ( m_pTaskBar )
+ m_pTaskBar->switchOn( true );
+}
+
+/** Hides the view taskbar. This should be connected with your "View" menu. */
+void KMdiMainFrm::hideViewTaskBar()
+{
+ if ( m_pTaskBar )
+ m_pTaskBar->switchOn( false );
+}
+
+//=============== fillWindowMenu ===============//
+void KMdiMainFrm::fillWindowMenu()
+{
+ bool tabPageMode = false;
+ if ( m_mdiMode == KMdi::TabPageMode )
+ tabPageMode = true;
+
+ bool IDEAlMode = false;
+ if ( m_mdiMode == KMdi::IDEAlMode )
+ IDEAlMode = true;
+
+ bool noViewOpened = false;
+ if ( m_pDocumentViews->isEmpty() )
+ noViewOpened = true;
+
+ // construct the menu and its submenus
+ if ( !m_bClearingOfWindowMenuBlocked )
+ m_pWindowMenu->clear();
+
+ d->closeWindowAction->plug(m_pWindowMenu);
+
+ int closeAllId = m_pWindowMenu->insertItem( i18n( "Close &All" ), this, SLOT( closeAllViews() ) );
+ if ( noViewOpened )
+ {
+ d->closeWindowAction->setEnabled(false);
+ m_pWindowMenu->setItemEnabled( closeAllId, false );
+ }
+
+ if ( !tabPageMode && !IDEAlMode )
+ {
+ int iconifyId = m_pWindowMenu->insertItem( i18n( "&Minimize All" ), this, SLOT( iconifyAllViews() ) );
+ if ( noViewOpened )
+ m_pWindowMenu->setItemEnabled( iconifyId, false );
+ }
+
+ m_pWindowMenu->insertSeparator();
+ m_pWindowMenu->insertItem( i18n( "&MDI Mode" ), m_pMdiModeMenu );
+ m_pMdiModeMenu->clear();
+ m_pMdiModeMenu->insertItem( i18n( "&Toplevel Mode" ), this, SLOT( switchToToplevelMode() ) );
+ m_pMdiModeMenu->insertItem( i18n( "C&hildframe Mode" ), this, SLOT( switchToChildframeMode() ) );
+ m_pMdiModeMenu->insertItem( i18n( "Ta&b Page Mode" ), this, SLOT( switchToTabPageMode() ) );
+ m_pMdiModeMenu->insertItem( i18n( "I&DEAl Mode" ), this, SLOT( switchToIDEAlMode() ) );
+ switch ( m_mdiMode )
+ {
+ case KMdi::ToplevelMode:
+ m_pMdiModeMenu->setItemChecked( m_pMdiModeMenu->idAt( 0 ), true );
+ break;
+ case KMdi::ChildframeMode:
+ m_pMdiModeMenu->setItemChecked( m_pMdiModeMenu->idAt( 1 ), true );
+ break;
+ case KMdi::TabPageMode:
+ m_pMdiModeMenu->setItemChecked( m_pMdiModeMenu->idAt( 2 ), true );
+ break;
+ case KMdi::IDEAlMode:
+ m_pMdiModeMenu->setItemChecked( m_pMdiModeMenu->idAt( 3 ), true );
+ break;
+ default:
+ break;
+ }
+
+ m_pWindowMenu->insertSeparator();
+ if ( !tabPageMode && !IDEAlMode )
+ {
+ int placMenuId = m_pWindowMenu->insertItem( i18n( "&Tile" ), m_pPlacingMenu );
+ m_pPlacingMenu->clear();
+ m_pPlacingMenu->insertItem( i18n( "Ca&scade Windows" ), m_pMdi, SLOT( cascadeWindows() ) );
+ m_pPlacingMenu->insertItem( i18n( "Cascade &Maximized" ), m_pMdi, SLOT( cascadeMaximized() ) );
+ m_pPlacingMenu->insertItem( i18n( "Expand &Vertically" ), m_pMdi, SLOT( expandVertical() ) );
+ m_pPlacingMenu->insertItem( i18n( "Expand &Horizontally" ), m_pMdi, SLOT( expandHorizontal() ) );
+ m_pPlacingMenu->insertItem( i18n( "Tile &Non-Overlapped" ), m_pMdi, SLOT( tileAnodine() ) );
+ m_pPlacingMenu->insertItem( i18n( "Tile Overla&pped" ), m_pMdi, SLOT( tilePragma() ) );
+ m_pPlacingMenu->insertItem( i18n( "Tile V&ertically" ), m_pMdi, SLOT( tileVertically() ) );
+ if ( m_mdiMode == KMdi::ToplevelMode )
+ {
+ m_pWindowMenu->setItemEnabled( placMenuId, false );
+ }
+ m_pWindowMenu->insertSeparator();
+ int dockUndockId = m_pWindowMenu->insertItem( i18n( "&Dock/Undock" ), m_pDockMenu );
+ m_pDockMenu->clear();
+ m_pWindowMenu->insertSeparator();
+ if ( noViewOpened )
+ {
+ m_pWindowMenu->setItemEnabled( placMenuId, false );
+ m_pWindowMenu->setItemEnabled( dockUndockId, false );
+ }
+ }
+ int entryCount = m_pWindowMenu->count();
+
+ // for all child frame windows: give an ID to every window and connect them in the end with windowMenuItemActivated()
+ int i = 100;
+ KMdiChildView* pView = 0L;
+ QPtrListIterator<KMdiChildView> it( *m_pDocumentViews );
+ QValueList<QDateTime> timeStamps;
+ for ( ; it.current(); ++it )
+ {
+ pView = it.current();
+ QDateTime timeStamp( pView->getTimeStamp() );
+
+ if ( pView->isToolView() )
+ {
+ continue;
+ }
+
+ QString item;
+ // set titles of minimized windows in brackets
+ if ( pView->isMinimized() )
+ {
+ item += "(";
+ item += pView->caption();
+ item += ")";
+ }
+ else
+ {
+ item += " ";
+ item += pView->caption();
+ }
+
+ // insert the window entry sorted by access time
+ unsigned int indx;
+ unsigned int windowItemCount = m_pWindowMenu->count() - entryCount;
+ bool inserted = false;
+ QString tmpString;
+ QValueList<QDateTime>::iterator timeStampIterator = timeStamps.begin();
+ for ( indx = 0; indx <= windowItemCount; indx++, ++timeStampIterator )
+ {
+ bool putHere = false;
+ if ( ( *timeStampIterator ) < timeStamp )
+ {
+ putHere = true;
+ timeStamps.insert( timeStampIterator, timeStamp );
+ }
+ if ( putHere )
+ {
+ m_pWindowMenu->insertItem( item, pView, SLOT( slot_clickedInWindowMenu() ), 0, -1, indx + entryCount );
+ if ( pView == m_pCurrentWindow )
+ {
+ m_pWindowMenu->setItemChecked( m_pWindowMenu->idAt( indx + entryCount ), true );
+ }
+ pView->setWindowMenuID( i );
+ if ( !tabPageMode )
+ {
+ m_pDockMenu->insertItem( item, pView, SLOT( slot_clickedInDockMenu() ), 0, -1, indx );
+ if ( pView->isAttached() )
+ {
+ m_pDockMenu->setItemChecked( m_pDockMenu->idAt( indx ), true );
+ }
+ }
+ inserted = true;
+ break;
+ indx = windowItemCount + 1; // break the loop
+ }
+ }
+ if ( !inserted )
+ { // append it
+ m_pWindowMenu->insertItem( item, pView, SLOT( slot_clickedInWindowMenu() ), 0, -1, windowItemCount + entryCount );
+ if ( pView == m_pCurrentWindow )
+ {
+ m_pWindowMenu->setItemChecked( m_pWindowMenu->idAt( windowItemCount + entryCount ), true );
+ }
+ pView->setWindowMenuID( i );
+ if ( !tabPageMode )
+ {
+ m_pDockMenu->insertItem( item, pView, SLOT( slot_clickedInDockMenu() ), 0, -1, windowItemCount );
+ if ( pView->isAttached() )
+ {
+ m_pDockMenu->setItemChecked( m_pDockMenu->idAt( windowItemCount ), true );
+ }
+ }
+ }
+ i++;
+ }
+}
+
+//================ windowMenuItemActivated ===============//
+
+void KMdiMainFrm::windowMenuItemActivated( int id )
+{
+ if ( id < 100 )
+ return ;
+ id -= 100;
+ KMdiChildView *pView = m_pDocumentViews->at( id );
+ if ( !pView )
+ return ;
+ if ( pView->isMinimized() )
+ pView->minimize();
+ if ( m_mdiMode != KMdi::TabPageMode )
+ {
+ KMdiChildFrm * pTopChild = m_pMdi->topChild();
+ if ( pTopChild )
+ {
+ if ( ( pView == pTopChild->m_pClient ) && pView->isAttached() )
+ {
+ return ;
+ }
+ }
+ }
+ activateView( pView );
+}
+
+//================ dockMenuItemActivated ===============//
+
+void KMdiMainFrm::dockMenuItemActivated( int id )
+{
+ if ( id < 100 )
+ return ;
+ id -= 100;
+ KMdiChildView *pView = m_pDocumentViews->at( id );
+ if ( !pView )
+ return ;
+ if ( pView->isMinimized() )
+ pView->minimize();
+ if ( pView->isAttached() )
+ {
+ detachWindow( pView, true );
+ }
+ else
+ { // is detached
+ attachWindow( pView, true );
+ }
+}
+
+//================ popupWindowMenu ===============//
+
+void KMdiMainFrm::popupWindowMenu( QPoint p )
+{
+ if ( !isFakingSDIApplication() )
+ {
+ m_pWindowMenu->popup( p );
+ }
+}
+
+//================ dragEndTimeOut ===============//
+void KMdiMainFrm::dragEndTimeOut()
+{
+ // send drag end to all concerned views.
+ KMdiChildView * pView;
+ for ( m_pDocumentViews->first(); ( pView = m_pDocumentViews->current() ) != 0L; m_pDocumentViews->next() )
+ {
+ KMdiChildFrmDragEndEvent dragEndEvent( 0L );
+ QApplication::sendEvent( pView, &dragEndEvent );
+ }
+}
+
+//================ setFrameDecorOfAttachedViews ===============//
+
+void KMdiMainFrm::setFrameDecorOfAttachedViews( int frameDecor )
+{
+ switch ( frameDecor )
+ {
+ case 0:
+ m_frameDecoration = KMdi::Win95Look;
+ break;
+ case 1:
+ m_frameDecoration = KMdi::KDE1Look;
+ break;
+ case 2:
+ m_frameDecoration = KMdi::KDELook;
+ break;
+ case 3:
+ m_frameDecoration = KMdi::KDELaptopLook;
+ break;
+ default:
+ qDebug( "unknown MDI decoration" );
+ break;
+ }
+ setMenuForSDIModeSysButtons( m_pMainMenuBar );
+ QPtrListIterator<KMdiChildView> it( *m_pDocumentViews );
+ for ( ; it.current(); ++it )
+ {
+ KMdiChildView* pView = it.current();
+ if ( pView->isToolView() )
+ continue;
+ if ( pView->isAttached() )
+ pView->mdiParent() ->redecorateButtons();
+ }
+}
+
+void KMdiMainFrm::fakeSDIApplication()
+{
+ m_bSDIApplication = true;
+ if ( m_pTaskBar )
+ m_pTaskBar->close();
+ m_pTaskBar = 0L;
+}
+
+void KMdiMainFrm::closeViewButtonPressed()
+{
+ KMdiChildView * pView = activeWindow();
+ if ( pView )
+ {
+ pView->close();
+ }
+}
+
+void KMdiMainFrm::setManagedDockPositionModeEnabled( bool enabled )
+{
+ m_managedDockPositionMode = enabled;
+}
+
+void KMdiMainFrm::setActiveToolDock( KMdiDockContainer* td )
+{
+ if ( td == d->activeDockPriority[ 0 ] )
+ return ;
+ if ( d->activeDockPriority[ 0 ] == 0 )
+ {
+ d->activeDockPriority[ 0 ] = td;
+ // d->focusList=new KMdiFocusList(this);
+ // if (m_pMdi) d->focusList->addWidgetTree(m_pMdi);
+ // if (m_documentTabWidget) d->focusList->addWidgetTree(m_documentTabWidget);
+ return ;
+ }
+ for ( int dst = 3, src = 2;src >= 0;dst--, src-- )
+ {
+ if ( d->activeDockPriority[ src ] == td )
+ src--;
+ if ( src < 0 )
+ break;
+ d->activeDockPriority[ dst ] = d->activeDockPriority[ src ];
+ }
+ d->activeDockPriority[ 0 ] = td;
+}
+
+void KMdiMainFrm::removeFromActiveDockList( KMdiDockContainer* td )
+{
+ for ( int i = 0;i < 4;i++ )
+ {
+ if ( d->activeDockPriority[ i ] == td )
+ {
+ for ( ;i < 3;i++ )
+ d->activeDockPriority[ i ] = d->activeDockPriority[ i + 1 ];
+ d->activeDockPriority[ 3 ] = 0;
+ break;
+ }
+ }
+ /*
+ if (d->activeDockPriority[0]==0) {
+ if (d->focusList) d->focusList->restore();
+ delete d->focusList;
+ d->focusList=0;
+ }
+ */
+}
+
+void KMdiMainFrm::prevToolViewInDock()
+{
+ KMdiDockContainer * td = d->activeDockPriority[ 0 ];
+ if ( !td )
+ return ;
+ td->prevToolView();
+}
+
+void KMdiMainFrm::nextToolViewInDock()
+{
+ KMdiDockContainer * td = d->activeDockPriority[ 0 ];
+ if ( !td )
+ return ;
+ td->nextToolView();
+}
+
+KMdi::TabWidgetVisibility KMdiMainFrm::tabWidgetVisibility()
+{
+ if ( m_documentTabWidget )
+ return m_documentTabWidget->tabWidgetVisibility();
+
+ return KMdi::NeverShowTabs;
+}
+
+void KMdiMainFrm::setTabWidgetVisibility( KMdi::TabWidgetVisibility visibility )
+{
+ if ( m_documentTabWidget )
+ m_documentTabWidget->setTabWidgetVisibility( visibility );
+}
+
+KTabWidget * KMdiMainFrm::tabWidget() const
+{
+ return m_documentTabWidget;
+}
+
+#include "kmdimainfrm.moc"
+
+// vim: ts=2 sw=2 et
+// kate: space-indent off; tab-width 4; replace-tabs off; indent-mode csands;