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;