From: Peter Penz Date: Tue, 24 Apr 2012 21:16:35 +0000 (+0200) Subject: Provide additional default groups for the Places Panel X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/commitdiff_plain/d9de39172033c28b8f9a7c1573130cf2124b4f7a Provide additional default groups for the Places Panel If Nepomuk is enabled, it is now possible to easily search for some most common queries by having additional groups. --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 868ff6c60..4d0519da9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -18,7 +18,6 @@ add_subdirectory(tests) ########### next target ############### set(dolphinprivate_LIB_SRCS - kitemviews/kfileitemlistgroupheader.cpp kitemviews/kfileitemlistview.cpp kitemviews/kfileitemlistwidget.cpp kitemviews/kfileitemmodel.cpp @@ -33,6 +32,7 @@ set(dolphinprivate_LIB_SRCS kitemviews/kitemlistwidget.cpp kitemviews/kitemmodelbase.cpp kitemviews/kstandarditem.cpp + kitemviews/kstandarditemlistgroupheader.cpp kitemviews/kstandarditemlistview.cpp kitemviews/kstandarditemlistwidget.cpp kitemviews/kstandarditemmodel.cpp @@ -143,6 +143,7 @@ set(dolphin_SRCS panels/information/pixmapviewer.cpp panels/information/phononwidget.cpp panels/places/placespanel.cpp + panels/places/placesitemlistgroupheader.cpp panels/panel.cpp panels/folders/treeviewcontextmenu.cpp panels/folders/folderspanel.cpp diff --git a/src/kitemviews/kfileitemlistview.cpp b/src/kitemviews/kfileitemlistview.cpp index 7bcc781fa..14547fc7b 100644 --- a/src/kitemviews/kfileitemlistview.cpp +++ b/src/kitemviews/kfileitemlistview.cpp @@ -19,7 +19,6 @@ #include "kfileitemlistview.h" -#include "kfileitemlistgroupheader.h" #include "kfileitemmodelrolesupdater.h" #include "kfileitemlistwidget.h" #include "kfileitemmodel.h" @@ -190,11 +189,6 @@ KItemListWidgetCreatorBase* KFileItemListView::defaultWidgetCreator() const return new KItemListWidgetCreator(); } -KItemListGroupHeaderCreatorBase* KFileItemListView::defaultGroupHeaderCreator() const -{ - return new KItemListGroupHeaderCreator(); -} - void KFileItemListView::onPreviewsShownChanged(bool shown) { Q_UNUSED(shown); diff --git a/src/kitemviews/kfileitemlistview.h b/src/kitemviews/kfileitemlistview.h index c8a3385fd..d795c96b5 100644 --- a/src/kitemviews/kfileitemlistview.h +++ b/src/kitemviews/kfileitemlistview.h @@ -77,7 +77,6 @@ public: protected: virtual KItemListWidgetCreatorBase* defaultWidgetCreator() const; - virtual KItemListGroupHeaderCreatorBase* defaultGroupHeaderCreator() const; virtual void onPreviewsShownChanged(bool shown); virtual void onItemLayoutChanged(ItemLayout current, ItemLayout previous); virtual void onModelChanged(KItemModelBase* current, KItemModelBase* previous); diff --git a/src/kitemviews/kitemlistgroupheader.cpp b/src/kitemviews/kitemlistgroupheader.cpp index bc68cd562..576d20b88 100644 --- a/src/kitemviews/kitemlistgroupheader.cpp +++ b/src/kitemviews/kitemlistgroupheader.cpp @@ -20,7 +20,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***************************************************************************/ -#include "kitemlistgroupheader.h" +#include "kstandarditemlistgroupheader.h" #include "kitemlistview.h" @@ -37,7 +37,7 @@ KItemListGroupHeader::KItemListGroupHeader(QGraphicsWidget* parent) : m_styleOption(), m_scrollOrientation(Qt::Vertical), m_itemIndex(-1), - m_lineColor(), + m_separatorColor(), m_roleColor(), m_roleBounds() { @@ -124,6 +124,7 @@ Qt::Orientation KItemListGroupHeader::scrollOrientation() const void KItemListGroupHeader::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { + Q_UNUSED(painter); Q_UNUSED(option); Q_UNUSED(widget); @@ -131,28 +132,8 @@ void KItemListGroupHeader::paint(QPainter* painter, const QStyleOptionGraphicsIt updateCache(); } - if (m_itemIndex == 0) { - // No top- or left-line should be drawn for the first group-header - return; - } - - painter->setPen(m_lineColor); - - if (m_scrollOrientation == Qt::Horizontal) { - painter->drawLine(0, 0, 0, size().height() - 1); - } else { - painter->drawLine(0, 0, size().width() - 1, 0); - } -} - -QRectF KItemListGroupHeader::roleBounds() const -{ - return m_roleBounds; -} - -QColor KItemListGroupHeader::roleColor() const -{ - return m_roleColor; + paintSeparator(painter, m_separatorColor); + paintRole(painter, m_roleBounds, m_roleColor); } void KItemListGroupHeader::roleChanged(const QByteArray& current, const QByteArray& previous) @@ -201,7 +182,7 @@ void KItemListGroupHeader::updateCache() // performance reasons. const QColor c1 = m_styleOption.palette.text().color(); const QColor c2 = m_styleOption.palette.base().color(); - m_lineColor = mixedColor(c1, c2, 10); + m_separatorColor = mixedColor(c1, c2, 10); m_roleColor = mixedColor(c1, c2, 70); const int padding = qMax(1, m_styleOption.padding); diff --git a/src/kitemviews/kitemlistgroupheader.h b/src/kitemviews/kitemlistgroupheader.h index c996a4870..e19ab4871 100644 --- a/src/kitemviews/kitemlistgroupheader.h +++ b/src/kitemviews/kitemlistgroupheader.h @@ -68,11 +68,8 @@ public: virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0); protected: - /** @return Bounding rectangle where the role should be drawn into. */ - QRectF roleBounds() const; - - /** @return Primary color that should be used for drawing the role. */ - QColor roleColor() const; + virtual void paintRole(QPainter* painter, const QRectF& roleBounds, const QColor& color) = 0; + virtual void paintSeparator(QPainter* painter, const QColor& color) = 0; /** * Is called after the role has been changed and allows the derived class @@ -120,7 +117,7 @@ private: Qt::Orientation m_scrollOrientation; int m_itemIndex; - QColor m_lineColor; + QColor m_separatorColor; QColor m_roleColor; QRectF m_roleBounds; }; diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index 6d2d98e93..8ecd1e212 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -1850,7 +1850,7 @@ void KItemListView::updateGroupHeaderForWidget(KItemListWidget* widget) } const QList > groups = model()->groups(); - if (groups.isEmpty()) { + if (groups.isEmpty() || !groupHeaderCreator()) { return; } diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h index 3c47e95c6..dd67b941b 100644 --- a/src/kitemviews/kitemlistview.h +++ b/src/kitemviews/kitemlistview.h @@ -25,7 +25,7 @@ #include -#include +#include #include #include #include diff --git a/src/kitemviews/kfileitemlistgroupheader.cpp b/src/kitemviews/kstandarditemlistgroupheader.cpp similarity index 69% rename from src/kitemviews/kfileitemlistgroupheader.cpp rename to src/kitemviews/kstandarditemlistgroupheader.cpp index 0c940ed28..3a5ddd944 100644 --- a/src/kitemviews/kfileitemlistgroupheader.cpp +++ b/src/kitemviews/kstandarditemlistgroupheader.cpp @@ -20,12 +20,12 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***************************************************************************/ -#include "kfileitemlistgroupheader.h" +#include "kstandarditemlistgroupheader.h" #include #include -KFileItemListGroupHeader::KFileItemListGroupHeader(QGraphicsWidget* parent) : +KStandardItemListGroupHeader::KStandardItemListGroupHeader(QGraphicsWidget* parent) : KItemListGroupHeader(parent), m_dirtyCache(true), m_text(), @@ -35,47 +35,65 @@ KFileItemListGroupHeader::KFileItemListGroupHeader(QGraphicsWidget* parent) : m_text.setPerformanceHint(QStaticText::AggressiveCaching); } -KFileItemListGroupHeader::~KFileItemListGroupHeader() +KStandardItemListGroupHeader::~KStandardItemListGroupHeader() { } -void KFileItemListGroupHeader::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) +void KStandardItemListGroupHeader::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { - KItemListGroupHeader::paint(painter, option, widget); - if (m_dirtyCache) { updateCache(); } + KItemListGroupHeader::paint(painter, option, widget); +} +void KStandardItemListGroupHeader::paintRole(QPainter* painter, const QRectF& roleBounds, const QColor& color) +{ if (m_pixmap.isNull()) { - painter->setPen(roleColor()); - painter->drawStaticText(roleBounds().topLeft(), m_text); + painter->setPen(color); + painter->drawStaticText(roleBounds.topLeft(), m_text); + } else { + painter->drawPixmap(roleBounds.topLeft(), m_pixmap); + } +} + +void KStandardItemListGroupHeader::paintSeparator(QPainter* painter, const QColor& color) +{ + if (itemIndex() == 0) { + // No top- or left-line should be drawn for the first group-header + return; + } + + painter->setPen(color); + + if (scrollOrientation() == Qt::Horizontal) { + painter->drawLine(0, 0, 0, size().height() - 1); } else { - painter->drawPixmap(roleBounds().topLeft(), m_pixmap); + painter->drawLine(0, 0, size().width() - 1, 0); } } -void KFileItemListGroupHeader::roleChanged(const QByteArray ¤t, const QByteArray &previous) +void KStandardItemListGroupHeader::roleChanged(const QByteArray ¤t, const QByteArray &previous) { Q_UNUSED(current); Q_UNUSED(previous); m_dirtyCache = true; } -void KFileItemListGroupHeader::dataChanged(const QVariant& current, const QVariant& previous) +void KStandardItemListGroupHeader::dataChanged(const QVariant& current, const QVariant& previous) { Q_UNUSED(current); Q_UNUSED(previous); m_dirtyCache = true; } -void KFileItemListGroupHeader::resizeEvent(QGraphicsSceneResizeEvent* event) +void KStandardItemListGroupHeader::resizeEvent(QGraphicsSceneResizeEvent* event) { QGraphicsWidget::resizeEvent(event); m_dirtyCache = true; } -void KFileItemListGroupHeader::updateCache() +void KStandardItemListGroupHeader::updateCache() { Q_ASSERT(m_dirtyCache); m_dirtyCache = false; @@ -104,4 +122,4 @@ void KFileItemListGroupHeader::updateCache() } } -#include "kfileitemlistgroupheader.moc" +#include "kstandarditemlistgroupheader.moc" diff --git a/src/kitemviews/kfileitemlistgroupheader.h b/src/kitemviews/kstandarditemlistgroupheader.h similarity index 81% rename from src/kitemviews/kfileitemlistgroupheader.h rename to src/kitemviews/kstandarditemlistgroupheader.h index 41a1123ff..26158d6ba 100644 --- a/src/kitemviews/kfileitemlistgroupheader.h +++ b/src/kitemviews/kstandarditemlistgroupheader.h @@ -17,8 +17,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***************************************************************************/ -#ifndef KFILEITEMLISTGROUPHEADER_H -#define KFILEITEMLISTGROUPHEADER_H +#ifndef KSTANDARDITEMLISTGROUPHEADER_H +#define KSTANDARDITEMLISTGROUPHEADER_H #include @@ -27,17 +27,19 @@ #include #include -class LIBDOLPHINPRIVATE_EXPORT KFileItemListGroupHeader : public KItemListGroupHeader +class LIBDOLPHINPRIVATE_EXPORT KStandardItemListGroupHeader : public KItemListGroupHeader { Q_OBJECT public: - KFileItemListGroupHeader(QGraphicsWidget* parent = 0); - virtual ~KFileItemListGroupHeader(); + KStandardItemListGroupHeader(QGraphicsWidget* parent = 0); + virtual ~KStandardItemListGroupHeader(); virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0); protected: + virtual void paintRole(QPainter* painter, const QRectF& roleBounds, const QColor& color); + virtual void paintSeparator(QPainter* painter, const QColor& color); virtual void roleChanged(const QByteArray ¤t, const QByteArray &previous); virtual void dataChanged(const QVariant& current, const QVariant& previous); virtual void resizeEvent(QGraphicsSceneResizeEvent* event); diff --git a/src/kitemviews/kstandarditemlistview.cpp b/src/kitemviews/kstandarditemlistview.cpp index bd5da9eb0..f4d05dcf6 100644 --- a/src/kitemviews/kstandarditemlistview.cpp +++ b/src/kitemviews/kstandarditemlistview.cpp @@ -22,6 +22,7 @@ #include #include #include "kstandarditemlistwidget.h" +#include "kstandarditemlistgroupheader.h" KStandardItemListView::KStandardItemListView(QGraphicsWidget* parent) : KItemListView(parent), @@ -82,7 +83,7 @@ KItemListWidgetCreatorBase* KStandardItemListView::defaultWidgetCreator() const KItemListGroupHeaderCreatorBase* KStandardItemListView::defaultGroupHeaderCreator() const { - return 0; // TODO: new KItemListGroupHeaderCreator() + return new KItemListGroupHeaderCreator(); } void KStandardItemListView::initializeItemListWidget(KItemListWidget* item) diff --git a/src/kitemviews/kstandarditemmodel.cpp b/src/kitemviews/kstandarditemmodel.cpp index 86ef9563b..897267df6 100644 --- a/src/kitemviews/kstandarditemmodel.cpp +++ b/src/kitemviews/kstandarditemmodel.cpp @@ -123,7 +123,22 @@ QString KStandardItemModel::roleDescription(const QByteArray& role) const QList > KStandardItemModel::groups() const { - return QList >(); + QList > groups; + + const QByteArray role = sortRole(); + bool isFirstGroupValue = true; + QString groupValue; + const int maxIndex = count() - 1; + for (int i = 0; i <= maxIndex; ++i) { + const QString newGroupValue = m_items.at(i)->dataValue(role).toString(); + if (newGroupValue != groupValue || isFirstGroupValue) { + groupValue = newGroupValue; + groups.append(QPair(i, newGroupValue)); + isFirstGroupValue = false; + } + } + + return groups; } #include "kstandarditemmodel.moc" 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 * + * * + * 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 * + * * + * 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 + +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 + #include + #include + #include + #include + #include + #include +#endif + #include #include #include #include #include #include +#include #include #include #include #include #include #include +#include +#include "placesitemlistgroupheader.h" #include +#include #include #include 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()); 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(); + 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(); + 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 devices = m_availableDevices; + QSet 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(); + 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 + +#include #include +#include +#include #include 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 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 m_defaultBookmarks; + QHash m_defaultBookmarksIndexes; }; #endif // PLACESPANEL_H diff --git a/src/search/dolphinsearchinformation.cpp b/src/search/dolphinsearchinformation.cpp index fde45f38e..8af951a7b 100644 --- a/src/search/dolphinsearchinformation.cpp +++ b/src/search/dolphinsearchinformation.cpp @@ -90,7 +90,7 @@ DolphinSearchInformation::DolphinSearchInformation() : m_indexingEnabled(false) { #ifdef HAVE_NEPOMUK - if (Nepomuk::ResourceManager::instance()->init() == 0) { + if (Nepomuk::ResourceManager::instance()->initialized()) { KConfig config("nepomukserverrc"); m_indexingEnabled = config.group("Service-nepomukfileindexer").readEntry("autostart", false); } diff --git a/src/settings/additionalinfodialog.cpp b/src/settings/additionalinfodialog.cpp index 3cac35b7b..3e2350968 100644 --- a/src/settings/additionalinfodialog.cpp +++ b/src/settings/additionalinfodialog.cpp @@ -53,7 +53,7 @@ AdditionalInfoDialog::AdditionalInfoDialog(QWidget* parent, bool nepomukRunning = false; bool indexingEnabled = false; #ifdef HAVE_NEPOMUK - nepomukRunning = (Nepomuk::ResourceManager::instance()->init() == 0); + nepomukRunning = (Nepomuk::ResourceManager::instance()->initialized()); if (nepomukRunning) { KConfig config("nepomukserverrc"); indexingEnabled = config.group("Service-nepomukfileindexer").readEntry("autostart", false); diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index 12932c709..d21743bf4 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -796,7 +796,7 @@ void DolphinView::slotHeaderContextMenuRequested(const QPointF& pos) bool nepomukRunning = false; bool indexingEnabled = false; #ifdef HAVE_NEPOMUK - nepomukRunning = (Nepomuk::ResourceManager::instance()->init() == 0); + nepomukRunning = (Nepomuk::ResourceManager::instance()->initialized()); if (nepomukRunning) { KConfig config("nepomukserverrc"); indexingEnabled = config.group("Service-nepomukfileindexer").readEntry("autostart", false); diff --git a/src/views/dolphinviewactionhandler.cpp b/src/views/dolphinviewactionhandler.cpp index 6f69a6420..7f23b7d54 100644 --- a/src/views/dolphinviewactionhandler.cpp +++ b/src/views/dolphinviewactionhandler.cpp @@ -237,7 +237,7 @@ QActionGroup* DolphinViewActionHandler::createFileItemRolesActionGroup(const QSt bool nepomukRunning = false; bool indexingEnabled = false; #ifdef HAVE_NEPOMUK - nepomukRunning = (Nepomuk::ResourceManager::instance()->init() == 0); + nepomukRunning = (Nepomuk::ResourceManager::instance()->initialized()); if (nepomukRunning) { KConfig config("nepomukserverrc"); indexingEnabled = config.group("Service-nepomukfileindexer").readEntry("autostart", false);