kmditaskbar.cpp

00001 //----------------------------------------------------------------------------
00002 //    filename             : kmditaskbar.cpp
00003 //----------------------------------------------------------------------------
00004 //    Project              : KDE MDI extension
00005 //
00006 //    begin                : 07/1999       by Szymon Stefanek as part of kvirc
00007 //                                         (an IRC application)
00008 //    changes              : 09/1999       by Falk Brettschneider to create an
00009 //                           - 06/2000     stand-alone Qt extension set of
00010 //                                         classes and a Qt-based library
00011 //                           2000-2003     maintained by the KDevelop project
00012 //    patches              : 02/2000       by Massimo Morin (mmorin@schedsys.com)
00013 //
00014 //    copyright            : (C) 1999-2003 by Szymon Stefanek (stefanek@tin.it)
00015 //                                         and
00016 //                                         Falk Brettschneider
00017 //    email                :  falkbr@kdevelop.org (Falk Brettschneider)
00018 //----------------------------------------------------------------------------
00019 //
00020 //----------------------------------------------------------------------------
00021 //
00022 //    This program is free software; you can redistribute it and/or modify
00023 //    it under the terms of the GNU Library General Public License as
00024 //    published by the Free Software Foundation; either version 2 of the
00025 //    License, or (at your option) any later version.
00026 //
00027 //----------------------------------------------------------------------------
00028 
00029 #include "kmditaskbar.h"
00030 #include "kmditaskbar.moc"
00031 
00032 #include "kmdimainfrm.h"
00033 #include "kmdichildview.h"
00034 #include "kmdidefines.h"
00035 
00036 #include <qtooltip.h>
00037 #include <qlabel.h>
00038 #include <qwidget.h>
00039 #include <qstyle.h>
00040 
00041 #include <qnamespace.h>
00042 
00043 /*
00044    @quickhelp: KMdiTaskBar
00045    @widget: Taskbar
00046       This window lists the currently open windows.<br>
00047       Each button corresponds to a single MDI (child) window.<br>
00048       The button is enabled (clickable) when the window is docked , and can be
00049       pressed to bring it to the top of the other docked windows.<br>
00050       The button text becomes red when new output is shown in the window and it is not the active one.<br>
00051 */
00052 
00053 //####################################################################
00054 //
00055 // KMdiTaskBarButton
00056 //
00057 //####################################################################
00058 KMdiTaskBarButton::KMdiTaskBarButton( KMdiTaskBar *pTaskBar, KMdiChildView *win_ptr )
00059         : QPushButton( pTaskBar ),
00060         m_actualText( "" )
00061 {
00062     setToggleButton( true );
00063     m_pWindow = win_ptr;
00064     QToolTip::add
00065         ( this, win_ptr->caption() );
00066     setFocusPolicy( NoFocus );
00067 }
00068 
00069 KMdiTaskBarButton::~KMdiTaskBarButton()
00070 {}
00071 
00072 void KMdiTaskBarButton::mousePressEvent( QMouseEvent* e )
00073 {
00074     switch ( e->button() )
00075     {
00076     case QMouseEvent::LeftButton:
00077         emit leftMouseButtonClicked( m_pWindow );
00078         break;
00079     case QMouseEvent::RightButton:
00080         emit rightMouseButtonClicked( m_pWindow );
00081         break;
00082     default:
00083         break;
00084     }
00085     emit clicked( m_pWindow );
00086 }
00087 
00089 void KMdiTaskBarButton::setNewText( const QString& s )
00090 {
00091     setText( s );
00092     emit buttonTextChanged( 0 );
00093 }
00094 
00095 void KMdiTaskBarButton::setText( const QString& s )
00096 {
00097     m_actualText = s;
00098     QButton::setText( s );
00099 }
00100 
00101 void KMdiTaskBarButton::fitText( const QString& origStr, int newWidth )
00102 {
00103     QButton::setText( m_actualText );
00104 
00105     int actualWidth = sizeHint().width();
00106     int realLetterCount = origStr.length();
00107     int newLetterCount = ( newWidth * realLetterCount ) / actualWidth;
00108     int w = newWidth + 1;
00109     QString s = origStr;
00110     while ( ( w > newWidth ) && ( newLetterCount >= 1 ) )
00111     {
00112         if ( newLetterCount < realLetterCount )
00113         {
00114             if ( newLetterCount > 3 )
00115                 s = origStr.left( newLetterCount / 2 ) + "..." + origStr.right( newLetterCount / 2 );
00116             else
00117             {
00118                 if ( newLetterCount > 1 )
00119                     s = origStr.left( newLetterCount ) + "..";
00120                 else
00121                     s = origStr.left( 1 );
00122             }
00123         }
00124         QFontMetrics fm = fontMetrics();
00125         w = fm.width( s );
00126         newLetterCount--;
00127     }
00128 
00129     QButton::setText( s );
00130 }
00131 
00132 QString KMdiTaskBarButton::actualText() const
00133 {
00134     return m_actualText;
00135 }
00136 
00137 //####################################################################
00138 //
00139 // KMdiTaskBar
00140 //
00141 //####################################################################
00142 
00143 KMdiTaskBar::KMdiTaskBar( KMdiMainFrm *parent, QMainWindow::ToolBarDock dock )
00144         : KToolBar( parent, "KMdiTaskBar",  /*honor_style*/ false,  /*readConfig*/ true )
00145         , m_pCurrentFocusedWindow( 0 )
00146         , m_pStretchSpace( 0 )
00147         , m_layoutIsPending( false )
00148         , m_bSwitchedOn( false )
00149 {
00150     m_pFrm = parent;
00151     m_pButtonList = new QPtrList<KMdiTaskBarButton>;
00152     m_pButtonList->setAutoDelete( true );
00153     //QT30   setFontPropagation(QWidget::SameFont);
00154     setMinimumWidth( 1 );
00155     setFocusPolicy( NoFocus );
00156     parent->moveToolBar( this, dock ); //XXX obsolete!
00157 }
00158 
00159 KMdiTaskBar::~KMdiTaskBar()
00160 {
00161     delete m_pButtonList;
00162 }
00163 
00164 KMdiTaskBarButton * KMdiTaskBar::addWinButton( KMdiChildView *win_ptr )
00165 {
00166     if ( m_pStretchSpace )
00167     {
00168         delete m_pStretchSpace;
00169         m_pStretchSpace = 0L;
00170         setStretchableWidget( 0L );
00171     }
00172 
00173     KMdiTaskBarButton *b = new KMdiTaskBarButton( this, win_ptr );
00174     QObject::connect( b, SIGNAL( clicked() ), win_ptr, SLOT( setFocus() ) );
00175     QObject::connect( b, SIGNAL( clicked( KMdiChildView* ) ), this, SLOT( setActiveButton( KMdiChildView* ) ) );
00176     QObject::connect( b, SIGNAL( leftMouseButtonClicked( KMdiChildView* ) ), m_pFrm, SLOT( activateView( KMdiChildView* ) ) );
00177     QObject::connect( b, SIGNAL( rightMouseButtonClicked( KMdiChildView* ) ), m_pFrm, SLOT( taskbarButtonRightClicked( KMdiChildView* ) ) );
00178     QObject::connect( b, SIGNAL( buttonTextChanged( int ) ), this, SLOT( layoutTaskBar( int ) ) );
00179     m_pButtonList->append( b );
00180     b->setToggleButton( true );
00181     b->setText( win_ptr->tabCaption() );
00182 
00183     layoutTaskBar();
00184 
00185     m_pStretchSpace = new QLabel( this, "empty" );
00186     m_pStretchSpace->setText( "" );
00187     setStretchableWidget( m_pStretchSpace );
00188     m_pStretchSpace->show();
00189 
00190     if ( m_bSwitchedOn )
00191     {
00192         b->show();
00193         show();
00194     }
00195     return b;
00196 }
00197 
00198 void KMdiTaskBar::removeWinButton( KMdiChildView *win_ptr, bool haveToLayoutTaskBar )
00199 {
00200     KMdiTaskBarButton * b = getButton( win_ptr );
00201     if ( b )
00202     {
00203         m_pButtonList->removeRef( b );
00204         if ( haveToLayoutTaskBar )
00205             layoutTaskBar();
00206     }
00207     if ( m_pButtonList->count() == 0 )
00208     {
00209         if ( m_pStretchSpace != 0L )
00210         {
00211             delete m_pStretchSpace;
00212             m_pStretchSpace = 0L;
00213             hide();
00214         }
00215     }
00216 }
00217 
00218 void KMdiTaskBar::switchOn( bool bOn )
00219 {
00220     m_bSwitchedOn = bOn;
00221     if ( !bOn )
00222     {
00223         hide();
00224     }
00225     else
00226     {
00227         if ( m_pButtonList->count() > 0 )
00228         {
00229             show();
00230         }
00231         else
00232         {
00233             hide();
00234         }
00235     }
00236 }
00237 
00238 KMdiTaskBarButton * KMdiTaskBar::getButton( KMdiChildView *win_ptr )
00239 {
00240     for ( KMdiTaskBarButton * b = m_pButtonList->first();b;b = m_pButtonList->next() )
00241     {
00242         if ( b->m_pWindow == win_ptr )
00243             return b;
00244     }
00245     return 0;
00246 }
00247 
00248 KMdiTaskBarButton * KMdiTaskBar::getNextWindowButton( bool bRight, KMdiChildView *win_ptr )
00249 {
00250     if ( bRight )
00251     {
00252         for ( KMdiTaskBarButton * b = m_pButtonList->first();b;b = m_pButtonList->next() )
00253         {
00254             if ( b->m_pWindow == win_ptr )
00255             {
00256                 b = m_pButtonList->next();
00257                 if ( !b )
00258                     b = m_pButtonList->first();
00259                 if ( win_ptr != b->m_pWindow )
00260                     return b;
00261                 else
00262                     return 0;
00263             }
00264         }
00265     }
00266     else
00267     {
00268         for ( KMdiTaskBarButton * b = m_pButtonList->first();b;b = m_pButtonList->next() )
00269         {
00270             if ( b->m_pWindow == win_ptr )
00271             {
00272                 b = m_pButtonList->prev();
00273                 if ( !b )
00274                     b = m_pButtonList->last();
00275                 if ( win_ptr != b->m_pWindow )
00276                     return b;
00277                 else
00278                     return 0;
00279             }
00280         }
00281     }
00282     return 0;
00283 }
00284 
00285 void KMdiTaskBar::setActiveButton( KMdiChildView *win_ptr )
00286 {
00287     KMdiTaskBarButton * newPressedButton = 0L;
00288     KMdiTaskBarButton* oldPressedButton = 0L;
00289     for ( KMdiTaskBarButton * b = m_pButtonList->first();b;b = m_pButtonList->next() )
00290     {
00291         if ( b->m_pWindow == win_ptr )
00292             newPressedButton = b;
00293         if ( b->m_pWindow == m_pCurrentFocusedWindow )
00294             oldPressedButton = b;
00295     }
00296 
00297     if ( newPressedButton != 0L && newPressedButton != oldPressedButton )
00298     {
00299         if ( oldPressedButton != 0L )
00300             oldPressedButton->toggle(); // switch off
00301         newPressedButton->toggle();   // switch on
00302         m_pCurrentFocusedWindow = win_ptr;
00303     }
00304 }
00305 
00306 void KMdiTaskBar::layoutTaskBar( int taskBarWidth )
00307 {
00308     if ( m_layoutIsPending )
00309         return ;
00310     m_layoutIsPending = true;
00311 
00312     if ( !taskBarWidth )
00313         // no width is given
00314         taskBarWidth = width();
00315 
00316     // calculate current width of all taskbar buttons
00317     int allButtonsWidth = 0;
00318     KMdiTaskBarButton *b = 0;
00319     for ( b = m_pButtonList->first();b;b = m_pButtonList->next() )
00320     {
00321         allButtonsWidth += b->width();
00322     }
00323 
00324     // calculate actual width of all taskbar buttons
00325     int allButtonsWidthHint = 0;
00326     for ( b = m_pButtonList->first();b;b = m_pButtonList->next() )
00327     {
00328         QFontMetrics fm = b->fontMetrics();
00329         QString s = b->actualText();
00330         QSize sz = fm.size( ShowPrefix, s );
00331         int w = sz.width() + 6;
00332         int h = sz.height() + sz.height() / 8 + 10;
00333         w += h;
00334         allButtonsWidthHint += w;
00335     }
00336 
00337     // if there's enough space, use actual width
00338     int buttonCount = m_pButtonList->count();
00339     int tbHandlePixel;
00340     tbHandlePixel = style().pixelMetric( QStyle::PM_DockWindowHandleExtent, this );
00341     int buttonAreaWidth = taskBarWidth - tbHandlePixel - style().pixelMetric( QStyle::PM_DefaultFrameWidth, this ) - 5;
00342     if ( ( ( allButtonsWidthHint ) <= buttonAreaWidth ) || ( width() < parentWidget() ->width() ) )
00343     {
00344         for ( b = m_pButtonList->first();b;b = m_pButtonList->next() )
00345         {
00346             b->setText( b->actualText() );
00347             if ( b->width() != b->sizeHint().width() )
00348             {
00349                 b->setFixedWidth( b->sizeHint().width() );
00350                 b->show();
00351             }
00352         }
00353     }
00354     else
00355     {
00356         // too many buttons for actual width
00357         int newButtonWidth;
00358         if ( buttonCount != 0 )
00359             newButtonWidth = buttonAreaWidth / buttonCount;
00360         else
00361             newButtonWidth = 0;
00362         if ( orientation() == Qt::Vertical )
00363             newButtonWidth = 80;
00364         if ( newButtonWidth > 0 )
00365             for ( b = m_pButtonList->first();b;b = m_pButtonList->next() )
00366             {
00367                 b->fitText( b->actualText(), newButtonWidth );
00368                 if ( b->width() != newButtonWidth )
00369                 {
00370                     b->setFixedWidth( newButtonWidth );
00371                     b->show();
00372                 }
00373             }
00374     }
00375     m_layoutIsPending = false;
00376 }
00377 
00378 void KMdiTaskBar::resizeEvent( QResizeEvent* rse )
00379 {
00380     if ( !m_layoutIsPending )
00381     {
00382         if ( m_pButtonList->count() != 0 )
00383         {
00384             layoutTaskBar( rse->size().width() );
00385         }
00386     }
00387     KToolBar::resizeEvent( rse );
00388 }
00389 
00390 // kate: space-indent off; tab-width 4; replace-tabs off; indent-mode csands;
KDE Home | KDE Accessibility Home | Description of Access Keys