• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.14.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(slotDoubleClicked()));
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 
135  void slotFilterFixedString(const QString &filter)
136  {
137  mFilterCollection->setFilterFixedString(filter);
138  if (mKeepTreeExpanded) {
139  mView->expandAll();
140  }
141  }
142 
143  void readConfig()
144  {
145  KConfig config( QLatin1String( "akonadi_contactrc" ) );
146  KConfigGroup group( &config, QLatin1String( "CollectionDialog" ) );
147  const QSize size = group.readEntry( "Size", QSize(800, 500) );
148  if ( size.isValid() ) {
149  mParent->resize( size );
150  }
151  }
152 
153  void writeConfig()
154  {
155  KConfig config( QLatin1String( "akonadi_contactrc" ) );
156  KConfigGroup group( &config, QLatin1String( "CollectionDialog" ) );
157  group.writeEntry( "Size", mParent->size() );
158  group.sync();
159  }
160 
161  CollectionDialog *mParent;
162 
163  ChangeRecorder *mMonitor;
164  CollectionFilterProxyModel *mMimeTypeFilterModel;
165  EntityRightsFilterModel *mRightsFilterModel;
166  EntityTreeView *mView;
167  AsyncSelectionHandler *mSelectionHandler;
168  QLabel *mTextLabel;
169  bool mAllowToCreateNewChildCollection;
170  bool mKeepTreeExpanded;
171  KRecursiveFilterProxyModel *mFilterCollection;
172  QCheckBox *mUseByDefault;
173 
174  void slotDoubleClicked();
175  void slotSelectionChanged();
176  void slotAddChildCollection();
177  void slotCollectionCreationResult(KJob *job);
178  bool canCreateCollection(const Akonadi::Collection &parentCollection) const;
179  void changeCollectionDialogOptions(CollectionDialogOptions options);
180  bool canSelectCollection() const;
181 };
182 
183 void CollectionDialog::Private::slotDoubleClicked()
184 {
185  if (canSelectCollection()) {
186  mParent->accept();
187  }
188 }
189 
190 bool CollectionDialog::Private::canSelectCollection() const
191 {
192  bool result = (mView->selectionModel()->selectedIndexes().count() > 0);
193  if (mAllowToCreateNewChildCollection) {
194  const Akonadi::Collection parentCollection = mParent->selectedCollection();
195 
196  if (parentCollection.isValid()) {
197  result = (parentCollection.rights() & Akonadi::Collection::CanCreateItem);
198  }
199  }
200  return result;
201 }
202 
203 void CollectionDialog::Private::slotSelectionChanged()
204 {
205  mParent->enableButton(KDialog::Ok, mView->selectionModel()->selectedIndexes().count() > 0);
206  if (mAllowToCreateNewChildCollection) {
207  const Akonadi::Collection parentCollection = mParent->selectedCollection();
208  const bool canCreateChildCollections = canCreateCollection(parentCollection);
209 
210  mParent->enableButton(KDialog::User1, (canCreateChildCollections && !parentCollection.isVirtual()));
211  if (parentCollection.isValid()) {
212  const bool canCreateItems = (parentCollection.rights() & Akonadi::Collection::CanCreateItem);
213  mParent->enableButton(KDialog::Ok, canCreateItems);
214  }
215  }
216 }
217 
218 void CollectionDialog::Private::changeCollectionDialogOptions(CollectionDialogOptions options)
219 {
220  mAllowToCreateNewChildCollection = (options & AllowToCreateNewChildCollection);
221  if (mAllowToCreateNewChildCollection) {
222  mParent->setButtons(Ok | Cancel | User1);
223  mParent->setButtonGuiItem(User1, KGuiItem(i18n("&New Subfolder..."), QLatin1String("folder-new"),
224  i18n("Create a new subfolder under the currently selected folder")));
225  mParent->enableButton(KDialog::User1, false);
226  connect(mParent, SIGNAL(user1Clicked()), mParent, SLOT(slotAddChildCollection()));
227  }
228  mKeepTreeExpanded = (options & KeepTreeExpanded);
229  if (mKeepTreeExpanded) {
230  mParent->connect(mRightsFilterModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
231  mView, SLOT(expandAll()), Qt::UniqueConnection);
232  mView->expandAll();
233  }
234 }
235 
236 bool CollectionDialog::Private::canCreateCollection(const Akonadi::Collection &parentCollection) const
237 {
238  if (!parentCollection.isValid()) {
239  return false;
240  }
241 
242  if ((parentCollection.rights() & Akonadi::Collection::CanCreateCollection)) {
243  const QStringList dialogMimeTypeFilter = mParent->mimeTypeFilter();
244  const QStringList parentCollectionMimeTypes = parentCollection.contentMimeTypes();
245  Q_FOREACH (const QString &mimetype, dialogMimeTypeFilter) {
246  if (parentCollectionMimeTypes.contains(mimetype)) {
247  return true;
248  }
249  }
250  return true;
251  }
252  return false;
253 }
254 
255 void CollectionDialog::Private::slotAddChildCollection()
256 {
257  const Akonadi::Collection parentCollection = mParent->selectedCollection();
258  if (canCreateCollection(parentCollection)) {
259  const QString name = KInputDialog::getText(i18nc("@title:window", "New Folder"),
260  i18nc("@label:textbox, name of a thing", "Name"),
261  QString(), 0, mParent);
262  if (name.isEmpty()) {
263  return;
264  }
265 
266  Akonadi::Collection collection;
267  collection.setName(name);
268  collection.setParentCollection(parentCollection);
269  Akonadi::CollectionCreateJob *job = new Akonadi::CollectionCreateJob(collection);
270  connect(job, SIGNAL(result(KJob*)), mParent, SLOT(slotCollectionCreationResult(KJob*)));
271  }
272 }
273 
274 void CollectionDialog::Private::slotCollectionCreationResult(KJob *job)
275 {
276  if (job->error()) {
277  KMessageBox::error(mParent, i18n("Could not create folder: %1", job->errorString()),
278  i18n("Folder creation failed"));
279  }
280 }
281 
282 CollectionDialog::CollectionDialog(QWidget *parent)
283  : KDialog(parent)
284  , d(new Private(0, this, CollectionDialog::None))
285 {
286 }
287 
288 CollectionDialog::CollectionDialog(QAbstractItemModel *model, QWidget *parent)
289  : KDialog(parent)
290  , d(new Private(model, this, CollectionDialog::None))
291 {
292 }
293 
294 CollectionDialog::CollectionDialog(CollectionDialogOptions options, QAbstractItemModel *model, QWidget *parent)
295  : KDialog(parent)
296  , d(new Private(model, this, options))
297 {
298 }
299 
300 CollectionDialog::~CollectionDialog()
301 {
302  delete d;
303 }
304 
305 Akonadi::Collection CollectionDialog::selectedCollection() const
306 {
307  if (selectionMode() == QAbstractItemView::SingleSelection) {
308  const QModelIndex index = d->mView->currentIndex();
309  if (index.isValid()) {
310  return index.model()->data(index, EntityTreeModel::CollectionRole).value<Collection>();
311  }
312  }
313 
314  return Collection();
315 }
316 
317 Akonadi::Collection::List CollectionDialog::selectedCollections() const
318 {
319  Collection::List collections;
320  const QItemSelectionModel *selectionModel = d->mView->selectionModel();
321  const QModelIndexList selectedIndexes = selectionModel->selectedIndexes();
322  foreach (const QModelIndex &index, selectedIndexes) {
323  if (index.isValid()) {
324  const Collection collection = index.model()->data(index, EntityTreeModel::CollectionRole).value<Collection>();
325  if (collection.isValid()) {
326  collections.append(collection);
327  }
328  }
329  }
330 
331  return collections;
332 }
333 
334 void CollectionDialog::setMimeTypeFilter(const QStringList &mimeTypes)
335 {
336  if (mimeTypeFilter() == mimeTypes) {
337  return;
338  }
339 
340  d->mMimeTypeFilterModel->clearFilters();
341  d->mMimeTypeFilterModel->addMimeTypeFilters(mimeTypes);
342 
343  if (d->mMonitor) {
344  foreach (const QString &mimetype, mimeTypes) {
345  d->mMonitor->setMimeTypeMonitored(mimetype);
346  }
347  }
348 }
349 
350 QStringList CollectionDialog::mimeTypeFilter() const
351 {
352  return d->mMimeTypeFilterModel->mimeTypeFilters();
353 }
354 
355 void CollectionDialog::setAccessRightsFilter(Collection::Rights rights)
356 {
357  if (accessRightsFilter() == rights) {
358  return;
359  }
360  d->mRightsFilterModel->setAccessRights(rights);
361 }
362 
363 Akonadi::Collection::Rights CollectionDialog::accessRightsFilter() const
364 {
365  return d->mRightsFilterModel->accessRights();
366 }
367 
368 void CollectionDialog::setDescription(const QString &text)
369 {
370  d->mTextLabel->setText(text);
371  d->mTextLabel->show();
372 }
373 
374 void CollectionDialog::setDefaultCollection(const Collection &collection)
375 {
376  d->mSelectionHandler->waitForCollection(collection);
377 }
378 
379 void CollectionDialog::setSelectionMode(QAbstractItemView::SelectionMode mode)
380 {
381  d->mView->setSelectionMode(mode);
382 }
383 
384 QAbstractItemView::SelectionMode CollectionDialog::selectionMode() const
385 {
386  return d->mView->selectionMode();
387 }
388 
389 void CollectionDialog::changeCollectionDialogOptions(CollectionDialogOptions options)
390 {
391  d->changeCollectionDialogOptions(options);
392 }
393 
394 void CollectionDialog::setUseFolderByDefault(bool b)
395 {
396  d->mUseByDefault->setChecked(b);
397  d->mUseByDefault->show();
398 }
399 
400 bool CollectionDialog::useFolderByDefault() const
401 {
402  return d->mUseByDefault->isChecked();
403 }
404 
405 #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:355
Akonadi::CollectionDialog::CollectionDialog
CollectionDialog(QWidget *parent=0)
Creates a new collection dialog.
Definition: collectiondialog_desktop.cpp:282
Akonadi::CollectionDialog::selectedCollection
Akonadi::Collection selectedCollection() const
Returns the selected collection if the selection mode is QAbstractItemView::SingleSelection.
Definition: collectiondialog_desktop.cpp:305
Akonadi::CollectionDialog::setSelectionMode
void setSelectionMode(QAbstractItemView::SelectionMode mode)
Sets the selection mode.
Definition: collectiondialog_desktop.cpp:379
Akonadi::CollectionDialog::useFolderByDefault
bool useFolderByDefault() const
Definition: collectiondialog_desktop.cpp:400
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:334
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:317
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:408
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:196
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:394
Akonadi::CollectionDialog::selectionMode
QAbstractItemView::SelectionMode selectionMode() const
Returns the selection mode.
Definition: collectiondialog_desktop.cpp:384
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:336
Akonadi::CollectionDialog::setDefaultCollection
void setDefaultCollection(const Collection &collection)
Sets the collection that shall be selected by default.
Definition: collectiondialog_desktop.cpp:374
Akonadi::CollectionDialog::changeCollectionDialogOptions
void changeCollectionDialogOptions(CollectionDialogOptions options)
Change collection dialog options.
Definition: collectiondialog_desktop.cpp:389
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:350
Akonadi::CollectionDialog::accessRightsFilter
Collection::Rights accessRightsFilter() const
Sets the access rights that the listed collections shall match with.
Definition: collectiondialog_desktop.cpp:363
Akonadi::EntityTreeModel::setItemPopulationStrategy
void setItemPopulationStrategy(ItemPopulationStrategy strategy)
Sets the item population strategy of the model.
Definition: entitytreemodel.cpp:1118
Akonadi::CollectionDialog::setDescription
void setDescription(const QString &text)
Sets the text that will be shown in the dialog.
Definition: collectiondialog_desktop.cpp:368
Akonadi
FreeBusyManager::Singleton.
Definition: actionstatemanager_p.h:28
Akonadi::EntityTreeModel
A model for collections and items together.
Definition: entitytreemodel.h:318
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:300
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 Fri Nov 14 2014 05:53:23 by doxygen 1.8.8 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.14.3 API Reference

Skip menu "kdepimlibs-4.14.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