41 #include "keyselectiondialog.h"
43 #include "keylistview.h"
44 #include "progressdialog.h"
47 #include <kleo/keylistjob.h>
48 #include <kleo/cryptobackendfactory.h>
51 #include <gpgmepp/key.h>
52 #include <gpgmepp/keylistresult.h>
55 #include <tdelocale.h>
56 #include <tdeapplication.h>
57 #include <tdeglobal.h>
58 #include <kiconloader.h>
61 #include <tdeconfig.h>
62 #include <tdemessagebox.h>
63 #include <tdeprocess.h>
64 #include <kactivelabel.h>
68 #include <tqcheckbox.h>
69 #include <tqtoolbutton.h>
74 #include <tqlineedit.h>
75 #include <tqwhatsthis.h>
76 #include <tqpopupmenu.h>
78 #include <tqpushbutton.h>
86 static bool checkKeyUsage(
const GpgME::Key & key,
unsigned int keyUsage ) {
88 if ( keyUsage & Kleo::KeySelectionDialog::ValidKeys ) {
89 if ( key.isInvalid() ) {
90 if ( key.keyListMode() & GpgME::Context::Validate ) {
91 kdDebug() <<
"key is invalid" << endl;
94 kdDebug() <<
"key is invalid - ignoring" << endl;
97 if ( key.isExpired() ) {
98 kdDebug() <<
"key is expired" << endl;
100 }
else if ( key.isRevoked() ) {
101 kdDebug() <<
"key is revoked" << endl;
103 }
else if ( key.isDisabled() ) {
104 kdDebug() <<
"key is disabled" << endl;
109 if ( keyUsage & Kleo::KeySelectionDialog::EncryptionKeys &&
110 !key.canEncrypt() ) {
111 kdDebug() <<
"key can't encrypt" << endl;
114 if ( keyUsage & Kleo::KeySelectionDialog::SigningKeys &&
116 kdDebug() <<
"key can't sign" << endl;
119 if ( keyUsage & Kleo::KeySelectionDialog::CertificationKeys &&
120 !key.canCertify() ) {
121 kdDebug() <<
"key can't certify" << endl;
124 if ( keyUsage & Kleo::KeySelectionDialog::AuthenticationKeys &&
125 !key.canAuthenticate() ) {
126 kdDebug() <<
"key can't authenticate" << endl;
130 if ( keyUsage & Kleo::KeySelectionDialog::SecretKeys &&
131 !( keyUsage & Kleo::KeySelectionDialog::PublicKeys ) &&
133 kdDebug() <<
"key isn't secret" << endl;
137 if ( keyUsage & Kleo::KeySelectionDialog::TrustedKeys &&
138 key.protocol() == GpgME::Context::OpenPGP &&
142 std::vector<GpgME::UserID> uids = key.userIDs();
143 for ( std::vector<GpgME::UserID>::const_iterator it = uids.begin() ; it != uids.end() ; ++it )
144 if ( !it->isRevoked() && it->validity() >= GpgME::UserID::Marginal )
146 kdDebug() <<
"key has no UIDs with validity >= Marginal" << endl;
155 static bool checkKeyUsage(
const std::vector<GpgME::Key> & keys,
unsigned int keyUsage ) {
156 for ( std::vector<GpgME::Key>::const_iterator it = keys.begin() ; it != keys.end() ; ++it )
157 if ( !checkKeyUsage( *it, keyUsage ) )
162 static inline TQString time_t2string( time_t t ) {
165 return dt.toString();
170 class ColumnStrategy :
public Kleo::KeyListView::ColumnStrategy {
172 ColumnStrategy(
unsigned int keyUsage );
174 TQString title(
int col )
const;
175 int width(
int col,
const TQFontMetrics & fm )
const;
177 TQString text(
const GpgME::Key & key,
int col )
const;
178 TQString toolTip(
const GpgME::Key & key,
int col )
const;
179 const TQPixmap * pixmap(
const GpgME::Key & key,
int col )
const;
182 const TQPixmap mKeyGoodPix, mKeyBadPix, mKeyUnknownPix, mKeyValidPix;
183 const unsigned int mKeyUsage;
186 ColumnStrategy::ColumnStrategy(
unsigned int keyUsage )
187 : Kleo::KeyListView::ColumnStrategy(),
188 mKeyGoodPix( UserIcon(
"key_ok" ) ),
189 mKeyBadPix( UserIcon(
"key_bad" ) ),
190 mKeyUnknownPix( UserIcon(
"key_unknown" ) ),
191 mKeyValidPix( UserIcon(
"key" ) ),
192 mKeyUsage( keyUsage )
194 kdWarning( keyUsage == 0, 5150 )
195 <<
"KeySelectionDialog: keyUsage == 0. You want to use AllKeys instead." << endl;
198 TQString ColumnStrategy::title(
int col )
const {
200 case 0:
return i18n(
"Key ID");
201 case 1:
return i18n(
"User ID");
202 default:
return TQString();
206 int ColumnStrategy::width(
int col,
const TQFontMetrics & fm )
const {
208 static const char hexchars[] =
"0123456789ABCDEF";
210 for (
unsigned int i = 0 ; i < 16 ; ++i )
211 maxWidth = kMax( fm.width( TQChar( hexchars[i] ) ), maxWidth );
212 return 8 * maxWidth + 2 * mKeyGoodPix.width();
214 return Kleo::KeyListView::ColumnStrategy::width( col, fm );
217 TQString ColumnStrategy::text(
const GpgME::Key & key,
int col )
const {
221 if ( key.shortKeyID() )
222 return TQString::fromUtf8( key.shortKeyID() );
224 return i18n(
"<unknown>");
229 const char * uid = key.userID(0).id();
230 if ( key.protocol() == GpgME::Context::OpenPGP )
231 return uid && *uid ? TQString::fromUtf8( uid ) : TQString() ;
236 default:
return TQString();
240 TQString ColumnStrategy::toolTip(
const GpgME::Key & key,
int )
const {
241 const char * uid = key.userID(0).id();
242 const char * fpr = key.primaryFingerprint();
243 const char * issuer = key.issuerName();
244 const GpgME::Subkey subkey = key.subkey(0);
245 const TQString expiry = subkey.neverExpires() ? i18n(
"never") : time_t2string( subkey.expirationTime() ) ;
246 const TQString creation = time_t2string( subkey.creationTime() );
247 if ( key.protocol() == GpgME::Context::OpenPGP )
248 return i18n(
"OpenPGP key for %1\n"
252 .arg( uid ? TQString::fromUtf8( uid ) : i18n(
"unknown"),
254 fpr ? TQString::fromLatin1( fpr ) : i18n(
"unknown") );
256 return i18n(
"S/MIME key for %1\n"
261 .arg( uid ?
Kleo::DN( uid ).prettyDN() : i18n(
"unknown"),
263 fpr ? TQString::fromLatin1( fpr ) : i18n(
"unknown") )
264 .arg( issuer ?
Kleo::DN( issuer ).prettyDN() : i18n(
"unknown") );
267 const TQPixmap * ColumnStrategy::pixmap(
const GpgME::Key & key,
int col )
const {
272 if ( !( key.keyListMode() & GpgME::Context::Validate ) ) {
273 return &mKeyUnknownPix;
276 if ( !checkKeyUsage( key, mKeyUsage ) ) {
280 if ( key.protocol() == GpgME::Context::CMS ) {
284 switch ( key.userID(0).validity() ) {
286 case GpgME::UserID::Unknown:
287 case GpgME::UserID::Undefined:
288 return &mKeyUnknownPix;
289 case GpgME::UserID::Never:
290 return &mKeyValidPix;
291 case GpgME::UserID::Marginal:
292 case GpgME::UserID::Full:
293 case GpgME::UserID::Ultimate:
301 static const int sCheckSelectionDelay = 250;
303 Kleo::KeySelectionDialog::KeySelectionDialog(
const TQString & title,
304 const TQString & text,
305 const std::vector<GpgME::Key> & selectedKeys,
306 unsigned int keyUsage,
307 bool extendedSelection,
309 TQWidget * parent,
const char * name,
311 : KDialogBase( parent, name, modal, title, Default|Ok|Cancel|Help, Ok ),
312 mOpenPGPBackend( 0 ),
315 mSelectedKeys( selectedKeys ),
316 mKeyUsage( keyUsage ),
317 mCurrentContextMenuItem( 0 )
319 init( rememberChoice, extendedSelection, text, TQString() );
322 Kleo::KeySelectionDialog::KeySelectionDialog(
const TQString & title,
323 const TQString & text,
324 const TQString & initialQuery,
325 const std::vector<GpgME::Key> & selectedKeys,
326 unsigned int keyUsage,
327 bool extendedSelection,
329 TQWidget * parent,
const char * name,
331 : KDialogBase( parent, name, modal, title, Default|Ok|Cancel|Help, Ok ),
332 mOpenPGPBackend( 0 ),
335 mSelectedKeys( selectedKeys ),
336 mKeyUsage( keyUsage ),
337 mSearchText( initialQuery ),
338 mInitialQuery( initialQuery ),
339 mCurrentContextMenuItem( 0 )
341 init( rememberChoice, extendedSelection, text, initialQuery );
344 Kleo::KeySelectionDialog::KeySelectionDialog(
const TQString & title,
345 const TQString & text,
346 const TQString & initialQuery,
347 unsigned int keyUsage,
348 bool extendedSelection,
350 TQWidget * parent,
const char * name,
352 : KDialogBase( parent, name, modal, title, Default|Ok|Cancel|Help, Ok ),
353 mOpenPGPBackend( 0 ),
356 mKeyUsage( keyUsage ),
357 mSearchText( initialQuery ),
358 mInitialQuery( initialQuery ),
359 mCurrentContextMenuItem( 0 )
361 init( rememberChoice, extendedSelection, text, initialQuery );
364 void Kleo::KeySelectionDialog::init(
bool rememberChoice,
bool extendedSelection,
365 const TQString & text,
const TQString & initialQuery ) {
366 if ( mKeyUsage & OpenPGPKeys )
367 mOpenPGPBackend = Kleo::CryptoBackendFactory::instance()->openpgp();
368 if ( mKeyUsage & SMIMEKeys )
369 mSMIMEBackend = Kleo::CryptoBackendFactory::instance()->smime();
371 mCheckSelectionTimer =
new TQTimer(
this );
372 mStartSearchTimer =
new TQTimer(
this );
374 TQFrame *page = makeMainWidget();
375 mTopLayout =
new TQVBoxLayout( page, 0, spacingHint() );
377 if ( !text.isEmpty() ) {
378 if ( text.startsWith(
"<qt>" ) ) {
379 KActiveLabel *textLabel =
new KActiveLabel( text, page );
380 disconnect( textLabel, TQ_SIGNAL(linkClicked(
const TQString&)), textLabel, TQ_SLOT(openLink(
const TQString&)) );
381 connect( textLabel, TQ_SIGNAL(linkClicked(
const TQString&)), TQ_SLOT(slotStartCertificateManager(
const TQString&)) );
382 textLabel->setAlignment( textLabel->alignment() | TQt::WordBreak );
383 mTopLayout->addWidget( textLabel );
385 KActiveLabel *textLabel =
new KActiveLabel( text, page );
386 textLabel->setAlignment( textLabel->alignment() | TQt::WordBreak );
387 mTopLayout->addWidget( textLabel );
391 TQPushButton *
const searchExternalPB
392 =
new TQPushButton( i18n(
"Search for &External Certificates"), page );
393 mTopLayout->addWidget( searchExternalPB, 0, TQt::AlignLeft );
394 connect( searchExternalPB, TQ_SIGNAL(clicked()),
this, TQ_SLOT(slotStartSearchForExternalCertificates()) );
395 if ( initialQuery.isEmpty() )
396 searchExternalPB->hide();
398 TQHBoxLayout * hlay =
new TQHBoxLayout( mTopLayout );
399 TQLineEdit * le =
new TQLineEdit( page );
400 le->setText( initialQuery );
401 TQToolButton *clearButton =
new TQToolButton( page );
402 clearButton->setIconSet( TDEGlobal::iconLoader()->loadIconSet(
403 TDEApplication::reverseLayout() ?
"clear_left":
"locationbar_erase", TDEIcon::Small, 0 ) );
404 hlay->addWidget( clearButton );
405 hlay->addWidget(
new TQLabel( le, i18n(
"&Search for:"), page ) );
406 hlay->addWidget( le, 1 );
409 connect( clearButton, TQ_SIGNAL( clicked() ), le, TQ_SLOT( clear() ) );
410 connect( le, TQ_SIGNAL(textChanged(
const TQString&)),
411 this, TQ_SLOT(slotSearch(
const TQString&)) );
412 connect( mStartSearchTimer, TQ_SIGNAL(timeout()), TQ_SLOT(slotFilter()) );
414 mKeyListView =
new KeyListView(
new ColumnStrategy( mKeyUsage ), 0, page,
"mKeyListView" );
415 mKeyListView->setResizeMode( TQListView::LastColumn );
416 mKeyListView->setRootIsDecorated(
true );
417 mKeyListView->setShowSortIndicator(
true );
418 mKeyListView->setSorting( 1,
true );
419 mKeyListView->setShowToolTips(
true );
420 if ( extendedSelection )
421 mKeyListView->setSelectionMode( TQListView::Extended );
422 mTopLayout->addWidget( mKeyListView, 10 );
424 if ( rememberChoice ) {
425 mRememberCB =
new TQCheckBox( i18n(
"&Remember choice"), page );
426 mTopLayout->addWidget( mRememberCB );
427 TQWhatsThis::add( mRememberCB,
428 i18n(
"<qt><p>If you check this box your choice will "
429 "be stored and you will not be asked again."
433 connect( mCheckSelectionTimer, TQ_SIGNAL(timeout()),
434 TQ_SLOT(slotCheckSelection()) );
437 connect( mKeyListView,
438 TQ_SIGNAL(doubleClicked(Kleo::KeyListViewItem*,
const TQPoint&,
int)),
439 TQ_SLOT(slotTryOk()) );
440 connect( mKeyListView,
441 TQ_SIGNAL(contextMenu(Kleo::KeyListViewItem*,
const TQPoint&)),
442 TQ_SLOT(slotRMB(Kleo::KeyListViewItem*,
const TQPoint&)) );
444 setButtonText( KDialogBase::Default, i18n(
"&Reread Keys") );
445 setButtonGuiItem( KDialogBase::Help, i18n(
"&Start Certificate Manager") );
446 connect(
this, TQ_SIGNAL(defaultClicked()),
this, TQ_SLOT(slotRereadKeys()) );
447 connect(
this, TQ_SIGNAL(helpClicked()),
this, TQ_SLOT(slotStartCertificateManager()) );
450 mTopLayout->activate();
453 KWin::setIcons( winId(), kapp->icon(), kapp->miniIcon() );
454 TQSize dialogSize( 500, 400 );
456 TDEConfigGroup dialogConfig( TDEGlobal::config(),
"Key Selection Dialog" );
457 dialogSize = dialogConfig.readSizeEntry(
"Dialog size", &dialogSize );
458 resize( dialogSize );
462 Kleo::KeySelectionDialog::~KeySelectionDialog() {
463 TDEConfigGroup dialogConfig( TDEGlobal::config(),
"Key Selection Dialog" );
464 dialogConfig.writeEntry(
"Dialog size", size() );
469 void Kleo::KeySelectionDialog::connectSignals() {
470 if ( mKeyListView->isMultiSelection() )
471 connect( mKeyListView, TQ_SIGNAL(selectionChanged()),
472 TQ_SLOT(slotSelectionChanged()) );
474 connect( mKeyListView, TQ_SIGNAL(selectionChanged(Kleo::KeyListViewItem*)),
475 TQ_SLOT(slotCheckSelection(Kleo::KeyListViewItem*)) );
478 void Kleo::KeySelectionDialog::disconnectSignals() {
479 if ( mKeyListView->isMultiSelection() )
480 disconnect( mKeyListView, TQ_SIGNAL(selectionChanged()),
481 this, TQ_SLOT(slotSelectionChanged()) );
483 disconnect( mKeyListView, TQ_SIGNAL(selectionChanged(Kleo::KeyListViewItem*)),
484 this, TQ_SLOT(slotCheckSelection(Kleo::KeyListViewItem*)) );
487 const GpgME::Key & Kleo::KeySelectionDialog::selectedKey()
const {
488 if ( mKeyListView->isMultiSelection() || !mKeyListView->selectedItem() )
489 return GpgME::Key::null;
490 return mKeyListView->selectedItem()->key();
493 TQString Kleo::KeySelectionDialog::fingerprint()
const {
494 return selectedKey().primaryFingerprint();
497 TQStringList Kleo::KeySelectionDialog::fingerprints()
const {
499 for ( std::vector<GpgME::Key>::const_iterator it = mSelectedKeys.begin() ; it != mSelectedKeys.end() ; ++it )
500 if (
const char * fpr = it->primaryFingerprint() )
501 result.push_back( fpr );
505 TQStringList Kleo::KeySelectionDialog::pgpKeyFingerprints()
const {
507 for ( std::vector<GpgME::Key>::const_iterator it = mSelectedKeys.begin() ; it != mSelectedKeys.end() ; ++it )
508 if ( it->protocol() == GpgME::Context::OpenPGP )
509 if (
const char * fpr = it->primaryFingerprint() )
510 result.push_back( fpr );
514 TQStringList Kleo::KeySelectionDialog::smimeFingerprints()
const {
516 for ( std::vector<GpgME::Key>::const_iterator it = mSelectedKeys.begin() ; it != mSelectedKeys.end() ; ++it )
517 if ( it->protocol() == GpgME::Context::CMS )
518 if (
const char * fpr = it->primaryFingerprint() )
519 result.push_back( fpr );
523 void Kleo::KeySelectionDialog::slotRereadKeys() {
524 mKeyListView->clear();
527 mSavedOffsetY = mKeyListView->contentsY();
530 mKeyListView->setEnabled(
false );
533 if ( mOpenPGPBackend )
534 startKeyListJobForBackend( mOpenPGPBackend, std::vector<GpgME::Key>(),
false );
536 startKeyListJobForBackend( mSMIMEBackend, std::vector<GpgME::Key>(),
false );
538 if ( mListJobCount == 0 ) {
539 mKeyListView->setEnabled(
true );
540 KMessageBox::information(
this,
541 i18n(
"No backends found for listing keys. "
542 "Check your installation."),
543 i18n(
"Key Listing Failed") );
548 void Kleo::KeySelectionDialog::slotHelp()
553 void Kleo::KeySelectionDialog::slotStartCertificateManager(
const TQString &query )
555 TDEProcess certManagerProc;
556 certManagerProc <<
"kleopatra";
557 if ( !query.isEmpty() )
558 certManagerProc <<
"--external" <<
"--query" << KURL::decode_string( query );
560 if( !certManagerProc.start( TDEProcess::DontCare ) )
561 KMessageBox::error(
this, i18n(
"Could not start certificate manager; "
562 "please check your installation." ),
563 i18n(
"Certificate Manager Error" ) );
565 kdDebug(5006) <<
"\nslotStartCertManager(): certificate manager started.\n" << endl;
568 #ifndef __KLEO_UI_SHOW_KEY_LIST_ERROR_H__
569 #define __KLEO_UI_SHOW_KEY_LIST_ERROR_H__
570 static void showKeyListError( TQWidget * parent,
const GpgME::Error & err ) {
572 const TQString msg = i18n(
"<qt><p>An error occurred while fetching "
573 "the keys from the backend:</p>"
574 "<p><b>%1</b></p></qt>" )
575 .arg( TQString::fromLocal8Bit( err.asString() ) );
577 KMessageBox::error( parent, msg, i18n(
"Key Listing Failed" ) );
582 struct ExtractFingerprint {
583 TQString operator()(
const GpgME::Key & key ) {
584 return key.primaryFingerprint();
589 void Kleo::KeySelectionDialog::startKeyListJobForBackend(
const CryptoBackend::Protocol * backend,
const std::vector<GpgME::Key> & keys,
bool validate ) {
591 KeyListJob * job = backend->keyListJob(
false,
false, validate );
596 connect( job, TQ_SIGNAL(result(
const GpgME::KeyListResult&)),
597 TQ_SLOT(slotKeyListResult(
const GpgME::KeyListResult&)) );
598 connect( job, TQ_SIGNAL(nextKey(
const GpgME::Key&)),
599 mKeyListView, validate ?
600 TQ_SLOT(slotRefreshKey(
const GpgME::Key&)) :
601 TQ_SLOT(slotAddKey(
const GpgME::Key&)) );
604 std::transform( keys.begin(), keys.end(), std::back_inserter( fprs ), ExtractFingerprint() );
605 const GpgME::Error err = job->start( fprs, mKeyUsage & SecretKeys && !( mKeyUsage & PublicKeys ) );
608 return showKeyListError(
this, err );
612 (void)
new ProgressDialog( job, validate ? i18n(
"Checking selected keys..." ) : i18n(
"Fetching keys..." ), this );
616 static void selectKeys( Kleo::KeyListView * klv,
const std::vector<GpgME::Key> & selectedKeys ) {
617 klv->clearSelection();
618 if ( selectedKeys.empty() )
620 for ( std::vector<GpgME::Key>::const_iterator it = selectedKeys.begin() ; it != selectedKeys.end() ; ++it )
621 if ( Kleo::KeyListViewItem * item = klv->itemByFingerprint( it->primaryFingerprint() ) )
622 item->setSelected(
true );
625 void Kleo::KeySelectionDialog::slotKeyListResult(
const GpgME::KeyListResult & res ) {
627 showKeyListError(
this, res.error() );
629 else if ( res.isTruncated() ) {
633 if ( --mListJobCount > 0 ) {
637 if ( mTruncated > 0 ) {
638 KMessageBox::information(
this,
639 i18n(
"<qt>One backend returned truncated output.<br>"
640 "Not all available keys are shown</qt>",
641 "<qt>%n backends returned truncated output.<br>"
642 "Not all available keys are shown</qt>",
644 i18n(
"Key List Result") );
647 mKeyListView->flushKeys();
649 mKeyListView->setEnabled(
true );
650 mListJobCount = mTruncated = 0;
651 mKeysToCheck.clear();
653 selectKeys( mKeyListView, mSelectedKeys );
659 slotSelectionChanged();
662 mKeyListView->setContentsPos( 0, mSavedOffsetY ); mSavedOffsetY = 0;
665 void Kleo::KeySelectionDialog::slotSelectionChanged() {
666 kdDebug(5150) <<
"KeySelectionDialog::slotSelectionChanged()" << endl;
671 mCheckSelectionTimer->start( sCheckSelectionDelay );
675 struct AlreadyChecked {
676 bool operator()(
const GpgME::Key & key )
const {
677 return key.keyListMode() & GpgME::Context::Validate ;
682 void Kleo::KeySelectionDialog::slotCheckSelection( KeyListViewItem * item ) {
683 kdDebug(5150) <<
"KeySelectionDialog::slotCheckSelection()\n";
685 mCheckSelectionTimer->stop();
687 mSelectedKeys.clear();
689 if ( !mKeyListView->isMultiSelection() ) {
691 mSelectedKeys.push_back( item->key() );
695 for ( KeyListViewItem * it = mKeyListView->firstChild() ; it ; it = it->nextSibling() ) {
696 if ( it->isSelected() ) {
697 mSelectedKeys.push_back( it->key() );
701 mKeysToCheck.clear();
702 std::remove_copy_if( mSelectedKeys.begin(), mSelectedKeys.end(),
703 std::back_inserter( mKeysToCheck ),
705 if ( mKeysToCheck.empty() ) {
706 enableButtonOK( !mSelectedKeys.empty() &&
707 checkKeyUsage( mSelectedKeys, mKeyUsage ) );
712 startValidatingKeyListing();
715 void Kleo::KeySelectionDialog::startValidatingKeyListing() {
716 if ( mKeysToCheck.empty() ) {
722 mSavedOffsetY = mKeyListView->contentsY();
725 mKeyListView->setEnabled(
false );
727 std::vector<GpgME::Key> smime, openpgp;
728 for ( std::vector<GpgME::Key>::const_iterator it = mKeysToCheck.begin() ; it != mKeysToCheck.end() ; ++it ) {
729 if ( it->protocol() == GpgME::Context::OpenPGP ) {
730 openpgp.push_back( *it );
733 smime.push_back( *it );
737 if ( !openpgp.empty() ) {
738 assert( mOpenPGPBackend );
739 startKeyListJobForBackend( mOpenPGPBackend, openpgp,
true );
741 if ( !smime.empty() ) {
742 assert( mSMIMEBackend );
743 startKeyListJobForBackend( mSMIMEBackend, smime,
true );
746 assert( mListJobCount > 0 );
749 bool Kleo::KeySelectionDialog::rememberSelection()
const {
750 return mRememberCB && mRememberCB->isChecked() ;
753 void Kleo::KeySelectionDialog::slotRMB( Kleo::KeyListViewItem * item,
const TQPoint & p ) {
756 mCurrentContextMenuItem = item;
759 menu.insertItem( i18n(
"Recheck Key" ),
this, TQ_SLOT(slotRecheckKey()) );
763 void Kleo::KeySelectionDialog::slotRecheckKey() {
764 if ( !mCurrentContextMenuItem || mCurrentContextMenuItem->key().isNull() )
767 mKeysToCheck.clear();
768 mKeysToCheck.push_back( mCurrentContextMenuItem->key() );
771 void Kleo::KeySelectionDialog::slotTryOk() {
772 if ( actionButton( Ok )->isEnabled() )
776 void Kleo::KeySelectionDialog::slotOk() {
777 if ( mCheckSelectionTimer->isActive() )
778 slotCheckSelection();
780 if ( !actionButton( Ok )->isEnabled() )
782 mStartSearchTimer->stop();
787 void Kleo::KeySelectionDialog::slotCancel() {
788 mCheckSelectionTimer->stop();
789 mStartSearchTimer->stop();
793 void Kleo::KeySelectionDialog::slotSearch(
const TQString & text ) {
794 mSearchText = text.stripWhiteSpace().upper();
798 void Kleo::KeySelectionDialog::slotSearch() {
799 mStartSearchTimer->start( sCheckSelectionDelay,
true );
802 void Kleo::KeySelectionDialog::slotFilter() {
803 if ( mSearchText.isEmpty() ) {
809 TQRegExp keyIdRegExp(
"(?:0x)?[A-F0-9]{1,8}",
false );
810 if ( keyIdRegExp.exactMatch( mSearchText ) ) {
811 if ( mSearchText.startsWith(
"0X" ) )
813 filterByKeyID( mSearchText.mid( 2 ) );
816 filterByKeyIDOrUID( mSearchText );
819 filterByUID( mSearchText );
823 void Kleo::KeySelectionDialog::filterByKeyID(
const TQString & keyID ) {
824 assert( keyID.length() <= 8 );
825 assert( !keyID.isEmpty() );
826 if ( keyID.isEmpty() )
829 for ( KeyListViewItem * item = mKeyListView->firstChild() ; item ; item = item->nextSibling() )
830 item->setVisible( item->text( 0 ).upper().startsWith( keyID ) );
833 static bool anyUIDMatches(
const Kleo::KeyListViewItem * item, TQRegExp & rx ) {
837 const std::vector<GpgME::UserID> uids = item->key().userIDs();
838 for ( std::vector<GpgME::UserID>::const_iterator it = uids.begin() ; it != uids.end() ; ++it )
839 if ( it->id() && rx.search( TQString::fromUtf8( it->id() ) ) >= 0 )
844 void Kleo::KeySelectionDialog::filterByKeyIDOrUID(
const TQString & str ) {
845 assert( !str.isEmpty() );
848 TQRegExp rx(
"\\b" + TQRegExp::escape( str ),
false );
850 for ( KeyListViewItem * item = mKeyListView->firstChild() ; item ; item = item->nextSibling() )
851 item->setVisible( item->text( 0 ).upper().startsWith( str ) || anyUIDMatches( item, rx ) );
855 void Kleo::KeySelectionDialog::filterByUID(
const TQString & str ) {
856 assert( !str.isEmpty() );
859 TQRegExp rx(
"\\b" + TQRegExp::escape( str ),
false );
861 for ( KeyListViewItem * item = mKeyListView->firstChild() ; item ; item = item->nextSibling() )
862 item->setVisible( anyUIDMatches( item, rx ) );
866 void Kleo::KeySelectionDialog::showAllItems() {
867 for ( KeyListViewItem * item = mKeyListView->firstChild() ; item ; item = item->nextSibling() )
868 item->setVisible(
true );
871 #include "keyselectiondialog.moc"
TQString prettyDN() const