22 #include "customfieldseditwidget.h"
24 #include "customfieldeditordialog.h"
25 #include "customfieldmanager_p.h"
26 #include "customfieldsdelegate.h"
27 #include "customfieldsmodel.h"
29 #include <kabc/addressee.h>
30 #include <klocalizedstring.h>
31 #include <kmessagebox.h>
33 #include <QtCore/QPointer>
34 #include <QtCore/QUuid>
35 #include <QGridLayout>
36 #include <QPushButton>
38 #include <QSortFilterProxyModel>
40 void splitCustomField(
const QString &str, QString &app, QString &name, QString &value )
42 const int colon = str.indexOf( QLatin1Char(
':' ) );
44 const QString tmp = str.left( colon );
45 value = str.mid( colon + 1 );
47 const int dash = tmp.indexOf( QLatin1Char(
'-' ) );
49 app = tmp.left( dash );
50 name = tmp.mid( dash + 1 );
55 CustomFieldsEditWidget::CustomFieldsEditWidget( QWidget *parent )
56 : QWidget( parent ), mReadOnly( false )
58 QGridLayout *layout =
new QGridLayout(
this );
59 layout->setMargin( 0 );
61 mView =
new QTreeView;
62 mView->setSortingEnabled(
true);
63 mView->setRootIsDecorated(
false );
64 mView->setItemDelegate(
new CustomFieldsDelegate(
this ) );
66 mAddButton =
new QPushButton( i18n(
"Add..." ) );
67 mEditButton =
new QPushButton( i18n(
"Edit..." ) );
68 mRemoveButton =
new QPushButton( i18n(
"Remove" ) );
70 layout->addWidget( mView, 0, 0, 4, 1 );
71 layout->addWidget( mAddButton, 0, 1 );
72 layout->addWidget( mEditButton, 1, 1 );
73 layout->addWidget( mRemoveButton, 2, 1 );
75 mModel =
new CustomFieldsModel(
this );
76 QSortFilterProxyModel *proxyModel =
new QSortFilterProxyModel;
77 proxyModel->setDynamicSortFilter(
true);
78 proxyModel->setSourceModel(mModel);
79 mView->setModel( proxyModel );
80 mView->setColumnHidden( 2,
true );
82 connect( mView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
83 this, SLOT(slotUpdateButtons()) );
84 connect( mAddButton, SIGNAL(clicked()),
this, SLOT(slotAdd()) );
85 connect( mEditButton, SIGNAL(clicked()),
this, SLOT(slotEdit()) );
86 connect( mRemoveButton, SIGNAL(clicked()),
this, SLOT(slotRemove()) );
90 CustomFieldsEditWidget::~CustomFieldsEditWidget()
94 void CustomFieldsEditWidget::loadContact(
const KABC::Addressee &contact )
96 CustomField::List externalCustomFields;
98 CustomField::List globalCustomFields = CustomFieldManager::globalCustomFieldDescriptions();
100 const QStringList customs = contact.customs();
101 foreach (
const QString &custom, customs ) {
103 QString app, name, value;
104 splitCustomField( custom, app, name, value );
107 if ( custom.startsWith( QLatin1String(
"messaging/" ) ) ) {
111 if ( app == QLatin1String(
"KADDRESSBOOK" ) ) {
112 static QSet<QString> blacklist;
113 if ( blacklist.isEmpty() ) {
114 blacklist << QLatin1String(
"BlogFeed" )
115 << QLatin1String(
"X-IMAddress" )
116 << QLatin1String(
"X-Profession" )
117 << QLatin1String(
"X-Office" )
118 << QLatin1String(
"X-ManagersName" )
119 << QLatin1String(
"X-AssistantsName" )
120 << QLatin1String(
"X-Anniversary" )
121 << QLatin1String(
"X-ANNIVERSARY" )
122 << QLatin1String(
"X-SpousesName" )
123 << QLatin1String(
"X-Profession" )
124 << QLatin1String(
"MailPreferedFormatting")
125 << QLatin1String(
"MailAllowToRemoteContent")
126 << QLatin1String(
"CRYPTOPROTOPREF" )
127 << QLatin1String(
"OPENPGPFP" )
128 << QLatin1String(
"SMIMEFP" )
129 << QLatin1String(
"CRYPTOSIGNPREF" )
130 << QLatin1String(
"CRYPTOENCRYPTPREF" );
133 if ( blacklist.contains( name ) ) {
139 bool isLocalCustomField =
false;
140 for (
int i = 0; i < mLocalCustomFields.count(); ++i ) {
141 if ( mLocalCustomFields[ i ].key() == name ) {
142 mLocalCustomFields[ i ].setValue( value );
143 isLocalCustomField =
true;
149 bool isGlobalCustomField =
false;
150 for (
int i = 0; i < globalCustomFields.count(); ++i ) {
151 if ( globalCustomFields[ i ].key() == name ) {
152 globalCustomFields[ i ].setValue( value );
153 isGlobalCustomField =
true;
159 if ( !isLocalCustomField && !isGlobalCustomField ) {
160 if ( app == QLatin1String(
"KADDRESSBOOK" ) ) {
164 customField.setValue( value );
166 mLocalCustomFields << customField;
169 const QString key = app + QLatin1Char(
'-' ) + name;
171 customField.setValue( value );
173 externalCustomFields << customField;
178 mModel->setCustomFields( CustomField::List() << mLocalCustomFields << globalCustomFields << externalCustomFields );
181 void CustomFieldsEditWidget::storeContact( KABC::Addressee &contact )
const
183 const CustomField::List customFields = mModel->customFields();
184 foreach (
const CustomField &customField, customFields ) {
187 if ( !customField.value().isEmpty() ) {
188 contact.insertCustom( QLatin1String(
"KADDRESSBOOK" ), customField.key(), customField.value() );
190 contact.removeCustom( QLatin1String(
"KADDRESSBOOK" ), customField.key() );
198 foreach (
const CustomField &oldCustomField, mLocalCustomFields ) {
201 bool fieldStillExists =
false;
202 foreach (
const CustomField &newCustomField, customFields ) {
204 if ( newCustomField.key() == oldCustomField.key() ) {
205 fieldStillExists =
true;
211 if ( !fieldStillExists ) {
212 contact.removeCustom( QLatin1String(
"KADDRESSBOOK" ), oldCustomField.key() );
218 CustomField::List globalCustomFields;
219 foreach (
const CustomField &customField, customFields ) {
221 globalCustomFields << customField;
225 CustomFieldManager::setGlobalCustomFieldDescriptions( globalCustomFields );
228 void CustomFieldsEditWidget::setReadOnly(
bool readOnly )
230 mReadOnly = readOnly;
232 mView->setEnabled( !mReadOnly );
237 void CustomFieldsEditWidget::setLocalCustomFieldDescriptions(
const QVariantList &descriptions )
239 mLocalCustomFields.clear();
241 foreach (
const QVariant &description, descriptions ) {
246 QVariantList CustomFieldsEditWidget::localCustomFieldDescriptions()
const
248 const CustomField::List customFields = mModel->customFields();
250 QVariantList descriptions;
251 foreach (
const CustomField &field, customFields ) {
253 descriptions.append( field.toVariantMap() );
260 void CustomFieldsEditWidget::slotAdd()
268 QString key = QUuid::createUuid().toString();
269 key.remove( QLatin1Char(
'{' ) );
270 key.remove( QLatin1Char(
'}' ) );
274 QPointer<CustomFieldEditorDialog> dlg =
new CustomFieldEditorDialog(
this );
275 dlg->setCustomField( field );
277 if ( dlg->exec() == QDialog::Accepted ) {
278 const int lastRow = mModel->rowCount();
279 mModel->insertRow( lastRow );
281 field = dlg->customField();
282 mModel->setData( mModel->index( lastRow, 2 ), field.key(), Qt::EditRole );
283 mModel->setData( mModel->index( lastRow, 0 ), field.title(), Qt::EditRole );
284 mModel->setData( mModel->index( lastRow, 0 ), field.type(), CustomFieldsModel::TypeRole );
285 mModel->setData( mModel->index( lastRow, 0 ), field.scope(), CustomFieldsModel::ScopeRole );
291 void CustomFieldsEditWidget::slotEdit()
293 const QModelIndex currentIndex = mView->currentIndex();
294 if ( !currentIndex.isValid() ) {
299 field.setKey( mModel->index( currentIndex.row(), 2 ).data( Qt::DisplayRole ).toString() );
300 field.setTitle( mModel->index( currentIndex.row(), 0 ).data( Qt::DisplayRole ).toString() );
301 field.setType( static_cast<CustomField::Type>( currentIndex.data( CustomFieldsModel::TypeRole ).toInt() ) );
302 field.setScope( static_cast<CustomField::Scope>( currentIndex.data( CustomFieldsModel::ScopeRole ).toInt() ) );
304 QPointer<CustomFieldEditorDialog> dlg =
new CustomFieldEditorDialog(
this );
305 dlg->setCustomField( field );
307 if ( dlg->exec() == QDialog::Accepted ) {
308 field = dlg->customField();
309 mModel->setData( mModel->index( currentIndex.row(), 2 ), field.key(), Qt::EditRole );
310 mModel->setData( mModel->index( currentIndex.row(), 0 ), field.title(), Qt::EditRole );
311 mModel->setData( currentIndex, field.type(), CustomFieldsModel::TypeRole );
312 mModel->setData( currentIndex, field.scope(), CustomFieldsModel::ScopeRole );
318 void CustomFieldsEditWidget::slotRemove()
320 const QModelIndex currentIndex = mView->currentIndex();
321 if ( !currentIndex.isValid() ) {
325 if ( KMessageBox::warningContinueCancel(
this,
326 i18nc(
"Custom Fields",
"Do you really want to delete the selected custom field?" ),
327 i18n(
"Confirm Delete" ), KStandardGuiItem::del() ) != KMessageBox::Continue ) {
331 mModel->removeRow( currentIndex.row() );
334 void CustomFieldsEditWidget::slotUpdateButtons()
336 const bool hasCurrent = mView->currentIndex().isValid();
337 const bool isExternal = ( hasCurrent &&
340 mAddButton->setEnabled( !mReadOnly );
341 mEditButton->setEnabled( !mReadOnly && hasCurrent && !isExternal );
342 mRemoveButton->setEnabled( !mReadOnly && hasCurrent && !isExternal );
A class that represents non-standard contact fields.
Field has been defined by the external data source (e.g. vCard)
Field has been defined by user for all contacts.
Field has been defined by user for one contact.