1 | /* |
2 | Copyright (c) 2007 Volker Krause <vkrause@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 "subscriptiondialog_p.h" |
21 | |
22 | #include "control.h" |
23 | #include "recursivecollectionfilterproxymodel.h" |
24 | #include "subscriptionjob_p.h" |
25 | #include "subscriptionmodel_p.h" |
26 | |
27 | #include <kdebug.h> |
28 | #include <kglobal.h> |
29 | #include <ksharedconfig.h> |
30 | |
31 | #include <klocalizedstring.h> |
32 | |
33 | #include <QVBoxLayout> |
34 | #include <QHBoxLayout> |
35 | |
36 | #ifndef KDEPIM_MOBILE_UI |
37 | #include <klineedit.h> |
38 | #include <KPushButton> |
39 | #include <krecursivefilterproxymodel.h> |
40 | #include <QHeaderView> |
41 | #include <QLabel> |
42 | #include <QTreeView> |
43 | #include <QCheckBox> |
44 | #else |
45 | #include <kdescendantsproxymodel.h> |
46 | #include <QListView> |
47 | #include <QSortFilterProxyModel> |
48 | |
49 | class CheckableFilterProxyModel : public QSortFilterProxyModel |
50 | { |
51 | public: |
52 | CheckableFilterProxyModel(QObject *parent = 0) |
53 | : QSortFilterProxyModel(parent) |
54 | { |
55 | } |
56 | |
57 | protected: |
58 | /*reimp*/ |
59 | bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const |
60 | { |
61 | QModelIndex sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent); |
62 | return sourceModel()->flags(sourceIndex) &Qt::ItemIsUserCheckable; |
63 | } |
64 | }; |
65 | #endif |
66 | |
67 | using namespace Akonadi; |
68 | |
69 | /** |
70 | * @internal |
71 | */ |
72 | class SubscriptionDialog::Private |
73 | { |
74 | public: |
75 | Private(SubscriptionDialog *parent) |
76 | : q(parent) |
77 | { |
78 | } |
79 | |
80 | void done() |
81 | { |
82 | SubscriptionJob *job = new SubscriptionJob(q); |
83 | job->subscribe(model->subscribed()); |
84 | job->unsubscribe(model->unsubscribed()); |
85 | connect(job, SIGNAL(result(KJob*)), q, SLOT(subscriptionResult(KJob*))); |
86 | } |
87 | |
88 | void subscriptionResult(KJob *job) |
89 | { |
90 | if (job->error()) { |
91 | // TODO |
92 | kWarning() << job->errorString(); |
93 | } |
94 | q->deleteLater(); |
95 | } |
96 | |
97 | void modelLoaded() |
98 | { |
99 | collectionView->setEnabled(true); |
100 | #ifndef KDEPIM_MOBILE_UI |
101 | collectionView->expandAll(); |
102 | #endif |
103 | q->enableButtonOk(true); |
104 | } |
105 | |
106 | void slotSetPattern(const QString &text) |
107 | { |
108 | filterRecursiveCollectionFilter->setSearchPattern(text); |
109 | #ifndef KDEPIM_MOBILE_UI |
110 | collectionView->expandAll(); |
111 | #endif |
112 | } |
113 | |
114 | void slotSetIncludeCheckedOnly(bool checked) |
115 | { |
116 | filterRecursiveCollectionFilter->setIncludeCheckedOnly(checked); |
117 | } |
118 | |
119 | void writeConfig() |
120 | { |
121 | KConfigGroup group(KGlobal::config(), "SubscriptionDialog" ); |
122 | group.writeEntry("Size" , q->size()); |
123 | } |
124 | |
125 | void readConfig() |
126 | { |
127 | KConfigGroup group(KGlobal::config(), "SubscriptionDialog" ); |
128 | const QSize sizeDialog = group.readEntry("Size" , QSize(300, 200)); |
129 | if (sizeDialog.isValid()) { |
130 | q->resize(sizeDialog); |
131 | } |
132 | } |
133 | |
134 | void slotUnSubscribe(); |
135 | void slotSubscribe(); |
136 | |
137 | SubscriptionDialog *q; |
138 | #ifndef KDEPIM_MOBILE_UI |
139 | QTreeView *collectionView; |
140 | KPushButton *subscribe; |
141 | KPushButton *unSubscribe; |
142 | #else |
143 | QListView *collectionView; |
144 | #endif |
145 | SubscriptionModel *model; |
146 | RecursiveCollectionFilterProxyModel *filterRecursiveCollectionFilter; |
147 | |
148 | }; |
149 | |
150 | void SubscriptionDialog::Private::slotSubscribe() |
151 | { |
152 | #ifndef KDEPIM_MOBILE_UI |
153 | QModelIndexList list = collectionView->selectionModel()->selectedIndexes(); |
154 | foreach (const QModelIndex &index, list) { |
155 | model->setData(index, Qt::Checked, Qt::CheckStateRole); |
156 | } |
157 | collectionView->setFocus(); |
158 | #endif |
159 | } |
160 | |
161 | void SubscriptionDialog::Private::slotUnSubscribe() |
162 | { |
163 | #ifndef KDEPIM_MOBILE_UI |
164 | QModelIndexList list = collectionView->selectionModel()->selectedIndexes(); |
165 | foreach (const QModelIndex &index, list) { |
166 | model->setData(index, Qt::Unchecked, Qt::CheckStateRole); |
167 | } |
168 | collectionView->setFocus(); |
169 | #endif |
170 | } |
171 | |
172 | SubscriptionDialog::SubscriptionDialog(QWidget *parent) |
173 | : KDialog(parent) |
174 | , d(new Private(this)) |
175 | { |
176 | init(QStringList()); |
177 | } |
178 | |
179 | SubscriptionDialog::SubscriptionDialog(const QStringList &mimetypes, QWidget *parent) |
180 | : KDialog(parent) |
181 | , d(new Private(this)) |
182 | { |
183 | init(mimetypes); |
184 | } |
185 | |
186 | void SubscriptionDialog::showHiddenCollection(bool showHidden) |
187 | { |
188 | d->model->showHiddenCollection(showHidden); |
189 | } |
190 | |
191 | void SubscriptionDialog::init(const QStringList &mimetypes) |
192 | { |
193 | enableButtonOk(false); |
194 | setCaption(i18n("Local Subscriptions" )); |
195 | QWidget *mainWidget = new QWidget(this); |
196 | QVBoxLayout *mainLayout = new QVBoxLayout; |
197 | mainWidget->setLayout(mainLayout); |
198 | setMainWidget(mainWidget); |
199 | |
200 | d->model = new SubscriptionModel(this); |
201 | |
202 | #ifndef KDEPIM_MOBILE_UI |
203 | d->filterRecursiveCollectionFilter |
204 | = new Akonadi::RecursiveCollectionFilterProxyModel(this); |
205 | d->filterRecursiveCollectionFilter->setDynamicSortFilter(true); |
206 | d->filterRecursiveCollectionFilter->setSourceModel(d->model); |
207 | d->filterRecursiveCollectionFilter->setFilterCaseSensitivity(Qt::CaseInsensitive); |
208 | if (!mimetypes.isEmpty()) { |
209 | d->filterRecursiveCollectionFilter->addContentMimeTypeInclusionFilters(mimetypes); |
210 | } |
211 | |
212 | d->collectionView = new QTreeView(mainWidget); |
213 | d->collectionView->setEditTriggers(QAbstractItemView::NoEditTriggers); |
214 | d->collectionView->header()->hide(); |
215 | d->collectionView->setModel(d->filterRecursiveCollectionFilter); |
216 | d->collectionView->setSelectionMode(QAbstractItemView::ExtendedSelection); |
217 | |
218 | QHBoxLayout *filterBarLayout = new QHBoxLayout; |
219 | |
220 | filterBarLayout->addWidget(new QLabel(i18n("Search:" ))); |
221 | |
222 | KLineEdit *lineEdit = new KLineEdit(mainWidget); |
223 | lineEdit->setClearButtonShown(true); |
224 | lineEdit->setFocus(); |
225 | connect(lineEdit, SIGNAL(textChanged(QString)), |
226 | this, SLOT(slotSetPattern(QString))); |
227 | filterBarLayout->addWidget(lineEdit); |
228 | QCheckBox *checkBox = new QCheckBox(i18n("Subscribed only" ), mainWidget); |
229 | connect(checkBox, SIGNAL(clicked(bool)), |
230 | this, SLOT(slotSetIncludeCheckedOnly(bool))); |
231 | filterBarLayout->addWidget(checkBox); |
232 | |
233 | QHBoxLayout *hboxLayout = new QHBoxLayout; |
234 | hboxLayout->addWidget(d->collectionView); |
235 | |
236 | QVBoxLayout *subscribeButtonLayout = new QVBoxLayout; |
237 | d->subscribe = new KPushButton(i18n("Subscribe" )); |
238 | subscribeButtonLayout->addWidget(d->subscribe); |
239 | connect(d->subscribe, SIGNAL(clicked()), this, SLOT(slotSubscribe())); |
240 | |
241 | d->unSubscribe = new KPushButton(i18n("Unsubscribe" )); |
242 | subscribeButtonLayout->addWidget(d->unSubscribe); |
243 | connect(d->unSubscribe, SIGNAL(clicked()), this, SLOT(slotUnSubscribe())); |
244 | subscribeButtonLayout->addItem(new QSpacerItem(5, 5, QSizePolicy::Minimum, QSizePolicy::Expanding)); |
245 | |
246 | hboxLayout->addLayout(subscribeButtonLayout); |
247 | |
248 | mainLayout->addLayout(filterBarLayout); |
249 | mainLayout->addLayout(hboxLayout); |
250 | |
251 | #else |
252 | |
253 | d->filterRecursiveCollectionFilter |
254 | = new Akonadi::RecursiveCollectionFilterProxyModel(this); |
255 | if (!mimetypes.isEmpty()) { |
256 | d->filterRecursiveCollectionFilter->addContentMimeTypeInclusionFilters(mimetypes); |
257 | } |
258 | |
259 | d->filterRecursiveCollectionFilter->setSourceModel(d->model); |
260 | |
261 | KDescendantsProxyModel *flatModel = new KDescendantsProxyModel(this); |
262 | flatModel->setDisplayAncestorData(true); |
263 | flatModel->setAncestorSeparator(QLatin1String("/" )); |
264 | flatModel->setSourceModel(d->filterRecursiveCollectionFilter); |
265 | |
266 | CheckableFilterProxyModel *checkableModel = new CheckableFilterProxyModel(this); |
267 | checkableModel->setSourceModel(flatModel); |
268 | |
269 | d->collectionView = new QListView(mainWidget); |
270 | |
271 | d->collectionView->setModel(checkableModel); |
272 | mainLayout->addWidget(d->collectionView); |
273 | #endif |
274 | |
275 | connect(d->model, SIGNAL(loaded()), SLOT(modelLoaded())); |
276 | connect(this, SIGNAL(okClicked()), SLOT(done())); |
277 | connect(this, SIGNAL(cancelClicked()), SLOT(deleteLater())); |
278 | Control::widgetNeedsAkonadi(mainWidget); |
279 | d->readConfig(); |
280 | } |
281 | |
282 | SubscriptionDialog::~SubscriptionDialog() |
283 | { |
284 | d->writeConfig(); |
285 | delete d; |
286 | } |
287 | |
288 | #include "moc_subscriptiondialog_p.cpp" |
289 | |