00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <qvgroupbox.h>
00022 #include <qvbox.h>
00023 #include <qlabel.h>
00024 #include <qwhatsthis.h>
00025 #include <qtooltip.h>
00026 #include <qapplication.h>
00027 #include <qtextcodec.h>
00028 #include <qdatetime.h>
00029 #include <qpixmap.h>
00030 #include <qlayout.h>
00031 #include <qtimer.h>
00032 #include <qpopupmenu.h>
00033 #include <qregexp.h>
00034
00035 #include <klocale.h>
00036 #include <kpassdlg.h>
00037 #include <kcharsets.h>
00038 #include <kseparator.h>
00039 #include <kiconloader.h>
00040 #include <klistview.h>
00041 #include <kconfigbase.h>
00042 #include <kconfig.h>
00043 #include <kprogress.h>
00044 #include <kapplication.h>
00045 #include <kwin.h>
00046 #if KDE_IS_VERSION( 3, 1, 90 )
00047 #include <kglobalsettings.h>
00048 #endif
00049
00050 #include "kpgp.h"
00051 #include "kpgpui.h"
00052 #include "kpgpkey.h"
00053
00054 #include <assert.h>
00055 #include <string.h>
00056
00057 const int Kpgp::KeySelectionDialog::sCheckSelectionDelay = 250;
00058
00059 namespace Kpgp {
00060
00061 PassphraseDialog::PassphraseDialog( QWidget *parent,
00062 const QString &caption, bool modal,
00063 const QString &keyID )
00064 :KDialogBase( parent, 0, modal, caption, Ok|Cancel )
00065 {
00066 QHBox *hbox = makeHBoxMainWidget();
00067 hbox->setSpacing( spacingHint() );
00068 hbox->setMargin( marginHint() );
00069
00070 QLabel *label = new QLabel(hbox);
00071 label->setPixmap( BarIcon("pgp-keys") );
00072
00073 QWidget *rightArea = new QWidget( hbox );
00074 QVBoxLayout *vlay = new QVBoxLayout( rightArea, 0, spacingHint() );
00075
00076 if (keyID.isNull())
00077 label = new QLabel(i18n("Please enter your OpenPGP passphrase:"),rightArea);
00078 else
00079 label = new QLabel(i18n("Please enter the OpenPGP passphrase for\n\"%1\":").arg(keyID),
00080 rightArea);
00081 lineedit = new KPasswordEdit( rightArea );
00082 lineedit->setEchoMode(QLineEdit::Password);
00083 lineedit->setMinimumWidth( fontMetrics().maxWidth()*20 );
00084 lineedit->setFocus();
00085 connect( lineedit, SIGNAL(returnPressed()), this, SLOT(slotOk()) );
00086
00087 vlay->addWidget( label );
00088 vlay->addWidget( lineedit );
00089
00090 disableResize();
00091 }
00092
00093
00094 PassphraseDialog::~PassphraseDialog()
00095 {
00096 }
00097
00098 const char * PassphraseDialog::passphrase()
00099 {
00100 return lineedit->password();
00101 }
00102
00103
00104
00105
00106
00107 Config::Config( QWidget *parent, const char *name, bool encrypt )
00108 : QWidget( parent, name ), pgp( Module::getKpgp() )
00109 {
00110 QGroupBox * group;
00111 QLabel * label;
00112 QString msg;
00113
00114
00115 QVBoxLayout *topLayout = new QVBoxLayout( this, 0, KDialog::spacingHint() );
00116
00117 group = new QVGroupBox( i18n("Warning"), this );
00118 group->layout()->setSpacing( KDialog::spacingHint() );
00119
00120
00121 label = new QLabel( i18n("Please check if encryption really "
00122 "works before you start using it seriously. Also note that attachments "
00123 "are not encrypted by the PGP/GPG module."), group );
00124
00125 QFont labelFont = label->font();
00126 labelFont.setBold( true );
00127 label->setFont( labelFont );
00128
00129 label->setAlignment( AlignLeft|WordBreak );
00130
00131
00132 topLayout->addWidget( group );
00133
00134 group = new QVGroupBox( i18n("Encryption Tool"), this );
00135 group->layout()->setSpacing( KDialog::spacingHint() );
00136
00137 QHBox * hbox = new QHBox( group );
00138 label = new QLabel( i18n("Select encryption tool to &use:"), hbox );
00139 toolCombo = new QComboBox( false, hbox );
00140 toolCombo->insertStringList( QStringList()
00141 << i18n("Autodetect")
00142 << i18n("GnuPG - Gnu Privacy Guard")
00143 << i18n("PGP Version 2.x")
00144 << i18n("PGP Version 5.x")
00145 << i18n("PGP Version 6.x")
00146 << i18n("Do not use any encryption tool") );
00147 label->setBuddy( toolCombo );
00148 hbox->setStretchFactor( toolCombo, 1 );
00149 connect( toolCombo, SIGNAL( activated( int ) ),
00150 this, SIGNAL( changed( void ) ) );
00151
00152
00153 topLayout->addWidget( group );
00154
00155 mpOptionsGroupBox = new QVGroupBox( i18n("Options"), this );
00156 mpOptionsGroupBox->layout()->setSpacing( KDialog::spacingHint() );
00157 storePass = new QCheckBox( i18n("&Keep passphrase in memory"),
00158 mpOptionsGroupBox );
00159 connect( storePass, SIGNAL( toggled( bool ) ),
00160 this, SIGNAL( changed( void ) ) );
00161 msg = i18n( "<qt><p>When this option is enabled, the passphrase of your "
00162 "private key will be remembered by the application as long "
00163 "as the application is running. Thus you will only have to "
00164 "enter the passphrase once.</p><p>Be aware that this could be a "
00165 "security risk. If you leave your computer, others "
00166 "can use it to send signed messages and/or read your encrypted "
00167 "messages. If a core dump occurs, the contents of your RAM will "
00168 "be saved onto disk, including your passphrase.</p>"
00169 "<p>Note that when using KMail, this setting only applies "
00170 "if you are not using gpg-agent. It is also ignored "
00171 "if you are using crypto plugins.</p></qt>" );
00172 QWhatsThis::add( storePass, msg );
00173 if( encrypt ) {
00174 encToSelf = new QCheckBox( i18n("Always encr&ypt to self"),
00175 mpOptionsGroupBox );
00176 connect( encToSelf, SIGNAL( toggled( bool ) ),
00177 this, SIGNAL( changed( void ) ) );
00178
00179 msg = i18n( "<qt><p>When this option is enabled, the message/file "
00180 "will not only be encrypted with the receiver's public key, "
00181 "but also with your key. This will enable you to decrypt the "
00182 "message/file at a later time. This is generally a good idea."
00183 "</p></qt>" );
00184 QWhatsThis::add( encToSelf, msg );
00185 }
00186 else
00187 encToSelf = 0;
00188 showCipherText = new QCheckBox( i18n("&Show signed/encrypted text after "
00189 "composing"),
00190 mpOptionsGroupBox );
00191 connect( showCipherText, SIGNAL( toggled( bool ) ),
00192 this, SIGNAL( changed( void ) ) );
00193
00194 msg = i18n( "<qt><p>When this option is enabled, the signed/encrypted text "
00195 "will be shown in a separate window, enabling you to know how "
00196 "it will look before it is sent. This is a good idea when "
00197 "you are verifying that your encryption system works.</p></qt>" );
00198 QWhatsThis::add( showCipherText, msg );
00199 if( encrypt ) {
00200 showKeyApprovalDlg = new QCheckBox( i18n("Always show the encryption "
00201 "keys &for approval"),
00202 mpOptionsGroupBox );
00203 connect( showKeyApprovalDlg, SIGNAL( toggled( bool ) ),
00204 this, SIGNAL( changed( void ) ) );
00205 msg = i18n( "<qt><p>When this option is enabled, the application will "
00206 "always show you a list of public keys from which you can "
00207 "choose the one it will use for encryption. If it is off, "
00208 "the application will only show the dialog if it cannot find "
00209 "the right key or if there are several which could be used. "
00210 "</p></qt>" );
00211 QWhatsThis::add( showKeyApprovalDlg, msg );
00212 }
00213 else
00214 showKeyApprovalDlg = 0;
00215
00216 topLayout->addWidget( mpOptionsGroupBox );
00217
00218 topLayout->addStretch(1);
00219
00220 setValues();
00221 }
00222
00223
00224 Config::~Config()
00225 {
00226 }
00227
00228 void
00229 Config::setValues()
00230 {
00231
00232 storePass->setChecked( pgp->storePassPhrase() );
00233 if( 0 != encToSelf )
00234 encToSelf->setChecked( pgp->encryptToSelf() );
00235 showCipherText->setChecked( pgp->showCipherText() );
00236 if( 0 != showKeyApprovalDlg )
00237 showKeyApprovalDlg->setChecked( pgp->showKeyApprovalDlg() );
00238
00239 int type = 0;
00240 switch (pgp->pgpType) {
00241
00242 default:
00243 case Module::tAuto: type = 0; break;
00244 case Module::tGPG: type = 1; break;
00245 case Module::tPGP2: type = 2; break;
00246 case Module::tPGP5: type = 3; break;
00247 case Module::tPGP6: type = 4; break;
00248 case Module::tOff: type = 5; break;
00249 }
00250 toolCombo->setCurrentItem( type );
00251 }
00252
00253 void
00254 Config::applySettings()
00255 {
00256 pgp->setStorePassPhrase(storePass->isChecked());
00257 if( 0 != encToSelf )
00258 pgp->setEncryptToSelf(encToSelf->isChecked());
00259 pgp->setShowCipherText(showCipherText->isChecked());
00260 if( 0 != showKeyApprovalDlg )
00261 pgp->setShowKeyApprovalDlg( showKeyApprovalDlg->isChecked() );
00262
00263 Module::PGPType type;
00264 switch ( toolCombo->currentItem() ) {
00265
00266 default:
00267 case 0: type = Module::tAuto; break;
00268 case 1: type = Module::tGPG; break;
00269 case 2: type = Module::tPGP2; break;
00270 case 3: type = Module::tPGP5; break;
00271 case 4: type = Module::tPGP6; break;
00272 case 5: type = Module::tOff; break;
00273 }
00274 pgp->pgpType = type;
00275
00276 pgp->writeConfig(true);
00277 }
00278
00279
00280
00281
00282 KeySelectionDialog::KeySelectionDialog( const KeyList& keyList,
00283 const QString& title,
00284 const QString& text,
00285 const KeyIDList& keyIds,
00286 const bool rememberChoice,
00287 const unsigned int allowedKeys,
00288 const bool extendedSelection,
00289 QWidget *parent, const char *name,
00290 bool modal )
00291 : KDialogBase( parent, name, modal, title, Default|Ok|Cancel, Ok ),
00292 mRememberCB( 0 ),
00293 mAllowedKeys( allowedKeys ),
00294 mCurrentContextMenuItem( 0 )
00295 {
00296 if ( kapp )
00297 KWin::setIcons( winId(), kapp->icon(), kapp->miniIcon() );
00298 Kpgp::Module *pgp = Kpgp::Module::getKpgp();
00299 KConfig *config = pgp->getConfig();
00300 KConfigGroup dialogConfig( config, "Key Selection Dialog" );
00301
00302 QSize defaultSize( 580, 400 );
00303 QSize dialogSize = dialogConfig.readSizeEntry( "Dialog size", &defaultSize );
00304
00305 resize( dialogSize );
00306
00307 mCheckSelectionTimer = new QTimer( this );
00308 mStartSearchTimer = new QTimer( this );
00309
00310
00311 mKeyGoodPix = new QPixmap( UserIcon("key_ok") );
00312 mKeyBadPix = new QPixmap( UserIcon("key_bad") );
00313 mKeyUnknownPix = new QPixmap( UserIcon("key_unknown") );
00314 mKeyValidPix = new QPixmap( UserIcon("key") );
00315
00316 QFrame *page = makeMainWidget();
00317 QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() );
00318
00319 if( !text.isEmpty() ) {
00320 QLabel *label = new QLabel( page );
00321 label->setText( text );
00322 topLayout->addWidget( label );
00323 }
00324
00325 QHBoxLayout * hlay = new QHBoxLayout( topLayout );
00326 QLineEdit * le = new QLineEdit( page );
00327 hlay->addWidget( new QLabel( le, i18n("&Search for:"), page ) );
00328 hlay->addWidget( le, 1 );
00329 le->setFocus();
00330
00331 connect( le, SIGNAL(textChanged(const QString&)),
00332 this, SLOT(slotSearch(const QString&)) );
00333 connect( mStartSearchTimer, SIGNAL(timeout()), SLOT(slotFilter()) );
00334
00335 mListView = new KListView( page );
00336 mListView->addColumn( i18n("Key ID") );
00337 mListView->addColumn( i18n("User ID") );
00338 mListView->setAllColumnsShowFocus( true );
00339 mListView->setResizeMode( QListView::LastColumn );
00340 mListView->setRootIsDecorated( true );
00341 mListView->setShowSortIndicator( true );
00342 mListView->setSorting( 1, true );
00343 mListView->setShowToolTips( true );
00344 if( extendedSelection ) {
00345 mListView->setSelectionMode( QListView::Extended );
00346
00347 }
00348 topLayout->addWidget( mListView, 10 );
00349
00350 if (rememberChoice) {
00351 mRememberCB = new QCheckBox( i18n("Remember choice"), page );
00352 topLayout->addWidget( mRememberCB );
00353 QWhatsThis::add(mRememberCB,
00354 i18n("<qt><p>If you check this box your choice will "
00355 "be stored and you will not be asked again."
00356 "</p></qt>"));
00357 }
00358
00359 initKeylist( keyList, keyIds );
00360
00361 QListViewItem *lvi;
00362 if( extendedSelection ) {
00363 lvi = mListView->currentItem();
00364 slotCheckSelection();
00365 }
00366 else {
00367 lvi = mListView->selectedItem();
00368 slotCheckSelection( lvi );
00369 }
00370
00371
00372 if( lvi != 0 )
00373 mListView->center( mListView->contentsX(), mListView->itemPos( lvi ) );
00374
00375 if( extendedSelection ) {
00376 connect( mCheckSelectionTimer, SIGNAL( timeout() ),
00377 this, SLOT( slotCheckSelection() ) );
00378 connect( mListView, SIGNAL( selectionChanged() ),
00379 this, SLOT( slotSelectionChanged() ) );
00380 }
00381 else {
00382 connect( mListView, SIGNAL( selectionChanged( QListViewItem* ) ),
00383 this, SLOT( slotSelectionChanged( QListViewItem* ) ) );
00384 }
00385 connect( mListView, SIGNAL( doubleClicked ( QListViewItem *, const QPoint &, int ) ), this, SLOT( accept() ) );
00386
00387 connect( mListView, SIGNAL( contextMenuRequested( QListViewItem*,
00388 const QPoint&, int ) ),
00389 this, SLOT( slotRMB( QListViewItem*, const QPoint&, int ) ) );
00390
00391 setButtonText( KDialogBase::Default, i18n("&Reread Keys") );
00392 connect( this, SIGNAL( defaultClicked() ),
00393 this, SLOT( slotRereadKeys() ) );
00394 }
00395
00396
00397 KeySelectionDialog::~KeySelectionDialog()
00398 {
00399 Kpgp::Module *pgp = Kpgp::Module::getKpgp();
00400 KConfig *config = pgp->getConfig();
00401 KConfigGroup dialogConfig( config, "Key Selection Dialog" );
00402 dialogConfig.writeEntry( "Dialog size", size() );
00403 config->sync();
00404 delete mKeyGoodPix;
00405 delete mKeyBadPix;
00406 delete mKeyUnknownPix;
00407 delete mKeyValidPix;
00408 }
00409
00410
00411 KeyID KeySelectionDialog::key() const
00412 {
00413 if( mListView->isMultiSelection() || mKeyIds.isEmpty() )
00414 return KeyID();
00415 else
00416 return mKeyIds.first();
00417 }
00418
00419
00420 void KeySelectionDialog::initKeylist( const KeyList& keyList,
00421 const KeyIDList& keyIds )
00422 {
00423 QListViewItem* firstSelectedItem = 0;
00424 mKeyIds.clear();
00425 mListView->clear();
00426
00427
00428 for( KeyListIterator it( keyList ); it.current(); ++it ) {
00429 KeyID curKeyId = (*it)->primaryKeyID();
00430
00431 QListViewItem* primaryUserID = new QListViewItem( mListView, curKeyId,
00432 (*it)->primaryUserID() );
00433
00434
00435 if( keyIds.findIndex( curKeyId ) != -1 ) {
00436 if( 0 == firstSelectedItem ) {
00437 firstSelectedItem = primaryUserID;
00438 }
00439 mListView->setSelected( primaryUserID, true );
00440 mKeyIds.append( curKeyId );
00441 }
00442 primaryUserID->setOpen( false );
00443
00444
00445 switch( keyValidity( *it ) ) {
00446 case 0:
00447 primaryUserID->setPixmap( 0, *mKeyUnknownPix );
00448 break;
00449 case 1:
00450 primaryUserID->setPixmap( 0, *mKeyValidPix );
00451 break;
00452 case 2:
00453 primaryUserID->setPixmap( 0, *mKeyGoodPix );
00454 break;
00455 case -1:
00456 primaryUserID->setPixmap( 0, *mKeyBadPix );
00457 break;
00458 }
00459
00460 QListViewItem* childItem;
00461
00462 childItem = new QListViewItem( primaryUserID, "",
00463 i18n( "Fingerprint: %1" )
00464 .arg( beautifyFingerprint( (*it)->primaryFingerprint() ) ) );
00465 if( primaryUserID->isSelected() && mListView->isMultiSelection() ) {
00466 mListView->setSelected( childItem, true );
00467 }
00468
00469 childItem = new QListViewItem( primaryUserID, "", keyInfo( *it ) );
00470 if( primaryUserID->isSelected() && mListView->isMultiSelection() ) {
00471 mListView->setSelected( childItem, true );
00472 }
00473
00474 UserIDList userIDs = (*it)->userIDs();
00475 UserIDListIterator uidit( userIDs );
00476 if( *uidit ) {
00477 ++uidit;
00478 for( ; *uidit; ++uidit ) {
00479 childItem = new QListViewItem( primaryUserID, "", (*uidit)->text() );
00480 if( primaryUserID->isSelected() && mListView->isMultiSelection() ) {
00481 mListView->setSelected( childItem, true );
00482 }
00483 }
00484 }
00485 }
00486
00487 if( 0 != firstSelectedItem ) {
00488 mListView->setCurrentItem( firstSelectedItem );
00489 }
00490 }
00491
00492
00493 QString KeySelectionDialog::keyInfo( const Kpgp::Key *key ) const
00494 {
00495 QString status, remark;
00496 if( key->revoked() ) {
00497 status = i18n("Revoked");
00498 }
00499 else if( key->expired() ) {
00500 status = i18n("Expired");
00501 }
00502 else if( key->disabled() ) {
00503 status = i18n("Disabled");
00504 }
00505 else if( key->invalid() ) {
00506 status = i18n("Invalid");
00507 }
00508 else {
00509 Validity keyTrust = key->keyTrust();
00510 switch( keyTrust ) {
00511 case KPGP_VALIDITY_UNDEFINED:
00512 status = i18n("Undefined trust");
00513 break;
00514 case KPGP_VALIDITY_NEVER:
00515 status = i18n("Untrusted");
00516 break;
00517 case KPGP_VALIDITY_MARGINAL:
00518 status = i18n("Marginally trusted");
00519 break;
00520 case KPGP_VALIDITY_FULL:
00521 status = i18n("Fully trusted");
00522 break;
00523 case KPGP_VALIDITY_ULTIMATE:
00524 status = i18n("Ultimately trusted");
00525 break;
00526 case KPGP_VALIDITY_UNKNOWN:
00527 default:
00528 status = i18n("Unknown");
00529 }
00530 if( key->secret() ) {
00531 remark = i18n("Secret key available");
00532 }
00533 else if( !key->canEncrypt() ) {
00534 remark = i18n("Sign only key");
00535 }
00536 else if( !key->canSign() ) {
00537 remark = i18n("Encryption only key");
00538 }
00539 }
00540
00541 QDateTime dt;
00542 dt.setTime_t( key->creationDate() );
00543 if( remark.isEmpty() ) {
00544 return " " + i18n("creation date and status of an OpenPGP key",
00545 "Creation date: %1, Status: %2")
00546 .arg( KGlobal::locale()->formatDate( dt.date(), true ) )
00547 .arg( status );
00548 }
00549 else {
00550 return " " + i18n("creation date, status and remark of an OpenPGP key",
00551 "Creation date: %1, Status: %2 (%3)")
00552 .arg( KGlobal::locale()->formatDate( dt.date(), true ) )
00553 .arg( status )
00554 .arg( remark );
00555 }
00556 }
00557
00558 QString KeySelectionDialog::beautifyFingerprint( const QCString& fpr ) const
00559 {
00560 QCString result;
00561
00562 if( 40 == fpr.length() ) {
00563
00564
00565 result.fill( ' ', 50 );
00566 memcpy( result.data() , fpr.data() , 4 );
00567 memcpy( result.data() + 5, fpr.data() + 4, 4 );
00568 memcpy( result.data() + 10, fpr.data() + 8, 4 );
00569 memcpy( result.data() + 15, fpr.data() + 12, 4 );
00570 memcpy( result.data() + 20, fpr.data() + 16, 4 );
00571 memcpy( result.data() + 26, fpr.data() + 20, 4 );
00572 memcpy( result.data() + 31, fpr.data() + 24, 4 );
00573 memcpy( result.data() + 36, fpr.data() + 28, 4 );
00574 memcpy( result.data() + 41, fpr.data() + 32, 4 );
00575 memcpy( result.data() + 46, fpr.data() + 36, 4 );
00576 }
00577 else if( 32 == fpr.length() ) {
00578
00579
00580 result.fill( ' ', 48 );
00581 memcpy( result.data() , fpr.data() , 2 );
00582 memcpy( result.data() + 3, fpr.data() + 2, 2 );
00583 memcpy( result.data() + 6, fpr.data() + 4, 2 );
00584 memcpy( result.data() + 9, fpr.data() + 6, 2 );
00585 memcpy( result.data() + 12, fpr.data() + 8, 2 );
00586 memcpy( result.data() + 15, fpr.data() + 10, 2 );
00587 memcpy( result.data() + 18, fpr.data() + 12, 2 );
00588 memcpy( result.data() + 21, fpr.data() + 14, 2 );
00589 memcpy( result.data() + 25, fpr.data() + 16, 2 );
00590 memcpy( result.data() + 28, fpr.data() + 18, 2 );
00591 memcpy( result.data() + 31, fpr.data() + 20, 2 );
00592 memcpy( result.data() + 34, fpr.data() + 22, 2 );
00593 memcpy( result.data() + 37, fpr.data() + 24, 2 );
00594 memcpy( result.data() + 40, fpr.data() + 26, 2 );
00595 memcpy( result.data() + 43, fpr.data() + 28, 2 );
00596 memcpy( result.data() + 46, fpr.data() + 30, 2 );
00597 }
00598 else {
00599 result = fpr;
00600 }
00601
00602 return result;
00603 }
00604
00605 int KeySelectionDialog::keyValidity( const Kpgp::Key *key ) const
00606 {
00607 if( 0 == key ) {
00608 return -1;
00609 }
00610
00611 if( ( mAllowedKeys & EncrSignKeys ) == EncryptionKeys ) {
00612
00613 if( ( mAllowedKeys & ValidKeys ) && !key->isValidEncryptionKey() ) {
00614
00615 return -1;
00616 }
00617 else if( !key->canEncrypt() ) {
00618 return -1;
00619 }
00620 }
00621 else if( ( mAllowedKeys & EncrSignKeys ) == SigningKeys ) {
00622
00623 if( ( mAllowedKeys & ValidKeys ) && !key->isValidSigningKey() ) {
00624
00625 return -1;
00626 }
00627 else if( !key->canSign() ) {
00628 return -1;
00629 }
00630 }
00631 else if( ( mAllowedKeys & ValidKeys ) && !key->isValid() ) {
00632
00633 return -1;
00634 }
00635
00636
00637 int val = 0;
00638 Validity keyTrust = key->keyTrust();
00639 switch( keyTrust ) {
00640 case KPGP_VALIDITY_NEVER:
00641 val = -1;
00642 break;
00643 case KPGP_VALIDITY_MARGINAL:
00644 case KPGP_VALIDITY_FULL:
00645 case KPGP_VALIDITY_ULTIMATE:
00646 val = 2;
00647 break;
00648 case KPGP_VALIDITY_UNDEFINED:
00649 if( mAllowedKeys & TrustedKeys ) {
00650
00651 val = -1;
00652 }
00653 else {
00654 val = 1;
00655 }
00656 break;
00657 case KPGP_VALIDITY_UNKNOWN:
00658 default:
00659 val = 0;
00660 }
00661
00662 return val;
00663 }
00664
00665
00666 void KeySelectionDialog::updateKeyInfo( const Kpgp::Key* key,
00667 QListViewItem* lvi ) const
00668 {
00669 if( 0 == lvi ) {
00670 return;
00671 }
00672
00673 if( lvi->parent() != 0 ) {
00674 lvi = lvi->parent();
00675 }
00676
00677 if( 0 == key ) {
00678
00679 while( lvi->firstChild() ) {
00680 kdDebug(5100) << "Deleting '" << lvi->firstChild()->text( 1 ) << "'\n";
00681 delete lvi->firstChild();
00682 }
00683 kdDebug(5100) << "Deleting key 0x" << lvi->text( 0 ) << " ("
00684 << lvi->text( 1 ) << ")\n";
00685 delete lvi;
00686 lvi = 0;
00687 return;
00688 }
00689
00690
00691 switch( keyValidity( key ) ) {
00692 case 0:
00693 lvi->setPixmap( 0, *mKeyUnknownPix );
00694 break;
00695 case 1:
00696 lvi->setPixmap( 0, *mKeyValidPix );
00697 break;
00698 case 2:
00699 lvi->setPixmap( 0, *mKeyGoodPix );
00700 break;
00701 case -1:
00702 lvi->setPixmap( 0, *mKeyBadPix );
00703 break;
00704 }
00705
00706
00707
00708
00709 for( lvi = lvi->firstChild(); lvi; lvi = lvi->nextSibling() ) {
00710 if( lvi->text( 1 ).at(0) == ' ' ) {
00711 lvi->setText( 1, keyInfo( key ) );
00712 break;
00713 }
00714 }
00715 }
00716
00717
00718 int
00719 KeySelectionDialog::keyAdmissibility( QListViewItem* lvi,
00720 TrustCheckMode trustCheckMode ) const
00721 {
00722
00723
00724
00725
00726
00727
00728 if( mAllowedKeys == AllKeys ) {
00729 return 1;
00730 }
00731
00732 Kpgp::Module *pgp = Kpgp::Module::getKpgp();
00733
00734 if( 0 == pgp ) {
00735 return 0;
00736 }
00737
00738 KeyID keyId = getKeyId( lvi );
00739 Kpgp::Key* key = pgp->publicKey( keyId );
00740
00741 if( 0 == key ) {
00742 return 0;
00743 }
00744
00745 int val = 0;
00746 if( trustCheckMode == ForceTrustCheck ) {
00747 key = pgp->rereadKey( keyId, true );
00748 updateKeyInfo( key, lvi );
00749 val = keyValidity( key );
00750 }
00751 else {
00752 val = keyValidity( key );
00753 if( ( trustCheckMode == AllowExpensiveTrustCheck ) && ( 0 == val ) ) {
00754 key = pgp->rereadKey( keyId, true );
00755 updateKeyInfo( key, lvi );
00756 val = keyValidity( key );
00757 }
00758 }
00759
00760 switch( val ) {
00761 case -1:
00762 return -1;
00763 break;
00764 case 0:
00765 return 0;
00766 break;
00767 case 1:
00768 if( mAllowedKeys & TrustedKeys ) {
00769
00770 return -1;
00771 }
00772 return 1;
00773 break;
00774 case 2:
00775 return 1;
00776 break;
00777 default:
00778 kdDebug( 5100 ) << "Error: Invalid key status value.\n";
00779 }
00780
00781 return 0;
00782 }
00783
00784
00785 KeyID
00786 KeySelectionDialog::getKeyId( const QListViewItem* lvi ) const
00787 {
00788 KeyID keyId;
00789
00790 if( 0 != lvi ) {
00791 if( 0 != lvi->parent() ) {
00792 keyId = lvi->parent()->text(0).local8Bit();
00793 }
00794 else {
00795 keyId = lvi->text(0).local8Bit();
00796 }
00797 }
00798
00799 return keyId;
00800 }
00801
00802
00803 void KeySelectionDialog::slotRereadKeys()
00804 {
00805 Kpgp::Module *pgp = Kpgp::Module::getKpgp();
00806
00807 if( 0 == pgp ) {
00808 return;
00809 }
00810
00811 KeyList keys;
00812
00813 if( PublicKeys & mAllowedKeys ) {
00814 pgp->readPublicKeys( true );
00815 keys = pgp->publicKeys();
00816 }
00817 else {
00818 pgp->readSecretKeys( true );
00819 keys = pgp->secretKeys();
00820 }
00821
00822
00823 int offsetY = mListView->contentsY();
00824
00825 if( mListView->isMultiSelection() ) {
00826 disconnect( mListView, SIGNAL( selectionChanged() ),
00827 this, SLOT( slotSelectionChanged() ) );
00828 }
00829 else {
00830 disconnect( mListView, SIGNAL( selectionChanged( QListViewItem * ) ),
00831 this, SLOT( slotSelectionChanged( QListViewItem * ) ) );
00832 }
00833
00834 initKeylist( keys, KeyIDList( mKeyIds ) );
00835 slotFilter();
00836
00837 if( mListView->isMultiSelection() ) {
00838 connect( mListView, SIGNAL( selectionChanged() ),
00839 this, SLOT( slotSelectionChanged() ) );
00840 slotSelectionChanged();
00841 }
00842 else {
00843 connect( mListView, SIGNAL( selectionChanged( QListViewItem * ) ),
00844 this, SLOT( slotSelectionChanged( QListViewItem * ) ) );
00845 }
00846
00847
00848 mListView->setContentsPos( 0, offsetY );
00849 }
00850
00851
00852 void KeySelectionDialog::slotSelectionChanged( QListViewItem * lvi )
00853 {
00854 slotCheckSelection( lvi );
00855 }
00856
00857
00858 void KeySelectionDialog::slotSelectionChanged()
00859 {
00860 kdDebug(5100) << "KeySelectionDialog::slotSelectionChanged()\n";
00861
00862
00863
00864
00865 mCheckSelectionTimer->start( sCheckSelectionDelay );
00866 }
00867
00868
00869 void KeySelectionDialog::slotCheckSelection( QListViewItem* plvi )
00870 {
00871 kdDebug(5100) << "KeySelectionDialog::slotCheckSelection()\n";
00872
00873 if( !mListView->isMultiSelection() ) {
00874 mKeyIds.clear();
00875 KeyID keyId = getKeyId( plvi );
00876 if( !keyId.isEmpty() ) {
00877 mKeyIds.append( keyId );
00878 enableButtonOK( 1 == keyAdmissibility( plvi, AllowExpensiveTrustCheck ) );
00879 }
00880 else {
00881 enableButtonOK( false );
00882 }
00883 }
00884 else {
00885 mCheckSelectionTimer->stop();
00886
00887
00888
00889 disconnect( mListView, SIGNAL( selectionChanged() ),
00890 this, SLOT( slotSelectionChanged() ) );
00891
00892 KeyIDList newKeyIdList;
00893 QValueList<QListViewItem*> keysToBeChecked;
00894
00895 bool keysAllowed = true;
00896 enum { UNKNOWN, SELECTED, DESELECTED } userAction = UNKNOWN;
00897
00898 for( QListViewItem *lvi = mListView->firstChild();
00899 0 != lvi;
00900 lvi = lvi->nextSibling() ) {
00901
00902
00903
00904
00905
00906
00907 int itemCount = 1 + lvi->childCount();
00908 int selectedCount = lvi->isSelected() ? 1 : 0;
00909 for( QListViewItem *clvi = lvi->firstChild();
00910 0 != clvi;
00911 clvi = clvi->nextSibling() ) {
00912 if( clvi->isSelected() ) {
00913 ++selectedCount;
00914 }
00915 }
00916
00917 if( userAction == UNKNOWN ) {
00918
00919
00920
00921
00922 if( 0 < selectedCount ) {
00923 if( -1 == mKeyIds.findIndex( lvi->text(0).local8Bit() ) ) {
00924
00925
00926 kdDebug(5100) << "selectedCount: "<<selectedCount<<"/"<<itemCount
00927 <<" --- User selected key "<<lvi->text(0)<<endl;
00928 userAction = SELECTED;
00929 }
00930 else if( ( itemCount > selectedCount ) &&
00931 ( -1 != mKeyIds.findIndex( lvi->text(0).local8Bit() ) ) ) {
00932
00933
00934 kdDebug(5100) << "selectedCount: "<<selectedCount<<"/"<<itemCount
00935 <<" --- User deselected key "<<lvi->text(0)<<endl;
00936 userAction = DESELECTED;
00937 }
00938 }
00939 }
00940 if( itemCount == selectedCount ) {
00941
00942 KeyID keyId = lvi->text(0).local8Bit();
00943 newKeyIdList.append( keyId );
00944 int admissibility = keyAdmissibility( lvi, NoExpensiveTrustCheck );
00945 if( -1 == admissibility ) {
00946 keysAllowed = false;
00947 }
00948 else if ( 0 == admissibility ) {
00949 keysToBeChecked.append( lvi );
00950 }
00951 }
00952 else if( 0 < selectedCount ) {
00953
00954
00955 if( userAction == SELECTED ) {
00956
00957 mListView->setSelected( lvi, true );
00958 for( QListViewItem *clvi = lvi->firstChild();
00959 0 != clvi;
00960 clvi = clvi->nextSibling() ) {
00961 mListView->setSelected( clvi, true );
00962 }
00963
00964 KeyID keyId = lvi->text(0).local8Bit();
00965 newKeyIdList.append( keyId );
00966 int admissibility = keyAdmissibility( lvi, NoExpensiveTrustCheck );
00967 if( -1 == admissibility ) {
00968 keysAllowed = false;
00969 }
00970 else if ( 0 == admissibility ) {
00971 keysToBeChecked.append( lvi );
00972 }
00973 }
00974 else {
00975
00976 mListView->setSelected( lvi, false );
00977 for( QListViewItem *clvi = lvi->firstChild();
00978 0 != clvi;
00979 clvi = clvi->nextSibling() ) {
00980 mListView->setSelected( clvi, false );
00981 }
00982 }
00983 }
00984 }
00985 kdDebug(5100) << "Selected keys: " << newKeyIdList.toStringList().join(", ") << endl;
00986 mKeyIds = newKeyIdList;
00987 if( !keysToBeChecked.isEmpty() ) {
00988 keysAllowed = keysAllowed && checkKeys( keysToBeChecked );
00989 }
00990 enableButtonOK( keysAllowed );
00991
00992 connect( mListView, SIGNAL( selectionChanged() ),
00993 this, SLOT( slotSelectionChanged() ) );
00994 }
00995 }
00996
00997
00998 bool KeySelectionDialog::checkKeys( const QValueList<QListViewItem*>& keys ) const
00999 {
01000 KProgressDialog* pProgressDlg = 0;
01001 bool keysAllowed = true;
01002 kdDebug(5100) << "Checking keys...\n";
01003
01004 pProgressDlg = new KProgressDialog( 0, 0, i18n("Checking Keys"),
01005 i18n("Checking key 0xMMMMMMMM..."),
01006 true );
01007 pProgressDlg->setAllowCancel( false );
01008 pProgressDlg->progressBar()->setTotalSteps( keys.count() );
01009 pProgressDlg->setMinimumDuration( 1000 );
01010 pProgressDlg->show();
01011
01012 for( QValueList<QListViewItem*>::ConstIterator it = keys.begin();
01013 it != keys.end();
01014 ++it ) {
01015 kdDebug(5100) << "Checking key 0x" << getKeyId( *it ) << "...\n";
01016 pProgressDlg->setLabel( i18n("Checking key 0x%1...")
01017 .arg( getKeyId( *it ) ) );
01018 kapp->processEvents();
01019 keysAllowed = keysAllowed && ( -1 != keyAdmissibility( *it, AllowExpensiveTrustCheck ) );
01020 pProgressDlg->progressBar()->advance( 1 );
01021 kapp->processEvents();
01022 }
01023
01024 delete pProgressDlg;
01025 pProgressDlg = 0;
01026
01027 return keysAllowed;
01028 }
01029
01030
01031 void KeySelectionDialog::slotRMB( QListViewItem* lvi, const QPoint& pos, int )
01032 {
01033 if( !lvi ) {
01034 return;
01035 }
01036
01037 mCurrentContextMenuItem = lvi;
01038
01039 QPopupMenu menu(this);
01040 menu.insertItem( i18n( "Recheck Key" ), this, SLOT( slotRecheckKey() ) );
01041 menu.exec( pos );
01042 }
01043
01044
01045 void KeySelectionDialog::slotRecheckKey()
01046 {
01047 if( 0 != mCurrentContextMenuItem ) {
01048
01049 keyAdmissibility( mCurrentContextMenuItem, ForceTrustCheck );
01050
01051 slotCheckSelection( mCurrentContextMenuItem );
01052 }
01053 }
01054
01055 void KeySelectionDialog::slotOk()
01056 {
01057 if( mCheckSelectionTimer->isActive() ) {
01058 slotCheckSelection();
01059 }
01060 mStartSearchTimer->stop();
01061 accept();
01062 }
01063
01064
01065 void KeySelectionDialog::slotCancel()
01066 {
01067 mCheckSelectionTimer->stop();
01068 mStartSearchTimer->stop();
01069 mKeyIds.clear();
01070 reject();
01071 }
01072
01073 void KeySelectionDialog::slotSearch( const QString & text )
01074 {
01075 mSearchText = text.stripWhiteSpace().upper();
01076 mStartSearchTimer->start( sCheckSelectionDelay, true );
01077 }
01078
01079 void KeySelectionDialog::slotFilter()
01080 {
01081 if ( mSearchText.isEmpty() ) {
01082 showAllItems();
01083 return;
01084 }
01085
01086
01087 QRegExp keyIdRegExp( "(?:0x)?[A-F0-9]{1,8}", false );
01088 if ( keyIdRegExp.exactMatch( mSearchText ) ) {
01089 if ( mSearchText.startsWith( "0X" ) )
01090
01091 filterByKeyID( mSearchText.mid( 2 ) );
01092 else
01093
01094 filterByKeyIDOrUID( mSearchText );
01095 } else {
01096
01097 filterByUID( mSearchText );
01098 }
01099 }
01100
01101 void KeySelectionDialog::filterByKeyID( const QString & keyID )
01102 {
01103 assert( keyID.length() <= 8 );
01104 assert( !keyID.isEmpty() );
01105 if ( keyID.isEmpty() )
01106 showAllItems();
01107 else
01108 for ( QListViewItem * item = mListView->firstChild() ; item ; item = item->nextSibling() )
01109 item->setVisible( item->text( 0 ).upper().startsWith( keyID ) );
01110 }
01111
01112 void KeySelectionDialog::filterByKeyIDOrUID( const QString & str )
01113 {
01114 assert( !str.isEmpty() );
01115
01116
01117 QRegExp rx( "\\b" + QRegExp::escape( str ), false );
01118
01119 for ( QListViewItem * item = mListView->firstChild() ; item ; item = item->nextSibling() )
01120 item->setVisible( item->text( 0 ).upper().startsWith( str )
01121 || rx.search( item->text( 1 ) ) >= 0
01122 || anyChildMatches( item, rx ) );
01123
01124 }
01125
01126 void KeySelectionDialog::filterByUID( const QString & str )
01127 {
01128 assert( !str.isEmpty() );
01129
01130
01131 QRegExp rx( "\\b" + QRegExp::escape( str ), false );
01132
01133 for ( QListViewItem * item = mListView->firstChild() ; item ; item = item->nextSibling() )
01134 item->setVisible( rx.search( item->text( 1 ) ) >= 0
01135 || anyChildMatches( item, rx ) );
01136 }
01137
01138
01139 bool KeySelectionDialog::anyChildMatches( const QListViewItem * item, QRegExp & rx ) const
01140 {
01141 if ( !item )
01142 return false;
01143
01144 QListViewItem * stop = item->nextSibling();
01145
01146 for ( QListViewItemIterator it( item->firstChild() ) ; it.current() && it.current() != stop ; ++it )
01147 if ( rx.search( it.current()->text( 1 ) ) >= 0 ) {
01148
01149 return true;
01150 }
01151 return false;
01152 }
01153
01154 void KeySelectionDialog::showAllItems()
01155 {
01156 for ( QListViewItem * item = mListView->firstChild() ; item ; item = item->nextSibling() )
01157 item->setVisible( true );
01158 }
01159
01160
01161 KeyRequester::KeyRequester( QWidget * parent, bool multipleKeys,
01162 unsigned int allowedKeys, const char * name )
01163 : QWidget( parent, name ),
01164 mDialogCaption( i18n("OpenPGP Key Selection") ),
01165 mDialogMessage( i18n("Please select an OpenPGP key to use.") ),
01166 mMulti( multipleKeys ),
01167 mAllowedKeys( allowedKeys ),
01168 d( 0 )
01169 {
01170 QHBoxLayout * hlay = new QHBoxLayout( this, 0, KDialog::spacingHint() );
01171
01172
01173 mLabel = new QLabel( this );
01174 mLabel->setFrameStyle( QFrame::Panel | QFrame::Sunken );
01175
01176
01177 mEraseButton = new QPushButton( this );
01178 mEraseButton->setAutoDefault( false );
01179 mEraseButton->setSizePolicy( QSizePolicy( QSizePolicy::Minimum,
01180 QSizePolicy::Minimum ) );
01181 mEraseButton->setPixmap( SmallIcon( "clear_left" ) );
01182 QToolTip::add( mEraseButton, i18n("Clear") );
01183
01184
01185 mDialogButton = new QPushButton( i18n("Change..."), this );
01186 mDialogButton->setAutoDefault( false );
01187
01188 hlay->addWidget( mLabel, 1 );
01189 hlay->addWidget( mEraseButton );
01190 hlay->addWidget( mDialogButton );
01191
01192 connect( mEraseButton, SIGNAL(clicked()), SLOT(slotEraseButtonClicked()) );
01193 connect( mDialogButton, SIGNAL(clicked()), SLOT(slotDialogButtonClicked()) );
01194
01195 setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding,
01196 QSizePolicy::Fixed ) );
01197 }
01198
01199 KeyRequester::~KeyRequester() {
01200
01201 }
01202
01203 KeyIDList KeyRequester::keyIDs() const {
01204 return mKeys;
01205 }
01206
01207 void KeyRequester::setKeyIDs( const KeyIDList & keyIDs ) {
01208 mKeys = keyIDs;
01209 if ( mKeys.empty() ) {
01210 mLabel->clear();
01211 return;
01212 }
01213 if ( mKeys.size() > 1 )
01214 setMultipleKeysEnabled( true );
01215
01216 QString s = mKeys.toStringList().join(", ");
01217
01218 mLabel->setText( s );
01219 QToolTip::remove( mLabel );
01220 QToolTip::add( mLabel, s );
01221 }
01222
01223 void KeyRequester::slotDialogButtonClicked() {
01224 Module * pgp = Module::getKpgp();
01225
01226 if ( !pgp ) {
01227 kdWarning() << "Kpgp::KeyRequester::slotDialogButtonClicked(): No pgp module found!" << endl;
01228 return;
01229 }
01230
01231 setKeyIDs( keyRequestHook( pgp ) );
01232 emit changed();
01233 }
01234
01235 void KeyRequester::slotEraseButtonClicked() {
01236 mKeys.clear();
01237 mLabel->clear();
01238 emit changed();
01239 }
01240
01241 void KeyRequester::setDialogCaption( const QString & caption ) {
01242 mDialogCaption = caption;
01243 }
01244
01245 void KeyRequester::setDialogMessage( const QString & msg ) {
01246 mDialogMessage = msg;
01247 }
01248
01249 bool KeyRequester::isMultipleKeysEnabled() const {
01250 return mMulti;
01251 }
01252
01253 void KeyRequester::setMultipleKeysEnabled( bool multi ) {
01254 if ( multi == mMulti ) return;
01255
01256 if ( !multi && mKeys.size() > 1 )
01257 mKeys.erase( ++mKeys.begin(), mKeys.end() );
01258
01259 mMulti = multi;
01260 }
01261
01262 int KeyRequester::allowedKeys() const {
01263 return mAllowedKeys;
01264 }
01265
01266 void KeyRequester::setAllowedKeys( int allowedKeys ) {
01267 mAllowedKeys = allowedKeys;
01268 }
01269
01270
01271 PublicKeyRequester::PublicKeyRequester( QWidget * parent, bool multi,
01272 unsigned int allowed, const char * name )
01273 : KeyRequester( parent, multi, allowed & ~SecretKeys, name )
01274 {
01275
01276 }
01277
01278 PublicKeyRequester::~PublicKeyRequester() {
01279
01280 }
01281
01282 KeyIDList PublicKeyRequester::keyRequestHook( Module * pgp ) const {
01283 assert( pgp );
01284 return pgp->selectPublicKeys( mDialogCaption, mDialogMessage, mKeys, QString::null, mAllowedKeys );
01285 }
01286
01287 SecretKeyRequester::SecretKeyRequester( QWidget * parent, bool multi,
01288 unsigned int allowed, const char * name )
01289 : KeyRequester( parent, multi, allowed & ~PublicKeys, name )
01290 {
01291
01292 }
01293
01294 SecretKeyRequester::~SecretKeyRequester() {
01295
01296 }
01297
01298 KeyIDList SecretKeyRequester::keyRequestHook( Module * pgp ) const {
01299 assert( pgp );
01300
01301 KeyID keyID = mKeys.first();
01302 keyID = pgp->selectSecretKey( mDialogCaption, mDialogMessage, keyID );
01303
01304 return KeyIDList() << keyID;
01305 }
01306
01307
01308
01309
01310 KeyApprovalDialog::KeyApprovalDialog( const QStringList& addresses,
01311 const QValueVector<KeyIDList>& keyIDs,
01312 const int allowedKeys,
01313 QWidget *parent, const char *name,
01314 bool modal )
01315 : KDialogBase( parent, name, modal, i18n("Encryption Key Approval"),
01316 Ok|Cancel, Ok ),
01317 mKeys( keyIDs ),
01318 mAllowedKeys( allowedKeys ),
01319 mPrefsChanged( false )
01320 {
01321 Kpgp::Module *pgp = Kpgp::Module::getKpgp();
01322
01323 if( pgp == 0 )
01324 return;
01325
01326
01327
01328
01329
01330
01331 QFrame *page = makeMainWidget();
01332 QVBoxLayout *topLayout = new QVBoxLayout( page, 0, KDialog::spacingHint() );
01333
01334 QLabel *label = new QLabel( i18n("The following keys will be used for "
01335 "encryption:"),
01336 page );
01337 topLayout->addWidget( label );
01338
01339 QScrollView* sv = new QScrollView( page );
01340 sv->setResizePolicy( QScrollView::AutoOneFit );
01341 topLayout->addWidget( sv );
01342 QVBox* bigvbox = new QVBox( sv->viewport() );
01343 bigvbox->setMargin( KDialog::marginHint() );
01344 bigvbox->setSpacing( KDialog::spacingHint() );
01345 sv->addChild( bigvbox );
01346
01347 QButtonGroup *mChangeButtonGroup = new QButtonGroup( bigvbox );
01348 mChangeButtonGroup->hide();
01349 mAddressLabels.resize( addresses.count() );
01350 mKeyIdsLabels.resize( keyIDs.size() );
01351
01352 mEncrPrefCombos.resize( addresses.count() );
01353
01354
01355 if( pgp->encryptToSelf() ) {
01356 mEncryptToSelf = 1;
01357 QHBox* hbox = new QHBox( bigvbox );
01358 new QLabel( i18n("Your keys:"), hbox );
01359 QLabel* keyidsL = new QLabel( hbox );
01360 if( keyIDs[0].isEmpty() ) {
01361 keyidsL->setText( i18n("<none> means 'no key'", "<none>") );
01362 }
01363 else {
01364 keyidsL->setText( "0x" + keyIDs[0].toStringList().join( "\n0x" ) );
01365 }
01366 keyidsL->setFrameStyle( QFrame::Panel | QFrame::Sunken );
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378 QPushButton *button = new QPushButton( i18n("Change..."), hbox );
01379 mChangeButtonGroup->insert( button );
01380 button->setAutoDefault( false );
01381 hbox->setStretchFactor( keyidsL, 10 );
01382 mKeyIdsLabels.insert( 0, keyidsL );
01383
01384
01385
01386 new KSeparator( Horizontal, bigvbox );
01387 }
01388 else {
01389 mEncryptToSelf = 0;
01390
01391 mKeyIdsLabels.insert( 0, 0 );
01392
01393 }
01394
01395 QStringList::ConstIterator ait;
01396 QValueVector<KeyIDList>::const_iterator kit;
01397 int i;
01398 for( ait = addresses.begin(), kit = keyIDs.begin(), i = 0;
01399 ( ait != addresses.end() ) && ( kit != keyIDs.end() );
01400 ++ait, ++kit, ++i ) {
01401 if( i == 0 ) {
01402 ++kit;
01403 }
01404 else {
01405 new KSeparator( Horizontal, bigvbox );
01406 }
01407
01408 QHBox *hbox = new QHBox( bigvbox );
01409 new QLabel( i18n("Recipient:"), hbox );
01410 QLabel *addressL = new QLabel( *ait, hbox );
01411 hbox->setStretchFactor( addressL, 10 );
01412 mAddressLabels.insert( i, addressL );
01413
01414 hbox = new QHBox( bigvbox );
01415 new QLabel( i18n("Encryption keys:"), hbox );
01416 QLabel* keyidsL = new QLabel( hbox );
01417 if( (*kit).isEmpty() ) {
01418 keyidsL->setText( i18n("<none> means 'no key'", "<none>") );
01419 }
01420 else {
01421 keyidsL->setText( "0x" + (*kit).toStringList().join( "\n0x" ) );
01422 }
01423 keyidsL->setFrameStyle( QFrame::Panel | QFrame::Sunken );
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435 QPushButton *button = new QPushButton( i18n("Change..."), hbox );
01436 mChangeButtonGroup->insert( button );
01437 button->setAutoDefault( false );
01438 hbox->setStretchFactor( keyidsL, 10 );
01439 mKeyIdsLabels.insert( i + 1, keyidsL );
01440
01441
01442
01443 hbox = new QHBox( bigvbox );
01444 new QLabel( i18n("Encryption preference:"), hbox );
01445 QComboBox *encrPrefCombo = new QComboBox( hbox );
01446 encrPrefCombo->insertItem( i18n("<none>") );
01447 encrPrefCombo->insertItem( i18n("Never Encrypt with This Key") );
01448 encrPrefCombo->insertItem( i18n("Always Encrypt with This Key") );
01449 encrPrefCombo->insertItem( i18n("Encrypt Whenever Encryption is Possible") );
01450 encrPrefCombo->insertItem( i18n("Always Ask") );
01451 encrPrefCombo->insertItem( i18n("Ask Whenever Encryption is Possible") );
01452
01453 EncryptPref encrPref = pgp->encryptionPreference( *ait );
01454 switch( encrPref ) {
01455 case NeverEncrypt:
01456 encrPrefCombo->setCurrentItem( 1 );
01457 break;
01458 case AlwaysEncrypt:
01459 encrPrefCombo->setCurrentItem( 2 );
01460 break;
01461 case AlwaysEncryptIfPossible:
01462 encrPrefCombo->setCurrentItem( 3 );
01463 break;
01464 case AlwaysAskForEncryption:
01465 encrPrefCombo->setCurrentItem( 4 );
01466 break;
01467 case AskWheneverPossible:
01468 encrPrefCombo->setCurrentItem( 5 );
01469 break;
01470 default:
01471 encrPrefCombo->setCurrentItem( 0 );
01472 }
01473 connect( encrPrefCombo, SIGNAL(activated(int)),
01474 this, SLOT(slotPrefsChanged(int)) );
01475 mEncrPrefCombos.insert( i, encrPrefCombo );
01476 }
01477 connect( mChangeButtonGroup, SIGNAL(clicked(int)),
01478 this, SLOT(slotChangeEncryptionKey(int)) );
01479
01480
01481 int dialogWidth = marginHint()
01482 + sv->frameWidth()
01483 + bigvbox->sizeHint().width()
01484 + sv->verticalScrollBar()->sizeHint().width()
01485 + sv->frameWidth()
01486 + marginHint()
01487 + 2;
01488
01489 int dialogHeight = marginHint()
01490 + label->sizeHint().height()
01491 + topLayout->spacing()
01492 + sv->frameWidth()
01493 + bigvbox->sizeHint().height()
01494 + sv->horizontalScrollBar()->sizeHint().height()
01495 + sv->frameWidth()
01496 + topLayout->spacing()
01497 + actionButton( KDialogBase::Cancel )->sizeHint().height()
01498 + marginHint()
01499 + 2;
01500
01501 QRect desk = KGlobalSettings::desktopGeometry(this);
01502 int screenWidth = desk.width();
01503 if( dialogWidth > 3*screenWidth/4 )
01504 dialogWidth = 3*screenWidth/4;
01505 int screenHeight = desk.height();
01506 if( dialogHeight > 7*screenHeight/8 )
01507 dialogHeight = 7*screenHeight/8;
01508
01509 setInitialSize( QSize( dialogWidth, dialogHeight ) );
01510 }
01511
01512 void
01513 KeyApprovalDialog::slotChangeEncryptionKey( int nr )
01514 {
01515 Kpgp::Module *pgp = Kpgp::Module::getKpgp();
01516
01517 kdDebug(5100)<<"Key approval dialog size is "
01518 <<width()<<"x"<<height()<<endl;
01519
01520 if( pgp == 0 )
01521 return;
01522
01523 if( !mEncryptToSelf )
01524 nr++;
01525 KeyIDList keyIds = mKeys[nr];
01526 if( nr == 0 ) {
01527 keyIds = pgp->selectPublicKeys( i18n("Encryption Key Selection"),
01528 i18n("if in your language something like "
01529 "'key(s)' isn't possible please "
01530 "use the plural in the translation",
01531 "Select the key(s) which should "
01532 "be used to encrypt the message "
01533 "to yourself."),
01534 keyIds,
01535 "",
01536 mAllowedKeys );
01537 }
01538 else {
01539 keyIds = pgp->selectPublicKeys( i18n("Encryption Key Selection"),
01540 i18n("if in your language something like "
01541 "'key(s)' isn't possible please "
01542 "use the plural in the translation",
01543 "Select the key(s) which should "
01544 "be used to encrypt the message "
01545 "for\n%1")
01546 .arg( mAddressLabels[nr-1]->text() ),
01547 keyIds,
01548 mAddressLabels[nr-1]->text(),
01549 mAllowedKeys );
01550 }
01551 if( !keyIds.isEmpty() ) {
01552 mKeys[nr] = keyIds;
01553 QLabel* keyidsL = mKeyIdsLabels[nr];
01554 keyidsL->setText( "0x" + keyIds.toStringList().join( "\n0x" ) );
01555
01556
01557
01558
01559
01560 }
01561 }
01562
01563
01564 void
01565 KeyApprovalDialog::slotOk()
01566 {
01567 Kpgp::Module *pgp = Kpgp::Module::getKpgp();
01568
01569 if( pgp == 0 ) {
01570 accept();
01571 return;
01572 }
01573
01574 if( mPrefsChanged ) {
01575
01576 for( unsigned int i = 0; i < mAddressLabels.size(); i++ ) {
01577
01578 EncryptPref encrPref;
01579 switch( mEncrPrefCombos[i]->currentItem() ) {
01580 case 1:
01581 encrPref = NeverEncrypt;
01582 break;
01583 case 2:
01584 encrPref = AlwaysEncrypt;
01585 break;
01586 case 3:
01587 encrPref = AlwaysEncryptIfPossible;
01588 break;
01589 case 4:
01590 encrPref = AlwaysAskForEncryption;
01591 break;
01592 case 5:
01593 encrPref = AskWheneverPossible;
01594 break;
01595 default:
01596 case 0:
01597 encrPref = UnknownEncryptPref;
01598 }
01599 pgp->setEncryptionPreference( mAddressLabels[i]->text(), encrPref );
01600 }
01601 }
01602
01603 accept();
01604 }
01605
01606
01607 void
01608 KeyApprovalDialog::slotCancel()
01609 {
01610 reject();
01611 }
01612
01613
01614
01615
01616 CipherTextDialog::CipherTextDialog( const QCString & text,
01617 const QCString & charset, QWidget *parent,
01618 const char *name, bool modal )
01619 :KDialogBase( parent, name, modal, i18n("OpenPGP Information"), Ok|Cancel, Ok)
01620 {
01621
01622 QFrame *page = makeMainWidget();
01623 QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() );
01624
01625 QLabel *label = new QLabel( page );
01626 label->setText(i18n("Result of the last encryption/sign operation:"));
01627 topLayout->addWidget( label );
01628
01629 mEditBox = new QMultiLineEdit( page );
01630 mEditBox->setReadOnly(true);
01631 topLayout->addWidget( mEditBox, 10 );
01632
01633 QString unicodeText;
01634 if (charset.isEmpty())
01635 unicodeText = QString::fromLocal8Bit(text.data());
01636 else {
01637 bool ok=true;
01638 QTextCodec *codec = KGlobal::charsets()->codecForName(charset, ok);
01639 if(!ok)
01640 unicodeText = QString::fromLocal8Bit(text.data());
01641 else
01642 unicodeText = codec->toUnicode(text.data(), text.length());
01643 }
01644
01645 mEditBox->setText(unicodeText);
01646
01647 setMinimumSize();
01648 }
01649
01650 void CipherTextDialog::setMinimumSize()
01651 {
01652
01653
01654 for ( int i = 0; i < mEditBox->paragraphs(); i++ )
01655 (void) mEditBox->paragraphRect( i );
01656
01657 mEditBox->setMinimumHeight( mEditBox->fontMetrics().lineSpacing() * 25 );
01658
01659 int textWidth = mEditBox->contentsWidth() + 30;
01660
01661
01662 #if KDE_IS_VERSION( 3, 1, 90 )
01663 int maxWidth = KGlobalSettings::desktopGeometry(parentWidget()).width()-100;
01664 #else
01665 KConfig gc("kdeglobals", false, false);
01666 gc.setGroup("Windows");
01667 int maxWidth;
01668 if (QApplication::desktop()->isVirtualDesktop() &&
01669 gc.readBoolEntry("XineramaEnabled", true) &&
01670 gc.readBoolEntry("XineramaPlacementEnabled", true)) {
01671 maxWidth = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(parentWidget())).width()-100;
01672 } else {
01673 maxWidth = QApplication::desktop()->geometry().width()-100;
01674 }
01675 #endif
01676
01677 mEditBox->setMinimumWidth( QMIN( textWidth, maxWidth ) );
01678 }
01679
01680 void KeyRequester::virtual_hook( int, void* ) {}
01681
01682 void PublicKeyRequester::virtual_hook( int id, void* data ) {
01683 base::virtual_hook( id, data );
01684 }
01685
01686 void SecretKeyRequester::virtual_hook( int id, void* data ) {
01687 base::virtual_hook( id, data );
01688 }
01689
01690 }
01691
01692
01693
01694 #include "kpgpui.moc"