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 );
63 mView =
new QTreeView;
64 mView->setSortingEnabled(
true);
65 mView->setRootIsDecorated(
false );
66 mView->setItemDelegate(
new CustomFieldsDelegate(
this ) );
68 mAddButton =
new QPushButton( i18n(
"Add..." ) );
69 mEditButton =
new QPushButton( i18n(
"Edit..." ) );
70 mRemoveButton =
new QPushButton( i18n(
"Remove" ) );
72 layout->addWidget( mView, 0, 0, 4, 1 );
73 layout->addWidget( mAddButton, 0, 1 );
74 layout->addWidget( mEditButton, 1, 1 );
75 layout->addWidget( mRemoveButton, 2, 1 );
77 mModel =
new CustomFieldsModel(
this );
78 QSortFilterProxyModel *proxyModel =
new QSortFilterProxyModel;
79 proxyModel->setDynamicSortFilter(
true);
80 proxyModel->setSourceModel(mModel);
81 mView->setModel( proxyModel );
82 mView->setColumnHidden( 2,
true );
84 connect( mView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
85 this, SLOT(slotUpdateButtons()) );
86 connect( mAddButton, SIGNAL(clicked()),
this, SLOT(slotAdd()) );
87 connect( mEditButton, SIGNAL(clicked()),
this, SLOT(slotEdit()) );
88 connect( mRemoveButton, SIGNAL(clicked()),
this, SLOT(slotRemove()) );
92 CustomFieldsEditWidget::~CustomFieldsEditWidget()
96 void CustomFieldsEditWidget::loadContact(
const KABC::Addressee &contact )
98 CustomField::List externalCustomFields;
100 CustomField::List globalCustomFields = CustomFieldManager::globalCustomFieldDescriptions();
102 const QStringList customs = contact.customs();
103 foreach (
const QString &custom, customs ) {
105 QString app, name, value;
106 splitCustomField( custom, app, name, value );
109 if ( custom.startsWith( QLatin1String(
"messaging/" ) ) ) {
113 if ( app == QLatin1String(
"KADDRESSBOOK" ) ) {
114 static QSet<QString> blacklist;
115 if ( blacklist.isEmpty() ) {
116 blacklist << QLatin1String(
"BlogFeed" )
117 << QLatin1String(
"X-IMAddress" )
118 << QLatin1String(
"X-Profession" )
119 << QLatin1String(
"X-Office" )
120 << QLatin1String(
"X-ManagersName" )
121 << QLatin1String(
"X-AssistantsName" )
122 << QLatin1String(
"X-Anniversary" )
123 << QLatin1String(
"X-ANNIVERSARY" )
124 << QLatin1String(
"X-SpousesName" )
125 << QLatin1String(
"X-Profession" )
126 << QLatin1String(
"MailPreferedFormatting")
127 << QLatin1String(
"MailAllowToRemoteContent")
128 << QLatin1String(
"CRYPTOPROTOPREF" )
129 << QLatin1String(
"OPENPGPFP" )
130 << QLatin1String(
"SMIMEFP" )
131 << QLatin1String(
"CRYPTOSIGNPREF" )
132 << QLatin1String(
"CRYPTOENCRYPTPREF" );
135 if ( blacklist.contains( name ) ) {
141 bool isLocalCustomField =
false;
142 for (
int i = 0; i < mLocalCustomFields.count(); ++i ) {
143 if ( mLocalCustomFields[ i ].key() == name ) {
144 mLocalCustomFields[ i ].setValue( value );
145 isLocalCustomField =
true;
151 bool isGlobalCustomField =
false;
152 for (
int i = 0; i < globalCustomFields.count(); ++i ) {
153 if ( globalCustomFields[ i ].key() == name ) {
154 globalCustomFields[ i ].setValue( value );
155 isGlobalCustomField =
true;
161 if ( !isLocalCustomField && !isGlobalCustomField ) {
162 if ( app == QLatin1String(
"KADDRESSBOOK" ) ) {
166 customField.setValue( value );
168 mLocalCustomFields << customField;
171 const QString key = app + QLatin1Char(
'-' ) + name;
173 customField.setValue( value );
175 externalCustomFields << customField;
180 mModel->setCustomFields( CustomField::List() << mLocalCustomFields << globalCustomFields << externalCustomFields );
183 void CustomFieldsEditWidget::storeContact( KABC::Addressee &contact )
const
185 const CustomField::List customFields = mModel->customFields();
186 foreach (
const CustomField &customField, customFields ) {
189 if ( !customField.value().isEmpty() ) {
190 contact.insertCustom( QLatin1String(
"KADDRESSBOOK" ), customField.key(), customField.value() );
192 contact.removeCustom( QLatin1String(
"KADDRESSBOOK" ), customField.key() );
200 foreach (
const CustomField &oldCustomField, mLocalCustomFields ) {
203 bool fieldStillExists =
false;
204 foreach (
const CustomField &newCustomField, customFields ) {
206 if ( newCustomField.key() == oldCustomField.key() ) {
207 fieldStillExists =
true;
213 if ( !fieldStillExists ) {
214 contact.removeCustom( QLatin1String(
"KADDRESSBOOK" ), oldCustomField.key() );
220 CustomField::List globalCustomFields;
221 foreach (
const CustomField &customField, customFields ) {
223 globalCustomFields << customField;
227 CustomFieldManager::setGlobalCustomFieldDescriptions( globalCustomFields );
230 void CustomFieldsEditWidget::setReadOnly(
bool readOnly )
232 mReadOnly = readOnly;
234 mView->setEnabled( !mReadOnly );
239 void CustomFieldsEditWidget::setLocalCustomFieldDescriptions(
const QVariantList &descriptions )
241 mLocalCustomFields.clear();
243 foreach (
const QVariant &description, descriptions ) {
248 QVariantList CustomFieldsEditWidget::localCustomFieldDescriptions()
const
250 const CustomField::List customFields = mModel->customFields();
252 QVariantList descriptions;
253 foreach (
const CustomField &field, customFields ) {
255 descriptions.append( field.toVariantMap() );
262 void CustomFieldsEditWidget::slotAdd()
270 QString key = QUuid::createUuid().toString();
271 key.remove( QLatin1Char(
'{' ) );
272 key.remove( QLatin1Char(
'}' ) );
276 QPointer<CustomFieldEditorDialog> dlg =
new CustomFieldEditorDialog(
this );
277 dlg->setCustomField( field );
279 if ( dlg->exec() == QDialog::Accepted ) {
280 const int lastRow = mModel->rowCount();
281 mModel->insertRow( lastRow );
283 field = dlg->customField();
284 mModel->setData( mModel->index( lastRow, 2 ), field.key(), Qt::EditRole );
285 mModel->setData( mModel->index( lastRow, 0 ), field.title(), Qt::EditRole );
286 mModel->setData( mModel->index( lastRow, 0 ), field.type(), CustomFieldsModel::TypeRole );
287 mModel->setData( mModel->index( lastRow, 0 ), field.scope(), CustomFieldsModel::ScopeRole );
293 void CustomFieldsEditWidget::slotEdit()
295 const QModelIndex currentIndex = mView->currentIndex();
296 if ( !currentIndex.isValid() ) {
301 field.setKey( mModel->index( currentIndex.row(), 2 ).data( Qt::DisplayRole ).toString() );
302 field.setTitle( mModel->index( currentIndex.row(), 0 ).data( Qt::DisplayRole ).toString() );
303 field.setType( static_cast<CustomField::Type>( currentIndex.data( CustomFieldsModel::TypeRole ).toInt() ) );
304 field.setScope( static_cast<CustomField::Scope>( currentIndex.data( CustomFieldsModel::ScopeRole ).toInt() ) );
306 QPointer<CustomFieldEditorDialog> dlg =
new CustomFieldEditorDialog(
this );
307 dlg->setCustomField( field );
309 if ( dlg->exec() == QDialog::Accepted ) {
310 field = dlg->customField();
311 mModel->setData( mModel->index( currentIndex.row(), 2 ), field.key(), Qt::EditRole );
312 mModel->setData( mModel->index( currentIndex.row(), 0 ), field.title(), Qt::EditRole );
313 mModel->setData( currentIndex, field.type(), CustomFieldsModel::TypeRole );
314 mModel->setData( currentIndex, field.scope(), CustomFieldsModel::ScopeRole );
320 void CustomFieldsEditWidget::slotRemove()
322 const QModelIndex currentIndex = mView->currentIndex();
323 if ( !currentIndex.isValid() ) {
327 if ( KMessageBox::warningContinueCancel(
this,
328 i18nc(
"Custom Fields",
"Do you really want to delete the selected custom field?" ),
329 i18n(
"Confirm Delete" ), KStandardGuiItem::del() ) != KMessageBox::Continue ) {
333 mModel->removeRow( currentIndex.row() );
336 void CustomFieldsEditWidget::slotUpdateButtons()
338 const bool hasCurrent = mView->currentIndex().isValid();
339 const bool isExternal = ( hasCurrent &&
342 mAddButton->setEnabled( !mReadOnly );
343 mEditButton->setEnabled( !mReadOnly && hasCurrent && !isExternal );
344 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.