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