keylistview.cpp
00001 /* 00002 keylistview.cpp 00003 00004 This file is part of libkleopatra, the KDE keymanagement library 00005 Copyright (c) 2004 Klarälvdalens Datakonsult AB 00006 00007 Libkleopatra is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU General Public License as 00009 published by the Free Software Foundation; either version 2 of the 00010 License, or (at your option) any later version. 00011 00012 Libkleopatra is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program; if not, write to the Free Software 00019 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 00021 In addition, as a special exception, the copyright holders give 00022 permission to link the code of this program with any edition of 00023 the TQt library by Trolltech AS, Norway (or with modified versions 00024 of TQt that use the same license as TQt), and distribute linked 00025 combinations including the two. You must obey the GNU General 00026 Public License in all respects for all of the code used other than 00027 TQt. If you modify this file, you may extend this exception to 00028 your version of the file, but you are not obligated to do so. If 00029 you do not wish to do so, delete this exception statement from 00030 your version. 00031 */ 00032 00033 #ifdef HAVE_CONFIG_H 00034 #include <config.h> 00035 #endif 00036 00037 #include "keylistview.h" 00038 00039 #include <kdebug.h> 00040 00041 #include <tqfontmetrics.h> 00042 #include <tqtooltip.h> 00043 #include <tqrect.h> 00044 #include <tqheader.h> 00045 #include <tqpoint.h> 00046 #include <tqptrlist.h> 00047 #include <tqpainter.h> 00048 #include <tqfont.h> 00049 #include <tqcolor.h> 00050 #include <tqtimer.h> 00051 #include <tqcstring.h> 00052 00053 #include <gpgmepp/key.h> 00054 00055 #include <vector> 00056 #include <map> 00057 00058 #include <assert.h> 00059 00060 static const int updateDelayMilliSecs = 500; 00061 00062 namespace { 00063 00064 class ItemToolTip : public TQToolTip { 00065 public: 00066 ItemToolTip( Kleo::KeyListView * parent ); 00067 protected: 00068 void maybeTip( const TQPoint & p ); 00069 private: 00070 Kleo::KeyListView * mKeyListView; 00071 }; 00072 00073 ItemToolTip::ItemToolTip( Kleo::KeyListView * parent ) 00074 : TQToolTip( parent->viewport() ), mKeyListView( parent ) {} 00075 00076 void ItemToolTip::maybeTip( const TQPoint & p ) { 00077 if ( !mKeyListView ) 00078 return; 00079 00080 const TQListViewItem * item = mKeyListView->itemAt( p ); 00081 if ( !item ) 00082 return; 00083 00084 const TQRect itemRect = mKeyListView->itemRect( item ); 00085 if ( !itemRect.isValid() ) 00086 return; 00087 00088 const int col = mKeyListView->header()->sectionAt( p.x() ); 00089 if ( col == -1 ) 00090 return; 00091 00092 const TQRect headerRect = mKeyListView->header()->sectionRect( col ); 00093 if ( !headerRect.isValid() ) 00094 return; 00095 00096 const TQRect cellRect( headerRect.left(), itemRect.top(), 00097 headerRect.width(), itemRect.height() ); 00098 00099 TQString tipStr; 00100 if ( const Kleo::KeyListViewItem * klvi = Kleo::lvi_cast<Kleo::KeyListViewItem>( item ) ) 00101 tipStr = klvi->toolTip( col ); 00102 else 00103 tipStr = item->text( col ) ; 00104 00105 if ( !tipStr.isEmpty() ) 00106 tip( cellRect, tipStr ); 00107 } 00108 00109 } // anon namespace 00110 00111 struct Kleo::KeyListView::Private { 00112 Private() : updateTimer( 0 ), itemToolTip( 0 ) {} 00113 00114 std::vector<GpgME::Key> keyBuffer; 00115 TQTimer * updateTimer; 00116 TQToolTip * itemToolTip; 00117 std::map<TQCString,KeyListViewItem*> itemMap; 00118 }; 00119 00120 // a list of signals where we want to replace TQListViewItem with 00121 // Kleo:KeyListViewItem: 00122 static const struct { 00123 const char * source; 00124 const char * target; 00125 } signalReplacements[] = { 00126 { TQT_SIGNAL(doubleClicked(TQListViewItem*,const TQPoint&,int)), 00127 TQT_SLOT(slotEmitDoubleClicked(TQListViewItem*,const TQPoint&,int)) }, 00128 { TQT_SIGNAL(returnPressed(TQListViewItem*)), 00129 TQT_SLOT(slotEmitReturnPressed(TQListViewItem*)) }, 00130 { TQT_SIGNAL(selectionChanged(TQListViewItem*)), 00131 TQT_SLOT(slotEmitSelectionChanged(TQListViewItem*)) }, 00132 { TQT_SIGNAL(contextMenu(TDEListView*, TQListViewItem*,const TQPoint&)), 00133 TQT_SLOT(slotEmitContextMenu(TDEListView*, TQListViewItem*,const TQPoint&)) }, 00134 }; 00135 static const int numSignalReplacements = sizeof signalReplacements / sizeof *signalReplacements; 00136 00137 00138 Kleo::KeyListView::KeyListView( const ColumnStrategy * columnStrategy, const DisplayStrategy * displayStrategy, TQWidget * parent, const char * name, WFlags f ) 00139 : TDEListView( parent, name ), 00140 mColumnStrategy( columnStrategy ), 00141 mDisplayStrategy ( displayStrategy ), 00142 mHierarchical( false ) 00143 { 00144 setWFlags( f ); 00145 00146 d = new Private(); 00147 00148 d->updateTimer = new TQTimer( this ); 00149 connect( d->updateTimer, TQT_SIGNAL(timeout()), TQT_SLOT(slotUpdateTimeout()) ); 00150 00151 if ( !columnStrategy ) { 00152 kdWarning(5150) << "Kleo::KeyListView: need a column strategy to work with!" << endl; 00153 return; 00154 } 00155 00156 const TQFontMetrics fm = fontMetrics(); 00157 00158 for ( int col = 0 ; !columnStrategy->title( col ).isEmpty() ; ++col ) { 00159 addColumn( columnStrategy->title( col ), columnStrategy->width( col, fm ) ); 00160 setColumnWidthMode( col, columnStrategy->widthMode( col ) ); 00161 } 00162 00163 setAllColumnsShowFocus( true ); 00164 setShowToolTips( false ); // we do it instead... 00165 00166 for ( int i = 0 ; i < numSignalReplacements ; ++i ) 00167 connect( this, signalReplacements[i].source, signalReplacements[i].target ); 00168 00169 TQToolTip::remove( this ); 00170 TQToolTip::remove( viewport() ); // make double sure :) 00171 d->itemToolTip = new ItemToolTip( this ); 00172 } 00173 00174 Kleo::KeyListView::~KeyListView() { 00175 d->updateTimer->stop(); 00176 // need to clear here, since in ~TQListView, our children won't have 00177 // a valid listView() pointing to us anymore, and their dtors try to 00178 // unregister from us. 00179 clear(); 00180 assert( d->itemMap.size() == 0 ); 00181 // need to delete the tooltip ourselves, as ~TQToolTip isn't virtual :o 00182 delete d->itemToolTip; d->itemToolTip = 0; 00183 delete d; d = 0; 00184 delete mColumnStrategy; mColumnStrategy = 0; 00185 delete mDisplayStrategy; mDisplayStrategy = 0; 00186 } 00187 00188 void Kleo::KeyListView::insertItem( TQListViewItem * qlvi ) { 00189 //kdDebug() << "Kleo::KeyListView::insertItem( " << qlvi << " )" << endl; 00190 TDEListView::insertItem( qlvi ); 00191 if ( KeyListViewItem * item = lvi_cast<KeyListViewItem>( qlvi ) ) 00192 registerItem( item ); 00193 } 00194 00195 void Kleo::KeyListView::takeItem( TQListViewItem * qlvi ) { 00196 //kdDebug() << "Kleo::KeyListView::takeItem( " << qlvi << " )" << endl; 00197 if ( KeyListViewItem * item = lvi_cast<KeyListViewItem>( qlvi ) ) 00198 deregisterItem( item ); 00199 TDEListView::takeItem( qlvi ); 00200 } 00201 00202 00203 void Kleo::KeyListView::setHierarchical( bool hier ) { 00204 if ( hier == mHierarchical ) 00205 return; 00206 mHierarchical = hier; 00207 if ( hier ) 00208 gatherScattered(); 00209 else 00210 scatterGathered( firstChild() ); 00211 } 00212 00213 void Kleo::KeyListView::slotAddKey( const GpgME::Key & key ) { 00214 if ( key.isNull() ) 00215 return; 00216 00217 d->keyBuffer.push_back( key ); 00218 if ( !d->updateTimer->isActive() ) 00219 d->updateTimer->start( updateDelayMilliSecs, true /* single-shot */ ); 00220 } 00221 00222 void Kleo::KeyListView::slotUpdateTimeout() { 00223 if ( d->keyBuffer.empty() ) 00224 return; 00225 00226 const bool wasUpdatesEnabled = viewport()->isUpdatesEnabled(); 00227 if ( wasUpdatesEnabled ) 00228 viewport()->setUpdatesEnabled( false ); 00229 kdDebug( 5150 ) << "Kleo::KeyListView::slotUpdateTimeout(): processing " 00230 << d->keyBuffer.size() << " items en block" << endl; 00231 if ( hierarchical() ) { 00232 for ( std::vector<GpgME::Key>::const_iterator it = d->keyBuffer.begin() ; it != d->keyBuffer.end() ; ++it ) 00233 doHierarchicalInsert( *it ); 00234 gatherScattered(); 00235 } else { 00236 for ( std::vector<GpgME::Key>::const_iterator it = d->keyBuffer.begin() ; it != d->keyBuffer.end() ; ++it ) 00237 (void)new KeyListViewItem( this, *it ); 00238 } 00239 if ( wasUpdatesEnabled ) 00240 viewport()->setUpdatesEnabled( true ); 00241 d->keyBuffer.clear(); 00242 } 00243 00244 void Kleo::KeyListView::clear() { 00245 d->updateTimer->stop(); 00246 d->keyBuffer.clear(); 00247 TDEListView::clear(); 00248 } 00249 00250 void Kleo::KeyListView::registerItem( KeyListViewItem * item ) { 00251 //kdDebug() << "registerItem( " << item << " )" << endl; 00252 if ( !item ) 00253 return; 00254 const TQCString fpr = item->key().primaryFingerprint(); 00255 if ( !fpr.isEmpty() ) 00256 d->itemMap.insert( std::make_pair( fpr, item ) ); 00257 } 00258 00259 void Kleo::KeyListView::deregisterItem( const KeyListViewItem * item ) { 00260 //kdDebug() << "deregisterItem( KeyLVI: " << item << " )" << endl; 00261 if ( !item ) 00262 return; 00263 std::map<TQCString,KeyListViewItem*>::iterator it 00264 = d->itemMap.find( item->key().primaryFingerprint() ); 00265 if ( it == d->itemMap.end() ) 00266 return; 00267 Q_ASSERT( it->second == item ); 00268 if ( it->second != item ) 00269 return; 00270 d->itemMap.erase( it ); 00271 } 00272 00273 void Kleo::KeyListView::doHierarchicalInsert( const GpgME::Key & key ) { 00274 const TQCString fpr = key.primaryFingerprint(); 00275 if ( fpr.isEmpty() ) 00276 return; 00277 KeyListViewItem * item = 0; 00278 if ( !key.isRoot() ) 00279 if ( KeyListViewItem * parent = itemByFingerprint( key.chainID() ) ) { 00280 item = new KeyListViewItem( parent, key ); 00281 parent->setOpen( true ); 00282 } 00283 if ( !item ) 00284 item = new KeyListViewItem( this, key ); // top-level (for now) 00285 00286 d->itemMap.insert( std::make_pair( fpr, item ) ); 00287 } 00288 00289 void Kleo::KeyListView::gatherScattered() { 00290 KeyListViewItem * item = firstChild(); 00291 while ( item ) { 00292 KeyListViewItem * cur = item; 00293 item = item->nextSibling(); 00294 if ( cur->key().isRoot() ) 00295 continue; 00296 if ( KeyListViewItem * parent = itemByFingerprint( cur->key().chainID() ) ) { 00297 // found a new parent... 00298 // ### todo: optimize by suppressing removing/adding the item to the itemMap... 00299 takeItem( cur ); 00300 parent->insertItem( cur ); 00301 parent->setOpen( true ); 00302 } 00303 } 00304 } 00305 00306 void Kleo::KeyListView::scatterGathered( TQListViewItem * start ) { 00307 TQListViewItem * item = start; 00308 while ( item ) { 00309 TQListViewItem * cur = item; 00310 item = item->nextSibling(); 00311 00312 scatterGathered( cur->firstChild() ); 00313 assert( cur->childCount() == 0 ); 00314 00315 // ### todo: optimize by suppressing removing/adding the item to the itemMap... 00316 if ( cur->parent() ) 00317 cur->parent()->takeItem( cur ); 00318 else 00319 takeItem( cur ); 00320 insertItem( cur ); 00321 } 00322 } 00323 00324 Kleo::KeyListViewItem * Kleo::KeyListView::itemByFingerprint( const TQCString & s ) const { 00325 if ( s.isEmpty() ) 00326 return 0; 00327 const std::map<TQCString,KeyListViewItem*>::const_iterator it = d->itemMap.find( s ); 00328 if ( it == d->itemMap.end() ) 00329 return 0; 00330 return it->second; 00331 } 00332 00333 00334 void Kleo::KeyListView::slotRefreshKey( const GpgME::Key & key ) { 00335 const char * fpr = key.primaryFingerprint(); 00336 if ( !fpr ) { 00337 return; 00338 } 00339 if ( KeyListViewItem * item = itemByFingerprint( fpr ) ) { 00340 item->setKey ( key ); 00341 } 00342 else { 00343 // none found -> add it 00344 slotAddKey( key ); 00345 } 00346 } 00347 00348 // slots for the emission of covariant signals: 00349 00350 void Kleo::KeyListView::slotEmitDoubleClicked( TQListViewItem * item, const TQPoint & p, int col ) { 00351 if ( !item || lvi_cast<KeyListViewItem>( item ) ) 00352 emit doubleClicked( static_cast<KeyListViewItem*>( item ), p, col ); 00353 } 00354 00355 void Kleo::KeyListView::slotEmitReturnPressed( TQListViewItem * item ) { 00356 if ( !item || lvi_cast<KeyListViewItem>( item ) ) 00357 emit returnPressed( static_cast<KeyListViewItem*>( item ) ); 00358 } 00359 00360 void Kleo::KeyListView::slotEmitSelectionChanged( TQListViewItem * item ) { 00361 if ( !item || lvi_cast<KeyListViewItem>( item ) ) 00362 emit selectionChanged( static_cast<KeyListViewItem*>( item ) ); 00363 } 00364 00365 void Kleo::KeyListView::slotEmitContextMenu( TDEListView*, TQListViewItem * item, const TQPoint & p ) { 00366 if ( !item || lvi_cast<KeyListViewItem>( item ) ) 00367 emit contextMenu( static_cast<KeyListViewItem*>( item ), p ); 00368 } 00369 00370 // 00371 // 00372 // KeyListViewItem 00373 // 00374 // 00375 00376 Kleo::KeyListViewItem::KeyListViewItem( KeyListView * parent, const GpgME::Key & key ) 00377 : TQListViewItem( parent ) 00378 { 00379 setKey( key ); 00380 } 00381 00382 Kleo::KeyListViewItem::KeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::Key & key ) 00383 : TQListViewItem( parent, after ) 00384 { 00385 setKey( key ); 00386 } 00387 00388 Kleo::KeyListViewItem::KeyListViewItem( KeyListViewItem * parent, const GpgME::Key & key ) 00389 : TQListViewItem( parent ) 00390 { 00391 setKey( key ); 00392 } 00393 00394 Kleo::KeyListViewItem::KeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::Key & key ) 00395 : TQListViewItem( parent, after ) 00396 { 00397 setKey( key ); 00398 } 00399 00400 Kleo::KeyListViewItem::~KeyListViewItem() { 00401 // delete the children first... When children are deleted in the 00402 // TQLVI dtor, they don't have listView() anymore, thus they don't 00403 // call deregister( this ), leading to stale entries in the 00404 // itemMap... 00405 while ( TQListViewItem * item = firstChild() ) 00406 delete item; 00407 // better do this here, too, since deletion is top-down and thus 00408 // we're deleted when our parent item is no longer a 00409 // KeyListViewItem, but a mere TQListViewItem, so our takeItem() 00410 // overload is gone by that time... 00411 if ( KeyListView * lv = listView() ) 00412 lv->deregisterItem( this ); 00413 } 00414 00415 void Kleo::KeyListViewItem::setKey( const GpgME::Key & key ) { 00416 KeyListView * lv = listView(); 00417 if ( lv ) 00418 lv->deregisterItem( this ); 00419 mKey = key; 00420 if ( lv ) 00421 lv->registerItem( this ); 00422 00423 // the ColumnStrategy operations might be very slow, so cache their 00424 // result here, where we're non-const :) 00425 const Kleo::KeyListView::ColumnStrategy * cs = lv ? lv->columnStrategy() : 0 ; 00426 if ( !cs ) 00427 return; 00428 const int numCols = lv ? lv->columns() : 0 ; 00429 for ( int i = 0 ; i < numCols ; ++i ) { 00430 setText( i, cs->text( key, i ) ); 00431 if ( const TQPixmap * pix = cs->pixmap( key, i ) ) 00432 setPixmap( i, *pix ); 00433 } 00434 repaint(); 00435 } 00436 00437 TQString Kleo::KeyListViewItem::toolTip( int col ) const { 00438 return listView() && listView()->columnStrategy() 00439 ? listView()->columnStrategy()->toolTip( key(), col ) 00440 : TQString() ; 00441 } 00442 00443 int Kleo::KeyListViewItem::compare( TQListViewItem * item, int col, bool ascending ) const { 00444 if ( !item || item->rtti() != RTTI || !listView() || !listView()->columnStrategy() ) 00445 return TQListViewItem::compare( item, col, ascending ); 00446 KeyListViewItem * that = static_cast<KeyListViewItem*>( item ); 00447 return listView()->columnStrategy()->compare( this->key(), that->key(), col ); 00448 } 00449 00450 void Kleo::KeyListViewItem::paintCell( TQPainter * p, const TQColorGroup & cg, int column, int width, int alignment ) { 00451 const KeyListView::DisplayStrategy * ds = listView() ? listView()->displayStrategy() : 0 ; 00452 if ( !ds ) { 00453 TQListViewItem::paintCell( p, cg, column, width, alignment ); 00454 return; 00455 } 00456 const TQColor fg = ds->keyForeground( key(), cg.text() ); 00457 const TQColor bg = ds->keyBackground( key(), cg.base() ); 00458 const TQFont f = ds->keyFont( key(), p->font() ); 00459 00460 TQColorGroup _cg = cg; 00461 p->setFont( f ); 00462 _cg.setColor( TQColorGroup::Text, fg ); 00463 _cg.setColor( TQColorGroup::Base, bg ); 00464 00465 TQListViewItem::paintCell( p, _cg, column, width, alignment ); 00466 } 00467 00468 void Kleo::KeyListViewItem::insertItem( TQListViewItem * qlvi ) { 00469 //kdDebug() << "Kleo::KeyListViewItem::insertItem( " << qlvi << " )" << endl; 00470 TQListViewItem::insertItem( qlvi ); 00471 if ( KeyListViewItem * item = lvi_cast<KeyListViewItem>( qlvi ) ) 00472 listView()->registerItem( item ); 00473 } 00474 00475 void Kleo::KeyListViewItem::takeItem( TQListViewItem * qlvi ) { 00476 //kdDebug() << "Kleo::KeyListViewItem::takeItem( " << qlvi << " )" << endl; 00477 if ( KeyListViewItem * item = lvi_cast<KeyListViewItem>( qlvi ) ) 00478 listView()->deregisterItem( item ); 00479 TQListViewItem::takeItem( qlvi ); 00480 } 00481 00482 00483 // 00484 // 00485 // SubkeyKeyListViewItem 00486 // 00487 // 00488 00489 Kleo::SubkeyKeyListViewItem::SubkeyKeyListViewItem( KeyListView * parent, const GpgME::Subkey & subkey ) 00490 : KeyListViewItem( parent, subkey.parent() ), mSubkey( subkey ) 00491 { 00492 00493 } 00494 00495 Kleo::SubkeyKeyListViewItem::SubkeyKeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::Subkey & subkey ) 00496 : KeyListViewItem( parent, after, subkey.parent() ), mSubkey( subkey ) 00497 { 00498 00499 } 00500 00501 Kleo::SubkeyKeyListViewItem::SubkeyKeyListViewItem( KeyListViewItem * parent, const GpgME::Subkey & subkey ) 00502 : KeyListViewItem( parent, subkey.parent() ), mSubkey( subkey ) 00503 { 00504 00505 } 00506 00507 Kleo::SubkeyKeyListViewItem::SubkeyKeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::Subkey & subkey ) 00508 : KeyListViewItem( parent, after, subkey.parent() ), mSubkey( subkey ) 00509 { 00510 00511 } 00512 00513 void Kleo::SubkeyKeyListViewItem::setSubkey( const GpgME::Subkey & subkey ) { 00514 mSubkey = subkey; 00515 setKey( subkey.parent() ); 00516 } 00517 00518 TQString Kleo::SubkeyKeyListViewItem::text( int col ) const { 00519 return listView() && listView()->columnStrategy() 00520 ? listView()->columnStrategy()->subkeyText( subkey(), col ) 00521 : TQString() ; 00522 } 00523 00524 TQString Kleo::SubkeyKeyListViewItem::toolTip( int col ) const { 00525 return listView() && listView()->columnStrategy() 00526 ? listView()->columnStrategy()->subkeyToolTip( subkey(), col ) 00527 : TQString() ; 00528 } 00529 00530 const TQPixmap * Kleo::SubkeyKeyListViewItem::pixmap( int col ) const { 00531 return listView() && listView()->columnStrategy() 00532 ? listView()->columnStrategy()->subkeyPixmap( subkey(), col ) : 0 ; 00533 } 00534 00535 int Kleo::SubkeyKeyListViewItem::compare( TQListViewItem * item, int col, bool ascending ) const { 00536 if ( !item || item->rtti() != RTTI || !listView() || !listView()->columnStrategy() ) 00537 return KeyListViewItem::compare( item, col, ascending ); 00538 SubkeyKeyListViewItem * that = static_cast<SubkeyKeyListViewItem*>( item ); 00539 return listView()->columnStrategy()->subkeyCompare( this->subkey(), that->subkey(), col ); 00540 } 00541 00542 void Kleo::SubkeyKeyListViewItem::paintCell( TQPainter * p, const TQColorGroup & cg, int column, int width, int alignment ) { 00543 const KeyListView::DisplayStrategy * ds = listView() ? listView()->displayStrategy() : 0 ; 00544 if ( !ds ) { 00545 TQListViewItem::paintCell( p, cg, column, width, alignment ); 00546 return; 00547 } 00548 const TQColor fg = ds->subkeyForeground( subkey(), cg.text() ); 00549 const TQColor bg = ds->subkeyBackground( subkey(), cg.base() ); 00550 const TQFont f = ds->subkeyFont( subkey(), p->font() ); 00551 00552 TQColorGroup _cg = cg; 00553 p->setFont( f ); 00554 _cg.setColor( TQColorGroup::Text, fg ); 00555 _cg.setColor( TQColorGroup::Base, bg ); 00556 00557 TQListViewItem::paintCell( p, _cg, column, width, alignment ); 00558 } 00559 00560 00561 // 00562 // 00563 // UserIDKeyListViewItem 00564 // 00565 // 00566 00567 Kleo::UserIDKeyListViewItem::UserIDKeyListViewItem( KeyListView * parent, const GpgME::UserID & userID ) 00568 : KeyListViewItem( parent, userID.parent() ), mUserID( userID ) 00569 { 00570 00571 } 00572 00573 Kleo::UserIDKeyListViewItem::UserIDKeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::UserID & userID ) 00574 : KeyListViewItem( parent, after, userID.parent() ), mUserID( userID ) 00575 { 00576 00577 } 00578 00579 Kleo::UserIDKeyListViewItem::UserIDKeyListViewItem( KeyListViewItem * parent, const GpgME::UserID & userID ) 00580 : KeyListViewItem( parent, userID.parent() ), mUserID( userID ) 00581 { 00582 00583 } 00584 00585 Kleo::UserIDKeyListViewItem::UserIDKeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::UserID & userID ) 00586 : KeyListViewItem( parent, after, userID.parent() ), mUserID( userID ) 00587 { 00588 00589 } 00590 00591 void Kleo::UserIDKeyListViewItem::setUserID( const GpgME::UserID & userID ) { 00592 mUserID = userID; 00593 setKey( userID.parent() ); 00594 } 00595 00596 TQString Kleo::UserIDKeyListViewItem::text( int col ) const { 00597 return listView() && listView()->columnStrategy() 00598 ? listView()->columnStrategy()->userIDText( userID(), col ) 00599 : TQString() ; 00600 } 00601 00602 TQString Kleo::UserIDKeyListViewItem::toolTip( int col ) const { 00603 return listView() && listView()->columnStrategy() 00604 ? listView()->columnStrategy()->userIDToolTip( userID(), col ) 00605 : TQString() ; 00606 } 00607 00608 const TQPixmap * Kleo::UserIDKeyListViewItem::pixmap( int col ) const { 00609 return listView() && listView()->columnStrategy() 00610 ? listView()->columnStrategy()->userIDPixmap( userID(), col ) : 0 ; 00611 } 00612 00613 int Kleo::UserIDKeyListViewItem::compare( TQListViewItem * item, int col, bool ascending ) const { 00614 if ( !item || item->rtti() != RTTI || !listView() || !listView()->columnStrategy() ) 00615 return KeyListViewItem::compare( item, col, ascending ); 00616 UserIDKeyListViewItem * that = static_cast<UserIDKeyListViewItem*>( item ); 00617 return listView()->columnStrategy()->userIDCompare( this->userID(), that->userID(), col ); 00618 } 00619 00620 00621 void Kleo::UserIDKeyListViewItem::paintCell( TQPainter * p, const TQColorGroup & cg, int column, int width, int alignment ) { 00622 const KeyListView::DisplayStrategy * ds = listView() ? listView()->displayStrategy() : 0 ; 00623 if ( !ds ) { 00624 TQListViewItem::paintCell( p, cg, column, width, alignment ); 00625 return; 00626 } 00627 const TQColor fg = ds->useridForeground( userID(), cg.text() ); 00628 const TQColor bg = ds->useridBackground( userID(), cg.base() ); 00629 const TQFont f = ds->useridFont( userID(), p->font() ); 00630 00631 TQColorGroup _cg = cg; 00632 p->setFont( f ); 00633 _cg.setColor( TQColorGroup::Text, fg ); 00634 _cg.setColor( TQColorGroup::Base, bg ); 00635 00636 TQListViewItem::paintCell( p, _cg, column, width, alignment ); 00637 } 00638 00639 00640 // 00641 // 00642 // SignatureKeyListViewItem 00643 // 00644 // 00645 00646 Kleo::SignatureKeyListViewItem::SignatureKeyListViewItem( KeyListView * parent, const GpgME::UserID::Signature & signature ) 00647 : KeyListViewItem( parent, signature.parent().parent() ), mSignature( signature ) 00648 { 00649 00650 } 00651 00652 Kleo::SignatureKeyListViewItem::SignatureKeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::UserID::Signature & signature ) 00653 : KeyListViewItem( parent, after, signature.parent().parent() ), mSignature( signature ) 00654 { 00655 00656 } 00657 00658 Kleo::SignatureKeyListViewItem::SignatureKeyListViewItem( KeyListViewItem * parent, const GpgME::UserID::Signature & signature ) 00659 : KeyListViewItem( parent, signature.parent().parent() ), mSignature( signature ) 00660 { 00661 00662 } 00663 00664 Kleo::SignatureKeyListViewItem::SignatureKeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::UserID::Signature & signature ) 00665 : KeyListViewItem( parent, after, signature.parent().parent() ), mSignature( signature ) 00666 { 00667 00668 } 00669 00670 void Kleo::SignatureKeyListViewItem::setSignature( const GpgME::UserID::Signature & signature ) { 00671 mSignature = signature; 00672 setKey( signature.parent().parent() ); 00673 } 00674 00675 TQString Kleo::SignatureKeyListViewItem::text( int col ) const { 00676 return listView() && listView()->columnStrategy() 00677 ? listView()->columnStrategy()->signatureText( signature(), col ) 00678 : TQString() ; 00679 } 00680 00681 TQString Kleo::SignatureKeyListViewItem::toolTip( int col ) const { 00682 return listView() && listView()->columnStrategy() 00683 ? listView()->columnStrategy()->signatureToolTip( signature(), col ) 00684 : TQString() ; 00685 } 00686 00687 const TQPixmap * Kleo::SignatureKeyListViewItem::pixmap( int col ) const { 00688 return listView() && listView()->columnStrategy() 00689 ? listView()->columnStrategy()->signaturePixmap( signature(), col ) : 0 ; 00690 } 00691 00692 int Kleo::SignatureKeyListViewItem::compare( TQListViewItem * item, int col, bool ascending ) const { 00693 if ( !item || item->rtti() != RTTI || !listView() || !listView()->columnStrategy() ) 00694 return KeyListViewItem::compare( item, col, ascending ); 00695 SignatureKeyListViewItem * that = static_cast<SignatureKeyListViewItem*>( item ); 00696 return listView()->columnStrategy()->signatureCompare( this->signature(), that->signature(), col ); 00697 } 00698 00699 void Kleo::SignatureKeyListViewItem::paintCell( TQPainter * p, const TQColorGroup & cg, int column, int width, int alignment ) { 00700 const KeyListView::DisplayStrategy * ds = listView() ? listView()->displayStrategy() : 0 ; 00701 if ( !ds ) { 00702 TQListViewItem::paintCell( p, cg, column, width, alignment ); 00703 return; 00704 } 00705 const TQColor fg = ds->signatureForeground( signature(), cg.text() ); 00706 const TQColor bg = ds->signatureBackground( signature(), cg.base() ); 00707 const TQFont f = ds->signatureFont( signature(), p->font() ); 00708 00709 TQColorGroup _cg = cg; 00710 p->setFont( f ); 00711 _cg.setColor( TQColorGroup::Text, fg ); 00712 _cg.setColor( TQColorGroup::Base, bg ); 00713 00714 TQListViewItem::paintCell( p, _cg, column, width, alignment ); 00715 } 00716 00717 00718 // 00719 // 00720 // ColumnStrategy 00721 // 00722 // 00723 00724 Kleo::KeyListView::ColumnStrategy::~ColumnStrategy() {} 00725 00726 int Kleo::KeyListView::ColumnStrategy::compare( const GpgME::Key & key1, const GpgME::Key & key2, int col ) const { 00727 return TQString::localeAwareCompare( text( key1, col ), text( key2, col ) ); 00728 } 00729 00730 int Kleo::KeyListView::ColumnStrategy::width( int col, const TQFontMetrics & fm ) const { 00731 return fm.width( title( col ) ) * 2; 00732 } 00733 00734 int Kleo::KeyListView::ColumnStrategy::subkeyCompare( const GpgME::Subkey & sub1, const GpgME::Subkey & sub2, int col ) const { 00735 return TQString::localeAwareCompare( subkeyText( sub1, col ), subkeyText( sub2, col ) ); 00736 } 00737 00738 int Kleo::KeyListView::ColumnStrategy::userIDCompare( const GpgME::UserID & uid1, const GpgME::UserID & uid2, int col ) const { 00739 return TQString::localeAwareCompare( userIDText( uid1, col ), userIDText( uid2, col ) ); 00740 } 00741 00742 int Kleo::KeyListView::ColumnStrategy::signatureCompare( const GpgME::UserID::Signature & sig1, const GpgME::UserID::Signature & sig2, int col ) const { 00743 return TQString::localeAwareCompare( signatureText( sig1, col ), signatureText( sig2, col ) ); 00744 } 00745 00746 TQString Kleo::KeyListView::ColumnStrategy::toolTip( const GpgME::Key & key, int col ) const { 00747 return text( key, col ); 00748 } 00749 00750 TQString Kleo::KeyListView::ColumnStrategy::subkeyToolTip( const GpgME::Subkey & sub, int col ) const { 00751 return subkeyText( sub, col ); 00752 } 00753 00754 TQString Kleo::KeyListView::ColumnStrategy::userIDToolTip( const GpgME::UserID & uid, int col ) const { 00755 return userIDText( uid, col ); 00756 } 00757 00758 TQString Kleo::KeyListView::ColumnStrategy::signatureToolTip( const GpgME::UserID::Signature & sig, int col ) const { 00759 return signatureText( sig, col ); 00760 } 00761 00762 // 00763 // 00764 // DisplayStrategy 00765 // 00766 // 00767 00768 Kleo::KeyListView::DisplayStrategy::~DisplayStrategy() {} 00769 00770 00771 //font 00772 TQFont Kleo::KeyListView::DisplayStrategy::keyFont( const GpgME::Key &, const TQFont & font ) const { 00773 return font; 00774 } 00775 00776 TQFont Kleo::KeyListView::DisplayStrategy::subkeyFont( const GpgME::Subkey &, const TQFont & font ) const { 00777 return font; 00778 } 00779 00780 TQFont Kleo::KeyListView::DisplayStrategy::useridFont( const GpgME::UserID &, const TQFont & font ) const { 00781 return font; 00782 } 00783 00784 TQFont Kleo::KeyListView::DisplayStrategy::signatureFont( const GpgME::UserID::Signature &, const TQFont & font ) const { 00785 return font; 00786 } 00787 00788 //foreground 00789 TQColor Kleo::KeyListView::DisplayStrategy::keyForeground( const GpgME::Key &, const TQColor & fg )const { 00790 return fg; 00791 } 00792 00793 TQColor Kleo::KeyListView::DisplayStrategy::subkeyForeground( const GpgME::Subkey &, const TQColor & fg ) const { 00794 return fg; 00795 } 00796 00797 TQColor Kleo::KeyListView::DisplayStrategy::useridForeground( const GpgME::UserID &, const TQColor & fg ) const { 00798 return fg; 00799 } 00800 00801 TQColor Kleo::KeyListView::DisplayStrategy::signatureForeground( const GpgME::UserID::Signature &, const TQColor & fg ) const { 00802 return fg; 00803 } 00804 00805 //background 00806 TQColor Kleo::KeyListView::DisplayStrategy::keyBackground( const GpgME::Key &, const TQColor & bg )const { 00807 return bg; 00808 } 00809 00810 TQColor Kleo::KeyListView::DisplayStrategy::subkeyBackground( const GpgME::Subkey &, const TQColor & bg ) const { 00811 return bg; 00812 } 00813 00814 TQColor Kleo::KeyListView::DisplayStrategy::useridBackground( const GpgME::UserID &, const TQColor & bg ) const { 00815 return bg; 00816 } 00817 00818 TQColor Kleo::KeyListView::DisplayStrategy::signatureBackground( const GpgME::UserID::Signature &, const TQColor & bg ) const { 00819 return bg; 00820 } 00821 00822 00823 // 00824 // 00825 // Collection of covariant return reimplementations of TQListView(Item) 00826 // members: 00827 // 00828 // 00829 00830 Kleo::KeyListView * Kleo::KeyListViewItem::listView() const { 00831 return static_cast<Kleo::KeyListView*>( TQListViewItem::listView() ); 00832 } 00833 00834 Kleo::KeyListViewItem * Kleo::KeyListViewItem::nextSibling() const { 00835 return static_cast<Kleo::KeyListViewItem*>( TQListViewItem::nextSibling() ); 00836 } 00837 00838 Kleo::KeyListViewItem * Kleo::KeyListView::firstChild() const { 00839 return static_cast<Kleo::KeyListViewItem*>( TDEListView::firstChild() ); 00840 } 00841 00842 Kleo::KeyListViewItem * Kleo::KeyListView::selectedItem() const { 00843 return static_cast<Kleo::KeyListViewItem*>( TDEListView::selectedItem() ); 00844 } 00845 00846 static void selectedItems( TQPtrList<Kleo::KeyListViewItem> & result, TQListViewItem * start ) { 00847 for ( TQListViewItem * item = start ; item ; item = item->nextSibling() ) { 00848 if ( item->isSelected() ) 00849 if ( Kleo::KeyListViewItem * i = Kleo::lvi_cast<Kleo::KeyListViewItem>( item ) ) 00850 result.append( i ); 00851 selectedItems( result, item->firstChild() ); 00852 } 00853 } 00854 00855 TQPtrList<Kleo::KeyListViewItem> Kleo::KeyListView::selectedItems() const { 00856 TQPtrList<KeyListViewItem> result; 00857 ::selectedItems( result, firstChild() ); 00858 return result; 00859 } 00860 00861 static bool hasSelection( TQListViewItem * start ) { 00862 for ( TQListViewItem * item = start ; item ; item = item->nextSibling() ) 00863 if ( item->isSelected() || hasSelection( item->firstChild() ) ) 00864 return true; 00865 return false; 00866 } 00867 00868 bool Kleo::KeyListView::hasSelection() const { 00869 return ::hasSelection( firstChild() ); 00870 } 00871 00872 #include "keylistview.moc"