00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <config-kleopatra.h>
00035
00036 #include "appearanceconfigwidget.h"
00037 #include "ui_appearanceconfigwidget.h"
00038
00039
00040 #include "tooltippreferences.h"
00041
00042 #include "libkleo/kleo/cryptobackendfactory.h"
00043 #include "libkleo/kleo/keyfiltermanager.h"
00044
00045 #ifdef ONLY_KLEO
00046 # include <utils/kleo_kicondialog.h>
00047 #else
00048 # include <kicondialog.h>
00049 #endif
00050
00051 #include <kconfig.h>
00052 #include <klocale.h>
00053 #include <kconfiggroup.h>
00054
00055 #include <QColor>
00056 #include <QFont>
00057 #include <QString>
00058 #include <QPainter>
00059 #include <QRegExp>
00060 #include <QApplication>
00061 #include <QColorDialog>
00062 #include <QFontDialog>
00063
00064 #include <boost/range.hpp>
00065 #include <boost/bind.hpp>
00066
00067 #include <algorithm>
00068 #include <cassert>
00069
00070 using namespace Kleo;
00071 using namespace Kleo::Config;
00072 using namespace boost;
00073 #ifdef ONLY_KLEO
00074 using namespace Kleo::KioAvoidance;
00075 #endif
00076
00077 enum {
00078 HasNameRole = Qt::UserRole + 0x1234,
00079 HasFontRole,
00080 IconNameRole,
00081 MayChangeNameRole,
00082 MayChangeForegroundRole,
00083 MayChangeBackgroundRole,
00084 MayChangeFontRole,
00085 MayChangeItalicRole,
00086 MayChangeBoldRole,
00087 MayChangeStrikeOutRole,
00088 MayChangeIconRole,
00089
00090 EndDummy
00091 };
00092
00093 static QFont tryToFindFontFor( const QListWidgetItem * item ) {
00094 if ( item )
00095 if ( const QListWidget * const lw = item->listWidget() )
00096 return lw->font();
00097 return QApplication::font( "QListWidget" );
00098 }
00099
00100 static bool is( const QListWidgetItem * item, bool (QFont::*func)() const ) {
00101 if ( !item )
00102 return false;
00103 const QVariant v = item->data( Qt::FontRole );
00104 if ( !v.isValid() || v.type() != QVariant::Font )
00105 return false;
00106 return (v.value<QFont>().*func)();
00107 }
00108
00109 static bool is_italic( const QListWidgetItem * item ) {
00110 return is( item, &QFont::italic );
00111 }
00112 static bool is_bold( const QListWidgetItem * item ) {
00113 return is( item, &QFont::bold );
00114 }
00115 static bool is_strikeout( const QListWidgetItem * item ) {
00116 return is( item, &QFont::strikeOut );
00117 }
00118
00119
00120 static void set( QListWidgetItem * item, bool on, void (QFont::*func)(bool) ) {
00121 if ( !item )
00122 return;
00123 const QVariant v = item->data( Qt::FontRole );
00124 QFont font = v.isValid() && v.type() == QVariant::Font ? v.value<QFont>() : tryToFindFontFor( item ) ;
00125 (font.*func)( on );
00126 item->setData( Qt::FontRole, font );
00127 }
00128
00129 static void set_italic( QListWidgetItem * item, bool on ) {
00130 set( item, on, &QFont::setItalic );
00131 }
00132 static void set_bold( QListWidgetItem * item, bool on ) {
00133 set( item, on, &QFont::setBold );
00134 }
00135 static void set_strikeout( QListWidgetItem * item, bool on ) {
00136 set( item, on, &QFont::setStrikeOut );
00137 }
00138
00139
00140 static void apply_config( const KConfigGroup & group, QListWidgetItem * item ) {
00141 if ( !item )
00142 return;
00143
00144 const QString name = group.readEntry( "Name" );
00145 item->setText( name.isEmpty() ? i18nc("Key filter without user-assigned name", "<unnamed>") : name );
00146 item->setData( HasNameRole, !name.isEmpty() );
00147 item->setData( MayChangeNameRole, !group.isEntryImmutable( "Name" ) );
00148
00149 const QColor fg = group.readEntry( "foreground-color", QColor() );
00150 item->setData( Qt::ForegroundRole, fg.isValid() ? QBrush( fg ) : QVariant() );
00151 item->setData( MayChangeForegroundRole, !group.isEntryImmutable( "foreground-color" ) );
00152
00153 const QColor bg = group.readEntry( "background-color", QColor() );
00154 item->setData( Qt::BackgroundRole, bg.isValid() ? QBrush( bg ) : QVariant() );
00155 item->setData( MayChangeBackgroundRole, !group.isEntryImmutable( "background-color" ) );
00156
00157 const QFont defaultFont = tryToFindFontFor( item );
00158 if ( group.hasKey( "font" ) ) {
00159 const QFont font = group.readEntry( "font", defaultFont );
00160 item->setData( Qt::FontRole, font != defaultFont ? font : QVariant() );
00161 item->setData( HasFontRole, font != defaultFont );
00162 } else {
00163 QFont font = defaultFont;
00164 font.setStrikeOut( group.readEntry( "font-strikeout", false ) );
00165 font.setItalic( group.readEntry( "font-italic", false ) );
00166 font.setBold( group.readEntry( "font-bold", false ) );
00167 item->setData( Qt::FontRole, font );
00168 item->setData( HasFontRole, false );
00169 }
00170 item->setData( MayChangeFontRole, !group.isEntryImmutable( "font" ) );
00171 item->setData( MayChangeItalicRole, !group.isEntryImmutable( "font-italic" ) );
00172 item->setData( MayChangeBoldRole, !group.isEntryImmutable( "font-bold" ) );
00173 item->setData( MayChangeStrikeOutRole, !group.isEntryImmutable( "font-strikeout" ) );
00174
00175 const QString iconName = group.readEntry( "icon" );
00176 item->setData( Qt::DecorationRole, iconName.isEmpty() ? QVariant() : KIcon( iconName ) );
00177 item->setData( IconNameRole, iconName.isEmpty() ? QVariant() : iconName );
00178 item->setData( MayChangeIconRole, !group.isEntryImmutable( "icon" ) );
00179 }
00180
00181 static void erase_if_allowed( QListWidgetItem * item, int role, int allowRole ) {
00182 if ( item && item->data( allowRole ).toBool() )
00183 item->setData( role, QVariant() );
00184 }
00185
00186 static void erase_if_allowed( QListWidgetItem * item, const int role[], size_t numRoles, int allowRole ) {
00187 if ( item && item->data( allowRole ).toBool() )
00188 for ( unsigned int i = 0 ; i < numRoles ; ++i )
00189 item->setData( role[i], QVariant() );
00190 }
00191
00192 #if 0
00193 static void erase_if_allowed( QListWidgetItem * item, int role, const int allowRole[], size_t numAllowRoles ) {
00194 if ( !item )
00195 return;
00196 for ( unsigned int i = 0 ; i < numAllowRoles ; ++i )
00197 if ( !item->data( allowRole[i] ).toBool() )
00198 return;
00199 item->setData( role, QVariant() );
00200 }
00201 #endif
00202
00203 static void erase_if_allowed( QListWidgetItem * item, const int role[], size_t numRoles, const int allowRole[], size_t numAllowRoles ) {
00204 if ( !item )
00205 return;
00206 for ( unsigned int i = 0 ; i < numAllowRoles ; ++i )
00207 if ( !item->data( allowRole[i] ).toBool() )
00208 return;
00209 for ( unsigned int i = 0 ; i < numRoles ; ++i )
00210 item->setData( role[i], QVariant() );
00211 }
00212
00213 static void set_default_appearance( QListWidgetItem * item ) {
00214 if ( !item )
00215 return;
00216 erase_if_allowed( item, Qt::ForegroundRole, MayChangeForegroundRole );
00217 erase_if_allowed( item, Qt::BackgroundRole, MayChangeBackgroundRole );
00218 static const int iconRoles[] = { Qt::DecorationRole, MayChangeIconRole };
00219 erase_if_allowed( item, iconRoles, size( iconRoles ), MayChangeIconRole );
00220 static const int fontRoles[] = { Qt::FontRole, HasFontRole };
00221 static const int fontAllowRoles[] = {
00222 MayChangeFontRole,
00223 MayChangeItalicRole,
00224 MayChangeBoldRole,
00225 MayChangeStrikeOutRole,
00226 };
00227 erase_if_allowed( item, fontRoles, size( fontRoles ), fontAllowRoles, size( fontAllowRoles ) );
00228 }
00229
00230 static void writeOrDelete( KConfigGroup & group, const char * key, const QVariant & value ) {
00231 if ( value.isValid() )
00232 group.writeEntry( key, value );
00233 else
00234 group.deleteEntry( key );
00235 }
00236
00237 static QVariant brush2color( const QVariant & v ) {
00238 if ( v.isValid() ) {
00239 if ( v.type() == QVariant::Color )
00240 return v;
00241 else if ( v.type() == QVariant::Brush )
00242 return v.value<QBrush>().color();
00243 }
00244 return QVariant();
00245 }
00246
00247 static void save_to_config( const QListWidgetItem * item, KConfigGroup & group ) {
00248 if ( !item )
00249 return;
00250 writeOrDelete( group, "Name", item->data( HasNameRole ).toBool() ? item->text() : QVariant() );
00251 writeOrDelete( group, "foreground-color", brush2color( item->data( Qt::ForegroundRole ) ) );
00252 writeOrDelete( group, "background-color", brush2color( item->data( Qt::BackgroundRole ) ) );
00253 writeOrDelete( group, "icon", item->data( IconNameRole ) );
00254
00255 group.deleteEntry( "font" );
00256 group.deleteEntry( "font-strikeout" );
00257 group.deleteEntry( "font-italic" );
00258 group.deleteEntry( "font-bold" );
00259
00260 if ( item->data( HasFontRole ).toBool() ) {
00261 writeOrDelete( group, "font", item->data( Qt::FontRole ) );
00262 return;
00263 }
00264
00265 if ( is_strikeout( item ) )
00266 group.writeEntry( "font-strikeout", true );
00267 if ( is_italic( item ) )
00268 group.writeEntry( "font-italic", true );
00269 if ( is_bold( item ) )
00270 group.writeEntry( "font-bold", true );
00271 }
00272
00273 static void kiosk_enable( QWidget * w, const QListWidgetItem * item, int allowRole ) {
00274 if ( !w )
00275 return;
00276 if ( item && !item->data( allowRole ).toBool() ) {
00277 w->setEnabled( false );
00278 w->setToolTip( i18n( "This parameter has been locked down by the system administrator." ) );
00279 } else {
00280 w->setEnabled( item );
00281 w->setToolTip( QString() );
00282 }
00283 }
00284
00285
00286
00287
00288
00289
00290
00291 class AppearanceConfigWidget::Private : public Ui_AppearanceConfigWidget {
00292 friend class ::Kleo::Config::AppearanceConfigWidget;
00293 AppearanceConfigWidget * const q;
00294 public:
00295 explicit Private( AppearanceConfigWidget * qq )
00296 : Ui_AppearanceConfigWidget(),
00297 q( qq )
00298 {
00299 setupUi( q );
00300
00301 if ( QLayout * const l = q->layout() )
00302 l->setMargin( 0 );
00303
00304 connect( iconButton, SIGNAL(clicked()), q, SLOT(slotIconClicked()) );
00305 connect( foregroundButton, SIGNAL(clicked()), q, SLOT(slotForegroundClicked()) );
00306 connect( backgroundButton, SIGNAL(clicked()), q, SLOT(slotBackgroundClicked()) );
00307 connect( fontButton, SIGNAL(clicked()), q, SLOT(slotFontClicked()) );
00308 connect( categoriesLV, SIGNAL(itemSelectionChanged()), q, SLOT(slotSelectionChanged()) );
00309 connect( defaultLookPB, SIGNAL(clicked()), q, SLOT(slotDefaultClicked()) );
00310 connect( italicCB, SIGNAL(toggled(bool)), q, SLOT(slotItalicToggled(bool)) );
00311 connect( boldCB, SIGNAL(toggled(bool)), q, SLOT(slotBoldToggled(bool)) );
00312 connect( strikeoutCB, SIGNAL(toggled(bool)), q, SLOT(slotStrikeOutToggled(bool)) );
00313 connect( tooltipValidityCheckBox, SIGNAL(toggled(bool)), q, SLOT(slotTooltipValidityChanged(bool)) );
00314 connect( tooltipOwnerCheckBox, SIGNAL(toggled(bool)), q, SLOT(slotTooltipOwnerChanged(bool)) );
00315 connect( tooltipDetailsCheckBox, SIGNAL(toggled(bool)), q, SLOT(slotTooltipDetailsChanged(bool)) );
00316 }
00317
00318 private:
00319 void enableDisableActions( QListWidgetItem * item );
00320 QListWidgetItem * selectedItem() const;
00321
00322 private:
00323 void slotIconClicked();
00324 void slotForegroundClicked();
00325 void slotBackgroundClicked();
00326 void slotFontClicked();
00327 void slotSelectionChanged();
00328 void slotDefaultClicked();
00329 void slotItalicToggled(bool);
00330 void slotBoldToggled(bool);
00331 void slotStrikeOutToggled(bool);
00332 void slotTooltipValidityChanged(bool);
00333 void slotTooltipOwnerChanged(bool);
00334 void slotTooltipDetailsChanged(bool);
00335 };
00336
00337 AppearanceConfigWidget::AppearanceConfigWidget( QWidget * p, Qt::WindowFlags f )
00338 : QWidget( p, f ), d( new Private( this ) )
00339 {
00340
00341 }
00342
00343
00344 AppearanceConfigWidget::~AppearanceConfigWidget() {}
00345
00346 void AppearanceConfigWidget::Private::slotSelectionChanged() {
00347 enableDisableActions( selectedItem() );
00348 }
00349
00350 QListWidgetItem * AppearanceConfigWidget::Private::selectedItem() const {
00351 const QList<QListWidgetItem*> items = categoriesLV->selectedItems();
00352 return items.empty() ? 0 : items.front() ;
00353 }
00354
00355 void AppearanceConfigWidget::Private::enableDisableActions( QListWidgetItem * item ) {
00356 kiosk_enable( iconButton, item, MayChangeIconRole );
00357 kiosk_enable( foregroundButton, item, MayChangeForegroundRole );
00358 kiosk_enable( backgroundButton, item, MayChangeBackgroundRole );
00359 kiosk_enable( fontButton, item, MayChangeFontRole );
00360 kiosk_enable( italicCB, item, MayChangeItalicRole );
00361 kiosk_enable( boldCB, item, MayChangeBoldRole );
00362 kiosk_enable( strikeoutCB, item, MayChangeStrikeOutRole );
00363
00364 defaultLookPB->setEnabled( item );
00365
00366 italicCB->setChecked( is_italic( item ) );
00367 boldCB->setChecked( is_bold( item ) );
00368 strikeoutCB->setChecked( is_strikeout( item ) );
00369 }
00370
00371 void AppearanceConfigWidget::Private::slotDefaultClicked() {
00372
00373 QListWidgetItem * const item = selectedItem();
00374 if ( !item )
00375 return;
00376
00377 set_default_appearance( item );
00378 enableDisableActions( item );
00379
00380 emit q->changed();
00381 }
00382
00383 void AppearanceConfigWidget::defaults() {
00384
00385 for ( int i = 0, end = d->categoriesLV->count() ; i != end ; ++i )
00386 set_default_appearance( d->categoriesLV->item( i ) );
00387 d->tooltipValidityCheckBox->setChecked( true );
00388 d->tooltipOwnerCheckBox->setChecked( false );
00389 d->tooltipDetailsCheckBox->setChecked( false );
00390 emit changed();
00391 }
00392
00393 void AppearanceConfigWidget::load() {
00394 d->categoriesLV->clear();
00395 KConfig * const config = CryptoBackendFactory::instance()->configObject();
00396 if ( !config )
00397 return;
00398 const QStringList groups = config->groupList().filter( QRegExp( "^Key Filter #\\d+$" ) );
00399 Q_FOREACH( const QString & group, groups ) {
00400
00401 apply_config( KConfigGroup( config, group ), new QListWidgetItem( d->categoriesLV ) );
00402 }
00403
00404 const TooltipPreferences prefs;
00405 d->tooltipValidityCheckBox->setChecked( prefs.showValidity() );
00406 d->tooltipOwnerCheckBox->setChecked( prefs.showOwnerInformation() );
00407 d->tooltipDetailsCheckBox->setChecked( prefs.showCertificateDetails() );
00408 }
00409
00410 void AppearanceConfigWidget::save() {
00411 TooltipPreferences prefs;
00412 prefs.setShowValidity( d->tooltipValidityCheckBox->isChecked() );
00413 prefs.setShowOwnerInformation( d->tooltipOwnerCheckBox->isChecked() );
00414 prefs.setShowCertificateDetails( d->tooltipDetailsCheckBox->isChecked() );
00415 prefs.writeConfig();
00416
00417 KConfig * const config = CryptoBackendFactory::instance()->configObject();
00418 if ( !config )
00419 return;
00420
00421
00422 const QStringList groups = config->groupList().filter( QRegExp( "^Key Filter #\\d+$" ) );
00423 #if 0
00424 if ( groups.isEmpty() ) {
00425
00426 Q3ListViewItemIterator lvit( categoriesLV );
00427 for ( ; lvit.current() ; ++lvit )
00428 groups << lvit.current()->text( 0 );
00429 }
00430 #endif
00431 for ( int i = 0, end = std::min( groups.size(), d->categoriesLV->count() ) ; i != end ; ++i ) {
00432 const QListWidgetItem * const item = d->categoriesLV->item( i );
00433 assert( item );
00434 KConfigGroup group( config, groups[i] );
00435 save_to_config( item, group );
00436 }
00437
00438 config->sync();
00439 KeyFilterManager::instance()->reload();
00440 }
00441
00442 void AppearanceConfigWidget::Private::slotIconClicked() {
00443 QListWidgetItem * const item = selectedItem();
00444 if ( !item )
00445 return;
00446
00447 const QString iconName = KIconDialog::getIcon(
00448 KIconLoader::Desktop, KIconLoader::Application, false, 0, false,
00449
00450 q );
00451 if ( iconName.isEmpty() )
00452 return;
00453
00454 item->setIcon( KIcon( iconName ) );
00455 item->setData( IconNameRole, iconName );
00456 }
00457
00458 void AppearanceConfigWidget::Private::slotForegroundClicked() {
00459 QListWidgetItem * const item = selectedItem();
00460 if ( !item )
00461 return;
00462
00463 const QVariant v = brush2color( item->data( Qt::ForegroundRole ) );
00464
00465 const QColor initial = v.isValid() ? v.value<QColor>() : categoriesLV->palette().color( QPalette::Normal, QPalette::Text );
00466 const QColor c = QColorDialog::getColor( initial, q );
00467
00468 if ( c.isValid() ) {
00469 item->setData( Qt::ForegroundRole, QBrush( c ) );
00470 emit q->changed();
00471 }
00472 }
00473
00474 void AppearanceConfigWidget::Private::slotBackgroundClicked() {
00475 QListWidgetItem * const item = selectedItem();
00476 if ( !item )
00477 return;
00478
00479 const QVariant v = brush2color( item->data( Qt::BackgroundRole ) );
00480
00481 const QColor initial = v.isValid() ? v.value<QColor>() : categoriesLV->palette().color( QPalette::Normal, QPalette::Base );
00482 const QColor c = QColorDialog::getColor( initial, q );
00483
00484 if ( c.isValid() ) {
00485 item->setData( Qt::BackgroundRole, QBrush( c ) );
00486 emit q->changed();
00487 }
00488 }
00489
00490 void AppearanceConfigWidget::Private::slotFontClicked() {
00491 QListWidgetItem * const item = selectedItem();
00492 if ( !item )
00493 return;
00494
00495 const QVariant v = item->data( Qt::FontRole );
00496
00497 bool ok = false;
00498 const QFont defaultFont = tryToFindFontFor( item );
00499 const QFont initial = v.isValid() && v.type() == QVariant::Font ? v.value<QFont>() : defaultFont ;
00500 QFont f = QFontDialog::getFont( &ok, initial, q );
00501 if ( !ok )
00502 return;
00503
00504
00505 if ( !item->data( MayChangeItalicRole ).toBool() )
00506 f.setItalic( initial.italic() );
00507 if ( !item->data( MayChangeBoldRole ).toBool() )
00508 f.setBold( initial.bold() );
00509 if ( !item->data( MayChangeStrikeOutRole ).toBool() )
00510 f.setStrikeOut( initial.strikeOut() );
00511
00512 item->setData( Qt::FontRole, f != defaultFont ? f : QVariant() );
00513 item->setData( HasFontRole, true );
00514 emit q->changed();
00515 }
00516
00517 void AppearanceConfigWidget::Private::slotItalicToggled( bool on ) {
00518 set_italic( selectedItem(), on );
00519 emit q->changed();
00520 }
00521
00522 void AppearanceConfigWidget::Private::slotBoldToggled( bool on ) {
00523 set_bold( selectedItem(), on );
00524 emit q->changed();
00525 }
00526
00527 void AppearanceConfigWidget::Private::slotStrikeOutToggled( bool on ) {
00528 set_strikeout( selectedItem(), on );
00529 emit q->changed();
00530 }
00531
00532 void AppearanceConfigWidget::Private::slotTooltipValidityChanged( bool )
00533 {
00534 emit q->changed();
00535 }
00536
00537 void AppearanceConfigWidget::Private::slotTooltipOwnerChanged( bool )
00538 {
00539 emit q->changed();
00540 }
00541
00542 void AppearanceConfigWidget::Private::slotTooltipDetailsChanged( bool )
00543 {
00544 emit q->changed();
00545 }
00546
00547
00548 #include "appearanceconfigwidget.moc"