Akonadi

collectionrequester.cpp
1 /*
2  SPDX-FileCopyrightText: 2008 Ingo Klöcker <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "collectionrequester.h"
8 #include "collectionfetchjob.h"
9 #include "collectionfetchscope.h"
10 #include "entitydisplayattribute.h"
11 
12 #include <KLocalizedString>
13 #include <KStandardShortcut>
14 #include <QLineEdit>
15 
16 #include <QAction>
17 #include <QEvent>
18 #include <QHBoxLayout>
19 #include <QPushButton>
20 
21 using namespace Akonadi;
22 
23 class Akonadi::CollectionRequesterPrivate
24 {
25 public:
26  explicit CollectionRequesterPrivate(CollectionRequester *parent)
27  : q(parent)
28  {
29  }
30 
31  ~CollectionRequesterPrivate()
32  {
33  }
34 
35  void fetchCollection(const Collection &collection);
36 
37  void init();
38 
39  // slots
40  void _k_slotOpenDialog();
41  void _k_collectionReceived(KJob *job);
42  void _k_collectionsNamesReceived(KJob *job);
43 
44  CollectionRequester *const q;
45  Collection collection;
46  QLineEdit *edit = nullptr;
47  QPushButton *button = nullptr;
48  CollectionDialog *collectionDialog = nullptr;
49 };
50 
51 void CollectionRequesterPrivate::fetchCollection(const Collection &collection)
52 {
53  auto job = new CollectionFetchJob(collection, Akonadi::CollectionFetchJob::Base, q);
54  job->setProperty("OriginalCollectionId", collection.id());
55  job->fetchScope().setAncestorRetrieval(CollectionFetchScope::All);
56  QObject::connect(job, &CollectionFetchJob::finished, q, [this](KJob *job) {
57  _k_collectionReceived(job);
58  });
59 }
60 
61 void CollectionRequesterPrivate::_k_collectionReceived(KJob *job)
62 {
63  auto fetch = qobject_cast<CollectionFetchJob *>(job);
64  if (!fetch) {
65  return;
66  }
67  if (fetch->collections().size() == 1) {
68  Collection::List chain;
69  Collection currentCollection = fetch->collections().at(0);
70  while (currentCollection.isValid()) {
71  chain << currentCollection;
72  currentCollection = Collection(currentCollection.parentCollection());
73  }
74 
75  auto namesFetch = new CollectionFetchJob(chain, CollectionFetchJob::Base, q);
76  namesFetch->setProperty("OriginalCollectionId", job->property("OriginalCollectionId"));
77  namesFetch->fetchScope().setAncestorRetrieval(CollectionFetchScope::Parent);
78  QObject::connect(namesFetch, &CollectionFetchJob::finished, q, [this](KJob *job) {
79  _k_collectionsNamesReceived(job);
80  });
81  } else {
82  _k_collectionsNamesReceived(job);
83  }
84 }
85 
86 void CollectionRequesterPrivate::_k_collectionsNamesReceived(KJob *job)
87 {
88  auto fetch = qobject_cast<CollectionFetchJob *>(job);
89  const qint64 originalId = fetch->property("OriginalCollectionId").toLongLong();
90 
92  const Akonadi::Collection::List lstCols = fetch->collections();
93  for (const Collection &collection : lstCols) {
94  names.insert(collection.id(), collection);
95  }
96 
97  QStringList namesList;
98  Collection currentCollection = names.take(originalId);
99  while (currentCollection.isValid()) {
100  namesList.prepend(currentCollection.displayName());
101  currentCollection = names.take(currentCollection.parentCollection().id());
102  }
103  edit->setText(namesList.join(QLatin1Char('/')));
104 }
105 
106 void CollectionRequesterPrivate::init()
107 {
108  auto hbox = new QHBoxLayout(q);
109  hbox->setContentsMargins({});
110 
111  edit = new QLineEdit(q);
112  edit->setReadOnly(true);
113  edit->setPlaceholderText(i18n("No Folder"));
114  edit->setClearButtonEnabled(false);
115  edit->setFocusPolicy(Qt::NoFocus);
116  hbox->addWidget(edit);
117 
118  button = new QPushButton(q);
119  button->setIcon(QIcon::fromTheme(QStringLiteral("document-open")));
120  const int buttonSize = edit->sizeHint().height();
121  button->setFixedSize(buttonSize, buttonSize);
122  button->setToolTip(i18n("Open collection dialog"));
123  hbox->addWidget(button);
124 
125  hbox->setSpacing(-1);
126 
127  edit->installEventFilter(q);
128  q->setFocusProxy(button);
129  q->setFocusPolicy(Qt::StrongFocus);
130 
131  q->connect(button, &QPushButton::clicked, q, [this]() {
132  _k_slotOpenDialog();
133  });
134 
135  auto openAction = new QAction(q);
136  openAction->setShortcut(KStandardShortcut::Open);
137  q->connect(openAction, &QAction::triggered, q, [this]() {
138  _k_slotOpenDialog();
139  });
140 
141  collectionDialog = new CollectionDialog(q);
142  collectionDialog->setWindowIcon(QIcon::fromTheme(QStringLiteral("akonadi")));
143  collectionDialog->setWindowTitle(i18nc("@title:window", "Select a collection"));
144  collectionDialog->setSelectionMode(QAbstractItemView::SingleSelection);
145  collectionDialog->changeCollectionDialogOptions(CollectionDialog::KeepTreeExpanded);
146 }
147 
148 void CollectionRequesterPrivate::_k_slotOpenDialog()
149 {
150  CollectionDialog *dlg = collectionDialog;
151 
152  if (dlg->exec() != QDialog::Accepted) {
153  return;
154  }
155 
156  const Akonadi::Collection collection = dlg->selectedCollection();
157  q->setCollection(collection);
158  Q_EMIT q->collectionChanged(collection);
159 }
160 
162  : QWidget(parent)
163  , d(new CollectionRequesterPrivate(this))
164 {
165  d->init();
166 }
167 
169  : QWidget(parent)
170  , d(new CollectionRequesterPrivate(this))
171 {
172  d->init();
174 }
175 
177 
179 {
180  return d->collection;
181 }
182 
184 {
185  d->collection = collection;
186  QString name;
187  if (collection.isValid()) {
188  name = collection.displayName();
189  }
190 
191  d->edit->setText(name);
193  d->fetchCollection(collection);
194 }
195 
197 {
198  if (d->collectionDialog) {
199  d->collectionDialog->setMimeTypeFilter(mimeTypes);
200  }
201 }
202 
204 {
205  if (d->collectionDialog) {
206  return d->collectionDialog->mimeTypeFilter();
207  } else {
208  return QStringList();
209  }
210 }
211 
213 {
214  if (d->collectionDialog) {
215  d->collectionDialog->setAccessRightsFilter(rights);
216  }
217 }
218 
220 {
221  if (d->collectionDialog) {
222  return d->collectionDialog->accessRightsFilter();
223  } else {
225  }
226 }
227 
229 {
230  if (d->collectionDialog) {
231  d->collectionDialog->changeCollectionDialogOptions(options);
232  }
233 }
234 
236 {
237  if (d->collectionDialog) {
238  d->collectionDialog->setContentMimeTypes(mimetypes);
239  }
240 }
241 
242 void CollectionRequester::changeEvent(QEvent *event)
243 {
244  if (event->type() == QEvent::WindowTitleChange) {
245  if (d->collectionDialog) {
246  d->collectionDialog->setWindowTitle(windowTitle());
247  }
248  } else if (event->type() == QEvent::EnabledChange) {
249  if (d->collectionDialog) {
250  d->collectionDialog->setEnabled(true);
251  }
252  }
254 }
255 
256 #include "moc_collectionrequester.cpp"
@ Parent
Only retrieve the immediate parent collection.
WindowTitleChange
void finished(KJob *job)
T take(const Key &key)
Q_EMITQ_EMIT
@ All
Retrieve all ancestors, up to Collection::root()
Akonadi::Collection collection() const
Returns the currently chosen collection, or an empty collection if none none was chosen.
QStringList mimeTypeFilter() const
Returns the mime types any of which the selected collection shall support.
QCA_EXPORT void init()
@ ReadOnly
Can only read items or subcollection of this collection.
Definition: collection.h:90
void clicked(bool checked)
virtual bool event(QEvent *event) override
QIcon fromTheme(const QString &name)
Represents a collection of PIM items.
Definition: collection.h:61
A collection selection dialog.
void collectionChanged(const Akonadi::Collection &collection)
This signal is emitted when the selected collection has changed.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
virtual void changeEvent(QEvent *event)
Job that fetches collections from the Akonadi storage.
void setCollection(const Akonadi::Collection &collection)
Sets the collection of the requester.
QMap::iterator insert(const Key &key, const T &value)
void prepend(const T &value)
QString i18n(const char *text, const TYPE &arg...)
Akonadi::Collection selectedCollection() const
Returns the selected collection if the selection mode is QAbstractItemView::SingleSelection.
CollectionRequester(QWidget *parent=nullptr)
Creates a collection requester.
virtual int exec()
~CollectionRequester() override
Destroys the collection requester.
QString join(const QString &separator) const const
@ Base
Only fetch the base collection.
Collection::Rights accessRightsFilter() const
Returns the access rights that the listed collections shall match with.
Collection parentCollection() const
Returns the parent collection of this object.
Definition: collection.cpp:187
void setContentMimeTypes(const QStringList &mimetypes)
Allow to specify collection content mimetype when we create new one.
void triggered(bool checked)
void changeCollectionDialogOptions(CollectionDialog::CollectionDialogOptions options)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
void setMimeTypeFilter(const QStringList &mimeTypes)
Sets the mime types any of which the selected collection shall support.
void setAccessRightsFilter(Collection::Rights rights)
Sets the access rights that the listed collections shall match with.
A widget to request an Akonadi collection from the user.
QVariant property(const char *name) const const
Helper integration between Akonadi and Qt.
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Sat Jun 25 2022 06:00:31 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.