00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <tqptrlist.h>
00023 #include <tqwidgetstack.h>
00024 #include <tqsignal.h>
00025 #include <tqobjectlist.h>
00026 #include <tqlabel.h>
00027 #include <tqimage.h>
00028 #include <tqpainter.h>
00029 #include <tqbitmap.h>
00030 #include <tqfontmetrics.h>
00031 #include <tqsignalmapper.h>
00032 #include <tqstyle.h>
00033 #include <tqframe.h>
00034 #include <tqdrawutil.h>
00035 #include <tqcursor.h>
00036 #include <tqtimer.h>
00037 #include <tqtooltip.h>
00038
00039 #include <kpopupmenu.h>
00040 #include <kapplication.h>
00041 #include <kdialog.h>
00042 #include <klocale.h>
00043 #include <kiconloader.h>
00044 #include <sidebarextension.h>
00045
00046 #include <kdebug.h>
00047
00048 #include "mainwindow.h"
00049
00050 #include "plugin.h"
00051
00052 #include "prefs.h"
00053 #include "iconsidepane.h"
00054
00055 namespace Kontact
00056 {
00057
00058
00059
00060 class PluginProxy
00061 {
00062 public:
00063 PluginProxy()
00064 : mPlugin( 0 )
00065 { }
00066
00067 PluginProxy( Plugin *plugin )
00068 : mPlugin( plugin )
00069 { }
00070
00071 PluginProxy & operator=( Plugin *plugin )
00072 {
00073 mPlugin = plugin;
00074 return *this;
00075 }
00076
00077 bool operator<( PluginProxy &rhs ) const
00078 {
00079 return mPlugin->weight() < rhs.mPlugin->weight();
00080 }
00081
00082 Plugin *plugin() const
00083 {
00084 return mPlugin;
00085 }
00086
00087 private:
00088 Plugin *mPlugin;
00089 };
00090
00091 }
00092
00093 using namespace Kontact;
00094
00095 EntryItem::EntryItem( Navigator *parent, Kontact::Plugin *plugin )
00096 : TQListBoxItem( parent ),
00097 mPlugin( plugin ),
00098 mHasHover( false ),
00099 mPaintActive( false )
00100 {
00101 reloadPixmap();
00102 setCustomHighlighting( true );
00103 setText( plugin->title() );
00104 }
00105
00106 EntryItem::~EntryItem()
00107 {
00108 }
00109
00110 void EntryItem::reloadPixmap()
00111 {
00112 int size = (int)navigator()->viewMode();
00113 if ( size != 0 )
00114 mPixmap = KGlobal::iconLoader()->loadIcon( mPlugin->icon(),
00115 KIcon::Desktop, size,
00116 mPlugin->disabled() ?
00117 KIcon::DisabledState
00118 : KIcon::DefaultState);
00119 else
00120 mPixmap = TQPixmap();
00121 }
00122
00123 Navigator* EntryItem::navigator() const
00124 {
00125 return static_cast<Navigator*>( listBox() );
00126 }
00127
00128 int EntryItem::width( const TQListBox *listbox ) const
00129 {
00130 int w = 0;
00131 if( navigator()->showIcons() ) {
00132 w = navigator()->viewMode();
00133 if ( navigator()->viewMode() == SmallIcons )
00134 w += 4;
00135 }
00136 if( navigator()->showText() ) {
00137 if ( navigator()->viewMode() == SmallIcons )
00138 w += listbox->fontMetrics().width( text() );
00139 else
00140 w = TQMAX( w, listbox->fontMetrics().width( text() ) );
00141 }
00142 return w + ( KDialog::marginHint() * 2 );
00143 }
00144
00145 int EntryItem::height( const TQListBox *listbox ) const
00146 {
00147 int h = 0;
00148 if ( navigator()->showIcons() )
00149 h = (int)navigator()->viewMode() + 4;
00150 if ( navigator()->showText() ) {
00151 if ( navigator()->viewMode() == SmallIcons || !navigator()->showIcons() )
00152 h = TQMAX( h, listbox->fontMetrics().lineSpacing() ) + KDialog::spacingHint() * 2;
00153 else
00154 h = (int)navigator()->viewMode() + listbox->fontMetrics().lineSpacing() + 4;
00155 }
00156 return h;
00157 }
00158
00159 void EntryItem::paint( TQPainter *p )
00160 {
00161 reloadPixmap();
00162
00163 TQListBox *box = listBox();
00164 bool iconAboveText = ( navigator()->viewMode() > SmallIcons )
00165 && navigator()->showIcons();
00166 int w = box->viewport()->width();
00167 int y = iconAboveText ? 2 :
00168 ( ( height( box ) - mPixmap.height() ) / 2 );
00169
00170
00171 if ( isCurrent() || isSelected() || mHasHover || mPaintActive ) {
00172 int h = height( box );
00173
00174 TQBrush brush;
00175 if ( isCurrent() || isSelected() || mPaintActive )
00176 brush = box->colorGroup().brush( TQColorGroup::Highlight );
00177 else
00178 brush = TQBrush(box->colorGroup().highlight().light( 115 ));
00179 p->fillRect( 1, 0, w - 2, h - 1, brush );
00180 TQPen pen = p->pen();
00181 TQPen oldPen = pen;
00182 pen.setColor( box->colorGroup().mid() );
00183 p->setPen( pen );
00184
00185 p->drawPoint( 1, 0 );
00186 p->drawPoint( 1, h - 2 );
00187 p->drawPoint( w - 2, 0 );
00188 p->drawPoint( w - 2, h - 2 );
00189
00190 p->setPen( oldPen );
00191 }
00192
00193 if ( !mPixmap.isNull() && navigator()->showIcons() ) {
00194 int x = iconAboveText ? ( ( w - mPixmap.width() ) / 2 ) :
00195 KDialog::marginHint();
00196 p->drawPixmap( x, y, mPixmap );
00197 }
00198
00199 TQColor shadowColor = listBox()->colorGroup().background().dark(115);
00200 if ( isCurrent() || isSelected() ) {
00201 p->setPen( box->colorGroup().highlightedText() );
00202 }
00203
00204 if ( !text().isEmpty() && navigator()->showText() ) {
00205 TQFontMetrics fm = p->fontMetrics();
00206
00207 int x = 0;
00208 if ( iconAboveText ) {
00209 x = ( w - fm.width( text() ) ) / 2;
00210 y += fm.height() - fm.descent();
00211 if ( navigator()->showIcons() )
00212 y += mPixmap.height();
00213 } else {
00214 x = KDialog::marginHint() + 4;
00215 if( navigator()->showIcons() ) {
00216 x += mPixmap.width();
00217 }
00218
00219 if ( !navigator()->showIcons() || mPixmap.height() < fm.height() )
00220 y = height( box )/2 - fm.height()/2 + fm.ascent();
00221 else
00222 y += mPixmap.height()/2 - fm.height()/2 + fm.ascent();
00223 }
00224
00225 if ( plugin()->disabled() ) {
00226 p->setPen( box->palette().disabled().text( ) );
00227 } else if ( isCurrent() || isSelected() || mHasHover ) {
00228 p->setPen( box->colorGroup().highlight().dark(115) );
00229 p->drawText( x + ( TQApplication::reverseLayout() ? -1 : 1),
00230 y + 1, text() );
00231 p->setPen( box->colorGroup().highlightedText() );
00232 }
00233 else
00234 p->setPen( box->colorGroup().text() );
00235
00236 p->drawText( x, y, text() );
00237 }
00238
00239
00240 if ( isCurrent() || isSelected() ) mHasHover = false;
00241 }
00242
00243 void EntryItem::setHover( bool hasHover )
00244 {
00245 mHasHover = hasHover;
00246 }
00247
00248 void EntryItem::setPaintActive( bool paintActive )
00249 {
00250 mPaintActive = paintActive;
00251 }
00252
00253 Navigator::Navigator( IconSidePane *parent, const char *name )
00254 : KListBox( parent, name ), mSidePane( parent ),
00255 mShowIcons( true ), mShowText( true )
00256 {
00257 mMouseOn = 0;
00258 mHighlightItem = 0;
00259 mViewMode = sizeIntToEnum( Prefs::self()->sidePaneIconSize() );
00260 mShowIcons = Prefs::self()->sidePaneShowIcons();
00261 mShowText = Prefs::self()->sidePaneShowText();
00262 setSelectionMode( KListBox::Single );
00263 viewport()->setBackgroundMode( PaletteBackground );
00264 setFrameStyle( TQFrame::NoFrame );
00265 setHScrollBarMode( TQScrollView::AlwaysOff );
00266 setAcceptDrops( true );
00267
00268 setFocusPolicy( TQ_NoFocus );
00269
00270 connect( this, TQT_SIGNAL( selectionChanged( TQListBoxItem* ) ),
00271 TQT_SLOT( slotExecuted( TQListBoxItem* ) ) );
00272 connect( this, TQT_SIGNAL( rightButtonPressed( TQListBoxItem*, const TQPoint& ) ),
00273 TQT_SLOT( slotShowRMBMenu( TQListBoxItem*, const TQPoint& ) ) );
00274 connect( this, TQT_SIGNAL( onItem( TQListBoxItem * ) ),
00275 TQT_SLOT( slotMouseOn( TQListBoxItem * ) ) );
00276 connect( this, TQT_SIGNAL( onViewport() ), TQT_SLOT( slotMouseOff() ) );
00277
00278 mMapper = new TQSignalMapper( TQT_TQOBJECT(this) );
00279 connect( mMapper, TQT_SIGNAL( mapped( int ) ), TQT_SLOT( shortCutSelected( int ) ) );
00280
00281 TQToolTip::remove( this );
00282 if ( !mShowText )
00283 new EntryItemToolTip( this );
00284
00285 }
00286
00287 TQSize Navigator::sizeHint() const
00288 {
00289 return TQSize( 100, 100 );
00290 }
00291
00292 void Navigator::highlightItem( EntryItem * item )
00293 {
00294 mHighlightItem = item;
00295
00296 setPaintActiveItem( mHighlightItem, true );
00297
00298 TQTimer::singleShot( 2000, this, TQT_SLOT( slotStopHighlight() ) );
00299 }
00300
00301 void Navigator::slotStopHighlight()
00302 {
00303 setPaintActiveItem( mHighlightItem, false );
00304 }
00305
00306 void Navigator::setSelected( TQListBoxItem *item, bool selected )
00307 {
00308
00309
00310
00311 if ( selected ) {
00312 EntryItem *entry = static_cast<EntryItem*>( item );
00313 emit pluginActivated( entry->plugin() );
00314 }
00315 }
00316
00317 void Navigator::updatePlugins( TQValueList<Kontact::Plugin*> plugins_ )
00318 {
00319 TQValueList<Kontact::PluginProxy> plugins;
00320 TQValueList<Kontact::Plugin*>::ConstIterator end_ = plugins_.end();
00321 TQValueList<Kontact::Plugin*>::ConstIterator it_ = plugins_.begin();
00322 for ( ; it_ != end_; ++it_ )
00323 plugins += PluginProxy( *it_ );
00324
00325 clear();
00326
00327 mActions.setAutoDelete( true );
00328 mActions.clear();
00329 mActions.setAutoDelete( false );
00330
00331 int minWidth = 0;
00332 qBubbleSort( plugins );
00333 TQValueList<Kontact::PluginProxy>::ConstIterator end = plugins.end();
00334 TQValueList<Kontact::PluginProxy>::ConstIterator it = plugins.begin();
00335 for ( ; it != end; ++it ) {
00336 Kontact::Plugin *plugin = ( *it ).plugin();
00337 if ( !plugin->showInSideBar() )
00338 continue;
00339
00340 EntryItem *item = new EntryItem( this, plugin );
00341 item->setSelectable( !plugin->disabled() );
00342
00343 if ( item->width( this ) > minWidth )
00344 minWidth = item->width( this );
00345 }
00346
00347 parentWidget()->setFixedWidth( minWidth );
00348 }
00349
00350 void Navigator::dragEnterEvent( TQDragEnterEvent *event )
00351 {
00352 kdDebug(5600) << "Navigator::dragEnterEvent()" << endl;
00353
00354 dragMoveEvent( event );
00355 }
00356
00357 void Navigator::dragMoveEvent( TQDragMoveEvent *event )
00358 {
00359 kdDebug(5600) << "Navigator::dragEnterEvent()" << endl;
00360
00361 kdDebug(5600) << " Format: " << event->format() << endl;
00362
00363 TQListBoxItem *item = itemAt( event->pos() );
00364
00365 if ( !item ) {
00366 event->accept( false );
00367 return;
00368 }
00369
00370 EntryItem *entry = static_cast<EntryItem*>( item );
00371
00372 kdDebug(5600) << " PLUGIN: " << entry->plugin()->identifier() << endl;
00373
00374 event->accept( entry->plugin()->canDecodeDrag( event ) );
00375 }
00376
00377 void Navigator::dropEvent( TQDropEvent *event )
00378 {
00379 kdDebug(5600) << "Navigator::dropEvent()" << endl;
00380
00381 TQListBoxItem *item = itemAt( event->pos() );
00382
00383 if ( !item ) {
00384 return;
00385 }
00386
00387 EntryItem *entry = static_cast<EntryItem*>( item );
00388
00389 kdDebug(5600) << " PLUGIN: " << entry->plugin()->identifier() << endl;
00390
00391 entry->plugin()->processDropEvent( event );
00392 }
00393
00394 void Navigator::resizeEvent( TQResizeEvent *event )
00395 {
00396 TQListBox::resizeEvent( event );
00397 triggerUpdate( true );
00398 }
00399
00400 void Navigator::enterEvent( TQEvent *event )
00401 {
00402
00403 KListBox::enterEvent( event );
00404 emit onItem( itemAt( mapFromGlobal( TQCursor::pos() ) ) );
00405 }
00406
00407 void Navigator::leaveEvent( TQEvent *event )
00408 {
00409 KListBox::leaveEvent( event );
00410 slotMouseOn( 0 );
00411 mMouseOn = 0;
00412 }
00413
00414 void Navigator::slotExecuted( TQListBoxItem *item )
00415 {
00416 if ( !item )
00417 return;
00418
00419 EntryItem *entry = static_cast<EntryItem*>( item );
00420
00421 emit pluginActivated( entry->plugin() );
00422 }
00423
00424 IconViewMode Navigator::sizeIntToEnum(int size) const
00425 {
00426 switch ( size ) {
00427 case int(LargeIcons):
00428 return LargeIcons;
00429 break;
00430 case int(NormalIcons):
00431 return NormalIcons;
00432 break;
00433 case int(SmallIcons):
00434 return SmallIcons;
00435 break;
00436 default:
00437
00438 return NormalIcons;
00439 kdDebug() << "View mode not implemented!" << endl;
00440 break;
00441 }
00442 }
00443
00444 void Navigator::slotShowRMBMenu( TQListBoxItem *, const TQPoint &pos )
00445 {
00446 KPopupMenu menu;
00447 menu.insertTitle( i18n( "Icon Size" ) );
00448 menu.insertItem( i18n( "Large" ), (int)LargeIcons );
00449 menu.setItemEnabled( (int)LargeIcons, mShowIcons );
00450 menu.insertItem( i18n( "Normal" ), (int)NormalIcons );
00451 menu.setItemEnabled( (int)NormalIcons, mShowIcons );
00452 menu.insertItem( i18n( "Small" ), (int)SmallIcons );
00453 menu.setItemEnabled( (int)SmallIcons, mShowIcons );
00454
00455 menu.setItemChecked( (int)mViewMode, true );
00456 menu.insertSeparator();
00457
00458 menu.insertItem( i18n( "Show Icons" ), (int)ShowIcons );
00459 menu.setItemChecked( (int)ShowIcons, mShowIcons );
00460 menu.setItemEnabled( (int)ShowIcons, mShowText );
00461 menu.insertItem( i18n( "Show Text" ), (int)ShowText );
00462 menu.setItemChecked( (int)ShowText, mShowText );
00463 menu.setItemEnabled( (int)ShowText, mShowIcons );
00464 int choice = menu.exec( pos );
00465
00466 if ( choice == -1 )
00467 return;
00468
00469 if ( choice >= SmallIcons ) {
00470 mViewMode = sizeIntToEnum( choice );
00471 Prefs::self()->setSidePaneIconSize( choice );
00472 } else {
00473
00474 if ( choice == ShowIcons ) {
00475 mShowIcons = !mShowIcons;
00476 Prefs::self()->setSidePaneShowIcons( mShowIcons );
00477 TQToolTip::remove( this );
00478 if ( !mShowText )
00479 new EntryItemToolTip( this );
00480 } else {
00481 mShowText = !mShowText;
00482 Prefs::self()->setSidePaneShowText( mShowText );
00483 TQToolTip::remove( this );
00484 }
00485 }
00486 int maxWidth = 0;
00487 TQListBoxItem* it = 0;
00488 for (int i = 0; (it = item(i)) != 0; ++i)
00489 {
00490 int width = it->width(this);
00491 if (width > maxWidth)
00492 maxWidth = width;
00493 }
00494 parentWidget()->setFixedWidth( maxWidth );
00495
00496 triggerUpdate( true );
00497 }
00498
00499 void Navigator::shortCutSelected( int pos )
00500 {
00501 setCurrentItem( pos );
00502 }
00503
00504 void Navigator::setHoverItem( TQListBoxItem* item, bool hover )
00505 {
00506 static_cast<EntryItem*>( item )->setHover( hover );
00507 updateItem( item );
00508 }
00509
00510 void Navigator::setPaintActiveItem( TQListBoxItem* item, bool paintActive )
00511 {
00512 static_cast<EntryItem*>( item )->setPaintActive( paintActive );
00513 updateItem( item );
00514 }
00515
00516 void Navigator::slotMouseOn( TQListBoxItem* newItem )
00517 {
00518 TQListBoxItem* oldItem = mMouseOn;
00519 if ( oldItem == newItem ) return;
00520
00521 if ( oldItem && !oldItem->isCurrent() && !oldItem->isSelected() )
00522 {
00523 setHoverItem( oldItem, false );
00524 }
00525
00526 if ( newItem && !newItem->isCurrent() && !newItem->isSelected() )
00527 {
00528 setHoverItem( newItem, true );
00529 }
00530 mMouseOn = newItem;
00531 }
00532
00533 void Navigator::slotMouseOff()
00534 {
00535 slotMouseOn( 0 );
00536 }
00537
00538 IconSidePane::IconSidePane( Core *core, TQWidget *parent, const char *name )
00539 : SidePaneBase( core, parent, name )
00540 {
00541 mNavigator = new Navigator( this );
00542 connect( mNavigator, TQT_SIGNAL( pluginActivated( Kontact::Plugin* ) ),
00543 TQT_SIGNAL( pluginSelected( Kontact::Plugin* ) ) );
00544
00545 setAcceptDrops( true );
00546 }
00547
00548 IconSidePane::~IconSidePane()
00549 {
00550 }
00551
00552 void IconSidePane::updatePlugins()
00553 {
00554 mNavigator->updatePlugins( core()->pluginList() );
00555 }
00556
00557 void IconSidePane::selectPlugin( Kontact::Plugin *plugin )
00558 {
00559 bool blocked = signalsBlocked();
00560 blockSignals( true );
00561
00562 for ( uint i = 0; i < mNavigator->count(); ++i ) {
00563 EntryItem *item = static_cast<EntryItem*>( mNavigator->item( i ) );
00564 if ( item->plugin() == plugin ) {
00565 mNavigator->setCurrentItem( i );
00566 break;
00567 }
00568 }
00569
00570 blockSignals( blocked );
00571 }
00572
00573 void IconSidePane::selectPlugin( const TQString &name )
00574 {
00575 bool blocked = signalsBlocked();
00576 blockSignals( true );
00577
00578 for ( uint i = 0; i < mNavigator->count(); ++i ) {
00579 EntryItem *item = static_cast<EntryItem*>( mNavigator->item( i ) );
00580 if ( item->plugin()->identifier() == name ) {
00581 mNavigator->setCurrentItem( i );
00582 break;
00583 }
00584 }
00585
00586 blockSignals( blocked );
00587 }
00588
00589 void IconSidePane::indicateForegrunding( Kontact::Plugin *plugin )
00590 {
00591 for ( uint i = 0; i < mNavigator->count(); ++i ) {
00592 EntryItem *item = static_cast<EntryItem*>( mNavigator->item( i ) );
00593 if ( item->plugin() == plugin ) {
00594 mNavigator->highlightItem( item );
00595 break;
00596 }
00597 }
00598
00599
00600 }
00601 #include "iconsidepane.moc"
00602
00603