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 #include <tdeglobalsettings.h>
55 const int Kpgp::KeySelectionDialog::sCheckSelectionDelay = 250;
59 PassphraseDialog::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 );
92 PassphraseDialog::~PassphraseDialog()
96 TQString PassphraseDialog::passphrase()
98 return lineedit->password();
105 Config::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 );
252 Config::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);
280 KeySelectionDialog::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() ) );
395 KeySelectionDialog::~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;
409 KeyID KeySelectionDialog::key()
const
411 if( mListView->isMultiSelection() || mKeyIds.isEmpty() )
414 return mKeyIds.first();
418 void 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 );
491 TQString 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 ) )
556 TQString 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 );
603 int 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:
664 void 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 ) );
717 KeySelectionDialog::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";
784 KeySelectionDialog::getKeyId(
const TQListViewItem* lvi )
const
789 if( 0 != lvi->parent() ) {
790 keyId = lvi->parent()->text(0).local8Bit();
793 keyId = lvi->text(0).local8Bit();
801 void 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 );
850 void KeySelectionDialog::slotSelectionChanged( TQListViewItem * lvi )
852 slotCheckSelection( lvi );
856 void KeySelectionDialog::slotSelectionChanged()
858 kdDebug(5100) <<
"KeySelectionDialog::slotSelectionChanged()\n";
863 mCheckSelectionTimer->start( sCheckSelectionDelay );
867 void 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() ) );
996 bool 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;
1029 void 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() ) );
1043 void KeySelectionDialog::slotRecheckKey()
1045 if( 0 != mCurrentContextMenuItem ) {
1047 keyAdmissibility( mCurrentContextMenuItem, ForceTrustCheck );
1049 slotCheckSelection( mCurrentContextMenuItem );
1053 void KeySelectionDialog::slotOk()
1055 if( mCheckSelectionTimer->isActive() ) {
1056 slotCheckSelection();
1058 mStartSearchTimer->stop();
1063 void KeySelectionDialog::slotCancel()
1065 mCheckSelectionTimer->stop();
1066 mStartSearchTimer->stop();
1071 void KeySelectionDialog::slotSearch(
const TQString & text )
1073 mSearchText = text.stripWhiteSpace().upper();
1074 mStartSearchTimer->start( sCheckSelectionDelay,
true );
1077 void 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 );
1099 void 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 ) );
1110 void 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 ) );
1124 void 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 ) );
1137 bool 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 ) {
1152 void KeySelectionDialog::showAllItems()
1154 for ( TQListViewItem * item = mListView->firstChild() ; item ; item = item->nextSibling() )
1155 item->setVisible(
true );
1159 KeyRequester::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 ) );
1197 KeyRequester::~KeyRequester() {
1201 KeyIDList KeyRequester::keyIDs()
const {
1205 void 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 );
1221 void KeyRequester::slotDialogButtonClicked() {
1222 Module * pgp = Module::getKpgp();
1225 kdWarning() <<
"Kpgp::KeyRequester::slotDialogButtonClicked(): No pgp module found!" << endl;
1229 setKeyIDs( keyRequestHook( pgp ) );
1233 void KeyRequester::slotEraseButtonClicked() {
1239 void KeyRequester::setDialogCaption(
const TQString & caption ) {
1240 mDialogCaption = caption;
1243 void KeyRequester::setDialogMessage(
const TQString & msg ) {
1244 mDialogMessage = msg;
1247 bool KeyRequester::isMultipleKeysEnabled()
const {
1251 void KeyRequester::setMultipleKeysEnabled(
bool multi ) {
1252 if ( multi == mMulti )
return;
1254 if ( !multi && mKeys.size() > 1 )
1255 mKeys.erase( ++mKeys.begin(), mKeys.end() );
1260 int KeyRequester::allowedKeys()
const {
1261 return mAllowedKeys;
1264 void KeyRequester::setAllowedKeys(
int allowedKeys ) {
1265 mAllowedKeys = allowedKeys;
1269 PublicKeyRequester::PublicKeyRequester( TQWidget * parent,
bool multi,
1270 unsigned int allowed,
const char * name )
1271 : KeyRequester( parent, multi, allowed & ~SecretKeys, name )
1276 PublicKeyRequester::~PublicKeyRequester() {
1280 KeyIDList PublicKeyRequester::keyRequestHook( Module * pgp )
const {
1282 return pgp->selectPublicKeys( mDialogCaption, mDialogMessage, mKeys, TQString(), mAllowedKeys );
1285 SecretKeyRequester::SecretKeyRequester( TQWidget * parent,
bool multi,
1286 unsigned int allowed,
const char * name )
1287 : KeyRequester( parent, multi, allowed & ~PublicKeys, name )
1292 SecretKeyRequester::~SecretKeyRequester() {
1296 KeyIDList SecretKeyRequester::keyRequestHook( Module * pgp )
const {
1299 KeyID keyID = mKeys.first();
1300 keyID = pgp->selectSecretKey( mDialogCaption, mDialogMessage, keyID );
1302 return KeyIDList() << keyID;
1308 KeyApprovalDialog::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 ) );
1511 KeyApprovalDialog::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" ) );
1563 KeyApprovalDialog::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 );
1606 KeyApprovalDialog::slotCancel()
1614 CipherTextDialog::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);
1648 void 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 ) );
1663 void KeyRequester::virtual_hook(
int,
void* ) {}
1665 void PublicKeyRequester::virtual_hook(
int id,
void* data ) {
1666 base::virtual_hook(
id, data );
1669 void SecretKeyRequester::virtual_hook(
int id,
void* data ) {
1670 base::virtual_hook(
id, data );
1677 #include "kpgpui.moc"