1/*
2 Copyright 2008 Ingo Klöcker <kloecker@kde.org>
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 "collectionrequester.h"
21#include "collectiondialog.h"
22#include "entitydisplayattribute.h"
23#include "collectionfetchjob.h"
24#include "collectionfetchscope.h"
25
26#include <klineedit.h>
27#include <klocalizedstring.h>
28#include <kpushbutton.h>
29#include <kicon.h>
30#include <kstandardshortcut.h>
31
32#include <QtCore/QEvent>
33#include <QAction>
34
35using namespace Akonadi;
36
37class CollectionRequester::Private
38{
39public:
40 Private(CollectionRequester *parent)
41 : q(parent)
42 , edit(0)
43 , button(0)
44 , collectionDialog(0)
45 {
46 }
47
48 ~Private()
49 {
50 }
51
52 void fetchCollection(const Collection &collection);
53
54 void init();
55
56 // slots
57 void _k_slotOpenDialog();
58 void _k_collectionReceived(KJob *job);
59 void _k_collectionsNamesReceived(KJob *job);
60
61 CollectionRequester *q;
62 Collection collection;
63 KLineEdit *edit;
64 KPushButton *button;
65 CollectionDialog *collectionDialog;
66};
67
68void CollectionRequester::Private::fetchCollection(const Collection &collection)
69{
70 CollectionFetchJob *job = new CollectionFetchJob(collection, Akonadi::CollectionFetchJob::Base, q);
71 job->setProperty("OriginalCollectionId", collection.id());
72 job->fetchScope().setAncestorRetrieval(CollectionFetchScope::All);
73 connect(job, SIGNAL(finished(KJob*)),
74 q, SLOT(_k_collectionReceived(KJob*)));
75}
76
77void CollectionRequester::Private::_k_collectionReceived(KJob *job)
78{
79 CollectionFetchJob *fetch = qobject_cast<CollectionFetchJob*>(job);
80 Collection::List chain;
81 if (fetch->collections().size() == 1) {
82 Collection currentCollection = fetch->collections().first();
83 while (currentCollection.isValid()) {
84 chain << currentCollection;
85 currentCollection = Collection(currentCollection.parentCollection());
86 }
87
88 CollectionFetchJob *namesFetch = new CollectionFetchJob(chain, CollectionFetchJob::Base, q);
89 namesFetch->setProperty("OriginalCollectionId", job->property("OriginalCollectionId"));
90 namesFetch->fetchScope().setAncestorRetrieval(CollectionFetchScope::Parent);
91 connect(namesFetch, SIGNAL(finished(KJob*)),
92 q, SLOT(_k_collectionsNamesReceived(KJob*)));
93 } else {
94 _k_collectionsNamesReceived(job);
95 }
96}
97
98void CollectionRequester::Private::_k_collectionsNamesReceived(KJob *job)
99{
100 CollectionFetchJob *fetch = qobject_cast<CollectionFetchJob*>(job);
101 const qint64 originalId = fetch->property("OriginalCollectionId").toLongLong();
102
103 QMap<qint64, Collection> names;
104 Q_FOREACH (const Collection &collection, fetch->collections()) {
105 names.insert(collection.id(), collection);
106 }
107
108 QStringList namesList;
109 Collection currentCollection = names.take(originalId);
110 while (currentCollection.isValid()) {
111 namesList.prepend(currentCollection.displayName());
112 currentCollection = names.take(currentCollection.parent());
113 }
114 edit->setText(namesList.join(QLatin1String( "/")));
115}
116
117void CollectionRequester::Private::init()
118{
119 q->setMargin(0);
120
121 edit = new KLineEdit(q);
122 edit->setReadOnly(true);
123 edit->setClickMessage(i18n("No Folder"));
124 edit->setClearButtonShown(false);
125 edit->setFocusPolicy(Qt::NoFocus);
126
127 button = new KPushButton(q);
128 button->setIcon(KIcon(QLatin1String("document-open")));
129 const int buttonSize = edit->sizeHint().height();
130 button->setFixedSize(buttonSize, buttonSize);
131 button->setToolTip(i18n("Open collection dialog"));
132
133 q->setSpacing(-1);
134
135 edit->installEventFilter(q);
136 q->setFocusProxy(button);
137 q->setFocusPolicy(Qt::StrongFocus);
138
139 q->connect(button, SIGNAL(clicked()), q, SLOT(_k_slotOpenDialog()));
140
141 QAction *openAction = new QAction(q);
142 openAction->setShortcut(KStandardShortcut::Open);
143 q->connect(openAction, SIGNAL(triggered(bool)), q, SLOT(_k_slotOpenDialog()));
144
145 collectionDialog = new CollectionDialog(q);
146 collectionDialog->setWindowIcon(KIcon(QLatin1String("akonadi")));
147 collectionDialog->setCaption(i18n("Select a collection"));
148 collectionDialog->setSelectionMode(QAbstractItemView::SingleSelection);
149 collectionDialog->changeCollectionDialogOptions(CollectionDialog::KeepTreeExpanded);
150}
151
152void CollectionRequester::Private::_k_slotOpenDialog()
153{
154 CollectionDialog *dlg = collectionDialog;
155
156 if (dlg->exec() != QDialog::Accepted) {
157 return;
158 }
159
160 const Akonadi::Collection collection = dlg->selectedCollection();
161 q->setCollection(collection);
162 emit q->collectionChanged(collection);
163}
164
165CollectionRequester::CollectionRequester(QWidget *parent)
166 : KHBox(parent)
167 , d(new Private(this))
168{
169 d->init();
170}
171
172CollectionRequester::CollectionRequester(const Akonadi::Collection &collection, QWidget *parent)
173 : KHBox(parent)
174 , d(new Private(this))
175{
176 d->init();
177 setCollection(collection);
178}
179
180CollectionRequester::~CollectionRequester()
181{
182 delete d;
183}
184
185Collection CollectionRequester::collection() const
186{
187 return d->collection;
188}
189
190void CollectionRequester::setCollection(const Collection &collection)
191{
192 d->collection = collection;
193 QString name;
194 if (collection.isValid()) {
195 name = collection.displayName();
196 }
197
198 d->edit->setText(name);
199 emit collectionChanged(collection);
200 d->fetchCollection(collection);
201}
202
203void CollectionRequester::setMimeTypeFilter(const QStringList &mimeTypes)
204{
205 if (d->collectionDialog) {
206 d->collectionDialog->setMimeTypeFilter(mimeTypes);
207 }
208}
209
210QStringList CollectionRequester::mimeTypeFilter() const
211{
212 if (d->collectionDialog) {
213 return d->collectionDialog->mimeTypeFilter();
214 } else {
215 return QStringList();
216 }
217}
218
219void CollectionRequester::setAccessRightsFilter(Collection::Rights rights)
220{
221 if (d->collectionDialog) {
222 d->collectionDialog->setAccessRightsFilter(rights);
223 }
224}
225
226Collection::Rights CollectionRequester::accessRightsFilter() const
227{
228 if (d->collectionDialog) {
229 return d->collectionDialog->accessRightsFilter();
230 } else {
231 return Akonadi::Collection::ReadOnly;
232 }
233}
234
235void CollectionRequester::changeCollectionDialogOptions(CollectionDialog::CollectionDialogOptions options)
236{
237 if (d->collectionDialog) {
238 d->collectionDialog->changeCollectionDialogOptions(options);
239 }
240}
241
242void CollectionRequester::changeEvent(QEvent *event)
243{
244 if (event->type() == QEvent::WindowTitleChange) {
245 if (d->collectionDialog) {
246 d->collectionDialog->setCaption(windowTitle());
247 }
248 } else if (event->type() == QEvent::EnabledChange) {
249 if (d->collectionDialog) {
250 d->collectionDialog->setEnabled(true);
251 }
252 }
253 KHBox::changeEvent(event);
254}
255
256#include "moc_collectionrequester.cpp"
257