21 #include <tqvgroupbox.h>
24 #include <tqwhatsthis.h>
25 #include <tqtooltip.h>
26 #include <tqapplication.h>
27 #include <tqtextcodec.h>
28 #include <tqdatetime.h>
32 #include <tqpopupmenu.h>
35 #include <tdelocale.h>
37 #include <kcharsets.h>
38 #include <kseparator.h>
39 #include <kiconloader.h>
40 #include <tdelistview.h>
41 #include <tdeconfigbase.h>
42 #include <tdeconfig.h>
43 #include <kprogress.h>
44 #include <tdeapplication.h>
46 #if KDE_IS_VERSION( 3, 1, 90 )
47 #include <tdeglobalsettings.h>
57 const int Kpgp::KeySelectionDialog::sCheckSelectionDelay = 250;
61 PassphraseDialog::PassphraseDialog( TQWidget *parent,
62 const TQString &caption,
bool modal,
63 const TQString &keyID )
64 :KDialogBase( parent, 0, modal, caption, Ok|Cancel )
66 TQHBox *hbox = makeHBoxMainWidget();
67 hbox->setSpacing( spacingHint() );
68 hbox->setMargin( marginHint() );
70 TQLabel *label =
new TQLabel(hbox);
71 label->setPixmap( BarIcon(
"pgp-keys") );
73 TQWidget *rightArea =
new TQWidget( hbox );
74 TQVBoxLayout *vlay =
new TQVBoxLayout( rightArea, 0, spacingHint() );
77 label =
new TQLabel(i18n(
"Please enter your OpenPGP passphrase:"),rightArea);
79 label =
new TQLabel(i18n(
"Please enter the OpenPGP passphrase for\n\"%1\":").arg(keyID),
81 lineedit =
new KPasswordEdit( rightArea );
82 lineedit->setEchoMode(TQLineEdit::Password);
83 lineedit->setMinimumWidth( fontMetrics().maxWidth()*20 );
85 connect( lineedit, TQ_SIGNAL(returnPressed()),
this, TQ_SLOT(slotOk()) );
87 vlay->addWidget( label );
88 vlay->addWidget( lineedit );
94 PassphraseDialog::~PassphraseDialog()
98 TQString PassphraseDialog::passphrase()
100 return lineedit->password();
107 Config::Config( TQWidget *parent,
const char *name,
bool encrypt )
108 : TQWidget( parent, name ), pgp( Module::getKpgp() )
115 TQVBoxLayout *topLayout =
new TQVBoxLayout(
this, 0, KDialog::spacingHint() );
117 group =
new TQVGroupBox( i18n(
"Warning"),
this );
118 group->layout()->setSpacing( KDialog::spacingHint() );
121 label =
new TQLabel( i18n(
"Please check if encryption really "
122 "works before you start using it seriously. Also note that attachments "
123 "are not encrypted by the PGP/GPG module."), group );
125 TQFont labelFont = label->font();
126 labelFont.setBold(
true );
127 label->setFont( labelFont );
129 label->setAlignment( AlignLeft|WordBreak );
132 topLayout->addWidget( group );
134 group =
new TQVGroupBox( i18n(
"Encryption Tool"),
this );
135 group->layout()->setSpacing( KDialog::spacingHint() );
137 TQHBox * hbox =
new TQHBox( group );
138 label =
new TQLabel( i18n(
"Select encryption tool to &use:"), hbox );
139 toolCombo =
new TQComboBox(
false, hbox );
140 toolCombo->insertStringList( TQStringList()
141 << i18n(
"Autodetect")
142 << i18n(
"GnuPG - Gnu Privacy Guard")
143 << i18n(
"PGP Version 2.x")
144 << i18n(
"PGP Version 5.x")
145 << i18n(
"PGP Version 6.x")
146 << i18n(
"Do not use any encryption tool") );
147 label->setBuddy( toolCombo );
148 hbox->setStretchFactor( toolCombo, 1 );
149 connect( toolCombo, TQ_SIGNAL( activated(
int ) ),
150 this, TQ_SIGNAL( changed(
void ) ) );
153 topLayout->addWidget( group );
155 mpOptionsGroupBox =
new TQVGroupBox( i18n(
"Options"),
this );
156 mpOptionsGroupBox->layout()->setSpacing( KDialog::spacingHint() );
157 storePass =
new TQCheckBox( i18n(
"&Keep passphrase in memory"),
159 connect( storePass, TQ_SIGNAL( toggled(
bool ) ),
160 this, TQ_SIGNAL( changed(
void ) ) );
161 msg = i18n(
"<qt><p>When this option is enabled, the passphrase of your "
162 "private key will be remembered by the application as long "
163 "as the application is running. Thus you will only have to "
164 "enter the passphrase once.</p><p>Be aware that this could be a "
165 "security risk. If you leave your computer, others "
166 "can use it to send signed messages and/or read your encrypted "
167 "messages. If a core dump occurs, the contents of your RAM will "
168 "be saved onto disk, including your passphrase.</p>"
169 "<p>Note that when using KMail, this setting only applies "
170 "if you are not using gpg-agent. It is also ignored "
171 "if you are using crypto plugins.</p></qt>" );
172 TQWhatsThis::add( storePass, msg );
174 encToSelf =
new TQCheckBox( i18n(
"Always encr&ypt to self"),
176 connect( encToSelf, TQ_SIGNAL( toggled(
bool ) ),
177 this, TQ_SIGNAL( changed(
void ) ) );
179 msg = i18n(
"<qt><p>When this option is enabled, the message/file "
180 "will not only be encrypted with the receiver's public key, "
181 "but also with your key. This will enable you to decrypt the "
182 "message/file at a later time. This is generally a good idea."
184 TQWhatsThis::add( encToSelf, msg );
188 showCipherText =
new TQCheckBox( i18n(
"&Show signed/encrypted text after "
191 connect( showCipherText, TQ_SIGNAL( toggled(
bool ) ),
192 this, TQ_SIGNAL( changed(
void ) ) );
194 msg = i18n(
"<qt><p>When this option is enabled, the signed/encrypted text "
195 "will be shown in a separate window, enabling you to know how "
196 "it will look before it is sent. This is a good idea when "
197 "you are verifying that your encryption system works.</p></qt>" );
198 TQWhatsThis::add( showCipherText, msg );
200 showKeyApprovalDlg =
new TQCheckBox( i18n(
"Always show the encryption "
201 "keys &for approval"),
203 connect( showKeyApprovalDlg, TQ_SIGNAL( toggled(
bool ) ),
204 this, TQ_SIGNAL( changed(
void ) ) );
205 msg = i18n(
"<qt><p>When this option is enabled, the application will "
206 "always show you a list of public keys from which you can "
207 "choose the one it will use for encryption. If it is off, "
208 "the application will only show the dialog if it cannot find "
209 "the right key or if there are several which could be used. "
211 TQWhatsThis::add( showKeyApprovalDlg, msg );
214 showKeyApprovalDlg = 0;
216 topLayout->addWidget( mpOptionsGroupBox );
218 topLayout->addStretch(1);
232 storePass->setChecked( pgp->storePassPhrase() );
234 encToSelf->setChecked( pgp->encryptToSelf() );
235 showCipherText->setChecked( pgp->showCipherText() );
236 if( 0 != showKeyApprovalDlg )
237 showKeyApprovalDlg->setChecked( pgp->showKeyApprovalDlg() );
240 switch (pgp->pgpType) {
243 case Module::tAuto: type = 0;
break;
244 case Module::tGPG: type = 1;
break;
245 case Module::tPGP2: type = 2;
break;
246 case Module::tPGP5: type = 3;
break;
247 case Module::tPGP6: type = 4;
break;
248 case Module::tOff: type = 5;
break;
250 toolCombo->setCurrentItem( type );
254 Config::applySettings()
256 pgp->setStorePassPhrase(storePass->isChecked());
258 pgp->setEncryptToSelf(encToSelf->isChecked());
259 pgp->setShowCipherText(showCipherText->isChecked());
260 if( 0 != showKeyApprovalDlg )
261 pgp->setShowKeyApprovalDlg( showKeyApprovalDlg->isChecked() );
263 Module::PGPType type;
264 switch ( toolCombo->currentItem() ) {
267 case 0: type = Module::tAuto;
break;
268 case 1: type = Module::tGPG;
break;
269 case 2: type = Module::tPGP2;
break;
270 case 3: type = Module::tPGP5;
break;
271 case 4: type = Module::tPGP6;
break;
272 case 5: type = Module::tOff;
break;
276 pgp->writeConfig(
true);
282 KeySelectionDialog::KeySelectionDialog(
const KeyList& keyList,
283 const TQString& title,
284 const TQString& text,
285 const KeyIDList& keyIds,
286 const bool rememberChoice,
287 const unsigned int allowedKeys,
288 const bool extendedSelection,
289 TQWidget *parent,
const char *name,
291 : KDialogBase( parent, name, modal, title, Default|Ok|Cancel, Ok ),
293 mAllowedKeys( allowedKeys ),
294 mCurrentContextMenuItem( 0 )
297 KWin::setIcons( winId(), kapp->icon(), kapp->miniIcon() );
298 Kpgp::Module *pgp = Kpgp::Module::getKpgp();
299 TDEConfig *config = pgp->getConfig();
300 TDEConfigGroup dialogConfig( config,
"Key Selection Dialog" );
302 TQSize defaultSize( 580, 400 );
303 TQSize dialogSize = dialogConfig.readSizeEntry(
"Dialog size", &defaultSize );
305 resize( dialogSize );
307 mCheckSelectionTimer =
new TQTimer(
this,
"mCheckSelectionTimer" );
308 mStartSearchTimer =
new TQTimer(
this,
"mStartSearchTimer" );
311 mKeyGoodPix =
new TQPixmap( UserIcon(
"key_ok") );
312 mKeyBadPix =
new TQPixmap( UserIcon(
"key_bad") );
313 mKeyUnknownPix =
new TQPixmap( UserIcon(
"key_unknown") );
314 mKeyValidPix =
new TQPixmap( UserIcon(
"key") );
316 TQFrame *page = makeMainWidget();
317 TQVBoxLayout *topLayout =
new TQVBoxLayout( page, 0, spacingHint() );
319 if( !text.isEmpty() ) {
320 TQLabel *label =
new TQLabel( page );
321 label->setText( text );
322 topLayout->addWidget( label );
325 TQHBoxLayout * hlay =
new TQHBoxLayout( topLayout );
326 TQLineEdit * le =
new TQLineEdit( page );
327 hlay->addWidget(
new TQLabel( le, i18n(
"&Search for:"), page ) );
328 hlay->addWidget( le, 1 );
331 connect( le, TQ_SIGNAL(textChanged(
const TQString&)),
332 this, TQ_SLOT(slotSearch(
const TQString&)) );
333 connect( mStartSearchTimer, TQ_SIGNAL(timeout()), TQ_SLOT(slotFilter()) );
335 mListView =
new TDEListView( page );
336 mListView->addColumn( i18n(
"Key ID") );
337 mListView->addColumn( i18n(
"User ID") );
338 mListView->setAllColumnsShowFocus(
true );
339 mListView->setResizeMode( TQListView::LastColumn );
340 mListView->setRootIsDecorated(
true );
341 mListView->setShowSortIndicator(
true );
342 mListView->setSorting( 1,
true );
343 mListView->setShowToolTips(
true );
344 if( extendedSelection ) {
345 mListView->setSelectionMode( TQListView::Extended );
348 topLayout->addWidget( mListView, 10 );
350 if (rememberChoice) {
351 mRememberCB =
new TQCheckBox( i18n(
"Remember choice"), page );
352 topLayout->addWidget( mRememberCB );
353 TQWhatsThis::add(mRememberCB,
354 i18n(
"<qt><p>If you check this box your choice will "
355 "be stored and you will not be asked again."
359 initKeylist( keyList, keyIds );
362 if( extendedSelection ) {
363 lvi = mListView->currentItem();
364 slotCheckSelection();
367 lvi = mListView->selectedItem();
368 slotCheckSelection( lvi );
373 mListView->center( mListView->contentsX(), mListView->itemPos( lvi ) );
375 if( extendedSelection ) {
376 connect( mCheckSelectionTimer, TQ_SIGNAL( timeout() ),
377 this, TQ_SLOT( slotCheckSelection() ) );
378 connect( mListView, TQ_SIGNAL( selectionChanged() ),
379 this, TQ_SLOT( slotSelectionChanged() ) );
382 connect( mListView, TQ_SIGNAL( selectionChanged( TQListViewItem* ) ),
383 this, TQ_SLOT( slotSelectionChanged( TQListViewItem* ) ) );
385 connect( mListView, TQ_SIGNAL( doubleClicked ( TQListViewItem *,
const TQPoint &,
int ) ),
this, TQ_SLOT( accept() ) );
387 connect( mListView, TQ_SIGNAL( contextMenuRequested( TQListViewItem*,
388 const TQPoint&,
int ) ),
389 this, TQ_SLOT( slotRMB( TQListViewItem*,
const TQPoint&,
int ) ) );
391 setButtonText( KDialogBase::Default, i18n(
"&Reread Keys") );
392 connect(
this, TQ_SIGNAL( defaultClicked() ),
393 this, TQ_SLOT( slotRereadKeys() ) );
397 KeySelectionDialog::~KeySelectionDialog()
399 Kpgp::Module *pgp = Kpgp::Module::getKpgp();
400 TDEConfig *config = pgp->getConfig();
401 TDEConfigGroup dialogConfig( config,
"Key Selection Dialog" );
402 dialogConfig.writeEntry(
"Dialog size", size() );
406 delete mKeyUnknownPix;
411 KeyID KeySelectionDialog::key()
const
413 if( mListView->isMultiSelection() || mKeyIds.isEmpty() )
416 return mKeyIds.first();
420 void KeySelectionDialog::initKeylist(
const KeyList& keyList,
421 const KeyIDList& keyIds )
423 TQListViewItem* firstSelectedItem = 0;
428 for( KeyListIterator it( keyList ); it.current(); ++it ) {
429 KeyID curKeyId = (*it)->primaryKeyID();
431 TQListViewItem* primaryUserID =
new TQListViewItem( mListView, curKeyId,
432 (*it)->primaryUserID() );
435 if( keyIds.findIndex( curKeyId ) != -1 ) {
436 if( 0 == firstSelectedItem ) {
437 firstSelectedItem = primaryUserID;
439 mListView->setSelected( primaryUserID,
true );
440 mKeyIds.append( curKeyId );
442 primaryUserID->setOpen(
false );
445 switch( keyValidity( *it ) ) {
447 primaryUserID->setPixmap( 0, *mKeyUnknownPix );
450 primaryUserID->setPixmap( 0, *mKeyValidPix );
453 primaryUserID->setPixmap( 0, *mKeyGoodPix );
456 primaryUserID->setPixmap( 0, *mKeyBadPix );
460 TQListViewItem* childItem;
462 childItem =
new TQListViewItem( primaryUserID,
"",
463 i18n(
"Fingerprint: %1" )
464 .arg( beautifyFingerprint( (*it)->primaryFingerprint() ) ) );
465 if( primaryUserID->isSelected() && mListView->isMultiSelection() ) {
466 mListView->setSelected( childItem,
true );
469 childItem =
new TQListViewItem( primaryUserID,
"", keyInfo( *it ) );
470 if( primaryUserID->isSelected() && mListView->isMultiSelection() ) {
471 mListView->setSelected( childItem,
true );
474 UserIDList userIDs = (*it)->userIDs();
475 UserIDListIterator uidit( userIDs );
478 for( ; *uidit; ++uidit ) {
479 childItem =
new TQListViewItem( primaryUserID,
"", (*uidit)->text() );
480 if( primaryUserID->isSelected() && mListView->isMultiSelection() ) {
481 mListView->setSelected( childItem,
true );
487 if( 0 != firstSelectedItem ) {
488 mListView->setCurrentItem( firstSelectedItem );
493 TQString KeySelectionDialog::keyInfo(
const Kpgp::Key *key )
const
495 TQString status, remark;
497 status = i18n(
"Revoked");
500 status = i18n(
"Expired");
503 status = i18n(
"Disabled");
506 status = i18n(
"Invalid");
509 Validity keyTrust = key->
keyTrust();
511 case KPGP_VALIDITY_UNDEFINED:
512 status = i18n(
"Undefined trust");
514 case KPGP_VALIDITY_NEVER:
515 status = i18n(
"Untrusted");
517 case KPGP_VALIDITY_MARGINAL:
518 status = i18n(
"Marginally trusted");
520 case KPGP_VALIDITY_FULL:
521 status = i18n(
"Fully trusted");
523 case KPGP_VALIDITY_ULTIMATE:
524 status = i18n(
"Ultimately trusted");
526 case KPGP_VALIDITY_UNKNOWN:
528 status = i18n(
"Unknown");
531 remark = i18n(
"Secret key available");
534 remark = i18n(
"Sign only key");
537 remark = i18n(
"Encryption only key");
543 if( remark.isEmpty() ) {
544 return " " + i18n(
"creation date and status of an OpenPGP key",
545 "Creation date: %1, Status: %2")
546 .arg( TDEGlobal::locale()->formatDate( dt.date(),
true ) )
550 return " " + i18n(
"creation date, status and remark of an OpenPGP key",
551 "Creation date: %1, Status: %2 (%3)")
552 .arg( TDEGlobal::locale()->formatDate( dt.date(),
true ) )
558 TQString KeySelectionDialog::beautifyFingerprint(
const TQCString& fpr )
const
562 if( 40 == fpr.length() ) {
565 result.fill(
' ', 50 );
566 memcpy( result.data() , fpr.data() , 4 );
567 memcpy( result.data() + 5, fpr.data() + 4, 4 );
568 memcpy( result.data() + 10, fpr.data() + 8, 4 );
569 memcpy( result.data() + 15, fpr.data() + 12, 4 );
570 memcpy( result.data() + 20, fpr.data() + 16, 4 );
571 memcpy( result.data() + 26, fpr.data() + 20, 4 );
572 memcpy( result.data() + 31, fpr.data() + 24, 4 );
573 memcpy( result.data() + 36, fpr.data() + 28, 4 );
574 memcpy( result.data() + 41, fpr.data() + 32, 4 );
575 memcpy( result.data() + 46, fpr.data() + 36, 4 );
577 else if( 32 == fpr.length() ) {
580 result.fill(
' ', 48 );
581 memcpy( result.data() , fpr.data() , 2 );
582 memcpy( result.data() + 3, fpr.data() + 2, 2 );
583 memcpy( result.data() + 6, fpr.data() + 4, 2 );
584 memcpy( result.data() + 9, fpr.data() + 6, 2 );
585 memcpy( result.data() + 12, fpr.data() + 8, 2 );
586 memcpy( result.data() + 15, fpr.data() + 10, 2 );
587 memcpy( result.data() + 18, fpr.data() + 12, 2 );
588 memcpy( result.data() + 21, fpr.data() + 14, 2 );
589 memcpy( result.data() + 25, fpr.data() + 16, 2 );
590 memcpy( result.data() + 28, fpr.data() + 18, 2 );
591 memcpy( result.data() + 31, fpr.data() + 20, 2 );
592 memcpy( result.data() + 34, fpr.data() + 22, 2 );
593 memcpy( result.data() + 37, fpr.data() + 24, 2 );
594 memcpy( result.data() + 40, fpr.data() + 26, 2 );
595 memcpy( result.data() + 43, fpr.data() + 28, 2 );
596 memcpy( result.data() + 46, fpr.data() + 30, 2 );
605 int KeySelectionDialog::keyValidity(
const Kpgp::Key *key )
const
611 if( ( mAllowedKeys & EncrSignKeys ) == EncryptionKeys ) {
621 else if( ( mAllowedKeys & EncrSignKeys ) == SigningKeys ) {
631 else if( ( mAllowedKeys & ValidKeys ) && !key->
isValid() ) {
638 Validity keyTrust = key->
keyTrust();
640 case KPGP_VALIDITY_NEVER:
643 case KPGP_VALIDITY_MARGINAL:
644 case KPGP_VALIDITY_FULL:
645 case KPGP_VALIDITY_ULTIMATE:
648 case KPGP_VALIDITY_UNDEFINED:
649 if( mAllowedKeys & TrustedKeys ) {
657 case KPGP_VALIDITY_UNKNOWN:
666 void KeySelectionDialog::updateKeyInfo(
const Kpgp::Key* key,
667 TQListViewItem* lvi )
const
673 if( lvi->parent() != 0 ) {
679 while( lvi->firstChild() ) {
680 kdDebug(5100) <<
"Deleting '" << lvi->firstChild()->text( 1 ) <<
"'\n";
681 delete lvi->firstChild();
683 kdDebug(5100) <<
"Deleting key 0x" << lvi->text( 0 ) <<
" ("
684 << lvi->text( 1 ) <<
")\n";
691 switch( keyValidity( key ) ) {
693 lvi->setPixmap( 0, *mKeyUnknownPix );
696 lvi->setPixmap( 0, *mKeyValidPix );
699 lvi->setPixmap( 0, *mKeyGoodPix );
702 lvi->setPixmap( 0, *mKeyBadPix );
709 for( lvi = lvi->firstChild(); lvi; lvi = lvi->nextSibling() ) {
710 if( lvi->text( 1 ).at(0) ==
' ' ) {
711 lvi->setText( 1, keyInfo( key ) );
719 KeySelectionDialog::keyAdmissibility( TQListViewItem* lvi,
720 TrustCheckMode trustCheckMode )
const
728 if( mAllowedKeys == AllKeys ) {
732 Kpgp::Module *pgp = Kpgp::Module::getKpgp();
738 KeyID keyId = getKeyId( lvi );
739 Kpgp::Key* key = pgp->publicKey( keyId );
746 if( trustCheckMode == ForceTrustCheck ) {
747 key = pgp->rereadKey( keyId,
true );
748 updateKeyInfo( key, lvi );
749 val = keyValidity( key );
752 val = keyValidity( key );
753 if( ( trustCheckMode == AllowExpensiveTrustCheck ) && ( 0 == val ) ) {
754 key = pgp->rereadKey( keyId,
true );
755 updateKeyInfo( key, lvi );
756 val = keyValidity( key );
768 if( mAllowedKeys & TrustedKeys ) {
778 kdDebug( 5100 ) <<
"Error: Invalid key status value.\n";
786 KeySelectionDialog::getKeyId(
const TQListViewItem* lvi )
const
791 if( 0 != lvi->parent() ) {
792 keyId = lvi->parent()->text(0).local8Bit();
795 keyId = lvi->text(0).local8Bit();
803 void KeySelectionDialog::slotRereadKeys()
805 Kpgp::Module *pgp = Kpgp::Module::getKpgp();
813 if( PublicKeys & mAllowedKeys ) {
814 pgp->readPublicKeys(
true );
815 keys = pgp->publicKeys();
818 pgp->readSecretKeys(
true );
819 keys = pgp->secretKeys();
823 int offsetY = mListView->contentsY();
825 if( mListView->isMultiSelection() ) {
826 disconnect( mListView, TQ_SIGNAL( selectionChanged() ),
827 this, TQ_SLOT( slotSelectionChanged() ) );
830 disconnect( mListView, TQ_SIGNAL( selectionChanged( TQListViewItem * ) ),
831 this, TQ_SLOT( slotSelectionChanged( TQListViewItem * ) ) );
834 initKeylist( keys, KeyIDList( mKeyIds ) );
837 if( mListView->isMultiSelection() ) {
838 connect( mListView, TQ_SIGNAL( selectionChanged() ),
839 this, TQ_SLOT( slotSelectionChanged() ) );
840 slotSelectionChanged();
843 connect( mListView, TQ_SIGNAL( selectionChanged( TQListViewItem * ) ),
844 this, TQ_SLOT( slotSelectionChanged( TQListViewItem * ) ) );
848 mListView->setContentsPos( 0, offsetY );
852 void KeySelectionDialog::slotSelectionChanged( TQListViewItem * lvi )
854 slotCheckSelection( lvi );
858 void KeySelectionDialog::slotSelectionChanged()
860 kdDebug(5100) <<
"KeySelectionDialog::slotSelectionChanged()\n";
865 mCheckSelectionTimer->start( sCheckSelectionDelay );
869 void KeySelectionDialog::slotCheckSelection( TQListViewItem* plvi )
871 kdDebug(5100) <<
"KeySelectionDialog::slotCheckSelection()\n";
873 if( !mListView->isMultiSelection() ) {
875 KeyID keyId = getKeyId( plvi );
876 if( !keyId.isEmpty() ) {
877 mKeyIds.append( keyId );
878 enableButtonOK( 1 == keyAdmissibility( plvi, AllowExpensiveTrustCheck ) );
881 enableButtonOK(
false );
885 mCheckSelectionTimer->stop();
889 disconnect( mListView, TQ_SIGNAL( selectionChanged() ),
890 this, TQ_SLOT( slotSelectionChanged() ) );
892 KeyIDList newKeyIdList;
893 TQValueList<TQListViewItem*> keysToBeChecked;
895 bool keysAllowed =
true;
896 enum { UNKNOWN, SELECTED, DESELECTED } userAction = UNKNOWN;
898 for( TQListViewItem *lvi = mListView->firstChild();
900 lvi = lvi->nextSibling() ) {
907 int itemCount = 1 + lvi->childCount();
908 int selectedCount = lvi->isSelected() ? 1 : 0;
909 for( TQListViewItem *clvi = lvi->firstChild();
911 clvi = clvi->nextSibling() ) {
912 if( clvi->isSelected() ) {
917 if( userAction == UNKNOWN ) {
922 if( 0 < selectedCount ) {
923 if( -1 == mKeyIds.findIndex( lvi->text(0).local8Bit() ) ) {
926 kdDebug(5100) <<
"selectedCount: "<<selectedCount<<
"/"<<itemCount
927 <<
" --- User selected key "<<lvi->text(0)<<endl;
928 userAction = SELECTED;
930 else if( ( itemCount > selectedCount ) &&
931 ( -1 != mKeyIds.findIndex( lvi->text(0).local8Bit() ) ) ) {
934 kdDebug(5100) <<
"selectedCount: "<<selectedCount<<
"/"<<itemCount
935 <<
" --- User deselected key "<<lvi->text(0)<<endl;
936 userAction = DESELECTED;
940 if( itemCount == selectedCount ) {
942 KeyID keyId = lvi->text(0).local8Bit();
943 newKeyIdList.append( keyId );
944 int admissibility = keyAdmissibility( lvi, NoExpensiveTrustCheck );
945 if( -1 == admissibility ) {
948 else if ( 0 == admissibility ) {
949 keysToBeChecked.append( lvi );
952 else if( 0 < selectedCount ) {
955 if( userAction == SELECTED ) {
957 mListView->setSelected( lvi,
true );
958 for( TQListViewItem *clvi = lvi->firstChild();
960 clvi = clvi->nextSibling() ) {
961 mListView->setSelected( clvi,
true );
964 KeyID keyId = lvi->text(0).local8Bit();
965 newKeyIdList.append( keyId );
966 int admissibility = keyAdmissibility( lvi, NoExpensiveTrustCheck );
967 if( -1 == admissibility ) {
970 else if ( 0 == admissibility ) {
971 keysToBeChecked.append( lvi );
976 mListView->setSelected( lvi,
false );
977 for( TQListViewItem *clvi = lvi->firstChild();
979 clvi = clvi->nextSibling() ) {
980 mListView->setSelected( clvi,
false );
985 kdDebug(5100) <<
"Selected keys: " << newKeyIdList.toStringList().join(
", ") << endl;
986 mKeyIds = newKeyIdList;
987 if( !keysToBeChecked.isEmpty() ) {
988 keysAllowed = keysAllowed && checkKeys( keysToBeChecked );
990 enableButtonOK( keysAllowed );
992 connect( mListView, TQ_SIGNAL( selectionChanged() ),
993 this, TQ_SLOT( slotSelectionChanged() ) );
998 bool KeySelectionDialog::checkKeys(
const TQValueList<TQListViewItem*>& keys )
const
1000 KProgressDialog* pProgressDlg = 0;
1001 bool keysAllowed =
true;
1002 kdDebug(5100) <<
"Checking keys...\n";
1004 pProgressDlg =
new KProgressDialog( 0, 0, i18n(
"Checking Keys"),
1005 i18n(
"Checking key 0xMMMMMMMM..."),
1007 pProgressDlg->setAllowCancel(
false );
1008 pProgressDlg->progressBar()->setTotalSteps( keys.count() );
1009 pProgressDlg->setMinimumDuration( 1000 );
1010 pProgressDlg->show();
1012 for( TQValueList<TQListViewItem*>::ConstIterator it = keys.begin();
1015 kdDebug(5100) <<
"Checking key 0x" << getKeyId( *it ) <<
"...\n";
1016 pProgressDlg->setLabel( i18n(
"Checking key 0x%1...")
1017 .arg( TQString( getKeyId( *it ) ) ) );
1018 kapp->processEvents();
1019 keysAllowed = keysAllowed && ( -1 != keyAdmissibility( *it, AllowExpensiveTrustCheck ) );
1020 pProgressDlg->progressBar()->advance( 1 );
1021 kapp->processEvents();
1024 delete pProgressDlg;
1031 void KeySelectionDialog::slotRMB( TQListViewItem* lvi,
const TQPoint& pos,
int )
1037 mCurrentContextMenuItem = lvi;
1039 TQPopupMenu menu(
this);
1040 menu.insertItem( i18n(
"Recheck Key" ),
this, TQ_SLOT( slotRecheckKey() ) );
1045 void KeySelectionDialog::slotRecheckKey()
1047 if( 0 != mCurrentContextMenuItem ) {
1049 keyAdmissibility( mCurrentContextMenuItem, ForceTrustCheck );
1051 slotCheckSelection( mCurrentContextMenuItem );
1055 void KeySelectionDialog::slotOk()
1057 if( mCheckSelectionTimer->isActive() ) {
1058 slotCheckSelection();
1060 mStartSearchTimer->stop();
1065 void KeySelectionDialog::slotCancel()
1067 mCheckSelectionTimer->stop();
1068 mStartSearchTimer->stop();
1073 void KeySelectionDialog::slotSearch(
const TQString & text )
1075 mSearchText = text.stripWhiteSpace().upper();
1076 mStartSearchTimer->start( sCheckSelectionDelay,
true );
1079 void KeySelectionDialog::slotFilter()
1081 if ( mSearchText.isEmpty() ) {
1087 TQRegExp keyIdRegExp(
"(?:0x)?[A-F0-9]{1,8}",
false );
1088 if ( keyIdRegExp.exactMatch( mSearchText ) ) {
1089 if ( mSearchText.startsWith(
"0X" ) )
1091 filterByKeyID( mSearchText.mid( 2 ) );
1094 filterByKeyIDOrUID( mSearchText );
1097 filterByUID( mSearchText );
1101 void KeySelectionDialog::filterByKeyID(
const TQString & keyID )
1103 assert( keyID.length() <= 8 );
1104 assert( !keyID.isEmpty() );
1105 if ( keyID.isEmpty() )
1108 for ( TQListViewItem * item = mListView->firstChild() ; item ; item = item->nextSibling() )
1109 item->setVisible( item->text( 0 ).upper().startsWith( keyID ) );
1112 void KeySelectionDialog::filterByKeyIDOrUID(
const TQString & str )
1114 assert( !str.isEmpty() );
1117 TQRegExp rx(
"\\b" + TQRegExp::escape( str ),
false );
1119 for ( TQListViewItem * item = mListView->firstChild() ; item ; item = item->nextSibling() )
1120 item->setVisible( item->text( 0 ).upper().startsWith( str )
1121 || rx.search( item->text( 1 ) ) >= 0
1122 || anyChildMatches( item, rx ) );
1126 void KeySelectionDialog::filterByUID(
const TQString & str )
1128 assert( !str.isEmpty() );
1131 TQRegExp rx(
"\\b" + TQRegExp::escape( str ),
false );
1133 for ( TQListViewItem * item = mListView->firstChild() ; item ; item = item->nextSibling() )
1134 item->setVisible( rx.search( item->text( 1 ) ) >= 0
1135 || anyChildMatches( item, rx ) );
1139 bool KeySelectionDialog::anyChildMatches(
const TQListViewItem * item, TQRegExp & rx )
const
1144 TQListViewItem * stop = item->nextSibling();
1146 for ( TQListViewItemIterator it( item->firstChild() ) ; it.current() && it.current() != stop ; ++it )
1147 if ( rx.search( it.current()->text( 1 ) ) >= 0 ) {
1154 void KeySelectionDialog::showAllItems()
1156 for ( TQListViewItem * item = mListView->firstChild() ; item ; item = item->nextSibling() )
1157 item->setVisible(
true );
1161 KeyRequester::KeyRequester( TQWidget * parent,
bool multipleKeys,
1162 unsigned int allowedKeys,
const char * name )
1163 : TQWidget( parent, name ),
1164 mDialogCaption( i18n(
"OpenPGP Key Selection") ),
1165 mDialogMessage( i18n(
"Please select an OpenPGP key to use.") ),
1166 mMulti( multipleKeys ),
1167 mAllowedKeys( allowedKeys ),
1170 TQHBoxLayout * hlay =
new TQHBoxLayout(
this, 0, KDialog::spacingHint() );
1173 mLabel =
new TQLabel(
this );
1174 mLabel->setFrameStyle( TQFrame::Panel | TQFrame::Sunken );
1177 mEraseButton =
new TQPushButton(
this );
1178 mEraseButton->setAutoDefault(
false );
1179 mEraseButton->setSizePolicy( TQSizePolicy( TQSizePolicy::Minimum,
1180 TQSizePolicy::Minimum ) );
1181 mEraseButton->setPixmap( SmallIcon(
"clear_left" ) );
1182 TQToolTip::add( mEraseButton, i18n(
"Clear") );
1185 mDialogButton =
new TQPushButton( i18n(
"Change..."),
this );
1186 mDialogButton->setAutoDefault(
false );
1188 hlay->addWidget( mLabel, 1 );
1189 hlay->addWidget( mEraseButton );
1190 hlay->addWidget( mDialogButton );
1192 connect( mEraseButton, TQ_SIGNAL(clicked()), TQ_SLOT(slotEraseButtonClicked()) );
1193 connect( mDialogButton, TQ_SIGNAL(clicked()), TQ_SLOT(slotDialogButtonClicked()) );
1195 setSizePolicy( TQSizePolicy( TQSizePolicy::MinimumExpanding,
1196 TQSizePolicy::Fixed ) );
1199 KeyRequester::~KeyRequester() {
1203 KeyIDList KeyRequester::keyIDs()
const {
1207 void KeyRequester::setKeyIDs(
const KeyIDList & keyIDs ) {
1209 if ( mKeys.empty() ) {
1213 if ( mKeys.size() > 1 )
1214 setMultipleKeysEnabled(
true );
1216 TQString s = mKeys.toStringList().join(
", ");
1218 mLabel->setText( s );
1219 TQToolTip::remove( mLabel );
1220 TQToolTip::add( mLabel, s );
1223 void KeyRequester::slotDialogButtonClicked() {
1224 Module * pgp = Module::getKpgp();
1227 kdWarning() <<
"Kpgp::KeyRequester::slotDialogButtonClicked(): No pgp module found!" << endl;
1231 setKeyIDs( keyRequestHook( pgp ) );
1235 void KeyRequester::slotEraseButtonClicked() {
1241 void KeyRequester::setDialogCaption(
const TQString & caption ) {
1242 mDialogCaption = caption;
1245 void KeyRequester::setDialogMessage(
const TQString & msg ) {
1246 mDialogMessage = msg;
1249 bool KeyRequester::isMultipleKeysEnabled()
const {
1253 void KeyRequester::setMultipleKeysEnabled(
bool multi ) {
1254 if ( multi == mMulti )
return;
1256 if ( !multi && mKeys.size() > 1 )
1257 mKeys.erase( ++mKeys.begin(), mKeys.end() );
1262 int KeyRequester::allowedKeys()
const {
1263 return mAllowedKeys;
1266 void KeyRequester::setAllowedKeys(
int allowedKeys ) {
1267 mAllowedKeys = allowedKeys;
1271 PublicKeyRequester::PublicKeyRequester( TQWidget * parent,
bool multi,
1272 unsigned int allowed,
const char * name )
1273 : KeyRequester( parent, multi, allowed & ~SecretKeys, name )
1278 PublicKeyRequester::~PublicKeyRequester() {
1282 KeyIDList PublicKeyRequester::keyRequestHook( Module * pgp )
const {
1284 return pgp->selectPublicKeys( mDialogCaption, mDialogMessage, mKeys, TQString(), mAllowedKeys );
1287 SecretKeyRequester::SecretKeyRequester( TQWidget * parent,
bool multi,
1288 unsigned int allowed,
const char * name )
1289 : KeyRequester( parent, multi, allowed & ~PublicKeys, name )
1294 SecretKeyRequester::~SecretKeyRequester() {
1298 KeyIDList SecretKeyRequester::keyRequestHook( Module * pgp )
const {
1301 KeyID keyID = mKeys.first();
1302 keyID = pgp->selectSecretKey( mDialogCaption, mDialogMessage, keyID );
1304 return KeyIDList() << keyID;
1310 KeyApprovalDialog::KeyApprovalDialog(
const TQStringList& addresses,
1311 const TQValueVector<KeyIDList>& keyIDs,
1312 const int allowedKeys,
1313 TQWidget *parent,
const char *name,
1315 : KDialogBase( parent, name, modal, i18n(
"Encryption Key Approval"),
1318 mAllowedKeys( allowedKeys ),
1319 mPrefsChanged( false )
1321 Kpgp::Module *pgp = Kpgp::Module::getKpgp();
1331 TQFrame *page = makeMainWidget();
1332 TQVBoxLayout *topLayout =
new TQVBoxLayout( page, 0, KDialog::spacingHint() );
1334 TQLabel *label =
new TQLabel( i18n(
"The following keys will be used for "
1337 topLayout->addWidget( label );
1339 TQScrollView* sv =
new TQScrollView( page );
1340 sv->setResizePolicy( TQScrollView::AutoOneFit );
1341 topLayout->addWidget( sv );
1342 TQVBox* bigvbox =
new TQVBox( sv->viewport() );
1343 bigvbox->setMargin( KDialog::marginHint() );
1344 bigvbox->setSpacing( KDialog::spacingHint() );
1345 sv->addChild( bigvbox );
1347 TQButtonGroup *mChangeButtonGroup =
new TQButtonGroup( bigvbox );
1348 mChangeButtonGroup->hide();
1349 mAddressLabels.resize( addresses.count() );
1350 mKeyIdsLabels.resize( keyIDs.size() );
1352 mEncrPrefCombos.resize( addresses.count() );
1355 if( pgp->encryptToSelf() ) {
1357 TQHBox* hbox =
new TQHBox( bigvbox );
1358 new TQLabel( i18n(
"Your keys:"), hbox );
1359 TQLabel* keyidsL =
new TQLabel( hbox );
1360 if( keyIDs[0].isEmpty() ) {
1361 keyidsL->setText( i18n(
"<none> means 'no key'",
"<none>") );
1364 keyidsL->setText(
"0x" + keyIDs[0].toStringList().join(
"\n0x" ) );
1366 keyidsL->setFrameStyle( TQFrame::Panel | TQFrame::Sunken );
1378 TQPushButton *button =
new TQPushButton( i18n(
"Change..."), hbox );
1379 mChangeButtonGroup->insert( button );
1380 button->setAutoDefault(
false );
1381 hbox->setStretchFactor( keyidsL, 10 );
1382 mKeyIdsLabels.insert( 0, keyidsL );
1386 new KSeparator( TQt::Horizontal, bigvbox );
1391 mKeyIdsLabels.insert( 0, 0 );
1395 TQStringList::ConstIterator ait;
1396 TQValueVector<KeyIDList>::const_iterator kit;
1398 for( ait = addresses.begin(), kit = keyIDs.begin(), i = 0;
1399 ( ait != addresses.end() ) && ( kit != keyIDs.end() );
1400 ++ait, ++kit, ++i ) {
1405 new KSeparator( TQt::Horizontal, bigvbox );
1408 TQHBox *hbox =
new TQHBox( bigvbox );
1409 new TQLabel( i18n(
"Recipient:"), hbox );
1410 TQLabel *addressL =
new TQLabel( *ait, hbox );
1411 hbox->setStretchFactor( addressL, 10 );
1412 mAddressLabels.insert( i, addressL );
1414 hbox =
new TQHBox( bigvbox );
1415 new TQLabel( i18n(
"Encryption keys:"), hbox );
1416 TQLabel* keyidsL =
new TQLabel( hbox );
1417 if( (*kit).isEmpty() ) {
1418 keyidsL->setText( i18n(
"<none> means 'no key'",
"<none>") );
1421 keyidsL->setText(
"0x" + (*kit).toStringList().join(
"\n0x" ) );
1423 keyidsL->setFrameStyle( TQFrame::Panel | TQFrame::Sunken );
1435 TQPushButton *button =
new TQPushButton( i18n(
"Change..."), hbox );
1436 mChangeButtonGroup->insert( button );
1437 button->setAutoDefault(
false );
1438 hbox->setStretchFactor( keyidsL, 10 );
1439 mKeyIdsLabels.insert( i + 1, keyidsL );
1443 hbox =
new TQHBox( bigvbox );
1444 new TQLabel( i18n(
"Encryption preference:"), hbox );
1445 TQComboBox *encrPrefCombo =
new TQComboBox( hbox );
1446 encrPrefCombo->insertItem( i18n(
"<none>") );
1447 encrPrefCombo->insertItem( i18n(
"Never Encrypt with This Key") );
1448 encrPrefCombo->insertItem( i18n(
"Always Encrypt with This Key") );
1449 encrPrefCombo->insertItem( i18n(
"Encrypt Whenever Encryption is Possible") );
1450 encrPrefCombo->insertItem( i18n(
"Always Ask") );
1451 encrPrefCombo->insertItem( i18n(
"Ask Whenever Encryption is Possible") );
1453 EncryptPref encrPref = pgp->encryptionPreference( *ait );
1454 switch( encrPref ) {
1456 encrPrefCombo->setCurrentItem( 1 );
1459 encrPrefCombo->setCurrentItem( 2 );
1461 case AlwaysEncryptIfPossible:
1462 encrPrefCombo->setCurrentItem( 3 );
1464 case AlwaysAskForEncryption:
1465 encrPrefCombo->setCurrentItem( 4 );
1467 case AskWheneverPossible:
1468 encrPrefCombo->setCurrentItem( 5 );
1471 encrPrefCombo->setCurrentItem( 0 );
1473 connect( encrPrefCombo, TQ_SIGNAL(activated(
int)),
1474 this, TQ_SLOT(slotPrefsChanged(
int)) );
1475 mEncrPrefCombos.insert( i, encrPrefCombo );
1477 connect( mChangeButtonGroup, TQ_SIGNAL(clicked(
int)),
1478 this, TQ_SLOT(slotChangeEncryptionKey(
int)) );
1481 int dialogWidth = marginHint()
1483 + bigvbox->sizeHint().width()
1484 + sv->verticalScrollBar()->sizeHint().width()
1489 int dialogHeight = marginHint()
1490 + label->sizeHint().height()
1491 + topLayout->spacing()
1493 + bigvbox->sizeHint().height()
1494 + sv->horizontalScrollBar()->sizeHint().height()
1496 + topLayout->spacing()
1497 + actionButton( KDialogBase::Cancel )->sizeHint().height()
1501 TQRect desk = TDEGlobalSettings::desktopGeometry(
this);
1502 int screenWidth = desk.width();
1503 if( dialogWidth > 3*screenWidth/4 )
1504 dialogWidth = 3*screenWidth/4;
1505 int screenHeight = desk.height();
1506 if( dialogHeight > 7*screenHeight/8 )
1507 dialogHeight = 7*screenHeight/8;
1509 setInitialSize( TQSize( dialogWidth, dialogHeight ) );
1513 KeyApprovalDialog::slotChangeEncryptionKey(
int nr )
1515 Kpgp::Module *pgp = Kpgp::Module::getKpgp();
1517 kdDebug(5100)<<
"Key approval dialog size is "
1518 <<width()<<
"x"<<height()<<endl;
1523 if( !mEncryptToSelf )
1525 KeyIDList keyIds = mKeys[nr];
1527 keyIds = pgp->selectPublicKeys( i18n(
"Encryption Key Selection"),
1528 i18n(
"if in your language something like "
1529 "'key(s)' isn't possible please "
1530 "use the plural in the translation",
1531 "Select the key(s) which should "
1532 "be used to encrypt the message "
1539 keyIds = pgp->selectPublicKeys( i18n(
"Encryption Key Selection"),
1540 i18n(
"if in your language something like "
1541 "'key(s)' isn't possible please "
1542 "use the plural in the translation",
1543 "Select the key(s) which should "
1544 "be used to encrypt the message "
1546 .arg( mAddressLabels[nr-1]->text() ),
1548 mAddressLabels[nr-1]->text(),
1551 if( !keyIds.isEmpty() ) {
1553 TQLabel* keyidsL = mKeyIdsLabels[nr];
1554 keyidsL->setText(
"0x" + keyIds.toStringList().join(
"\n0x" ) );
1565 KeyApprovalDialog::slotOk()
1567 Kpgp::Module *pgp = Kpgp::Module::getKpgp();
1574 if( mPrefsChanged ) {
1576 for(
unsigned int i = 0; i < mAddressLabels.size(); i++ ) {
1578 EncryptPref encrPref;
1579 switch( mEncrPrefCombos[i]->currentItem() ) {
1581 encrPref = NeverEncrypt;
1584 encrPref = AlwaysEncrypt;
1587 encrPref = AlwaysEncryptIfPossible;
1590 encrPref = AlwaysAskForEncryption;
1593 encrPref = AskWheneverPossible;
1597 encrPref = UnknownEncryptPref;
1599 pgp->setEncryptionPreference( mAddressLabels[i]->text(), encrPref );
1608 KeyApprovalDialog::slotCancel()
1616 CipherTextDialog::CipherTextDialog(
const TQCString & text,
1617 const TQCString & charset, TQWidget *parent,
1618 const char *name,
bool modal )
1619 :KDialogBase( parent, name, modal, i18n(
"OpenPGP Information"), Ok|Cancel, Ok)
1622 TQFrame *page = makeMainWidget();
1623 TQVBoxLayout *topLayout =
new TQVBoxLayout( page, 0, spacingHint() );
1625 TQLabel *label =
new TQLabel( page );
1626 label->setText(i18n(
"Result of the last encryption/sign operation:"));
1627 topLayout->addWidget( label );
1629 mEditBox =
new TQMultiLineEdit( page );
1630 mEditBox->setReadOnly(
true);
1631 topLayout->addWidget( mEditBox, 10 );
1633 TQString unicodeText;
1634 if (charset.isEmpty())
1635 unicodeText = TQString::fromLocal8Bit(text.data());
1638 TQTextCodec *codec = TDEGlobal::charsets()->codecForName(charset, ok);
1640 unicodeText = TQString::fromLocal8Bit(text.data());
1642 unicodeText = codec->toUnicode(text.data(), text.length());
1645 mEditBox->setText(unicodeText);
1650 void CipherTextDialog::setMinimumSize()
1654 for (
int i = 0; i < mEditBox->paragraphs(); i++ )
1655 (
void) mEditBox->paragraphRect( i );
1657 mEditBox->setMinimumHeight( mEditBox->fontMetrics().lineSpacing() * 25 );
1659 int textWidth = mEditBox->contentsWidth() + 30;
1662 #if KDE_IS_VERSION( 3, 1, 90 )
1663 int maxWidth = TDEGlobalSettings::desktopGeometry(parentWidget()).width()-100;
1665 TDEConfig gc(
"kdeglobals",
false,
false);
1666 gc.setGroup(
"Windows");
1668 if (TQApplication::desktop()->isVirtualDesktop() &&
1669 gc.readBoolEntry(
"XineramaEnabled",
true) &&
1670 gc.readBoolEntry(
"XineramaPlacementEnabled",
true)) {
1671 maxWidth = TQApplication::desktop()->screenGeometry(TQApplication::desktop()->screenNumber(parentWidget())).width()-100;
1673 maxWidth = TQApplication::desktop()->geometry().width()-100;
1677 mEditBox->setMinimumWidth( TQMIN( textWidth, maxWidth ) );
1680 void KeyRequester::virtual_hook(
int,
void* ) {}
1682 void PublicKeyRequester::virtual_hook(
int id,
void* data ) {
1683 base::virtual_hook(
id, data );
1686 void SecretKeyRequester::virtual_hook(
int id,
void* data ) {
1687 base::virtual_hook(
id, data );
1694 #include "kpgpui.moc"
This class is used to store information about a PGP key.
bool invalid() const
Returns true if the key is invalid.
bool secret() const
Returns true if the key is a secret key.
bool isValid() const
Returns true if the key is valid, i.e.
bool canSign() const
Returns true if the key can be used to sign data.
bool canEncrypt() const
Returns true if the key can be used to encrypt data.
bool disabled() const
Returns true if the key has been disabled.
bool revoked() const
Returns true if the key has been revoked.
bool expired() const
Returns true if the key has expired.
bool isValidEncryptionKey() const
Returns true if the key is a valid encryption key.
Validity keyTrust() const
Returns the trust value of this key.
bool isValidSigningKey() const
Returns true if the key is a valid signing key.
time_t creationDate() const
Returns the creation date of the primary subkey.