certmanager/lib

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 Qt library by Trolltech AS, Norway (or with modified versions
00024     of Qt that use the same license as Qt), 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     Qt.  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 <qfontmetrics.h>
00042 #include <qtooltip.h>
00043 #include <qrect.h>
00044 #include <qheader.h>
00045 #include <qpoint.h>
00046 #include <qptrlist.h>
00047 #include <qpainter.h>
00048 #include <qfont.h>
00049 #include <qcolor.h>
00050 #include <qtimer.h>
00051 #include <qcstring.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 QToolTip {
00065   public:
00066     ItemToolTip( Kleo::KeyListView * parent );
00067   protected:
00068     void maybeTip( const QPoint & p );
00069   private:
00070     Kleo::KeyListView * mKeyListView;
00071   };
00072 
00073   ItemToolTip::ItemToolTip( Kleo::KeyListView * parent )
00074     : QToolTip( parent->viewport() ), mKeyListView( parent ) {}
00075 
00076   void ItemToolTip::maybeTip( const QPoint & p ) {
00077     if ( !mKeyListView )
00078       return;
00079 
00080     const QListViewItem * item = mKeyListView->itemAt( p );
00081     if ( !item )
00082       return;
00083 
00084     const QRect 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 QRect headerRect = mKeyListView->header()->sectionRect( col );
00093     if ( !headerRect.isValid() )
00094       return;
00095 
00096     const QRect cellRect( headerRect.left(), itemRect.top(),
00097               headerRect.width(), itemRect.height() );
00098 
00099     QString 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   QTimer * updateTimer;
00116   QToolTip * itemToolTip;
00117   std::map<QCString,KeyListViewItem*> itemMap;
00118 };
00119 
00120 // a list of signals where we want to replace QListViewItem with
00121 // Kleo:KeyListViewItem:
00122 static const struct {
00123   const char * source;
00124   const char * target;
00125 } signalReplacements[] = {
00126   { SIGNAL(doubleClicked(QListViewItem*,const QPoint&,int)),
00127     SLOT(slotEmitDoubleClicked(QListViewItem*,const QPoint&,int)) },
00128   { SIGNAL(returnPressed(QListViewItem*)),
00129     SLOT(slotEmitReturnPressed(QListViewItem*)) },
00130   { SIGNAL(selectionChanged(QListViewItem*)),
00131     SLOT(slotEmitSelectionChanged(QListViewItem*)) },
00132   { SIGNAL(contextMenu(KListView*, QListViewItem*,const QPoint&)),
00133     SLOT(slotEmitContextMenu(KListView*, QListViewItem*,const QPoint&)) },
00134 };
00135 static const int numSignalReplacements = sizeof signalReplacements / sizeof *signalReplacements;
00136 
00137 
00138 Kleo::KeyListView::KeyListView( const ColumnStrategy * columnStrategy, const DisplayStrategy * displayStrategy, QWidget * parent, const char * name, WFlags f )
00139   : KListView( 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 QTimer( this );
00149   connect( d->updateTimer, SIGNAL(timeout()), 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 QFontMetrics 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   QToolTip::remove( this );
00170   QToolTip::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 ~QListView, 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 ~QToolTip 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( QListViewItem * qlvi ) {
00189   //kdDebug() << "Kleo::KeyListView::insertItem( " << qlvi << " )" << endl;
00190   KListView::insertItem( qlvi );
00191   if ( KeyListViewItem * item = lvi_cast<KeyListViewItem>( qlvi ) )
00192     registerItem( item );
00193 }
00194 
00195 void Kleo::KeyListView::takeItem( QListViewItem * qlvi ) {
00196   //kdDebug() << "Kleo::KeyListView::takeItem( " << qlvi << " )" << endl;
00197   if ( KeyListViewItem * item = lvi_cast<KeyListViewItem>( qlvi ) )
00198     deregisterItem( item );
00199   KListView::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   KListView::clear();
00248 }
00249 
00250 void Kleo::KeyListView::registerItem( KeyListViewItem * item ) {
00251   //kdDebug() << "registerItem( " << item << " )" << endl;
00252   if ( !item )
00253     return;
00254   const QCString 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<QCString,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 QCString 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( QListViewItem * start ) {
00307   QListViewItem * item = start;
00308   while ( item ) {
00309     QListViewItem * 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 QCString & s ) const {
00325   if ( s.isEmpty() )
00326     return 0;
00327   const std::map<QCString,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   if ( KeyListViewItem * item = itemByFingerprint( fpr ) )
00339     item->setKey ( key );
00340   else
00341     // none found -> add it
00342     slotAddKey( key );
00343 }
00344 
00345 // slots for the emission of covariant signals:
00346 
00347 void Kleo::KeyListView::slotEmitDoubleClicked( QListViewItem * item, const QPoint & p, int col ) {
00348   if ( !item || lvi_cast<KeyListViewItem>( item ) )
00349     emit doubleClicked( static_cast<KeyListViewItem*>( item ), p, col );
00350 }
00351 
00352 void Kleo::KeyListView::slotEmitReturnPressed( QListViewItem * item ) {
00353   if ( !item || lvi_cast<KeyListViewItem>( item ) )
00354     emit returnPressed( static_cast<KeyListViewItem*>( item ) );
00355 }
00356 
00357 void Kleo::KeyListView::slotEmitSelectionChanged( QListViewItem * item ) {
00358   if ( !item || lvi_cast<KeyListViewItem>( item ) )
00359     emit selectionChanged( static_cast<KeyListViewItem*>( item ) );
00360 }
00361 
00362 void Kleo::KeyListView::slotEmitContextMenu( KListView*, QListViewItem * item, const QPoint & p ) {
00363   if ( !item || lvi_cast<KeyListViewItem>( item ) )
00364     emit contextMenu( static_cast<KeyListViewItem*>( item ), p );
00365 }
00366 
00367 //
00368 //
00369 // KeyListViewItem
00370 //
00371 //
00372 
00373 Kleo::KeyListViewItem::KeyListViewItem( KeyListView * parent, const GpgME::Key & key )
00374   : QListViewItem( parent )
00375 {
00376   setKey( key );
00377 }
00378 
00379 Kleo::KeyListViewItem::KeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::Key & key )
00380   : QListViewItem( parent, after )
00381 {
00382   setKey( key );
00383 }
00384 
00385 Kleo::KeyListViewItem::KeyListViewItem( KeyListViewItem * parent, const GpgME::Key & key )
00386   : QListViewItem( parent )
00387 {
00388   setKey( key );
00389 }
00390 
00391 Kleo::KeyListViewItem::KeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::Key & key )
00392   : QListViewItem( parent, after )
00393 {
00394   setKey( key );
00395 }
00396 
00397 Kleo::KeyListViewItem::~KeyListViewItem() {
00398   // delete the children first... When children are deleted in the
00399   // QLVI dtor, they don't have listView() anymore, thus they don't
00400   // call deregister( this ), leading to stale entries in the
00401   // itemMap...
00402   while ( QListViewItem * item = firstChild() )
00403     delete item;
00404   // better do this here, too, since deletion is top-down and thus
00405   // we're deleted when our parent item is no longer a
00406   // KeyListViewItem, but a mere QListViewItem, so our takeItem()
00407   // overload is gone by that time...
00408   if ( KeyListView * lv = listView() )
00409     lv->deregisterItem( this );
00410 }
00411 
00412 void Kleo::KeyListViewItem::setKey( const GpgME::Key & key ) {
00413   KeyListView * lv = listView();
00414   if ( lv )
00415     lv->deregisterItem( this );
00416   mKey = key;
00417   if ( lv )
00418     lv->registerItem( this );
00419 
00420   // the ColumnStrategy operations might be very slow, so cache their
00421   // result here, where we're non-const :)
00422   const Kleo::KeyListView::ColumnStrategy * cs = lv ? lv->columnStrategy() : 0 ;
00423   if ( !cs )
00424     return;
00425   const int numCols = lv ? lv->columns() : 0 ;
00426   for ( int i = 0 ; i < numCols ; ++i ) {
00427     setText( i, cs->text( key, i ) );
00428     if ( const QPixmap * pix = cs->pixmap( key, i ) )
00429       setPixmap( i, *pix );
00430   }
00431   repaint();
00432 }
00433 
00434 QString Kleo::KeyListViewItem::toolTip( int col ) const {
00435   return listView() && listView()->columnStrategy()
00436     ? listView()->columnStrategy()->toolTip( key(), col )
00437     : QString::null ;
00438 }
00439 
00440 int Kleo::KeyListViewItem::compare( QListViewItem * item, int col, bool ascending ) const {
00441   if ( !item || item->rtti() != RTTI || !listView() || !listView()->columnStrategy() )
00442     return QListViewItem::compare( item, col, ascending );
00443   KeyListViewItem * that = static_cast<KeyListViewItem*>( item );
00444   return listView()->columnStrategy()->compare( this->key(), that->key(), col );
00445 }
00446 
00447 void Kleo::KeyListViewItem::paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment ) {
00448   const KeyListView::DisplayStrategy * ds = listView() ? listView()->displayStrategy() : 0 ;
00449   if ( !ds ) {
00450     QListViewItem::paintCell( p, cg, column, width, alignment );
00451     return;
00452   }
00453   const QColor fg = ds->keyForeground( key(), cg.text() );
00454   const QColor bg = ds->keyBackground( key(), cg.base() );
00455   const QFont f = ds->keyFont( key(), p->font() );
00456 
00457   QColorGroup _cg = cg;
00458   p->setFont( f );
00459   _cg.setColor( QColorGroup::Text, fg );
00460   _cg.setColor( QColorGroup::Base, bg );
00461 
00462   QListViewItem::paintCell( p, _cg, column, width, alignment );
00463 }
00464 
00465 void Kleo::KeyListViewItem::insertItem( QListViewItem * qlvi ) {
00466   //kdDebug() << "Kleo::KeyListViewItem::insertItem( " << qlvi << " )" << endl;
00467   QListViewItem::insertItem( qlvi );
00468   if ( KeyListViewItem * item = lvi_cast<KeyListViewItem>( qlvi ) )
00469     listView()->registerItem( item );
00470 }
00471 
00472 void Kleo::KeyListViewItem::takeItem( QListViewItem * qlvi ) {
00473   //kdDebug() << "Kleo::KeyListViewItem::takeItem( " << qlvi << " )" << endl;
00474   if ( KeyListViewItem * item = lvi_cast<KeyListViewItem>( qlvi ) )
00475     listView()->deregisterItem( item );
00476   QListViewItem::takeItem( qlvi );
00477 }
00478 
00479 
00480 //
00481 //
00482 // SubkeyKeyListViewItem
00483 //
00484 //
00485 
00486 Kleo::SubkeyKeyListViewItem::SubkeyKeyListViewItem( KeyListView * parent, const GpgME::Subkey & subkey )
00487   : KeyListViewItem( parent, subkey.parent() ), mSubkey( subkey )
00488 {
00489 
00490 }
00491 
00492 Kleo::SubkeyKeyListViewItem::SubkeyKeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::Subkey & subkey )
00493   : KeyListViewItem( parent, after, subkey.parent() ), mSubkey( subkey )
00494 {
00495 
00496 }
00497 
00498 Kleo::SubkeyKeyListViewItem::SubkeyKeyListViewItem( KeyListViewItem * parent, const GpgME::Subkey & subkey )
00499   : KeyListViewItem( parent, subkey.parent() ), mSubkey( subkey )
00500 {
00501 
00502 }
00503 
00504 Kleo::SubkeyKeyListViewItem::SubkeyKeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::Subkey & subkey )
00505   : KeyListViewItem( parent, after, subkey.parent() ), mSubkey( subkey )
00506 {
00507 
00508 }
00509 
00510 void Kleo::SubkeyKeyListViewItem::setSubkey( const GpgME::Subkey & subkey ) {
00511   mSubkey = subkey;
00512   setKey( subkey.parent() );
00513 }
00514 
00515 QString Kleo::SubkeyKeyListViewItem::text( int col ) const {
00516   return listView() && listView()->columnStrategy()
00517     ? listView()->columnStrategy()->subkeyText( subkey(), col )
00518     : QString::null ;
00519 }
00520 
00521 QString Kleo::SubkeyKeyListViewItem::toolTip( int col ) const {
00522   return listView() && listView()->columnStrategy()
00523     ? listView()->columnStrategy()->subkeyToolTip( subkey(), col )
00524     : QString::null ;
00525 }
00526 
00527 const QPixmap * Kleo::SubkeyKeyListViewItem::pixmap( int col ) const {
00528   return listView() && listView()->columnStrategy()
00529     ? listView()->columnStrategy()->subkeyPixmap( subkey(), col ) : 0 ;
00530 }
00531 
00532 int Kleo::SubkeyKeyListViewItem::compare( QListViewItem * item, int col, bool ascending ) const {
00533   if ( !item || item->rtti() != RTTI || !listView() || !listView()->columnStrategy() )
00534     return KeyListViewItem::compare( item, col, ascending );
00535   SubkeyKeyListViewItem * that = static_cast<SubkeyKeyListViewItem*>( item );
00536   return listView()->columnStrategy()->subkeyCompare( this->subkey(), that->subkey(), col );
00537 }
00538 
00539 void Kleo::SubkeyKeyListViewItem::paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment ) {
00540   const KeyListView::DisplayStrategy * ds = listView() ? listView()->displayStrategy() : 0 ;
00541   if ( !ds ) {
00542     QListViewItem::paintCell( p, cg, column, width, alignment );
00543     return;
00544   }
00545   const QColor fg = ds->subkeyForeground( subkey(), cg.text() );
00546   const QColor bg = ds->subkeyBackground( subkey(), cg.base() );
00547   const QFont f = ds->subkeyFont( subkey(), p->font() );
00548 
00549   QColorGroup _cg = cg;
00550   p->setFont( f );
00551   _cg.setColor( QColorGroup::Text, fg );
00552   _cg.setColor( QColorGroup::Base, bg );
00553 
00554   QListViewItem::paintCell( p, _cg, column, width, alignment );
00555 }
00556 
00557 
00558 //
00559 //
00560 // UserIDKeyListViewItem
00561 //
00562 //
00563 
00564 Kleo::UserIDKeyListViewItem::UserIDKeyListViewItem( KeyListView * parent, const GpgME::UserID & userID )
00565   : KeyListViewItem( parent, userID.parent() ), mUserID( userID )
00566 {
00567 
00568 }
00569 
00570 Kleo::UserIDKeyListViewItem::UserIDKeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::UserID & userID )
00571   : KeyListViewItem( parent, after, userID.parent() ), mUserID( userID )
00572 {
00573 
00574 }
00575 
00576 Kleo::UserIDKeyListViewItem::UserIDKeyListViewItem( KeyListViewItem * parent, const GpgME::UserID & userID )
00577   : KeyListViewItem( parent, userID.parent() ), mUserID( userID )
00578 {
00579 
00580 }
00581 
00582 Kleo::UserIDKeyListViewItem::UserIDKeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::UserID & userID )
00583   : KeyListViewItem( parent, after, userID.parent() ), mUserID( userID )
00584 {
00585 
00586 }
00587 
00588 void Kleo::UserIDKeyListViewItem::setUserID( const GpgME::UserID & userID ) {
00589   mUserID = userID;
00590   setKey( userID.parent() );
00591 }
00592 
00593 QString Kleo::UserIDKeyListViewItem::text( int col ) const {
00594   return listView() && listView()->columnStrategy()
00595     ? listView()->columnStrategy()->userIDText( userID(), col )
00596     : QString::null ;
00597 }
00598 
00599 QString Kleo::UserIDKeyListViewItem::toolTip( int col ) const {
00600   return listView() && listView()->columnStrategy()
00601     ? listView()->columnStrategy()->userIDToolTip( userID(), col )
00602     : QString::null ;
00603 }
00604 
00605 const QPixmap * Kleo::UserIDKeyListViewItem::pixmap( int col ) const {
00606   return listView() && listView()->columnStrategy()
00607     ? listView()->columnStrategy()->userIDPixmap( userID(), col ) : 0 ;
00608 }
00609 
00610 int Kleo::UserIDKeyListViewItem::compare( QListViewItem * item, int col, bool ascending ) const {
00611   if ( !item || item->rtti() != RTTI || !listView() || !listView()->columnStrategy() )
00612     return KeyListViewItem::compare( item, col, ascending );
00613   UserIDKeyListViewItem * that = static_cast<UserIDKeyListViewItem*>( item );
00614   return listView()->columnStrategy()->userIDCompare( this->userID(), that->userID(), col );
00615 }
00616 
00617 
00618 void Kleo::UserIDKeyListViewItem::paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment ) {
00619   const KeyListView::DisplayStrategy * ds = listView() ? listView()->displayStrategy() : 0 ;
00620   if ( !ds ) {
00621     QListViewItem::paintCell( p, cg, column, width, alignment );
00622     return;
00623   }
00624   const QColor fg = ds->useridForeground( userID(), cg.text() );
00625   const QColor bg = ds->useridBackground( userID(), cg.base() );
00626   const QFont f = ds->useridFont( userID(), p->font() );
00627 
00628   QColorGroup _cg = cg;
00629   p->setFont( f );
00630   _cg.setColor( QColorGroup::Text, fg );
00631   _cg.setColor( QColorGroup::Base, bg );
00632 
00633   QListViewItem::paintCell( p, _cg, column, width, alignment );
00634 }
00635 
00636 
00637 //
00638 //
00639 // SignatureKeyListViewItem
00640 //
00641 //
00642 
00643 Kleo::SignatureKeyListViewItem::SignatureKeyListViewItem( KeyListView * parent, const GpgME::UserID::Signature & signature )
00644   : KeyListViewItem( parent, signature.parent().parent() ), mSignature( signature )
00645 {
00646 
00647 }
00648 
00649 Kleo::SignatureKeyListViewItem::SignatureKeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::UserID::Signature & signature )
00650   : KeyListViewItem( parent, after, signature.parent().parent() ), mSignature( signature )
00651 {
00652 
00653 }
00654 
00655 Kleo::SignatureKeyListViewItem::SignatureKeyListViewItem( KeyListViewItem * parent, const GpgME::UserID::Signature & signature )
00656   : KeyListViewItem( parent, signature.parent().parent() ), mSignature( signature )
00657 {
00658 
00659 }
00660 
00661 Kleo::SignatureKeyListViewItem::SignatureKeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::UserID::Signature & signature )
00662   : KeyListViewItem( parent, after, signature.parent().parent() ), mSignature( signature )
00663 {
00664 
00665 }
00666 
00667 void Kleo::SignatureKeyListViewItem::setSignature( const GpgME::UserID::Signature & signature ) {
00668   mSignature = signature;
00669   setKey( signature.parent().parent() );
00670 }
00671 
00672 QString Kleo::SignatureKeyListViewItem::text( int col ) const {
00673   return listView() && listView()->columnStrategy()
00674     ? listView()->columnStrategy()->signatureText( signature(), col )
00675     : QString::null ;
00676 }
00677 
00678 QString Kleo::SignatureKeyListViewItem::toolTip( int col ) const {
00679   return listView() && listView()->columnStrategy()
00680     ? listView()->columnStrategy()->signatureToolTip( signature(), col )
00681     : QString::null ;
00682 }
00683 
00684 const QPixmap * Kleo::SignatureKeyListViewItem::pixmap( int col ) const {
00685   return listView() && listView()->columnStrategy()
00686     ? listView()->columnStrategy()->signaturePixmap( signature(), col ) : 0 ;
00687 }
00688 
00689 int Kleo::SignatureKeyListViewItem::compare( QListViewItem * item, int col, bool ascending ) const {
00690   if ( !item || item->rtti() != RTTI || !listView() || !listView()->columnStrategy() )
00691     return KeyListViewItem::compare( item, col, ascending );
00692   SignatureKeyListViewItem * that = static_cast<SignatureKeyListViewItem*>( item );
00693   return listView()->columnStrategy()->signatureCompare( this->signature(), that->signature(), col );
00694 }
00695 
00696 void Kleo::SignatureKeyListViewItem::paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment ) {
00697   const KeyListView::DisplayStrategy * ds = listView() ? listView()->displayStrategy() : 0 ;
00698   if ( !ds ) {
00699     QListViewItem::paintCell( p, cg, column, width, alignment );
00700     return;
00701   }
00702   const QColor fg = ds->signatureForeground( signature(), cg.text() );
00703   const QColor bg = ds->signatureBackground( signature(), cg.base() );
00704   const QFont f = ds->signatureFont( signature(), p->font() );
00705 
00706   QColorGroup _cg = cg;
00707   p->setFont( f );
00708   _cg.setColor( QColorGroup::Text, fg );
00709   _cg.setColor( QColorGroup::Base, bg );
00710 
00711   QListViewItem::paintCell( p, _cg, column, width, alignment );
00712 }
00713 
00714 
00715 //
00716 //
00717 // ColumnStrategy
00718 //
00719 //
00720 
00721 Kleo::KeyListView::ColumnStrategy::~ColumnStrategy() {}
00722 
00723 int Kleo::KeyListView::ColumnStrategy::compare( const GpgME::Key & key1, const GpgME::Key & key2, int col ) const {
00724   return QString::localeAwareCompare( text( key1, col ), text( key2, col ) );
00725 }
00726 
00727 int Kleo::KeyListView::ColumnStrategy::width( int col, const QFontMetrics & fm ) const {
00728   return fm.width( title( col ) ) * 2;
00729 }
00730 
00731 int Kleo::KeyListView::ColumnStrategy::subkeyCompare( const GpgME::Subkey & sub1, const GpgME::Subkey & sub2, int col ) const {
00732   return QString::localeAwareCompare( subkeyText( sub1, col ), subkeyText( sub2, col ) );
00733 }
00734 
00735 int Kleo::KeyListView::ColumnStrategy::userIDCompare( const GpgME::UserID & uid1, const GpgME::UserID & uid2, int col ) const {
00736   return QString::localeAwareCompare( userIDText( uid1, col ), userIDText( uid2, col ) );
00737 }
00738 
00739 int Kleo::KeyListView::ColumnStrategy::signatureCompare( const GpgME::UserID::Signature & sig1, const GpgME::UserID::Signature & sig2, int col ) const {
00740   return QString::localeAwareCompare( signatureText( sig1, col ), signatureText( sig2, col ) );
00741 }
00742 
00743 QString Kleo::KeyListView::ColumnStrategy::toolTip( const GpgME::Key & key, int col ) const {
00744   return text( key, col );
00745 }
00746 
00747 QString Kleo::KeyListView::ColumnStrategy::subkeyToolTip( const GpgME::Subkey & sub, int col ) const {
00748   return subkeyText( sub, col );
00749 }
00750 
00751 QString Kleo::KeyListView::ColumnStrategy::userIDToolTip( const GpgME::UserID & uid, int col ) const {
00752   return userIDText( uid, col );
00753 }
00754 
00755 QString Kleo::KeyListView::ColumnStrategy::signatureToolTip( const GpgME::UserID::Signature & sig, int col ) const {
00756   return signatureText( sig, col );
00757 }
00758 
00759 //
00760 //
00761 // DisplayStrategy
00762 //
00763 //
00764 
00765 Kleo::KeyListView::DisplayStrategy::~DisplayStrategy() {}
00766 
00767 
00768 //font
00769 QFont Kleo::KeyListView::DisplayStrategy::keyFont( const GpgME::Key &, const QFont & font ) const {
00770   return font;
00771 }
00772 
00773 QFont Kleo::KeyListView::DisplayStrategy::subkeyFont( const GpgME::Subkey &, const QFont & font ) const {
00774   return font;
00775 }
00776 
00777 QFont Kleo::KeyListView::DisplayStrategy::useridFont( const GpgME::UserID &, const QFont & font ) const {
00778   return font;
00779 }
00780 
00781 QFont Kleo::KeyListView::DisplayStrategy::signatureFont( const GpgME::UserID::Signature &, const QFont & font ) const {
00782   return font;
00783 }
00784 
00785 //foreground
00786 QColor Kleo::KeyListView::DisplayStrategy::keyForeground( const GpgME::Key &, const QColor & fg )const {
00787   return fg;
00788 }
00789 
00790 QColor Kleo::KeyListView::DisplayStrategy::subkeyForeground( const GpgME::Subkey &, const QColor & fg ) const {
00791   return fg;
00792 }
00793 
00794 QColor Kleo::KeyListView::DisplayStrategy::useridForeground( const GpgME::UserID &, const QColor & fg ) const {
00795   return fg;
00796 }
00797 
00798 QColor Kleo::KeyListView::DisplayStrategy::signatureForeground( const GpgME::UserID::Signature &, const QColor & fg ) const {
00799   return fg;
00800 }
00801 
00802 //background
00803 QColor Kleo::KeyListView::DisplayStrategy::keyBackground( const GpgME::Key &, const QColor & bg )const {
00804   return bg;
00805 }
00806 
00807 QColor Kleo::KeyListView::DisplayStrategy::subkeyBackground( const GpgME::Subkey &, const QColor & bg ) const {
00808   return bg;
00809 }
00810 
00811 QColor Kleo::KeyListView::DisplayStrategy::useridBackground( const GpgME::UserID &, const QColor & bg ) const {
00812   return bg;
00813 }
00814 
00815 QColor Kleo::KeyListView::DisplayStrategy::signatureBackground( const GpgME::UserID::Signature &, const QColor & bg ) const {
00816   return bg;
00817 }
00818 
00819 
00820 //
00821 //
00822 // Collection of covariant return reimplementations of QListView(Item)
00823 // members:
00824 //
00825 //
00826 
00827 Kleo::KeyListView * Kleo::KeyListViewItem::listView() const {
00828   return static_cast<Kleo::KeyListView*>( QListViewItem::listView() );
00829 }
00830 
00831 Kleo::KeyListViewItem * Kleo::KeyListViewItem::nextSibling() const {
00832   return static_cast<Kleo::KeyListViewItem*>( QListViewItem::nextSibling() );
00833 }
00834 
00835 Kleo::KeyListViewItem * Kleo::KeyListView::firstChild() const {
00836   return static_cast<Kleo::KeyListViewItem*>( KListView::firstChild() );
00837 }
00838 
00839 Kleo::KeyListViewItem * Kleo::KeyListView::selectedItem() const {
00840   return static_cast<Kleo::KeyListViewItem*>( KListView::selectedItem() );
00841 }
00842 
00843 static void selectedItems( QPtrList<Kleo::KeyListViewItem> & result, QListViewItem * start ) {
00844   for ( QListViewItem * item = start ; item ; item = item->nextSibling() ) {
00845     if ( item->isSelected() )
00846       if ( Kleo::KeyListViewItem * i = Kleo::lvi_cast<Kleo::KeyListViewItem>( item ) )
00847     result.append( i );
00848     selectedItems( result, item->firstChild() );
00849   }
00850 }
00851 
00852 QPtrList<Kleo::KeyListViewItem> Kleo::KeyListView::selectedItems() const {
00853   QPtrList<KeyListViewItem> result;
00854   ::selectedItems( result, firstChild() );
00855   return result;
00856 }
00857 
00858 static bool hasSelection( QListViewItem * start ) {
00859   for ( QListViewItem * item = start ; item ; item = item->nextSibling() )
00860     if ( item->isSelected() || hasSelection( item->firstChild() ) )
00861       return true;
00862   return false;
00863 }
00864 
00865 bool Kleo::KeyListView::hasSelection() const {
00866   return ::hasSelection( firstChild() );
00867 }
00868 
00869 #include "keylistview.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys