Akonadi

collectionpathresolver.cpp
1 /*
2  Copyright (c) 2007 Volker Krause <[email protected]>
3 
4  This library is free software; you can redistribute it and/or modify it
5  under the terms of the GNU Library General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or (at your
7  option) any later version.
8 
9  This library is distributed in the hope that it will be useful, but WITHOUT
10  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12  License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to the
16  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  02110-1301, USA.
18 */
19 
20 #include "collectionpathresolver.h"
21 
22 #include "collectionfetchjob.h"
23 #include "job_p.h"
24 
25 #include "akonadicore_debug.h"
26 
27 #include <KLocalizedString>
28 
29 #include <QStringList>
30 
31 using namespace Akonadi;
32 
33 //@cond PRIVATE
34 
35 class Akonadi::CollectionPathResolverPrivate : public JobPrivate
36 {
37 public:
38  CollectionPathResolverPrivate(CollectionPathResolver *parent)
39  : JobPrivate(parent)
40  , mColId(-1)
41  , mPathToId(false)
42  {
43  }
44 
45  void init(const QString &path, const Collection &rootCollection)
46  {
48 
49  mPathToId = true;
50  mPath = path;
51  if (mPath.startsWith(q->pathDelimiter())) {
52  mPath = mPath.right(mPath.length() - q->pathDelimiter().length());
53  }
54  if (mPath.endsWith(q->pathDelimiter())) {
55  mPath = mPath.left(mPath.length() - q->pathDelimiter().length());
56  }
57 
58  mPathParts = splitPath(mPath);
59  mCurrentNode = rootCollection;
60  }
61 
62  void jobResult(KJob *job);
63 
64  QStringList splitPath(const QString &path)
65  {
66  if (path.isEmpty()) { // path is normalized, so non-empty means at least one hit
67  return QStringList();
68  }
69 
70  QStringList rv;
71  int begin = 0;
72  const int pathSize(path.size());
73  for (int i = 0; i < pathSize; ++i) {
74  if (path[i] == QLatin1Char('/')) {
75  QString pathElement = path.mid(begin, i - begin);
76  pathElement.replace(QLatin1String("\\/"), QLatin1String("/"));
77  rv.append(pathElement);
78  begin = i + 1;
79  }
80  if (i < path.size() - 2 && path[i] == QLatin1Char('\\') && path[i + 1] == QLatin1Char('/')) {
81  ++i;
82  }
83  }
84  QString pathElement = path.mid(begin);
85  pathElement.replace(QLatin1String("\\/"), QLatin1String("/"));
86  rv.append(pathElement);
87  return rv;
88  }
89 
90  Q_DECLARE_PUBLIC(CollectionPathResolver)
91 
92  Collection mCurrentNode;
93  QStringList mPathParts;
94  QString mPath;
95  Collection::Id mColId;
96  bool mPathToId = false;
97 };
98 
99 void CollectionPathResolverPrivate::jobResult(KJob *job)
100 {
101  if (job->error()) {
102  return;
103  }
104 
106 
107  CollectionFetchJob *list = static_cast<CollectionFetchJob *>(job);
108  CollectionFetchJob *nextJob = nullptr;
109  const Collection::List cols = list->collections();
110  if (cols.isEmpty()) {
111  mColId = -1;
112  q->setError(CollectionPathResolver::Unknown);
113  q->setErrorText(i18n("No such collection."));
114  q->emitResult();
115  return;
116  }
117 
118  if (mPathToId) {
119  const QString currentPart = mPathParts.takeFirst();
120  bool found = false;
121  for (const Collection &c : cols) {
122  if (c.name() == currentPart) {
123  mCurrentNode = c;
124  found = true;
125  break;
126  }
127  }
128  if (!found) {
129  qCWarning(AKONADICORE_LOG) << "No such collection" << currentPart << "with parent" << mCurrentNode.id();
130  mColId = -1;
131  q->setError(CollectionPathResolver::Unknown);
132  q->setErrorText(i18n("No such collection."));
133  q->emitResult();
134  return;
135  }
136  if (mPathParts.isEmpty()) {
137  mColId = mCurrentNode.id();
138  q->emitResult();
139  return;
140  }
141  nextJob = new CollectionFetchJob(mCurrentNode, CollectionFetchJob::FirstLevel, q);
142  } else {
143  Collection col = list->collections().at(0);
144  mCurrentNode = col.parentCollection();
145  mPathParts.prepend(col.name());
146  if (mCurrentNode == Collection::root()) {
147  q->emitResult();
148  return;
149  }
150  nextJob = new CollectionFetchJob(mCurrentNode, CollectionFetchJob::Base, q);
151  }
152  q->connect(nextJob, &CollectionFetchJob::result, q, [this](KJob *job) { jobResult(job);});
153 }
154 
156  : Job(new CollectionPathResolverPrivate(this), parent)
157 {
159  d->init(path, Collection::root());
160 }
161 
162 CollectionPathResolver::CollectionPathResolver(const QString &path, const Collection &parentCollection, QObject *parent)
163  : Job(new CollectionPathResolverPrivate(this), parent)
164 {
166  d->init(path, parentCollection);
167 }
168 
170  : Job(new CollectionPathResolverPrivate(this), parent)
171 {
173 
174  d->mPathToId = false;
175  d->mColId = collection.id();
176  d->mCurrentNode = collection;
177 }
178 
180 {
181 }
182 
184 {
185  Q_D(const CollectionPathResolver);
186 
187  return d->mColId;
188 }
189 
191 {
192  Q_D(const CollectionPathResolver);
193 
194  if (d->mPathToId) {
195  return d->mPath;
196  }
197  return d->mPathParts.join(pathDelimiter());
198 }
199 
201 {
202  return QStringLiteral("/");
203 }
204 
206 {
208 
209  CollectionFetchJob *job = nullptr;
210  if (d->mPathToId) {
211  if (d->mPath.isEmpty()) {
212  d->mColId = Collection::root().id();
213  emitResult();
214  return;
215  }
216  job = new CollectionFetchJob(d->mCurrentNode, CollectionFetchJob::FirstLevel, this);
217  } else {
218  if (d->mColId == 0) {
219  d->mColId = Collection::root().id();
220  emitResult();
221  return;
222  }
223  job = new CollectionFetchJob(d->mCurrentNode, CollectionFetchJob::Base, this);
224  }
225  connect(job, &CollectionFetchJob::result, this, [d](KJob *job) { d->jobResult(job);});
226 }
227 
228 //@endcond
229 
230 #include "moc_collectionpathresolver.cpp"
CollectionPathResolver(const QString &path, QObject *parent=nullptr)
Creates a new collection path resolver to convert a path into a id.
Collection::List collections() const
Returns the list of fetched collection.
Collection::Id collection() const
Returns the collection id.
QString name() const
Returns the i18n&#39;ed name of the collection.
Definition: collection.cpp:225
void emitResult()
void doStart() override
This method must be reimplemented in the concrete jobs.
Unknown error.
Definition: job.h:115
Only list direct sub-collections of the base collection.
Represents a collection of PIM items.
Definition: collection.h:76
qint64 Id
Describes the unique id type.
Definition: collection.h:82
int size() const const
Job that fetches collections from the Akonadi storage.
Base class for all actions in the Akonadi storage.
Definition: job.h:93
const QList< QKeySequence > & begin()
Only fetch the base collection.
QUICKADDONS_EXPORT void init()
void append(const T &value)
QString path() const
Returns the collection path.
bool isEmpty() const const
bool isEmpty() const const
static Collection root()
Returns the root collection.
Definition: collection.cpp:303
Collection parentCollection() const
Returns the parent collection of this object.
Definition: collection.cpp:211
QString right(int n) const const
QString i18n(const char *text, const TYPE &arg...)
QString & replace(int position, int n, QChar after)
const T & at(int i) const const
Id id() const
Returns the unique identifier of the collection.
Definition: collection.cpp:112
QString mid(int position, int n) const const
T takeFirst()
bool isEmpty() const const
Helper integration between Akonadi and Qt.
QString left(int n) const const
~CollectionPathResolver() override
Destroys the collection path resolver.
void prepend(const T &value)
void result(KJob *job)
static QString pathDelimiter()
Returns the path delimiter for collections.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
KIOFILEWIDGETS_EXPORT QStringList list(const QString &fileClass)
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon May 25 2020 22:46:08 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.