F:/KPlato/koffice/libs/kofficeui/KoKoolBar.cpp

Aller à la documentation de ce fichier.
00001 /* This file is part of the KDE project
00002    Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include <KoKoolBar.h>
00021 #include <kiconloader.h>
00022 
00023 #include <QPainter>
00024 #include <QPushButton>
00025 #include <QPixmap>
00026 #include <Q3Frame>
00027 #include <QResizeEvent>
00028 
00029 static int g_koKoolBarId = 0;
00030 
00031 KoKoolBar::KoKoolBar( QWidget *_parent, const char* /*_name*/ ) :
00032   QWidget( _parent ), m_iActiveGroup( -1 )
00033 {
00034   m_mapGroups.setAutoDelete( true );
00035   m_pBox = new KoKoolBarBox( this );
00036 }
00037 
00038 int KoKoolBar::insertGroup( const QString& _text )
00039 {
00040   KoKoolBarGroup *p = new KoKoolBarGroup( this, _text );
00041   m_mapGroups.insert( p->id(), p );
00042 
00043   if ( m_iActiveGroup == -1 )
00044     setActiveGroup( p->id() );
00045   else
00046     resizeEvent( 0L );
00047   return p->id();
00048 }
00049 
00050 int KoKoolBar::insertItem( int _grp, const QPixmap& _pix, const QString& _text,
00051                            QObject *_obj, const char *_slot )
00052 {
00053   KoKoolBarGroup* g = m_mapGroups[ _grp ];
00054   if ( !g )
00055     return -1;
00056   KoKoolBarItem *item = new KoKoolBarItem( g, _pix, _text );
00057 
00058   if ( _obj != 0L && _slot != 0L )
00059     connect( item, SIGNAL( pressed( int, int ) ), _obj, _slot );
00060   g->append( item );
00061 
00062   if ( g->id() == m_iActiveGroup )
00063     m_pBox->update();
00064 
00065   return item->id();
00066 }
00067 
00068 void KoKoolBar::removeGroup( int _grp )
00069 {
00070   KoKoolBarGroup* g = m_mapGroups[ _grp ];
00071   if ( !g )
00072     return;
00073 
00074   m_mapGroups.remove( _grp );
00075 
00076   if ( _grp == m_iActiveGroup )
00077   {
00078     if ( m_mapGroups.count() == 0 )
00079     {
00080       m_iActiveGroup = -1;
00081       m_pBox->setActiveGroup( 0L );
00082     }
00083     else
00084     {
00085       Q3IntDictIterator<KoKoolBarGroup> it( m_mapGroups );
00086       g = it.current();
00087       m_iActiveGroup = g->id();
00088       m_pBox->setActiveGroup( g );
00089     }
00090   }
00091 
00092   resizeEvent( 0L );
00093 }
00094 
00095 void KoKoolBar::removeItem( int _grp, int _id )
00096 {
00097   KoKoolBarGroup* g = m_mapGroups[ _grp ];
00098   if ( !g )
00099     return;
00100 
00101   g->remove( _id );
00102 
00103   if ( g->id() == m_iActiveGroup )
00104     m_pBox->update();
00105 }
00106 
00107 void KoKoolBar::renameItem( int _grp, int _id, const QString & _text )
00108 {
00109   KoKoolBarGroup* g = m_mapGroups[ _grp ];
00110   if ( !g )
00111     return;
00112 
00113   KoKoolBarItem * item = g->item( _id );
00114   if ( !item )
00115     return;
00116 
00117   item->setText( _text );
00118 
00119   if ( g->id() == m_iActiveGroup )
00120     m_pBox->update();
00121 }
00122 
00123 void KoKoolBar::setActiveGroup( int _grp )
00124 {
00125   KoKoolBarGroup* g = m_mapGroups[ _grp ];
00126   if ( !g )
00127     return;
00128 
00129   m_iActiveGroup = g->id();
00130   m_pBox->setActiveGroup( g );
00131 
00132   resizeEvent( 0L );
00133 }
00134 
00135 void KoKoolBar::resizeEvent( QResizeEvent * ev )
00136 {
00137   if ( m_iActiveGroup == -1 )
00138     return;
00139 
00140   int buttonheight = fontMetrics().height() + 4;
00141 
00142   KoKoolBarGroup *g = m_mapGroups[ m_iActiveGroup ];
00143   if ( !g )
00144     return;
00145 
00146   // Go behind g
00147   Q3IntDictIterator<KoKoolBarGroup> it( m_mapGroups );
00148   while( it.current() != g )
00149     ++it;
00150   // Position of g
00151   Q3IntDictIterator<KoKoolBarGroup> pos = it;
00152   ++it;
00153 
00154   // How many left ?
00155   int result = 0;
00156   Q3IntDictIterator<KoKoolBarGroup> i = it;
00157   while( i.current() )
00158   {
00159     ++result;
00160     ++i;
00161   }
00162 
00163   int y = height() - buttonheight * result;
00164   for( ; it.current(); ++it )
00165   {
00166     it.current()->button()->setGeometry( 0, y, width(), buttonheight );
00167     it.current()->button()->show();
00168     y += buttonheight;
00169   }
00170 
00171   int y2 = 0;
00172   it.toFirst();
00173   ++pos;
00174   while( it.current() != pos.current() )
00175   {
00176     it.current()->button()->setGeometry( 0, y2, width(), buttonheight );
00177     it.current()->button()->show();
00178     ++it;
00179     y2 += buttonheight;
00180   }
00181 
00182   if ( height() - y2 - result * buttonheight >= 0 )
00183   {
00184     m_pBox->show();
00185     m_pBox->setGeometry( 0, y2, width(), height() - y2 - result * buttonheight );
00186     if ( !ev ) // fake event
00187       m_pBox->sizeChanged();
00188   }
00189   else
00190     m_pBox->hide();
00191 
00192 }
00193 
00194 void KoKoolBar::enableItem( int _grp, int _id, bool _enable )
00195 {
00196   KoKoolBarGroup* g = m_mapGroups[ _grp ];
00197   if ( !g )
00198     return;
00199   KoKoolBarItem *item = g->item( _id );
00200   if ( !item )
00201     return;
00202   item->setEnabled( _enable );
00203 }
00204 
00205 void KoKoolBar::enableGroup( int _grp, bool _enable )
00206 {
00207   KoKoolBarGroup* g = m_mapGroups[ _grp ];
00208   if ( !g )
00209     return;
00210   g->setEnabled( _enable );
00211 }
00212 
00213 KoKoolBarBox::KoKoolBarBox( KoKoolBar *_bar ) :
00214   Q3Frame( _bar ), m_pBar( _bar ),
00215   m_pButtonUp( 0L ), m_pButtonDown( 0L )
00216 {
00217   m_iYOffset = 0;
00218   m_iYIcon = 0;
00219   m_pGroup = 0L;
00220 
00221   setFrameShape( StyledPanel );
00222   setFrameShadow( Sunken );
00223   // setBackgroundMode( PaletteBase );
00224   setBackgroundRole( QPalette::Window );
00225 }
00226 
00227 void KoKoolBarBox::setActiveGroup( KoKoolBarGroup *_grp )
00228 {
00229   m_pGroup = _grp;
00230   m_iYOffset = 0;
00231   m_iYIcon = 0;
00232   update();
00233 }
00234 
00235 bool KoKoolBarBox::needsScrolling() const
00236 {
00237   if ( m_pGroup == 0L )
00238     return false;
00239 
00240   return ( maxHeight() > height() );
00241 }
00242 
00243 void KoKoolBarBox::resizeEvent( QResizeEvent * )
00244 {
00245   if ( needsScrolling() )
00246   {
00247     if ( m_pButtonUp == 0L )
00248     {
00249       m_pButtonUp = new QPushButton( this );
00250       m_pButtonUp->setIcon(  UserIcon( "koKoolBarUp" ) );
00251       connect( m_pButtonUp, SIGNAL( clicked() ), this, SLOT( scrollUp() ) );
00252     }
00253     if ( m_pButtonDown == 0L )
00254     {
00255       m_pButtonDown = new QPushButton( this );
00256       m_pButtonDown->setIcon( UserIcon( "koKoolBarDown" ) );
00257       connect( m_pButtonDown, SIGNAL( clicked() ), this, SLOT( scrollDown() ) );
00258     }
00259     m_pButtonUp->show();
00260     m_pButtonUp->raise();
00261     m_pButtonDown->show();
00262     m_pButtonDown->raise();
00263     updateScrollButtons();
00264   }
00265   else
00266   {
00267     if ( m_pButtonUp )
00268       m_pButtonUp->hide();
00269     if ( m_pButtonDown )
00270       m_pButtonDown->hide();
00271   }
00272 }
00273 
00274 KoKoolBarItem* KoKoolBarBox::findByPos( int _abs_y ) const
00275 {
00276   if ( m_pGroup == 0L )
00277     return 0L;
00278 
00279   int y = 0;
00280 
00281   Q3IntDictIterator<KoKoolBarItem> it = m_pGroup->iterator();
00282   for ( ; it.current(); ++it )
00283   {
00284     int dy = it.current()->height();
00285     if ( y <= _abs_y && _abs_y <= y + dy )
00286       return it.current();
00287     y += dy;
00288   }
00289 
00290   return 0L;
00291 }
00292 
00293 int KoKoolBarBox::maxHeight() const
00294 {
00295   int y = 0;
00296 
00297   Q3IntDictIterator<KoKoolBarItem> it = m_pGroup->iterator();
00298   for ( ; it.current(); ++it )
00299     y += it.current()->height();
00300 
00301   return y;
00302 }
00303 
00304 bool KoKoolBarBox::isAtTop() const
00305 {
00306   return ( m_iYIcon == 0 );
00307 }
00308 
00309 bool KoKoolBarBox::isAtBottom() const
00310 {
00311   if ( m_pGroup->items() == 0 )
00312     return true;
00313   int h = maxHeight();
00314   if ( height() + m_iYOffset >= h )
00315     return true;
00316   if ( m_pGroup->items() - 1 == m_iYIcon )
00317     return true;
00318   return false;
00319 }
00320 
00321 void KoKoolBarBox::scrollUp()
00322 {
00323   if ( isAtTop() )
00324     return;
00325 
00326   int y = 0;
00327   int i = 0;
00328   m_iYIcon--;
00329 
00330   Q3IntDictIterator<KoKoolBarItem> it = m_pGroup->iterator();
00331   for ( ; i < m_iYIcon && it.current(); ++it )
00332   {
00333     y += it.current()->height();
00334     ++i;
00335   }
00336 
00337   int old = m_iYOffset;
00338   m_iYOffset = y;
00339 
00340   QWidget::scroll( 0, old - m_iYOffset, contentsRect() );
00341   updateScrollButtons();
00342 }
00343 
00344 void KoKoolBarBox::scrollDown()
00345 {
00346   if ( isAtBottom() )
00347     return;
00348 
00349   int y = 0;
00350   int i = 0;
00351   m_iYIcon++;
00352 
00353   Q3IntDictIterator<KoKoolBarItem> it = m_pGroup->iterator();
00354   for ( ; i < m_iYIcon && it.current(); ++it )
00355   {
00356     y += it.current()->height();
00357     i++;
00358   }
00359   int h = maxHeight();
00360   if ( y + height() > h ) // Don't go after last item
00361     y = h - height();
00362 
00363   int old = m_iYOffset;
00364   m_iYOffset = y;
00365 
00366   QWidget::scroll( 0, old - m_iYOffset, contentsRect() );
00367   updateScrollButtons();
00368 }
00369 
00370 void KoKoolBarBox::updateScrollButtons()
00371 {
00372   if ( isAtTop() )
00373     m_pButtonUp->setEnabled( false );
00374   else
00375     m_pButtonUp->setEnabled( true );
00376 
00377   if ( isAtBottom() )
00378     m_pButtonDown->setEnabled( false );
00379   else
00380     m_pButtonDown->setEnabled( true );
00381 
00382   const int bs = 14; // buttonSize
00383   m_pButtonUp->setGeometry( width() - bs, height() - 2 * bs, bs, bs );
00384   m_pButtonDown->setGeometry( width() - bs, height() - bs, bs, bs );
00385 }
00386 
00387 void KoKoolBarBox::drawContents( QPainter * painter )
00388 {
00389   if ( m_pGroup == 0L )
00390     return;
00391 
00392   int y = -m_iYOffset;
00393 
00394   Q3IntDictIterator<KoKoolBarItem> it = m_pGroup->iterator();
00395   for ( ; it.current(); ++it )
00396   {
00397     if ( y + it.current()->height() >= 0 && y <= height() ) // visible ?
00398     {
00399       painter->drawPixmap( ( width() - it.current()->pixmap().width() ) / 2, y, it.current()->pixmap() );
00400       if ( !it.current()->text().isEmpty() )
00401       {
00402         int y2 = y + it.current()->pixmap().height() + 2;
00403         painter->drawText( ( width() - painter->fontMetrics().width( it.current()->text() ) ) / 2,
00404                             y2 + painter->fontMetrics().ascent(), it.current()->text() );
00405       }
00406     }
00407 
00408     y += it.current()->height();
00409   }
00410 }
00411 
00412 KoKoolBarGroup::KoKoolBarGroup( KoKoolBar *_bar, const QString& _text ) :
00413   m_pBar( _bar )
00414 {
00415   m_mapItems.setAutoDelete( true );
00416 
00417   m_pButton = new QPushButton( _text, _bar );
00418 
00419   m_bEnabled = true;
00420 
00421   connect( m_pButton, SIGNAL( clicked() ), this, SLOT( pressed() ) );
00422   m_id = g_koKoolBarId++;
00423 }
00424 
00425 KoKoolBarGroup::~KoKoolBarGroup()
00426 {
00427   delete m_pButton;
00428 }
00429 
00430 void KoKoolBarGroup::remove( int _id )
00431 {
00432   m_mapItems.remove( _id );
00433 }
00434 
00435 void KoKoolBarGroup::pressed()
00436 {
00437   m_pBar->setActiveGroup( m_id );
00438 }
00439 
00440 KoKoolBarItem::KoKoolBarItem( KoKoolBarGroup *_grp, const QPixmap& _pix, const QString&_text )
00441   : m_pGroup( _grp )
00442 {
00443   m_pixmap = _pix;
00444   m_strText = _text;
00445   m_bEnabled = true;
00446   m_id = g_koKoolBarId++;
00447   calc( _grp->bar() );
00448 }
00449 
00450 void KoKoolBarItem::calc( QWidget *_widget )
00451 {
00452   m_iHeight = pixmap().height() + 8;
00453 
00454   if ( !m_strText.isEmpty() )
00455     m_iHeight += _widget->fontMetrics().height() + 2;
00456 }
00457 
00458 void KoKoolBarItem::press()
00459 {
00460   emit pressed();
00461   emit pressed( m_pGroup->id(), m_id );
00462 }
00463 
00464 /*
00465 
00466 int main( int argc, char **argv )
00467 {
00468   KApplication app( argc, argv );
00469   KoKoolBar bar;
00470   int file = bar.insertGroup("File");
00471   QPixmap pix;
00472   pix.load( "/opt/kde/share/icons/image.xpm" );
00473   bar.insertItem( file, pix );
00474   pix.load( "/opt/kde/share/icons/html.xpm" );
00475   bar.insertItem( file, pix );
00476   pix.load( "/opt/kde/share/icons/txt.xpm" );
00477   bar.insertItem( file, pix );
00478   pix.load( "/opt/kde/share/icons/kfm.xpm" );
00479   bar.insertItem( file, pix );
00480 
00481   bar.insertGroup("Edit");
00482   bar.insertGroup("View");
00483   bar.insertGroup("Layout");
00484   bar.insertGroup("Help");
00485   bar.setGeometry( 100, 100, 80, 300 );
00486   bar.show();
00487 
00488   app.exec();
00489 }
00490 */
00491 
00492 #include <KoKoolBar.moc>

Généré le Wed Nov 22 23:41:05 2006 pour KPlato par  doxygen 1.5.1-p1