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

akonadi/contact

  • akonadi
  • contact
  • editor
addresseditwidget.cpp
1/*
2 This file is part of Akonadi Contact.
3
4 Copyright (c) 2009 Tobias Koenig <tokoe@kde.org>
5
6 This library is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Library General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or (at your
9 option) any later version.
10
11 This library is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14 License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301, USA.
20*/
21
22#include "addresseditwidget.h"
23
24#include "autoqpointer_p.h"
25
26#include <QtCore/QEvent>
27#include <QtCore/QList>
28#include <QApplication>
29#include <QButtonGroup>
30#include <QCheckBox>
31#include <QFrame>
32#include <QGridLayout>
33#include <QGroupBox>
34#include <QKeyEvent>
35#include <QLabel>
36#include <QPushButton>
37
38#include <kacceleratormanager.h>
39#include <kcombobox.h>
40#include <kdebug.h>
41#include <khbox.h>
42#include <kinputdialog.h>
43#include <klineedit.h>
44#include <klocale.h>
45#include <klocalizedstring.h>
46#include <kglobal.h>
47#include <kmessagebox.h>
48#include <kseparator.h>
49#include <ktextedit.h>
50
51#include <functional>
52
53struct LocaleAwareLessThan : std::binary_function<QString, QString, bool> {
54 bool operator()(const QString &s1, const QString &s2) const
55 {
56 return QString::localeAwareCompare(s1, s2) < 0 ;
57 }
58};
59
60class TabPressEater : public QObject
61{
62public:
63 TabPressEater(QObject *parent)
64 : QObject(parent)
65 {
66 setObjectName(QLatin1String("TabPressEater"));
67 }
68
69protected:
70 bool eventFilter(QObject *, QEvent *event)
71 {
72 if (event->type() == QEvent::KeyPress) {
73 QKeyEvent *keyEvent = (QKeyEvent *)event;
74 if (keyEvent->key() == Qt::Key_Tab) {
75 QApplication::sendEvent(parent(), event);
76 return true;
77 } else {
78 return false;
79 }
80 } else {
81 return false;
82 }
83 }
84};
85
91class AddressTypeDialog : public KDialog
92{
93public:
94 AddressTypeDialog(KABC::Address::Type type, QWidget *parent);
95 ~AddressTypeDialog();
96
97 KABC::Address::Type type() const;
98
99private:
100 QButtonGroup *mGroup;
101
102 KABC::Address::TypeList mTypeList;
103};
104
105AddressSelectionWidget::AddressSelectionWidget(QWidget *parent)
106 : KComboBox(parent)
107{
108 connect(this, SIGNAL(activated(int)), SLOT(selected(int)));
109}
110
111AddressSelectionWidget::~AddressSelectionWidget()
112{
113}
114
115void AddressSelectionWidget::setAddresses(const KABC::Address::List &addresses)
116{
117 mAddresses = addresses;
118 updateView();
119}
120
121void AddressSelectionWidget::setCurrentAddress(const KABC::Address &address)
122{
123 const int index = mAddresses.indexOf(address);
124 if (index != -1) {
125 setCurrentIndex(index);
126 }
127}
128
129KABC::Address AddressSelectionWidget::currentAddress() const
130{
131 if (currentIndex() != -1 && currentIndex() < mAddresses.count()) {
132 return mAddresses.at(currentIndex());
133 } else {
134 return KABC::Address();
135 }
136}
137
138void AddressSelectionWidget::selected(int index)
139{
140 Q_ASSERT(index != -1 && index < mAddresses.count());
141 emit selectionChanged(mAddresses.at(index));
142}
143
144void AddressSelectionWidget::updateView()
145{
146 clear();
147 for (int i = 0; i < mAddresses.count(); ++i) {
148 addItem(KABC::Address::typeLabel(mAddresses.at(i).type()));
149 }
150}
151
152AddressTypeCombo::AddressTypeCombo(QWidget *parent)
153 : KComboBox(parent)
154 , mType(KABC::Address::Home)
155 , mLastSelected(0)
156{
157 for (int i = 0; i < KABC::Address::typeList().count(); ++i) {
158 mTypeList.append(KABC::Address::typeList().at(i));
159 }
160 mTypeList.append(-1); // Others...
161
162 update();
163
164 connect(this, SIGNAL(activated(int)),
165 this, SLOT(selected(int)));
166}
167
168AddressTypeCombo::~AddressTypeCombo()
169{
170}
171
172void AddressTypeCombo::setType(KABC::Address::Type type)
173{
174 if (!mTypeList.contains((int)type)) {
175 // insert at the end, but before the 'Others...' entry
176 mTypeList.insert(mTypeList.at(mTypeList.count() - 1), (int)type);
177 }
178
179 mType = type;
180 update();
181}
182
183KABC::Address::Type AddressTypeCombo::type() const
184{
185 return mType;
186}
187
188void AddressTypeCombo::update()
189{
190 bool blocked = signalsBlocked();
191 blockSignals(true);
192
193 clear();
194 for (int i = 0; i < mTypeList.count(); ++i) {
195 if (mTypeList.at(i) == -1) { // "Other..." entry
196 addItem(i18nc("@item:inlistbox Category of contact info field", "Other..."));
197 } else {
198 addItem(KABC::Address::typeLabel(KABC::Address::Type(mTypeList.at(i))));
199 }
200 }
201
202 setCurrentIndex(mLastSelected = mTypeList.indexOf(mType));
203
204 blockSignals(blocked);
205}
206
207void AddressTypeCombo::selected(int pos)
208{
209 if (mTypeList.at(pos) == -1) {
210 otherSelected();
211 } else {
212 mType = KABC::Address::Type(mTypeList.at(pos));
213 mLastSelected = pos;
214 }
215}
216
217void AddressTypeCombo::otherSelected()
218{
219 AutoQPointer<AddressTypeDialog> dlg = new AddressTypeDialog(mType, this);
220 if (dlg->exec()) {
221 mType = dlg->type();
222 if (!mTypeList.contains(mType)) {
223 mTypeList.insert(mTypeList.at(mTypeList.count() - 1), mType);
224 }
225 } else {
226 setType(KABC::Address::Type(mTypeList.at(mLastSelected)));
227 }
228
229 update();
230}
231
232AddressEditWidget::AddressEditWidget(QWidget *parent)
233 : QWidget(parent)
234 , mReadOnly(false)
235{
236 QGridLayout *layout = new QGridLayout;
237 layout->setSpacing(KDialog::spacingHint());
238 layout->setMargin(0);
239
240 QHBoxLayout *hboxLayout = new QHBoxLayout;
241 QLabel *label = new QLabel(i18nc("@label:listbox type of address", "Address type:"), this);
242 hboxLayout->addWidget(label);
243
244 mAddressSelectionWidget = new AddressSelectionWidget(this);
245 connect(mAddressSelectionWidget, SIGNAL(selectionChanged(KABC::Address)),
246 SLOT(updateAddressView()));
247 label->setBuddy(mAddressSelectionWidget);
248 hboxLayout->addWidget(mAddressSelectionWidget, 1);
249 layout->addLayout(hboxLayout, 0, 0, 1, 3);
250
251 mAddressView = new QLabel(this);
252 mAddressView->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
253 mAddressView->setMinimumHeight(20);
254 mAddressView->setAlignment(Qt::AlignTop);
255 mAddressView->setTextFormat(Qt::PlainText);
256 mAddressView->setTextInteractionFlags(Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse);
257 layout->addWidget(mAddressView, 1, 0, 1, 3);
258
259 mCreateButton = new QPushButton(i18nc("@action:button street/postal", "New..."), this);
260 connect(mCreateButton, SIGNAL(clicked()), this, SLOT(createAddress()));
261 mEditButton = new QPushButton(i18nc("@action:button street/postal", "Edit..."), this);
262 connect(mEditButton, SIGNAL(clicked()), this, SLOT(editAddress()));
263 mDeleteButton = new QPushButton(i18nc("@action:button street/postal", "Delete"), this);
264 connect(mDeleteButton, SIGNAL(clicked()), this, SLOT(deleteAddress()));
265
266 layout->addWidget(mCreateButton, 2, 0);
267 layout->addWidget(mEditButton, 2, 1);
268 layout->addWidget(mDeleteButton, 2, 2);
269 setLayout(layout);
270 updateButtons();
271}
272
273AddressEditWidget::~AddressEditWidget()
274{
275}
276
277void AddressEditWidget::setReadOnly(bool readOnly)
278{
279 if (mReadOnly != readOnly) {
280 mReadOnly = readOnly;
281 updateButtons();
282 }
283}
284
285void AddressEditWidget::updateName(const QString &name)
286{
287 if (mName != name) {
288 mName = name;
289 updateAddressView();
290 }
291}
292
293void AddressEditWidget::createAddress()
294{
295 AutoQPointer<AddressEditDialog> dialog = new AddressEditDialog(this);
296 if (dialog->exec()) {
297 const KABC::Address address = dialog->address();
298 fixPreferredAddress(address);
299 mAddressList.append(address);
300 mAddressSelectionWidget->setAddresses(mAddressList);
301 mAddressSelectionWidget->setCurrentAddress(address);
302
303 updateAddressView();
304 updateButtons();
305 }
306}
307
308void AddressEditWidget::editAddress()
309{
310 AutoQPointer<AddressEditDialog> dialog = new AddressEditDialog(this);
311 dialog->setAddress(mAddressSelectionWidget->currentAddress());
312 if (dialog->exec()) {
313 const KABC::Address address = dialog->address();
314 fixPreferredAddress(address);
315 mAddressList[mAddressSelectionWidget->currentIndex()] = address;
316 mAddressSelectionWidget->setAddresses(mAddressList);
317 mAddressSelectionWidget->setCurrentAddress(address);
318
319 updateAddressView();
320 }
321}
322
323void AddressEditWidget::deleteAddress()
324{
325 const int result = KMessageBox::questionYesNo(this, i18n("Do you really want to delete this address?"));
326
327 if (result != KMessageBox::Yes) {
328 return;
329 }
330
331 mAddressList.removeAt(mAddressSelectionWidget->currentIndex());
332 mAddressSelectionWidget->setAddresses(mAddressList);
333 updateAddressView();
334 updateButtons();
335}
336
337void AddressEditWidget::fixPreferredAddress(const KABC::Address &preferredAddress)
338{
339 // as the preferred address is mutual exclusive, we have to
340 // remove the flag from all other addresses
341 if (preferredAddress.type() &KABC::Address::Pref) {
342 for (int i = 0; i < mAddressList.count(); ++i) {
343 KABC::Address &address = mAddressList[i];
344 address.setType(address.type() &~KABC::Address::Pref);
345 }
346 }
347}
348
349void AddressEditWidget::updateAddressView()
350{
351 const KABC::Address address = mAddressSelectionWidget->currentAddress();
352
353 if (address.isEmpty()) {
354 mAddressView->setText(QString());
355 } else {
356 mAddressView->setText(address.formattedAddress(mName));
357 }
358}
359
360void AddressEditWidget::updateButtons()
361{
362 mCreateButton->setEnabled(!mReadOnly);
363 mEditButton->setEnabled(!mReadOnly && (mAddressList.count() > 0));
364 mDeleteButton->setEnabled(!mReadOnly && (mAddressList.count() > 0));
365}
366
367void AddressEditWidget::loadContact(const KABC::Addressee &contact)
368{
369 mName = contact.realName();
370 mAddressList = contact.addresses();
371
372 mAddressSelectionWidget->setAddresses(mAddressList);
373
374 // set the preferred address as the visible one
375 for (int i = 0; i < mAddressList.count(); ++i) {
376 if (mAddressList.at(i).type() &KABC::Address::Pref) {
377 mAddressSelectionWidget->setCurrentAddress(mAddressList.at(i));
378 break;
379 }
380 }
381
382 updateAddressView();
383 updateButtons();
384}
385
386void AddressEditWidget::storeContact(KABC::Addressee &contact) const
387{
388 // delete all previous addresses
389 const KABC::Address::List oldAddresses = contact.addresses();
390 for (int i = 0; i < oldAddresses.count(); ++i) {
391 contact.removeAddress(oldAddresses.at(i));
392 }
393
394 // insert the new ones
395 for (int i = 0; i < mAddressList.count(); ++i) {
396 const KABC::Address address(mAddressList.at(i));
397 if (!address.isEmpty()) {
398 contact.insertAddress(address);
399 }
400 }
401}
402
403AddressEditDialog::AddressEditDialog(QWidget *parent)
404 : KDialog(parent)
405{
406 setCaption(i18nc("street/postal", "Edit Address"));
407 setButtons(Ok | Cancel);
408 setDefaultButton(Ok);
409 showButtonSeparator(true);
410
411 QWidget *page = new QWidget(this);
412 setMainWidget(page);
413
414 QGridLayout *topLayout = new QGridLayout(page);
415 topLayout->setSpacing(spacingHint());
416 topLayout->setMargin(0);
417
418 QLabel *label = new QLabel(i18nc("@label:listbox type of address", "Address type:"), this);
419 topLayout->addWidget(label, 0, 0);
420
421 mTypeCombo = new AddressTypeCombo(page);
422 label->setBuddy(mTypeCombo);
423 topLayout->addWidget(mTypeCombo, 0, 1);
424
425 label = new QLabel(i18nc("<streetLabel>:", "%1:", KABC::Address::streetLabel()), page);
426 label->setAlignment(Qt::AlignTop | Qt::AlignLeft);
427 topLayout->addWidget(label, 1, 0);
428 mStreetTextEdit = new KTextEdit(page);
429 mStreetTextEdit->setAcceptRichText(false);
430 label->setBuddy(mStreetTextEdit);
431 topLayout->addWidget(mStreetTextEdit, 1, 1);
432
433 TabPressEater *eater = new TabPressEater(this);
434 mStreetTextEdit->installEventFilter(eater);
435
436 label = new QLabel(i18nc("<postOfficeBoxLabel>:", "%1:", KABC::Address::postOfficeBoxLabel()), page);
437 topLayout->addWidget(label, 2 , 0);
438 mPOBoxEdit = new KLineEdit(page);
439 mPOBoxEdit->setTrapReturnKey(true);
440 label->setBuddy(mPOBoxEdit);
441 topLayout->addWidget(mPOBoxEdit, 2, 1);
442
443 label = new QLabel(i18nc("<localityLabel>:", "%1:", KABC::Address::localityLabel()), page);
444 topLayout->addWidget(label, 3, 0);
445 mLocalityEdit = new KLineEdit(page);
446 mLocalityEdit->setTrapReturnKey(true);
447 label->setBuddy(mLocalityEdit);
448 topLayout->addWidget(mLocalityEdit, 3, 1);
449
450 label = new QLabel(i18nc("<regionLabel>:", "%1:", KABC::Address::regionLabel()), page);
451 topLayout->addWidget(label, 4, 0);
452 mRegionEdit = new KLineEdit(page);
453 mRegionEdit->setTrapReturnKey(true);
454 label->setBuddy(mRegionEdit);
455 topLayout->addWidget(mRegionEdit, 4, 1);
456
457 label = new QLabel(i18nc("<postalCodeLabel>:", "%1:", KABC::Address::postalCodeLabel()), page);
458 topLayout->addWidget(label, 5, 0);
459 mPostalCodeEdit = new KLineEdit(page);
460 mPostalCodeEdit->setTrapReturnKey(true);
461 label->setBuddy(mPostalCodeEdit);
462 topLayout->addWidget(mPostalCodeEdit, 5, 1);
463
464 label = new QLabel(i18nc("<countryLabel>:", "%1:", KABC::Address::countryLabel()), page);
465 topLayout->addWidget(label, 6, 0);
466 mCountryCombo = new KComboBox(page);
467 mCountryCombo->setEditable(true);
468 mCountryCombo->setDuplicatesEnabled(false);
469
470 QPushButton *labelButton = new QPushButton(i18n("Edit Label..."), page);
471 topLayout->addWidget(labelButton, 7, 0, 1, 2);
472 connect(labelButton, SIGNAL(clicked()), SLOT(editLabel()));
473
474 fillCountryCombo();
475 label->setBuddy(mCountryCombo);
476 topLayout->addWidget(mCountryCombo, 6, 1);
477
478 mPreferredCheckBox = new QCheckBox(i18nc("street/postal", "This is the preferred address"), page);
479 topLayout->addWidget(mPreferredCheckBox, 8, 0, 1, 2);
480
481 KHBox *buttonBox = new KHBox(page);
482 buttonBox->setSpacing(spacingHint());
483 topLayout->addWidget(buttonBox, 9, 0, 1, 2);
484
485 KAcceleratorManager::manage(this);
486}
487
488AddressEditDialog::~AddressEditDialog()
489{
490}
491
492void AddressEditDialog::editLabel()
493{
494 bool ok = false;
495 QString result = KInputDialog::getMultiLineText(KABC::Address::labelLabel(),
496 KABC::Address::labelLabel(),
497 mLabel, &ok, this);
498 if (ok) {
499 mLabel = result;
500 }
501}
502
503void AddressEditDialog::setAddress(const KABC::Address &address)
504{
505 mAddress = address;
506
507 mTypeCombo->setType(mAddress.type());
508 mStreetTextEdit->setPlainText(mAddress.street());
509 mRegionEdit->setText(mAddress.region());
510 mLocalityEdit->setText(mAddress.locality());
511 mPostalCodeEdit->setText(mAddress.postalCode());
512 mPOBoxEdit->setText(mAddress.postOfficeBox());
513 mLabel = mAddress.label();
514 mPreferredCheckBox->setChecked(mAddress.type() &KABC::Address::Pref);
515
516 if (mAddress.isEmpty()) {
517 mCountryCombo->setItemText(mCountryCombo->currentIndex(),
518 KGlobal::locale()->countryCodeToName(KGlobal::locale()->country()));
519 } else {
520 mCountryCombo->setItemText(mCountryCombo->currentIndex(), mAddress.country());
521 }
522
523 mStreetTextEdit->setFocus();
524}
525
526KABC::Address AddressEditDialog::address() const
527{
528 KABC::Address address(mAddress);
529
530 address.setType(mTypeCombo->type());
531 address.setLocality(mLocalityEdit->text());
532 address.setRegion(mRegionEdit->text());
533 address.setPostalCode(mPostalCodeEdit->text());
534 address.setCountry(mCountryCombo->currentText());
535 address.setPostOfficeBox(mPOBoxEdit->text());
536 address.setStreet(mStreetTextEdit->toPlainText());
537 address.setLabel(mLabel);
538
539 if (mPreferredCheckBox->isChecked()) {
540 address.setType(address.type() | KABC::Address::Pref);
541 } else {
542 address.setType(address.type() &~(KABC::Address::Pref));
543 }
544
545 return address;
546}
547
548void AddressEditDialog::fillCountryCombo()
549{
550 QStringList countries;
551
552 foreach (const QString &cc, KGlobal::locale()->allCountriesList()) {
553 countries.append(KGlobal::locale()->countryCodeToName(cc));
554 }
555
556 qSort(countries.begin(), countries.end(), LocaleAwareLessThan());
557
558 mCountryCombo->addItems(countries);
559 mCountryCombo->setAutoCompletion(true);
560 mCountryCombo->completionObject()->setItems(countries);
561 mCountryCombo->completionObject()->setIgnoreCase(true);
562
563 const QString currentCountry = KGlobal::locale()->countryCodeToName(KGlobal::locale()->country());
564 mCountryCombo->setCurrentIndex(mCountryCombo->findText(currentCountry));
565}
566
567AddressTypeDialog::AddressTypeDialog(KABC::Address::Type type, QWidget *parent)
568 : KDialog(parent)
569{
570 setCaption(i18nc("street/postal", "Edit Address Type"));
571 setButtons(Ok | Cancel);
572 setDefaultButton(Ok);
573
574 QWidget *page = new QWidget(this);
575 setMainWidget(page);
576 QVBoxLayout *layout = new QVBoxLayout(page);
577 layout->setSpacing(KDialog::spacingHint());
578 layout->setMargin(0);
579
580 QGroupBox *box = new QGroupBox(i18nc("street/postal", "Address Types"), page);
581 layout->addWidget(box);
582 mGroup = new QButtonGroup(box);
583 mGroup->setExclusive(false);
584
585 QGridLayout *buttonLayout = new QGridLayout(box);
586
587 mTypeList = KABC::Address::typeList();
588 mTypeList.removeAll(KABC::Address::Pref);
589
590 KABC::Address::TypeList::ConstIterator it;
591 int i = 0;
592 int row = 0;
593 for (it = mTypeList.constBegin(); it != mTypeList.constEnd(); ++it, ++i) {
594 QCheckBox *cb = new QCheckBox(KABC::Address::typeLabel(*it), box);
595 cb->setChecked(type &mTypeList[i]);
596 buttonLayout->addWidget(cb, row, i % 3);
597
598 if (i % 3 == 2) {
599 ++row;
600 }
601 mGroup->addButton(cb);
602 }
603}
604
605AddressTypeDialog::~AddressTypeDialog()
606{
607}
608
609KABC::Address::Type AddressTypeDialog::type() const
610{
611 KABC::Address::Type type;
612 for (int i = 0; i < mGroup->buttons().count(); ++i) {
613 QCheckBox *box = dynamic_cast<QCheckBox *>(mGroup->buttons().at(i));
614 if (box && box->isChecked()) {
615 type |= mTypeList[i];
616 }
617 }
618
619 return type;
620}
AddressEditDialog
Dialog for editing address details.
Definition addresseditwidget.h:181
AddressSelectionWidget
A widget that shows a list of addresses for selection.
Definition addresseditwidget.h:42
AddressSelectionWidget::setCurrentAddress
void setCurrentAddress(const KABC::Address &address)
Sets the current address.
Definition addresseditwidget.cpp:121
AddressSelectionWidget::setAddresses
void setAddresses(const KABC::Address::List &addresses)
Sets the list of addresses that can be chosen from.
Definition addresseditwidget.cpp:115
AddressSelectionWidget::selectionChanged
void selectionChanged(const KABC::Address &address)
This signal is emitted whenever the selection of the address has changed.
AddressSelectionWidget::AddressSelectionWidget
AddressSelectionWidget(QWidget *parent=0)
Creates a new address selection widget.
Definition addresseditwidget.cpp:105
AddressSelectionWidget::~AddressSelectionWidget
virtual ~AddressSelectionWidget()
Destroys the address selection widget.
Definition addresseditwidget.cpp:111
AddressSelectionWidget::currentAddress
KABC::Address currentAddress() const
Returns the current selected address.
Definition addresseditwidget.cpp:129
AddressTypeCombo::type
KABC::Address::Type type() const
Returns the type that is currently selected.
Definition addresseditwidget.cpp:183
AddressTypeCombo::AddressTypeCombo
AddressTypeCombo(QWidget *parent=0)
Creates a new address type combo.
Definition addresseditwidget.cpp:152
AddressTypeCombo::setType
void setType(KABC::Address::Type type)
Sets the type that shall be selected in the combobox.
Definition addresseditwidget.cpp:172
AddressTypeCombo::~AddressTypeCombo
~AddressTypeCombo()
Destroys the address type combo.
Definition addresseditwidget.cpp:168
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Wed Jan 24 2024 00:00:00 by doxygen 1.10.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.14.10 API Reference

Skip menu "kdepimlibs-4.14.10 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • 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