00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "customfieldseditwidget.h"
00023
00024 #include "customfieldeditordialog.h"
00025 #include "customfieldmanager_p.h"
00026 #include "customfieldsdelegate.h"
00027 #include "customfieldsmodel.h"
00028
00029 #include <kabc/addressee.h>
00030 #include <klocale.h>
00031 #include <kmessagebox.h>
00032
00033 #include <QtCore/QPointer>
00034 #include <QtCore/QUuid>
00035 #include <QtGui/QGridLayout>
00036 #include <QtGui/QPushButton>
00037 #include <QtGui/QTreeView>
00038
00039 void splitCustomField( const QString &str, QString &app, QString &name, QString &value )
00040 {
00041 const int colon = str.indexOf( QLatin1Char( ':' ) );
00042 if ( colon != -1 ) {
00043 const QString tmp = str.left( colon );
00044 value = str.mid( colon + 1 );
00045
00046 const int dash = tmp.indexOf( QLatin1Char( '-' ) );
00047 if ( dash != -1 ) {
00048 app = tmp.left( dash );
00049 name = tmp.mid( dash + 1 );
00050 }
00051 }
00052 }
00053
00054 CustomFieldsEditWidget::CustomFieldsEditWidget( QWidget *parent )
00055 : QWidget( parent ), mReadOnly( false )
00056 {
00057 QGridLayout *layout = new QGridLayout( this );
00058 layout->setMargin( 0 );
00059
00060 mView = new QTreeView;
00061 mView->setRootIsDecorated( false );
00062 mView->setItemDelegate( new CustomFieldsDelegate( this ) );
00063
00064 mAddButton = new QPushButton( i18n( "Add..." ) );
00065 mEditButton = new QPushButton( i18n( "Edit..." ) );
00066 mRemoveButton = new QPushButton( i18n( "Remove" ) );
00067
00068 layout->addWidget( mView, 0, 0, 4, 1 );
00069 layout->addWidget( mAddButton, 0, 1 );
00070 layout->addWidget( mEditButton, 1, 1 );
00071 layout->addWidget( mRemoveButton, 2, 1 );
00072
00073 mModel = new CustomFieldsModel( this );
00074 mView->setModel( mModel );
00075 mView->setColumnHidden( 2, true );
00076
00077 connect( mView->selectionModel(), SIGNAL( currentChanged( const QModelIndex&, const QModelIndex& ) ),
00078 this, SLOT( slotUpdateButtons() ) );
00079 connect( mAddButton, SIGNAL( clicked() ), this, SLOT( slotAdd() ) );
00080 connect( mEditButton, SIGNAL( clicked() ), this, SLOT( slotEdit() ) );
00081 connect( mRemoveButton, SIGNAL( clicked() ), this, SLOT( slotRemove() ) );
00082 }
00083
00084 CustomFieldsEditWidget::~CustomFieldsEditWidget()
00085 {
00086 }
00087
00088 void CustomFieldsEditWidget::loadContact( const KABC::Addressee &contact )
00089 {
00090 CustomField::List externalCustomFields;
00091
00092 CustomField::List globalCustomFields = CustomFieldManager::globalCustomFieldDescriptions();
00093
00094 const QStringList customs = contact.customs();
00095 foreach ( const QString &custom, customs ) {
00096
00097 QString app, name, value;
00098 splitCustomField( custom, app, name, value );
00099
00100
00101 if ( custom.startsWith( QLatin1String( "messaging/" ) ) )
00102 continue;
00103
00104 if ( app == QLatin1String( "KADDRESSBOOK" ) ) {
00105 static QSet<QString> blacklist;
00106 if ( blacklist.isEmpty() ) {
00107 blacklist << QLatin1String( "BlogFeed" )
00108 << QLatin1String( "X-IMAddress" )
00109 << QLatin1String( "X-Profession" )
00110 << QLatin1String( "X-Office" )
00111 << QLatin1String( "X-ManagersName" )
00112 << QLatin1String( "X-AssistantsName" )
00113 << QLatin1String( "X-Anniversary" )
00114 << QLatin1String( "X-SpousesName" )
00115 << QLatin1String( "X-Profession" );
00116 }
00117
00118 if ( blacklist.contains( name ) )
00119 continue;
00120 }
00121
00122
00123 bool isLocalCustomField = false;
00124 for ( int i = 0; i < mLocalCustomFields.count(); ++i ) {
00125 if ( mLocalCustomFields[ i ].key() == name ) {
00126 mLocalCustomFields[ i ].setValue( value );
00127 isLocalCustomField = true;
00128 break;
00129 }
00130 }
00131
00132
00133 bool isGlobalCustomField = false;
00134 for ( int i = 0; i < globalCustomFields.count(); ++i ) {
00135 if ( globalCustomFields[ i ].key() == name ) {
00136 globalCustomFields[ i ].setValue( value );
00137 isGlobalCustomField = true;
00138 break;
00139 }
00140 }
00141
00142
00143 if ( !isLocalCustomField && !isGlobalCustomField ) {
00144 if ( app == QLatin1String( "KADDRESSBOOK" ) ) {
00145
00146
00147 CustomField customField( name, name, CustomField::TextType, CustomField::LocalScope );
00148 customField.setValue( value );
00149
00150 mLocalCustomFields << customField;
00151 } else {
00152
00153 const QString key = app + QLatin1Char( '-' ) + name;
00154 CustomField customField( key, key, CustomField::TextType, CustomField::ExternalScope );
00155 customField.setValue( value );
00156
00157 externalCustomFields << customField;
00158 }
00159 }
00160 }
00161
00162 mModel->setCustomFields( CustomField::List() << mLocalCustomFields << globalCustomFields << externalCustomFields );
00163 }
00164
00165 void CustomFieldsEditWidget::storeContact( KABC::Addressee &contact ) const
00166 {
00167 const CustomField::List customFields = mModel->customFields();
00168 foreach ( const CustomField &customField, customFields ) {
00169
00170 if ( customField.scope() != CustomField::ExternalScope ) {
00171 if ( !customField.value().isEmpty() )
00172 contact.insertCustom( QLatin1String( "KADDRESSBOOK" ), customField.key(), customField.value() );
00173 else
00174 contact.removeCustom( QLatin1String( "KADDRESSBOOK" ), customField.key() );
00175 }
00176 }
00177
00178
00179
00180
00181 foreach ( const CustomField &oldCustomField, mLocalCustomFields ) {
00182 if ( oldCustomField.scope() != CustomField::ExternalScope ) {
00183
00184 bool fieldStillExists = false;
00185 foreach ( const CustomField &newCustomField, customFields ) {
00186 if ( newCustomField.scope() != CustomField::ExternalScope ) {
00187 if ( newCustomField.key() == oldCustomField.key() ) {
00188 fieldStillExists = true;
00189 break;
00190 }
00191 }
00192 }
00193
00194 if ( !fieldStillExists )
00195 contact.removeCustom( QLatin1String( "KADDRESSBOOK" ), oldCustomField.key() );
00196 }
00197 }
00198
00199
00200 CustomField::List globalCustomFields;
00201 foreach ( const CustomField &customField, customFields ) {
00202 if ( customField.scope() == CustomField::GlobalScope ) {
00203 globalCustomFields << customField;
00204 }
00205 }
00206
00207 CustomFieldManager::setGlobalCustomFieldDescriptions( globalCustomFields );
00208 }
00209
00210 void CustomFieldsEditWidget::setReadOnly( bool readOnly )
00211 {
00212 mReadOnly = readOnly;
00213
00214 mView->setEnabled( !mReadOnly );
00215
00216 slotUpdateButtons();
00217 }
00218
00219 void CustomFieldsEditWidget::setLocalCustomFieldDescriptions( const QVariantList &descriptions )
00220 {
00221 mLocalCustomFields.clear();
00222
00223 foreach ( const QVariant &description, descriptions )
00224 mLocalCustomFields.append( CustomField::fromVariantMap( description.toMap(), CustomField::LocalScope ) );
00225 }
00226
00227 QVariantList CustomFieldsEditWidget::localCustomFieldDescriptions() const
00228 {
00229 const CustomField::List customFields = mModel->customFields();
00230
00231 QVariantList descriptions;
00232 foreach ( const CustomField &field, customFields ) {
00233 if ( field.scope() == CustomField::LocalScope )
00234 descriptions.append( field.toVariantMap() );
00235 }
00236
00237 return descriptions;
00238 }
00239
00240 void CustomFieldsEditWidget::slotAdd()
00241 {
00242 CustomField field;
00243
00244
00245
00246
00247
00248 QString key = QUuid::createUuid().toString();
00249 key.remove( QLatin1Char( '{' ) );
00250 key.remove( QLatin1Char( '}' ) );
00251
00252 field.setKey( key );
00253
00254 QPointer<CustomFieldEditorDialog> dlg = new CustomFieldEditorDialog( this );
00255 dlg->setCustomField( field );
00256
00257 if ( dlg->exec() == QDialog::Accepted ) {
00258 const int lastRow = mModel->rowCount();
00259 mModel->insertRow( lastRow );
00260
00261 field = dlg->customField();
00262 mModel->setData( mModel->index( lastRow, 2 ), field.key(), Qt::EditRole );
00263 mModel->setData( mModel->index( lastRow, 0 ), field.title(), Qt::EditRole );
00264 mModel->setData( mModel->index( lastRow, 0 ), field.type(), CustomFieldsModel::TypeRole );
00265 mModel->setData( mModel->index( lastRow, 0 ), field.scope(), CustomFieldsModel::ScopeRole );
00266 }
00267
00268 delete dlg;
00269 }
00270
00271 void CustomFieldsEditWidget::slotEdit()
00272 {
00273 const QModelIndex currentIndex = mView->currentIndex();
00274 if ( !currentIndex.isValid() )
00275 return;
00276
00277 CustomField field;
00278 field.setKey( mModel->index( currentIndex.row(), 2 ).data( Qt::DisplayRole ).toString() );
00279 field.setTitle( mModel->index( currentIndex.row(), 0 ).data( Qt::DisplayRole ).toString() );
00280 field.setType( static_cast<CustomField::Type>( currentIndex.data( CustomFieldsModel::TypeRole ).toInt() ) );
00281 field.setScope( static_cast<CustomField::Scope>( currentIndex.data( CustomFieldsModel::ScopeRole ).toInt() ) );
00282
00283 QPointer<CustomFieldEditorDialog> dlg = new CustomFieldEditorDialog( this );
00284 dlg->setCustomField( field );
00285
00286 if ( dlg->exec() == QDialog::Accepted ) {
00287 field = dlg->customField();
00288 mModel->setData( mModel->index( currentIndex.row(), 2 ), field.key(), Qt::EditRole );
00289 mModel->setData( mModel->index( currentIndex.row(), 0 ), field.title(), Qt::EditRole );
00290 mModel->setData( currentIndex, field.type(), CustomFieldsModel::TypeRole );
00291 mModel->setData( currentIndex, field.scope(), CustomFieldsModel::ScopeRole );
00292 }
00293
00294 delete dlg;
00295 }
00296
00297 void CustomFieldsEditWidget::slotRemove()
00298 {
00299 const QModelIndex currentIndex = mView->currentIndex();
00300 if ( !currentIndex.isValid() )
00301 return;
00302
00303 if ( KMessageBox::warningContinueCancel( this,
00304 i18nc( "Custom Fields", "Do you really want to delete the selected custom field?" ),
00305 i18n( "Confirm Delete" ), KStandardGuiItem::del() ) != KMessageBox::Continue ) {
00306 return;
00307 }
00308
00309 mModel->removeRow( currentIndex.row() );
00310 }
00311
00312 void CustomFieldsEditWidget::slotUpdateButtons()
00313 {
00314 const bool hasCurrent = mView->currentIndex().isValid();
00315 const bool isExternal = (hasCurrent &&
00316 (static_cast<CustomField::Scope>( mView->currentIndex().data( CustomFieldsModel::ScopeRole ).toInt() ) == CustomField::ExternalScope) );
00317
00318 mAddButton->setEnabled( !mReadOnly );
00319 mEditButton->setEnabled( !mReadOnly && hasCurrent && !isExternal );
00320 mRemoveButton->setEnabled( !mReadOnly && hasCurrent && !isExternal );
00321 }
00322
00323 #include "customfieldseditwidget.moc"