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"