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