akonadi
contactgroupeditor.cpp
00001 /* 00002 This file is part of Akonadi Contact. 00003 00004 Copyright (c) 2007-2009 Tobias Koenig <tokoe@kde.org> 00005 00006 This library is free software; you can redistribute it and/or modify it 00007 under the terms of the GNU Library General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or (at your 00009 option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, but WITHOUT 00012 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00013 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00014 License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to the 00018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00019 02110-1301, USA. 00020 */ 00021 00022 #include "contactgroupeditor.h" 00023 #include "contactgroupeditor_p.h" 00024 00025 #include "autoqpointer_p.h" 00026 #include "contactgroupmodel_p.h" 00027 #include "contactgroupeditordelegate_p.h" 00028 #include "waitingoverlay_p.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/contactgroup.h> 00039 #include <klocale.h> 00040 #include <klineedit.h> 00041 #include <kmessagebox.h> 00042 #include <KColorScheme> 00043 00044 00045 #include <QtCore/QTimer> 00046 #include <QtGui/QGridLayout> 00047 #include <QtGui/QMessageBox> 00048 #include <QtGui/QTableView> 00049 00050 using namespace Akonadi; 00051 00052 ContactGroupEditor::Private::Private( ContactGroupEditor *parent ) 00053 : mParent( parent ), mMonitor( 0 ), mReadOnly( false ) 00054 { 00055 } 00056 00057 ContactGroupEditor::Private::~Private() 00058 { 00059 delete mMonitor; 00060 } 00061 00062 void ContactGroupEditor::Private::adaptHeaderSizes() 00063 { 00064 mGui.membersView->header()->setDefaultSectionSize( mGui.membersView->header()->width() / 2 ); 00065 mGui.membersView->header()->resizeSections( QHeaderView::Interactive ); 00066 } 00067 00068 void ContactGroupEditor::Private::itemFetchDone( KJob *job ) 00069 { 00070 if ( job->error() ) 00071 return; 00072 00073 ItemFetchJob *fetchJob = qobject_cast<ItemFetchJob*>( job ); 00074 if ( !fetchJob ) 00075 return; 00076 00077 if ( fetchJob->items().isEmpty() ) 00078 return; 00079 00080 mItem = fetchJob->items().first(); 00081 00082 mReadOnly = false; 00083 if ( mMode == ContactGroupEditor::EditMode ) { 00084 // if in edit mode we have to fetch the parent collection to find out 00085 // about the modify rights of the item 00086 00087 Akonadi::CollectionFetchJob *collectionFetchJob = new Akonadi::CollectionFetchJob( mItem.parentCollection(), 00088 Akonadi::CollectionFetchJob::Base ); 00089 mParent->connect( collectionFetchJob, SIGNAL(result(KJob*)), 00090 SLOT(parentCollectionFetchDone(KJob*)) ); 00091 } else { 00092 const KABC::ContactGroup group = mItem.payload<KABC::ContactGroup>(); 00093 loadContactGroup( group ); 00094 00095 setReadOnly( mReadOnly ); 00096 00097 QTimer::singleShot( 0, mParent, SLOT(adaptHeaderSizes()) ); 00098 } 00099 } 00100 00101 void ContactGroupEditor::Private::parentCollectionFetchDone( KJob *job ) 00102 { 00103 if ( job->error() ) 00104 return; 00105 00106 Akonadi::CollectionFetchJob *fetchJob = qobject_cast<Akonadi::CollectionFetchJob*>( job ); 00107 if ( !fetchJob ) 00108 return; 00109 00110 const Akonadi::Collection parentCollection = fetchJob->collections().first(); 00111 if ( parentCollection.isValid() ) 00112 mReadOnly = !(parentCollection.rights() & Collection::CanChangeItem); 00113 00114 const KABC::ContactGroup group = mItem.payload<KABC::ContactGroup>(); 00115 loadContactGroup( group ); 00116 00117 setReadOnly( mReadOnly ); 00118 00119 QTimer::singleShot( 0, mParent, SLOT(adaptHeaderSizes()) ); 00120 } 00121 00122 void ContactGroupEditor::Private::storeDone( KJob *job ) 00123 { 00124 if ( job->error() ) { 00125 emit mParent->error( job->errorString() ); 00126 return; 00127 } 00128 00129 if ( mMode == EditMode ) 00130 emit mParent->contactGroupStored( mItem ); 00131 else if ( mMode == CreateMode ) 00132 emit mParent->contactGroupStored( static_cast<ItemCreateJob*>( job )->item() ); 00133 } 00134 00135 void ContactGroupEditor::Private::itemChanged( const Item&, const QSet<QByteArray>& ) 00136 { 00137 AutoQPointer<QMessageBox> dlg = new QMessageBox( mParent ); //krazy:exclude=qclasses 00138 00139 dlg->setInformativeText( i18n( "The contact group has been changed by someone else.\nWhat should be done?" ) ); 00140 dlg->addButton( i18n( "Take over changes" ), QMessageBox::AcceptRole ); 00141 dlg->addButton( i18n( "Ignore and Overwrite changes" ), QMessageBox::RejectRole ); 00142 00143 if ( dlg->exec() == QMessageBox::AcceptRole ) { 00144 ItemFetchJob *job = new ItemFetchJob( mItem ); 00145 job->fetchScope().fetchFullPayload(); 00146 job->fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent ); 00147 00148 mParent->connect( job, SIGNAL(result(KJob*)), mParent, SLOT(itemFetchDone(KJob*)) ); 00149 new WaitingOverlay( job, mParent ); 00150 } 00151 } 00152 00153 void ContactGroupEditor::Private::loadContactGroup( const KABC::ContactGroup &group ) 00154 { 00155 mGui.groupName->setText( group.name() ); 00156 00157 mGroupModel->loadContactGroup( group ); 00158 00159 const QAbstractItemModel *model = mGui.membersView->model(); 00160 mGui.membersView->setCurrentIndex( model->index( model->rowCount() - 1, 0 ) ); 00161 00162 if ( mMode == EditMode ) 00163 mGui.membersView->setFocus(); 00164 00165 mGui.membersView->header()->resizeSections( QHeaderView::Stretch ); 00166 } 00167 00168 bool ContactGroupEditor::Private::storeContactGroup( KABC::ContactGroup &group ) 00169 { 00170 if ( mGui.groupName->text().isEmpty() ) { 00171 KMessageBox::error( mParent, i18n( "The name of the contact group must not be empty." ) ); 00172 return false; 00173 } 00174 00175 group.setName( mGui.groupName->text() ); 00176 00177 if ( !mGroupModel->storeContactGroup( group ) ) { 00178 KMessageBox::error( mParent, mGroupModel->lastErrorMessage() ); 00179 return false; 00180 } 00181 00182 return true; 00183 } 00184 00185 void ContactGroupEditor::Private::setupMonitor() 00186 { 00187 delete mMonitor; 00188 mMonitor = new Monitor; 00189 mMonitor->ignoreSession( Session::defaultSession() ); 00190 00191 connect( mMonitor, SIGNAL(itemChanged(Akonadi::Item,QSet<QByteArray>)), 00192 mParent, SLOT(itemChanged(Akonadi::Item,QSet<QByteArray>)) ); 00193 } 00194 00195 void ContactGroupEditor::Private::setReadOnly( bool readOnly ) 00196 { 00197 mGui.groupName->setReadOnly( readOnly ); 00198 mGui.membersView->setEnabled( !readOnly ); 00199 } 00200 00201 00202 ContactGroupEditor::ContactGroupEditor( Mode mode, QWidget *parent ) 00203 : QWidget( parent ), d( new Private( this ) ) 00204 { 00205 d->mMode = mode; 00206 d->mGui.setupUi( this ); 00207 00208 d->mGui.membersView->setEditTriggers( QAbstractItemView::AllEditTriggers ); 00209 00210 d->mGroupModel = new ContactGroupModel( this ); 00211 d->mGui.membersView->setModel( d->mGroupModel ); 00212 d->mGui.membersView->setItemDelegate( new ContactGroupEditorDelegate( d->mGui.membersView, this ) ); 00213 00214 if ( mode == CreateMode ) { 00215 KABC::ContactGroup dummyGroup; 00216 d->mGroupModel->loadContactGroup( dummyGroup ); 00217 00218 QTimer::singleShot( 0, this, SLOT(adaptHeaderSizes()) ); 00219 QTimer::singleShot( 0, d->mGui.groupName, SLOT(setFocus()) ); 00220 } 00221 00222 d->mGui.membersView->header()->setStretchLastSection( true ); 00223 } 00224 00225 ContactGroupEditor::~ContactGroupEditor() 00226 { 00227 delete d; 00228 } 00229 00230 void ContactGroupEditor::loadContactGroup( const Akonadi::Item &item ) 00231 { 00232 if ( d->mMode == CreateMode ) 00233 Q_ASSERT_X( false, "ContactGroupEditor::loadContactGroup", "You are calling loadContactGroup in CreateMode!" ); 00234 00235 ItemFetchJob *job = new ItemFetchJob( item ); 00236 job->fetchScope().fetchFullPayload(); 00237 job->fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent ); 00238 00239 connect( job, SIGNAL(result(KJob*)), SLOT(itemFetchDone(KJob*)) ); 00240 00241 d->setupMonitor(); 00242 d->mMonitor->setItemMonitored( item ); 00243 00244 new WaitingOverlay( job, this ); 00245 } 00246 00247 bool ContactGroupEditor::saveContactGroup() 00248 { 00249 if ( d->mMode == EditMode ) { 00250 if ( !d->mItem.isValid() ) 00251 return false; 00252 00253 if ( d->mReadOnly ) 00254 return true; 00255 00256 KABC::ContactGroup group = d->mItem.payload<KABC::ContactGroup>(); 00257 00258 if ( !d->storeContactGroup( group ) ) 00259 return false; 00260 00261 d->mItem.setPayload<KABC::ContactGroup>( group ); 00262 00263 ItemModifyJob *job = new ItemModifyJob( d->mItem ); 00264 connect( job, SIGNAL(result(KJob*)), SLOT(storeDone(KJob*)) ); 00265 } else if ( d->mMode == CreateMode ) { 00266 if ( !d->mDefaultCollection.isValid() ) { 00267 const QStringList mimeTypeFilter( KABC::ContactGroup::mimeType() ); 00268 00269 AutoQPointer<CollectionDialog> dlg = new CollectionDialog( this ); 00270 dlg->setMimeTypeFilter( mimeTypeFilter ); 00271 dlg->setAccessRightsFilter( Collection::CanCreateItem ); 00272 dlg->setCaption( i18n( "Select Address Book" ) ); 00273 dlg->setDescription( i18n( "Select the address book the new contact group shall be saved in:" ) ); 00274 00275 if ( dlg->exec() == KDialog::Accepted ) 00276 setDefaultAddressBook( dlg->selectedCollection() ); 00277 else 00278 return false; 00279 } 00280 00281 KABC::ContactGroup group; 00282 if ( !d->storeContactGroup( group ) ) 00283 return false; 00284 00285 Item item; 00286 item.setPayload<KABC::ContactGroup>( group ); 00287 item.setMimeType( KABC::ContactGroup::mimeType() ); 00288 00289 ItemCreateJob *job = new ItemCreateJob( item, d->mDefaultCollection ); 00290 connect( job, SIGNAL(result(KJob*)), SLOT(storeDone(KJob*)) ); 00291 } 00292 00293 return true; 00294 } 00295 00296 void ContactGroupEditor::setContactGroupTemplate( const KABC::ContactGroup &group ) 00297 { 00298 d->mGroupModel->loadContactGroup( group ); 00299 d->mGui.membersView->header()->setDefaultSectionSize( d->mGui.membersView->header()->width() / 2 ); 00300 d->mGui.membersView->header()->resizeSections( QHeaderView::Interactive ); 00301 } 00302 00303 void ContactGroupEditor::setDefaultAddressBook( const Akonadi::Collection &collection ) 00304 { 00305 d->mDefaultCollection = collection; 00306 } 00307 00308 void ContactGroupEditor::groupNameIsValid(bool isValid) 00309 { 00310 #ifndef QT_NO_STYLE_STYLESHEET 00311 QString styleSheet; 00312 if ( !isValid ) { 00313 const KColorScheme::BackgroundRole bgColorScheme( KColorScheme::NegativeBackground ); 00314 KStatefulBrush bgBrush( KColorScheme::View, bgColorScheme ); 00315 styleSheet = QString::fromLatin1( "QLineEdit{ background-color:%1 }" ). 00316 arg( bgBrush.brush( this ).color().name() ); 00317 } 00318 d->mGui.groupName->setStyleSheet(styleSheet); 00319 #endif 00320 } 00321 00322 #include "contactgroupeditor.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Aug 27 2012 22:09:21 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Aug 27 2012 22:09:21 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.