certmanager/lib

keylistview.cpp
1/*
2 keylistview.cpp
3
4 This file is part of libkleopatra, the KDE keymanagement library
5 Copyright (c) 2004 Klarälvdalens Datakonsult AB
6
7 Libkleopatra is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
11
12 Libkleopatra is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
21 In addition, as a special exception, the copyright holders give
22 permission to link the code of this program with any edition of
23 the TQt library by Trolltech AS, Norway (or with modified versions
24 of TQt that use the same license as TQt), and distribute linked
25 combinations including the two. You must obey the GNU General
26 Public License in all respects for all of the code used other than
27 TQt. If you modify this file, you may extend this exception to
28 your version of the file, but you are not obligated to do so. If
29 you do not wish to do so, delete this exception statement from
30 your version.
31*/
32
33#ifdef HAVE_CONFIG_H
34#include <config.h>
35#endif
36
37#include "keylistview.h"
38
39#include <kdebug.h>
40
41#include <tqfontmetrics.h>
42#include <tqtooltip.h>
43#include <tqrect.h>
44#include <tqheader.h>
45#include <tqpoint.h>
46#include <tqptrlist.h>
47#include <tqpainter.h>
48#include <tqfont.h>
49#include <tqcolor.h>
50#include <tqtimer.h>
51#include <tqcstring.h>
52
53#include <gpgmepp/key.h>
54
55#include <vector>
56#include <map>
57
58#include <assert.h>
59
60static const int updateDelayMilliSecs = 500;
61
62namespace {
63
64 class ItemToolTip : public TQToolTip {
65 public:
66 ItemToolTip( Kleo::KeyListView * parent );
67 protected:
68 void maybeTip( const TQPoint & p );
69 private:
70 Kleo::KeyListView * mKeyListView;
71 };
72
73 ItemToolTip::ItemToolTip( Kleo::KeyListView * parent )
74 : TQToolTip( parent->viewport() ), mKeyListView( parent ) {}
75
76 void ItemToolTip::maybeTip( const TQPoint & p ) {
77 if ( !mKeyListView )
78 return;
79
80 const TQListViewItem * item = mKeyListView->itemAt( p );
81 if ( !item )
82 return;
83
84 const TQRect itemRect = mKeyListView->itemRect( item );
85 if ( !itemRect.isValid() )
86 return;
87
88 const int col = mKeyListView->header()->sectionAt( p.x() );
89 if ( col == -1 )
90 return;
91
92 const TQRect headerRect = mKeyListView->header()->sectionRect( col );
93 if ( !headerRect.isValid() )
94 return;
95
96 const TQRect cellRect( headerRect.left(), itemRect.top(),
97 headerRect.width(), itemRect.height() );
98
99 TQString tipStr;
100 if ( const Kleo::KeyListViewItem * klvi = Kleo::lvi_cast<Kleo::KeyListViewItem>( item ) )
101 tipStr = klvi->toolTip( col );
102 else
103 tipStr = item->text( col ) ;
104
105 if ( !tipStr.isEmpty() )
106 tip( cellRect, tipStr );
107 }
108
109} // anon namespace
110
111struct Kleo::KeyListView::Private {
112 Private() : updateTimer( 0 ), itemToolTip( 0 ) {}
113
114 std::vector<GpgME::Key> keyBuffer;
115 TQTimer * updateTimer;
116 TQToolTip * itemToolTip;
117 std::map<TQCString,KeyListViewItem*> itemMap;
118};
119
120// a list of signals where we want to replace TQListViewItem with
121// Kleo:KeyListViewItem:
122static const struct {
123 const char * source;
124 const char * target;
125} signalReplacements[] = {
126 { TQ_SIGNAL(doubleClicked(TQListViewItem*,const TQPoint&,int)),
127 TQ_SLOT(slotEmitDoubleClicked(TQListViewItem*,const TQPoint&,int)) },
128 { TQ_SIGNAL(returnPressed(TQListViewItem*)),
129 TQ_SLOT(slotEmitReturnPressed(TQListViewItem*)) },
130 { TQ_SIGNAL(selectionChanged(TQListViewItem*)),
131 TQ_SLOT(slotEmitSelectionChanged(TQListViewItem*)) },
132 { TQ_SIGNAL(contextMenu(TDEListView*, TQListViewItem*,const TQPoint&)),
133 TQ_SLOT(slotEmitContextMenu(TDEListView*, TQListViewItem*,const TQPoint&)) },
134};
135static const int numSignalReplacements = sizeof signalReplacements / sizeof *signalReplacements;
136
137
138Kleo::KeyListView::KeyListView( const ColumnStrategy * columnStrategy, const DisplayStrategy * displayStrategy, TQWidget * parent, const char * name, WFlags f )
139 : TDEListView( parent, name ),
140 mColumnStrategy( columnStrategy ),
141 mDisplayStrategy ( displayStrategy ),
142 mHierarchical( false )
143{
144 setWFlags( f );
145
146 d = new Private();
147
148 d->updateTimer = new TQTimer( this );
149 connect( d->updateTimer, TQ_SIGNAL(timeout()), TQ_SLOT(slotUpdateTimeout()) );
150
151 if ( !columnStrategy ) {
152 kdWarning(5150) << "Kleo::KeyListView: need a column strategy to work with!" << endl;
153 return;
154 }
155
156 const TQFontMetrics fm = fontMetrics();
157
158 for ( int col = 0 ; !columnStrategy->title( col ).isEmpty() ; ++col ) {
159 addColumn( columnStrategy->title( col ), columnStrategy->width( col, fm ) );
160 setColumnWidthMode( col, columnStrategy->widthMode( col ) );
161 }
162
163 setAllColumnsShowFocus( true );
164 setShowToolTips( false ); // we do it instead...
165
166 for ( int i = 0 ; i < numSignalReplacements ; ++i )
167 connect( this, signalReplacements[i].source, signalReplacements[i].target );
168
169 TQToolTip::remove( this );
170 TQToolTip::remove( viewport() ); // make double sure :)
171 d->itemToolTip = new ItemToolTip( this );
172}
173
174Kleo::KeyListView::~KeyListView() {
175 d->updateTimer->stop();
176 // need to clear here, since in ~TQListView, our children won't have
177 // a valid listView() pointing to us anymore, and their dtors try to
178 // unregister from us.
179 clear();
180 assert( d->itemMap.size() == 0 );
181 // need to delete the tooltip ourselves, as ~TQToolTip isn't virtual :o
182 delete d->itemToolTip; d->itemToolTip = 0;
183 delete d; d = 0;
184 delete mColumnStrategy; mColumnStrategy = 0;
185 delete mDisplayStrategy; mDisplayStrategy = 0;
186}
187
188void Kleo::KeyListView::insertItem( TQListViewItem * qlvi ) {
189 //kdDebug() << "Kleo::KeyListView::insertItem( " << qlvi << " )" << endl;
190 TDEListView::insertItem( qlvi );
191 if ( KeyListViewItem * item = lvi_cast<KeyListViewItem>( qlvi ) )
192 registerItem( item );
193}
194
195void Kleo::KeyListView::takeItem( TQListViewItem * qlvi ) {
196 //kdDebug() << "Kleo::KeyListView::takeItem( " << qlvi << " )" << endl;
197 if ( KeyListViewItem * item = lvi_cast<KeyListViewItem>( qlvi ) )
198 deregisterItem( item );
199 TDEListView::takeItem( qlvi );
200}
201
202
203void Kleo::KeyListView::setHierarchical( bool hier ) {
204 if ( hier == mHierarchical )
205 return;
206 mHierarchical = hier;
207 if ( hier )
208 gatherScattered();
209 else
210 scatterGathered( firstChild() );
211}
212
213void Kleo::KeyListView::slotAddKey( const GpgME::Key & key ) {
214 if ( key.isNull() )
215 return;
216
217 d->keyBuffer.push_back( key );
218 if ( !d->updateTimer->isActive() )
219 d->updateTimer->start( updateDelayMilliSecs, true /* single-shot */ );
220}
221
222void Kleo::KeyListView::slotUpdateTimeout() {
223 if ( d->keyBuffer.empty() )
224 return;
225
226 const bool wasUpdatesEnabled = viewport()->isUpdatesEnabled();
227 if ( wasUpdatesEnabled )
228 viewport()->setUpdatesEnabled( false );
229 kdDebug( 5150 ) << "Kleo::KeyListView::slotUpdateTimeout(): processing "
230 << d->keyBuffer.size() << " items en block" << endl;
231 if ( hierarchical() ) {
232 for ( std::vector<GpgME::Key>::const_iterator it = d->keyBuffer.begin() ; it != d->keyBuffer.end() ; ++it )
233 doHierarchicalInsert( *it );
234 gatherScattered();
235 } else {
236 for ( std::vector<GpgME::Key>::const_iterator it = d->keyBuffer.begin() ; it != d->keyBuffer.end() ; ++it )
237 (void)new KeyListViewItem( this, *it );
238 }
239 if ( wasUpdatesEnabled )
240 viewport()->setUpdatesEnabled( true );
241 d->keyBuffer.clear();
242}
243
244void Kleo::KeyListView::clear() {
245 d->updateTimer->stop();
246 d->keyBuffer.clear();
247 TDEListView::clear();
248}
249
250void Kleo::KeyListView::registerItem( KeyListViewItem * item ) {
251 //kdDebug() << "registerItem( " << item << " )" << endl;
252 if ( !item )
253 return;
254 const TQCString fpr = item->key().primaryFingerprint();
255 if ( !fpr.isEmpty() )
256 d->itemMap.insert( std::make_pair( fpr, item ) );
257}
258
259void Kleo::KeyListView::deregisterItem( const KeyListViewItem * item ) {
260 //kdDebug() << "deregisterItem( KeyLVI: " << item << " )" << endl;
261 if ( !item )
262 return;
263 std::map<TQCString,KeyListViewItem*>::iterator it
264 = d->itemMap.find( item->key().primaryFingerprint() );
265 if ( it == d->itemMap.end() )
266 return;
267 Q_ASSERT( it->second == item );
268 if ( it->second != item )
269 return;
270 d->itemMap.erase( it );
271}
272
273void Kleo::KeyListView::doHierarchicalInsert( const GpgME::Key & key ) {
274 const TQCString fpr = key.primaryFingerprint();
275 if ( fpr.isEmpty() )
276 return;
277 KeyListViewItem * item = 0;
278 if ( !key.isRoot() )
279 if ( KeyListViewItem * parent = itemByFingerprint( key.chainID() ) ) {
280 item = new KeyListViewItem( parent, key );
281 parent->setOpen( true );
282 }
283 if ( !item )
284 item = new KeyListViewItem( this, key ); // top-level (for now)
285
286 d->itemMap.insert( std::make_pair( fpr, item ) );
287}
288
289void Kleo::KeyListView::gatherScattered() {
290 KeyListViewItem * item = firstChild();
291 while ( item ) {
292 KeyListViewItem * cur = item;
293 item = item->nextSibling();
294 if ( cur->key().isRoot() )
295 continue;
296 if ( KeyListViewItem * parent = itemByFingerprint( cur->key().chainID() ) ) {
297 // found a new parent...
298 // ### todo: optimize by suppressing removing/adding the item to the itemMap...
299 takeItem( cur );
300 parent->insertItem( cur );
301 parent->setOpen( true );
302 }
303 }
304}
305
306void Kleo::KeyListView::scatterGathered( TQListViewItem * start ) {
307 TQListViewItem * item = start;
308 while ( item ) {
309 TQListViewItem * cur = item;
310 item = item->nextSibling();
311
312 scatterGathered( cur->firstChild() );
313 assert( cur->childCount() == 0 );
314
315 // ### todo: optimize by suppressing removing/adding the item to the itemMap...
316 if ( cur->parent() )
317 cur->parent()->takeItem( cur );
318 else
319 takeItem( cur );
320 insertItem( cur );
321 }
322}
323
324Kleo::KeyListViewItem * Kleo::KeyListView::itemByFingerprint( const TQCString & s ) const {
325 if ( s.isEmpty() )
326 return 0;
327 const std::map<TQCString,KeyListViewItem*>::const_iterator it = d->itemMap.find( s );
328 if ( it == d->itemMap.end() )
329 return 0;
330 return it->second;
331}
332
333
334void Kleo::KeyListView::slotRefreshKey( const GpgME::Key & key ) {
335 const char * fpr = key.primaryFingerprint();
336 if ( !fpr ) {
337 return;
338 }
339 if ( KeyListViewItem * item = itemByFingerprint( fpr ) ) {
340 item->setKey ( key );
341 }
342 else {
343 // none found -> add it
344 slotAddKey( key );
345 }
346}
347
348// slots for the emission of covariant signals:
349
350void Kleo::KeyListView::slotEmitDoubleClicked( TQListViewItem * item, const TQPoint & p, int col ) {
351 if ( !item || lvi_cast<KeyListViewItem>( item ) )
352 emit doubleClicked( static_cast<KeyListViewItem*>( item ), p, col );
353}
354
355void Kleo::KeyListView::slotEmitReturnPressed( TQListViewItem * item ) {
356 if ( !item || lvi_cast<KeyListViewItem>( item ) )
357 emit returnPressed( static_cast<KeyListViewItem*>( item ) );
358}
359
360void Kleo::KeyListView::slotEmitSelectionChanged( TQListViewItem * item ) {
361 if ( !item || lvi_cast<KeyListViewItem>( item ) )
362 emit selectionChanged( static_cast<KeyListViewItem*>( item ) );
363}
364
365void Kleo::KeyListView::slotEmitContextMenu( TDEListView*, TQListViewItem * item, const TQPoint & p ) {
366 if ( !item || lvi_cast<KeyListViewItem>( item ) )
367 emit contextMenu( static_cast<KeyListViewItem*>( item ), p );
368}
369
370//
371//
372// KeyListViewItem
373//
374//
375
376Kleo::KeyListViewItem::KeyListViewItem( KeyListView * parent, const GpgME::Key & key )
377 : TQListViewItem( parent )
378{
379 setKey( key );
380}
381
382Kleo::KeyListViewItem::KeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::Key & key )
383 : TQListViewItem( parent, after )
384{
385 setKey( key );
386}
387
388Kleo::KeyListViewItem::KeyListViewItem( KeyListViewItem * parent, const GpgME::Key & key )
389 : TQListViewItem( parent )
390{
391 setKey( key );
392}
393
394Kleo::KeyListViewItem::KeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::Key & key )
395 : TQListViewItem( parent, after )
396{
397 setKey( key );
398}
399
400Kleo::KeyListViewItem::~KeyListViewItem() {
401 // delete the children first... When children are deleted in the
402 // TQLVI dtor, they don't have listView() anymore, thus they don't
403 // call deregister( this ), leading to stale entries in the
404 // itemMap...
405 while ( TQListViewItem * item = firstChild() )
406 delete item;
407 // better do this here, too, since deletion is top-down and thus
408 // we're deleted when our parent item is no longer a
409 // KeyListViewItem, but a mere TQListViewItem, so our takeItem()
410 // overload is gone by that time...
411 if ( KeyListView * lv = listView() )
412 lv->deregisterItem( this );
413}
414
415void Kleo::KeyListViewItem::setKey( const GpgME::Key & key ) {
416 KeyListView * lv = listView();
417 if ( lv )
418 lv->deregisterItem( this );
419 mKey = key;
420 if ( lv )
421 lv->registerItem( this );
422
423 // the ColumnStrategy operations might be very slow, so cache their
424 // result here, where we're non-const :)
425 const Kleo::KeyListView::ColumnStrategy * cs = lv ? lv->columnStrategy() : 0 ;
426 if ( !cs )
427 return;
428 const int numCols = lv ? lv->columns() : 0 ;
429 for ( int i = 0 ; i < numCols ; ++i ) {
430 setText( i, cs->text( key, i ) );
431 if ( const TQPixmap * pix = cs->pixmap( key, i ) )
432 setPixmap( i, *pix );
433 }
434 repaint();
435}
436
437TQString Kleo::KeyListViewItem::toolTip( int col ) const {
438 return listView() && listView()->columnStrategy()
439 ? listView()->columnStrategy()->toolTip( key(), col )
440 : TQString() ;
441}
442
443int Kleo::KeyListViewItem::compare( TQListViewItem * item, int col, bool ascending ) const {
444 if ( !item || item->rtti() != RTTI || !listView() || !listView()->columnStrategy() )
445 return TQListViewItem::compare( item, col, ascending );
446 KeyListViewItem * that = static_cast<KeyListViewItem*>( item );
447 return listView()->columnStrategy()->compare( this->key(), that->key(), col );
448}
449
450void Kleo::KeyListViewItem::paintCell( TQPainter * p, const TQColorGroup & cg, int column, int width, int alignment ) {
451 const KeyListView::DisplayStrategy * ds = listView() ? listView()->displayStrategy() : 0 ;
452 if ( !ds ) {
453 TQListViewItem::paintCell( p, cg, column, width, alignment );
454 return;
455 }
456 const TQColor fg = ds->keyForeground( key(), cg.text() );
457 const TQColor bg = ds->keyBackground( key(), cg.base() );
458 const TQFont f = ds->keyFont( key(), p->font() );
459
460 TQColorGroup _cg = cg;
461 p->setFont( f );
462 _cg.setColor( TQColorGroup::Text, fg );
463 _cg.setColor( TQColorGroup::Base, bg );
464
465 TQListViewItem::paintCell( p, _cg, column, width, alignment );
466}
467
468void Kleo::KeyListViewItem::insertItem( TQListViewItem * qlvi ) {
469 //kdDebug() << "Kleo::KeyListViewItem::insertItem( " << qlvi << " )" << endl;
470 TQListViewItem::insertItem( qlvi );
471 if ( KeyListViewItem * item = lvi_cast<KeyListViewItem>( qlvi ) )
472 listView()->registerItem( item );
473}
474
475void Kleo::KeyListViewItem::takeItem( TQListViewItem * qlvi ) {
476 //kdDebug() << "Kleo::KeyListViewItem::takeItem( " << qlvi << " )" << endl;
477 if ( KeyListViewItem * item = lvi_cast<KeyListViewItem>( qlvi ) )
478 listView()->deregisterItem( item );
479 TQListViewItem::takeItem( qlvi );
480}
481
482
483//
484//
485// SubkeyKeyListViewItem
486//
487//
488
489Kleo::SubkeyKeyListViewItem::SubkeyKeyListViewItem( KeyListView * parent, const GpgME::Subkey & subkey )
490 : KeyListViewItem( parent, subkey.parent() ), mSubkey( subkey )
491{
492
493}
494
495Kleo::SubkeyKeyListViewItem::SubkeyKeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::Subkey & subkey )
496 : KeyListViewItem( parent, after, subkey.parent() ), mSubkey( subkey )
497{
498
499}
500
501Kleo::SubkeyKeyListViewItem::SubkeyKeyListViewItem( KeyListViewItem * parent, const GpgME::Subkey & subkey )
502 : KeyListViewItem( parent, subkey.parent() ), mSubkey( subkey )
503{
504
505}
506
507Kleo::SubkeyKeyListViewItem::SubkeyKeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::Subkey & subkey )
508 : KeyListViewItem( parent, after, subkey.parent() ), mSubkey( subkey )
509{
510
511}
512
513void Kleo::SubkeyKeyListViewItem::setSubkey( const GpgME::Subkey & subkey ) {
514 mSubkey = subkey;
515 setKey( subkey.parent() );
516}
517
518TQString Kleo::SubkeyKeyListViewItem::text( int col ) const {
519 return listView() && listView()->columnStrategy()
520 ? listView()->columnStrategy()->subkeyText( subkey(), col )
521 : TQString() ;
522}
523
524TQString Kleo::SubkeyKeyListViewItem::toolTip( int col ) const {
525 return listView() && listView()->columnStrategy()
526 ? listView()->columnStrategy()->subkeyToolTip( subkey(), col )
527 : TQString() ;
528}
529
530const TQPixmap * Kleo::SubkeyKeyListViewItem::pixmap( int col ) const {
531 return listView() && listView()->columnStrategy()
532 ? listView()->columnStrategy()->subkeyPixmap( subkey(), col ) : 0 ;
533}
534
535int Kleo::SubkeyKeyListViewItem::compare( TQListViewItem * item, int col, bool ascending ) const {
536 if ( !item || item->rtti() != RTTI || !listView() || !listView()->columnStrategy() )
537 return KeyListViewItem::compare( item, col, ascending );
538 SubkeyKeyListViewItem * that = static_cast<SubkeyKeyListViewItem*>( item );
539 return listView()->columnStrategy()->subkeyCompare( this->subkey(), that->subkey(), col );
540}
541
542void Kleo::SubkeyKeyListViewItem::paintCell( TQPainter * p, const TQColorGroup & cg, int column, int width, int alignment ) {
543 const KeyListView::DisplayStrategy * ds = listView() ? listView()->displayStrategy() : 0 ;
544 if ( !ds ) {
545 TQListViewItem::paintCell( p, cg, column, width, alignment );
546 return;
547 }
548 const TQColor fg = ds->subkeyForeground( subkey(), cg.text() );
549 const TQColor bg = ds->subkeyBackground( subkey(), cg.base() );
550 const TQFont f = ds->subkeyFont( subkey(), p->font() );
551
552 TQColorGroup _cg = cg;
553 p->setFont( f );
554 _cg.setColor( TQColorGroup::Text, fg );
555 _cg.setColor( TQColorGroup::Base, bg );
556
557 TQListViewItem::paintCell( p, _cg, column, width, alignment );
558}
559
560
561//
562//
563// UserIDKeyListViewItem
564//
565//
566
567Kleo::UserIDKeyListViewItem::UserIDKeyListViewItem( KeyListView * parent, const GpgME::UserID & userID )
568 : KeyListViewItem( parent, userID.parent() ), mUserID( userID )
569{
570
571}
572
573Kleo::UserIDKeyListViewItem::UserIDKeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::UserID & userID )
574 : KeyListViewItem( parent, after, userID.parent() ), mUserID( userID )
575{
576
577}
578
579Kleo::UserIDKeyListViewItem::UserIDKeyListViewItem( KeyListViewItem * parent, const GpgME::UserID & userID )
580 : KeyListViewItem( parent, userID.parent() ), mUserID( userID )
581{
582
583}
584
585Kleo::UserIDKeyListViewItem::UserIDKeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::UserID & userID )
586 : KeyListViewItem( parent, after, userID.parent() ), mUserID( userID )
587{
588
589}
590
591void Kleo::UserIDKeyListViewItem::setUserID( const GpgME::UserID & userID ) {
592 mUserID = userID;
593 setKey( userID.parent() );
594}
595
596TQString Kleo::UserIDKeyListViewItem::text( int col ) const {
597 return listView() && listView()->columnStrategy()
598 ? listView()->columnStrategy()->userIDText( userID(), col )
599 : TQString() ;
600}
601
602TQString Kleo::UserIDKeyListViewItem::toolTip( int col ) const {
603 return listView() && listView()->columnStrategy()
604 ? listView()->columnStrategy()->userIDToolTip( userID(), col )
605 : TQString() ;
606}
607
608const TQPixmap * Kleo::UserIDKeyListViewItem::pixmap( int col ) const {
609 return listView() && listView()->columnStrategy()
610 ? listView()->columnStrategy()->userIDPixmap( userID(), col ) : 0 ;
611}
612
613int Kleo::UserIDKeyListViewItem::compare( TQListViewItem * item, int col, bool ascending ) const {
614 if ( !item || item->rtti() != RTTI || !listView() || !listView()->columnStrategy() )
615 return KeyListViewItem::compare( item, col, ascending );
616 UserIDKeyListViewItem * that = static_cast<UserIDKeyListViewItem*>( item );
617 return listView()->columnStrategy()->userIDCompare( this->userID(), that->userID(), col );
618}
619
620
621void Kleo::UserIDKeyListViewItem::paintCell( TQPainter * p, const TQColorGroup & cg, int column, int width, int alignment ) {
622 const KeyListView::DisplayStrategy * ds = listView() ? listView()->displayStrategy() : 0 ;
623 if ( !ds ) {
624 TQListViewItem::paintCell( p, cg, column, width, alignment );
625 return;
626 }
627 const TQColor fg = ds->useridForeground( userID(), cg.text() );
628 const TQColor bg = ds->useridBackground( userID(), cg.base() );
629 const TQFont f = ds->useridFont( userID(), p->font() );
630
631 TQColorGroup _cg = cg;
632 p->setFont( f );
633 _cg.setColor( TQColorGroup::Text, fg );
634 _cg.setColor( TQColorGroup::Base, bg );
635
636 TQListViewItem::paintCell( p, _cg, column, width, alignment );
637}
638
639
640//
641//
642// SignatureKeyListViewItem
643//
644//
645
646Kleo::SignatureKeyListViewItem::SignatureKeyListViewItem( KeyListView * parent, const GpgME::UserID::Signature & signature )
647 : KeyListViewItem( parent, signature.parent().parent() ), mSignature( signature )
648{
649
650}
651
652Kleo::SignatureKeyListViewItem::SignatureKeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::UserID::Signature & signature )
653 : KeyListViewItem( parent, after, signature.parent().parent() ), mSignature( signature )
654{
655
656}
657
658Kleo::SignatureKeyListViewItem::SignatureKeyListViewItem( KeyListViewItem * parent, const GpgME::UserID::Signature & signature )
659 : KeyListViewItem( parent, signature.parent().parent() ), mSignature( signature )
660{
661
662}
663
664Kleo::SignatureKeyListViewItem::SignatureKeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::UserID::Signature & signature )
665 : KeyListViewItem( parent, after, signature.parent().parent() ), mSignature( signature )
666{
667
668}
669
670void Kleo::SignatureKeyListViewItem::setSignature( const GpgME::UserID::Signature & signature ) {
671 mSignature = signature;
672 setKey( signature.parent().parent() );
673}
674
675TQString Kleo::SignatureKeyListViewItem::text( int col ) const {
676 return listView() && listView()->columnStrategy()
677 ? listView()->columnStrategy()->signatureText( signature(), col )
678 : TQString() ;
679}
680
681TQString Kleo::SignatureKeyListViewItem::toolTip( int col ) const {
682 return listView() && listView()->columnStrategy()
683 ? listView()->columnStrategy()->signatureToolTip( signature(), col )
684 : TQString() ;
685}
686
687const TQPixmap * Kleo::SignatureKeyListViewItem::pixmap( int col ) const {
688 return listView() && listView()->columnStrategy()
689 ? listView()->columnStrategy()->signaturePixmap( signature(), col ) : 0 ;
690}
691
692int Kleo::SignatureKeyListViewItem::compare( TQListViewItem * item, int col, bool ascending ) const {
693 if ( !item || item->rtti() != RTTI || !listView() || !listView()->columnStrategy() )
694 return KeyListViewItem::compare( item, col, ascending );
695 SignatureKeyListViewItem * that = static_cast<SignatureKeyListViewItem*>( item );
696 return listView()->columnStrategy()->signatureCompare( this->signature(), that->signature(), col );
697}
698
699void Kleo::SignatureKeyListViewItem::paintCell( TQPainter * p, const TQColorGroup & cg, int column, int width, int alignment ) {
700 const KeyListView::DisplayStrategy * ds = listView() ? listView()->displayStrategy() : 0 ;
701 if ( !ds ) {
702 TQListViewItem::paintCell( p, cg, column, width, alignment );
703 return;
704 }
705 const TQColor fg = ds->signatureForeground( signature(), cg.text() );
706 const TQColor bg = ds->signatureBackground( signature(), cg.base() );
707 const TQFont f = ds->signatureFont( signature(), p->font() );
708
709 TQColorGroup _cg = cg;
710 p->setFont( f );
711 _cg.setColor( TQColorGroup::Text, fg );
712 _cg.setColor( TQColorGroup::Base, bg );
713
714 TQListViewItem::paintCell( p, _cg, column, width, alignment );
715}
716
717
718//
719//
720// ColumnStrategy
721//
722//
723
724Kleo::KeyListView::ColumnStrategy::~ColumnStrategy() {}
725
726int Kleo::KeyListView::ColumnStrategy::compare( const GpgME::Key & key1, const GpgME::Key & key2, int col ) const {
727 return TQString::localeAwareCompare( text( key1, col ), text( key2, col ) );
728}
729
730int Kleo::KeyListView::ColumnStrategy::width( int col, const TQFontMetrics & fm ) const {
731 return fm.width( title( col ) ) * 2;
732}
733
734int Kleo::KeyListView::ColumnStrategy::subkeyCompare( const GpgME::Subkey & sub1, const GpgME::Subkey & sub2, int col ) const {
735 return TQString::localeAwareCompare( subkeyText( sub1, col ), subkeyText( sub2, col ) );
736}
737
738int Kleo::KeyListView::ColumnStrategy::userIDCompare( const GpgME::UserID & uid1, const GpgME::UserID & uid2, int col ) const {
739 return TQString::localeAwareCompare( userIDText( uid1, col ), userIDText( uid2, col ) );
740}
741
742int Kleo::KeyListView::ColumnStrategy::signatureCompare( const GpgME::UserID::Signature & sig1, const GpgME::UserID::Signature & sig2, int col ) const {
743 return TQString::localeAwareCompare( signatureText( sig1, col ), signatureText( sig2, col ) );
744}
745
746TQString Kleo::KeyListView::ColumnStrategy::toolTip( const GpgME::Key & key, int col ) const {
747 return text( key, col );
748}
749
750TQString Kleo::KeyListView::ColumnStrategy::subkeyToolTip( const GpgME::Subkey & sub, int col ) const {
751 return subkeyText( sub, col );
752}
753
754TQString Kleo::KeyListView::ColumnStrategy::userIDToolTip( const GpgME::UserID & uid, int col ) const {
755 return userIDText( uid, col );
756}
757
758TQString Kleo::KeyListView::ColumnStrategy::signatureToolTip( const GpgME::UserID::Signature & sig, int col ) const {
759 return signatureText( sig, col );
760}
761
762//
763//
764// DisplayStrategy
765//
766//
767
768Kleo::KeyListView::DisplayStrategy::~DisplayStrategy() {}
769
770
771//font
772TQFont Kleo::KeyListView::DisplayStrategy::keyFont( const GpgME::Key &, const TQFont & font ) const {
773 return font;
774}
775
776TQFont Kleo::KeyListView::DisplayStrategy::subkeyFont( const GpgME::Subkey &, const TQFont & font ) const {
777 return font;
778}
779
780TQFont Kleo::KeyListView::DisplayStrategy::useridFont( const GpgME::UserID &, const TQFont & font ) const {
781 return font;
782}
783
784TQFont Kleo::KeyListView::DisplayStrategy::signatureFont( const GpgME::UserID::Signature &, const TQFont & font ) const {
785 return font;
786}
787
788//foreground
789TQColor Kleo::KeyListView::DisplayStrategy::keyForeground( const GpgME::Key &, const TQColor & fg )const {
790 return fg;
791}
792
793TQColor Kleo::KeyListView::DisplayStrategy::subkeyForeground( const GpgME::Subkey &, const TQColor & fg ) const {
794 return fg;
795}
796
797TQColor Kleo::KeyListView::DisplayStrategy::useridForeground( const GpgME::UserID &, const TQColor & fg ) const {
798 return fg;
799}
800
801TQColor Kleo::KeyListView::DisplayStrategy::signatureForeground( const GpgME::UserID::Signature &, const TQColor & fg ) const {
802 return fg;
803}
804
805//background
806TQColor Kleo::KeyListView::DisplayStrategy::keyBackground( const GpgME::Key &, const TQColor & bg )const {
807 return bg;
808}
809
810TQColor Kleo::KeyListView::DisplayStrategy::subkeyBackground( const GpgME::Subkey &, const TQColor & bg ) const {
811 return bg;
812}
813
814TQColor Kleo::KeyListView::DisplayStrategy::useridBackground( const GpgME::UserID &, const TQColor & bg ) const {
815 return bg;
816}
817
818TQColor Kleo::KeyListView::DisplayStrategy::signatureBackground( const GpgME::UserID::Signature &, const TQColor & bg ) const {
819 return bg;
820}
821
822
823//
824//
825// Collection of covariant return reimplementations of TQListView(Item)
826// members:
827//
828//
829
830Kleo::KeyListView * Kleo::KeyListViewItem::listView() const {
831 return static_cast<Kleo::KeyListView*>( TQListViewItem::listView() );
832}
833
834Kleo::KeyListViewItem * Kleo::KeyListViewItem::nextSibling() const {
835 return static_cast<Kleo::KeyListViewItem*>( TQListViewItem::nextSibling() );
836}
837
838Kleo::KeyListViewItem * Kleo::KeyListView::firstChild() const {
839 return static_cast<Kleo::KeyListViewItem*>( TDEListView::firstChild() );
840}
841
842Kleo::KeyListViewItem * Kleo::KeyListView::selectedItem() const {
843 return static_cast<Kleo::KeyListViewItem*>( TDEListView::selectedItem() );
844}
845
846static void selectedItems( TQPtrList<Kleo::KeyListViewItem> & result, TQListViewItem * start ) {
847 for ( TQListViewItem * item = start ; item ; item = item->nextSibling() ) {
848 if ( item->isSelected() )
849 if ( Kleo::KeyListViewItem * i = Kleo::lvi_cast<Kleo::KeyListViewItem>( item ) )
850 result.append( i );
851 selectedItems( result, item->firstChild() );
852 }
853}
854
855TQPtrList<Kleo::KeyListViewItem> Kleo::KeyListView::selectedItems() const {
856 TQPtrList<KeyListViewItem> result;
857 ::selectedItems( result, firstChild() );
858 return result;
859}
860
861static bool hasSelection( TQListViewItem * start ) {
862 for ( TQListViewItem * item = start ; item ; item = item->nextSibling() )
863 if ( item->isSelected() || hasSelection( item->firstChild() ) )
864 return true;
865 return false;
866}
867
868bool Kleo::KeyListView::hasSelection() const {
869 return ::hasSelection( firstChild() );
870}
871
872#include "keylistview.moc"