]> cloud.milkyroute.net Git - dolphin.git/blob - src/kfileplacesmodel.cpp
Further cleanup to prepare the move.
[dolphin.git] / src / kfileplacesmodel.cpp
1 /* This file is part of the KDE project
2 Copyright (C) 2007 Kevin Ottens <ervin@kde.org>
3 Copyright (C) 2007 David Faure <faure@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License version 2 as published by the Free Software Foundation.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public 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
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18
19 */
20 #include "kfileplacesmodel.h"
21 #include "kfileplacesitem_p.h"
22
23 #include <kglobal.h>
24 #include <kstandarddirs.h>
25 #include <kcomponentdata.h>
26 #include <kicon.h>
27
28 #include <kdevicelistmodel.h>
29 #include <kbookmarkmanager.h>
30 #include <kbookmark.h>
31
32 #include <solid/volume.h>
33
34 class KFilePlacesModel::Private
35 {
36 public:
37 Private(KFilePlacesModel *self) : q(self), deviceModel(0), bookmarkManager(0) {}
38
39
40 KFilePlacesModel *q;
41
42 QList<KFilePlacesItem*> items;
43 QMap<QString, QPersistentModelIndex> availableDevices;
44
45 KDeviceListModel *deviceModel;
46 KBookmarkManager *bookmarkManager;
47
48 QVariant bookmarkData(const QString &address, int role) const;
49 QVariant deviceData(const QPersistentModelIndex &index, int role) const;
50
51 void _k_devicesInserted(const QModelIndex &parent, int start, int end);
52 void _k_devicesRemoved(const QModelIndex &parent, int start, int end);
53 void _k_reloadBookmarks();
54 };
55
56 KFilePlacesModel::KFilePlacesModel(QObject *parent)
57 : QAbstractItemModel(parent), d(new Private(this))
58 {
59 QString basePath = KGlobal::mainComponent().componentName();
60 basePath.append("/bookmarks.xml");
61 const QString file = KStandardDirs::locateLocal("data", basePath);
62
63 d->bookmarkManager = KBookmarkManager::managerForFile(file, "dolphin", false);
64
65 d->deviceModel = new KDeviceListModel("IS Volume", this);
66
67 connect(d->deviceModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)),
68 this, SLOT(_k_devicesInserted(const QModelIndex&, int, int)));
69 connect(d->deviceModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)),
70 this, SLOT(_k_devicesRemoved(const QModelIndex&, int, int)));
71 connect(d->bookmarkManager, SIGNAL(changed(const QString&, const QString&)),
72 this, SLOT(_k_reloadBookmarks()));
73
74 d->_k_reloadBookmarks();
75 }
76
77 KFilePlacesModel::~KFilePlacesModel()
78 {
79 delete d;
80 }
81
82 KUrl KFilePlacesModel::url(const QModelIndex &index) const
83 {
84 return KUrl(data(index, UrlRole).toUrl());
85 }
86
87 bool KFilePlacesModel::mountNeeded(const QModelIndex &index) const
88 {
89 return data(index, MountNeededRole).toBool();
90 }
91
92 KIcon KFilePlacesModel::icon(const QModelIndex &index) const
93 {
94 return KIcon(data(index, Qt::DecorationRole).value<QIcon>());
95 }
96
97 QString KFilePlacesModel::text(const QModelIndex &index) const
98 {
99 return data(index, Qt::DisplayRole).toString();
100 }
101
102 QVariant KFilePlacesModel::data(const QModelIndex &index, int role) const
103 {
104 if (!index.isValid())
105 return QVariant();
106
107 QVariant returnData;
108
109 KFilePlacesItem *item = static_cast<KFilePlacesItem*>(index.internalPointer());
110
111 if (item->isDevice()) {
112 returnData = d->deviceData(item->deviceIndex(), role);
113 } else {
114 returnData = d->bookmarkData(item->bookmarkAddress(), role);
115 }
116
117 return returnData;
118 }
119
120 QModelIndex KFilePlacesModel::index(int row, int column, const QModelIndex &parent) const
121 {
122 if (row<0 || column!=0 || row>=d->items.size())
123 return QModelIndex();
124
125 if (parent.isValid())
126 return QModelIndex();
127
128 return createIndex(row, column, d->items[row]);
129 }
130
131 QModelIndex KFilePlacesModel::parent(const QModelIndex &child) const
132 {
133 return QModelIndex();
134 }
135
136 int KFilePlacesModel::rowCount(const QModelIndex &parent) const
137 {
138 if (parent.isValid())
139 return 0;
140 else
141 return d->items.size();
142 }
143
144 int KFilePlacesModel::columnCount(const QModelIndex &parent) const
145 {
146 Q_UNUSED(parent)
147 // We only know 1 piece of information for a particular entry
148 return 1;
149 }
150
151 QModelIndex KFilePlacesModel::closestItem(const KUrl &url) const
152 {
153 int foundRow = -1;
154 int maxLength = 0;
155
156 // Search the item which is equal to the URL or at least is a parent URL.
157 // If there are more than one possible item URL candidates, choose the item
158 // which covers the bigger range of the URL.
159 for (int row = 0; row<d->items.size(); ++row) {
160 KFilePlacesItem *item = d->items[row];
161 KUrl itemUrl;
162
163 if (item->isDevice()) {
164 itemUrl = KUrl(d->deviceData(item->deviceIndex(), UrlRole).toUrl());
165 } else {
166 itemUrl = KUrl(d->bookmarkData(item->bookmarkAddress(), UrlRole).toUrl());
167 }
168
169 if (itemUrl.isParentOf(url)) {
170 const int length = itemUrl.prettyUrl().length();
171 if (length > maxLength) {
172 foundRow = row;
173 maxLength = length;
174 }
175 }
176 }
177
178 if (foundRow==-1)
179 return QModelIndex();
180 else
181 return createIndex(foundRow, 0, d->items[foundRow]);
182 }
183
184 QVariant KFilePlacesModel::Private::bookmarkData(const QString &address, int role) const
185 {
186 KBookmark bookmark = bookmarkManager->findByAddress(address);
187
188 if (bookmark.isNull()) return QVariant();
189
190 switch (role)
191 {
192 case Qt::DisplayRole:
193 return bookmark.text();
194 case Qt::DecorationRole:
195 return KIcon(bookmark.icon());
196 case UrlRole:
197 return QUrl(bookmark.url());
198 case MountNeededRole:
199 return false;
200 default:
201 return QVariant();
202 }
203 }
204
205 QVariant KFilePlacesModel::Private::deviceData(const QPersistentModelIndex &index, int role) const
206 {
207 if (index.isValid()) {
208 switch (role)
209 {
210 case UrlRole:
211 return QUrl(KUrl(deviceModel->deviceForIndex(index).as<Solid::Volume>()->mountPoint()));
212 case MountNeededRole:
213 return !deviceModel->deviceForIndex(index).as<Solid::Volume>()->isMounted();
214 default:
215 return deviceModel->data(index, role);
216 }
217 } else {
218 return QVariant();
219 }
220 }
221
222 void KFilePlacesModel::Private::_k_devicesInserted(const QModelIndex &parent, int start, int end)
223 {
224 for (int i = start; i<=end; ++i) {
225 QModelIndex index = parent.child(i, 0);
226 QString udi = deviceModel->deviceForIndex(index).udi();
227
228 availableDevices[udi] = index;
229 }
230
231 _k_reloadBookmarks();
232 }
233
234 void KFilePlacesModel::Private::_k_devicesRemoved(const QModelIndex &parent, int start, int end)
235 {
236 for (int i = start; i<=end; ++i) {
237 QModelIndex index = parent.child(i, 0);
238 // Can't find by UDI since the device is already invalid.
239 availableDevices.remove(availableDevices.key(index));
240 }
241
242 _k_reloadBookmarks();
243 }
244
245 void KFilePlacesModel::Private::_k_reloadBookmarks()
246 {
247 qDeleteAll(items);
248 items.clear();
249 q->reset();
250
251 KBookmarkGroup root = bookmarkManager->root();
252 KBookmark bookmark = root.first();
253 QMap<QString, QPersistentModelIndex> devices = availableDevices;
254
255 while (!bookmark.isNull()) {
256 QString udi = bookmark.metaDataItem("UDI");
257 QPersistentModelIndex index = devices.take(udi);
258
259 if (udi.isEmpty() || index.isValid()) {
260 q->beginInsertRows(QModelIndex(), items.size(), items.size());
261
262 KFilePlacesItem *item = new KFilePlacesItem();
263 item->setBookmarkAddress(bookmark.address());
264 if (index.isValid()) {
265 item->setDeviceIndex(index);
266 // TODO: Update bookmark internal element
267 }
268 items << item;
269
270 q->endInsertRows();
271 }
272
273 bookmark = root.next(bookmark);
274 }
275
276 // Add bookmarks for the remaining devices, they were previously unknown
277 foreach (QString udi, devices.keys()) {
278 bookmark = root.createNewSeparator();
279 bookmark.setMetaDataItem("UDI", udi);
280
281 q->beginInsertRows(QModelIndex(), items.size(), items.size());
282
283 KFilePlacesItem *item = new KFilePlacesItem();
284 item->setBookmarkAddress(bookmark.address());
285 item->setDeviceIndex(devices[udi]);
286 // TODO: Update bookmark internal element
287 items << item;
288
289 q->endInsertRows();
290 }
291 }
292
293 #include "kfileplacesmodel.moc"