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

akonadi

  • akonadi
collectiondialog_desktop.cpp
1 /*
2  Copyright 2008 Ingo Klöcker <kloecker@kde.org>
3  Copyright 2010 Laurent Montel <montel@kde.org>
4 
5  This library is free software; you can redistribute it and/or modify it
6  under the terms of the GNU Library General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or (at your
8  option) any later version.
9 
10  This library is distributed in the hope that it will be useful, but WITHOUT
11  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13  License for more details.
14 
15  You should have received a copy of the GNU Library General Public License
16  along with this library; see the file COPYING.LIB. If not, write to the
17  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  02110-1301, USA.
19 */
20 
21 #include "collectiondialog.h"
22 
23 #include "asyncselectionhandler_p.h"
24 
25 #include <akonadi/changerecorder.h>
26 #include <akonadi/collectionfetchscope.h>
27 #include <akonadi/collectionfilterproxymodel.h>
28 #include <akonadi/entityrightsfiltermodel.h>
29 #include <akonadi/entitytreemodel.h>
30 #include <akonadi/entitytreeview.h>
31 #include <akonadi/session.h>
32 #include <akonadi/collectioncreatejob.h>
33 #include <akonadi/collectionutils_p.h>
34 
35 #include <QHeaderView>
36 #include <QLabel>
37 #include <QVBoxLayout>
38 #include <QCheckBox>
39 
40 #include <KLineEdit>
41 #include <KLocalizedString>
42 #include <KInputDialog>
43 #include <KMessageBox>
44 
45 using namespace Akonadi;
46 
47 class CollectionDialog::Private
48 {
49  public:
50  Private( QAbstractItemModel *customModel, CollectionDialog *parent, CollectionDialogOptions options )
51  : mParent( parent ),
52  mMonitor( 0 )
53  {
54  // setup GUI
55  QWidget *widget = mParent->mainWidget();
56  QVBoxLayout *layout = new QVBoxLayout( widget );
57  layout->setContentsMargins( 0, 0, 0, 0 );
58 
59  mTextLabel = new QLabel;
60  layout->addWidget( mTextLabel );
61  mTextLabel->hide();
62 
63  KLineEdit* filterCollectionLineEdit = new KLineEdit( widget );
64  filterCollectionLineEdit->setClearButtonShown( true );
65  filterCollectionLineEdit->setClickMessage( i18nc( "@info/plain Displayed grayed-out inside the "
66  "textbox, verb to search", "Search" ) );
67  layout->addWidget( filterCollectionLineEdit );
68 
69  mView = new EntityTreeView;
70  mView->setDragDropMode( QAbstractItemView::NoDragDrop );
71  mView->header()->hide();
72  layout->addWidget( mView );
73 
74  mUseByDefault = new QCheckBox(i18n("Use folder by default"));
75  mUseByDefault->hide();
76  layout->addWidget(mUseByDefault);
77 
78  mParent->enableButton( KDialog::Ok, false );
79 
80  // setup models
81  QAbstractItemModel *baseModel;
82 
83  if ( customModel ) {
84  baseModel = customModel;
85  } else {
86  mMonitor = new Akonadi::ChangeRecorder( mParent );
87  mMonitor->fetchCollection( true );
88  mMonitor->setCollectionMonitored( Akonadi::Collection::root() );
89 
90  EntityTreeModel *model = new EntityTreeModel( mMonitor, mParent );
91  model->setItemPopulationStrategy( EntityTreeModel::NoItemPopulation );
92  baseModel = model;
93  }
94 
95  mMimeTypeFilterModel = new CollectionFilterProxyModel( mParent );
96  mMimeTypeFilterModel->setSourceModel( baseModel );
97  mMimeTypeFilterModel->setExcludeVirtualCollections( true );
98 
99  mRightsFilterModel = new EntityRightsFilterModel( mParent );
100  mRightsFilterModel->setSourceModel( mMimeTypeFilterModel );
101 
102  mFilterCollection = new KRecursiveFilterProxyModel( mParent );
103  mFilterCollection->setDynamicSortFilter( true );
104  mFilterCollection->setSourceModel( mRightsFilterModel );
105  mFilterCollection->setFilterCaseSensitivity( Qt::CaseInsensitive );
106  mView->setModel( mFilterCollection );
107 
108  changeCollectionDialogOptions( options );
109  mParent->connect( filterCollectionLineEdit, SIGNAL(textChanged(QString)),
110  mParent, SLOT(slotFilterFixedString(QString)) );
111 
112  mParent->connect( mView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
113  mParent, SLOT(slotSelectionChanged()) );
114 
115  mParent->connect( mView, SIGNAL(doubleClicked(QModelIndex)),
116  mParent, SLOT(accept()) );
117 
118  mSelectionHandler = new AsyncSelectionHandler( mFilterCollection, mParent );
119  mParent->connect( mSelectionHandler, SIGNAL(collectionAvailable(QModelIndex)),
120  mParent, SLOT(slotCollectionAvailable(QModelIndex)) );
121  readConfig();
122  }
123 
124  ~Private()
125  {
126  writeConfig();
127  }
128 
129  void slotCollectionAvailable( const QModelIndex &index )
130  {
131  mView->expandAll();
132  mView->setCurrentIndex( index );
133  }
134  void slotFilterFixedString( const QString &filter)
135  {
136  mFilterCollection->setFilterFixedString(filter);
137  if (mKeepTreeExpanded)
138  mView->expandAll();
139  }
140 
141  void readConfig()
142  {
143  KConfig config( QLatin1String( "akonadi_contactrc" ) );
144  KConfigGroup group( &config, QLatin1String( "CollectionDialog" ) );
145  const QSize size = group.readEntry( "Size", QSize(800, 500) );
146  if ( size.isValid() ) {
147  mParent->resize( size );
148  }
149  }
150 
151  void writeConfig()
152  {
153  KConfig config( QLatin1String( "akonadi_contactrc" ) );
154  KConfigGroup group( &config, QLatin1String( "CollectionDialog" ) );
155  group.writeEntry( "Size", mParent->size() );
156  group.sync();
157  }
158 
159  CollectionDialog *mParent;
160 
161  ChangeRecorder *mMonitor;
162  CollectionFilterProxyModel *mMimeTypeFilterModel;
163  EntityRightsFilterModel *mRightsFilterModel;
164  EntityTreeView *mView;
165  AsyncSelectionHandler *mSelectionHandler;
166  QLabel *mTextLabel;
167  bool mAllowToCreateNewChildCollection;
168  bool mKeepTreeExpanded;
169  KRecursiveFilterProxyModel *mFilterCollection;
170  QCheckBox *mUseByDefault;
171 
172  void slotSelectionChanged();
173  void slotAddChildCollection();
174  void slotCollectionCreationResult( KJob* job );
175  bool canCreateCollection( const Akonadi::Collection &parentCollection ) const;
176  void changeCollectionDialogOptions( CollectionDialogOptions options );
177 
178 };
179 
180 void CollectionDialog::Private::slotSelectionChanged()
181 {
182  mParent->enableButton( KDialog::Ok, mView->selectionModel()->selectedIndexes().count() > 0 );
183  if ( mAllowToCreateNewChildCollection ) {
184  const Akonadi::Collection parentCollection = mParent->selectedCollection();
185  const bool canCreateChildCollections = canCreateCollection( parentCollection );
186 
187  mParent->enableButton( KDialog::User1, ( canCreateChildCollections && !parentCollection.isVirtual() ) );
188  if ( parentCollection.isValid() ) {
189  const bool canCreateItems = ( parentCollection.rights() & Akonadi::Collection::CanCreateItem );
190  mParent->enableButton( KDialog::Ok, canCreateItems );
191  }
192  }
193 }
194 
195 void CollectionDialog::Private::changeCollectionDialogOptions( CollectionDialogOptions options )
196 {
197  mAllowToCreateNewChildCollection = ( options & AllowToCreateNewChildCollection );
198  if ( mAllowToCreateNewChildCollection ) {
199  mParent->setButtons( Ok | Cancel | User1 );
200  mParent->setButtonGuiItem( User1, KGuiItem( i18n( "&New Subfolder..." ), QLatin1String( "folder-new" ),
201  i18n( "Create a new subfolder under the currently selected folder" ) ) );
202  mParent->enableButton( KDialog::User1, false );
203  connect( mParent, SIGNAL(user1Clicked()), mParent, SLOT(slotAddChildCollection()) );
204  }
205  mKeepTreeExpanded = ( options & KeepTreeExpanded );
206  if ( mKeepTreeExpanded ) {
207  mParent->connect( mRightsFilterModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
208  mView, SLOT(expandAll()), Qt::UniqueConnection );
209  mView->expandAll();
210  }
211 }
212 
213 bool CollectionDialog::Private::canCreateCollection( const Akonadi::Collection &parentCollection ) const
214 {
215  if ( !parentCollection.isValid() ) {
216  return false;
217  }
218 
219  if ( ( parentCollection.rights() & Akonadi::Collection::CanCreateCollection ) ) {
220  const QStringList dialogMimeTypeFilter = mParent->mimeTypeFilter();
221  const QStringList parentCollectionMimeTypes = parentCollection.contentMimeTypes();
222  Q_FOREACH ( const QString& mimetype, dialogMimeTypeFilter ) {
223  if ( parentCollectionMimeTypes.contains( mimetype ) ) {
224  return true;
225  }
226  }
227  return true;
228  }
229  return false;
230 }
231 
232 void CollectionDialog::Private::slotAddChildCollection()
233 {
234  const Akonadi::Collection parentCollection = mParent->selectedCollection();
235  if ( canCreateCollection( parentCollection ) ) {
236  const QString name = KInputDialog::getText( i18nc( "@title:window", "New Folder" ),
237  i18nc( "@label:textbox, name of a thing", "Name" ),
238  QString(), 0, mParent );
239  if ( name.isEmpty() ) {
240  return;
241  }
242 
243  Akonadi::Collection collection;
244  collection.setName( name );
245  collection.setParentCollection( parentCollection );
246  Akonadi::CollectionCreateJob *job = new Akonadi::CollectionCreateJob( collection );
247  connect( job, SIGNAL(result(KJob*)), mParent, SLOT(slotCollectionCreationResult(KJob*)) );
248  }
249 }
250 
251 void CollectionDialog::Private::slotCollectionCreationResult( KJob* job )
252 {
253  if ( job->error() ) {
254  KMessageBox::error( mParent, i18n( "Could not create folder: %1", job->errorString() ),
255  i18n( "Folder creation failed" ) );
256  }
257 }
258 
259 CollectionDialog::CollectionDialog( QWidget *parent )
260  : KDialog( parent ),
261  d( new Private( 0, this, CollectionDialog::None ) )
262 {
263 }
264 
265 CollectionDialog::CollectionDialog( QAbstractItemModel *model, QWidget *parent )
266  : KDialog( parent ),
267  d( new Private( model, this, CollectionDialog::None ) )
268 {
269 }
270 
271 CollectionDialog::CollectionDialog( CollectionDialogOptions options, QAbstractItemModel *model, QWidget *parent )
272  : KDialog( parent ),
273  d( new Private( model, this, options ) )
274 {
275 }
276 
277 CollectionDialog::~CollectionDialog()
278 {
279  delete d;
280 }
281 
282 Akonadi::Collection CollectionDialog::selectedCollection() const
283 {
284  if ( selectionMode() == QAbstractItemView::SingleSelection ) {
285  const QModelIndex index = d->mView->currentIndex();
286  if ( index.isValid() ) {
287  return index.model()->data( index, EntityTreeModel::CollectionRole ).value<Collection>();
288  }
289  }
290 
291  return Collection();
292 }
293 
294 Akonadi::Collection::List CollectionDialog::selectedCollections() const
295 {
296  Collection::List collections;
297  const QItemSelectionModel *selectionModel = d->mView->selectionModel();
298  const QModelIndexList selectedIndexes = selectionModel->selectedIndexes();
299  foreach ( const QModelIndex &index, selectedIndexes ) {
300  if ( index.isValid() ) {
301  const Collection collection = index.model()->data( index, EntityTreeModel::CollectionRole ).value<Collection>();
302  if ( collection.isValid() ) {
303  collections.append( collection );
304  }
305  }
306  }
307 
308  return collections;
309 }
310 
311 void CollectionDialog::setMimeTypeFilter( const QStringList &mimeTypes )
312 {
313  if ( mimeTypeFilter() == mimeTypes )
314  return;
315 
316  d->mMimeTypeFilterModel->clearFilters();
317  d->mMimeTypeFilterModel->addMimeTypeFilters( mimeTypes );
318 
319  if ( d->mMonitor ) {
320  foreach ( const QString &mimetype, mimeTypes ) {
321  d->mMonitor->setMimeTypeMonitored( mimetype );
322  }
323  }
324 }
325 
326 QStringList CollectionDialog::mimeTypeFilter() const
327 {
328  return d->mMimeTypeFilterModel->mimeTypeFilters();
329 }
330 
331 void CollectionDialog::setAccessRightsFilter( Collection::Rights rights )
332 {
333  if ( accessRightsFilter() == rights )
334  return;
335  d->mRightsFilterModel->setAccessRights( rights );
336 }
337 
338 Akonadi::Collection::Rights CollectionDialog::accessRightsFilter() const
339 {
340  return d->mRightsFilterModel->accessRights();
341 }
342 
343 void CollectionDialog::setDescription( const QString &text )
344 {
345  d->mTextLabel->setText( text );
346  d->mTextLabel->show();
347 }
348 
349 void CollectionDialog::setDefaultCollection( const Collection &collection )
350 {
351  d->mSelectionHandler->waitForCollection( collection );
352 }
353 
354 void CollectionDialog::setSelectionMode( QAbstractItemView::SelectionMode mode )
355 {
356  d->mView->setSelectionMode( mode );
357 }
358 
359 QAbstractItemView::SelectionMode CollectionDialog::selectionMode() const
360 {
361  return d->mView->selectionMode();
362 }
363 
364 void CollectionDialog::changeCollectionDialogOptions( CollectionDialogOptions options )
365 {
366  d->changeCollectionDialogOptions( options );
367 }
368 
369 void CollectionDialog::setUseFolderByDefault( bool b )
370 {
371  d->mUseByDefault->setChecked(b);
372  d->mUseByDefault->show();
373 }
374 
375 bool CollectionDialog::useFolderByDefault() const
376 {
377  return d->mUseByDefault->isChecked();
378 }
379 
380 #include "moc_collectiondialog.cpp"
Akonadi::CollectionDialog::setAccessRightsFilter
void setAccessRightsFilter(Collection::Rights rights)
Sets the access rights that the listed collections shall match with.
Definition: collectiondialog_desktop.cpp:331
Akonadi::CollectionDialog::CollectionDialog
CollectionDialog(QWidget *parent=0)
Creates a new collection dialog.
Definition: collectiondialog_desktop.cpp:259
Akonadi::CollectionDialog::selectedCollection
Akonadi::Collection selectedCollection() const
Returns the selected collection if the selection mode is QAbstractItemView::SingleSelection.
Definition: collectiondialog_desktop.cpp:282
Akonadi::CollectionDialog::setSelectionMode
void setSelectionMode(QAbstractItemView::SelectionMode mode)
Sets the selection mode.
Definition: collectiondialog_desktop.cpp:354
Akonadi::CollectionDialog::useFolderByDefault
bool useFolderByDefault() const
Definition: collectiondialog_desktop.cpp:375
Akonadi::CollectionDialog::setMimeTypeFilter
void setMimeTypeFilter(const QStringList &mimeTypes)
Sets the mime types any of which the selected collection(s) shall support.
Definition: collectiondialog_desktop.cpp:311
Akonadi::CollectionFilterProxyModel
A proxy model that filters collections by mime type.
Definition: collectionfilterproxymodel.h:54
Akonadi::AsyncSelectionHandler
Definition: asyncselectionhandler_p.h:42
Akonadi::CollectionDialog
A collection selection dialog.
Definition: collectiondialog.h:67
Akonadi::CollectionDialog::selectedCollections
Akonadi::Collection::List selectedCollections() const
Returns the list of selected collections.
Definition: collectiondialog_desktop.cpp:294
Akonadi::Collection
Represents a collection of PIM items.
Definition: collection.h:75
Akonadi::EntityTreeModel::NoItemPopulation
Do not include items in the model.
Definition: entitytreemodel.h:407
Akonadi::Collection::CanCreateCollection
Can create new subcollections in this collection.
Definition: collection.h:92
Akonadi::EntityRightsFilterModel
A proxy model that filters entities by access rights.
Definition: entityrightsfiltermodel.h:60
Akonadi::Entity::setParentCollection
void setParentCollection(const Collection &parent)
Set the parent collection of this object.
Definition: entity.cpp:195
Akonadi::Collection::setName
void setName(const QString &name)
Sets the i18n'ed name of the collection.
Definition: collection.cpp:93
Akonadi::CollectionDialog::setUseFolderByDefault
void setUseFolderByDefault(bool b)
Definition: collectiondialog_desktop.cpp:369
Akonadi::CollectionDialog::selectionMode
QAbstractItemView::SelectionMode selectionMode() const
Returns the selection mode.
Definition: collectiondialog_desktop.cpp:359
Akonadi::EntityTreeView
A view to show an item/collection tree provided by an EntityTreeModel.
Definition: entitytreeview.h:71
Akonadi::Collection::CanCreateItem
Can create new items in this collection.
Definition: collection.h:89
Akonadi::Collection::root
static Collection root()
Returns the root collection.
Definition: collection.cpp:192
Akonadi::EntityTreeModel::CollectionRole
The collection.
Definition: entitytreemodel.h:335
Akonadi::CollectionDialog::setDefaultCollection
void setDefaultCollection(const Collection &collection)
Sets the collection that shall be selected by default.
Definition: collectiondialog_desktop.cpp:349
Akonadi::CollectionDialog::changeCollectionDialogOptions
void changeCollectionDialogOptions(CollectionDialogOptions options)
Change collection dialog options.
Definition: collectiondialog_desktop.cpp:364
Akonadi::Collection::rights
Rights rights() const
Returns the rights the user has on the collection.
Definition: collection.cpp:99
Akonadi::CollectionDialog::mimeTypeFilter
QStringList mimeTypeFilter() const
Returns the mime types any of which the selected collection(s) shall support.
Definition: collectiondialog_desktop.cpp:326
Akonadi::CollectionDialog::accessRightsFilter
Collection::Rights accessRightsFilter() const
Sets the access rights that the listed collections shall match with.
Definition: collectiondialog_desktop.cpp:338
Akonadi::EntityTreeModel::setItemPopulationStrategy
void setItemPopulationStrategy(ItemPopulationStrategy strategy)
Sets the item population strategy of the model.
Definition: entitytreemodel.cpp:1075
Akonadi::CollectionDialog::setDescription
void setDescription(const QString &text)
Sets the text that will be shown in the dialog.
Definition: collectiondialog_desktop.cpp:343
Akonadi::EntityTreeModel
A model for collections and items together.
Definition: entitytreemodel.h:317
Akonadi::Collection::contentMimeTypes
QStringList contentMimeTypes() const
Returns a list of possible content mimetypes, e.g.
Definition: collection.cpp:115
Akonadi::CollectionDialog::~CollectionDialog
~CollectionDialog()
Destroys the collection dialog.
Definition: collectiondialog_desktop.cpp:277
Akonadi::CollectionCreateJob
Job that creates a new collection in the Akonadi storage.
Definition: collectioncreatejob.h:52
Akonadi::Entity::isValid
bool isValid() const
Returns whether the entity is valid.
Definition: entity.cpp:97
Akonadi::Collection::List
QList< Collection > List
Describes a list of collections.
Definition: collection.h:81
Akonadi::Collection::isVirtual
bool isVirtual() const
Returns whether the collection is virtual, for example a search collection.
Definition: collection.cpp:261
Akonadi::ChangeRecorder
Records and replays change notification.
Definition: changerecorder.h:47
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Mon Jul 21 2014 08:03:50 by doxygen 1.8.6 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-4.13.3 API Reference

Skip menu "kdepimlibs-4.13.3 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
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