4 Copyright (C) 2001,2002 the KPGP authors
5 See file AUTHORS.kpgp for details
7 This file is part of KPGP, the KDE PGP/GnuPG support library.
9 KPGP is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 #include <QApplication>
34 #include <QVBoxLayout>
35 #include <QHBoxLayout>
36 #include <QProgressBar>
37 #include <QButtonGroup>
40 #include <QTreeWidget>
41 #include <QHeaderView>
42 #include <QScrollArea>
44 #include <QAbstractTextDocumentLayout>
47 #include <kconfiggroup.h>
49 #include <kpassworddialog.h>
50 #include <kcharsets.h>
51 #include <kseparator.h>
52 #include <kiconloader.h>
53 #include <kconfigbase.h>
55 #include <kprogressdialog.h>
56 #include <kwindowsystem.h>
57 #include <kpushbutton.h>
58 #include <kglobalsettings.h>
59 #include <klineedit.h>
62 #include <string.h> // for memcpy(3)
64 #ifndef QT_NO_TREEWIDGET
65 const int Kpgp::KeySelectionDialog::sCheckSelectionDelay
= 250;
70 PassphraseDialog::PassphraseDialog( QWidget
*parent
,
71 const QString
&caption
,
72 const QString
&keyID
)
73 :KPasswordDialog( parent
)
75 setCaption( caption
);
76 setButtons( Ok
|Cancel
);
78 setPixmap( BarIcon("dialog-password") );
81 setPrompt(i18n("Please enter your OpenPGP passphrase:"));
83 setPrompt(i18n("Please enter the OpenPGP passphrase for\n\"%1\":", keyID
) );
87 PassphraseDialog::~PassphraseDialog()
91 QString
PassphraseDialog::passphrase()
97 // ------------------------------------------------------------------------
98 // Forbidden accels for KMail: AC GH OP
100 Config::Config( QWidget
*parent
, bool encrypt
)
101 : QWidget( parent
), pgp( Module::getKpgp() )
108 QVBoxLayout
*topLayout
= new QVBoxLayout( this );
109 topLayout
->setSpacing( KDialog::spacingHint() );
110 topLayout
->setMargin( 0 );
112 group
= new QGroupBox( i18n("Warning"), this );
113 QVBoxLayout
*lay
= new QVBoxLayout(group
);
114 lay
->setSpacing( KDialog::spacingHint() );
115 // (mmutz) work around Qt label bug in 3.0.0 (and possibly later):
116 // 1. Don't use rich text: No <qt><b>...</b></qt>
117 label
= new QLabel( i18n("Please check if encryption really "
118 "works before you start using it seriously. Also note that attachments "
119 "are not encrypted by the PGP/GPG module."), group
);
120 label
->setWordWrap( true );
121 lay
->addWidget( label
);
122 // 2. instead, set the font to bold:
123 QFont labelFont
= label
->font();
124 labelFont
.setBold( true );
125 label
->setFont( labelFont
);
126 // 3. and activate wordwarp:
127 // end; to remove the workaround, add <qt><b>..</b></qt> around the
128 // text and remove lines QFont... -> label->setAlignment(...).
129 topLayout
->addWidget( group
);
130 group
= new QGroupBox( i18n("Encryption Tool"), this );
131 lay
= new QVBoxLayout(group
);
132 lay
->setSpacing( KDialog::spacingHint() );
134 KHBox
* hbox
= new KHBox( group
);
135 lay
->addWidget( hbox
);
136 label
= new QLabel( i18n("Select encryption tool to &use:"), hbox
);
137 toolCombo
= new QComboBox( hbox
);
138 toolCombo
->setEditable( false );
139 toolCombo
->addItems( QStringList()
140 << i18n("Autodetect")
141 << i18n("GnuPG - Gnu Privacy Guard")
142 << i18n("PGP Version 2.x")
143 << i18n("PGP Version 5.x")
144 << i18n("PGP Version 6.x")
145 << i18n("Do not use any encryption tool") );
146 label
->setBuddy( toolCombo
);
147 hbox
->setStretchFactor( toolCombo
, 1 );
148 connect( toolCombo
, SIGNAL(activated(int)),
149 this, SIGNAL(changed()) );
150 // This is the place to add a KUrlRequester to be used for asking
151 // the user for the path to the executable...
152 topLayout
->addWidget( group
);
154 mpOptionsGroupBox
= new QGroupBox( i18n("Options"), this );
155 lay
= new QVBoxLayout( mpOptionsGroupBox
);
156 lay
->setSpacing( KDialog::spacingHint() );
157 storePass
= new QCheckBox( i18n("&Keep passphrase in memory"),
159 lay
->addWidget( storePass
);
160 connect( storePass
, SIGNAL(toggled(bool)),
161 this, SIGNAL(changed()) );
162 msg
= i18n( "<qt><p>When this option is enabled, the passphrase of your "
163 "private key will be remembered by the application as long "
164 "as the application is running. Thus you will only have to "
165 "enter the passphrase once.</p><p>Be aware that this could be a "
166 "security risk. If you leave your computer, others "
167 "can use it to send signed messages and/or read your encrypted "
168 "messages. If a core dump occurs, the contents of your RAM will "
169 "be saved onto disk, including your passphrase.</p>"
170 "<p>Note that when using KMail, this setting only applies "
171 "if you are not using gpg-agent. It is also ignored "
172 "if you are using crypto plugins.</p></qt>" );
173 storePass
->setWhatsThis( msg
);
175 encToSelf
= new QCheckBox( i18n("Always encr&ypt to self"),
177 connect( encToSelf
, SIGNAL(toggled(bool)),
178 this, SIGNAL(changed()) );
180 msg
= i18n( "<qt><p>When this option is enabled, the message/file "
181 "will not only be encrypted with the receiver's public key, "
182 "but also with your key. This will enable you to decrypt the "
183 "message/file at a later time. This is generally a good idea."
185 encToSelf
->setWhatsThis( msg
);
189 showCipherText
= new QCheckBox( i18n("&Show signed/encrypted text after "
191 lay
->addWidget( showCipherText
);
192 connect( showCipherText
, SIGNAL(toggled(bool)),
193 this, SIGNAL(changed()) );
195 msg
= i18n( "<qt><p>When this option is enabled, the signed/encrypted text "
196 "will be shown in a separate window, enabling you to know how "
197 "it will look before it is sent. This is a good idea when "
198 "you are verifying that your encryption system works.</p></qt>" );
199 showCipherText
->setWhatsThis( msg
);
201 showKeyApprovalDlg
= new QCheckBox( i18n("Always show the encryption "
202 "keys &for approval"));
203 lay
->addWidget( showKeyApprovalDlg
);
204 connect( showKeyApprovalDlg
, SIGNAL(toggled(bool)),
205 this, SIGNAL(changed()) );
206 msg
= i18n( "<qt><p>When this option is enabled, the application will "
207 "always show you a list of public keys from which you can "
208 "choose the one it will use for encryption. If it is off, "
209 "the application will only show the dialog if it cannot find "
210 "the right key or if there are several which could be used. "
212 showKeyApprovalDlg
->setWhatsThis( msg
);
215 showKeyApprovalDlg
= 0;
217 topLayout
->addWidget( mpOptionsGroupBox
);
219 topLayout
->addStretch(1);
221 setValues(); // is this needed by KNode, b/c for KMail, it's not.
232 // set default values
233 storePass
->setChecked( pgp
->storePassPhrase() );
235 encToSelf
->setChecked( pgp
->encryptToSelf() );
236 showCipherText
->setChecked( pgp
->showCipherText() );
237 if( 0 != showKeyApprovalDlg
)
238 showKeyApprovalDlg
->setChecked( pgp
->showKeyApprovalDlg() );
241 switch (pgp
->pgpType
) {
242 // translate Kpgp::Module enum to combobox' entries:
244 case Module::tAuto
: type
= 0; break;
245 case Module::tGPG
: type
= 1; break;
246 case Module::tPGP2
: type
= 2; break;
247 case Module::tPGP5
: type
= 3; break;
248 case Module::tPGP6
: type
= 4; break;
249 case Module::tOff
: type
= 5; break;
251 toolCombo
->setCurrentIndex( type
);
255 Config::applySettings()
257 pgp
->setStorePassPhrase(storePass
->isChecked());
259 pgp
->setEncryptToSelf(encToSelf
->isChecked());
260 pgp
->setShowCipherText(showCipherText
->isChecked());
261 if( 0 != showKeyApprovalDlg
)
262 pgp
->setShowKeyApprovalDlg( showKeyApprovalDlg
->isChecked() );
264 Module::PGPType type
;
265 switch ( toolCombo
->currentIndex() ) {
266 // convert combobox entry indices to Kpgp::Module constants:
268 case 0: type
= Module::tAuto
; break;
269 case 1: type
= Module::tGPG
; break;
270 case 2: type
= Module::tPGP2
; break;
271 case 3: type
= Module::tPGP5
; break;
272 case 4: type
= Module::tPGP6
; break;
273 case 5: type
= Module::tOff
; break;
277 pgp
->writeConfig(true);
280 #ifndef QT_NO_TREEWIDGET
283 // ------------------------------------------------------------------------
284 KeySelectionDialog::KeySelectionDialog( const KeyList
& keyList
,
285 const QString
& title
,
287 const KeyIDList
& keyIds
,
288 const bool rememberChoice
,
289 const unsigned int allowedKeys
,
290 const bool extendedSelection
,
294 mAllowedKeys( allowedKeys
),
295 mCurrentContextMenuItem( 0 )
298 setButtons( Default
|Ok
|Cancel
);
300 KWindowSystem::setIcons( winId(),
301 qApp
->windowIcon().pixmap( IconSize( KIconLoader::Desktop
),
302 IconSize( KIconLoader::Desktop
) ),
303 qApp
->windowIcon().pixmap( IconSize( KIconLoader::Small
),
304 IconSize( KIconLoader::Small
) ) );
306 Kpgp::Module
*pgp
= Kpgp::Module::getKpgp();
307 KConfig
*config
= pgp
->getConfig();
308 KConfigGroup
dialogConfig( config
, "Key Selection Dialog" );
310 QSize
defaultSize( 580, 400 );
311 QSize dialogSize
= dialogConfig
.readEntry( "Dialog size", defaultSize
);
313 resize( dialogSize
);
315 mCheckSelectionTimer
= new QTimer( this );
316 mStartSearchTimer
= new QTimer( this );
317 mStartSearchTimer
->setSingleShot( true );
319 // load the key status icons
320 mKeyGoodPix
= new QPixmap( UserIcon("key_ok") );
321 mKeyBadPix
= new QPixmap( UserIcon("key_bad") );
322 mKeyUnknownPix
= new QPixmap( UserIcon("key_unknown") );
323 mKeyValidPix
= new QPixmap( UserIcon("key") );
325 QFrame
*page
= new QFrame( this );
326 setMainWidget( page
);
327 QVBoxLayout
*topLayout
= new QVBoxLayout( page
);
328 topLayout
->setSpacing( spacingHint() );
329 topLayout
->setMargin( 0 );
331 if( !text
.isEmpty() ) {
332 QLabel
*label
= new QLabel( page
);
333 label
->setText( text
);
334 topLayout
->addWidget( label
);
337 QHBoxLayout
* hlay
= new QHBoxLayout(); // inherits spacing
338 topLayout
->addLayout( hlay
);
339 QLineEdit
* le
= new QLineEdit( page
);
340 QLabel
*label
= new QLabel( i18n("&Search for:"), page
);
341 label
->setBuddy( le
);
342 hlay
->addWidget( label
);
343 hlay
->addWidget( le
, 1 );
346 connect( le
, SIGNAL(textChanged(QString
)),
347 this, SLOT(slotSearch(QString
)) );
348 connect( mStartSearchTimer
, SIGNAL(timeout()), SLOT(slotFilter()) );
350 mListView
= new QTreeWidget( page
);
351 mListView
->setHeaderLabels( QStringList()
353 << i18n("User ID") );
354 mListView
->setAllColumnsShowFocus( true );
355 mListView
->header()->setStretchLastSection( true );
356 mListView
->setRootIsDecorated( true );
357 mListView
->setSortingEnabled( true );
358 mListView
->header()->setSortIndicatorShown( true );
359 mListView
->sortItems( 1, Qt::AscendingOrder
); // sort by User ID
360 // mListView->setShowToolTips( true );
361 if( extendedSelection
) {
362 mListView
->setSelectionMode( QTreeWidget::ExtendedSelection
);
363 //mListView->setSelectionMode( QListView::Multi );
365 topLayout
->addWidget( mListView
, 10 );
367 if (rememberChoice
) {
368 mRememberCB
= new QCheckBox( i18n("Remember choice"), page
);
369 topLayout
->addWidget( mRememberCB
);
370 mRememberCB
->setWhatsThis(
371 i18n("<qt><p>If you check this box your choice will "
372 "be stored and you will not be asked again."
376 initKeylist( keyList
, keyIds
);
378 QTreeWidgetItem
*lvi
= 0;
379 if( extendedSelection
) {
380 lvi
= mListView
->currentItem();
381 slotCheckSelection();
384 if ( mListView
->selectedItems().size() > 0 )
385 lvi
= mListView
->selectedItems().first();
386 slotCheckSelection( lvi
);
389 mListView
->scrollToItem( lvi
);
391 if( extendedSelection
) {
392 connect( mCheckSelectionTimer
, SIGNAL(timeout()),
393 this, SLOT(slotCheckSelection()) );
394 connect( mListView
, SIGNAL(itemSelectionChanged()),
395 this, SLOT(slotSelectionChanged()) );
398 connect( mListView
, SIGNAL(itemSelectionChanged()),
399 this, SLOT(slotSelectionChanged()) );
401 connect( mListView
, SIGNAL(itemDoubleClicked(QTreeWidgetItem
*,int)), this, SLOT(accept()) );
403 mListView
->setContextMenuPolicy( Qt::CustomContextMenu
);
404 connect( mListView
, SIGNAL(customContextMenuRequested(QPoint
)),
405 this, SLOT(slotRMB(QPoint
)) );
407 setButtonGuiItem( KDialog::Default
, KGuiItem(i18n("&Reread Keys")) );
408 connect( this, SIGNAL(defaultClicked()),
409 this, SLOT(slotRereadKeys()) );
410 connect(this, SIGNAL(okClicked()),SLOT(slotOk()));
411 connect(this,SIGNAL(cancelClicked()),SLOT(slotCancel()));
415 KeySelectionDialog::~KeySelectionDialog()
417 Kpgp::Module
*pgp
= Kpgp::Module::getKpgp();
418 KConfig
*config
= pgp
->getConfig();
419 KConfigGroup
dialogConfig( config
, "Key Selection Dialog" );
420 dialogConfig
.writeEntry( "Dialog size", size() );
424 delete mKeyUnknownPix
;
429 KeyID
KeySelectionDialog::key() const
431 if( mListView
->selectionMode() == QTreeWidget::ExtendedSelection
|| mKeyIds
.isEmpty() )
434 return mKeyIds
.first();
438 void KeySelectionDialog::initKeylist( const KeyList
& keyList
,
439 const KeyIDList
& keyIds
)
441 QTreeWidgetItem
* firstSelectedItem
= 0;
445 // build a list of all public keys
446 foreach ( Key
* key
, keyList
) {
447 KeyID curKeyId
= key
->primaryKeyID();
449 QTreeWidgetItem
* primaryUserID
= new QTreeWidgetItem( mListView
);
450 primaryUserID
->setText( 0, curKeyId
);
451 primaryUserID
->setText( 1, key
->primaryUserID() );
453 // select and open the given key
454 if( keyIds
.indexOf( curKeyId
) != -1 ) {
455 if( 0 == firstSelectedItem
) {
456 firstSelectedItem
= primaryUserID
;
458 primaryUserID
->setSelected( true );
459 mKeyIds
.append( curKeyId
);
461 primaryUserID
->setExpanded( false );
463 // set icon for this key
464 switch( keyValidity( key
) ) {
465 case 0: // the key's validity can't be determined
466 primaryUserID
->setData( 0, Qt::DecorationRole
, *mKeyUnknownPix
);
468 case 1: // key is valid but not trusted
469 primaryUserID
->setData( 0, Qt::DecorationRole
, *mKeyValidPix
);
471 case 2: // key is valid and trusted
472 primaryUserID
->setData( 0, Qt::DecorationRole
, *mKeyGoodPix
);
474 case -1: // key is invalid
475 primaryUserID
->setData( 0, Qt::DecorationRole
, *mKeyBadPix
);
479 QTreeWidgetItem
* childItem
;
481 childItem
= new QTreeWidgetItem( primaryUserID
);
482 childItem
->setText( 1, i18n( "Fingerprint: %1" , beautifyFingerprint( key
->primaryFingerprint() ) ) );
483 if( primaryUserID
->isSelected() && mListView
->selectionMode() == QTreeWidget::ExtendedSelection
) {
484 childItem
->setSelected( true );
487 childItem
= new QTreeWidgetItem( primaryUserID
);
488 childItem
->setText( 1, keyInfo( key
) );
489 if( primaryUserID
->isSelected() && mListView
->selectionMode() == QTreeWidget::ExtendedSelection
) {
490 childItem
->setSelected( true );
493 UserIDList userIDs
= key
->userIDs();
494 UserIDList::Iterator
uidit( userIDs
.begin() );
495 if( uidit
!= userIDs
.end() ) {
496 ++uidit
; // skip the primary user ID
497 for( ; uidit
!= userIDs
.end(); ++uidit
) {
498 childItem
= new QTreeWidgetItem( primaryUserID
);
499 childItem
->setText( 1, (*uidit
)->text() );
500 if( primaryUserID
->isSelected() && mListView
->selectionMode() == QTreeWidget::ExtendedSelection
) {
501 childItem
->setSelected( true );
507 if( 0 != firstSelectedItem
) {
508 mListView
->setCurrentItem( firstSelectedItem
);
513 QString
KeySelectionDialog::keyInfo( const Kpgp::Key
*key
) const
515 QString status
, remark
;
516 if( key
->revoked() ) {
517 status
= i18n("Revoked");
519 else if( key
->expired() ) {
520 status
= i18n("Expired");
522 else if( key
->disabled() ) {
523 status
= i18n("Disabled");
525 else if( key
->invalid() ) {
526 status
= i18n("Invalid");
529 Validity keyTrust
= key
->keyTrust();
531 case KPGP_VALIDITY_UNDEFINED
:
532 status
= i18n("Undefined trust");
534 case KPGP_VALIDITY_NEVER
:
535 status
= i18n("Untrusted");
537 case KPGP_VALIDITY_MARGINAL
:
538 status
= i18n("Marginally trusted");
540 case KPGP_VALIDITY_FULL
:
541 status
= i18n("Fully trusted");
543 case KPGP_VALIDITY_ULTIMATE
:
544 status
= i18n("Ultimately trusted");
546 case KPGP_VALIDITY_UNKNOWN
:
548 status
= i18n("Unknown");
550 if( key
->secret() ) {
551 remark
= i18n("Secret key available");
553 else if( !key
->canEncrypt() ) {
554 remark
= i18n("Sign only key");
556 else if( !key
->canSign() ) {
557 remark
= i18n("Encryption only key");
562 dt
.setTime_t( key
->creationDate() );
563 if( remark
.isEmpty() ) {
564 return ' ' + i18nc("creation date and status of an OpenPGP key",
565 "Creation date: %1, Status: %2",
566 KGlobal::locale()->formatDate( dt
.date(), KLocale::ShortDate
) ,
570 return ' ' + i18nc("creation date, status and remark of an OpenPGP key",
571 "Creation date: %1, Status: %2 (%3)",
572 KGlobal::locale()->formatDate( dt
.date(), KLocale::ShortDate
) ,
578 QString
KeySelectionDialog::beautifyFingerprint( const QByteArray
& fpr
) const
582 if( 40 == fpr
.length() ) {
583 // convert to this format:
584 // 0000 1111 2222 3333 4444 5555 6666 7777 8888 9999
585 result
.fill( ' ', 50 );
586 memcpy( result
.data() , fpr
.data() , 4 );
587 memcpy( result
.data() + 5, fpr
.data() + 4, 4 );
588 memcpy( result
.data() + 10, fpr
.data() + 8, 4 );
589 memcpy( result
.data() + 15, fpr
.data() + 12, 4 );
590 memcpy( result
.data() + 20, fpr
.data() + 16, 4 );
591 memcpy( result
.data() + 26, fpr
.data() + 20, 4 );
592 memcpy( result
.data() + 31, fpr
.data() + 24, 4 );
593 memcpy( result
.data() + 36, fpr
.data() + 28, 4 );
594 memcpy( result
.data() + 41, fpr
.data() + 32, 4 );
595 memcpy( result
.data() + 46, fpr
.data() + 36, 4 );
597 else if( 32 == fpr
.length() ) {
598 // convert to this format:
599 // 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF
600 result
.fill( ' ', 48 );
601 memcpy( result
.data() , fpr
.data() , 2 );
602 memcpy( result
.data() + 3, fpr
.data() + 2, 2 );
603 memcpy( result
.data() + 6, fpr
.data() + 4, 2 );
604 memcpy( result
.data() + 9, fpr
.data() + 6, 2 );
605 memcpy( result
.data() + 12, fpr
.data() + 8, 2 );
606 memcpy( result
.data() + 15, fpr
.data() + 10, 2 );
607 memcpy( result
.data() + 18, fpr
.data() + 12, 2 );
608 memcpy( result
.data() + 21, fpr
.data() + 14, 2 );
609 memcpy( result
.data() + 25, fpr
.data() + 16, 2 );
610 memcpy( result
.data() + 28, fpr
.data() + 18, 2 );
611 memcpy( result
.data() + 31, fpr
.data() + 20, 2 );
612 memcpy( result
.data() + 34, fpr
.data() + 22, 2 );
613 memcpy( result
.data() + 37, fpr
.data() + 24, 2 );
614 memcpy( result
.data() + 40, fpr
.data() + 26, 2 );
615 memcpy( result
.data() + 43, fpr
.data() + 28, 2 );
616 memcpy( result
.data() + 46, fpr
.data() + 30, 2 );
618 else { // unknown length of fingerprint
625 int KeySelectionDialog::keyValidity( const Kpgp::Key
*key
) const
631 if( ( mAllowedKeys
& EncrSignKeys
) == EncryptionKeys
) {
632 // only encryption keys are allowed
633 if( ( mAllowedKeys
& ValidKeys
) && !key
->isValidEncryptionKey() ) {
634 // only valid encryption keys are allowed
637 else if( !key
->canEncrypt() ) {
641 else if( ( mAllowedKeys
& EncrSignKeys
) == SigningKeys
) {
642 // only signing keys are allowed
643 if( ( mAllowedKeys
& ValidKeys
) && !key
->isValidSigningKey() ) {
644 // only valid signing keys are allowed
647 else if( !key
->canSign() ) {
651 else if( ( mAllowedKeys
& ValidKeys
) && !key
->isValid() ) {
652 // only valid keys are allowed
656 // check the key's trust
658 Validity keyTrust
= key
->keyTrust();
660 case KPGP_VALIDITY_NEVER
:
663 case KPGP_VALIDITY_MARGINAL
:
664 case KPGP_VALIDITY_FULL
:
665 case KPGP_VALIDITY_ULTIMATE
:
668 case KPGP_VALIDITY_UNDEFINED
:
669 if( mAllowedKeys
& TrustedKeys
) {
670 // only trusted keys are allowed
677 case KPGP_VALIDITY_UNKNOWN
:
686 void KeySelectionDialog::updateKeyInfo( const Kpgp::Key
* key
,
687 QTreeWidgetItem
* lvi
) const
693 if( lvi
->parent() != 0 ) {
698 // the key doesn't exist anymore -> delete it from the list view
699 while( lvi
->childCount() ) {
700 kDebug( 5326 ) <<"Deleting '" << lvi
->child( 0 )->text( 1 ) <<"'";
701 delete lvi
->takeChild( 0 );
703 kDebug( 5326 ) <<"Deleting key 0x" << lvi
->text( 0 ) <<" ("
704 << lvi
->text( 1 ) << ")\n";
710 // update the icon for this key
711 switch( keyValidity( key
) ) {
712 case 0: // the key's validity can't be determined
713 lvi
->setData( 0, Qt::DecorationRole
, *mKeyUnknownPix
);
715 case 1: // key is valid but not trusted
716 lvi
->setData( 0, Qt::DecorationRole
, *mKeyValidPix
);
718 case 2: // key is valid and trusted
719 lvi
->setData( 0, Qt::DecorationRole
, *mKeyGoodPix
);
721 case -1: // key is invalid
722 lvi
->setData( 0, Qt::DecorationRole
, *mKeyBadPix
);
726 // update the key info for this key
727 // the key info is identified by a leading space; this shouldn't be
728 // a problem because User Ids shouldn't start with a space
729 QTreeWidgetItemIterator
it( lvi
);
731 if( lvi
->text( 1 ).at(0) == ' ' ) {
732 lvi
->setText( 1, keyInfo( key
) );
741 KeySelectionDialog::keyAdmissibility( QTreeWidgetItem
* lvi
,
742 TrustCheckMode trustCheckMode
) const
745 // -1 = key must not be chosen,
746 // 0 = not enough information to decide whether the give key is allowed
748 // 1 = key can be chosen
750 if( mAllowedKeys
== AllKeys
) {
754 Kpgp::Module
*pgp
= Kpgp::Module::getKpgp();
760 KeyID keyId
= getKeyId( lvi
);
761 Kpgp::Key
* key
= pgp
->publicKey( keyId
);
768 if( trustCheckMode
== ForceTrustCheck
) {
769 key
= pgp
->rereadKey( keyId
, true );
770 updateKeyInfo( key
, lvi
);
771 val
= keyValidity( key
);
774 val
= keyValidity( key
);
775 if( ( trustCheckMode
== AllowExpensiveTrustCheck
) && ( 0 == val
) ) {
776 key
= pgp
->rereadKey( keyId
, true );
777 updateKeyInfo( key
, lvi
);
778 val
= keyValidity( key
);
783 case -1: // key is not usable
786 case 0: // key status unknown
789 case 1: // key is valid, but untrusted
790 if( mAllowedKeys
& TrustedKeys
) {
791 // only trusted keys are allowed
796 case 2: // key is trusted
800 kDebug( 5326 ) <<"Error: Invalid key status value.";
808 KeySelectionDialog::getKeyId( const QTreeWidgetItem
* lvi
) const
813 if( 0 != lvi
->parent() ) {
814 keyId
= lvi
->parent()->text(0).toLocal8Bit();
817 keyId
= lvi
->text(0).toLocal8Bit();
825 void KeySelectionDialog::slotRereadKeys()
827 Kpgp::Module
*pgp
= Kpgp::Module::getKpgp();
835 if( PublicKeys
& mAllowedKeys
) {
836 pgp
->readPublicKeys( true );
837 keys
= pgp
->publicKeys();
840 pgp
->readSecretKeys( true );
841 keys
= pgp
->secretKeys();
844 // save the current position of the contents
845 int offsetY
= mListView
->verticalScrollBar()->value();
847 disconnect( mListView
, SIGNAL(itemSelectionChanged()),
848 this, SLOT(slotSelectionChanged()) );
850 initKeylist( keys
, KeyIDList( mKeyIds
) );
853 connect( mListView
, SIGNAL(itemSelectionChanged()),
854 this, SLOT(slotSelectionChanged()) );
855 slotSelectionChanged();
857 // restore the saved position of the contents
858 mListView
->verticalScrollBar()->setValue( offsetY
);
862 void KeySelectionDialog::slotSelectionChanged()
864 kDebug( 5326 ) <<"KeySelectionDialog::slotSelectionChanged()";
866 if ( mListView
->selectionMode() == QTreeWidget::ExtendedSelection
) {
867 // (re)start the check selection timer. Checking the selection is delayed
868 // because else drag-selection doesn't work very good (checking key trust
870 mCheckSelectionTimer
->start( sCheckSelectionDelay
);
872 if ( mListView
->selectedItems().size() > 0 )
873 slotCheckSelection( mListView
->selectedItems().first() );
878 void KeySelectionDialog::slotCheckSelection( QTreeWidgetItem
* plvi
/* = 0 */ )
880 kDebug( 5326 ) <<"KeySelectionDialog::slotCheckSelection()";
882 if( mListView
->selectionMode() != QTreeWidget::ExtendedSelection
) {
884 KeyID keyId
= getKeyId( plvi
);
885 if( !keyId
.isEmpty() ) {
886 mKeyIds
.append( keyId
);
887 enableButton( Ok
, 1 == keyAdmissibility( plvi
, AllowExpensiveTrustCheck
) );
890 enableButton( Ok
, false );
894 mCheckSelectionTimer
->stop();
896 // As we might change the selection, we have to disconnect the slot
897 // to prevent recursion
898 disconnect( mListView
, SIGNAL(itemSelectionChanged()),
899 this, SLOT(slotSelectionChanged()) );
901 KeyIDList newKeyIdList
;
902 QList
<QTreeWidgetItem
*> keysToBeChecked
;
904 bool keysAllowed
= true;
905 enum { UNKNOWN
, SELECTED
, DESELECTED
} userAction
= UNKNOWN
;
906 // Iterate over the tree to find selected keys.
907 for( int lviIndex
= 0; lviIndex
< mListView
->topLevelItemCount(); ++lviIndex
) {
908 QTreeWidgetItem
*lvi
= mListView
->topLevelItem( lviIndex
);
909 // We make sure that either all items belonging to a key are selected
910 // or unselected. As it's possible to select/deselect multiple keys at
911 // once in extended selection mode we have to figure out whether the user
912 // selected or deselected keys.
914 // First count the selected items of this key
915 int itemCount
= 1 + lvi
->childCount();
916 int selectedCount
= lvi
->isSelected() ? 1 : 0;
917 for( int clviIndex
= 0; clviIndex
< lvi
->childCount(); ++clviIndex
) {
918 QTreeWidgetItem
*clvi
= lvi
->child( clviIndex
);
919 if( clvi
->isSelected() ) {
924 if( userAction
== UNKNOWN
) {
925 // Figure out whether the user selected or deselected this key
926 // Remark: A selected count of 0 doesn't mean anything since in
927 // extended selection mode a normal left click deselects
928 // the not clicked items.
929 if( 0 < selectedCount
) {
930 if( -1 == mKeyIds
.indexOf( lvi
->text(0).toLocal8Bit() ) ) {
931 // some items of this key are selected and the key wasn't selected
932 // before => the user selected something
933 kDebug( 5326 ) <<"selectedCount:"<<selectedCount
<<"/"<<itemCount
934 <<"--- User selected key"<<lvi
->text(0);
935 userAction
= SELECTED
;
937 else if( ( itemCount
> selectedCount
) &&
938 ( -1 != mKeyIds
.indexOf( lvi
->text(0).toLocal8Bit() ) ) ) {
939 // some items of this key are unselected and the key was selected
940 // before => the user deselected something
941 kDebug( 5326 ) <<"selectedCount:"<<selectedCount
<<"/"<<itemCount
942 <<"--- User deselected key"<<lvi
->text(0);
943 userAction
= DESELECTED
;
947 if( itemCount
== selectedCount
) {
948 // add key to the list of selected keys
949 KeyID keyId
= lvi
->text(0).toLocal8Bit();
950 newKeyIdList
.append( keyId
);
951 int admissibility
= keyAdmissibility( lvi
, NoExpensiveTrustCheck
);
952 if( -1 == admissibility
) {
955 else if ( 0 == admissibility
) {
956 keysToBeChecked
.append( lvi
);
959 else if( 0 < selectedCount
) {
960 // not all items of this key are selected or unselected. change this
961 // according to the user's action
962 if( userAction
== SELECTED
) {
963 // select all items of this key
964 lvi
->setSelected( true );
965 for( int clviIndex
= 0; clviIndex
< lvi
->childCount(); ++clviIndex
) {
966 QTreeWidgetItem
*clvi
= lvi
->child( clviIndex
);
967 clvi
->setSelected( true );
969 // add key to the list of selected keys
970 KeyID keyId
= lvi
->text(0).toLocal8Bit();
971 newKeyIdList
.append( keyId
);
972 int admissibility
= keyAdmissibility( lvi
, NoExpensiveTrustCheck
);
973 if( -1 == admissibility
) {
976 else if ( 0 == admissibility
) {
977 keysToBeChecked
.append( lvi
);
980 else { // userAction == DESELECTED
981 // deselect all items of this key
982 lvi
->setSelected( false );
983 for ( int clviIndex
= 0; clviIndex
< lvi
->childCount(); ++clviIndex
) {
984 QTreeWidgetItem
*clvi
= lvi
->child( clviIndex
);
985 clvi
->setSelected( false );
990 kDebug( 5326 ) <<"Selected keys:" << newKeyIdList
.toStringList().join(",");
991 mKeyIds
= newKeyIdList
;
992 if( !keysToBeChecked
.isEmpty() ) {
993 keysAllowed
= keysAllowed
&& checkKeys( keysToBeChecked
);
995 enableButton( Ok
, keysAllowed
);
997 connect( mListView
, SIGNAL(selectionChanged()),
998 this, SLOT(slotSelectionChanged()) );
1003 bool KeySelectionDialog::checkKeys( const QList
<QTreeWidgetItem
*>& keys
) const
1005 KProgressDialog
* pProgressDlg
= 0;
1006 bool keysAllowed
= true;
1007 kDebug( 5326 ) <<"Checking keys...";
1009 pProgressDlg
= new KProgressDialog( 0, i18n("Checking Keys"),
1010 i18n("Checking key 0xMMMMMMMM..."));
1011 pProgressDlg
->setModal(true );
1012 pProgressDlg
->setAllowCancel( false );
1013 pProgressDlg
->progressBar()->setMaximum( keys
.count() );
1014 pProgressDlg
->setMinimumDuration( 1000 );
1015 pProgressDlg
->show();
1017 for( QList
<QTreeWidgetItem
*>::ConstIterator it
= keys
.begin();
1020 kDebug( 5326 ) <<"Checking key 0x" << getKeyId( *it
) <<"...";
1021 pProgressDlg
->setLabelText( i18n("Checking key 0x%1...",
1022 QString::fromAscii( getKeyId( *it
) ) ) );
1023 qApp
->processEvents();
1024 keysAllowed
= keysAllowed
&& ( -1 != keyAdmissibility( *it
, AllowExpensiveTrustCheck
) );
1025 pProgressDlg
->progressBar()->setValue( pProgressDlg
->progressBar()->value() + 1 );
1026 qApp
->processEvents();
1029 delete pProgressDlg
;
1036 void KeySelectionDialog::slotRMB( const QPoint
& pos
)
1038 QTreeWidgetItem
*lvi
= mListView
->itemAt( pos
);
1043 mCurrentContextMenuItem
= lvi
;
1046 menu
.addAction( i18n( "Recheck Key" ), this, SLOT(slotRecheckKey()) );
1047 menu
.exec( mListView
->viewport()->mapToGlobal( pos
) );
1051 void KeySelectionDialog::slotRecheckKey()
1053 if( 0 != mCurrentContextMenuItem
) {
1054 // force rereading the key
1055 keyAdmissibility( mCurrentContextMenuItem
, ForceTrustCheck
);
1056 // recheck the selection
1057 slotCheckSelection( mCurrentContextMenuItem
);
1061 void KeySelectionDialog::slotOk()
1063 if( mCheckSelectionTimer
->isActive() ) {
1064 slotCheckSelection();
1066 mStartSearchTimer
->stop();
1071 void KeySelectionDialog::slotCancel()
1073 mCheckSelectionTimer
->stop();
1074 mStartSearchTimer
->stop();
1079 void KeySelectionDialog::slotSearch( const QString
& text
)
1081 mSearchText
= text
.trimmed().toUpper();
1082 mStartSearchTimer
->start( sCheckSelectionDelay
);
1085 void KeySelectionDialog::slotFilter()
1087 if ( mSearchText
.isEmpty() ) {
1092 // OK, so we need to filter:
1093 QRegExp
keyIdRegExp( "(?:0x)?[A-F0-9]{1,8}", Qt::CaseInsensitive
);
1094 if ( keyIdRegExp
.exactMatch( mSearchText
) ) {
1095 if ( mSearchText
.startsWith( "0X" ) )
1096 // search for keyID only:
1097 filterByKeyID( mSearchText
.mid( 2 ) );
1099 // search for UID and keyID:
1100 filterByKeyIDOrUID( mSearchText
);
1103 filterByUID( mSearchText
);
1107 void KeySelectionDialog::filterByKeyID( const QString
& keyID
)
1109 assert( keyID
.length() <= 8 );
1110 assert( !keyID
.isEmpty() ); // regexp in slotFilter should prevent these
1111 if ( keyID
.isEmpty() )
1114 for ( int i
= 0; i
< mListView
->topLevelItemCount(); ++i
) {
1115 QTreeWidgetItem
* item
= mListView
->topLevelItem( i
);
1116 item
->setHidden( !item
->text( 0 ).toUpper().startsWith( keyID
) );
1121 void KeySelectionDialog::filterByKeyIDOrUID( const QString
& str
)
1123 assert( !str
.isEmpty() );
1125 // match beginnings of words:
1126 QRegExp
rx( "\\b" + QRegExp::escape( str
), Qt::CaseInsensitive
);
1128 for ( int i
= 0; i
< mListView
->topLevelItemCount(); ++i
) {
1129 QTreeWidgetItem
* item
= mListView
->topLevelItem( i
);
1130 item
->setHidden( !item
->text( 0 ).toUpper().startsWith( str
)
1131 && rx
.indexIn( item
->text( 1 ) ) < 0
1132 && !anyChildMatches( item
, rx
) );
1136 void KeySelectionDialog::filterByUID( const QString
& str
)
1138 assert( !str
.isEmpty() );
1140 // match beginnings of words:
1141 QRegExp
rx( "\\b" + QRegExp::escape( str
), Qt::CaseInsensitive
);
1143 for ( int i
= 0; i
< mListView
->topLevelItemCount(); ++i
) {
1144 QTreeWidgetItem
* item
= mListView
->topLevelItem( i
);
1145 item
->setHidden( rx
.indexIn( item
->text( 1 ) ) < 0
1146 && !anyChildMatches( item
, rx
) );
1151 bool KeySelectionDialog::anyChildMatches( const QTreeWidgetItem
* item
, QRegExp
& rx
) const
1156 for ( int i
= 0; i
< item
->childCount(); ++i
) {
1157 QTreeWidgetItem
* it
= item
->child( i
);
1158 if ( rx
.indexIn( it
->text( 1 ) ) >= 0 ) {
1159 //item->setOpen( true ); // do we want that?
1167 void KeySelectionDialog::showAllItems()
1169 for ( QTreeWidgetItemIterator
it( mListView
); *it
; ++it
)
1170 (*it
)->setHidden( false );
1173 #endif // QT_NO_TREEWIDGET
1175 // ------------------------------------------------------------------------
1176 KeyRequester::KeyRequester( QWidget
* parent
, bool multipleKeys
,
1177 unsigned int allowedKeys
, const char * name
)
1178 : QWidget( parent
),
1179 mDialogCaption( i18n("OpenPGP Key Selection") ),
1180 mDialogMessage( i18n("Please select an OpenPGP key to use.") ),
1181 mMulti( multipleKeys
),
1182 mAllowedKeys( allowedKeys
),
1185 setObjectName( name
);
1186 QHBoxLayout
* hlay
= new QHBoxLayout( this );
1187 hlay
->setSpacing( KDialog::spacingHint() );
1188 hlay
->setMargin( 0 );
1190 // the label where the key id is to be displayed:
1191 mLabel
= new QLabel( this );
1192 mLabel
->setFrameStyle( QFrame::Panel
| QFrame::Sunken
);
1194 // the button to unset any key:
1195 mEraseButton
= new QPushButton( this );
1196 mEraseButton
->setAutoDefault( false );
1197 mEraseButton
->setSizePolicy( QSizePolicy( QSizePolicy::Minimum
,
1198 QSizePolicy::Minimum
) );
1199 mEraseButton
->setIcon( KIcon( "edit-clear-locationbar-rtl" ) );
1200 mEraseButton
->setToolTip( i18n("Clear") );
1202 // the button to call the KeySelectionDialog:
1203 mDialogButton
= new QPushButton( i18n("Change..."), this );
1204 mDialogButton
->setAutoDefault( false );
1206 hlay
->addWidget( mLabel
, 1 );
1207 hlay
->addWidget( mEraseButton
);
1208 hlay
->addWidget( mDialogButton
);
1210 connect( mEraseButton
, SIGNAL(clicked()), SLOT(slotEraseButtonClicked()) );
1211 connect( mDialogButton
, SIGNAL(clicked()), SLOT(slotDialogButtonClicked()) );
1213 setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding
,
1214 QSizePolicy::Fixed
) );
1217 KeyRequester::~KeyRequester() {
1221 KeyIDList
KeyRequester::keyIDs() const {
1225 void KeyRequester::setKeyIDs( const KeyIDList
& keyIDs
) {
1227 if ( mKeys
.empty() ) {
1231 if ( mKeys
.size() > 1 )
1232 setMultipleKeysEnabled( true );
1234 QString s
= mKeys
.toStringList().join(", ");
1236 mLabel
->setText( s
);
1237 mLabel
->setToolTip( s
);
1240 void KeyRequester::slotDialogButtonClicked() {
1241 Module
* pgp
= Module::getKpgp();
1244 kWarning(5326) <<"Kpgp::KeyRequester::slotDialogButtonClicked(): No pgp module found!";
1248 setKeyIDs( keyRequestHook( pgp
) );
1252 void KeyRequester::slotEraseButtonClicked() {
1258 void KeyRequester::setDialogCaption( const QString
& caption
) {
1259 mDialogCaption
= caption
;
1262 void KeyRequester::setDialogMessage( const QString
& msg
) {
1263 mDialogMessage
= msg
;
1266 bool KeyRequester::isMultipleKeysEnabled() const {
1270 void KeyRequester::setMultipleKeysEnabled( bool multi
) {
1271 if ( multi
== mMulti
) return;
1273 if ( !multi
&& mKeys
.size() > 1 )
1274 mKeys
.erase( ++mKeys
.begin(), mKeys
.end() );
1279 int KeyRequester::allowedKeys() const {
1280 return mAllowedKeys
;
1283 void KeyRequester::setAllowedKeys( int allowedKeys
) {
1284 mAllowedKeys
= allowedKeys
;
1288 PublicKeyRequester::PublicKeyRequester( QWidget
* parent
, bool multi
,
1289 unsigned int allowed
, const char * name
)
1290 : KeyRequester( parent
, multi
, allowed
& ~SecretKeys
, name
)
1295 PublicKeyRequester::~PublicKeyRequester() {
1299 KeyIDList
PublicKeyRequester::keyRequestHook( Module
* pgp
) const {
1301 return pgp
->selectPublicKeys( mDialogCaption
, mDialogMessage
, mKeys
, QString(), mAllowedKeys
);
1304 SecretKeyRequester::SecretKeyRequester( QWidget
* parent
, bool multi
,
1305 unsigned int allowed
, const char * name
)
1306 : KeyRequester( parent
, multi
, allowed
& ~PublicKeys
, name
)
1311 SecretKeyRequester::~SecretKeyRequester() {
1315 KeyIDList
SecretKeyRequester::keyRequestHook( Module
* pgp
) const {
1321 KeyID keyID
= mKeys
.first();
1322 keyID
= pgp
->selectSecretKey( mDialogCaption
, mDialogMessage
, keyID
);
1324 return KeyIDList() << keyID
;
1329 // ------------------------------------------------------------------------
1330 KeyApprovalDialog::KeyApprovalDialog( const QStringList
& addresses
,
1331 const QVector
<KeyIDList
>& keyIDs
,
1332 const int allowedKeys
,
1334 : KDialog( parent
),
1336 mAllowedKeys( allowedKeys
),
1337 mPrefsChanged( false )
1339 setCaption( i18n("Encryption Key Approval") );
1340 setButtons( Ok
|Cancel
);
1342 Kpgp::Module
*pgp
= Kpgp::Module::getKpgp();
1347 // ##### error handling
1348 // if( addresses.isEmpty() || keyList.isEmpty() ||
1349 // addresses.count()+1 != keyList.count() )
1352 QFrame
*page
= new QFrame( this );
1353 setMainWidget( page
);
1354 QVBoxLayout
*topLayout
= new QVBoxLayout( page
);
1355 topLayout
->setSpacing( KDialog::spacingHint() );
1356 topLayout
->setMargin( 0 );
1358 QLabel
*label
= new QLabel( i18n("The following keys will be used for "
1361 topLayout
->addWidget( label
);
1363 QScrollArea
* sv
= new QScrollArea( page
);
1364 sv
->setWidgetResizable( true );
1365 topLayout
->addWidget( sv
);
1366 KVBox
* bigvbox
= new KVBox
;
1367 sv
->setWidget( bigvbox
);
1368 //bigvbox->setMargin( KDialog::marginHint() );
1369 bigvbox
->setSpacing( KDialog::spacingHint() );
1371 QButtonGroup
*mChangeButtonGroup
= new QButtonGroup
;
1372 mAddressLabels
.resize( addresses
.count() );
1373 mKeyIdsLabels
.resize( keyIDs
.size() );
1374 //mKeyIdListBoxes.resize( keyIDs.size() );
1375 mEncrPrefCombos
.resize( addresses
.count() );
1378 if( pgp
->encryptToSelf() ) {
1380 KHBox
* hbox
= new KHBox( bigvbox
);
1381 new QLabel( i18n("Your keys:"), hbox
);
1382 QLabel
* keyidsL
= new QLabel( hbox
);
1383 if( keyIDs
[0].isEmpty() ) {
1384 keyidsL
->setText( i18nc( "@info", "<placeholder>none</placeholder> means 'no key'" ) );
1387 keyidsL
->setText( "0x" + keyIDs
[0].toStringList().join( "\n0x" ) );
1389 keyidsL
->setFrameStyle( QFrame::Panel
| QFrame::Sunken
);
1391 QListBox* keyidLB = new QListBox( hbox );
1392 if( keyIDs[0].isEmpty() ) {
1393 keyidLB->insertItem( i18n("<none>") );
1396 keyidLB->insertStringList( keyIDs[0].toStringList() );
1398 keyidLB->setSelectionMode( QListBox::NoSelection );
1399 keyidLB->setFrameStyle( QFrame::Panel | QFrame::Sunken );
1401 QPushButton
*button
= new QPushButton( i18n("Change..."), hbox
);
1402 mChangeButtonGroup
->addButton( button
);
1403 button
->setAutoDefault( false );
1404 hbox
->setStretchFactor( keyidsL
, 10 );
1405 mKeyIdsLabels
.insert( 0, keyidsL
);
1406 //hbox->setStretchFactor( keyidLB, 10 );
1407 //mKeyIdListBoxes.insert( 0, keyidLB );
1409 new KSeparator( Qt::Horizontal
, bigvbox
);
1413 // insert dummy KeyIdListBox
1414 mKeyIdsLabels
.insert( 0, 0 );
1415 //mKeyIdListBoxes.insert( 0, 0 );
1418 QStringList::ConstIterator ait
;
1419 QVector
<KeyIDList
>::const_iterator kit
;
1421 for( ait
= addresses
.begin(), kit
= keyIDs
.begin(), i
= 0;
1422 ( ait
!= addresses
.end() ) && ( kit
!= keyIDs
.end() );
1423 ++ait
, ++kit
, ++i
) {
1425 ++kit
; // skip the sender's key id
1428 new KSeparator( Qt::Horizontal
, bigvbox
);
1431 KHBox
*hbox
= new KHBox( bigvbox
);
1432 new QLabel( i18n("Recipient:"), hbox
);
1433 QLabel
*addressL
= new QLabel( *ait
, hbox
);
1434 hbox
->setStretchFactor( addressL
, 10 );
1435 mAddressLabels
.insert( i
, addressL
);
1437 hbox
= new KHBox( bigvbox
);
1438 new QLabel( i18n("Encryption keys:"), hbox
);
1439 QLabel
* keyidsL
= new QLabel( hbox
);
1440 if( (*kit
).isEmpty() ) {
1441 keyidsL
->setText( i18nc( "@info", "<placeholder>none</placeholder> means 'no key'" ) );
1444 keyidsL
->setText( "0x" + (*kit
).toStringList().join( "\n0x" ) );
1446 keyidsL
->setFrameStyle( QFrame::Panel
| QFrame::Sunken
);
1448 QListBox* keyidLB = new QListBox( hbox );
1449 if( (*kit).isEmpty() ) {
1450 keyidLB->insertItem( i18n("<none>") );
1453 keyidLB->insertStringList( (*kit).toStringList() );
1455 keyidLB->setSelectionMode( QListBox::NoSelection );
1456 keyidLB->setFrameStyle( QFrame::Panel | QFrame::Sunken );
1458 QPushButton
*button
= new QPushButton( i18n("Change..."), hbox
);
1459 mChangeButtonGroup
->addButton( button
);
1460 button
->setAutoDefault( false );
1461 hbox
->setStretchFactor( keyidsL
, 10 );
1462 mKeyIdsLabels
.insert( i
+ 1, keyidsL
);
1463 //hbox->setStretchFactor( keyidLB, 10 );
1464 //mKeyIdListBoxes.insert( i + 1, keyidLB );
1466 hbox
= new KHBox( bigvbox
);
1467 new QLabel( i18n("Encryption preference:"), hbox
);
1468 QComboBox
*encrPrefCombo
= new QComboBox( hbox
);
1469 encrPrefCombo
->addItem( i18nc( "@item:inlistbox", "<placeholder>none</placeholder>") );
1470 encrPrefCombo
->addItem( i18nc( "@item:inlistbox", "Never Encrypt with This Key") );
1471 encrPrefCombo
->addItem( i18nc( "@item:inlistbox", "Always Encrypt with This Key") );
1472 encrPrefCombo
->addItem( i18nc( "@item:inlistbox", "Encrypt Whenever Encryption is Possible") );
1473 encrPrefCombo
->addItem( i18nc( "@item:inlistbox", "Always Ask") );
1474 encrPrefCombo
->addItem( i18nc( "@item:inlistbox", "Ask Whenever Encryption is Possible") );
1476 EncryptPref encrPref
= pgp
->encryptionPreference( *ait
);
1477 switch( encrPref
) {
1479 encrPrefCombo
->setCurrentIndex( 1 );
1482 encrPrefCombo
->setCurrentIndex( 2 );
1484 case AlwaysEncryptIfPossible
:
1485 encrPrefCombo
->setCurrentIndex( 3 );
1487 case AlwaysAskForEncryption
:
1488 encrPrefCombo
->setCurrentIndex( 4 );
1490 case AskWheneverPossible
:
1491 encrPrefCombo
->setCurrentIndex( 5 );
1494 encrPrefCombo
->setCurrentIndex( 0 );
1496 connect( encrPrefCombo
, SIGNAL(activated(int)),
1497 this, SLOT(slotPrefsChanged(int)) );
1498 mEncrPrefCombos
.insert( i
, encrPrefCombo
);
1500 connect( mChangeButtonGroup
, SIGNAL(buttonClicked(int)),
1501 this, SLOT(slotChangeEncryptionKey(int)) );
1503 QSize size
= sizeHint();
1505 // don't make the dialog too large
1506 QRect desk
= KGlobalSettings::desktopGeometry(this);
1507 int screenWidth
= desk
.width();
1508 if( size
.width() > 3*screenWidth
/4 )
1509 size
.setWidth( 3*screenWidth
/4 );
1510 int screenHeight
= desk
.height();
1511 if( size
.height() > 7*screenHeight
/8 )
1512 size
.setHeight( 7*screenHeight
/8 );
1513 connect(this,SIGNAL(okClicked()),SLOT(slotOk()));
1514 connect(this,SIGNAL(cancelClicked()),SLOT(slotCancel()));
1515 setInitialSize( size
);
1519 KeyApprovalDialog::slotChangeEncryptionKey( int nr
)
1521 Kpgp::Module
*pgp
= Kpgp::Module::getKpgp();
1523 kDebug( 5326 )<<"Key approval dialog size is"
1524 <<width()<<"x"<<height();
1529 if( !mEncryptToSelf
)
1531 KeyIDList keyIds
= mKeys
[nr
];
1533 keyIds
= pgp
->selectPublicKeys( i18n("Encryption Key Selection"),
1534 i18nc("if in your language something like "
1535 "'key(s)' isn't possible please "
1536 "use the plural in the translation",
1537 "Select the key(s) which should "
1538 "be used to encrypt the message "
1545 keyIds
= pgp
->selectPublicKeys( i18n("Encryption Key Selection"),
1546 i18nc("if in your language something like "
1547 "'key(s)' isn't possible please "
1548 "use the plural in the translation",
1549 "Select the key(s) which should "
1550 "be used to encrypt the message "
1552 mAddressLabels
[nr
-1]->text() ),
1554 mAddressLabels
[nr
-1]->text(),
1557 if( !keyIds
.isEmpty() ) {
1559 QLabel
* keyidsL
= mKeyIdsLabels
[nr
];
1560 keyidsL
->setText( "0x" + keyIds
.toStringList().join( "\n0x" ) );
1562 QListBox* qlb = mKeyIdListBoxes[nr];
1564 qlb->insertStringList( keyIds.toStringList() );
1571 KeyApprovalDialog::slotOk()
1573 Kpgp::Module
*pgp
= Kpgp::Module::getKpgp();
1580 if( mPrefsChanged
) {
1581 // store the changed preferences
1582 for( int i
= 0; i
< mAddressLabels
.size(); i
++ ) {
1583 // traverse all Address and Encryption Preference widgets
1584 EncryptPref encrPref
;
1585 switch( mEncrPrefCombos
[i
]->currentIndex() ) {
1587 encrPref
= NeverEncrypt
;
1590 encrPref
= AlwaysEncrypt
;
1593 encrPref
= AlwaysEncryptIfPossible
;
1596 encrPref
= AlwaysAskForEncryption
;
1599 encrPref
= AskWheneverPossible
;
1603 encrPref
= UnknownEncryptPref
;
1605 pgp
->setEncryptionPreference( mAddressLabels
[i
]->text(), encrPref
);
1614 KeyApprovalDialog::slotCancel()
1621 // ------------------------------------------------------------------------
1622 CipherTextDialog::CipherTextDialog( const QByteArray
& text
,
1623 const QByteArray
& charset
, QWidget
*parent
)
1626 setCaption( i18n("OpenPGP Information") );
1627 setButtons( Ok
|Cancel
);
1629 // FIXME (post KDE2.2): show some more info, e.g. the output of GnuPG/PGP
1630 QFrame
*page
= new QFrame( this );
1631 setMainWidget( page
);
1632 QVBoxLayout
*topLayout
= new QVBoxLayout( page
);
1633 topLayout
->setSpacing( spacingHint() );
1634 topLayout
->setMargin( 0 );
1636 QLabel
*label
= new QLabel( page
);
1637 label
->setText(i18n("Result of the last encryption/sign operation:"));
1638 topLayout
->addWidget( label
);
1640 mEditBox
= new QTextEdit( page
);
1641 mEditBox
->setReadOnly(true);
1642 topLayout
->addWidget( mEditBox
, 10 );
1644 QString unicodeText
;
1645 if (charset
.isEmpty())
1646 unicodeText
= QString::fromLocal8Bit(text
.data());
1649 QTextCodec
*codec
= KGlobal::charsets()->codecForName(charset
, ok
);
1651 unicodeText
= QString::fromLocal8Bit(text
.data());
1653 unicodeText
= codec
->toUnicode(text
.data(), text
.length());
1656 mEditBox
->setText(unicodeText
);
1661 void CipherTextDialog::setMinimumSize()
1663 // this seems to force a layout of the entire document, so we get a
1664 // a proper contentsWidth(). Is there a better way?
1665 (void) mEditBox
->document()->documentLayout()->documentSize();
1667 mEditBox
->setMinimumHeight( mEditBox
->fontMetrics().lineSpacing() * 25 );
1669 int textWidth
= mEditBox
->viewport()->width() + 30;
1672 int maxWidth
= KGlobalSettings::desktopGeometry(parentWidget()).width()-100;
1674 mEditBox
->setMinimumWidth( qMin( textWidth
, maxWidth
) );
1677 void KeyRequester::virtual_hook( int, void* ) {}
1679 void PublicKeyRequester::virtual_hook( int id
, void* data
) {
1680 base::virtual_hook( id
, data
);
1683 void SecretKeyRequester::virtual_hook( int id
, void* data
) {
1684 base::virtual_hook( id
, data
);
1691 #include "kpgpui.moc"