1 /***************************************************************************
2 * Copyright (C) 2012 by Peter Penz <peter.penz19@gmail.com> *
4 * Based on KFilePlacesModel from kdelibs: *
5 * Copyright (C) 2007 Kevin Ottens <ervin@kde.org> *
6 * Copyright (C) 2007 David Faure <faure@kde.org> *
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. *
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. *
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 ***************************************************************************/
24 #include "placesitemmodel.h"
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>
37 #include <KBookmarkGroup>
38 #include <KBookmarkManager>
39 #include <KComponentData>
41 #include <kitemviews/kstandarditem.h>
43 #include <KStandardDirs>
47 PlacesItemModel::PlacesItemModel(QObject
* parent
) :
48 KStandardItemModel(parent
),
49 m_nepomukRunning(false),
53 m_defaultBookmarksIndexes()
56 m_nepomukRunning
= (Nepomuk::ResourceManager::instance()->initialized());
58 const QString file
= KStandardDirs::locateLocal("data", "kfileplaces/bookmarks.xml");
59 m_bookmarkManager
= KBookmarkManager::managerForFile(file
, "kfilePlaces");
61 createDefaultBookmarks();
65 PlacesItemModel::~PlacesItemModel()
69 void PlacesItemModel::loadBookmarks()
71 KBookmarkGroup root
= m_bookmarkManager
->root();
72 KBookmark bookmark
= root
.first();
73 QSet
<QString
> devices
= m_availableDevices
;
75 QSet
<KUrl
> missingDefaultBookmarks
;
76 foreach (const DefaultBookmarkData
& data
, m_defaultBookmarks
) {
77 missingDefaultBookmarks
.insert(data
.url
);
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
);
86 const bool allowedHere
= (appName
.isEmpty() || appName
== KGlobal::mainComponent().componentName())
87 && (m_nepomukRunning
|| url
.protocol() != QLatin1String("timeline"));
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
);
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
);
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
));
106 item
->setText(bookmark
.text());
109 if (deviceAvailable
) {
110 item
->setDataValue("udi", udi
);
111 item
->setGroup(i18nc("@item", "Devices"));
113 item
->setGroup(i18nc("@item", "Places"));
119 bookmark
= root
.next(bookmark
);
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
);
136 void PlacesItemModel::createDefaultBookmarks()
138 Q_ASSERT(m_defaultBookmarks
.isEmpty());
139 Q_ASSERT(m_defaultBookmarksIndexes
.isEmpty());
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
147 m_defaultBookmarks
.append(DefaultBookmarkData(KUrl(KUser().homeDir()),
149 i18nc("@item", "Home"),
151 m_defaultBookmarks
.append(DefaultBookmarkData(KUrl("remote:/"),
153 i18nc("@item", "Network"),
155 m_defaultBookmarks
.append(DefaultBookmarkData(KUrl("/"),
157 i18nc("@item", "Root"),
159 m_defaultBookmarks
.append(DefaultBookmarkData(KUrl("trash:/"),
161 i18nc("@item", "Trash"),
164 if (m_nepomukRunning
) {
165 m_defaultBookmarks
.append(DefaultBookmarkData(KUrl("timeline:/today"),
167 i18nc("@item Recently Accessed", "Today"),
168 recentlyAccessedGroup
));
169 m_defaultBookmarks
.append(DefaultBookmarkData(KUrl("timeline:/yesterday"),
171 i18nc("@item Recently Accessed", "Yesterday"),
172 recentlyAccessedGroup
));
173 m_defaultBookmarks
.append(DefaultBookmarkData(KUrl("timeline:/thismonth"),
175 i18nc("@item Recently Accessed", "This Month"),
176 recentlyAccessedGroup
));
177 m_defaultBookmarks
.append(DefaultBookmarkData(KUrl("timeline:/lastmonth"),
179 i18nc("@item Recently Accessed", "Last Month"),
180 recentlyAccessedGroup
));
181 m_defaultBookmarks
.append(DefaultBookmarkData(KUrl("search:/documents"),
183 i18nc("@item Commonly Accessed", "Documents"),
185 m_defaultBookmarks
.append(DefaultBookmarkData(KUrl("search:/images"),
187 i18nc("@item Commonly Accessed", "Images"),
189 m_defaultBookmarks
.append(DefaultBookmarkData(KUrl("search:/audio"),
191 i18nc("@item Commonly Accessed", "Audio"),
193 m_defaultBookmarks
.append(DefaultBookmarkData(KUrl("search:/videos"),
195 i18nc("@item Commonly Accessed", "Videos"),
199 for (int i
= 0; i
< m_defaultBookmarks
.count(); ++i
) {
200 m_defaultBookmarksIndexes
.insert(m_defaultBookmarks
[i
].url
, i
);
205 KUrl
PlacesItemModel::translatedDefaultBookmarkUrl(const KUrl
& url
) const
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
);
214 return translatedUrl
;
217 KUrl
PlacesItemModel::createTimelineUrl(const KUrl
& url
)
219 // TODO: Clarify with the Nepomuk-team whether it makes sense
220 // provide default-timeline-URLs like 'yesterday', 'this month'
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());
239 Q_ASSERT(path
.endsWith("today"));
246 QString
PlacesItemModel::timelineDateString(int year
, int month
, int day
)
248 QString date
= QString::number(year
) + '-';
252 date
+= QString::number(month
);
259 date
+= QString::number(day
);
265 KUrl
PlacesItemModel::createSearchUrl(const KUrl
& url
)
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")));
292 KUrl
PlacesItemModel::searchUrlForTerm(const Nepomuk::Query::Term
& term
)
294 const Nepomuk::Query::Query
query(term
);
295 return query
.toSearchUrl();
299 #include "placesitemmodel.moc"