• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdepim
  • Sitemap
  • Contact Us
 

kleopatra

appearanceconfigwidget.cpp

Go to the documentation of this file.
00001 /*
00002     appearanceconfigwidget.cpp
00003 
00004     This file is part of kleopatra, the KDE key manager
00005     Copyright (c) 2002,2004,2008 Klarälvdalens Datakonsult AB
00006     Copyright (c) 2002,2003 Marc Mutz <mutz@kde.org>
00007 
00008     Libkleopatra is free software; you can redistribute it and/or
00009     modify it under the terms of the GNU General Public License as
00010     published by the Free Software Foundation; either version 2 of the
00011     License, or (at your option) any later version.
00012 
00013     Libkleopatra is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016     General Public License for more details.
00017 
00018     You should have received a copy of the GNU General Public License
00019     along with this program; if not, write to the Free Software
00020     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00021 
00022     In addition, as a special exception, the copyright holders give
00023     permission to link the code of this program with any edition of
00024     the Qt library by Trolltech AS, Norway (or with modified versions
00025     of Qt that use the same license as Qt), and distribute linked
00026     combinations including the two.  You must obey the GNU General
00027     Public License in all respects for all of the code used other than
00028     Qt.  If you modify this file, you may extend this exception to
00029     your version of the file, but you are not obligated to do so.  If
00030     you do not wish to do so, delete this exception statement from
00031     your version.
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 //    load();
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     // This simply means "default look for every category"
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         //QListWidgetItem * item = new QListWidgetItem( d->categoriesLV );
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     // We know (assume) that the groups in the config object haven't changed,
00421     // so we just iterate over them and over the listviewitems, and map one-to-one.
00422     const QStringList groups = config->groupList().filter( QRegExp( "^Key Filter #\\d+$" ) );
00423 #if 0
00424     if ( groups.isEmpty() ) {
00425         // If we created the default categories ourselves just now, then we need to make up their list
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( /* repeating default arguments begin */
00448                                                   KIconLoader::Desktop, KIconLoader::Application, false, 0, false,
00449                                                   /* repeating default arguments end */
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     // disallow circumventing KIOSK:
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"

kleopatra

Skip menu "kleopatra"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

kdepim

Skip menu "kdepim"
  • akonadi
  •   clients
  •   kabc
  •   kcal
  •   kcm
  • akregator
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt
  • kdgantt1
  • kjots
  • kleopatra
  • kmail
  • kmobiletools
  • knode
  • knotes
  • kontact
  • kontactinterfaces
  • korganizer
  •   korgac
  • kpilot
  • ktimetracker
  • libkdepim
  • libkholidays
  • libkleo
  • libkpgp
  • maildir
Generated for kdepim by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal