docs update, needs proofreading
[kdepim.git] / libkleo / ui / cryptoconfigmodule.cpp
blob73b3d5e27ec1f016ee01eb6f86ab886738653234
1 /*
2 cryptoconfigmodule.cpp
4 This file is part of kgpgcertmanager
5 Copyright (c) 2004 Klar�vdalens Datakonsult AB
7 Libkleopatra is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License,
9 version 2, as published by the Free Software Foundation.
11 Libkleopatra is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 In addition, as a special exception, the copyright holders give
21 permission to link the code of this program with any edition of
22 the Qt library by Trolltech AS, Norway (or with modified versions
23 of Qt that use the same license as Qt), and distribute linked
24 combinations including the two. You must obey the GNU General
25 Public License in all respects for all of the code used other than
26 Qt. If you modify this file, you may extend this exception to
27 your version of the file, but you are not obligated to do so. If
28 you do not wish to do so, delete this exception statement from
29 your version.
32 #include "cryptoconfigmodule.h"
33 #include "cryptoconfigmodule_p.h"
34 #include "directoryserviceswidget.h"
35 #include "kdhorizontalline.h"
36 #include "filenamerequester.h"
38 #include "kleo/cryptoconfig.h"
40 #include <klineedit.h>
41 #include <klocale.h>
42 #include <kdebug.h>
43 #include <knuminput.h>
44 #include <kiconloader.h>
45 #include <kglobal.h>
46 #include <kcomponentdata.h>
47 #include <kicon.h>
48 #ifndef KDEPIM_ONLY_KLEO
49 # include <kurlrequester.h>
50 #endif
52 #include <QApplication>
53 #include <QLabel>
54 #include <QLayout>
55 #include <QPushButton>
56 #include <QRegExp>
57 #include <QPixmap>
58 #include <QVBoxLayout>
59 #include <QList>
60 #include <QHBoxLayout>
61 #include <QGridLayout>
62 #include <QScrollArea>
63 #include <QDesktopWidget>
64 #include <QCheckBox>
65 #include <QStyle>
66 #include <QComboBox>
68 #include <cassert>
70 using namespace Kleo;
72 namespace {
74 class ScrollArea : public QScrollArea {
75 public:
76 explicit ScrollArea( QWidget* p ) : QScrollArea( p ) {}
77 /* reimp */ QSize sizeHint() const {
78 const QSize wsz = widget() ? widget()->sizeHint() : QSize();
79 return QSize( wsz.width() + style()->pixelMetric( QStyle::PM_ScrollBarExtent ), QScrollArea::sizeHint().height() );
84 inline KIcon loadIcon( const QString &s ) {
85 QString ss = s;
86 return KIcon( ss.replace( QRegExp( "[^a-zA-Z0-9_]" ), "-" ) );
89 static unsigned int num_components_with_options( const Kleo::CryptoConfig * config ) {
90 if ( !config )
91 return 0;
92 const QStringList components = config->componentList();
93 unsigned int result = 0;
94 for ( QStringList::const_iterator it = components.begin() ; it != components.end() ; ++it )
95 if ( const Kleo::CryptoConfigComponent * const comp = config->component( *it ) )
96 if ( !comp->groupList().empty() )
97 ++result;
98 return result;
101 static const KPageView::FaceType determineJanusFace( const Kleo::CryptoConfig * config, Kleo::CryptoConfigModule::Layout layout ) {
102 return num_components_with_options( config ) < 2
103 ? KPageView::Plain
104 : layout == Kleo::CryptoConfigModule::TabbedLayout ? KPageView::Tabbed : KPageView::List ;
107 Kleo::CryptoConfigModule::CryptoConfigModule( Kleo::CryptoConfig* config, QWidget * parent )
108 : KPageWidget( parent ), mConfig( config )
110 init( IconListLayout );
113 Kleo::CryptoConfigModule::CryptoConfigModule( Kleo::CryptoConfig* config, Layout layout, QWidget * parent )
114 : KPageWidget( parent ), mConfig( config )
116 init( layout );
119 void Kleo::CryptoConfigModule::init( Layout layout ) {
120 Kleo::CryptoConfig * const config = mConfig;
121 const KPageView::FaceType type=determineJanusFace( config, layout );
122 setFaceType(type);
123 QVBoxLayout * vlay = 0;
124 QWidget * vbox = 0;
125 if ( type == Plain ) {
126 vbox = new QWidget(this);
127 vlay = new QVBoxLayout( vbox );
128 vlay->setSpacing( KDialog::spacingHint() );
129 vlay->setMargin( 0 );
130 addPage( vbox, i18n("GpgConf Error") );
133 const QStringList components = config->componentList();
134 for ( QStringList::const_iterator it = components.begin(); it != components.end(); ++it ) {
135 //kDebug(5150) <<"Component" << (*it).toLocal8Bit() <<":";
136 Kleo::CryptoConfigComponent* comp = config->component( *it );
137 Q_ASSERT( comp );
138 if ( comp->groupList().empty() )
139 continue;
140 if ( type != Plain ) {
141 vbox = new QWidget(this);
142 vlay = new QVBoxLayout( vbox );
143 vlay->setSpacing( KDialog::spacingHint() );
144 vlay->setMargin( 0 );
145 KPageWidgetItem *pageItem = new KPageWidgetItem( vbox, comp->description() );
146 if ( type != Tabbed )
147 pageItem->setIcon( loadIcon( comp->iconName() ) );
148 addPage(pageItem);
151 QScrollArea* scrollArea = type == Tabbed ? new QScrollArea( this ) : new ScrollArea( this );
152 scrollArea->setWidgetResizable( true );
154 vlay->addWidget( scrollArea );
156 CryptoConfigComponentGUI* compGUI =
157 new CryptoConfigComponentGUI( this, comp, scrollArea );
158 compGUI->setObjectName( *it );
159 scrollArea->setWidget( compGUI );
160 scrollArea->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred );
161 // KJanusWidget doesn't seem to have iterators, so we store a copy...
162 mComponentGUIs.append( compGUI );
164 // Set a nice startup size
165 const int deskHeight = QApplication::desktop()->height();
166 int dialogHeight;
167 if (deskHeight > 1000) // very big desktop ?
168 dialogHeight = 800;
169 else if (deskHeight > 650) // big desktop ?
170 dialogHeight = 500;
171 else // small (800x600, 640x480) desktop
172 dialogHeight = 400;
173 assert( scrollArea->widget() );
174 if ( type != Tabbed )
175 scrollArea->setMinimumHeight( qMin( compGUI->sizeHint().height(), dialogHeight ) );
177 if ( mComponentGUIs.empty() ) {
178 const QString msg = i18n("The gpgconf tool used to provide the information "
179 "for this dialog does not seem to be installed "
180 "properly. It did not return any components. "
181 "Try running \"%1\" on the command line for more "
182 "information.",
183 components.empty() ? "gpgconf --list-components" : "gpgconf --list-options gpg" );
184 QLabel * label = new QLabel( msg, vbox );
185 label->setWordWrap( true);
186 label->setMinimumHeight( fontMetrics().lineSpacing() * 5 );
187 vlay->addWidget( label );
191 bool Kleo::CryptoConfigModule::hasError() const {
192 return mComponentGUIs.empty();
195 void Kleo::CryptoConfigModule::save()
197 bool changed = false;
198 QList<CryptoConfigComponentGUI *>::Iterator it = mComponentGUIs.begin();
199 for( ; it != mComponentGUIs.end(); ++it ) {
200 if ( (*it)->save() )
201 changed = true;
203 if ( changed )
204 mConfig->sync(true /*runtime*/);
207 void Kleo::CryptoConfigModule::reset()
209 QList<CryptoConfigComponentGUI *>::Iterator it = mComponentGUIs.begin();
210 for( ; it != mComponentGUIs.end(); ++it ) {
211 (*it)->load();
215 void Kleo::CryptoConfigModule::defaults()
217 QList<CryptoConfigComponentGUI *>::Iterator it = mComponentGUIs.begin();
218 for( ; it != mComponentGUIs.end(); ++it ) {
219 (*it)->defaults();
223 void Kleo::CryptoConfigModule::cancel()
225 mConfig->clear();
228 ////
230 Kleo::CryptoConfigComponentGUI::CryptoConfigComponentGUI(
231 CryptoConfigModule* module, Kleo::CryptoConfigComponent* component,
232 QWidget* parent )
233 : QWidget( parent ),
234 mComponent( component )
236 QGridLayout * glay = new QGridLayout( this );
237 glay->setSpacing( KDialog::spacingHint() );
238 const QStringList groups = mComponent->groupList();
239 if ( groups.size() > 1 ) {
240 glay->setColumnMinimumWidth( 0, KDHorizontalLine::indentHint() );
241 for ( QStringList::const_iterator it = groups.begin(), end = groups.end() ; it != end; ++it ) {
242 Kleo::CryptoConfigGroup* group = mComponent->group( *it );
243 Q_ASSERT( group );
244 if ( !group )
245 continue;
246 const QString title = group->description();
247 KDHorizontalLine * hl = new KDHorizontalLine( title.isEmpty() ? *it : title, this );
248 const int row = glay->rowCount();
249 glay->addWidget( hl, row, 0, 1, 3 );
250 mGroupGUIs.append( new CryptoConfigGroupGUI( module, group, glay, this ) );
252 } else if ( !groups.empty() ) {
253 mGroupGUIs.append( new CryptoConfigGroupGUI( module, mComponent->group( groups.front() ), glay, this ) );
255 glay->setRowStretch( glay->rowCount(), 1 );
259 bool Kleo::CryptoConfigComponentGUI::save()
261 bool changed = false;
262 QList<CryptoConfigGroupGUI *>::Iterator it = mGroupGUIs.begin();
263 for( ; it != mGroupGUIs.end(); ++it ) {
264 if ( (*it)->save() )
265 changed = true;
267 return changed;
270 void Kleo::CryptoConfigComponentGUI::load()
272 QList<CryptoConfigGroupGUI *>::Iterator it = mGroupGUIs.begin();
273 for( ; it != mGroupGUIs.end(); ++it )
274 (*it)->load();
277 void Kleo::CryptoConfigComponentGUI::defaults()
279 QList<CryptoConfigGroupGUI *>::Iterator it = mGroupGUIs.begin();
280 for( ; it != mGroupGUIs.end(); ++it )
281 (*it)->defaults();
284 ////
286 Kleo::CryptoConfigGroupGUI::CryptoConfigGroupGUI(
287 CryptoConfigModule* module, Kleo::CryptoConfigGroup* group,
288 QGridLayout * glay, QWidget* widget)
289 : QObject( module ), mGroup( group )
291 const int startRow = glay->rowCount();
292 const QStringList entries = mGroup->entryList();
293 for( QStringList::const_iterator it = entries.begin(), end = entries.end() ; it != end; ++it ) {
294 Kleo::CryptoConfigEntry* entry = group->entry( *it );
295 Q_ASSERT( entry );
296 if ( entry->level() > CryptoConfigEntry::Level_Advanced ) {
297 kDebug(5150) << "entry" << *it << "too advanced, skipping";
298 continue;
300 CryptoConfigEntryGUI* entryGUI =
301 CryptoConfigEntryGUIFactory::createEntryGUI( module, entry, *it, glay, widget );
302 if ( entryGUI ) {
303 mEntryGUIs.append( entryGUI );
304 entryGUI->load();
307 const int endRow = glay->rowCount() - 1;
308 if ( endRow < startRow )
309 return;
311 const QString iconName = group->iconName();
312 if ( iconName.isEmpty() )
313 return;
315 QLabel * l = new QLabel( widget );
316 l->setPixmap( loadIcon( iconName ).pixmap( KIconLoader::SizeMedium, KIconLoader::SizeMedium ) );
317 glay->addWidget( l, startRow, 0, endRow-startRow+1, 1, Qt::AlignTop );
320 bool Kleo::CryptoConfigGroupGUI::save()
322 bool changed = false;
323 QList<CryptoConfigEntryGUI *>::Iterator it = mEntryGUIs.begin();
324 for( ; it != mEntryGUIs.end(); ++it ) {
325 if ( (*it)->isChanged() ) {
326 (*it)->save();
327 changed = true;
330 return changed;
333 void Kleo::CryptoConfigGroupGUI::load()
335 QList<CryptoConfigEntryGUI *>::Iterator it = mEntryGUIs.begin();
336 for( ; it != mEntryGUIs.end(); ++it )
337 (*it)->load();
340 void Kleo::CryptoConfigGroupGUI::defaults()
342 QList<CryptoConfigEntryGUI *>::Iterator it = mEntryGUIs.begin();
343 for( ; it != mEntryGUIs.end(); ++it )
344 (*it)->resetToDefault();
347 ////
349 typedef CryptoConfigEntryGUI * (*constructor)( CryptoConfigModule *, Kleo::CryptoConfigEntry *, const QString &, QGridLayout *, QWidget * );
351 namespace {
352 template <typename T_Widget>
353 CryptoConfigEntryGUI * _create( CryptoConfigModule * m, Kleo::CryptoConfigEntry * e, const QString & n, QGridLayout * l, QWidget * p ) {
354 return new T_Widget( m, e, n, l, p );
358 static const struct WidgetsByEntryName {
359 const char * entryGlob;
360 constructor create;
361 } widgetsByEntryName[] = {
362 { "*/*/debug-level", &_create<CryptoConfigEntryDebugLevel> },
363 { "gpg/*/keyserver", &_create<CryptoConfigEntryKeyserver> }
365 static const unsigned int numWidgetsByEntryName = sizeof widgetsByEntryName / sizeof *widgetsByEntryName;
367 static const constructor listWidgets[CryptoConfigEntry::NumArgType] = {
368 // None: A list of options with no arguments (e.g. -v -v -v) is shown as a spinbox
369 &_create<CryptoConfigEntrySpinBox>,
370 0, // String
371 // Int/UInt: Let people type list of numbers (1,2,3....). Untested.
372 &_create<CryptoConfigEntryLineEdit>,
373 &_create<CryptoConfigEntryLineEdit>,
374 0, // Path
375 0, // URL
376 &_create<CryptoConfigEntryLDAPURL>,
377 0, // DirPath
380 static const constructor scalarWidgets[CryptoConfigEntry::NumArgType] = {
381 &_create<CryptoConfigEntryCheckBox>, // None
382 &_create<CryptoConfigEntryLineEdit>, // String
383 &_create<CryptoConfigEntrySpinBox>, // Int
384 &_create<CryptoConfigEntrySpinBox>, // UInt
385 &_create<CryptoConfigEntryPath>, // Path
386 &_create<CryptoConfigEntryURL>, // URL
387 0, // LDAPURL
388 &_create<CryptoConfigEntryDirPath>, // DirPath
391 CryptoConfigEntryGUI* Kleo::CryptoConfigEntryGUIFactory::createEntryGUI( CryptoConfigModule* module, Kleo::CryptoConfigEntry* entry, const QString& entryName, QGridLayout * glay, QWidget* widget )
393 assert( entry );
395 // try to lookup by path:
396 const QString path = entry->path();
397 for ( unsigned int i = 0 ; i < numWidgetsByEntryName ; ++i )
398 if ( QRegExp( QLatin1String( widgetsByEntryName[i].entryGlob ), Qt::CaseSensitive, QRegExp::Wildcard ).exactMatch( path ) )
399 return widgetsByEntryName[i].create( module, entry, entryName, glay, widget );
401 // none found, so look up by type:
402 const unsigned int argType = entry->argType();
403 assert( argType < CryptoConfigEntry::NumArgType );
404 if ( entry->isList() )
405 if ( const constructor create = listWidgets[argType] )
406 return create( module, entry, entryName, glay, widget );
407 else
408 kWarning(5150) <<"No widget implemented for list of type" << entry->argType();
409 else
410 if ( const constructor create = scalarWidgets[argType] )
411 return create( module, entry, entryName, glay, widget );
412 else
413 kWarning(5150) <<"No widget implemented for type" << entry->argType();
415 return 0;
418 ////
420 Kleo::CryptoConfigEntryGUI::CryptoConfigEntryGUI(
421 CryptoConfigModule* module,
422 Kleo::CryptoConfigEntry* entry,
423 const QString& entryName )
424 : QObject( module ), mEntry( entry ), mName( entryName ), mChanged( false )
426 connect( this, SIGNAL( changed() ), module, SIGNAL( changed() ) );
429 QString Kleo::CryptoConfigEntryGUI::description() const
431 QString descr = mEntry->description();
432 if ( descr.isEmpty() ) // shouldn't happen
433 return QString( "<%1>" ).arg( mName );
434 if ( i18nc( "Translate this to 'yes' or 'no' (use the English words!) "
435 "depending on whether your language uses "
436 "Sentence style capitalisation in GUI labels (yes) or not (no). "
437 "Context: We get some backend strings in that have the wrong "
438 "capitalizaion (in English, at least) so we need to force the "
439 "first character to upper-case. It is this behaviour you can "
440 "control for your language with this translation.", "yes" ) == QLatin1String( "yes" ) )
441 descr[0] = descr[0].toUpper();
442 return descr;
445 void Kleo::CryptoConfigEntryGUI::resetToDefault()
447 mEntry->resetToDefault();
448 load();
451 ////
453 Kleo::CryptoConfigEntryLineEdit::CryptoConfigEntryLineEdit(
454 CryptoConfigModule* module,
455 Kleo::CryptoConfigEntry* entry, const QString& entryName,
456 QGridLayout * glay, QWidget* widget )
457 : CryptoConfigEntryGUI( module, entry, entryName )
459 const int row = glay->rowCount();
460 mLineEdit = new KLineEdit( widget );
461 QLabel *label = new QLabel( description(), widget );
462 label->setBuddy( mLineEdit );
463 glay->addWidget( label, row, 1 );
464 glay->addWidget( mLineEdit, row, 2 );
465 if ( entry->isReadOnly() ) {
466 label->setEnabled( false );
467 mLineEdit->setEnabled( false );
468 } else {
469 connect( mLineEdit, SIGNAL( textChanged( const QString& ) ), SLOT( slotChanged() ) );
473 void Kleo::CryptoConfigEntryLineEdit::doSave()
475 mEntry->setStringValue( mLineEdit->text() );
478 void Kleo::CryptoConfigEntryLineEdit::doLoad()
480 mLineEdit->setText( mEntry->stringValue() );
483 ////
485 static const struct {
486 const char * label;
487 const char * name;
488 } debugLevels[] = {
489 { I18N_NOOP( "None (no debugging at all)" ), "none" },
490 { I18N_NOOP( "Basic (some basic debug messages)" ), "basic" },
491 { I18N_NOOP( "Advanced (more verbose debug messages)" ), "advanced" },
492 { I18N_NOOP( "Expert (even more detailed messages)" ), "expert" },
493 { I18N_NOOP( "Guru (all of the debug messages you can get)" ), "guru" },
495 static const unsigned int numDebugLevels = sizeof debugLevels / sizeof *debugLevels;
497 Kleo::CryptoConfigEntryDebugLevel::CryptoConfigEntryDebugLevel( CryptoConfigModule * module, Kleo::CryptoConfigEntry * entry,
498 const QString & entryName, QGridLayout * glay, QWidget * widget )
499 : CryptoConfigEntryGUI( module, entry, entryName ),
500 mComboBox( new QComboBox( widget ) )
502 QLabel *label = new QLabel( i18n("Set the debugging level to"), widget );
503 label->setBuddy( mComboBox );
505 for ( unsigned int i = 0 ; i < numDebugLevels ; ++i )
506 mComboBox->addItem( i18n( debugLevels[i].label ) );
508 if ( entry->isReadOnly() ) {
509 label->setEnabled( false );
510 mComboBox->setEnabled( false );
511 } else {
512 connect( mComboBox, SIGNAL(currentIndexChanged(int)), SLOT(slotChanged()) );
515 const int row = glay->rowCount();
516 glay->addWidget( label, row, 1 );
517 glay->addWidget( mComboBox, row, 2 );
520 void Kleo::CryptoConfigEntryDebugLevel::doSave()
522 const unsigned int idx = mComboBox->currentIndex();
523 if ( idx < numDebugLevels )
524 mEntry->setStringValue( QLatin1String( debugLevels[idx].name ) );
525 else
526 mEntry->setStringValue( QString() );
529 void Kleo::CryptoConfigEntryDebugLevel::doLoad()
531 const QString str = mEntry->stringValue();
532 for ( unsigned int i = 0 ; i < numDebugLevels ; ++i )
533 if ( str == QLatin1String( debugLevels[i].name ) ) {
534 mComboBox->setCurrentIndex( i );
535 return;
537 mComboBox->setCurrentIndex( 0 );
540 ////
542 Kleo::CryptoConfigEntryPath::CryptoConfigEntryPath(
543 CryptoConfigModule* module,
544 Kleo::CryptoConfigEntry* entry, const QString& entryName,
545 QGridLayout * glay, QWidget* widget )
546 : CryptoConfigEntryGUI( module, entry, entryName ),
547 mUrlRequester( 0 ),
548 mFileNameRequester( 0 )
550 const int row = glay->rowCount();
551 QWidget * req;
552 #ifdef KDEPIM_ONLY_KLEO
553 req = mFileNameRequester = new FileNameRequester( widget );
554 mFileNameRequester->setExistingOnly( false );
555 mFileNameRequester->setFilter( QDir::Files );
556 #else
557 req = mUrlRequester = new KUrlRequester( widget );
558 mUrlRequester->setMode( KFile::File | KFile::LocalOnly );
559 #endif
560 QLabel *label = new QLabel( description(), widget );
561 label->setBuddy( req );
562 glay->addWidget( label, row, 1 );
563 glay->addWidget( req, row, 2 );
564 if ( entry->isReadOnly() ) {
565 label->setEnabled( false );
566 #ifndef KDEPIM_ONLY_KLEO
567 if ( mUrlRequester )
568 mUrlRequester->setEnabled( false );
569 #endif
570 if ( mFileNameRequester )
571 mFileNameRequester->setEnabled( false );
572 } else {
573 #ifndef KDEPIM_ONLY_KLEO
574 if ( mUrlRequester )
575 connect( mUrlRequester, SIGNAL(textChanged(QString)),
576 this, SLOT(slotChanged()) );
577 #endif
578 if ( mFileNameRequester )
579 connect( mFileNameRequester, SIGNAL(fileNameChanged(QString)),
580 this, SLOT(slotChanged()) );
584 void Kleo::CryptoConfigEntryPath::doSave()
586 #ifdef KDEPIM_ONLY_KLEO
587 mEntry->setURLValue( KUrl::fromPath( mFileNameRequester->fileName() ) );
588 #else
589 mEntry->setURLValue( mUrlRequester->url() );
590 #endif
593 void Kleo::CryptoConfigEntryPath::doLoad()
595 #ifdef KDEPIM_ONLY_KLEO
596 mFileNameRequester->setFileName( mEntry->urlValue().path() );
597 #else
598 mUrlRequester->setUrl( mEntry->urlValue() );
599 #endif
602 ////
604 Kleo::CryptoConfigEntryDirPath::CryptoConfigEntryDirPath(
605 CryptoConfigModule* module,
606 Kleo::CryptoConfigEntry* entry, const QString& entryName,
607 QGridLayout * glay, QWidget* widget )
608 : CryptoConfigEntryGUI( module, entry, entryName ),
609 mUrlRequester( 0 ),
610 mFileNameRequester( 0 )
612 const int row = glay->rowCount();
613 QWidget * req;
614 #ifdef KDEPIM_ONLY_KLEO
615 req = mFileNameRequester = new FileNameRequester( widget );
616 mFileNameRequester->setExistingOnly( false );
617 mFileNameRequester->setFilter( QDir::Dirs );
618 #else
619 req = mUrlRequester = new KUrlRequester( widget );
620 mUrlRequester->setMode( KFile::Directory | KFile::LocalOnly );
621 #endif
622 QLabel *label = new QLabel( description(), widget );
623 label->setBuddy( req );
624 glay->addWidget( label, row, 1 );
625 glay->addWidget( req, row, 2 );
626 if ( entry->isReadOnly() ) {
627 label->setEnabled( false );
628 #ifndef KDEPIM_ONLY_KLEO
629 if ( mUrlRequester )
630 mUrlRequester->setEnabled( false );
631 #endif
632 if ( mFileNameRequester )
633 mFileNameRequester->setEnabled( false );
634 } else {
635 #ifndef KDEPIM_ONLY_KLEO
636 if ( mUrlRequester )
637 connect( mUrlRequester, SIGNAL(textChanged(QString)),
638 this, SLOT(slotChanged()) );
639 #endif
640 if ( mFileNameRequester )
641 connect( mFileNameRequester, SIGNAL(fileNameChanged(QString)),
642 this, SLOT(slotChanged()) );
646 void Kleo::CryptoConfigEntryDirPath::doSave()
648 #ifdef KDEPIM_ONLY_KLEO
649 mEntry->setURLValue( KUrl::fromPath( mFileNameRequester->fileName() ) );
650 #else
651 mEntry->setURLValue( mUrlRequester->url() );
652 #endif
655 void Kleo::CryptoConfigEntryDirPath::doLoad()
657 #ifdef KDEPIM_ONLY_KLEO
658 mFileNameRequester->setFileName( mEntry->urlValue().path() );
659 #else
660 mUrlRequester->setUrl( mEntry->urlValue() );
661 #endif
664 ////
666 Kleo::CryptoConfigEntryURL::CryptoConfigEntryURL(
667 CryptoConfigModule* module,
668 Kleo::CryptoConfigEntry* entry, const QString& entryName,
669 QGridLayout * glay, QWidget* widget )
670 : CryptoConfigEntryGUI( module, entry, entryName ),
671 mLineEdit( 0 )
672 #ifndef KDEPIM_ONLY_KLEO
673 , mUrlRequester( 0 )
674 #endif
676 const int row = glay->rowCount();
677 QWidget * req;
678 #ifdef KDEPIM_ONLY_KLEO
679 req = mLineEdit = new QLineEdit( widget );
680 #else
681 req = mUrlRequester = new KUrlRequester( widget );
682 mUrlRequester->setMode( KFile::File | KFile::ExistingOnly );
683 #endif
684 QLabel *label = new QLabel( description(), widget );
685 label->setBuddy( req );
686 glay->addWidget( label, row, 1 );
687 glay->addWidget( req, row, 2 );
688 if ( entry->isReadOnly() ) {
689 label->setEnabled( false );
690 #ifndef KDEPIM_ONLY_KLEO
691 if ( mUrlRequester )
692 mUrlRequester->setEnabled( false );
693 #endif
694 if ( mLineEdit )
695 mLineEdit->setEnabled( false );
696 } else {
697 connect( req, SIGNAL(textChanged(QString)),
698 this, SLOT(slotChanged()) );
702 void Kleo::CryptoConfigEntryURL::doSave()
704 #ifdef KDEPIM_ONLY_KLEO
705 mEntry->setURLValue( KUrl( mLineEdit->text() ) );
706 #else
707 mEntry->setURLValue( mUrlRequester->url() );
708 #endif
711 void Kleo::CryptoConfigEntryURL::doLoad()
713 #ifdef KDEPIM_ONLY_KLEO
714 mLineEdit->setText( mEntry->urlValue().url() );
715 #else
716 mUrlRequester->setUrl( mEntry->urlValue().url() );
717 #endif
720 ////
722 Kleo::CryptoConfigEntrySpinBox::CryptoConfigEntrySpinBox(
723 CryptoConfigModule* module,
724 Kleo::CryptoConfigEntry* entry, const QString& entryName,
725 QGridLayout * glay, QWidget* widget )
726 : CryptoConfigEntryGUI( module, entry, entryName )
729 if ( entry->argType() == Kleo::CryptoConfigEntry::ArgType_None && entry->isList() ) {
730 mKind = ListOfNone;
731 } else if ( entry->argType() == Kleo::CryptoConfigEntry::ArgType_UInt ) {
732 mKind = UInt;
733 } else {
734 Q_ASSERT( entry->argType() == Kleo::CryptoConfigEntry::ArgType_Int );
735 mKind = Int;
738 const int row = glay->rowCount();
739 mNumInput = new KIntNumInput( widget );
740 QLabel *label = new QLabel( description(), widget );
741 label->setBuddy( mNumInput );
742 glay->addWidget( label, row, 1 );
743 glay->addWidget( mNumInput, row, 2 );
745 if ( entry->isReadOnly() ) {
746 label->setEnabled( false );
747 mNumInput->setEnabled( false );
748 } else {
749 if ( mKind == UInt || mKind == ListOfNone )
750 mNumInput->setMinimum( 0 );
751 connect( mNumInput, SIGNAL( valueChanged(int) ), SLOT( slotChanged() ) );
755 void Kleo::CryptoConfigEntrySpinBox::doSave()
757 int value = mNumInput->value();
758 switch ( mKind ) {
759 case ListOfNone:
760 mEntry->setNumberOfTimesSet( value );
761 break;
762 case UInt:
763 mEntry->setUIntValue( value );
764 break;
765 case Int:
766 mEntry->setIntValue( value );
767 break;
771 void Kleo::CryptoConfigEntrySpinBox::doLoad()
773 int value = 0;
774 switch ( mKind ) {
775 case ListOfNone:
776 value = mEntry->numberOfTimesSet();
777 break;
778 case UInt:
779 value = mEntry->uintValue();
780 break;
781 case Int:
782 value = mEntry->intValue();
783 break;
785 mNumInput->setValue( value );
788 ////
790 Kleo::CryptoConfigEntryCheckBox::CryptoConfigEntryCheckBox(
791 CryptoConfigModule* module,
792 Kleo::CryptoConfigEntry* entry, const QString& entryName,
793 QGridLayout * glay, QWidget* widget )
794 : CryptoConfigEntryGUI( module, entry, entryName )
796 const int row = glay->rowCount();
797 mCheckBox = new QCheckBox( widget );
798 glay->addWidget( mCheckBox, row, 1, 1, 2 );
799 mCheckBox->setText( description() );
800 if ( entry->isReadOnly() ) {
801 mCheckBox->setEnabled( false );
802 } else {
803 connect( mCheckBox, SIGNAL( toggled(bool) ), SLOT( slotChanged() ) );
807 void Kleo::CryptoConfigEntryCheckBox::doSave()
809 mEntry->setBoolValue( mCheckBox->isChecked() );
812 void Kleo::CryptoConfigEntryCheckBox::doLoad()
814 mCheckBox->setChecked( mEntry->boolValue() );
819 Kleo::CryptoConfigEntryLDAPURL::CryptoConfigEntryLDAPURL(
820 CryptoConfigModule* module,
821 Kleo::CryptoConfigEntry* entry,
822 const QString& entryName,
823 QGridLayout * glay, QWidget* widget )
824 : CryptoConfigEntryGUI( module, entry, entryName )
826 mLabel = new QLabel( widget );
827 mPushButton = new QPushButton( entry->isReadOnly() ? i18n("Show...") : i18n( "Edit..." ), widget );
830 const int row = glay->rowCount();
831 QLabel *label = new QLabel( description(), widget );
832 label->setBuddy( mPushButton );
833 glay->addWidget( label, row, 1 );
834 QHBoxLayout * hlay = new QHBoxLayout;
835 glay->addLayout( hlay, row, 2 );
836 hlay->addWidget( mLabel, 1 );
837 hlay->addWidget( mPushButton );
839 if ( entry->isReadOnly() )
840 mLabel->setEnabled( false );
841 connect( mPushButton, SIGNAL( clicked() ), SLOT( slotOpenDialog() ) );
844 static KUrl::List strings2urls( const QStringList & strs ) {
845 KUrl::List urls;
846 Q_FOREACH( const QString & str, strs )
847 if ( !str.isEmpty() )
848 urls.push_back( KUrl( str ) );
849 return urls;
852 static QStringList urls2strings( const KUrl::List & urls ) {
853 QStringList result;
854 Q_FOREACH( const KUrl & url, urls )
855 result.push_back( url.url() );
856 return result;
859 void Kleo::CryptoConfigEntryLDAPURL::doLoad()
861 setURLList( mEntry->urlValueList() );
864 void Kleo::CryptoConfigEntryLDAPURL::doSave()
866 mEntry->setURLValueList( mURLList );
869 void Kleo::CryptoConfigEntryLDAPURL::slotOpenDialog()
871 // I'm a bad boy and I do it all on the stack. Enough classes already :)
872 // This is just a simple dialog around the directory-services-widget
873 KDialog dialog( mPushButton->parentWidget() );
874 dialog.setCaption( i18n( "Configure LDAP Servers" ) );
875 if ( mEntry->isReadOnly() )
876 dialog.setButtons( KDialog::Ok );
877 else
878 dialog.setButtons( KDialog::Default|KDialog::Cancel|KDialog::Ok );
879 DirectoryServicesWidget* dirserv = new DirectoryServicesWidget( &dialog );
880 dirserv->setX509ReadOnly( mEntry->isReadOnly() );
881 dirserv->setAllowedSchemes( DirectoryServicesWidget::LDAP );
882 dirserv->setAllowedProtocols( DirectoryServicesWidget::X509Protocol );
883 dirserv->addX509Services( mURLList );
884 dialog.setMainWidget( dirserv );
885 connect( &dialog, SIGNAL(defaultClicked()), dirserv, SLOT(clear()) );
886 if ( dialog.exec() ) {
887 setURLList( dirserv->x509Services() );
888 slotChanged();
892 void Kleo::CryptoConfigEntryLDAPURL::setURLList( const KUrl::List& urlList )
894 mURLList = urlList;
895 if ( mURLList.isEmpty() )
896 mLabel->setText( i18n( "No server configured yet" ) );
897 else
898 mLabel->setText( i18np( "1 server configured", "%1 servers configured", mURLList.count() ) );
903 Kleo::CryptoConfigEntryKeyserver::CryptoConfigEntryKeyserver(
904 CryptoConfigModule* module,
905 Kleo::CryptoConfigEntry* entry,
906 const QString& entryName,
907 QGridLayout * glay, QWidget* widget )
908 : CryptoConfigEntryGUI( module, entry, entryName )
910 mLabel = new QLabel( widget );
911 mPushButton = new QPushButton( i18n( "Edit..." ), widget );
914 const int row = glay->rowCount();
915 QLabel *label = new QLabel( i18n("Use keyserver at"), widget );
916 label->setBuddy( mPushButton );
917 glay->addWidget( label, row, 1 );
918 QHBoxLayout * hlay = new QHBoxLayout;
919 glay->addLayout( hlay, row, 2 );
920 hlay->addWidget( mLabel, 1 );
921 hlay->addWidget( mPushButton );
923 if ( entry->isReadOnly() ) {
924 mLabel->setEnabled( false );
925 mPushButton->hide();
926 } else {
927 connect( mPushButton, SIGNAL( clicked() ), SLOT( slotOpenDialog() ) );
931 Kleo::ParsedKeyserver Kleo::parseKeyserver( const QString & str ) {
932 const QStringList list = str.split( QRegExp( QLatin1String( "[\\s,]" ) ), QString::SkipEmptyParts );
933 if ( list.empty() )
934 return Kleo::ParsedKeyserver();
935 Kleo::ParsedKeyserver result;
936 result.url = list.front();
937 Q_FOREACH( const QString & kvpair, list.mid( 1 ) ) {
938 const int idx = kvpair.indexOf( QLatin1Char( '=' ) );
939 if ( idx < 0 ) {
940 result.options.push_back( qMakePair( kvpair, QString() ) ); // null QString
941 } else {
942 const QString key = kvpair.left( idx );
943 const QString value = kvpair.mid( idx+1 );
944 if ( value.isEmpty() )
945 result.options.push_back( qMakePair( key, QString("") ) ); // make sure it's not a null QString, only an empty one
946 else
947 result.options.push_back( qMakePair( key, value ) );
950 return result;
953 QString Kleo::assembleKeyserver( const ParsedKeyserver & keyserver ) {
954 if ( keyserver.options.empty() )
955 return keyserver.url;
956 QString result = keyserver.url;
957 typedef QPair<QString,QString> Pair;
958 Q_FOREACH( const Pair & pair, keyserver.options )
959 if ( pair.second.isNull() )
960 result += QLatin1Char( ' ' ) + pair.first ;
961 else
962 result += QLatin1Char( ' ' ) + pair.first + QLatin1Char( '=' ) + pair.second ;
963 return result;
966 void Kleo::CryptoConfigEntryKeyserver::doLoad()
968 mParsedKeyserver = parseKeyserver( mEntry->stringValue() );
969 mLabel->setText( mParsedKeyserver.url );
972 void Kleo::CryptoConfigEntryKeyserver::doSave()
974 mParsedKeyserver.url = mLabel->text();
975 mEntry->setStringValue( assembleKeyserver( mParsedKeyserver ) );
978 static KUrl::List string2urls( const QString & str ) {
979 return str.isEmpty() ? KUrl::List() : KUrl( str ) ;
982 static QString urls2string( const KUrl::List & urls ) {
983 return urls.empty() ? QString() : urls.front().url() ;
986 void Kleo::CryptoConfigEntryKeyserver::slotOpenDialog()
988 // I'm a bad boy and I do it all on the stack. Enough classes already :)
989 // This is just a simple dialog around the directory-services-widget
990 KDialog dialog( mPushButton->parentWidget() );
991 dialog.setCaption( i18n( "Configure Keyservers" ) );
992 dialog.setButtons( KDialog::Default|KDialog::Cancel|KDialog::Ok );
993 DirectoryServicesWidget dirserv( &dialog );
994 dirserv.setOpenPGPReadOnly( mEntry->isReadOnly() );
995 dirserv.setAllowedSchemes( DirectoryServicesWidget::AllSchemes );
996 dirserv.setAllowedProtocols( DirectoryServicesWidget::OpenPGPProtocol );
997 dirserv.addOpenPGPServices( string2urls( mLabel->text() ) );
998 dialog.setMainWidget( &dirserv );
999 connect( &dialog, SIGNAL(defaultClicked()), &dirserv, SLOT(clear()) );
1000 if ( dialog.exec() ) {
1001 mLabel->setText( urls2string( dirserv.openPGPServices() ) );
1002 slotChanged();
1006 #include "cryptoconfigmodule.moc"
1007 #include "cryptoconfigmodule_p.moc"