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

akonadi/contact

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

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kblog
  • kcal
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.6.1
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