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>
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.
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.
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.
20 #include "kfileplacesmodel.h"
21 #include "kfileplacesitem_p.h"
24 #include <kstandarddirs.h>
25 #include <kcomponentdata.h>
28 #include <kdevicelistmodel.h>
29 #include <kbookmarkmanager.h>
30 #include <kbookmark.h>
32 #include <solid/volume.h>
34 class KFilePlacesModel::Private
37 Private(KFilePlacesModel
*self
) : q(self
), deviceModel(0), bookmarkManager(0) {}
42 QList
<KFilePlacesItem
*> items
;
43 QMap
<QString
, QPersistentModelIndex
> availableDevices
;
45 KDeviceListModel
*deviceModel
;
46 KBookmarkManager
*bookmarkManager
;
48 QVariant
bookmarkData(const QString
&address
, int role
) const;
49 QVariant
deviceData(const QPersistentModelIndex
&index
, int role
) const;
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();
56 KFilePlacesModel::KFilePlacesModel(QObject
*parent
)
57 : QAbstractItemModel(parent
), d(new Private(this))
59 QString basePath
= KGlobal::mainComponent().componentName();
60 basePath
.append("/bookmarks.xml");
61 const QString file
= KStandardDirs::locateLocal("data", basePath
);
63 d
->bookmarkManager
= KBookmarkManager::managerForFile(file
, "dolphin", false);
65 d
->deviceModel
= new KDeviceListModel("IS Volume", this);
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()));
74 d
->_k_reloadBookmarks();
77 KFilePlacesModel::~KFilePlacesModel()
82 KUrl
KFilePlacesModel::url(const QModelIndex
&index
) const
84 return KUrl(data(index
, UrlRole
).toString());
87 bool KFilePlacesModel::mountNeeded(const QModelIndex
&index
) const
89 return data(index
, MountNeededRole
).toBool();
92 QVariant
KFilePlacesModel::data(const QModelIndex
&index
, int role
) const
99 KFilePlacesItem
*item
= static_cast<KFilePlacesItem
*>(index
.internalPointer());
101 if (item
->isDevice()) {
102 returnData
= d
->deviceData(item
->deviceIndex(), role
);
104 returnData
= d
->bookmarkData(item
->bookmarkAddress(), role
);
110 QModelIndex
KFilePlacesModel::index(int row
, int column
, const QModelIndex
&parent
) const
112 if (row
<0 || column
!=0 || row
>=d
->items
.size())
113 return QModelIndex();
115 if (parent
.isValid())
116 return QModelIndex();
118 return createIndex(row
, column
, d
->items
[row
]);
121 QModelIndex
KFilePlacesModel::parent(const QModelIndex
&child
) const
123 return QModelIndex();
126 int KFilePlacesModel::rowCount(const QModelIndex
&parent
) const
128 if (parent
.isValid())
131 return d
->items
.size();
134 int KFilePlacesModel::columnCount(const QModelIndex
&parent
) const
137 // We only know 1 information for a particualiar entry
141 QModelIndex
KFilePlacesModel::closestItem(const KUrl
&url
) const
146 // Search the item which is equal to the URL or at least is a parent URL.
147 // If there are more than one possible item URL candidates, choose the item
148 // which covers the bigger range of the URL.
149 for (int row
= 0; row
<d
->items
.size(); ++row
) {
150 KFilePlacesItem
*item
= d
->items
[row
];
153 if (item
->isDevice()) {
154 itemUrl
= KUrl(d
->deviceData(item
->deviceIndex(), UrlRole
).toString());
156 itemUrl
= KUrl(d
->bookmarkData(item
->bookmarkAddress(), UrlRole
).toString());
159 if (itemUrl
.isParentOf(url
)) {
160 const int length
= itemUrl
.prettyUrl().length();
161 if (length
> maxLength
) {
169 return QModelIndex();
171 return createIndex(foundRow
, 0, d
->items
[foundRow
]);
174 QVariant
KFilePlacesModel::Private::bookmarkData(const QString
&address
, int role
) const
176 KBookmark bookmark
= bookmarkManager
->findByAddress(address
);
178 if (bookmark
.isNull()) return QVariant();
182 case Qt::DisplayRole
:
183 return bookmark
.text();
184 case Qt::DecorationRole
:
185 return KIcon(bookmark
.icon());
187 return bookmark
.url();
188 case MountNeededRole
:
195 QVariant
KFilePlacesModel::Private::deviceData(const QPersistentModelIndex
&index
, int role
) const
197 if (index
.isValid()) {
201 return KUrl(deviceModel
->deviceForIndex(index
).as
<Solid::Volume
>()->mountPoint());
202 case MountNeededRole
:
203 return !deviceModel
->deviceForIndex(index
).as
<Solid::Volume
>()->isMounted();
205 return deviceModel
->data(index
, role
);
212 void KFilePlacesModel::Private::_k_devicesInserted(const QModelIndex
&parent
, int start
, int end
)
214 for (int i
= start
; i
<=end
; ++i
) {
215 QModelIndex index
= parent
.child(i
, 0);
216 QString udi
= deviceModel
->deviceForIndex(index
).udi();
218 availableDevices
[udi
] = index
;
221 _k_reloadBookmarks();
224 void KFilePlacesModel::Private::_k_devicesRemoved(const QModelIndex
&parent
, int start
, int end
)
226 for (int i
= start
; i
<=end
; ++i
) {
227 QModelIndex index
= parent
.child(i
, 0);
228 // Can't find by UDI since the device is already invalid.
229 availableDevices
.remove(availableDevices
.key(index
));
232 _k_reloadBookmarks();
235 void KFilePlacesModel::Private::_k_reloadBookmarks()
241 KBookmarkGroup root
= bookmarkManager
->root();
242 KBookmark bookmark
= root
.first();
243 QMap
<QString
, QPersistentModelIndex
> devices
= availableDevices
;
245 while (!bookmark
.isNull()) {
246 QString udi
= bookmark
.metaDataItem("UDI");
247 QPersistentModelIndex index
= devices
.take(udi
);
249 if (udi
.isEmpty() || index
.isValid()) {
250 q
->beginInsertRows(QModelIndex(), items
.size(), items
.size());
252 KFilePlacesItem
*item
= new KFilePlacesItem();
253 item
->setBookmarkAddress(bookmark
.address());
254 if (index
.isValid()) {
255 item
->setDeviceIndex(index
);
256 // TODO: Update bookmark internal element
263 bookmark
= root
.next(bookmark
);
266 // Add bookmarks for the remaining devices, they were previously unknown
267 foreach (QString udi
, devices
.keys()) {
268 bookmark
= root
.createNewSeparator();
269 bookmark
.setMetaDataItem("UDI", udi
);
271 q
->beginInsertRows(QModelIndex(), items
.size(), items
.size());
273 KFilePlacesItem
*item
= new KFilePlacesItem();
274 item
->setBookmarkAddress(bookmark
.address());
275 item
->setDeviceIndex(devices
[udi
]);
276 // TODO: Update bookmark internal element
283 #include "kfileplacesmodel.moc"