• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.8.3 API Reference
  • KDE Home
  • Contact Us
 

akonadi/contact

addresseditwidget.cpp
00001 /*
00002     This file is part of Akonadi Contact.
00003 
00004     Copyright (c) 2009 Tobias Koenig <tokoe@kde.org>
00005 
00006     This library is free software; you can redistribute it and/or modify it
00007     under the terms of the GNU Library General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or (at your
00009     option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful, but WITHOUT
00012     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00013     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00014     License for more details.
00015 
00016     You should have received a copy of the GNU Library General Public License
00017     along with this library; see the file COPYING.LIB.  If not, write to the
00018     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00019     02110-1301, USA.
00020 */
00021 
00022 #include "addresseditwidget.h"
00023 
00024 #include "autoqpointer_p.h"
00025 
00026 #include <QtCore/QEvent>
00027 #include <QtCore/QList>
00028 #include <QtGui/QApplication>
00029 #include <QtGui/QBoxLayout>
00030 #include <QtGui/QButtonGroup>
00031 #include <QtGui/QCheckBox>
00032 #include <QtGui/QFrame>
00033 #include <QtGui/QGridLayout>
00034 #include <QtGui/QGroupBox>
00035 #include <QtGui/QKeyEvent>
00036 #include <QtGui/QLabel>
00037 #include <QtGui/QPushButton>
00038 
00039 #include <kacceleratormanager.h>
00040 #include <kcombobox.h>
00041 #include <kdebug.h>
00042 #include <khbox.h>
00043 #include <kinputdialog.h>
00044 #include <klineedit.h>
00045 #include <klocale.h>
00046 #include <kmessagebox.h>
00047 #include <kseparator.h>
00048 #include <ktextedit.h>
00049 
00050 #include <functional>
00051 
00052 struct LocaleAwareLessThan : std::binary_function<QString,QString,bool> {
00053   bool operator()( const QString &s1, const QString &s2 ) const
00054   {
00055     return QString::localeAwareCompare( s1, s2 ) < 0 ;
00056   }
00057 };
00058 
00059 class TabPressEater : public QObject
00060 {
00061   public:
00062     TabPressEater( QObject *parent )
00063       : QObject( parent )
00064     {
00065       setObjectName( QLatin1String( "TabPressEater" ) );
00066     }
00067 
00068   protected:
00069     bool eventFilter( QObject*, QEvent *event )
00070     {
00071       if ( event->type() == QEvent::KeyPress ) {
00072         QKeyEvent *keyEvent = (QKeyEvent*)event;
00073         if ( keyEvent->key() == Qt::Key_Tab ) {
00074           QApplication::sendEvent( parent(), event );
00075           return true;
00076         } else
00077           return false;
00078       } else {
00079         return false;
00080       }
00081     }
00082 };
00083 
00089 class AddressTypeDialog : public KDialog
00090 {
00091   public:
00092     AddressTypeDialog( KABC::Address::Type type, QWidget *parent );
00093     ~AddressTypeDialog();
00094 
00095     KABC::Address::Type type() const;
00096 
00097   private:
00098     QButtonGroup *mGroup;
00099 
00100     KABC::Address::TypeList mTypeList;
00101 };
00102 
00103 
00104 AddressSelectionWidget::AddressSelectionWidget( QWidget *parent )
00105   : KComboBox( parent )
00106 {
00107   connect( this, SIGNAL(activated(int)), SLOT(selected(int)) );
00108 }
00109 
00110 AddressSelectionWidget::~AddressSelectionWidget()
00111 {
00112 }
00113 
00114 void AddressSelectionWidget::setAddresses( const KABC::Address::List &addresses )
00115 {
00116   mAddresses = addresses;
00117   updateView();
00118 }
00119 
00120 void AddressSelectionWidget::setCurrentAddress( const KABC::Address &address )
00121 {
00122   const int index = mAddresses.indexOf( address );
00123   if ( index != -1 )
00124     setCurrentIndex( index );
00125 }
00126 
00127 KABC::Address AddressSelectionWidget::currentAddress() const
00128 {
00129   if ( currentIndex() != -1 && currentIndex() < mAddresses.count() )
00130     return mAddresses.at( currentIndex() );
00131   else
00132     return KABC::Address();
00133 }
00134 
00135 void AddressSelectionWidget::selected( int index )
00136 {
00137   Q_ASSERT( index != -1 && index < mAddresses.count() );
00138   emit selectionChanged( mAddresses.at( index ) );
00139 }
00140 
00141 void AddressSelectionWidget::updateView()
00142 {
00143   clear();
00144   for ( int i = 0; i < mAddresses.count(); ++i )
00145     addItem( KABC::Address::typeLabel( mAddresses.at( i ).type() ) );
00146 }
00147 
00148 
00149 
00150 AddressTypeCombo::AddressTypeCombo( QWidget *parent )
00151   : KComboBox( parent ),
00152     mType( KABC::Address::Home ),
00153     mLastSelected( 0 )
00154 {
00155   for ( int i = 0; i < KABC::Address::typeList().count(); ++i )
00156     mTypeList.append( KABC::Address::typeList().at( i ) );
00157   mTypeList.append( -1 ); // Others...
00158 
00159   update();
00160 
00161   connect( this, SIGNAL(activated(int)),
00162            this, SLOT(selected(int)) );
00163 }
00164 
00165 AddressTypeCombo::~AddressTypeCombo()
00166 {
00167 }
00168 
00169 void AddressTypeCombo::setType( KABC::Address::Type type )
00170 {
00171   if ( !mTypeList.contains( (int)type ) ) {
00172     // insert at the end, but before the 'Others...' entry
00173     mTypeList.insert( mTypeList.at( mTypeList.count() - 1 ), (int)type );
00174   }
00175 
00176   mType = type;
00177   update();
00178 }
00179 
00180 KABC::Address::Type AddressTypeCombo::type() const
00181 {
00182   return mType;
00183 }
00184 
00185 void AddressTypeCombo::update()
00186 {
00187   bool blocked = signalsBlocked();
00188   blockSignals( true );
00189 
00190   clear();
00191   for ( int i = 0; i < mTypeList.count(); ++i ) {
00192     if ( mTypeList.at( i ) == -1 ) // "Other..." entry
00193       addItem( i18nc( "@item:inlistbox Category of contact info field", "Other..." ) );
00194     else
00195       addItem( KABC::Address::typeLabel( KABC::Address::Type( mTypeList.at( i ) ) ) );
00196   }
00197 
00198   setCurrentIndex( mLastSelected = mTypeList.indexOf( mType ) );
00199 
00200   blockSignals( blocked );
00201 }
00202 
00203 void AddressTypeCombo::selected( int pos )
00204 {
00205   if ( mTypeList.at( pos ) == -1 )
00206     otherSelected();
00207   else {
00208     mType = KABC::Address::Type( mTypeList.at( pos ) );
00209     mLastSelected = pos;
00210   }
00211 }
00212 
00213 void AddressTypeCombo::otherSelected()
00214 {
00215   AutoQPointer<AddressTypeDialog> dlg = new AddressTypeDialog( mType, this );
00216   if ( dlg->exec() ) {
00217     mType = dlg->type();
00218     if ( !mTypeList.contains( mType ) )
00219       mTypeList.insert( mTypeList.at( mTypeList.count() - 1 ), mType );
00220   } else {
00221     setType( KABC::Address::Type( mTypeList.at( mLastSelected ) ) );
00222   }
00223 
00224   update();
00225 }
00226 
00227 
00228 AddressEditWidget::AddressEditWidget( QWidget *parent )
00229   : QWidget( parent ), mReadOnly( false )
00230 {
00231   QGridLayout *layout = new QGridLayout( this );
00232   layout->setSpacing( KDialog::spacingHint() );
00233   layout->setMargin( 0 );
00234 
00235   mAddressSelectionWidget = new AddressSelectionWidget( this );
00236   connect( mAddressSelectionWidget, SIGNAL(selectionChanged(KABC::Address)),
00237            SLOT(updateAddressView()) );
00238   layout->addWidget( mAddressSelectionWidget, 0, 0, 1, 3 );
00239 
00240   mAddressView = new QLabel( this );
00241   mAddressView->setFrameStyle( QFrame::Panel | QFrame::Sunken );
00242   mAddressView->setMinimumHeight( 20 );
00243   mAddressView->setAlignment( Qt::AlignTop );
00244   mAddressView->setTextFormat( Qt::PlainText );
00245   mAddressView->setTextInteractionFlags( Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse );
00246   layout->addWidget( mAddressView, 1, 0, 1, 3 );
00247 
00248   mCreateButton = new QPushButton( i18nc( "street/postal", "New..." ), this );
00249   connect( mCreateButton, SIGNAL(clicked()), this, SLOT(createAddress()) );
00250   mEditButton = new QPushButton( i18nc( "street/postal", "Edit..." ), this );
00251   connect( mEditButton, SIGNAL(clicked()), this, SLOT(editAddress()) );
00252   mDeleteButton = new QPushButton( i18nc( "street/postal", "Delete" ), this );
00253   connect( mDeleteButton, SIGNAL(clicked()), this, SLOT(deleteAddress()) );
00254 
00255   layout->addWidget( mCreateButton, 2, 0 );
00256   layout->addWidget( mEditButton, 2, 1 );
00257   layout->addWidget( mDeleteButton, 2, 2 );
00258 
00259   updateButtons();
00260 }
00261 
00262 AddressEditWidget::~AddressEditWidget()
00263 {
00264 }
00265 
00266 void AddressEditWidget::setReadOnly( bool readOnly )
00267 {
00268   mReadOnly = readOnly;
00269   updateButtons();
00270 }
00271 
00272 void AddressEditWidget::updateName( const QString &name )
00273 {
00274   mName = name;
00275   updateAddressView();
00276 }
00277 
00278 void AddressEditWidget::createAddress()
00279 {
00280   AutoQPointer<AddressEditDialog> dialog = new AddressEditDialog( this );
00281   if ( dialog->exec() ) {
00282     const KABC::Address address = dialog->address();
00283     fixPreferredAddress( address );
00284     mAddressList.append( address );
00285     mAddressSelectionWidget->setAddresses( mAddressList );
00286     mAddressSelectionWidget->setCurrentAddress( address );
00287 
00288     updateAddressView();
00289     updateButtons();
00290   }
00291 }
00292 
00293 void AddressEditWidget::editAddress()
00294 {
00295   AutoQPointer<AddressEditDialog> dialog = new AddressEditDialog( this );
00296   dialog->setAddress( mAddressSelectionWidget->currentAddress() );
00297   if ( dialog->exec() ) {
00298     const KABC::Address address = dialog->address();
00299     fixPreferredAddress( address );
00300     mAddressList[ mAddressSelectionWidget->currentIndex() ] = address;
00301     mAddressSelectionWidget->setAddresses( mAddressList );
00302     mAddressSelectionWidget->setCurrentAddress( address );
00303 
00304     updateAddressView();
00305   }
00306 }
00307 
00308 void AddressEditWidget::deleteAddress()
00309 {
00310   const int result = KMessageBox::questionYesNo( this, i18n( "Do you really want to delete this address?" ) );
00311 
00312   if ( result != KMessageBox::Yes )
00313     return;
00314 
00315   mAddressList.removeAt( mAddressSelectionWidget->currentIndex() );
00316   mAddressSelectionWidget->setAddresses( mAddressList );
00317   updateAddressView();
00318   updateButtons();
00319 }
00320 
00321 void AddressEditWidget::fixPreferredAddress( const KABC::Address &preferredAddress )
00322 {
00323   // as the preferred address is mutual exclusive, we have to
00324   // remove the flag from all other addresses
00325   if ( preferredAddress.type() & KABC::Address::Pref ) {
00326     for ( int i = 0; i < mAddressList.count(); ++i ) {
00327       KABC::Address &address = mAddressList[ i ];
00328       address.setType( address.type() & ~KABC::Address::Pref );
00329     }
00330   }
00331 }
00332 
00333 void AddressEditWidget::updateAddressView()
00334 {
00335   const KABC::Address address = mAddressSelectionWidget->currentAddress();
00336 
00337   if ( address.isEmpty() )
00338     mAddressView->setText( QString() );
00339   else
00340     mAddressView->setText( address.formattedAddress( mName ) );
00341 }
00342 
00343 void AddressEditWidget::updateButtons()
00344 {
00345   mCreateButton->setEnabled( !mReadOnly );
00346   mEditButton->setEnabled( !mReadOnly && (mAddressList.count() > 0) );
00347   mDeleteButton->setEnabled( !mReadOnly && (mAddressList.count() > 0) );
00348 }
00349 
00350 void AddressEditWidget::loadContact( const KABC::Addressee &contact )
00351 {
00352   mName = contact.realName();
00353   mAddressList = contact.addresses();
00354 
00355   mAddressSelectionWidget->setAddresses( mAddressList );
00356 
00357   // set the preferred address as the visible one
00358   for ( int i = 0; i < mAddressList.count(); ++i ) {
00359     if ( mAddressList.at( i ).type() & KABC::Address::Pref ) {
00360       mAddressSelectionWidget->setCurrentAddress( mAddressList.at( i ) );
00361       break;
00362     }
00363   }
00364 
00365   updateAddressView();
00366   updateButtons();
00367 }
00368 
00369 void AddressEditWidget::storeContact( KABC::Addressee &contact ) const
00370 {
00371   // delete all previous addresses
00372   const KABC::Address::List oldAddresses = contact.addresses();
00373   for ( int i = 0; i < oldAddresses.count(); ++i )
00374     contact.removeAddress( oldAddresses.at( i ) );
00375 
00376   // insert the new ones
00377   for ( int i = 0; i < mAddressList.count(); ++i ) {
00378     const KABC::Address address( mAddressList.at( i ) );
00379     if ( !address.isEmpty() )
00380       contact.insertAddress( address );
00381   }
00382 }
00383 
00384 
00385 AddressEditDialog::AddressEditDialog( QWidget *parent )
00386   : KDialog(parent)
00387 {
00388   setCaption( i18nc( "street/postal", "Edit Address" ) );
00389   setButtons( Ok | Cancel );
00390   setDefaultButton( Ok );
00391   showButtonSeparator( true );
00392 
00393   QWidget *page = new QWidget( this );
00394   setMainWidget( page );
00395 
00396   QGridLayout *topLayout = new QGridLayout( page );
00397   topLayout->setSpacing( spacingHint() );
00398   topLayout->setMargin( 0 );
00399 
00400   mTypeCombo = new AddressTypeCombo( page );
00401   topLayout->addWidget( mTypeCombo, 0, 0, 1, 2 );
00402 
00403   QLabel *label = new QLabel( i18nc( "<streetLabel>:", "%1:", KABC::Address::streetLabel() ), page );
00404   label->setAlignment( Qt::AlignTop | Qt::AlignLeft );
00405   topLayout->addWidget( label, 1, 0 );
00406   mStreetTextEdit = new KTextEdit( page );
00407   mStreetTextEdit->setAcceptRichText( false );
00408   label->setBuddy( mStreetTextEdit );
00409   topLayout->addWidget( mStreetTextEdit, 1, 1 );
00410 
00411   TabPressEater *eater = new TabPressEater( this );
00412   mStreetTextEdit->installEventFilter( eater );
00413 
00414   label = new QLabel( i18nc( "<postOfficeBoxLabel>:", "%1:", KABC::Address::postOfficeBoxLabel() ), page );
00415   topLayout->addWidget( label, 2 , 0 );
00416   mPOBoxEdit = new KLineEdit( page );
00417   label->setBuddy( mPOBoxEdit );
00418   topLayout->addWidget( mPOBoxEdit, 2, 1 );
00419 
00420   label = new QLabel( i18nc( "<localityLabel>:", "%1:", KABC::Address::localityLabel() ), page );
00421   topLayout->addWidget( label, 3, 0 );
00422   mLocalityEdit = new KLineEdit( page );
00423   label->setBuddy( mLocalityEdit );
00424   topLayout->addWidget( mLocalityEdit, 3, 1 );
00425 
00426   label = new QLabel( i18nc( "<regionLabel>:", "%1:", KABC::Address::regionLabel() ), page );
00427   topLayout->addWidget( label, 4, 0 );
00428   mRegionEdit = new KLineEdit( page );
00429   label->setBuddy( mRegionEdit );
00430   topLayout->addWidget( mRegionEdit, 4, 1 );
00431 
00432   label = new QLabel( i18nc( "<postalCodeLabel>:", "%1:", KABC::Address::postalCodeLabel() ), page );
00433   topLayout->addWidget( label, 5, 0 );
00434   mPostalCodeEdit = new KLineEdit( page );
00435   label->setBuddy( mPostalCodeEdit );
00436   topLayout->addWidget( mPostalCodeEdit, 5, 1 );
00437 
00438   label = new QLabel( i18nc( "<countryLabel>:", "%1:", KABC::Address::countryLabel() ), page );
00439   topLayout->addWidget( label, 6, 0 );
00440   mCountryCombo = new KComboBox( page );
00441   mCountryCombo->setEditable( true );
00442   mCountryCombo->setDuplicatesEnabled( false );
00443 
00444   QPushButton *labelButton = new QPushButton( i18n( "Edit Label..." ), page );
00445   topLayout->addWidget( labelButton, 7, 0, 1, 2 );
00446   connect( labelButton, SIGNAL(clicked()), SLOT(editLabel()) );
00447 
00448   fillCountryCombo();
00449   label->setBuddy( mCountryCombo );
00450   topLayout->addWidget( mCountryCombo, 6, 1 );
00451 
00452   mPreferredCheckBox = new QCheckBox( i18nc( "street/postal", "This is the preferred address" ), page );
00453   topLayout->addWidget( mPreferredCheckBox, 8, 0, 1, 2 );
00454 
00455   KSeparator *sep = new KSeparator( Qt::Horizontal, page );
00456   topLayout->addWidget( sep, 9, 0, 1, 2 );
00457 
00458   KHBox *buttonBox = new KHBox( page );
00459   buttonBox->setSpacing( spacingHint() );
00460   topLayout->addWidget( buttonBox, 10, 0, 1, 2 );
00461 
00462   KAcceleratorManager::manage( this );
00463 }
00464 
00465 AddressEditDialog::~AddressEditDialog()
00466 {
00467 }
00468 
00469 void AddressEditDialog::editLabel()
00470 {
00471   bool ok = false;
00472   QString result = KInputDialog::getMultiLineText( KABC::Address::labelLabel(),
00473                                                    KABC::Address::labelLabel(),
00474                                                    mLabel, &ok, this );
00475   if ( ok )
00476     mLabel = result;
00477 }
00478 
00479 void AddressEditDialog::setAddress( const KABC::Address &address )
00480 {
00481   mAddress = address;
00482 
00483   mTypeCombo->setType( mAddress.type() );
00484   mStreetTextEdit->setPlainText( mAddress.street() );
00485   mRegionEdit->setText( mAddress.region() );
00486   mLocalityEdit->setText( mAddress.locality() );
00487   mPostalCodeEdit->setText( mAddress.postalCode() );
00488   mPOBoxEdit->setText( mAddress.postOfficeBox() );
00489   mLabel = mAddress.label();
00490   mPreferredCheckBox->setChecked( mAddress.type() & KABC::Address::Pref );
00491 
00492   if ( mAddress.isEmpty() )
00493     mCountryCombo->setItemText( mCountryCombo->currentIndex(),
00494                                 KGlobal::locale()->countryCodeToName( KGlobal::locale()->country() ) );
00495   else
00496     mCountryCombo->setItemText( mCountryCombo->currentIndex(), mAddress.country() );
00497 
00498   mStreetTextEdit->setFocus();
00499 }
00500 
00501 KABC::Address AddressEditDialog::address() const
00502 {
00503   KABC::Address address( mAddress );
00504 
00505   address.setType( mTypeCombo->type() );
00506   address.setLocality( mLocalityEdit->text() );
00507   address.setRegion( mRegionEdit->text() );
00508   address.setPostalCode( mPostalCodeEdit->text() );
00509   address.setCountry( mCountryCombo->currentText() );
00510   address.setPostOfficeBox( mPOBoxEdit->text() );
00511   address.setStreet( mStreetTextEdit->toPlainText() );
00512   address.setLabel( mLabel );
00513 
00514   if ( mPreferredCheckBox->isChecked() ) {
00515     address.setType( address.type() | KABC::Address::Pref );
00516   } else
00517     address.setType( address.type() & ~(KABC::Address::Pref) );
00518 
00519   return address;
00520 }
00521 
00522 void AddressEditDialog::fillCountryCombo()
00523 {
00524   QStringList countries;
00525 
00526   foreach ( const QString &cc, KGlobal::locale()->allCountriesList() )
00527     countries.append( KGlobal::locale()->countryCodeToName( cc ) );
00528 
00529   qSort( countries.begin(), countries.end(), LocaleAwareLessThan() );
00530 
00531   mCountryCombo->addItems( countries );
00532   mCountryCombo->setAutoCompletion( true );
00533   mCountryCombo->completionObject()->setItems( countries );
00534   mCountryCombo->completionObject()->setIgnoreCase( true );
00535 
00536   const QString currentCountry = KGlobal::locale()->countryCodeToName( KGlobal::locale()->country() );
00537   mCountryCombo->setCurrentIndex( mCountryCombo->findText( currentCountry ) );
00538 }
00539 
00540 
00541 AddressTypeDialog::AddressTypeDialog( KABC::Address::Type type, QWidget *parent )
00542   : KDialog( parent)
00543 {
00544   setCaption( i18nc( "street/postal", "Edit Address Type" ) );
00545   setButtons( Ok | Cancel );
00546   setDefaultButton( Ok );
00547 
00548   QWidget *page = new QWidget(this);
00549   setMainWidget( page );
00550   QVBoxLayout *layout = new QVBoxLayout( page );
00551   layout->setSpacing( KDialog::spacingHint() );
00552   layout->setMargin( 0 );
00553 
00554   QGroupBox *box  = new QGroupBox( i18nc( "street/postal", "Address Types" ), page );
00555   layout->addWidget( box );
00556   mGroup = new QButtonGroup( box );
00557   mGroup->setExclusive ( false );
00558 
00559   QGridLayout *buttonLayout = new QGridLayout( box );
00560 
00561   mTypeList = KABC::Address::typeList();
00562   mTypeList.removeAll( KABC::Address::Pref );
00563 
00564   KABC::Address::TypeList::ConstIterator it;
00565   int i = 0;
00566   int row = 0;
00567   for ( it = mTypeList.constBegin(); it != mTypeList.constEnd(); ++it, ++i ) {
00568     QCheckBox *cb = new QCheckBox( KABC::Address::typeLabel( *it ), box );
00569     cb->setChecked( type & mTypeList[ i ] );
00570     buttonLayout->addWidget( cb, row, i%3 );
00571 
00572     if( i%3 == 2 )
00573         ++row;
00574     mGroup->addButton( cb );
00575   }
00576 }
00577 
00578 AddressTypeDialog::~AddressTypeDialog()
00579 {
00580 }
00581 
00582 KABC::Address::Type AddressTypeDialog::type() const
00583 {
00584   KABC::Address::Type type;
00585   for ( int i = 0; i < mGroup->buttons().count(); ++i ) {
00586     QCheckBox *box = dynamic_cast<QCheckBox*>( mGroup->buttons().at( i ) );
00587     if ( box && box->isChecked() )
00588       type |= mTypeList[ i ];
00589   }
00590 
00591   return type;
00592 }
00593 
00594 #include "addresseditwidget.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu May 10 2012 22:19:25 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akonadi/contact

Skip menu "akonadi/contact"
  • Main Page
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Related Pages

kdepimlibs-4.8.3 API Reference

Skip menu "kdepimlibs-4.8.3 API Reference"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal