00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "contacteditor.h"
00023
00024 #include "abstractcontacteditorwidget_p.h"
00025 #include "autoqpointer_p.h"
00026 #include "contactmetadata_p.h"
00027 #include "contactmetadataattribute_p.h"
00028 #include "editor/contacteditorwidget.h"
00029
00030 #include <akonadi/collectiondialog.h>
00031 #include <akonadi/collectionfetchjob.h>
00032 #include <akonadi/itemcreatejob.h>
00033 #include <akonadi/itemfetchjob.h>
00034 #include <akonadi/itemfetchscope.h>
00035 #include <akonadi/itemmodifyjob.h>
00036 #include <akonadi/monitor.h>
00037 #include <akonadi/session.h>
00038 #include <kabc/addressee.h>
00039 #include <klocale.h>
00040
00041 #include <QtGui/QVBoxLayout>
00042 #include <QtGui/QMessageBox>
00043
00044 using namespace Akonadi;
00045
00046 class ContactEditor::Private
00047 {
00048 public:
00049 Private( ContactEditor::Mode mode, AbstractContactEditorWidget *editorWidget, ContactEditor *parent )
00050 : mParent( parent ), mMode( mode ), mMonitor( 0 ), mReadOnly( false )
00051 {
00052 if ( editorWidget )
00053 mEditorWidget = editorWidget;
00054 else
00055 mEditorWidget = new ContactEditorWidget();
00056
00057 QVBoxLayout *layout = new QVBoxLayout( mParent );
00058 layout->setMargin( 0 );
00059 layout->setSpacing( 0 );
00060 layout->addWidget( mEditorWidget );
00061 }
00062
00063 ~Private()
00064 {
00065 delete mMonitor;
00066 }
00067
00068 void itemFetchDone( KJob* );
00069 void parentCollectionFetchDone( KJob* );
00070 void storeDone( KJob* );
00071 void itemChanged( const Akonadi::Item &item, const QSet<QByteArray>& );
00072
00073 void loadContact( const KABC::Addressee &addr, const ContactMetaData &metaData );
00074 void storeContact( KABC::Addressee &addr, ContactMetaData &metaData );
00075 void setupMonitor();
00076
00077 ContactEditor *mParent;
00078 ContactEditor::Mode mMode;
00079 Akonadi::Item mItem;
00080 Akonadi::ContactMetaData mContactMetaData;
00081 Akonadi::Monitor *mMonitor;
00082 Akonadi::Collection mDefaultCollection;
00083 AbstractContactEditorWidget *mEditorWidget;
00084 bool mReadOnly;
00085 };
00086
00087 void ContactEditor::Private::itemFetchDone( KJob *job )
00088 {
00089 if ( job->error() != KJob::NoError )
00090 return;
00091
00092 Akonadi::ItemFetchJob *fetchJob = qobject_cast<Akonadi::ItemFetchJob*>( job );
00093 if ( !fetchJob )
00094 return;
00095
00096 if ( fetchJob->items().isEmpty() )
00097 return;
00098
00099 mItem = fetchJob->items().first();
00100
00101 mReadOnly = false;
00102 if ( mMode == ContactEditor::EditMode ) {
00103
00104
00105
00106 Akonadi::CollectionFetchJob *collectionFetchJob = new Akonadi::CollectionFetchJob( mItem.parentCollection(),
00107 Akonadi::CollectionFetchJob::Base );
00108 mParent->connect( collectionFetchJob, SIGNAL( result( KJob* ) ),
00109 SLOT( parentCollectionFetchDone( KJob* ) ) );
00110 } else {
00111 const KABC::Addressee addr = mItem.payload<KABC::Addressee>();
00112 mContactMetaData.load( mItem );
00113 loadContact( addr, mContactMetaData );
00114 mEditorWidget->setReadOnly( mReadOnly );
00115 }
00116 }
00117
00118 void ContactEditor::Private::parentCollectionFetchDone( KJob *job )
00119 {
00120 if ( job->error() )
00121 return;
00122
00123 Akonadi::CollectionFetchJob *fetchJob = qobject_cast<Akonadi::CollectionFetchJob*>( job );
00124 if ( !fetchJob )
00125 return;
00126
00127 const Akonadi::Collection parentCollection = fetchJob->collections().first();
00128 if ( parentCollection.isValid() )
00129 mReadOnly = !(parentCollection.rights() & Collection::CanChangeItem);
00130
00131 mEditorWidget->setReadOnly( mReadOnly );
00132
00133 const KABC::Addressee addr = mItem.payload<KABC::Addressee>();
00134 mContactMetaData.load( mItem );
00135 loadContact( addr, mContactMetaData );
00136 }
00137
00138 void ContactEditor::Private::storeDone( KJob *job )
00139 {
00140 if ( job->error() != KJob::NoError ) {
00141 emit mParent->error( job->errorString() );
00142 return;
00143 }
00144
00145 if ( mMode == EditMode )
00146 emit mParent->contactStored( mItem );
00147 else if ( mMode == CreateMode )
00148 emit mParent->contactStored( static_cast<Akonadi::ItemCreateJob*>( job )->item() );
00149 }
00150
00151 void ContactEditor::Private::itemChanged( const Akonadi::Item&, const QSet<QByteArray>& )
00152 {
00153 QMessageBox dlg( mParent );
00154
00155 dlg.setInformativeText( i18n( "The contact has been changed by someone else.\nWhat should be done?" ) );
00156 dlg.addButton( i18n( "Take over changes" ), QMessageBox::AcceptRole );
00157 dlg.addButton( i18n( "Ignore and Overwrite changes" ), QMessageBox::RejectRole );
00158
00159 if ( dlg.exec() == QMessageBox::AcceptRole ) {
00160 Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob( mItem );
00161 job->fetchScope().fetchFullPayload();
00162 job->fetchScope().fetchAttribute<ContactMetaDataAttribute>();
00163 job->fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
00164
00165 mParent->connect( job, SIGNAL( result( KJob* ) ), mParent, SLOT( itemFetchDone( KJob* ) ) );
00166 }
00167 }
00168
00169 void ContactEditor::Private::loadContact( const KABC::Addressee &addr, const ContactMetaData &metaData )
00170 {
00171 mEditorWidget->loadContact( addr, metaData );
00172 }
00173
00174 void ContactEditor::Private::storeContact( KABC::Addressee &addr, ContactMetaData &metaData )
00175 {
00176 mEditorWidget->storeContact( addr, metaData );
00177 }
00178
00179 void ContactEditor::Private::setupMonitor()
00180 {
00181 delete mMonitor;
00182 mMonitor = new Akonadi::Monitor;
00183 mMonitor->ignoreSession( Akonadi::Session::defaultSession() );
00184
00185 connect( mMonitor, SIGNAL( itemChanged( const Akonadi::Item&, const QSet<QByteArray>& ) ),
00186 mParent, SLOT( itemChanged( const Akonadi::Item&, const QSet<QByteArray>& ) ) );
00187 }
00188
00189
00190 ContactEditor::ContactEditor( Mode mode, QWidget *parent )
00191 : QWidget( parent ), d( new Private( mode, 0, this ) )
00192 {
00193 }
00194
00195 ContactEditor::ContactEditor( Mode mode, AbstractContactEditorWidget *editorWidget, QWidget *parent )
00196 : QWidget( parent ), d( new Private( mode, editorWidget, this ) )
00197 {
00198 }
00199
00200 ContactEditor::~ContactEditor()
00201 {
00202 delete d;
00203 }
00204
00205 void ContactEditor::loadContact( const Akonadi::Item &item )
00206 {
00207 if ( d->mMode == CreateMode )
00208 Q_ASSERT_X( false, "ContactEditor::loadContact", "You are calling loadContact in CreateMode!" );
00209
00210 Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob( item );
00211 job->fetchScope().fetchFullPayload();
00212 job->fetchScope().fetchAttribute<ContactMetaDataAttribute>();
00213 job->fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
00214
00215 connect( job, SIGNAL( result( KJob* ) ), SLOT( itemFetchDone( KJob* ) ) );
00216
00217 d->setupMonitor();
00218 d->mMonitor->setItemMonitored( item );
00219 }
00220
00221 bool ContactEditor::saveContact()
00222 {
00223 if ( d->mMode == EditMode ) {
00224 if ( !d->mItem.isValid() )
00225 return true;
00226
00227 if ( d->mReadOnly )
00228 return true;
00229
00230 KABC::Addressee addr = d->mItem.payload<KABC::Addressee>();
00231
00232 d->storeContact( addr, d->mContactMetaData );
00233
00234 d->mContactMetaData.store( d->mItem );
00235
00236 d->mItem.setPayload<KABC::Addressee>( addr );
00237
00238 Akonadi::ItemModifyJob *job = new Akonadi::ItemModifyJob( d->mItem );
00239 connect( job, SIGNAL( result( KJob* ) ), SLOT( storeDone( KJob* ) ) );
00240 } else if ( d->mMode == CreateMode ) {
00241 if ( !d->mDefaultCollection.isValid() ) {
00242 const QStringList mimeTypeFilter( KABC::Addressee::mimeType() );
00243
00244 AutoQPointer<CollectionDialog> dlg = new CollectionDialog( this );
00245 dlg->setMimeTypeFilter( mimeTypeFilter );
00246 dlg->setAccessRightsFilter( Collection::CanCreateItem );
00247 dlg->setCaption( i18n( "Select Address Book" ) );
00248 dlg->setDescription( i18n( "Select the address book the new contact shall be saved in:" ) );
00249 if ( dlg->exec() == KDialog::Accepted )
00250 setDefaultAddressBook( dlg->selectedCollection() );
00251 else
00252 return false;
00253 }
00254
00255 KABC::Addressee addr;
00256 d->storeContact( addr, d->mContactMetaData );
00257
00258 Akonadi::Item item;
00259 item.setPayload<KABC::Addressee>( addr );
00260 item.setMimeType( KABC::Addressee::mimeType() );
00261
00262 d->mContactMetaData.store( item );
00263
00264 Akonadi::ItemCreateJob *job = new Akonadi::ItemCreateJob( item, d->mDefaultCollection );
00265 connect( job, SIGNAL( result( KJob* ) ), SLOT( storeDone( KJob* ) ) );
00266 }
00267
00268 return true;
00269 }
00270
00271 void ContactEditor::setContactTemplate( const KABC::Addressee &contact )
00272 {
00273 d->loadContact( contact, d->mContactMetaData );
00274 }
00275
00276 void ContactEditor::setDefaultAddressBook( const Akonadi::Collection &collection )
00277 {
00278 d->mDefaultCollection = collection;
00279 }
00280
00281 #include "contacteditor.moc"