• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.14.10 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
45using namespace Akonadi;
46
47class CollectionDialog::Private
48{
49public:
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 QStringList mContentMimeTypes;
174
175 void slotDoubleClicked();
176 void slotSelectionChanged();
177 void slotAddChildCollection();
178 void slotCollectionCreationResult(KJob *job);
179 bool canCreateCollection(const Akonadi::Collection &parentCollection) const;
180 void changeCollectionDialogOptions(CollectionDialogOptions options);
181 bool canSelectCollection() const;
182};
183
184void CollectionDialog::Private::slotDoubleClicked()
185{
186 if (canSelectCollection()) {
187 mParent->accept();
188 }
189}
190
191bool CollectionDialog::Private::canSelectCollection() const
192{
193 bool result = (mView->selectionModel()->selectedIndexes().count() > 0);
194 if (mAllowToCreateNewChildCollection) {
195 const Akonadi::Collection parentCollection = mParent->selectedCollection();
196
197 if (parentCollection.isValid()) {
198 result = (parentCollection.rights() & Akonadi::Collection::CanCreateItem);
199 }
200 }
201 return result;
202}
203
204void CollectionDialog::Private::slotSelectionChanged()
205{
206 mParent->enableButton(KDialog::Ok, mView->selectionModel()->selectedIndexes().count() > 0);
207 if (mAllowToCreateNewChildCollection) {
208 const Akonadi::Collection parentCollection = mParent->selectedCollection();
209 const bool canCreateChildCollections = canCreateCollection(parentCollection);
210
211 mParent->enableButton(KDialog::User1, (canCreateChildCollections && !parentCollection.isVirtual()));
212 if (parentCollection.isValid()) {
213 const bool canCreateItems = (parentCollection.rights() & Akonadi::Collection::CanCreateItem);
214 mParent->enableButton(KDialog::Ok, canCreateItems);
215 }
216 }
217}
218
219void CollectionDialog::Private::changeCollectionDialogOptions(CollectionDialogOptions options)
220{
221 mAllowToCreateNewChildCollection = (options & AllowToCreateNewChildCollection);
222 if (mAllowToCreateNewChildCollection) {
223 mParent->setButtons(Ok | Cancel | User1);
224 mParent->setButtonGuiItem(User1, KGuiItem(i18n("&New Subfolder..."), QLatin1String("folder-new"),
225 i18n("Create a new subfolder under the currently selected folder")));
226 mParent->enableButton(KDialog::User1, false);
227 connect(mParent, SIGNAL(user1Clicked()), mParent, SLOT(slotAddChildCollection()));
228 }
229 mKeepTreeExpanded = (options & KeepTreeExpanded);
230 if (mKeepTreeExpanded) {
231 mParent->connect(mRightsFilterModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
232 mView, SLOT(expandAll()), Qt::UniqueConnection);
233 mView->expandAll();
234 }
235}
236
237bool CollectionDialog::Private::canCreateCollection(const Akonadi::Collection &parentCollection) const
238{
239 if (!parentCollection.isValid()) {
240 return false;
241 }
242
243 if ((parentCollection.rights() & Akonadi::Collection::CanCreateCollection)) {
244 const QStringList dialogMimeTypeFilter = mParent->mimeTypeFilter();
245 const QStringList parentCollectionMimeTypes = parentCollection.contentMimeTypes();
246 Q_FOREACH (const QString &mimetype, dialogMimeTypeFilter) {
247 if (parentCollectionMimeTypes.contains(mimetype)) {
248 return true;
249 }
250 }
251 return true;
252 }
253 return false;
254}
255
256void CollectionDialog::Private::slotAddChildCollection()
257{
258 const Akonadi::Collection parentCollection = mParent->selectedCollection();
259 if (canCreateCollection(parentCollection)) {
260 const QString name = KInputDialog::getText(i18nc("@title:window", "New Folder"),
261 i18nc("@label:textbox, name of a thing", "Name"),
262 QString(), 0, mParent);
263 if (name.isEmpty()) {
264 return;
265 }
266
267 Akonadi::Collection collection;
268 collection.setName(name);
269 collection.setParentCollection(parentCollection);
270 if (!mContentMimeTypes.isEmpty()) {
271 collection.setContentMimeTypes(mContentMimeTypes);
272 }
273 Akonadi::CollectionCreateJob *job = new Akonadi::CollectionCreateJob(collection);
274 connect(job, SIGNAL(result(KJob*)), mParent, SLOT(slotCollectionCreationResult(KJob*)));
275 }
276}
277
278void CollectionDialog::Private::slotCollectionCreationResult(KJob *job)
279{
280 if (job->error()) {
281 KMessageBox::error(mParent, i18n("Could not create folder: %1", job->errorString()),
282 i18n("Folder creation failed"));
283 }
284}
285
286CollectionDialog::CollectionDialog(QWidget *parent)
287 : KDialog(parent)
288 , d(new Private(0, this, CollectionDialog::None))
289{
290}
291
292CollectionDialog::CollectionDialog(QAbstractItemModel *model, QWidget *parent)
293 : KDialog(parent)
294 , d(new Private(model, this, CollectionDialog::None))
295{
296}
297
298CollectionDialog::CollectionDialog(CollectionDialogOptions options, QAbstractItemModel *model, QWidget *parent)
299 : KDialog(parent)
300 , d(new Private(model, this, options))
301{
302}
303
304CollectionDialog::~CollectionDialog()
305{
306 delete d;
307}
308
309Akonadi::Collection CollectionDialog::selectedCollection() const
310{
311 if (selectionMode() == QAbstractItemView::SingleSelection) {
312 const QModelIndex index = d->mView->currentIndex();
313 if (index.isValid()) {
314 return index.model()->data(index, EntityTreeModel::CollectionRole).value<Collection>();
315 }
316 }
317
318 return Collection();
319}
320
321Akonadi::Collection::List CollectionDialog::selectedCollections() const
322{
323 Collection::List collections;
324 const QItemSelectionModel *selectionModel = d->mView->selectionModel();
325 const QModelIndexList selectedIndexes = selectionModel->selectedIndexes();
326 foreach (const QModelIndex &index, selectedIndexes) {
327 if (index.isValid()) {
328 const Collection collection = index.model()->data(index, EntityTreeModel::CollectionRole).value<Collection>();
329 if (collection.isValid()) {
330 collections.append(collection);
331 }
332 }
333 }
334
335 return collections;
336}
337
338void CollectionDialog::setMimeTypeFilter(const QStringList &mimeTypes)
339{
340 if (mimeTypeFilter() == mimeTypes) {
341 return;
342 }
343
344 d->mMimeTypeFilterModel->clearFilters();
345 d->mMimeTypeFilterModel->addMimeTypeFilters(mimeTypes);
346
347 if (d->mMonitor) {
348 foreach (const QString &mimetype, mimeTypes) {
349 d->mMonitor->setMimeTypeMonitored(mimetype);
350 }
351 }
352}
353
354QStringList CollectionDialog::mimeTypeFilter() const
355{
356 return d->mMimeTypeFilterModel->mimeTypeFilters();
357}
358
359void CollectionDialog::setAccessRightsFilter(Collection::Rights rights)
360{
361 if (accessRightsFilter() == rights) {
362 return;
363 }
364 d->mRightsFilterModel->setAccessRights(rights);
365}
366
367Akonadi::Collection::Rights CollectionDialog::accessRightsFilter() const
368{
369 return d->mRightsFilterModel->accessRights();
370}
371
372void CollectionDialog::setDescription(const QString &text)
373{
374 d->mTextLabel->setText(text);
375 d->mTextLabel->show();
376}
377
378void CollectionDialog::setDefaultCollection(const Collection &collection)
379{
380 d->mSelectionHandler->waitForCollection(collection);
381}
382
383void CollectionDialog::setSelectionMode(QAbstractItemView::SelectionMode mode)
384{
385 d->mView->setSelectionMode(mode);
386}
387
388QAbstractItemView::SelectionMode CollectionDialog::selectionMode() const
389{
390 return d->mView->selectionMode();
391}
392
393void CollectionDialog::changeCollectionDialogOptions(CollectionDialogOptions options)
394{
395 d->changeCollectionDialogOptions(options);
396}
397
398void CollectionDialog::setUseFolderByDefault(bool b)
399{
400 d->mUseByDefault->setChecked(b);
401 d->mUseByDefault->show();
402}
403
404bool CollectionDialog::useFolderByDefault() const
405{
406 return d->mUseByDefault->isChecked();
407}
408
409void CollectionDialog::setContentMimeTypes(const QStringList &mimetypes)
410{
411 d->mContentMimeTypes = mimetypes;
412}
413
414
415#include "moc_collectiondialog.cpp"
Akonadi::AsyncSelectionHandler
Definition: asyncselectionhandler_p.h:43
Akonadi::ChangeRecorder
Records and replays change notification.
Definition: changerecorder.h:48
Akonadi::CollectionCreateJob
Job that creates a new collection in the Akonadi storage.
Definition: collectioncreatejob.h:53
Akonadi::CollectionDialog
A collection selection dialog.
Definition: collectiondialog.h:68
Akonadi::CollectionDialog::setContentMimeTypes
void setContentMimeTypes(const QStringList &mimetypes)
Allow to specify collection content mimetype when we create new one.
Definition: collectiondialog_desktop.cpp:409
Akonadi::CollectionDialog::CollectionDialog
CollectionDialog(QWidget *parent=0)
Creates a new collection dialog.
Definition: collectiondialog_desktop.cpp:286
Akonadi::CollectionDialog::setUseFolderByDefault
void setUseFolderByDefault(bool b)
Definition: collectiondialog_desktop.cpp:398
Akonadi::CollectionDialog::selectedCollection
Akonadi::Collection selectedCollection() const
Returns the selected collection if the selection mode is QAbstractItemView::SingleSelection.
Definition: collectiondialog_desktop.cpp:309
Akonadi::CollectionDialog::changeCollectionDialogOptions
void changeCollectionDialogOptions(CollectionDialogOptions options)
Change collection dialog options.
Definition: collectiondialog_desktop.cpp:393
Akonadi::CollectionDialog::selectionMode
QAbstractItemView::SelectionMode selectionMode() const
Returns the selection mode.
Definition: collectiondialog_desktop.cpp:388
Akonadi::CollectionDialog::setDefaultCollection
void setDefaultCollection(const Collection &collection)
Sets the collection that shall be selected by default.
Definition: collectiondialog_desktop.cpp:378
Akonadi::CollectionDialog::setSelectionMode
void setSelectionMode(QAbstractItemView::SelectionMode mode)
Sets the selection mode.
Definition: collectiondialog_desktop.cpp:383
Akonadi::CollectionDialog::setAccessRightsFilter
void setAccessRightsFilter(Collection::Rights rights)
Sets the access rights that the listed collections shall match with.
Definition: collectiondialog_desktop.cpp:359
Akonadi::CollectionDialog::~CollectionDialog
~CollectionDialog()
Destroys the collection dialog.
Definition: collectiondialog_desktop.cpp:304
Akonadi::CollectionDialog::mimeTypeFilter
QStringList mimeTypeFilter() const
Returns the mime types any of which the selected collection(s) shall support.
Definition: collectiondialog_desktop.cpp:354
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:338
Akonadi::CollectionDialog::setDescription
void setDescription(const QString &text)
Sets the text that will be shown in the dialog.
Definition: collectiondialog_desktop.cpp:372
Akonadi::CollectionDialog::accessRightsFilter
Collection::Rights accessRightsFilter() const
Sets the access rights that the listed collections shall match with.
Definition: collectiondialog_desktop.cpp:367
Akonadi::CollectionDialog::selectedCollections
Akonadi::Collection::List selectedCollections() const
Returns the list of selected collections.
Definition: collectiondialog_desktop.cpp:321
Akonadi::CollectionDialog::useFolderByDefault
bool useFolderByDefault() const
Definition: collectiondialog_desktop.cpp:404
Akonadi::CollectionFilterProxyModel
A proxy model that filters collections by mime type.
Definition: collectionfilterproxymodel.h:55
Akonadi::Collection
Represents a collection of PIM items.
Definition: collection.h:76
Akonadi::Collection::contentMimeTypes
QStringList contentMimeTypes() const
Returns a list of possible content mimetypes, e.g.
Definition: collection.cpp:115
Akonadi::Collection::root
static Collection root()
Returns the root collection.
Definition: collection.cpp:192
Akonadi::Collection::rights
Rights rights() const
Returns the rights the user has on the collection.
Definition: collection.cpp:99
Akonadi::Collection::List
QList< Collection > List
Describes a list of collections.
Definition: collection.h:81
Akonadi::Collection::CanCreateItem
@ CanCreateItem
Can create new items in this collection.
Definition: collection.h:89
Akonadi::Collection::CanCreateCollection
@ CanCreateCollection
Can create new subcollections in this collection.
Definition: collection.h:92
Akonadi::Collection::isVirtual
bool isVirtual() const
Returns whether the collection is virtual, for example a search collection.
Definition: collection.cpp:261
Akonadi::EntityRightsFilterModel
A proxy model that filters entities by access rights.
Definition: entityrightsfiltermodel.h:61
Akonadi::EntityTreeModel
A model for collections and items together.
Definition: entitytreemodel.h:319
Akonadi::EntityTreeModel::NoItemPopulation
@ NoItemPopulation
Do not include items in the model.
Definition: entitytreemodel.h:409
Akonadi::EntityTreeModel::setItemPopulationStrategy
void setItemPopulationStrategy(ItemPopulationStrategy strategy)
Sets the item population strategy of the model.
Definition: entitytreemodel.cpp:1121
Akonadi::EntityTreeModel::CollectionRole
@ CollectionRole
The collection.
Definition: entitytreemodel.h:336
Akonadi::EntityTreeView
A view to show an item/collection tree provided by an EntityTreeModel.
Definition: entitytreeview.h:72
Akonadi::Entity::isValid
bool isValid() const
Returns whether the entity is valid.
Definition: entity.cpp:97
Akonadi
FreeBusyManager::Singleton.
Definition: actionstatemanager_p.h:28
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu Jul 21 2022 00:00:00 by doxygen 1.9.5 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.10 API Reference

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