• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepimlibs API Reference
  • KDE Home
  • Contact Us
 

akonadi

  • sources
  • kde-4.12
  • kdepimlibs
  • akonadi
  • contact
contactgroupeditor.cpp
1 /*
2  This file is part of Akonadi Contact.
3 
4  Copyright (c) 2007-2009 Tobias Koenig <tokoe@kde.org>
5 
6  This library is free software; you can redistribute it and/or modify it
7  under the terms of the GNU Library General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or (at your
9  option) any later version.
10 
11  This library is distributed in the hope that it will be useful, but WITHOUT
12  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14  License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to the
18  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  02110-1301, USA.
20 */
21 
22 #include "contactgroupeditor.h"
23 #include "contactgroupeditor_p.h"
24 
25 #include "autoqpointer_p.h"
26 #include "contactgroupmodel_p.h"
27 #include "contactgroupeditordelegate_p.h"
28 #include "waitingoverlay_p.h"
29 
30 #include <akonadi/collectiondialog.h>
31 #include <akonadi/collectionfetchjob.h>
32 #include <akonadi/itemcreatejob.h>
33 #include <akonadi/itemfetchjob.h>
34 #include <akonadi/itemfetchscope.h>
35 #include <akonadi/itemmodifyjob.h>
36 #include <akonadi/monitor.h>
37 #include <akonadi/session.h>
38 #include <kabc/contactgroup.h>
39 #include <klocalizedstring.h>
40 #include <klineedit.h>
41 #include <kmessagebox.h>
42 #include <KColorScheme>
43 
44 #include <QtCore/QTimer>
45 #include <QGridLayout>
46 #include <QMessageBox>
47 #include <QTableView>
48 
49 using namespace Akonadi;
50 
51 ContactGroupEditor::Private::Private( ContactGroupEditor *parent )
52  : mParent( parent ), mMonitor( 0 ), mReadOnly( false )
53 {
54 }
55 
56 ContactGroupEditor::Private::~Private()
57 {
58  delete mMonitor;
59 }
60 
61 void ContactGroupEditor::Private::adaptHeaderSizes()
62 {
63  mGui.membersView->header()->setDefaultSectionSize( mGui.membersView->header()->width() / 2 );
64  mGui.membersView->header()->resizeSections( QHeaderView::Interactive );
65 }
66 
67 void ContactGroupEditor::Private::itemFetchDone( KJob *job )
68 {
69  if ( job->error() ) {
70  return;
71  }
72 
73  ItemFetchJob *fetchJob = qobject_cast<ItemFetchJob*>( job );
74  if ( !fetchJob ) {
75  return;
76  }
77 
78  if ( fetchJob->items().isEmpty() ) {
79  return;
80  }
81 
82  mItem = fetchJob->items().first();
83 
84  mReadOnly = false;
85  if ( mMode == ContactGroupEditor::EditMode ) {
86  // if in edit mode we have to fetch the parent collection to find out
87  // about the modify rights of the item
88 
89  Akonadi::CollectionFetchJob *collectionFetchJob = new Akonadi::CollectionFetchJob( mItem.parentCollection(),
90  Akonadi::CollectionFetchJob::Base );
91  mParent->connect( collectionFetchJob, SIGNAL(result(KJob*)),
92  SLOT(parentCollectionFetchDone(KJob*)) );
93  } else {
94  const KABC::ContactGroup group = mItem.payload<KABC::ContactGroup>();
95  loadContactGroup( group );
96 
97  setReadOnly( mReadOnly );
98 
99  QTimer::singleShot( 0, mParent, SLOT(adaptHeaderSizes()) );
100  }
101 }
102 
103 void ContactGroupEditor::Private::parentCollectionFetchDone( KJob *job )
104 {
105  if ( job->error() ) {
106  return;
107  }
108 
109  Akonadi::CollectionFetchJob *fetchJob = qobject_cast<Akonadi::CollectionFetchJob*>( job );
110  if ( !fetchJob ) {
111  return;
112  }
113 
114  const Akonadi::Collection parentCollection = fetchJob->collections().first();
115  if ( parentCollection.isValid() ) {
116  mReadOnly = !( parentCollection.rights() & Collection::CanChangeItem );
117  }
118 
119  const KABC::ContactGroup group = mItem.payload<KABC::ContactGroup>();
120  loadContactGroup( group );
121 
122  setReadOnly( mReadOnly );
123 
124  QTimer::singleShot( 0, mParent, SLOT(adaptHeaderSizes()) );
125 }
126 
127 void ContactGroupEditor::Private::storeDone( KJob *job )
128 {
129  if ( job->error() ) {
130  emit mParent->error( job->errorString() );
131  return;
132  }
133 
134  if ( mMode == EditMode ) {
135  emit mParent->contactGroupStored( mItem );
136  } else if ( mMode == CreateMode ) {
137  emit mParent->contactGroupStored( static_cast<ItemCreateJob*>( job )->item() );
138  }
139 }
140 
141 void ContactGroupEditor::Private::itemChanged( const Item&, const QSet<QByteArray>& )
142 {
143  AutoQPointer<QMessageBox> dlg = new QMessageBox( mParent ); //krazy:exclude=qclasses
144 
145  dlg->setInformativeText( i18n( "The contact group has been changed by someone else.\nWhat should be done?" ) );
146  dlg->addButton( i18n( "Take over changes" ), QMessageBox::AcceptRole );
147  dlg->addButton( i18n( "Ignore and Overwrite changes" ), QMessageBox::RejectRole );
148 
149  if ( dlg->exec() == QMessageBox::AcceptRole ) {
150  ItemFetchJob *job = new ItemFetchJob( mItem );
151  job->fetchScope().fetchFullPayload();
152  job->fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
153 
154  mParent->connect( job, SIGNAL(result(KJob*)), mParent, SLOT(itemFetchDone(KJob*)) );
155  new WaitingOverlay( job, mParent );
156  }
157 }
158 
159 void ContactGroupEditor::Private::loadContactGroup( const KABC::ContactGroup &group )
160 {
161  mGui.groupName->setText( group.name() );
162 
163  mGroupModel->loadContactGroup( group );
164 
165  const QAbstractItemModel *model = mGui.membersView->model();
166  mGui.membersView->setCurrentIndex( model->index( model->rowCount() - 1, 0 ) );
167 
168  if ( mMode == EditMode ) {
169  mGui.membersView->setFocus();
170  }
171 
172  mGui.membersView->header()->resizeSections( QHeaderView::Stretch );
173 }
174 
175 bool ContactGroupEditor::Private::storeContactGroup( KABC::ContactGroup &group )
176 {
177  if ( mGui.groupName->text().isEmpty() ) {
178  KMessageBox::error( mParent, i18n( "The name of the contact group must not be empty." ) );
179  return false;
180  }
181 
182  group.setName( mGui.groupName->text() );
183 
184  if ( !mGroupModel->storeContactGroup( group ) ) {
185  KMessageBox::error( mParent, mGroupModel->lastErrorMessage() );
186  return false;
187  }
188 
189  return true;
190 }
191 
192 void ContactGroupEditor::Private::setupMonitor()
193 {
194  delete mMonitor;
195  mMonitor = new Monitor;
196  mMonitor->ignoreSession( Session::defaultSession() );
197 
198  connect( mMonitor, SIGNAL(itemChanged(Akonadi::Item,QSet<QByteArray>)),
199  mParent, SLOT(itemChanged(Akonadi::Item,QSet<QByteArray>)) );
200 }
201 
202 void ContactGroupEditor::Private::setReadOnly( bool readOnly )
203 {
204  mGui.groupName->setReadOnly( readOnly );
205  mGui.membersView->setEnabled( !readOnly );
206 }
207 
208 ContactGroupEditor::ContactGroupEditor( Mode mode, QWidget *parent )
209  : QWidget( parent ), d( new Private( this ) )
210 {
211  d->mMode = mode;
212  d->mGui.setupUi( this );
213 
214  d->mGui.membersView->setEditTriggers( QAbstractItemView::AllEditTriggers );
215 
216  d->mGroupModel = new ContactGroupModel( this );
217  d->mGui.membersView->setModel( d->mGroupModel );
218  d->mGui.membersView->setItemDelegate( new ContactGroupEditorDelegate( d->mGui.membersView, this ) );
219 
220  if ( mode == CreateMode ) {
221  KABC::ContactGroup dummyGroup;
222  d->mGroupModel->loadContactGroup( dummyGroup );
223 
224  QTimer::singleShot( 0, this, SLOT(adaptHeaderSizes()) );
225  QTimer::singleShot( 0, d->mGui.groupName, SLOT(setFocus()) );
226  }
227 
228  d->mGui.membersView->header()->setStretchLastSection( true );
229 }
230 
231 ContactGroupEditor::~ContactGroupEditor()
232 {
233  delete d;
234 }
235 
236 void ContactGroupEditor::loadContactGroup( const Akonadi::Item &item )
237 {
238  if ( d->mMode == CreateMode ) {
239  Q_ASSERT_X( false, "ContactGroupEditor::loadContactGroup", "You are calling loadContactGroup in CreateMode!" );
240  }
241 
242  ItemFetchJob *job = new ItemFetchJob( item );
243  job->fetchScope().fetchFullPayload();
244  job->fetchScope().setAncestorRetrieval( Akonadi::ItemFetchScope::Parent );
245 
246  connect( job, SIGNAL(result(KJob*)), SLOT(itemFetchDone(KJob*)) );
247 
248  d->setupMonitor();
249  d->mMonitor->setItemMonitored( item );
250 
251  new WaitingOverlay( job, this );
252 }
253 
254 bool ContactGroupEditor::saveContactGroup()
255 {
256  if ( d->mMode == EditMode ) {
257  if ( !d->mItem.isValid() ) {
258  return false;
259  }
260 
261  if ( d->mReadOnly ) {
262  return true;
263  }
264 
265  KABC::ContactGroup group = d->mItem.payload<KABC::ContactGroup>();
266 
267  if ( !d->storeContactGroup( group ) ) {
268  return false;
269  }
270 
271  d->mItem.setPayload<KABC::ContactGroup>( group );
272 
273  ItemModifyJob *job = new ItemModifyJob( d->mItem );
274  connect( job, SIGNAL(result(KJob*)), SLOT(storeDone(KJob*)) );
275  } else if ( d->mMode == CreateMode ) {
276  if ( !d->mDefaultCollection.isValid() ) {
277  const QStringList mimeTypeFilter( KABC::ContactGroup::mimeType() );
278 
279  AutoQPointer<CollectionDialog> dlg = new CollectionDialog( this );
280  dlg->setMimeTypeFilter( mimeTypeFilter );
281  dlg->setAccessRightsFilter( Collection::CanCreateItem );
282  dlg->setCaption( i18n( "Select Address Book" ) );
283  dlg->setDescription( i18n( "Select the address book the new contact group shall be saved in:" ) );
284 
285  if ( dlg->exec() == KDialog::Accepted ) {
286  setDefaultAddressBook( dlg->selectedCollection() );
287  } else {
288  return false;
289  }
290  }
291 
292  KABC::ContactGroup group;
293  if ( !d->storeContactGroup( group ) ) {
294  return false;
295  }
296 
297  Item item;
298  item.setPayload<KABC::ContactGroup>( group );
299  item.setMimeType( KABC::ContactGroup::mimeType() );
300 
301  ItemCreateJob *job = new ItemCreateJob( item, d->mDefaultCollection );
302  connect( job, SIGNAL(result(KJob*)), SLOT(storeDone(KJob*)) );
303  }
304 
305  return true;
306 }
307 
308 void ContactGroupEditor::setContactGroupTemplate( const KABC::ContactGroup &group )
309 {
310  d->mGroupModel->loadContactGroup( group );
311  d->mGui.membersView->header()->setDefaultSectionSize( d->mGui.membersView->header()->width() / 2 );
312  d->mGui.membersView->header()->resizeSections( QHeaderView::Interactive );
313 }
314 
315 void ContactGroupEditor::setDefaultAddressBook( const Akonadi::Collection &collection )
316 {
317  d->mDefaultCollection = collection;
318 }
319 
320 void ContactGroupEditor::groupNameIsValid(bool isValid)
321 {
322 #ifndef QT_NO_STYLE_STYLESHEET
323  QString styleSheet;
324  if ( !isValid ) {
325  const KColorScheme::BackgroundRole bgColorScheme( KColorScheme::NegativeBackground );
326  KStatefulBrush bgBrush( KColorScheme::View, bgColorScheme );
327  styleSheet = QString::fromLatin1( "QLineEdit{ background-color:%1 }" ).
328  arg( bgBrush.brush( this ).color().name() );
329  }
330  d->mGui.groupName->setStyleSheet( styleSheet );
331 #endif
332 }
333 
334 #include "moc_contactgroupeditor.cpp"
WaitingOverlay
Definition: waitingoverlay_p.h:34
Akonadi::CollectionFetchJob::collections
Collection::List collections() const
Returns the list of fetched collection.
Definition: collectionfetchjob.cpp:175
Akonadi::CollectionDialog
A collection selection dialog.
Definition: collectiondialog.h:67
Akonadi::ContactGroupEditor::setContactGroupTemplate
void setContactGroupTemplate(const KABC::ContactGroup &group)
Sets a contact group that is used as template in create mode.
Definition: contactgroupeditor.cpp:308
Akonadi::Collection
Represents a collection of PIM items.
Definition: collection.h:75
Akonadi::CollectionFetchJob
Job that fetches collections from the Akonadi storage.
Definition: collectionfetchjob.h:53
Akonadi::Monitor::ignoreSession
void ignoreSession(Session *session)
Ignores all change notifications caused by the given session.
Definition: monitor.cpp:166
Akonadi::ContactGroupEditor::loadContactGroup
void loadContactGroup(const Akonadi::Item &group)
Loads the contact group into the editor.
Definition: contactgroupeditor.cpp:236
Akonadi::ItemFetchScope::fetchFullPayload
void fetchFullPayload(bool fetch=true)
Sets whether the full payload shall be fetched.
Definition: itemfetchscope.cpp:68
Akonadi::ItemFetchJob::items
Item::List items() const
Returns the fetched items.
Definition: itemfetchjob.cpp:228
Akonadi::ContactGroupEditor::~ContactGroupEditor
virtual ~ContactGroupEditor()
Destroys the contact group editor.
Definition: contactgroupeditor.cpp:231
Akonadi::CollectionFetchJob::Base
Only fetch the base collection.
Definition: collectionfetchjob.h:62
Akonadi::ItemFetchJob::fetchScope
ItemFetchScope & fetchScope()
Returns the item fetch scope.
Definition: itemfetchjob.cpp:256
Akonadi::ContactGroupEditor::CreateMode
Creates a new contact group.
Definition: contactgroupeditor.h:91
Akonadi::ItemFetchScope::Parent
Only retrieve the immediate parent collection.
Definition: itemfetchscope.h:77
Akonadi::Collection::CanCreateItem
Can create new items in this collection.
Definition: collection.h:89
Akonadi::ContactGroupEditor::Mode
Mode
Describes the mode of the contact group editor.
Definition: contactgroupeditor.h:90
Akonadi::ItemCreateJob
Job that creates a new item in the Akonadi storage.
Definition: itemcreatejob.h:73
Akonadi::Collection::rights
Rights rights() const
Returns the rights the user has on the collection.
Definition: collection.cpp:99
AutoQPointer
A QPointer which when destructed, deletes the object it points to.
Definition: autoqpointer_p.h:34
Akonadi::ItemFetchScope::setAncestorRetrieval
void setAncestorRetrieval(AncestorRetrieval ancestorDepth)
Sets how many levels of ancestor collections should be included in the retrieval. ...
Definition: itemfetchscope.cpp:128
Akonadi::Monitor
Monitors an item or collection for changes.
Definition: monitor.h:72
Akonadi::ContactGroupEditor
An widget to edit contact groups in Akonadi.
Definition: contactgroupeditor.h:82
Akonadi::ContactGroupEditor::EditMode
Edits an existing contact group.
Definition: contactgroupeditor.h:92
Akonadi::ItemModifyJob
Job that modifies an existing item in the Akonadi storage.
Definition: itemmodifyjob.h:97
Akonadi::ItemFetchJob
Job that fetches items from the Akonadi storage.
Definition: itemfetchjob.h:82
Akonadi::Entity::isValid
bool isValid() const
Returns whether the entity is valid.
Definition: entity.cpp:97
Akonadi::ContactGroupEditor::setDefaultAddressBook
void setDefaultAddressBook(const Akonadi::Collection &addressbook)
Sets the addressbook which shall be used to store new contact groups.
Definition: contactgroupeditor.cpp:315
Akonadi::ContactGroupEditor::saveContactGroup
bool saveContactGroup()
Saves the contact group from the editor back to the storage.
Definition: contactgroupeditor.cpp:254
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:00:27 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akonadi

Skip menu "akonadi"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Modules
  • Related Pages

kdepimlibs API Reference

Skip menu "kdepimlibs API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kldap
  • kmbox
  • kmime
  • kpimidentities
  • kpimtextedit
  • kresources
  • ktnef
  • kxmlrpcclient
  • microblog

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal