00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <qbitmap.h>
00024 #include <qcursor.h>
00025 #include <qdrawutil.h>
00026 #include <qfontmetrics.h>
00027 #include <qframe.h>
00028 #include <qlabel.h>
00029 #include <qobjectlist.h>
00030 #include <qpainter.h>
00031 #include <qptrlist.h>
00032 #include <qstyle.h>
00033 #include <qtooltip.h>
00034 #include <qwidgetstack.h>
00035
00036
00037 #include <kapplication.h>
00038 #include <kdebug.h>
00039 #include <kdialog.h>
00040 #include <kiconloader.h>
00041 #include <klocale.h>
00042 #include <kpopupmenu.h>
00043 #include <kpushbutton.h>
00044
00045 #include "iconsidepane.h"
00046
00047 EntryItem::EntryItem( Navigator *parent, int _id, const QString &_text, const QString & _pix )
00048 : QListBoxItem( parent ),
00049 mPixmapName(_pix),
00050 mId(_id),
00051 mHasHover( false ),
00052 mPaintActive( false )
00053 {
00054 reloadPixmap();
00055 setCustomHighlighting( true );
00056 setText( _text );
00057 }
00058
00059 EntryItem::~EntryItem()
00060 {
00061 }
00062
00063 void EntryItem::setNewText(const QString &_text)
00064 {
00065 setText( _text );
00066 }
00067
00068 void EntryItem::reloadPixmap()
00069 {
00070 int size = (int)navigator()->viewMode();
00071 if ( size != 0 )
00072 mPixmap = KGlobal::iconLoader()->loadIcon( mPixmapName, KIcon::Desktop, size );
00073 else
00074 mPixmap = QPixmap();
00075 }
00076
00077 Navigator* EntryItem::navigator() const
00078 {
00079 return static_cast<Navigator*>( listBox() );
00080 }
00081
00082 int EntryItem::width( const QListBox *listbox ) const
00083 {
00084 int w = 0;
00085 if( navigator()->showIcons() ) {
00086 w = navigator()->viewMode();
00087 if ( navigator()->viewMode() == SmallIcons )
00088 w += 4;
00089 }
00090 if( navigator()->showText() ) {
00091 if ( navigator()->viewMode() == SmallIcons )
00092 w += listbox->fontMetrics().width( text() );
00093 else
00094 w = QMAX( w, listbox->fontMetrics().width( text() ) );
00095 }
00096 return w + ( KDialog::marginHint() * 2 );
00097 }
00098
00099 int EntryItem::height( const QListBox *listbox ) const
00100 {
00101 int h = 0;
00102 if ( navigator()->showIcons() )
00103 h = (int)navigator()->viewMode() + 4;
00104 if ( navigator()->showText() ) {
00105 if ( navigator()->viewMode() == SmallIcons || !navigator()->showIcons() )
00106 h = QMAX( h, listbox->fontMetrics().lineSpacing() ) + KDialog::spacingHint() * 2;
00107 else
00108 h = (int)navigator()->viewMode() + listbox->fontMetrics().lineSpacing() + 4;
00109 }
00110 return h;
00111 }
00112
00113 void EntryItem::paint( QPainter *p )
00114 {
00115 reloadPixmap();
00116
00117 QListBox *box = listBox();
00118 bool iconAboveText = ( navigator()->viewMode() > SmallIcons )
00119 && navigator()->showIcons();
00120 int w = box->viewport()->width();
00121 int y = 2;
00122
00123
00124 if ( isCurrent() || isSelected() || mHasHover || mPaintActive ) {
00125 int h = height( box );
00126
00127 QBrush brush;
00128 if ( isCurrent() || isSelected() || mPaintActive )
00129 brush = box->colorGroup().brush( QColorGroup::Highlight );
00130 else
00131 brush = box->colorGroup().highlight().light( 115 );
00132 p->fillRect( 1, 0, w - 2, h - 1, brush );
00133 QPen pen = p->pen();
00134 QPen oldPen = pen;
00135 pen.setColor( box->colorGroup().mid() );
00136 p->setPen( pen );
00137
00138 p->drawPoint( 1, 0 );
00139 p->drawPoint( 1, h - 2 );
00140 p->drawPoint( w - 2, 0 );
00141 p->drawPoint( w - 2, h - 2 );
00142
00143 p->setPen( oldPen );
00144 }
00145
00146 if ( !mPixmap.isNull() && navigator()->showIcons() ) {
00147 int x = iconAboveText ? ( ( w - mPixmap.width() ) / 2 ) :
00148 KDialog::marginHint();
00149 p->drawPixmap( x, y, mPixmap );
00150 }
00151
00152 QColor shadowColor = listBox()->colorGroup().background().dark(115);
00153 if ( isCurrent() || isSelected() ) {
00154 p->setPen( box->colorGroup().highlightedText() );
00155 }
00156
00157 if ( !text().isEmpty() && navigator()->showText() ) {
00158 QFontMetrics fm = p->fontMetrics();
00159
00160 int x = 0;
00161 if ( iconAboveText ) {
00162 x = ( w - fm.width( text() ) ) / 2;
00163 y += fm.height() - fm.descent();
00164 if ( navigator()->showIcons() )
00165 y += mPixmap.height();
00166 } else {
00167 x = KDialog::marginHint() + 4;
00168 if( navigator()->showIcons() ) {
00169 x += mPixmap.width();
00170 }
00171
00172 if ( !navigator()->showIcons() || mPixmap.height() < fm.height() )
00173 y += fm.ascent() + fm.leading()/2;
00174 else
00175 y += mPixmap.height()/2 - fm.height()/2 + fm.ascent();
00176 }
00177
00178 if ( isCurrent() || isSelected() || mHasHover ) {
00179 p->setPen( box->colorGroup().highlight().dark(115) );
00180 p->drawText( x + ( QApplication::reverseLayout() ? -1 : 1),
00181 y + 1, text() );
00182 p->setPen( box->colorGroup().highlightedText() );
00183 }
00184 else
00185 p->setPen( box->colorGroup().text() );
00186
00187 p->drawText( x, y, text() );
00188 }
00189
00190
00191 if ( isCurrent() || isSelected() ) mHasHover = false;
00192 }
00193
00194 void EntryItem::setHover( bool hasHover )
00195 {
00196 mHasHover = hasHover;
00197 }
00198
00199 void EntryItem::setPaintActive( bool paintActive )
00200 {
00201 mPaintActive = paintActive;
00202 }
00203
00204
00205
00206 Navigator::Navigator(bool _selectable, KPopupMenu * menu, IconSidePane *_iconsidepane, QWidget *parent, const char *name )
00207 : KListBox( parent, name ), mSidePane( _iconsidepane ), mPopupMenu( menu )
00208 {
00209 setSelectionMode( KListBox::Single );
00210 viewport()->setBackgroundMode( PaletteBackground );
00211 setFrameStyle( QFrame::NoFrame );
00212 setHScrollBarMode( QScrollView::AlwaysOff );
00213
00214 mMinWidth = 0;
00215 mSelectable = _selectable;
00216 executedItem = 0;
00217 mMouseOn = 0;
00218
00219 setFocusPolicy( NoFocus );
00220
00221 connect( this, SIGNAL( clicked( QListBoxItem* ) ),
00222 SLOT( slotExecuted( QListBoxItem* ) ) );
00223 connect( this, SIGNAL( onItem( QListBoxItem * ) ),
00224 SLOT( slotMouseOn( QListBoxItem * ) ) );
00225 connect( this, SIGNAL( onViewport() ), SLOT( slotMouseOff() ) );
00226
00227 QToolTip::remove( this );
00228 if ( !mSidePane->showText() )
00229 new EntryItemToolTip( this );
00230 }
00231
00232 IconViewMode Navigator::viewMode()
00233 {
00234 return mSidePane->viewMode();
00235 }
00236
00237 bool Navigator::showText()
00238 {
00239 return mSidePane->showText();
00240 }
00241
00242 bool Navigator::showIcons()
00243 {
00244 return mSidePane->showIcons();
00245 }
00246
00247 void Navigator::mouseReleaseEvent(QMouseEvent *e)
00248 {
00249 KListBox::mouseReleaseEvent(e);
00250 if ( e->button() != LeftButton || !mLeftMouseButtonPressed )
00251 return;
00252 if ( itemAt( e->pos() ) && executedItem == selectedItem() )
00253 emit itemSelected( currentItem() );
00254 if ( !mSelectable )
00255 clearSelection();
00256 }
00257
00258 void Navigator::mousePressEvent(QMouseEvent *e)
00259 {
00260 if ( e->button() != LeftButton || itemAt( e->pos() ) == 0 )
00261 {
00262 mLeftMouseButtonPressed = false;
00263 if (e->button() == RightButton)
00264 slotShowRMBMenu( 0,mapToGlobal( e->pos() ) );
00265 return;
00266 }
00267 else
00268 mLeftMouseButtonPressed = true;
00269 KListBox::mousePressEvent(e);
00270 }
00271
00272 void Navigator::enterEvent( QEvent *event )
00273 {
00274
00275 KListBox::enterEvent( event );
00276 emit onItem( itemAt( mapFromGlobal( QCursor::pos() ) ) );
00277 }
00278
00279 void Navigator::slotExecuted( QListBoxItem *item )
00280 {
00281 if ( !item )
00282 return;
00283 executedItem = item;
00284 }
00285
00286 QSize Navigator::sizeHint() const
00287 {
00288 return QSize( mMinWidth, 100 );
00289 }
00290
00291 void Navigator::calculateMinWidth()
00292 {
00293 mMinWidth = mSidePane->minWidth();
00294
00295 for (EntryItem *item = static_cast<EntryItem *>(firstItem()) ; item; item = static_cast<EntryItem *>(item->next()))
00296 {
00297 if (item->width( this ) > mMinWidth)
00298 mMinWidth = item->width( this );
00299 }
00300
00301 parentWidget()->setFixedWidth( mMinWidth );
00302 triggerUpdate(true);
00303 }
00304
00305 int Navigator::insertItem(const QString &_text, const QString & _pix)
00306 {
00307 EntryItem *item = new EntryItem( this, count(), _text, _pix );
00308 if (item->width( this ) > mSidePane->minWidth() )
00309 {
00310 mMinWidth = item->width( this );
00311 parentWidget()->setMinimumWidth( mMinWidth );
00312
00313 }
00314 return item->id();
00315 }
00316
00317 void Navigator::setHoverItem( QListBoxItem* item, bool hover )
00318 {
00319 static_cast<EntryItem*>( item )->setHover( hover );
00320 updateItem( item );
00321 }
00322
00323 void Navigator::setPaintActiveItem( QListBoxItem* item, bool paintActive )
00324 {
00325 static_cast<EntryItem*>( item )->setPaintActive( paintActive );
00326 updateItem( item );
00327 }
00328
00329 void Navigator::slotMouseOn( QListBoxItem* newItem )
00330 {
00331 QListBoxItem* oldItem = mMouseOn;
00332 if ( oldItem == newItem )
00333 return;
00334
00335 if ( oldItem && !oldItem->isCurrent() && !oldItem->isSelected() )
00336 setHoverItem( oldItem, false );
00337
00338 if ( newItem && !newItem->isCurrent() && !newItem->isSelected() )
00339 setHoverItem( newItem, true );
00340 mMouseOn = newItem;
00341 }
00342
00343 void Navigator::slotMouseOff()
00344 {
00345 slotMouseOn( 0 );
00346 }
00347
00348 void Navigator::resizeEvent( QResizeEvent *event )
00349 {
00350 QListBox::resizeEvent( event );
00351 triggerUpdate( true );
00352 }
00353
00354 void Navigator::slotShowRMBMenu( QListBoxItem *, const QPoint &pos )
00355 {
00356 int choice = mPopupMenu->exec( pos );
00357
00358 if ( choice == -1 )
00359 return;
00360
00361 mSidePane->resetWidth();
00362 if ( choice >= SmallIcons ) {
00363 mSidePane->setViewMode( mSidePane->sizeIntToEnum( choice ) );
00364 mPopupMenu->setItemChecked( (int)SmallIcons, false);
00365 mPopupMenu->setItemChecked( (int)NormalIcons, false);
00366 mPopupMenu->setItemChecked( (int)LargeIcons, false);
00367 mPopupMenu->setItemChecked( mSidePane->viewMode(), true);
00368 KoShellSettings::setSidePaneIconSize( choice );
00369 }
00370 else
00371 {
00372
00373 if ( choice == ShowIcons ) {
00374 mSidePane->toogleIcons();
00375 mPopupMenu->setItemChecked( (int)ShowIcons, mSidePane->showIcons() );
00376 mPopupMenu->setItemEnabled( (int)ShowText, mSidePane->showIcons() );
00377 mPopupMenu->setItemEnabled( (int)SmallIcons, mSidePane->showIcons());
00378 mPopupMenu->setItemEnabled( (int)NormalIcons, mSidePane->showIcons());
00379 mPopupMenu->setItemEnabled( (int)LargeIcons, mSidePane->showIcons());
00380 KoShellSettings::setSidePaneShowIcons( mSidePane->showIcons() );
00381
00382 QToolTip::remove( this );
00383 } else {
00384 mSidePane->toogleText();
00385 mSidePane->resetWidth();
00386 mPopupMenu->setItemChecked( (int)ShowText, mSidePane->showText() );
00387 mPopupMenu->setItemEnabled( (int)ShowIcons, mSidePane->showText() );
00388 mPopupMenu->setItemEnabled( (int)SmallIcons, true);
00389 mPopupMenu->setItemEnabled( (int)NormalIcons, true);
00390 mPopupMenu->setItemEnabled( (int)LargeIcons, true);
00391 KoShellSettings::setSidePaneShowText( mSidePane->showText() );
00392 new EntryItemToolTip( this );
00393
00394
00395
00396
00397 }
00398 }
00399 calculateMinWidth();
00400 emit updateAllWidgets();
00401 }
00402
00403
00404
00405 IconSidePane::IconSidePane(QWidget *parent, const char *name )
00406 : QVBox( parent, name )
00407 {
00408 m_buttongroup = new QButtonGroup(1, QGroupBox::Horizontal, this);
00409 m_buttongroup->setExclusive(true);
00410 m_buttongroup->hide();
00411 mWidgetstack = new QWidgetStack(this);
00412 mWidgetstack->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
00413
00414
00415 mShowIcons = KoShellSettings::sidePaneShowIcons();
00416 mShowText = KoShellSettings::sidePaneShowText();
00417 mViewMode = sizeIntToEnum( KoShellSettings::sidePaneIconSize() );
00418 mPopupMenu = new KPopupMenu(0);
00419 mPopupMenu->insertTitle( i18n( "Icon Size" ) );
00420 mPopupMenu->insertItem( i18n( "Large" ), (int)LargeIcons );
00421 mPopupMenu->setItemEnabled( (int)LargeIcons, mShowIcons );
00422 mPopupMenu->insertItem( i18n( "Normal" ), (int)NormalIcons );
00423 mPopupMenu->setItemEnabled( (int)NormalIcons, mShowIcons );
00424 mPopupMenu->insertItem( i18n( "Small" ), (int)SmallIcons );
00425 mPopupMenu->setItemEnabled( (int)SmallIcons, mShowIcons );
00426 mPopupMenu->setItemChecked( (int)mViewMode, true );
00427 mPopupMenu->insertSeparator();
00428 mPopupMenu->insertItem( i18n( "Show Icons" ), (int)ShowIcons );
00429 mPopupMenu->setItemChecked( (int)ShowIcons, mShowIcons );
00430 mPopupMenu->setItemEnabled( (int)ShowIcons, mShowText );
00431 mPopupMenu->insertItem( i18n( "Show Text" ), (int)ShowText );
00432 mPopupMenu->setItemChecked( (int)ShowText, mShowText );
00433 mPopupMenu->setItemEnabled( (int)ShowText, mShowIcons );
00434 if ( !mShowText )
00435 m_buttongroup->hide();
00436 }
00437
00438 IconSidePane::~IconSidePane()
00439 {
00440 }
00441
00442 int IconSidePane::insertItem(int _grp, const QString & _pix, const QString &_text)
00443 {
00444 return static_cast<Navigator*>( mWidgetstack->widget(_grp))->insertItem( _text, _pix );
00445 }
00446
00447 int IconSidePane::insertItem(const QString & _pix, const QString &_text)
00448 {
00449 return mCurrentNavigator->insertItem(_text, _pix);
00450 }
00451
00452 void IconSidePane::renameItem( int _grp, int _id, const QString & _text )
00453 {
00454 Navigator *navigator = static_cast<Navigator*>(mWidgetstack->widget(_grp));
00455 if (!navigator)
00456 return;
00457 EntryItem *item = 0;
00458 for (uint i=0; i< navigator->count(); i++)
00459 {
00460 item = static_cast<EntryItem *>(navigator->item(i));
00461 if (_id == item->id())
00462 {
00463 item->setNewText(_text);
00464 navigator->triggerUpdate(false);
00465 break;
00466 }
00467 }
00468 }
00469
00470 void IconSidePane::removeItem( int _grp, int _id )
00471 {
00472 Navigator *navigator = static_cast<Navigator*>(mWidgetstack->widget(_grp));
00473 if (!navigator)
00474 return;
00475 for (uint i=0; i< navigator->count(); i++)
00476 {
00477 if (_id == static_cast<EntryItem *>(navigator->item(i))->id())
00478 {
00479 navigator->removeItem(i);
00480 break;
00481 }
00482 }
00483 }
00484
00485 int IconSidePane::insertGroup(const QString &_text, bool _selectable, QObject *_obj, const char *_slot)
00486 {
00487 mCurrentNavigator = new Navigator(_selectable, mPopupMenu, this, mWidgetstack );
00488
00489 if ( _obj != 0L && _slot != 0L )
00490 connect( mCurrentNavigator, SIGNAL( itemSelected(int ) ), _obj, _slot );
00491 connect( mCurrentNavigator, SIGNAL( updateAllWidgets() ), this, SLOT(updateAllWidgets()) );
00492 int const id = mWidgetstack->addWidget(mCurrentNavigator);
00493 mWidgetStackIds.append( id );
00494 KPushButton *b = new KPushButton( _text, m_buttongroup );
00495 m_buttongroup->insert( b, id );
00496 connect( b, SIGNAL( clicked() ), this, SLOT( buttonClicked() ) );
00497 b->setToggleButton( true );
00498 b->setFocusPolicy( NoFocus );
00499 if (m_buttongroup->count()==1)
00500 {
00501 mCurrentNavigator->calculateMinWidth();
00502 m_buttongroup->setButton(m_buttongroup->id(b));
00503 mWidgetstack->raiseWidget(id);
00504 }
00505 if ( b->width() > minimumWidth() )
00506 setMinimumWidth( b->width() );
00507 return id;
00508 }
00509
00510 void IconSidePane::buttonClicked()
00511 {
00512 mWidgetstack->raiseWidget( m_buttongroup->selectedId() );
00513 }
00514
00515 void IconSidePane::selectGroup(int group_id)
00516 {
00517 mWidgetstack->raiseWidget(group_id);
00518 }
00519
00520 void IconSidePane::itemSelected(int item)
00521 {
00522 kdDebug() << "Item selected:" << item << endl;
00523 }
00524
00525 Navigator * IconSidePane::group(int _grp)
00526 {
00527 return static_cast<Navigator*>(mWidgetstack->widget(_grp));
00528 }
00529
00530 void IconSidePane::updateAllWidgets()
00531 {
00532 QValueList<int>::iterator it;
00533 for ( it = mWidgetStackIds.begin(); it != mWidgetStackIds.end(); ++it )
00534 static_cast<Navigator*>(mWidgetstack->widget(*it))->triggerUpdate( true );
00535 }
00536
00537 int IconSidePane::minWidth()
00538 {
00539 int width = 0;
00540 QValueList<int>::iterator it;
00541 Navigator *n;
00542 for ( it = mWidgetStackIds.begin(); it != mWidgetStackIds.end(); ++it )
00543 {
00544 n = static_cast<Navigator*>(mWidgetstack->widget(*it));
00545 if ( n->minWidth() > width )
00546 width = n->minWidth();
00547 }
00548 return width;
00549 }
00550
00551 void IconSidePane::resetWidth()
00552 {
00553 QValueList<int>::iterator it;
00554 Navigator *n;
00555 for ( it = mWidgetStackIds.begin(); it != mWidgetStackIds.end(); ++it )
00556 {
00557 n = static_cast<Navigator*>(mWidgetstack->widget(*it));
00558 n->resetWidth();
00559 n->triggerUpdate(true);
00560 }
00561 }
00562
00563 IconViewMode IconSidePane::sizeIntToEnum(int size) const
00564 {
00565 switch ( size ) {
00566 case int(LargeIcons):
00567 return LargeIcons;
00568 break;
00569 case int(NormalIcons):
00570 return NormalIcons;
00571 break;
00572 case int(SmallIcons):
00573 return SmallIcons;
00574 break;
00575 default:
00576
00577 return NormalIcons;
00578 kdDebug() << "View mode not implemented!" << endl;
00579 break;
00580 }
00581 }
00582
00583 void IconSidePane::setActionCollection( KActionCollection *actionCollection )
00584 {
00585 mActionCollection = actionCollection;
00586 }
00587
00588 KActionCollection *IconSidePane::actionCollection() const
00589 {
00590 return mActionCollection;
00591 }
00592
00593 #include "iconsidepane.moc"
00594
00595