1 | /* This file is part of the KDE project |
2 | Copyright (C) 2007 Kevin Ottens <ervin@kde.org> |
3 | |
4 | This library is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU Library General Public |
6 | License version 2 as published by the Free Software Foundation. |
7 | |
8 | This library is distributed in the hope that it will be useful, |
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
11 | Library General Public License for more details. |
12 | |
13 | You should have received a copy of the GNU Library General Public License |
14 | along with this library; see the file COPYING.LIB. If not, write to |
15 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
16 | Boston, MA 02110-1301, USA. |
17 | |
18 | */ |
19 | |
20 | #include "kfileplacesitem_p.h" |
21 | #include "kfileplacesmodel.h" |
22 | |
23 | #include <QtCore/QDateTime> |
24 | |
25 | #include <kbookmarkmanager.h> |
26 | #include <kiconloader.h> |
27 | #include <kdirlister.h> |
28 | #include <klocale.h> |
29 | #include <solid/block.h> |
30 | #include <solid/opticaldisc.h> |
31 | #include <solid/opticaldrive.h> |
32 | #include <solid/storageaccess.h> |
33 | #include <solid/storagevolume.h> |
34 | #include <solid/storagedrive.h> |
35 | #include <solid/portablemediaplayer.h> |
36 | |
37 | |
38 | KFilePlacesItem::KFilePlacesItem(KBookmarkManager *manager, |
39 | const QString &address, |
40 | const QString &udi) |
41 | : m_manager(manager), m_lister(0), m_folderIsEmpty(true), m_isCdrom(false), |
42 | m_isAccessible(false), m_device(udi) |
43 | { |
44 | setBookmark(m_manager->findByAddress(address)); |
45 | |
46 | if (udi.isEmpty() && m_bookmark.metaDataItem("ID" ).isEmpty()) { |
47 | m_bookmark.setMetaDataItem("ID" , generateNewId()); |
48 | } else if (udi.isEmpty()) { |
49 | if (hasFullIcon(m_bookmark)) { |
50 | // TODO if this is only for the trash, it would be much faster to just read trashrc |
51 | m_lister = new KDirLister(this); |
52 | m_lister->setAutoErrorHandlingEnabled(false, 0); // don't bother the user if trash:/ doesn't exist |
53 | m_lister->setDelayedMimeTypes(true); // we don't need the mimetypes, so don't penalize other KDirLister users |
54 | connect(m_lister, SIGNAL(completed()), |
55 | this, SLOT(onListerCompleted())); |
56 | m_lister->openUrl(m_bookmark.url()); |
57 | } |
58 | } else if (!udi.isEmpty() && m_device.isValid()) { |
59 | m_access = m_device.as<Solid::StorageAccess>(); |
60 | m_volume = m_device.as<Solid::StorageVolume>(); |
61 | m_disc = m_device.as<Solid::OpticalDisc>(); |
62 | m_mtp = m_device.as<Solid::PortableMediaPlayer>(); |
63 | if (m_access) { |
64 | connect(m_access, SIGNAL(accessibilityChanged(bool,QString)), |
65 | this, SLOT(onAccessibilityChanged(bool))); |
66 | onAccessibilityChanged(m_access->isAccessible()); |
67 | } |
68 | m_iconPath = m_device.icon(); |
69 | m_emblems = m_device.emblems(); |
70 | } |
71 | } |
72 | |
73 | KFilePlacesItem::~KFilePlacesItem() |
74 | { |
75 | } |
76 | |
77 | QString KFilePlacesItem::id() const |
78 | { |
79 | if (isDevice()) { |
80 | return bookmark().metaDataItem("UDI" ); |
81 | } else { |
82 | return bookmark().metaDataItem("ID" ); |
83 | } |
84 | } |
85 | |
86 | bool KFilePlacesItem::isDevice() const |
87 | { |
88 | return !bookmark().metaDataItem("UDI" ).isEmpty(); |
89 | } |
90 | |
91 | KBookmark KFilePlacesItem::bookmark() const |
92 | { |
93 | return m_bookmark; |
94 | } |
95 | |
96 | void KFilePlacesItem::setBookmark(const KBookmark &bookmark) |
97 | { |
98 | m_bookmark = bookmark; |
99 | |
100 | if (bookmark.metaDataItem("isSystemItem" ) == "true" ) { |
101 | // This context must stay as it is - the translated system bookmark names |
102 | // are created with 'KFile System Bookmarks' as their context, so this |
103 | // ensures the right string is picked from the catalog. |
104 | // (coles, 13th May 2009) |
105 | |
106 | m_text = i18nc("KFile System Bookmarks" , bookmark.text().toUtf8().data()); |
107 | } else { |
108 | m_text = bookmark.text(); |
109 | } |
110 | } |
111 | |
112 | Solid::Device KFilePlacesItem::device() const |
113 | { |
114 | if (m_device.udi().isEmpty()) { |
115 | m_device = Solid::Device(bookmark().metaDataItem("UDI" )); |
116 | if (m_device.isValid()) { |
117 | m_access = m_device.as<Solid::StorageAccess>(); |
118 | m_volume = m_device.as<Solid::StorageVolume>(); |
119 | m_disc = m_device.as<Solid::OpticalDisc>(); |
120 | m_mtp = m_device.as<Solid::PortableMediaPlayer>(); |
121 | } else { |
122 | m_access = 0; |
123 | m_volume = 0; |
124 | m_disc = 0; |
125 | m_mtp = 0; |
126 | } |
127 | } |
128 | return m_device; |
129 | } |
130 | |
131 | QVariant KFilePlacesItem::data(int role) const |
132 | { |
133 | QVariant returnData; |
134 | |
135 | if (role!=KFilePlacesModel::HiddenRole && role!=Qt::BackgroundRole && isDevice()) { |
136 | returnData = deviceData(role); |
137 | } else { |
138 | returnData = bookmarkData(role); |
139 | } |
140 | |
141 | return returnData; |
142 | } |
143 | |
144 | QVariant KFilePlacesItem::bookmarkData(int role) const |
145 | { |
146 | KBookmark b = bookmark(); |
147 | |
148 | if (b.isNull()) return QVariant(); |
149 | |
150 | switch (role) |
151 | { |
152 | case Qt::DisplayRole: |
153 | return m_text; |
154 | case Qt::DecorationRole: |
155 | return KIcon(iconNameForBookmark(b)); |
156 | case Qt::BackgroundRole: |
157 | if (b.metaDataItem("IsHidden" )=="true" ) { |
158 | return Qt::lightGray; |
159 | } else { |
160 | return QVariant(); |
161 | } |
162 | case KFilePlacesModel::UrlRole: |
163 | return QUrl(b.url()); |
164 | case KFilePlacesModel::SetupNeededRole: |
165 | return false; |
166 | case KFilePlacesModel::HiddenRole: |
167 | return b.metaDataItem("IsHidden" )=="true" ; |
168 | default: |
169 | return QVariant(); |
170 | } |
171 | } |
172 | |
173 | QVariant KFilePlacesItem::deviceData(int role) const |
174 | { |
175 | Solid::Device d = device(); |
176 | |
177 | if (d.isValid()) { |
178 | switch (role) |
179 | { |
180 | case Qt::DisplayRole: |
181 | return d.description(); |
182 | case Qt::DecorationRole: |
183 | return KIcon(m_iconPath, 0, m_emblems); |
184 | case KFilePlacesModel::UrlRole: |
185 | if (m_access) { |
186 | return QUrl(KUrl(m_access->filePath())); |
187 | } else if (m_disc && (m_disc->availableContent() & Solid::OpticalDisc::Audio)!=0) { |
188 | Solid::Block *block = d.as<Solid::Block>(); |
189 | if (block) { |
190 | QString device = block->device(); |
191 | return QUrl(QString("audiocd:/?device=%1" ).arg(device)); |
192 | } |
193 | // We failed to get the block device. Assume audiocd:/ can |
194 | // figure it out, but cannot handle multiple disc drives. |
195 | // See https://bugs.kde.org/show_bug.cgi?id=314544#c40 |
196 | return QUrl(QString("audiocd:/" )); |
197 | } else if (m_mtp) { |
198 | return QUrl(QString("mtp:udi=%1" ).arg(d.udi())); |
199 | } else { |
200 | return QVariant(); |
201 | } |
202 | case KFilePlacesModel::SetupNeededRole: |
203 | if (m_access) { |
204 | return !m_isAccessible; |
205 | } else { |
206 | return QVariant(); |
207 | } |
208 | |
209 | case KFilePlacesModel::FixedDeviceRole: |
210 | { |
211 | Solid::StorageDrive *drive = 0; |
212 | Solid::Device parentDevice = m_device; |
213 | while (parentDevice.isValid() && !drive) { |
214 | drive = parentDevice.as<Solid::StorageDrive>(); |
215 | parentDevice = parentDevice.parent(); |
216 | } |
217 | if (drive!=0) { |
218 | return !drive->isHotpluggable() && !drive->isRemovable(); |
219 | } |
220 | return true; |
221 | } |
222 | |
223 | case KFilePlacesModel::CapacityBarRecommendedRole: |
224 | return m_isAccessible && !m_isCdrom; |
225 | |
226 | default: |
227 | return QVariant(); |
228 | } |
229 | } else { |
230 | return QVariant(); |
231 | } |
232 | } |
233 | |
234 | KBookmark KFilePlacesItem::createBookmark(KBookmarkManager *manager, |
235 | const QString &label, |
236 | const KUrl &url, |
237 | const QString &iconName, |
238 | KFilePlacesItem *after) |
239 | { |
240 | KBookmarkGroup root = manager->root(); |
241 | if (root.isNull()) |
242 | return KBookmark(); |
243 | QString empty_icon = iconName; |
244 | if (url==KUrl("trash:/" )) { |
245 | if (empty_icon.endsWith(QLatin1String("-full" ))) { |
246 | empty_icon.chop(5); |
247 | } else if (empty_icon.isEmpty()) { |
248 | empty_icon = "user-trash" ; |
249 | } |
250 | } |
251 | KBookmark bookmark = root.addBookmark(label, url, empty_icon); |
252 | bookmark.setMetaDataItem("ID" , generateNewId()); |
253 | |
254 | if (after) { |
255 | root.moveBookmark(bookmark, after->bookmark()); |
256 | } |
257 | |
258 | return bookmark; |
259 | } |
260 | |
261 | KBookmark KFilePlacesItem::createSystemBookmark(KBookmarkManager *manager, |
262 | const QString &untranslatedLabel, |
263 | const QString &translatedLabel, |
264 | const KUrl &url, |
265 | const QString &iconName) |
266 | { |
267 | Q_UNUSED(translatedLabel); // parameter is only necessary to force the caller |
268 | // providing a translated string for the label |
269 | |
270 | KBookmark bookmark = createBookmark(manager, untranslatedLabel, url, iconName); |
271 | if (!bookmark.isNull()) |
272 | bookmark.setMetaDataItem("isSystemItem" , "true" ); |
273 | return bookmark; |
274 | } |
275 | |
276 | |
277 | KBookmark KFilePlacesItem::createDeviceBookmark(KBookmarkManager *manager, |
278 | const QString &udi) |
279 | { |
280 | KBookmarkGroup root = manager->root(); |
281 | if (root.isNull()) |
282 | return KBookmark(); |
283 | KBookmark bookmark = root.createNewSeparator(); |
284 | bookmark.setMetaDataItem("UDI" , udi); |
285 | bookmark.setMetaDataItem("isSystemItem" , "true" ); |
286 | return bookmark; |
287 | } |
288 | |
289 | QString KFilePlacesItem::generateNewId() |
290 | { |
291 | static int count = 0; |
292 | |
293 | // return QString::number(count++); |
294 | |
295 | return QString::number(QDateTime::currentDateTime().toTime_t()) |
296 | + '/' + QString::number(count++); |
297 | |
298 | |
299 | // return QString::number(QDateTime::currentDateTime().toTime_t()) |
300 | // + '/' + QString::number(qrand()); |
301 | } |
302 | |
303 | void KFilePlacesItem::onAccessibilityChanged(bool isAccessible) |
304 | { |
305 | m_isAccessible = isAccessible; |
306 | m_isCdrom = m_device.is<Solid::OpticalDrive>() || m_device.parent().is<Solid::OpticalDrive>(); |
307 | m_emblems = m_device.emblems(); |
308 | |
309 | emit itemChanged(id()); |
310 | } |
311 | |
312 | bool KFilePlacesItem::hasFullIcon(const KBookmark &bookmark) const |
313 | { |
314 | return bookmark.url()==KUrl("trash:/" ); |
315 | } |
316 | |
317 | QString KFilePlacesItem::iconNameForBookmark(const KBookmark &bookmark) const |
318 | { |
319 | if (!m_folderIsEmpty && hasFullIcon(bookmark)) { |
320 | return bookmark.icon()+"-full" ; |
321 | } else { |
322 | return bookmark.icon(); |
323 | } |
324 | } |
325 | |
326 | void KFilePlacesItem::onListerCompleted() |
327 | { |
328 | m_folderIsEmpty = m_lister->items().isEmpty(); |
329 | emit itemChanged(id()); |
330 | } |
331 | |
332 | #include "kfileplacesitem_p.moc" |
333 | |