┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
path: root/src/panels
diff options
context:
space:
mode:
Diffstat (limited to 'src/panels')
-rw-r--r--src/panels/places/placesitemlistgroupheader.cpp40
-rw-r--r--src/panels/places/placesitemlistgroupheader.h38
-rw-r--r--src/panels/places/placespanel.cpp257
-rw-r--r--src/panels/places/placespanel.h66
4 files changed, 390 insertions, 11 deletions
diff --git a/src/panels/places/placesitemlistgroupheader.cpp b/src/panels/places/placesitemlistgroupheader.cpp
new file mode 100644
index 000000000..27d4c7917
--- /dev/null
+++ b/src/panels/places/placesitemlistgroupheader.cpp
@@ -0,0 +1,40 @@
+/***************************************************************************
+ * Copyright (C) 2012 by Peter Penz <[email protected]> *
+ * *
+ * Based on the Itemviews NG project from Trolltech Labs: *
+ * http://qt.gitorious.org/qt-labs/itemviews-ng *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#include "placesitemlistgroupheader.h"
+
+PlacesItemListGroupHeader::PlacesItemListGroupHeader(QGraphicsWidget* parent) :
+ KStandardItemListGroupHeader(parent)
+{
+}
+
+PlacesItemListGroupHeader::~PlacesItemListGroupHeader()
+{
+}
+
+void PlacesItemListGroupHeader::paintSeparator(QPainter* painter, const QColor& color)
+{
+ Q_UNUSED(painter);
+ Q_UNUSED(color);
+}
+
+#include "placesitemlistgroupheader.moc"
diff --git a/src/panels/places/placesitemlistgroupheader.h b/src/panels/places/placesitemlistgroupheader.h
new file mode 100644
index 000000000..fbcd116f1
--- /dev/null
+++ b/src/panels/places/placesitemlistgroupheader.h
@@ -0,0 +1,38 @@
+/***************************************************************************
+ * Copyright (C) 2012 by Peter Penz <[email protected]> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef PLACESITEMLISTGROUPHEADER_H
+#define PLACESITEMLISTGROUPHEADER_H
+
+#include <kitemviews/kstandarditemlistgroupheader.h>
+
+class PlacesItemListGroupHeader : public KStandardItemListGroupHeader
+{
+ Q_OBJECT
+
+public:
+ PlacesItemListGroupHeader(QGraphicsWidget* parent = 0);
+ virtual ~PlacesItemListGroupHeader();
+
+protected:
+ virtual void paintSeparator(QPainter* painter, const QColor& color);
+};
+#endif
+
+
diff --git a/src/panels/places/placespanel.cpp b/src/panels/places/placespanel.cpp
index 5ea4b971c..d13eb0812 100644
--- a/src/panels/places/placespanel.cpp
+++ b/src/panels/places/placespanel.cpp
@@ -23,28 +23,45 @@
#include "placespanel.h"
+#ifdef HAVE_NEPOMUK
+ #include <Nepomuk/ResourceManager>
+ #include <Nepomuk/Query/ComparisonTerm>
+ #include <Nepomuk/Query/LiteralTerm>
+ #include <Nepomuk/Query/Query>
+ #include <Nepomuk/Query/ResourceTypeTerm>
+ #include <Nepomuk/Vocabulary/NFO>
+ #include <Nepomuk/Vocabulary/NIE>
+#endif
+
#include <KBookmark>
#include <KBookmarkGroup>
#include <KBookmarkManager>
#include <KComponentData>
#include <KDebug>
#include <KIcon>
+#include <KLocale>
#include <kitemviews/kitemlistcontainer.h>
#include <kitemviews/kitemlistcontroller.h>
#include <kitemviews/kstandarditem.h>
#include <kitemviews/kstandarditemlistview.h>
#include <kitemviews/kstandarditemmodel.h>
#include <KStandardDirs>
+#include <KUser>
+#include "placesitemlistgroupheader.h"
#include <views/draganddrophelper.h>
+#include <QDir>
#include <QVBoxLayout>
#include <QShowEvent>
PlacesPanel::PlacesPanel(QWidget* parent) :
Panel(parent),
+ m_nepomukRunning(false),
m_controller(0),
m_model(0),
m_availableDevices(),
- m_bookmarkManager(0)
+ m_bookmarkManager(0),
+ m_defaultBookmarks(),
+ m_defaultBookmarksIndexes()
{
}
@@ -68,17 +85,27 @@ void PlacesPanel::showEvent(QShowEvent* event)
// Postpone the creating of the controller to the first show event.
// This assures that no performance and memory overhead is given when the folders panel is not
// used at all and stays invisible.
+#ifdef HAVE_NEPOMUK
+ m_nepomukRunning = (Nepomuk::ResourceManager::instance()->initialized());
+#endif
+ createDefaultBookmarks();
+
const QString file = KStandardDirs::locateLocal("data", "kfileplaces/bookmarks.xml");
- m_bookmarkManager = KBookmarkManager::managerForFile(file, "kfileplaces");
+ m_bookmarkManager = KBookmarkManager::managerForFile(file, "kfilePlaces");
m_model = new KStandardItemModel(this);
+ m_model->setGroupedSorting(true);
+ m_model->setSortRole("group");
loadBookmarks();
KStandardItemListView* view = new KStandardItemListView();
+ view->setGroupHeaderCreator(new KItemListGroupHeaderCreator<PlacesItemListGroupHeader>());
m_controller = new KItemListController(m_model, view, this);
m_controller->setSelectionBehavior(KItemListController::SingleSelection);
connect(m_controller, SIGNAL(itemActivated(int)), this, SLOT(slotItemActivated(int)));
connect(m_controller, SIGNAL(itemMiddleClicked(int)), this, SLOT(slotItemMiddleClicked(int)));
+ connect(m_controller, SIGNAL(itemContextMenuRequested(int,QPointF)), this, SLOT(slotItemContextMenuRequested(int,QPointF)));
+ connect(m_controller, SIGNAL(viewContextMenuRequested(QPointF)), this, SLOT(slotViewContextMenuRequested(QPointF)));
KItemListContainer* container = new KItemListContainer(m_controller, this);
container->setEnabledFrame(false);
@@ -93,55 +120,263 @@ void PlacesPanel::showEvent(QShowEvent* event)
void PlacesPanel::slotItemActivated(int index)
{
- const KStandardItem* item = m_model->item(index);
- if (item) {
- const KUrl url = item->dataValue("url").value<KUrl>();
+ const KUrl url = urlForIndex(index);
+ if (!url.isEmpty()) {
emit placeActivated(url);
}
}
void PlacesPanel::slotItemMiddleClicked(int index)
{
- const KStandardItem* item = m_model->item(index);
- if (item) {
- const KUrl url = item->dataValue("url").value<KUrl>();
+ const KUrl url = urlForIndex(index);
+ if (!url.isEmpty()) {
emit placeMiddleClicked(url);
}
}
+void PlacesPanel::slotItemContextMenuRequested(int index, const QPointF& pos)
+{
+ Q_UNUSED(index);
+ Q_UNUSED(pos);
+}
+
+void PlacesPanel::slotViewContextMenuRequested(const QPointF& pos)
+{
+ Q_UNUSED(pos);
+}
+
void PlacesPanel::slotUrlsDropped(const KUrl& dest, QDropEvent* event, QWidget* parent)
{
Q_UNUSED(parent);
DragAndDropHelper::dropUrls(KFileItem(), dest, event);
}
+void PlacesPanel::createDefaultBookmarks()
+{
+ Q_ASSERT(m_defaultBookmarks.isEmpty());
+ Q_ASSERT(m_defaultBookmarksIndexes.isEmpty());
+
+ const QString placesGroup = i18nc("@item", "Places");
+ const QString recentlyAccessedGroup = i18nc("@item", "Recently Accessed");
+ const QString searchForGroup = i18nc("@item", "Search For");
+ const QString timeLineIcon = "package_utility_time"; // TODO: Ask the Oxygen team to create
+ // a custom icon for the timeline-protocol
+
+ m_defaultBookmarks.append(DefaultBookmarkData(KUrl(KUser().homeDir()),
+ "user-home",
+ i18nc("@item", "Home"),
+ placesGroup));
+ m_defaultBookmarks.append(DefaultBookmarkData(KUrl("remote:/"),
+ "network-workgroup",
+ i18nc("@item", "Network"),
+ placesGroup));
+ m_defaultBookmarks.append(DefaultBookmarkData(KUrl("/"),
+ "folder-red",
+ i18nc("@item", "Root"),
+ placesGroup));
+ m_defaultBookmarks.append(DefaultBookmarkData(KUrl("trash:/"),
+ "user-trash",
+ i18nc("@item", "Trash"),
+ placesGroup));
+
+ if (m_nepomukRunning) {
+ m_defaultBookmarks.append(DefaultBookmarkData(KUrl("timeline:/today"),
+ timeLineIcon,
+ i18nc("@item Recently Accessed", "Today"),
+ recentlyAccessedGroup));
+ m_defaultBookmarks.append(DefaultBookmarkData(KUrl("timeline:/yesterday"),
+ timeLineIcon,
+ i18nc("@item Recently Accessed", "Yesterday"),
+ recentlyAccessedGroup));
+ m_defaultBookmarks.append(DefaultBookmarkData(KUrl("timeline:/thismonth"),
+ timeLineIcon,
+ i18nc("@item Recently Accessed", "This Month"),
+ recentlyAccessedGroup));
+ m_defaultBookmarks.append(DefaultBookmarkData(KUrl("timeline:/lastmonth"),
+ timeLineIcon,
+ i18nc("@item Recently Accessed", "Last Month"),
+ recentlyAccessedGroup));
+ m_defaultBookmarks.append(DefaultBookmarkData(KUrl("search:/documents"),
+ "folder-txt",
+ i18nc("@item Commonly Accessed", "Documents"),
+ searchForGroup));
+ m_defaultBookmarks.append(DefaultBookmarkData(KUrl("search:/images"),
+ "folder-image",
+ i18nc("@item Commonly Accessed", "Images"),
+ searchForGroup));
+ m_defaultBookmarks.append(DefaultBookmarkData(KUrl("search:/music"),
+ "folder-sound",
+ i18nc("@item Commonly Accessed", "Music"),
+ searchForGroup));
+ m_defaultBookmarks.append(DefaultBookmarkData(KUrl("search:/videos"),
+ "folder-video",
+ i18nc("@item Commonly Accessed", "Videos"),
+ searchForGroup));
+ }
+
+ for (int i = 0; i < m_defaultBookmarks.count(); ++i) {
+ m_defaultBookmarksIndexes.insert(m_defaultBookmarks[i].url, i);
+ }
+}
+
void PlacesPanel::loadBookmarks()
{
KBookmarkGroup root = m_bookmarkManager->root();
KBookmark bookmark = root.first();
QSet<QString> devices = m_availableDevices;
+ QSet<KUrl> missingDefaultBookmarks;
+ foreach (const DefaultBookmarkData& data, m_defaultBookmarks) {
+ missingDefaultBookmarks.insert(data.url);
+ }
+
while (!bookmark.isNull()) {
const QString udi = bookmark.metaDataItem("UDI");
+ const KUrl url = bookmark.url();
const QString appName = bookmark.metaDataItem("OnlyInApp");
const bool deviceAvailable = devices.remove(udi);
- const bool allowedHere = appName.isEmpty() || (appName == KGlobal::mainComponent().componentName());
+ const bool allowedHere = (appName.isEmpty() || appName == KGlobal::mainComponent().componentName())
+ && (m_nepomukRunning || url.protocol() != QLatin1String("timeline"));
if ((udi.isEmpty() && allowedHere) || deviceAvailable) {
KStandardItem* item = new KStandardItem();
item->setIcon(KIcon(bookmark.icon()));
- item->setText(bookmark.text());
item->setDataValue("address", bookmark.address());
- item->setDataValue("url", bookmark.url());
+ item->setDataValue("url", url);
+
+ if (missingDefaultBookmarks.contains(url)) {
+ missingDefaultBookmarks.remove(url);
+ // Always apply the translated text to the default bookmarks, otherwise an outdated
+ // translation might be shown.
+ const int index = m_defaultBookmarksIndexes.value(url);
+ item->setText(m_defaultBookmarks[index].text);
+ } else {
+ item->setText(bookmark.text());
+ }
+
if (deviceAvailable) {
item->setDataValue("udi", udi);
+ item->setGroup(i18nc("@item", "Devices"));
+ } else {
+ item->setGroup(i18nc("@item", "Places"));
}
+
m_model->appendItem(item);
}
bookmark = root.next(bookmark);
}
+
+ if (!missingDefaultBookmarks.isEmpty()) {
+ foreach (const DefaultBookmarkData& data, m_defaultBookmarks) {
+ if (missingDefaultBookmarks.contains(data.url)) {
+ KStandardItem* item = new KStandardItem();
+ item->setIcon(KIcon(data.icon));
+ item->setText(data.text);
+ item->setDataValue("url", data.url);
+ item->setGroup(data.group);
+ m_model->appendItem(item);
+ }
+ }
+ }
+}
+
+KUrl PlacesPanel::urlForIndex(int index) const
+{
+ const KStandardItem* item = m_model->item(index);
+ if (!item) {
+ return KUrl();
+ }
+
+ KUrl url = item->dataValue("url").value<KUrl>();
+ if (url.protocol() == QLatin1String("timeline")) {
+ url = createTimelineUrl(url);
+ } else if (url.protocol() == QLatin1String("search")) {
+ url = createSearchUrl(url);
+ }
+
+ return url;
+}
+
+KUrl PlacesPanel::createTimelineUrl(const KUrl& url)
+{
+ // TODO: Clarify with the Nepomuk-team whether it makes sense
+ // provide default-timeline-URLs like 'yesterday', 'this month'
+ // and 'last month'.
+ KUrl timelineUrl;
+
+ const QString path = url.pathOrUrl();
+ if (path.endsWith("yesterday")) {
+ const QDate date = QDate::currentDate().addDays(-1);
+ const int year = date.year();
+ const int month = date.month();
+ const int day = date.day();
+ timelineUrl = "timeline:/" + timelineDateString(year, month) +
+ '/' + timelineDateString(year, month, day);
+ } else if (path.endsWith("thismonth")) {
+ const QDate date = QDate::currentDate();
+ timelineUrl = "timeline:/" + timelineDateString(date.year(), date.month());
+ } else if (path.endsWith("lastmonth")) {
+ const QDate date = QDate::currentDate().addMonths(-1);
+ timelineUrl = "timeline:/" + timelineDateString(date.year(), date.month());
+ } else {
+ Q_ASSERT(path.endsWith("today"));
+ timelineUrl= url;
+ }
+
+ return timelineUrl;
+}
+
+QString PlacesPanel::timelineDateString(int year, int month, int day)
+{
+ QString date = QString::number(year) + '-';
+ if (month < 10) {
+ date += '0';
+ }
+ date += QString::number(month);
+
+ if (day >= 1) {
+ date += '-';
+ if (day < 10) {
+ date += '0';
+ }
+ date += QString::number(day);
+ }
+
+ return date;
+}
+
+KUrl PlacesPanel::createSearchUrl(const KUrl& url)
+{
+ KUrl searchUrl;
+
+#ifdef HAVE_NEPOMUK
+ const QString path = url.pathOrUrl();
+ if (path.endsWith("documents")) {
+ searchUrl = searchUrlForTerm(Nepomuk::Query::ResourceTypeTerm(Nepomuk::Vocabulary::NFO::Document()));
+ } else if (path.endsWith("images")) {
+ searchUrl = searchUrlForTerm(Nepomuk::Query::ResourceTypeTerm(Nepomuk::Vocabulary::NFO::Image()));
+ } else if (path.endsWith("music")) {
+ searchUrl = searchUrlForTerm(Nepomuk::Query::ComparisonTerm(Nepomuk::Vocabulary::NIE::mimeType(),
+ Nepomuk::Query::LiteralTerm("audio")));
+ } else if (path.endsWith("videos")) {
+ searchUrl = searchUrlForTerm(Nepomuk::Query::ComparisonTerm(Nepomuk::Vocabulary::NIE::mimeType(),
+ Nepomuk::Query::LiteralTerm("video")));
+ } else {
+ Q_ASSERT(false);
+ }
+#endif
+
+ return searchUrl;
+}
+
+#ifdef HAVE_NEPOMUK
+KUrl PlacesPanel::searchUrlForTerm(const Nepomuk::Query::Term& term)
+{
+ const Nepomuk::Query::Query query(term);
+ return query.toSearchUrl();
}
+#endif
#include "placespanel.moc"
diff --git a/src/panels/places/placespanel.h b/src/panels/places/placespanel.h
index 80cb732f0..ea05601e0 100644
--- a/src/panels/places/placespanel.h
+++ b/src/panels/places/placespanel.h
@@ -21,13 +21,28 @@
#ifndef PLACESPANEL_H
#define PLACESPANEL_H
+#include <config-nepomuk.h>
+
+#include <KUrl>
#include <panels/panel.h>
+#include <QHash>
+#include <QList>
#include <QSet>
class KBookmarkManager;
class KItemListController;
class KStandardItemModel;
+#ifdef HAVE_NEPOMUK
+namespace Nepomuk
+{
+ namespace Query
+ {
+ class Term;
+ }
+}
+#endif
+
/**
* @brief Combines bookmarks and mounted devices as list.
*/
@@ -50,16 +65,67 @@ protected:
private slots:
void slotItemActivated(int index);
void slotItemMiddleClicked(int index);
+ void slotItemContextMenuRequested(int index, const QPointF& pos);
+ void slotViewContextMenuRequested(const QPointF& pos);
void slotUrlsDropped(const KUrl& dest, QDropEvent* event, QWidget* parent);
private:
+ void createDefaultBookmarks();
void loadBookmarks();
+ KUrl urlForIndex(int index) const;
+
+ /**
+ * @return URL using the timeline-protocol for searching.
+ */
+ static KUrl createTimelineUrl(const KUrl& url);
+
+ /**
+ * Helper method for createTimelineUrl().
+ * @return String that represents a date-path in the format that
+ * the timeline-protocol expects.
+ */
+ static QString timelineDateString(int year, int month, int day = 0);
+
+ /**
+ * @return URL that can be listed by KIO and results in searching
+ * for a given term. The URL \a url represents a places-internal
+ * URL like e.g. "search:/documents"
+ */
+ static KUrl createSearchUrl(const KUrl& url);
+
+#ifdef HAVE_NEPOMUK
+ /**
+ * Helper method for createSearchUrl().
+ * @return URL that can be listed by KIO and results in searching
+ * for the given term.
+ */
+ static KUrl searchUrlForTerm(const Nepomuk::Query::Term& term);
+#endif
private:
+ bool m_nepomukRunning;
+
KItemListController* m_controller;
KStandardItemModel* m_model;
+
QSet<QString> m_availableDevices;
KBookmarkManager* m_bookmarkManager;
+
+ struct DefaultBookmarkData
+ {
+ DefaultBookmarkData(const KUrl& url,
+ const QString& icon,
+ const QString& text,
+ const QString& group) :
+ url(url), icon(icon), text(text), group(group) {}
+ KUrl url;
+ QString icon;
+ QString text;
+ QString group;
+ };
+
+ QList<DefaultBookmarkData> m_defaultBookmarks;
+ QHash<KUrl, int> m_defaultBookmarksIndexes;
};
#endif // PLACESPANEL_H