]> cloud.milkyroute.net Git - dolphin.git/blob - src/panels/places/placesitemmodel.cpp
Places panel: Internal cleanup
[dolphin.git] / src / panels / places / placesitemmodel.cpp
1 /***************************************************************************
2 * Copyright (C) 2012 by Peter Penz <peter.penz19@gmail.com> *
3 * *
4 * Based on KFilePlacesModel from kdelibs: *
5 * Copyright (C) 2007 Kevin Ottens <ervin@kde.org> *
6 * Copyright (C) 2007 David Faure <faure@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 "placesitemmodel.h"
25
26 #ifdef HAVE_NEPOMUK
27 #include <Nepomuk/ResourceManager>
28 #include <Nepomuk/Query/ComparisonTerm>
29 #include <Nepomuk/Query/LiteralTerm>
30 #include <Nepomuk/Query/Query>
31 #include <Nepomuk/Query/ResourceTypeTerm>
32 #include <Nepomuk/Vocabulary/NFO>
33 #include <Nepomuk/Vocabulary/NIE>
34 #endif
35
36 #include <KBookmark>
37 #include <KBookmarkGroup>
38 #include <KBookmarkManager>
39 #include <KComponentData>
40 #include <KIcon>
41 #include <kitemviews/kstandarditem.h>
42 #include <KLocale>
43 #include <KStandardDirs>
44 #include <KUser>
45 #include <QDate>
46
47 PlacesItemModel::PlacesItemModel(QObject* parent) :
48 KStandardItemModel(parent),
49 m_nepomukRunning(false),
50 m_availableDevices(),
51 m_bookmarkManager(0),
52 m_defaultBookmarks(),
53 m_defaultBookmarksIndexes()
54 {
55 #ifdef HAVE_NEPOMUK
56 m_nepomukRunning = (Nepomuk::ResourceManager::instance()->initialized());
57 #endif
58 const QString file = KStandardDirs::locateLocal("data", "kfileplaces/bookmarks.xml");
59 m_bookmarkManager = KBookmarkManager::managerForFile(file, "kfilePlaces");
60
61 createDefaultBookmarks();
62 loadBookmarks();
63 }
64
65 PlacesItemModel::~PlacesItemModel()
66 {
67 }
68
69 void PlacesItemModel::loadBookmarks()
70 {
71 KBookmarkGroup root = m_bookmarkManager->root();
72 KBookmark bookmark = root.first();
73 QSet<QString> devices = m_availableDevices;
74
75 QSet<KUrl> missingDefaultBookmarks;
76 foreach (const DefaultBookmarkData& data, m_defaultBookmarks) {
77 missingDefaultBookmarks.insert(data.url);
78 }
79
80 while (!bookmark.isNull()) {
81 const QString udi = bookmark.metaDataItem("UDI");
82 const KUrl url = bookmark.url();
83 const QString appName = bookmark.metaDataItem("OnlyInApp");
84 const bool deviceAvailable = devices.remove(udi);
85
86 const bool allowedHere = (appName.isEmpty() || appName == KGlobal::mainComponent().componentName())
87 && (m_nepomukRunning || url.protocol() != QLatin1String("timeline"));
88
89 if ((udi.isEmpty() && allowedHere) || deviceAvailable) {
90 KStandardItem* item = new KStandardItem();
91 item->setIcon(KIcon(bookmark.icon()));
92 item->setDataValue("address", bookmark.address());
93 item->setDataValue("url", url);
94
95 if (missingDefaultBookmarks.contains(url)) {
96 missingDefaultBookmarks.remove(url);
97 // Apply the translated text to the default bookmarks, otherwise an outdated
98 // translation might be shown.
99 const int index = m_defaultBookmarksIndexes.value(url);
100 item->setText(m_defaultBookmarks[index].text);
101
102 // The default bookmarks don't contain "real" queries stored as URLs, so
103 // they must be translated first.
104 item->setDataValue("url", translatedDefaultBookmarkUrl(url));
105 } else {
106 item->setText(bookmark.text());
107 }
108
109 if (deviceAvailable) {
110 item->setDataValue("udi", udi);
111 item->setGroup(i18nc("@item", "Devices"));
112 } else {
113 item->setGroup(i18nc("@item", "Places"));
114 }
115
116 appendItem(item);
117 }
118
119 bookmark = root.next(bookmark);
120 }
121
122 if (!missingDefaultBookmarks.isEmpty()) {
123 foreach (const DefaultBookmarkData& data, m_defaultBookmarks) {
124 if (missingDefaultBookmarks.contains(data.url)) {
125 KStandardItem* item = new KStandardItem();
126 item->setIcon(KIcon(data.icon));
127 item->setText(data.text);
128 item->setDataValue("url", translatedDefaultBookmarkUrl(data.url));
129 item->setGroup(data.group);
130 appendItem(item);
131 }
132 }
133 }
134 }
135
136 void PlacesItemModel::createDefaultBookmarks()
137 {
138 Q_ASSERT(m_defaultBookmarks.isEmpty());
139 Q_ASSERT(m_defaultBookmarksIndexes.isEmpty());
140
141 const QString placesGroup = i18nc("@item", "Places");
142 const QString recentlyAccessedGroup = i18nc("@item", "Recently Accessed");
143 const QString searchForGroup = i18nc("@item", "Search For");
144 const QString timeLineIcon = "package_utility_time"; // TODO: Ask the Oxygen team to create
145 // a custom icon for the timeline-protocol
146
147 m_defaultBookmarks.append(DefaultBookmarkData(KUrl(KUser().homeDir()),
148 "user-home",
149 i18nc("@item", "Home"),
150 placesGroup));
151 m_defaultBookmarks.append(DefaultBookmarkData(KUrl("remote:/"),
152 "network-workgroup",
153 i18nc("@item", "Network"),
154 placesGroup));
155 m_defaultBookmarks.append(DefaultBookmarkData(KUrl("/"),
156 "folder-red",
157 i18nc("@item", "Root"),
158 placesGroup));
159 m_defaultBookmarks.append(DefaultBookmarkData(KUrl("trash:/"),
160 "user-trash",
161 i18nc("@item", "Trash"),
162 placesGroup));
163
164 if (m_nepomukRunning) {
165 m_defaultBookmarks.append(DefaultBookmarkData(KUrl("timeline:/today"),
166 timeLineIcon,
167 i18nc("@item Recently Accessed", "Today"),
168 recentlyAccessedGroup));
169 m_defaultBookmarks.append(DefaultBookmarkData(KUrl("timeline:/yesterday"),
170 timeLineIcon,
171 i18nc("@item Recently Accessed", "Yesterday"),
172 recentlyAccessedGroup));
173 m_defaultBookmarks.append(DefaultBookmarkData(KUrl("timeline:/thismonth"),
174 timeLineIcon,
175 i18nc("@item Recently Accessed", "This Month"),
176 recentlyAccessedGroup));
177 m_defaultBookmarks.append(DefaultBookmarkData(KUrl("timeline:/lastmonth"),
178 timeLineIcon,
179 i18nc("@item Recently Accessed", "Last Month"),
180 recentlyAccessedGroup));
181 m_defaultBookmarks.append(DefaultBookmarkData(KUrl("search:/documents"),
182 "folder-txt",
183 i18nc("@item Commonly Accessed", "Documents"),
184 searchForGroup));
185 m_defaultBookmarks.append(DefaultBookmarkData(KUrl("search:/images"),
186 "folder-image",
187 i18nc("@item Commonly Accessed", "Images"),
188 searchForGroup));
189 m_defaultBookmarks.append(DefaultBookmarkData(KUrl("search:/audio"),
190 "folder-sound",
191 i18nc("@item Commonly Accessed", "Audio"),
192 searchForGroup));
193 m_defaultBookmarks.append(DefaultBookmarkData(KUrl("search:/videos"),
194 "folder-video",
195 i18nc("@item Commonly Accessed", "Videos"),
196 searchForGroup));
197 }
198
199 for (int i = 0; i < m_defaultBookmarks.count(); ++i) {
200 m_defaultBookmarksIndexes.insert(m_defaultBookmarks[i].url, i);
201 }
202 }
203
204
205 KUrl PlacesItemModel::translatedDefaultBookmarkUrl(const KUrl& url) const
206 {
207 KUrl translatedUrl = url;
208 if (url.protocol() == QLatin1String("timeline")) {
209 translatedUrl = createTimelineUrl(url);
210 } else if (url.protocol() == QLatin1String("search")) {
211 translatedUrl = createSearchUrl(url);
212 }
213
214 return translatedUrl;
215 }
216
217 KUrl PlacesItemModel::createTimelineUrl(const KUrl& url)
218 {
219 // TODO: Clarify with the Nepomuk-team whether it makes sense
220 // provide default-timeline-URLs like 'yesterday', 'this month'
221 // and 'last month'.
222 KUrl timelineUrl;
223
224 const QString path = url.pathOrUrl();
225 if (path.endsWith("yesterday")) {
226 const QDate date = QDate::currentDate().addDays(-1);
227 const int year = date.year();
228 const int month = date.month();
229 const int day = date.day();
230 timelineUrl = "timeline:/" + timelineDateString(year, month) +
231 '/' + timelineDateString(year, month, day);
232 } else if (path.endsWith("thismonth")) {
233 const QDate date = QDate::currentDate();
234 timelineUrl = "timeline:/" + timelineDateString(date.year(), date.month());
235 } else if (path.endsWith("lastmonth")) {
236 const QDate date = QDate::currentDate().addMonths(-1);
237 timelineUrl = "timeline:/" + timelineDateString(date.year(), date.month());
238 } else {
239 Q_ASSERT(path.endsWith("today"));
240 timelineUrl= url;
241 }
242
243 return timelineUrl;
244 }
245
246 QString PlacesItemModel::timelineDateString(int year, int month, int day)
247 {
248 QString date = QString::number(year) + '-';
249 if (month < 10) {
250 date += '0';
251 }
252 date += QString::number(month);
253
254 if (day >= 1) {
255 date += '-';
256 if (day < 10) {
257 date += '0';
258 }
259 date += QString::number(day);
260 }
261
262 return date;
263 }
264
265 KUrl PlacesItemModel::createSearchUrl(const KUrl& url)
266 {
267 KUrl searchUrl;
268
269 #ifdef HAVE_NEPOMUK
270 const QString path = url.pathOrUrl();
271 if (path.endsWith("documents")) {
272 searchUrl = searchUrlForTerm(Nepomuk::Query::ResourceTypeTerm(Nepomuk::Vocabulary::NFO::Document()));
273 } else if (path.endsWith("images")) {
274 searchUrl = searchUrlForTerm(Nepomuk::Query::ResourceTypeTerm(Nepomuk::Vocabulary::NFO::Image()));
275 } else if (path.endsWith("audio")) {
276 searchUrl = searchUrlForTerm(Nepomuk::Query::ComparisonTerm(Nepomuk::Vocabulary::NIE::mimeType(),
277 Nepomuk::Query::LiteralTerm("audio")));
278 } else if (path.endsWith("videos")) {
279 searchUrl = searchUrlForTerm(Nepomuk::Query::ComparisonTerm(Nepomuk::Vocabulary::NIE::mimeType(),
280 Nepomuk::Query::LiteralTerm("video")));
281 } else {
282 Q_ASSERT(false);
283 }
284 #else
285 Q_UNUSED(url);
286 #endif
287
288 return searchUrl;
289 }
290
291 #ifdef HAVE_NEPOMUK
292 KUrl PlacesItemModel::searchUrlForTerm(const Nepomuk::Query::Term& term)
293 {
294 const Nepomuk::Query::Query query(term);
295 return query.toSearchUrl();
296 }
297 #endif
298
299 #include "placesitemmodel.moc"