]> cloud.milkyroute.net Git - dolphin.git/blob - src/panels/places/placesitem.cpp
Expand DolphinQuery to support different Url schemes
[dolphin.git] / src / panels / places / placesitem.cpp
1 /***************************************************************************
2 * Copyright (C) 2012 by Peter Penz <peter.penz19@gmail.com> *
3 * Copyright (C) 2018 by Elvis Angelaccio <elvis.angelaccio@kde.org> *
4 * *
5 * Based on KFilePlacesItem from kdelibs: *
6 * Copyright (C) 2007 Kevin Ottens <ervin@kde.org> *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
22 ***************************************************************************/
23
24 #include "placesitem.h"
25 #include "trash/dolphintrash.h"
26
27 #include "dolphindebug.h"
28 #include "placesitemsignalhandler.h"
29
30 #include <KDirLister>
31 #include <KLocalizedString>
32 #include <Solid/Block>
33
34 PlacesItem::PlacesItem(const KBookmark& bookmark, PlacesItem* parent) :
35 KStandardItem(parent),
36 m_device(),
37 m_access(),
38 m_volume(),
39 m_disc(),
40 m_mtp(),
41 m_signalHandler(nullptr),
42 m_bookmark()
43 {
44 m_signalHandler = new PlacesItemSignalHandler(this);
45 setBookmark(bookmark);
46 }
47
48 PlacesItem::~PlacesItem()
49 {
50 delete m_signalHandler;
51 }
52
53 void PlacesItem::setUrl(const QUrl &url)
54 {
55 // The default check in KStandardItem::setDataValue()
56 // for equal values does not work with a custom value
57 // like QUrl. Hence do a manual check to prevent that
58 // setting an equal URL results in an itemsChanged()
59 // signal.
60 if (dataValue("url").toUrl() != url) {
61 if (url.scheme() == QLatin1String("trash")) {
62 QObject::connect(&Trash::instance(), &Trash::emptinessChanged, m_signalHandler.data(), &PlacesItemSignalHandler::onTrashEmptinessChanged);
63 }
64
65 setDataValue("url", url);
66 }
67 }
68
69 QUrl PlacesItem::url() const
70 {
71 return dataValue("url").toUrl();
72 }
73
74 void PlacesItem::setUdi(const QString& udi)
75 {
76 setDataValue("udi", udi);
77 }
78
79 QString PlacesItem::udi() const
80 {
81 return dataValue("udi").toString();
82 }
83
84 void PlacesItem::setApplicationName(const QString &applicationName)
85 {
86 setDataValue("applicationName", applicationName);
87 }
88
89 QString PlacesItem::applicationName() const
90 {
91 return dataValue("applicationName").toString();
92 }
93
94 void PlacesItem::setHidden(bool hidden)
95 {
96 setDataValue("isHidden", hidden);
97 }
98
99 bool PlacesItem::isHidden() const
100 {
101 return dataValue("isHidden").toBool();
102 }
103
104 bool PlacesItem::isGroupHidden() const
105 {
106 return dataValue("isGroupHidden").toBool();
107 }
108
109 void PlacesItem::setGroupHidden(bool hidden)
110 {
111 setDataValue("isGroupHidden", hidden);
112 }
113
114 void PlacesItem::setSystemItem(bool isSystemItem)
115 {
116 setDataValue("isSystemItem", isSystemItem);
117 }
118
119 bool PlacesItem::isSystemItem() const
120 {
121 return dataValue("isSystemItem").toBool();
122 }
123
124 Solid::Device PlacesItem::device() const
125 {
126 return m_device;
127 }
128
129 void PlacesItem::setBookmark(const KBookmark& bookmark)
130 {
131 const bool bookmarkDataChanged = !(bookmark == m_bookmark);
132
133 // bookmark object must be updated to keep in sync with source model
134 m_bookmark = bookmark;
135
136 if (!bookmarkDataChanged) {
137 return;
138 }
139
140 delete m_access;
141 delete m_volume;
142 delete m_disc;
143 delete m_mtp;
144
145 const QString udi = bookmark.metaDataItem(QStringLiteral("UDI"));
146 if (udi.isEmpty()) {
147 setIcon(bookmark.icon());
148 setText(i18ndc("kio5", "KFile System Bookmarks", bookmark.text().toUtf8().constData()));
149 setUrl(bookmark.url());
150 setSystemItem(bookmark.metaDataItem(QStringLiteral("isSystemItem")) == QLatin1String("true"));
151 } else {
152 initializeDevice(udi);
153 }
154
155 setHidden(bookmark.metaDataItem(QStringLiteral("IsHidden")) == QLatin1String("true"));
156 }
157
158 KBookmark PlacesItem::bookmark() const
159 {
160 return m_bookmark;
161 }
162
163 bool PlacesItem::storageSetupNeeded() const
164 {
165 return m_access ? !m_access->isAccessible() : false;
166 }
167
168 bool PlacesItem::isSearchOrTimelineUrl() const
169 {
170 const QString urlScheme = url().scheme();
171 return (urlScheme.contains("search") || urlScheme.contains("timeline"));
172 }
173
174 void PlacesItem::onDataValueChanged(const QByteArray& role,
175 const QVariant& current,
176 const QVariant& previous)
177 {
178 Q_UNUSED(current)
179 Q_UNUSED(previous)
180
181 if (!m_bookmark.isNull()) {
182 updateBookmarkForRole(role);
183 }
184 }
185
186 void PlacesItem::onDataChanged(const QHash<QByteArray, QVariant>& current,
187 const QHash<QByteArray, QVariant>& previous)
188 {
189 Q_UNUSED(previous)
190
191 if (!m_bookmark.isNull()) {
192 QHashIterator<QByteArray, QVariant> it(current);
193 while (it.hasNext()) {
194 it.next();
195 updateBookmarkForRole(it.key());
196 }
197 }
198 }
199
200 void PlacesItem::initializeDevice(const QString& udi)
201 {
202 m_device = Solid::Device(udi);
203 if (!m_device.isValid()) {
204 return;
205 }
206
207 m_access = m_device.as<Solid::StorageAccess>();
208 m_volume = m_device.as<Solid::StorageVolume>();
209 m_disc = m_device.as<Solid::OpticalDisc>();
210 m_mtp = m_device.as<Solid::PortableMediaPlayer>();
211
212 setText(m_device.displayName());
213 setIcon(m_device.icon());
214 setIconOverlays(m_device.emblems());
215 setUdi(udi);
216
217 if (m_access) {
218 setUrl(QUrl::fromLocalFile(m_access->filePath()));
219 QObject::connect(m_access.data(), &Solid::StorageAccess::accessibilityChanged,
220 m_signalHandler.data(), &PlacesItemSignalHandler::onAccessibilityChanged);
221 QObject::connect(m_access.data(), &Solid::StorageAccess::teardownRequested,
222 m_signalHandler.data(), &PlacesItemSignalHandler::onTearDownRequested);
223 } else if (m_disc && (m_disc->availableContent() & Solid::OpticalDisc::Audio) != 0) {
224 Solid::Block *block = m_device.as<Solid::Block>();
225 if (block) {
226 const QString device = block->device();
227 setUrl(QUrl(QStringLiteral("audiocd:/?device=%1").arg(device)));
228 } else {
229 setUrl(QUrl(QStringLiteral("audiocd:/")));
230 }
231 } else if (m_mtp) {
232 setUrl(QUrl(QStringLiteral("mtp:udi=%1").arg(m_device.udi())));
233 }
234 }
235
236 void PlacesItem::onAccessibilityChanged()
237 {
238 setIconOverlays(m_device.emblems());
239 setUrl(QUrl::fromLocalFile(m_access->filePath()));
240 }
241
242 void PlacesItem::updateBookmarkForRole(const QByteArray& role)
243 {
244 Q_ASSERT(!m_bookmark.isNull());
245 if (role == "iconName") {
246 m_bookmark.setIcon(icon());
247 } else if (role == "text") {
248 // Only store the text in the KBookmark if it is not the translation of
249 // the current text. This makes sure that the text is re-translated if
250 // the user chooses another language, or the translation itself changes.
251 //
252 // NOTE: It is important to use "KFile System Bookmarks" as context
253 // (see PlacesItemModel::createSystemBookmarks()).
254 if (text() != i18ndc("kio5", "KFile System Bookmarks", m_bookmark.text().toUtf8().data())) {
255 m_bookmark.setFullText(text());
256 }
257 } else if (role == "url") {
258 m_bookmark.setUrl(url());
259 } else if (role == "udi") {
260 m_bookmark.setMetaDataItem(QStringLiteral("UDI"), udi());
261 } else if (role == "applicationName") {
262 m_bookmark.setMetaDataItem(QStringLiteral("OnlyInApp"), applicationName());
263 } else if (role == "isSystemItem") {
264 m_bookmark.setMetaDataItem(QStringLiteral("isSystemItem"), isSystemItem() ? QStringLiteral("true") : QStringLiteral("false"));
265 } else if (role == "isHidden") {
266 m_bookmark.setMetaDataItem(QStringLiteral("IsHidden"), isHidden() ? QStringLiteral("true") : QStringLiteral("false"));
267 }
268 }
269
270 QString PlacesItem::generateNewId()
271 {
272 // The ID-generation must be different as done in KFilePlacesItem from kdelibs
273 // to prevent identical IDs, because 'count' is of course not shared. We append a
274 // " (V2)" to indicate that the ID has been generated by
275 // a new version of the places view.
276 static int count = 0;
277 return QString::number(QDateTime::currentDateTimeUtc().toTime_t()) +
278 '/' + QString::number(count++) + " (V2)";
279 }
280
281 PlacesItemSignalHandler *PlacesItem::signalHandler() const
282 {
283 return m_signalHandler.data();
284 }