21#include <tqvgroupbox.h>
24#include <tqwhatsthis.h>
26#include <tqapplication.h>
27#include <tqtextcodec.h>
28#include <tqdatetime.h>
32#include <tqpopupmenu.h>
38#include <kseparator.h>
39#include <kiconloader.h>
40#include <tdelistview.h>
41#include <tdeconfigbase.h>
44#include <tdeapplication.h>
46#include <tdeglobalsettings.h>
55const int Kpgp::KeySelectionDialog::sCheckSelectionDelay = 250;
59PassphraseDialog::PassphraseDialog( TQWidget *parent,
60 const TQString &caption,
bool modal,
61 const TQString &keyID )
62 :KDialogBase( parent, 0, modal, caption, Ok|Cancel )
64 TQHBox *hbox = makeHBoxMainWidget();
65 hbox->setSpacing( spacingHint() );
66 hbox->setMargin( marginHint() );
68 TQLabel *label =
new TQLabel(hbox);
69 label->setPixmap( BarIcon(
"pgp-keys") );
71 TQWidget *rightArea =
new TQWidget( hbox );
72 TQVBoxLayout *vlay =
new TQVBoxLayout( rightArea, 0, spacingHint() );
75 label =
new TQLabel(i18n(
"Please enter your OpenPGP passphrase:"),rightArea);
77 label =
new TQLabel(i18n(
"Please enter the OpenPGP passphrase for\n\"%1\":").arg(keyID),
79 lineedit =
new KPasswordEdit( rightArea );
80 lineedit->setEchoMode(TQLineEdit::Password);
81 lineedit->setMinimumWidth( fontMetrics().maxWidth()*20 );
83 connect( lineedit, TQ_SIGNAL(returnPressed()),
this, TQ_SLOT(slotOk()) );
85 vlay->addWidget( label );
86 vlay->addWidget( lineedit );
92PassphraseDialog::~PassphraseDialog()
96TQString PassphraseDialog::passphrase()
98 return lineedit->password();
105Config::Config( TQWidget *parent,
const char *name,
bool encrypt )
106 : TQWidget( parent, name ), pgp( Module::getKpgp() )
113 TQVBoxLayout *topLayout =
new TQVBoxLayout(
this, 0, KDialog::spacingHint() );
115 group =
new TQVGroupBox( i18n(
"Warning"),
this );
116 group->layout()->setSpacing( KDialog::spacingHint() );
119 label =
new TQLabel( i18n(
"Please check if encryption really "
120 "works before you start using it seriously. Also note that attachments "
121 "are not encrypted by the PGP/GPG module."), group );
123 TQFont labelFont = label->font();
124 labelFont.setBold(
true );
125 label->setFont( labelFont );
127 label->setAlignment( AlignLeft|WordBreak );
130 topLayout->addWidget( group );
132 group =
new TQVGroupBox( i18n(
"Encryption Tool"),
this );
133 group->layout()->setSpacing( KDialog::spacingHint() );
135 TQHBox * hbox =
new TQHBox( group );
136 label =
new TQLabel( i18n(
"Select encryption tool to &use:"), hbox );
137 toolCombo =
new TQComboBox(
false, hbox );
138 toolCombo->insertStringList( TQStringList()
139 << i18n(
"Autodetect")
140 << i18n(
"GnuPG - Gnu Privacy Guard")
141 << i18n(
"PGP Version 2.x")
142 << i18n(
"PGP Version 5.x")
143 << i18n(
"PGP Version 6.x")
144 << i18n(
"Do not use any encryption tool") );
145 label->setBuddy( toolCombo );
146 hbox->setStretchFactor( toolCombo, 1 );
147 connect( toolCombo, TQ_SIGNAL( activated(
int ) ),
148 this, TQ_SIGNAL( changed(
void ) ) );
151 topLayout->addWidget( group );
153 mpOptionsGroupBox =
new TQVGroupBox( i18n(
"Options"),
this );
154 mpOptionsGroupBox->layout()->setSpacing( KDialog::spacingHint() );
155 storePass =
new TQCheckBox( i18n(
"&Keep passphrase in memory"),
157 connect( storePass, TQ_SIGNAL( toggled(
bool ) ),
158 this, TQ_SIGNAL( changed(
void ) ) );
159 msg = i18n(
"<qt><p>When this option is enabled, the passphrase of your "
160 "private key will be remembered by the application as long "
161 "as the application is running. Thus you will only have to "
162 "enter the passphrase once.</p><p>Be aware that this could be a "
163 "security risk. If you leave your computer, others "
164 "can use it to send signed messages and/or read your encrypted "
165 "messages. If a core dump occurs, the contents of your RAM will "
166 "be saved onto disk, including your passphrase.</p>"
167 "<p>Note that when using KMail, this setting only applies "
168 "if you are not using gpg-agent. It is also ignored "
169 "if you are using crypto plugins.</p></qt>" );
170 TQWhatsThis::add( storePass, msg );
172 encToSelf =
new TQCheckBox( i18n(
"Always encr&ypt to self"),
174 connect( encToSelf, TQ_SIGNAL( toggled(
bool ) ),
175 this, TQ_SIGNAL( changed(
void ) ) );
177 msg = i18n(
"<qt><p>When this option is enabled, the message/file "
178 "will not only be encrypted with the receiver's public key, "
179 "but also with your key. This will enable you to decrypt the "
180 "message/file at a later time. This is generally a good idea."
182 TQWhatsThis::add( encToSelf, msg );
186 showCipherText =
new TQCheckBox( i18n(
"&Show signed/encrypted text after "
189 connect( showCipherText, TQ_SIGNAL( toggled(
bool ) ),
190 this, TQ_SIGNAL( changed(
void ) ) );
192 msg = i18n(
"<qt><p>When this option is enabled, the signed/encrypted text "
193 "will be shown in a separate window, enabling you to know how "
194 "it will look before it is sent. This is a good idea when "
195 "you are verifying that your encryption system works.</p></qt>" );
196 TQWhatsThis::add( showCipherText, msg );
198 showKeyApprovalDlg =
new TQCheckBox( i18n(
"Always show the encryption "
199 "keys &for approval"),
201 connect( showKeyApprovalDlg, TQ_SIGNAL( toggled(
bool ) ),
202 this, TQ_SIGNAL( changed(
void ) ) );
203 msg = i18n(
"<qt><p>When this option is enabled, the application will "
204 "always show you a list of public keys from which you can "
205 "choose the one it will use for encryption. If it is off, "
206 "the application will only show the dialog if it cannot find "
207 "the right key or if there are several which could be used. "
209 TQWhatsThis::add( showKeyApprovalDlg, msg );
212 showKeyApprovalDlg = 0;
214 topLayout->addWidget( mpOptionsGroupBox );
216 topLayout->addStretch(1);
230 storePass->setChecked( pgp->storePassPhrase() );
232 encToSelf->setChecked( pgp->encryptToSelf() );
233 showCipherText->setChecked( pgp->showCipherText() );
234 if( 0 != showKeyApprovalDlg )
235 showKeyApprovalDlg->setChecked( pgp->showKeyApprovalDlg() );
238 switch (pgp->pgpType) {
241 case Module::tAuto: type = 0;
break;
242 case Module::tGPG: type = 1;
break;
243 case Module::tPGP2: type = 2;
break;
244 case Module::tPGP5: type = 3;
break;
245 case Module::tPGP6: type = 4;
break;
246 case Module::tOff: type = 5;
break;
248 toolCombo->setCurrentItem( type );
252Config::applySettings()
254 pgp->setStorePassPhrase(storePass->isChecked());
256 pgp->setEncryptToSelf(encToSelf->isChecked());
257 pgp->setShowCipherText(showCipherText->isChecked());
258 if( 0 != showKeyApprovalDlg )
259 pgp->setShowKeyApprovalDlg( showKeyApprovalDlg->isChecked() );
261 Module::PGPType type;
262 switch ( toolCombo->currentItem() ) {
265 case 0: type = Module::tAuto;
break;
266 case 1: type = Module::tGPG;
break;
267 case 2: type = Module::tPGP2;
break;
268 case 3: type = Module::tPGP5;
break;
269 case 4: type = Module::tPGP6;
break;
270 case 5: type = Module::tOff;
break;
274 pgp->writeConfig(
true);
280KeySelectionDialog::KeySelectionDialog(
const KeyList& keyList,
281 const TQString& title,
282 const TQString& text,
283 const KeyIDList& keyIds,
284 const bool rememberChoice,
285 const unsigned int allowedKeys,
286 const bool extendedSelection,
287 TQWidget *parent,
const char *name,
289 : KDialogBase( parent, name, modal, title, Default|Ok|Cancel, Ok ),
291 mAllowedKeys( allowedKeys ),
292 mCurrentContextMenuItem( 0 )
295 KWin::setIcons( winId(), tdeApp->icon(), tdeApp->miniIcon() );
296 Kpgp::Module *pgp = Kpgp::Module::getKpgp();
297 TDEConfig *config = pgp->getConfig();
298 TDEConfigGroup dialogConfig( config,
"Key Selection Dialog" );
300 TQSize defaultSize( 580, 400 );
301 TQSize dialogSize = dialogConfig.readSizeEntry(
"Dialog size", &defaultSize );
303 resize( dialogSize );
305 mCheckSelectionTimer =
new TQTimer(
this,
"mCheckSelectionTimer" );
306 mStartSearchTimer =
new TQTimer(
this,
"mStartSearchTimer" );
309 mKeyGoodPix =
new TQPixmap( UserIcon(
"key_ok") );
310 mKeyBadPix =
new TQPixmap( UserIcon(
"key_bad") );
311 mKeyUnknownPix =
new TQPixmap( UserIcon(
"key_unknown") );
312 mKeyValidPix =
new TQPixmap( UserIcon(
"key") );
314 TQFrame *page = makeMainWidget();
315 TQVBoxLayout *topLayout =
new TQVBoxLayout( page, 0, spacingHint() );
317 if( !text.isEmpty() ) {
318 TQLabel *label =
new TQLabel( page );
319 label->setText( text );
320 topLayout->addWidget( label );
323 TQHBoxLayout * hlay =
new TQHBoxLayout( topLayout );
324 TQLineEdit * le =
new TQLineEdit( page );
325 hlay->addWidget(
new TQLabel( le, i18n(
"&Search for:"), page ) );
326 hlay->addWidget( le, 1 );
329 connect( le, TQ_SIGNAL(textChanged(
const TQString&)),
330 this, TQ_SLOT(slotSearch(
const TQString&)) );
331 connect( mStartSearchTimer, TQ_SIGNAL(timeout()), TQ_SLOT(slotFilter()) );
333 mListView =
new TDEListView( page );
334 mListView->addColumn( i18n(
"Key ID") );
335 mListView->addColumn( i18n(
"User ID") );
336 mListView->setAllColumnsShowFocus(
true );
337 mListView->setResizeMode( TQListView::LastColumn );
338 mListView->setRootIsDecorated(
true );
339 mListView->setShowSortIndicator(
true );
340 mListView->setSorting( 1,
true );
341 mListView->setShowToolTips(
true );
342 if( extendedSelection ) {
343 mListView->setSelectionMode( TQListView::Extended );
346 topLayout->addWidget( mListView, 10 );
348 if (rememberChoice) {
349 mRememberCB =
new TQCheckBox( i18n(
"Remember choice"), page );
350 topLayout->addWidget( mRememberCB );
351 TQWhatsThis::add(mRememberCB,
352 i18n(
"<qt><p>If you check this box your choice will "
353 "be stored and you will not be asked again."
357 initKeylist( keyList, keyIds );
360 if( extendedSelection ) {
361 lvi = mListView->currentItem();
362 slotCheckSelection();
365 lvi = mListView->selectedItem();
366 slotCheckSelection( lvi );
371 mListView->center( mListView->contentsX(), mListView->itemPos( lvi ) );
373 if( extendedSelection ) {
374 connect( mCheckSelectionTimer, TQ_SIGNAL( timeout() ),
375 this, TQ_SLOT( slotCheckSelection() ) );
376 connect( mListView, TQ_SIGNAL( selectionChanged() ),
377 this, TQ_SLOT( slotSelectionChanged() ) );
380 connect( mListView, TQ_SIGNAL( selectionChanged( TQListViewItem* ) ),
381 this, TQ_SLOT( slotSelectionChanged( TQListViewItem* ) ) );
383 connect( mListView, TQ_SIGNAL( doubleClicked ( TQListViewItem *,
const TQPoint &,
int ) ),
this, TQ_SLOT( accept() ) );
385 connect( mListView, TQ_SIGNAL( contextMenuRequested( TQListViewItem*,
386 const TQPoint&,
int ) ),
387 this, TQ_SLOT( slotRMB( TQListViewItem*,
const TQPoint&,
int ) ) );
389 setButtonText( KDialogBase::Default, i18n(
"&Reread Keys") );
390 connect(
this, TQ_SIGNAL( defaultClicked() ),
391 this, TQ_SLOT( slotRereadKeys() ) );
395KeySelectionDialog::~KeySelectionDialog()
397 Kpgp::Module *pgp = Kpgp::Module::getKpgp();
398 TDEConfig *config = pgp->getConfig();
399 TDEConfigGroup dialogConfig( config,
"Key Selection Dialog" );
400 dialogConfig.writeEntry(
"Dialog size", size() );
404 delete mKeyUnknownPix;
409KeyID KeySelectionDialog::key()
const
411 if( mListView->isMultiSelection() || mKeyIds.isEmpty() )
414 return mKeyIds.first();
418void KeySelectionDialog::initKeylist(
const KeyList& keyList,
419 const KeyIDList& keyIds )
421 TQListViewItem* firstSelectedItem = 0;
426 for( KeyListIterator it( keyList ); it.current(); ++it ) {
427 KeyID curKeyId = (*it)->primaryKeyID();
429 TQListViewItem* primaryUserID =
new TQListViewItem( mListView, curKeyId,
430 (*it)->primaryUserID() );
433 if( keyIds.findIndex( curKeyId ) != -1 ) {
434 if( 0 == firstSelectedItem ) {
435 firstSelectedItem = primaryUserID;
437 mListView->setSelected( primaryUserID,
true );
438 mKeyIds.append( curKeyId );
440 primaryUserID->setOpen(
false );
443 switch( keyValidity( *it ) ) {
445 primaryUserID->setPixmap( 0, *mKeyUnknownPix );
448 primaryUserID->setPixmap( 0, *mKeyValidPix );
451 primaryUserID->setPixmap( 0, *mKeyGoodPix );
454 primaryUserID->setPixmap( 0, *mKeyBadPix );
458 TQListViewItem* childItem;
460 childItem =
new TQListViewItem( primaryUserID,
"",
461 i18n(
"Fingerprint: %1" )
462 .arg( beautifyFingerprint( (*it)->primaryFingerprint() ) ) );
463 if( primaryUserID->isSelected() && mListView->isMultiSelection() ) {
464 mListView->setSelected( childItem,
true );
467 childItem =
new TQListViewItem( primaryUserID,
"", keyInfo( *it ) );
468 if( primaryUserID->isSelected() && mListView->isMultiSelection() ) {
469 mListView->setSelected( childItem,
true );
472 UserIDList userIDs = (*it)->userIDs();
473 UserIDListIterator uidit( userIDs );
476 for( ; *uidit; ++uidit ) {
477 childItem =
new TQListViewItem( primaryUserID,
"", (*uidit)->text() );
478 if( primaryUserID->isSelected() && mListView->isMultiSelection() ) {
479 mListView->setSelected( childItem,
true );
485 if( 0 != firstSelectedItem ) {
486 mListView->setCurrentItem( firstSelectedItem );
491TQString KeySelectionDialog::keyInfo(
const Kpgp::Key *key )
const
493 TQString status, remark;
495 status = i18n(
"Revoked");
498 status = i18n(
"Expired");
501 status = i18n(
"Disabled");
504 status = i18n(
"Invalid");
507 Validity keyTrust = key->
keyTrust();
509 case KPGP_VALIDITY_UNDEFINED:
510 status = i18n(
"Undefined trust");
512 case KPGP_VALIDITY_NEVER:
513 status = i18n(
"Untrusted");
515 case KPGP_VALIDITY_MARGINAL:
516 status = i18n(
"Marginally trusted");
518 case KPGP_VALIDITY_FULL:
519 status = i18n(
"Fully trusted");
521 case KPGP_VALIDITY_ULTIMATE:
522 status = i18n(
"Ultimately trusted");
524 case KPGP_VALIDITY_UNKNOWN:
526 status = i18n(
"Unknown");
529 remark = i18n(
"Secret key available");
532 remark = i18n(
"Sign only key");
535 remark = i18n(
"Encryption only key");
541 if( remark.isEmpty() ) {
542 return " " + i18n(
"creation date and status of an OpenPGP key",
543 "Creation date: %1, Status: %2")
544 .arg( TDEGlobal::locale()->formatDate( dt.date(),
true ) )
548 return " " + i18n(
"creation date, status and remark of an OpenPGP key",
549 "Creation date: %1, Status: %2 (%3)")
550 .arg( TDEGlobal::locale()->formatDate( dt.date(),
true ) )
556TQString KeySelectionDialog::beautifyFingerprint(
const TQCString& fpr )
const
560 if( 40 == fpr.length() ) {
563 result.fill(
' ', 50 );
564 memcpy( result.data() , fpr.data() , 4 );
565 memcpy( result.data() + 5, fpr.data() + 4, 4 );
566 memcpy( result.data() + 10, fpr.data() + 8, 4 );
567 memcpy( result.data() + 15, fpr.data() + 12, 4 );
568 memcpy( result.data() + 20, fpr.data() + 16, 4 );
569 memcpy( result.data() + 26, fpr.data() + 20, 4 );
570 memcpy( result.data() + 31, fpr.data() + 24, 4 );
571 memcpy( result.data() + 36, fpr.data() + 28, 4 );
572 memcpy( result.data() + 41, fpr.data() + 32, 4 );
573 memcpy( result.data() + 46, fpr.data() + 36, 4 );
575 else if( 32 == fpr.length() ) {
578 result.fill(
' ', 48 );
579 memcpy( result.data() , fpr.data() , 2 );
580 memcpy( result.data() + 3, fpr.data() + 2, 2 );
581 memcpy( result.data() + 6, fpr.data() + 4, 2 );
582 memcpy( result.data() + 9, fpr.data() + 6, 2 );
583 memcpy( result.data() + 12, fpr.data() + 8, 2 );
584 memcpy( result.data() + 15, fpr.data() + 10, 2 );
585 memcpy( result.data() + 18, fpr.data() + 12, 2 );
586 memcpy( result.data() + 21, fpr.data() + 14, 2 );
587 memcpy( result.data() + 25, fpr.data() + 16, 2 );
588 memcpy( result.data() + 28, fpr.data() + 18, 2 );
589 memcpy( result.data() + 31, fpr.data() + 20, 2 );
590 memcpy( result.data() + 34, fpr.data() + 22, 2 );
591 memcpy( result.data() + 37, fpr.data() + 24, 2 );
592 memcpy( result.data() + 40, fpr.data() + 26, 2 );
593 memcpy( result.data() + 43, fpr.data() + 28, 2 );
594 memcpy( result.data() + 46, fpr.data() + 30, 2 );
603int KeySelectionDialog::keyValidity(
const Kpgp::Key *key )
const
609 if( ( mAllowedKeys & EncrSignKeys ) == EncryptionKeys ) {
619 else if( ( mAllowedKeys & EncrSignKeys ) == SigningKeys ) {
629 else if( ( mAllowedKeys & ValidKeys ) && !key->
isValid() ) {
636 Validity keyTrust = key->
keyTrust();
638 case KPGP_VALIDITY_NEVER:
641 case KPGP_VALIDITY_MARGINAL:
642 case KPGP_VALIDITY_FULL:
643 case KPGP_VALIDITY_ULTIMATE:
646 case KPGP_VALIDITY_UNDEFINED:
647 if( mAllowedKeys & TrustedKeys ) {
655 case KPGP_VALIDITY_UNKNOWN:
664void KeySelectionDialog::updateKeyInfo(
const Kpgp::Key* key,
665 TQListViewItem* lvi )
const
671 if( lvi->parent() != 0 ) {
677 while( lvi->firstChild() ) {
678 kdDebug(5100) <<
"Deleting '" << lvi->firstChild()->text( 1 ) <<
"'\n";
679 delete lvi->firstChild();
681 kdDebug(5100) <<
"Deleting key 0x" << lvi->text( 0 ) <<
" ("
682 << lvi->text( 1 ) <<
")\n";
689 switch( keyValidity( key ) ) {
691 lvi->setPixmap( 0, *mKeyUnknownPix );
694 lvi->setPixmap( 0, *mKeyValidPix );
697 lvi->setPixmap( 0, *mKeyGoodPix );
700 lvi->setPixmap( 0, *mKeyBadPix );
707 for( lvi = lvi->firstChild(); lvi; lvi = lvi->nextSibling() ) {
708 if( lvi->text( 1 ).at(0) ==
' ' ) {
709 lvi->setText( 1, keyInfo( key ) );
717KeySelectionDialog::keyAdmissibility( TQListViewItem* lvi,
718 TrustCheckMode trustCheckMode )
const
726 if( mAllowedKeys == AllKeys ) {
730 Kpgp::Module *pgp = Kpgp::Module::getKpgp();
736 KeyID keyId = getKeyId( lvi );
737 Kpgp::Key* key = pgp->publicKey( keyId );
744 if( trustCheckMode == ForceTrustCheck ) {
745 key = pgp->rereadKey( keyId,
true );
746 updateKeyInfo( key, lvi );
747 val = keyValidity( key );
750 val = keyValidity( key );
751 if( ( trustCheckMode == AllowExpensiveTrustCheck ) && ( 0 == val ) ) {
752 key = pgp->rereadKey( keyId,
true );
753 updateKeyInfo( key, lvi );
754 val = keyValidity( key );
766 if( mAllowedKeys & TrustedKeys ) {
776 kdDebug( 5100 ) <<
"Error: Invalid key status value.\n";
784KeySelectionDialog::getKeyId(
const TQListViewItem* lvi )
const
789 if( 0 != lvi->parent() ) {
790 keyId = lvi->parent()->text(0).local8Bit();
793 keyId = lvi->text(0).local8Bit();
801void KeySelectionDialog::slotRereadKeys()
803 Kpgp::Module *pgp = Kpgp::Module::getKpgp();
811 if( PublicKeys & mAllowedKeys ) {
812 pgp->readPublicKeys(
true );
813 keys = pgp->publicKeys();
816 pgp->readSecretKeys(
true );
817 keys = pgp->secretKeys();
821 int offsetY = mListView->contentsY();
823 if( mListView->isMultiSelection() ) {
824 disconnect( mListView, TQ_SIGNAL( selectionChanged() ),
825 this, TQ_SLOT( slotSelectionChanged() ) );
828 disconnect( mListView, TQ_SIGNAL( selectionChanged( TQListViewItem * ) ),
829 this, TQ_SLOT( slotSelectionChanged( TQListViewItem * ) ) );
832 initKeylist( keys, KeyIDList( mKeyIds ) );
835 if( mListView->isMultiSelection() ) {
836 connect( mListView, TQ_SIGNAL( selectionChanged() ),
837 this, TQ_SLOT( slotSelectionChanged() ) );
838 slotSelectionChanged();
841 connect( mListView, TQ_SIGNAL( selectionChanged( TQListViewItem * ) ),
842 this, TQ_SLOT( slotSelectionChanged( TQListViewItem * ) ) );
846 mListView->setContentsPos( 0, offsetY );
850void KeySelectionDialog::slotSelectionChanged( TQListViewItem * lvi )
852 slotCheckSelection( lvi );
856void KeySelectionDialog::slotSelectionChanged()
858 kdDebug(5100) <<
"KeySelectionDialog::slotSelectionChanged()\n";
863 mCheckSelectionTimer->start( sCheckSelectionDelay );
867void KeySelectionDialog::slotCheckSelection( TQListViewItem* plvi )
869 kdDebug(5100) <<
"KeySelectionDialog::slotCheckSelection()\n";
871 if( !mListView->isMultiSelection() ) {
873 KeyID keyId = getKeyId( plvi );
874 if( !keyId.isEmpty() ) {
875 mKeyIds.append( keyId );
876 enableButtonOK( 1 == keyAdmissibility( plvi, AllowExpensiveTrustCheck ) );
879 enableButtonOK(
false );
883 mCheckSelectionTimer->stop();
887 disconnect( mListView, TQ_SIGNAL( selectionChanged() ),
888 this, TQ_SLOT( slotSelectionChanged() ) );
890 KeyIDList newKeyIdList;
891 TQValueList<TQListViewItem*> keysToBeChecked;
893 bool keysAllowed =
true;
894 enum { UNKNOWN, SELECTED, DESELECTED } userAction = UNKNOWN;
896 for( TQListViewItem *lvi = mListView->firstChild();
898 lvi = lvi->nextSibling() ) {
905 int itemCount = 1 + lvi->childCount();
906 int selectedCount = lvi->isSelected() ? 1 : 0;
907 for( TQListViewItem *clvi = lvi->firstChild();
909 clvi = clvi->nextSibling() ) {
910 if( clvi->isSelected() ) {
915 if( userAction == UNKNOWN ) {
920 if( 0 < selectedCount ) {
921 if( -1 == mKeyIds.findIndex( lvi->text(0).local8Bit() ) ) {
924 kdDebug(5100) <<
"selectedCount: "<<selectedCount<<
"/"<<itemCount
925 <<
" --- User selected key "<<lvi->text(0)<<endl;
926 userAction = SELECTED;
928 else if( ( itemCount > selectedCount ) &&
929 ( -1 != mKeyIds.findIndex( lvi->text(0).local8Bit() ) ) ) {
932 kdDebug(5100) <<
"selectedCount: "<<selectedCount<<
"/"<<itemCount
933 <<
" --- User deselected key "<<lvi->text(0)<<endl;
934 userAction = DESELECTED;
938 if( itemCount == selectedCount ) {
940 KeyID keyId = lvi->text(0).local8Bit();
941 newKeyIdList.append( keyId );
942 int admissibility = keyAdmissibility( lvi, NoExpensiveTrustCheck );
943 if( -1 == admissibility ) {
946 else if ( 0 == admissibility ) {
947 keysToBeChecked.append( lvi );
950 else if( 0 < selectedCount ) {
953 if( userAction == SELECTED ) {
955 mListView->setSelected( lvi,
true );
956 for( TQListViewItem *clvi = lvi->firstChild();
958 clvi = clvi->nextSibling() ) {
959 mListView->setSelected( clvi,
true );
962 KeyID keyId = lvi->text(0).local8Bit();
963 newKeyIdList.append( keyId );
964 int admissibility = keyAdmissibility( lvi, NoExpensiveTrustCheck );
965 if( -1 == admissibility ) {
968 else if ( 0 == admissibility ) {
969 keysToBeChecked.append( lvi );
974 mListView->setSelected( lvi,
false );
975 for( TQListViewItem *clvi = lvi->firstChild();
977 clvi = clvi->nextSibling() ) {
978 mListView->setSelected( clvi,
false );
983 kdDebug(5100) <<
"Selected keys: " << newKeyIdList.toStringList().join(
", ") << endl;
984 mKeyIds = newKeyIdList;
985 if( !keysToBeChecked.isEmpty() ) {
986 keysAllowed = keysAllowed && checkKeys( keysToBeChecked );
988 enableButtonOK( keysAllowed );
990 connect( mListView, TQ_SIGNAL( selectionChanged() ),
991 this, TQ_SLOT( slotSelectionChanged() ) );
996bool KeySelectionDialog::checkKeys(
const TQValueList<TQListViewItem*>& keys )
const
998 KProgressDialog* pProgressDlg = 0;
999 bool keysAllowed =
true;
1000 kdDebug(5100) <<
"Checking keys...\n";
1002 pProgressDlg =
new KProgressDialog( 0, 0, i18n(
"Checking Keys"),
1003 i18n(
"Checking key 0xMMMMMMMM..."),
1005 pProgressDlg->setAllowCancel(
false );
1006 pProgressDlg->progressBar()->setTotalSteps( keys.count() );
1007 pProgressDlg->setMinimumDuration( 1000 );
1008 pProgressDlg->show();
1010 for( TQValueList<TQListViewItem*>::ConstIterator it = keys.begin();
1013 kdDebug(5100) <<
"Checking key 0x" << getKeyId( *it ) <<
"...\n";
1014 pProgressDlg->setLabel( i18n(
"Checking key 0x%1...")
1015 .arg( TQString( getKeyId( *it ) ) ) );
1016 tdeApp->processEvents();
1017 keysAllowed = keysAllowed && ( -1 != keyAdmissibility( *it, AllowExpensiveTrustCheck ) );
1018 pProgressDlg->progressBar()->advance( 1 );
1019 tdeApp->processEvents();
1022 delete pProgressDlg;
1029void KeySelectionDialog::slotRMB( TQListViewItem* lvi,
const TQPoint& pos,
int )
1035 mCurrentContextMenuItem = lvi;
1037 TQPopupMenu menu(
this);
1038 menu.insertItem( i18n(
"Recheck Key" ),
this, TQ_SLOT( slotRecheckKey() ) );
1043void KeySelectionDialog::slotRecheckKey()
1045 if( 0 != mCurrentContextMenuItem ) {
1047 keyAdmissibility( mCurrentContextMenuItem, ForceTrustCheck );
1049 slotCheckSelection( mCurrentContextMenuItem );
1053void KeySelectionDialog::slotOk()
1055 if( mCheckSelectionTimer->isActive() ) {
1056 slotCheckSelection();
1058 mStartSearchTimer->stop();
1063void KeySelectionDialog::slotCancel()
1065 mCheckSelectionTimer->stop();
1066 mStartSearchTimer->stop();
1071void KeySelectionDialog::slotSearch(
const TQString & text )
1073 mSearchText = text.stripWhiteSpace().upper();
1074 mStartSearchTimer->start( sCheckSelectionDelay,
true );
1077void KeySelectionDialog::slotFilter()
1079 if ( mSearchText.isEmpty() ) {
1085 TQRegExp keyIdRegExp(
"(?:0x)?[A-F0-9]{1,8}",
false );
1086 if ( keyIdRegExp.exactMatch( mSearchText ) ) {
1087 if ( mSearchText.startsWith(
"0X" ) )
1089 filterByKeyID( mSearchText.mid( 2 ) );
1092 filterByKeyIDOrUID( mSearchText );
1095 filterByUID( mSearchText );
1099void KeySelectionDialog::filterByKeyID(
const TQString & keyID )
1101 assert( keyID.length() <= 8 );
1102 assert( !keyID.isEmpty() );
1103 if ( keyID.isEmpty() )
1106 for ( TQListViewItem * item = mListView->firstChild() ; item ; item = item->nextSibling() )
1107 item->setVisible( item->text( 0 ).upper().startsWith( keyID ) );
1110void KeySelectionDialog::filterByKeyIDOrUID(
const TQString & str )
1112 assert( !str.isEmpty() );
1115 TQRegExp rx(
"\\b" + TQRegExp::escape( str ),
false );
1117 for ( TQListViewItem * item = mListView->firstChild() ; item ; item = item->nextSibling() )
1118 item->setVisible( item->text( 0 ).upper().startsWith( str )
1119 || rx.search( item->text( 1 ) ) >= 0
1120 || anyChildMatches( item, rx ) );
1124void KeySelectionDialog::filterByUID(
const TQString & str )
1126 assert( !str.isEmpty() );
1129 TQRegExp rx(
"\\b" + TQRegExp::escape( str ),
false );
1131 for ( TQListViewItem * item = mListView->firstChild() ; item ; item = item->nextSibling() )
1132 item->setVisible( rx.search( item->text( 1 ) ) >= 0
1133 || anyChildMatches( item, rx ) );
1137bool KeySelectionDialog::anyChildMatches(
const TQListViewItem * item, TQRegExp & rx )
const
1142 TQListViewItem * stop = item->nextSibling();
1144 for ( TQListViewItemIterator it( item->firstChild() ) ; it.current() && it.current() != stop ; ++it )
1145 if ( rx.search( it.current()->text( 1 ) ) >= 0 ) {
1152void KeySelectionDialog::showAllItems()
1154 for ( TQListViewItem * item = mListView->firstChild() ; item ; item = item->nextSibling() )
1155 item->setVisible(
true );
1159KeyRequester::KeyRequester( TQWidget * parent,
bool multipleKeys,
1160 unsigned int allowedKeys,
const char * name )
1161 : TQWidget( parent, name ),
1162 mDialogCaption( i18n(
"OpenPGP Key Selection") ),
1163 mDialogMessage( i18n(
"Please select an OpenPGP key to use.") ),
1164 mMulti( multipleKeys ),
1165 mAllowedKeys( allowedKeys ),
1168 TQHBoxLayout * hlay =
new TQHBoxLayout(
this, 0, KDialog::spacingHint() );
1171 mLabel =
new TQLabel(
this );
1172 mLabel->setFrameStyle( TQFrame::Panel | TQFrame::Sunken );
1175 mEraseButton =
new TQPushButton(
this );
1176 mEraseButton->setAutoDefault(
false );
1177 mEraseButton->setSizePolicy( TQSizePolicy( TQSizePolicy::Minimum,
1178 TQSizePolicy::Minimum ) );
1179 mEraseButton->setPixmap( SmallIcon(
"clear_left" ) );
1180 TQToolTip::add( mEraseButton, i18n(
"Clear") );
1183 mDialogButton =
new TQPushButton( i18n(
"Change..."),
this );
1184 mDialogButton->setAutoDefault(
false );
1186 hlay->addWidget( mLabel, 1 );
1187 hlay->addWidget( mEraseButton );
1188 hlay->addWidget( mDialogButton );
1190 connect( mEraseButton, TQ_SIGNAL(clicked()), TQ_SLOT(slotEraseButtonClicked()) );
1191 connect( mDialogButton, TQ_SIGNAL(clicked()), TQ_SLOT(slotDialogButtonClicked()) );
1193 setSizePolicy( TQSizePolicy( TQSizePolicy::MinimumExpanding,
1194 TQSizePolicy::Fixed ) );
1197KeyRequester::~KeyRequester() {
1201KeyIDList KeyRequester::keyIDs()
const {
1205void KeyRequester::setKeyIDs(
const KeyIDList & keyIDs ) {
1207 if ( mKeys.empty() ) {
1211 if ( mKeys.size() > 1 )
1212 setMultipleKeysEnabled(
true );
1214 TQString s = mKeys.toStringList().join(
", ");
1216 mLabel->setText( s );
1217 TQToolTip::remove( mLabel );
1218 TQToolTip::add( mLabel, s );
1221void KeyRequester::slotDialogButtonClicked() {
1222 Module * pgp = Module::getKpgp();
1225 kdWarning() <<
"Kpgp::KeyRequester::slotDialogButtonClicked(): No pgp module found!" << endl;
1229 setKeyIDs( keyRequestHook( pgp ) );
1233void KeyRequester::slotEraseButtonClicked() {
1239void KeyRequester::setDialogCaption(
const TQString & caption ) {
1240 mDialogCaption = caption;
1243void KeyRequester::setDialogMessage(
const TQString & msg ) {
1244 mDialogMessage = msg;
1247bool KeyRequester::isMultipleKeysEnabled()
const {
1251void KeyRequester::setMultipleKeysEnabled(
bool multi ) {
1252 if ( multi == mMulti )
return;
1254 if ( !multi && mKeys.size() > 1 )
1255 mKeys.erase( ++mKeys.begin(), mKeys.end() );
1260int KeyRequester::allowedKeys()
const {
1261 return mAllowedKeys;
1264void KeyRequester::setAllowedKeys(
int allowedKeys ) {
1265 mAllowedKeys = allowedKeys;
1269PublicKeyRequester::PublicKeyRequester( TQWidget * parent,
bool multi,
1270 unsigned int allowed,
const char * name )
1271 : KeyRequester( parent, multi, allowed & ~SecretKeys, name )
1276PublicKeyRequester::~PublicKeyRequester() {
1280KeyIDList PublicKeyRequester::keyRequestHook( Module * pgp )
const {
1282 return pgp->selectPublicKeys( mDialogCaption, mDialogMessage, mKeys, TQString(), mAllowedKeys );
1285SecretKeyRequester::SecretKeyRequester( TQWidget * parent,
bool multi,
1286 unsigned int allowed,
const char * name )
1287 : KeyRequester( parent, multi, allowed & ~PublicKeys, name )
1292SecretKeyRequester::~SecretKeyRequester() {
1296KeyIDList SecretKeyRequester::keyRequestHook( Module * pgp )
const {
1299 KeyID keyID = mKeys.first();
1300 keyID = pgp->selectSecretKey( mDialogCaption, mDialogMessage, keyID );
1302 return KeyIDList() << keyID;
1308KeyApprovalDialog::KeyApprovalDialog(
const TQStringList& addresses,
1309 const TQValueVector<KeyIDList>& keyIDs,
1310 const int allowedKeys,
1311 TQWidget *parent,
const char *name,
1313 : KDialogBase( parent, name, modal, i18n(
"Encryption Key Approval"),
1316 mAllowedKeys( allowedKeys ),
1317 mPrefsChanged( false )
1319 Kpgp::Module *pgp = Kpgp::Module::getKpgp();
1329 TQFrame *page = makeMainWidget();
1330 TQVBoxLayout *topLayout =
new TQVBoxLayout( page, 0, KDialog::spacingHint() );
1332 TQLabel *label =
new TQLabel( i18n(
"The following keys will be used for "
1335 topLayout->addWidget( label );
1337 TQScrollView* sv =
new TQScrollView( page );
1338 sv->setResizePolicy( TQScrollView::AutoOneFit );
1339 topLayout->addWidget( sv );
1340 TQVBox* bigvbox =
new TQVBox( sv->viewport() );
1341 bigvbox->setMargin( KDialog::marginHint() );
1342 bigvbox->setSpacing( KDialog::spacingHint() );
1343 sv->addChild( bigvbox );
1345 TQButtonGroup *mChangeButtonGroup =
new TQButtonGroup( bigvbox );
1346 mChangeButtonGroup->hide();
1347 mAddressLabels.resize( addresses.count() );
1348 mKeyIdsLabels.resize( keyIDs.size() );
1350 mEncrPrefCombos.resize( addresses.count() );
1353 if( pgp->encryptToSelf() ) {
1355 TQHBox* hbox =
new TQHBox( bigvbox );
1356 new TQLabel( i18n(
"Your keys:"), hbox );
1357 TQLabel* keyidsL =
new TQLabel( hbox );
1358 if( keyIDs[0].isEmpty() ) {
1359 keyidsL->setText( i18n(
"<none> means 'no key'",
"<none>") );
1362 keyidsL->setText(
"0x" + keyIDs[0].toStringList().join(
"\n0x" ) );
1364 keyidsL->setFrameStyle( TQFrame::Panel | TQFrame::Sunken );
1376 TQPushButton *button =
new TQPushButton( i18n(
"Change..."), hbox );
1377 mChangeButtonGroup->insert( button );
1378 button->setAutoDefault(
false );
1379 hbox->setStretchFactor( keyidsL, 10 );
1380 mKeyIdsLabels.insert( 0, keyidsL );
1384 new KSeparator( TQt::Horizontal, bigvbox );
1389 mKeyIdsLabels.insert( 0, 0 );
1393 TQStringList::ConstIterator ait;
1394 TQValueVector<KeyIDList>::const_iterator kit;
1396 for( ait = addresses.begin(), kit = keyIDs.begin(), i = 0;
1397 ( ait != addresses.end() ) && ( kit != keyIDs.end() );
1398 ++ait, ++kit, ++i ) {
1403 new KSeparator( TQt::Horizontal, bigvbox );
1406 TQHBox *hbox =
new TQHBox( bigvbox );
1407 new TQLabel( i18n(
"Recipient:"), hbox );
1408 TQLabel *addressL =
new TQLabel( *ait, hbox );
1409 hbox->setStretchFactor( addressL, 10 );
1410 mAddressLabels.insert( i, addressL );
1412 hbox =
new TQHBox( bigvbox );
1413 new TQLabel( i18n(
"Encryption keys:"), hbox );
1414 TQLabel* keyidsL =
new TQLabel( hbox );
1415 if( (*kit).isEmpty() ) {
1416 keyidsL->setText( i18n(
"<none> means 'no key'",
"<none>") );
1419 keyidsL->setText(
"0x" + (*kit).toStringList().join(
"\n0x" ) );
1421 keyidsL->setFrameStyle( TQFrame::Panel | TQFrame::Sunken );
1433 TQPushButton *button =
new TQPushButton( i18n(
"Change..."), hbox );
1434 mChangeButtonGroup->insert( button );
1435 button->setAutoDefault(
false );
1436 hbox->setStretchFactor( keyidsL, 10 );
1437 mKeyIdsLabels.insert( i + 1, keyidsL );
1441 hbox =
new TQHBox( bigvbox );
1442 new TQLabel( i18n(
"Encryption preference:"), hbox );
1443 TQComboBox *encrPrefCombo =
new TQComboBox( hbox );
1444 encrPrefCombo->insertItem( i18n(
"<none>") );
1445 encrPrefCombo->insertItem( i18n(
"Never Encrypt with This Key") );
1446 encrPrefCombo->insertItem( i18n(
"Always Encrypt with This Key") );
1447 encrPrefCombo->insertItem( i18n(
"Encrypt Whenever Encryption is Possible") );
1448 encrPrefCombo->insertItem( i18n(
"Always Ask") );
1449 encrPrefCombo->insertItem( i18n(
"Ask Whenever Encryption is Possible") );
1451 EncryptPref encrPref = pgp->encryptionPreference( *ait );
1452 switch( encrPref ) {
1454 encrPrefCombo->setCurrentItem( 1 );
1457 encrPrefCombo->setCurrentItem( 2 );
1459 case AlwaysEncryptIfPossible:
1460 encrPrefCombo->setCurrentItem( 3 );
1462 case AlwaysAskForEncryption:
1463 encrPrefCombo->setCurrentItem( 4 );
1465 case AskWheneverPossible:
1466 encrPrefCombo->setCurrentItem( 5 );
1469 encrPrefCombo->setCurrentItem( 0 );
1471 connect( encrPrefCombo, TQ_SIGNAL(activated(
int)),
1472 this, TQ_SLOT(slotPrefsChanged(
int)) );
1473 mEncrPrefCombos.insert( i, encrPrefCombo );
1475 connect( mChangeButtonGroup, TQ_SIGNAL(clicked(
int)),
1476 this, TQ_SLOT(slotChangeEncryptionKey(
int)) );
1479 int dialogWidth = marginHint()
1481 + bigvbox->sizeHint().width()
1482 + sv->verticalScrollBar()->sizeHint().width()
1487 int dialogHeight = marginHint()
1488 + label->sizeHint().height()
1489 + topLayout->spacing()
1491 + bigvbox->sizeHint().height()
1492 + sv->horizontalScrollBar()->sizeHint().height()
1494 + topLayout->spacing()
1495 + actionButton( KDialogBase::Cancel )->sizeHint().height()
1499 TQRect desk = TDEGlobalSettings::desktopGeometry(
this);
1500 int screenWidth = desk.width();
1501 if( dialogWidth > 3*screenWidth/4 )
1502 dialogWidth = 3*screenWidth/4;
1503 int screenHeight = desk.height();
1504 if( dialogHeight > 7*screenHeight/8 )
1505 dialogHeight = 7*screenHeight/8;
1507 setInitialSize( TQSize( dialogWidth, dialogHeight ) );
1511KeyApprovalDialog::slotChangeEncryptionKey(
int nr )
1513 Kpgp::Module *pgp = Kpgp::Module::getKpgp();
1515 kdDebug(5100)<<
"Key approval dialog size is "
1516 <<width()<<
"x"<<height()<<endl;
1521 if( !mEncryptToSelf )
1523 KeyIDList keyIds = mKeys[nr];
1525 keyIds = pgp->selectPublicKeys( i18n(
"Encryption Key Selection"),
1526 i18n(
"if in your language something like "
1527 "'key(s)' isn't possible please "
1528 "use the plural in the translation",
1529 "Select the key(s) which should "
1530 "be used to encrypt the message "
1537 keyIds = pgp->selectPublicKeys( i18n(
"Encryption Key Selection"),
1538 i18n(
"if in your language something like "
1539 "'key(s)' isn't possible please "
1540 "use the plural in the translation",
1541 "Select the key(s) which should "
1542 "be used to encrypt the message "
1544 .arg( mAddressLabels[nr-1]->text() ),
1546 mAddressLabels[nr-1]->text(),
1549 if( !keyIds.isEmpty() ) {
1551 TQLabel* keyidsL = mKeyIdsLabels[nr];
1552 keyidsL->setText(
"0x" + keyIds.toStringList().join(
"\n0x" ) );
1563KeyApprovalDialog::slotOk()
1565 Kpgp::Module *pgp = Kpgp::Module::getKpgp();
1572 if( mPrefsChanged ) {
1574 for(
unsigned int i = 0; i < mAddressLabels.size(); i++ ) {
1576 EncryptPref encrPref;
1577 switch( mEncrPrefCombos[i]->currentItem() ) {
1579 encrPref = NeverEncrypt;
1582 encrPref = AlwaysEncrypt;
1585 encrPref = AlwaysEncryptIfPossible;
1588 encrPref = AlwaysAskForEncryption;
1591 encrPref = AskWheneverPossible;
1595 encrPref = UnknownEncryptPref;
1597 pgp->setEncryptionPreference( mAddressLabels[i]->text(), encrPref );
1606KeyApprovalDialog::slotCancel()
1614CipherTextDialog::CipherTextDialog(
const TQCString & text,
1615 const TQCString & charset, TQWidget *parent,
1616 const char *name,
bool modal )
1617 :KDialogBase( parent, name, modal, i18n(
"OpenPGP Information"), Ok|Cancel, Ok)
1620 TQFrame *page = makeMainWidget();
1621 TQVBoxLayout *topLayout =
new TQVBoxLayout( page, 0, spacingHint() );
1623 TQLabel *label =
new TQLabel( page );
1624 label->setText(i18n(
"Result of the last encryption/sign operation:"));
1625 topLayout->addWidget( label );
1627 mEditBox =
new TQMultiLineEdit( page );
1628 mEditBox->setReadOnly(
true);
1629 topLayout->addWidget( mEditBox, 10 );
1631 TQString unicodeText;
1632 if (charset.isEmpty())
1633 unicodeText = TQString::fromLocal8Bit(text.data());
1636 TQTextCodec *codec = TDEGlobal::charsets()->codecForName(charset, ok);
1638 unicodeText = TQString::fromLocal8Bit(text.data());
1640 unicodeText = codec->toUnicode(text.data(), text.length());
1643 mEditBox->setText(unicodeText);
1648void CipherTextDialog::setMinimumSize()
1652 for (
int i = 0; i < mEditBox->paragraphs(); i++ )
1653 (
void) mEditBox->paragraphRect( i );
1655 mEditBox->setMinimumHeight( mEditBox->fontMetrics().lineSpacing() * 25 );
1657 int textWidth = mEditBox->contentsWidth() + 30;
1658 int maxWidth = TDEGlobalSettings::desktopGeometry(parentWidget()).width()-100;
1660 mEditBox->setMinimumWidth( TQMIN( textWidth, maxWidth ) );
1663void KeyRequester::virtual_hook(
int,
void* ) {}
1665void PublicKeyRequester::virtual_hook(
int id,
void* data ) {
1666 base::virtual_hook(
id, data );
1669void SecretKeyRequester::virtual_hook(
int id,
void* data ) {
1670 base::virtual_hook(
id, data );
1677#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.