Places Panel: Prepare code to save state of bookmarks

The saving is still disabled currently until 100 % backward
compatibility with KFilePlacesView has been reached.
This commit is contained in:
Peter Penz 2012-05-13 21:44:58 +02:00
parent 6039c246ea
commit 1426b8d3c7
8 changed files with 433 additions and 239 deletions

View file

@ -142,3 +142,20 @@ QList<KStandardItem*> KStandardItem::children() const
{
return m_children;
}
void KStandardItem::onDataValueChanged(const QByteArray& role,
const QVariant& current,
const QVariant& previous)
{
Q_UNUSED(role);
Q_UNUSED(current);
Q_UNUSED(previous);
}
void KStandardItem::onDataChanged(const QHash<QByteArray, QVariant>& current,
const QHash<QByteArray, QVariant>& previous)
{
Q_UNUSED(current);
Q_UNUSED(previous);
}

View file

@ -79,6 +79,14 @@ public:
QList<KStandardItem*> children() const;
protected:
virtual void onDataValueChanged(const QByteArray& role,
const QVariant& current,
const QVariant& previous);
virtual void onDataChanged(const QHash<QByteArray, QVariant>& current,
const QHash<QByteArray, QVariant>& previous);
private:
KStandardItem* m_parent;
QList<KStandardItem*> m_children;

View file

@ -22,53 +22,24 @@
#include "placesitem.h"
#include <KBookmark>
#include <KBookmarkManager>
#include <KDebug>
#include <KIcon>
#include <KLocale>
#include "placesitemstorageaccesslistener.h"
#include <QDateTime>
#include <Solid/Block>
PlacesItem::PlacesItem(PlacesItem* parent) :
KStandardItem(parent),
m_device(),
m_access(),
m_volume(),
m_disc(),
m_accessListener(0)
{
}
PlacesItem::PlacesItem(const KBookmark& bookmark, PlacesItem* parent) :
KStandardItem(parent),
m_device(),
m_access(),
m_volume(),
m_disc(),
m_accessListener(0)
m_accessListener(0),
m_bookmark()
{
setHidden(bookmark.metaDataItem("IsHidden") == QLatin1String("true"));
const QString udi = bookmark.metaDataItem("UDI");
if (udi.isEmpty()) {
setIcon(bookmark.icon());
setText(bookmark.text());
setUrl(bookmark.url());
setDataValue("address", bookmark.address());
setGroup(i18nc("@item", "Places"));
} else {
initializeDevice(udi);
}
}
PlacesItem::PlacesItem(const QString& udi, PlacesItem* parent) :
KStandardItem(parent),
m_device(),
m_access(),
m_volume(),
m_disc(),
m_accessListener(0)
{
initializeDevice(udi);
setBookmark(bookmark);
}
PlacesItem::PlacesItem(const PlacesItem& item) :
@ -77,14 +48,14 @@ PlacesItem::PlacesItem(const PlacesItem& item) :
m_access(),
m_volume(),
m_disc(),
m_accessListener(0)
m_accessListener(0),
m_bookmark()
{
}
PlacesItem::~PlacesItem()
{
delete m_accessListener;
m_accessListener = 0;
}
void PlacesItem::setUrl(const KUrl& url)
@ -110,6 +81,9 @@ QString PlacesItem::udi() const
void PlacesItem::setHidden(bool hidden)
{
setDataValue("isHidden", hidden);
if (!m_bookmark.isNull()) {
m_bookmark.setMetaDataItem("IsHidden", hidden ? "true" : "false");
}
}
bool PlacesItem::isHidden() const
@ -117,11 +91,109 @@ bool PlacesItem::isHidden() const
return dataValue("isHidden").toBool();
}
void PlacesItem::setSystemItem(bool isSystemItem)
{
setDataValue("isSystemItem", isSystemItem);
}
bool PlacesItem::isSystemItem() const
{
return dataValue("isSystemItem").toBool();
}
Solid::Device PlacesItem::device() const
{
return m_device;
}
void PlacesItem::setBookmark(const KBookmark& bookmark)
{
m_bookmark = bookmark;
delete m_access;
delete m_volume;
delete m_disc;
delete m_accessListener;
const QString udi = bookmark.metaDataItem("UDI");
if (udi.isEmpty()) {
setIcon(bookmark.icon());
setText(bookmark.text());
setUrl(bookmark.url());
setDataValue("address", bookmark.address());
setGroup(i18nc("@item", "Places"));
} else {
initializeDevice(udi);
}
setHidden(bookmark.metaDataItem("IsHidden") == QLatin1String("true"));
}
KBookmark PlacesItem::bookmark() const
{
return m_bookmark;
}
KBookmark PlacesItem::createBookmark(KBookmarkManager* manager,
const QString& text,
const KUrl& url,
const QString& iconName,
PlacesItem* after)
{
KBookmarkGroup root = manager->root();
if (root.isNull()) {
return KBookmark();
}
KBookmark bookmark = root.addBookmark(text, url, iconName);
bookmark.setMetaDataItem("ID", generateNewId());
if (after) {
root.moveBookmark(bookmark, after->bookmark());
}
return bookmark;
}
KBookmark PlacesItem::createDeviceBookmark(KBookmarkManager* manager,
const QString& udi)
{
KBookmarkGroup root = manager->root();
if (root.isNull()) {
return KBookmark();
}
KBookmark bookmark = root.createNewSeparator();
bookmark.setMetaDataItem("UDI", udi);
bookmark.setMetaDataItem("isSystemItem", "true");
return bookmark;
}
void PlacesItem::onDataValueChanged(const QByteArray& role,
const QVariant& current,
const QVariant& previous)
{
Q_UNUSED(current);
Q_UNUSED(previous);
if (!m_bookmark.isNull()) {
updateBookmarkForRole(role);
}
}
void PlacesItem::onDataChanged(const QHash<QByteArray, QVariant>& current,
const QHash<QByteArray, QVariant>& previous)
{
Q_UNUSED(previous);
if (!m_bookmark.isNull()) {
QHashIterator<QByteArray, QVariant> it(current);
while (it.hasNext()) {
it.next();
updateBookmarkForRole(it.key());
}
}
}
void PlacesItem::initializeDevice(const QString& udi)
{
m_device = Solid::Device(udi);
@ -141,11 +213,11 @@ void PlacesItem::initializeDevice(const QString& udi)
if (m_access) {
setUrl(m_access->filePath());
// The access listener takes care to call PlacesItem::onAccessibilityChanged()
// in case if the accessibility of m_access has been changed.
Q_ASSERT(!m_accessListener);
m_accessListener = new PlacesItemStorageAccessListener(this);
if (!m_accessListener) {
// The access listener takes care to call PlacesItem::onAccessibilityChanged()
// in case if the accessibility of m_access has been changed.
m_accessListener = new PlacesItemStorageAccessListener(this);
}
} else if (m_disc && (m_disc->availableContent() & Solid::OpticalDisc::Audio) != 0) {
const QString device = m_device.as<Solid::Block>()->device();
setUrl(QString("audiocd:/?device=%1").arg(device));
@ -157,3 +229,26 @@ void PlacesItem::onAccessibilityChanged()
setIconOverlays(m_device.emblems());
}
void PlacesItem::updateBookmarkForRole(const QByteArray& role)
{
Q_ASSERT(!m_bookmark.isNull());
if (role == "iconName") {
m_bookmark.setIcon(icon());
} else if (role == "text") {
m_bookmark.setDescription(text());
} else if (role == "url") {
m_bookmark.setUrl(url());
} else if (role == "udi)") {
m_bookmark.setMetaDataItem("UDI", udi());
} else if (role == "isSystemItem") {
m_bookmark.setMetaDataItem("isSystemItem", isSystemItem() ? "true" : "false");
} else if (role == "isHidden") {
m_bookmark.setMetaDataItem("IsHidden", isHidden() ? "true" : "false");
}
}
QString PlacesItem::generateNewId()
{
static int count = 0;
return QString::number(QDateTime::currentDateTime().toTime_t()) + '/' + QString::number(count++);
}

View file

@ -20,6 +20,7 @@
#ifndef PLACESITEM_H
#define PLACESITEM_H
#include <KBookmark>
#include <kitemviews/kstandarditem.h>
#include <KUrl>
#include <QPointer>
@ -28,7 +29,6 @@
#include <Solid/StorageAccess>
#include <Solid/StorageVolume>
class KBookmark;
class PlacesItemStorageAccessListener;
/**
@ -38,10 +38,8 @@ class PlacesItem : public KStandardItem
{
public:
explicit PlacesItem(PlacesItem* parent = 0);
explicit PlacesItem(const KBookmark& bookmark, PlacesItem* parent = 0);
explicit PlacesItem(const QString& udi, PlacesItem* parent = 0);
PlacesItem(const PlacesItem& item);
explicit PlacesItem(const PlacesItem& item);
virtual ~PlacesItem();
void setUrl(const KUrl& url);
@ -53,8 +51,30 @@ public:
void setHidden(bool hidden);
bool isHidden() const;
void setSystemItem(bool isSystemItem);
bool isSystemItem() const;
Solid::Device device() const;
void setBookmark(const KBookmark& bookmark);
KBookmark bookmark() const;
static KBookmark createBookmark(KBookmarkManager* manager,
const QString& text,
const KUrl& url,
const QString& iconName,
PlacesItem* after = 0);
static KBookmark createDeviceBookmark(KBookmarkManager* manager,
const QString& udi);
protected:
virtual void onDataValueChanged(const QByteArray& role,
const QVariant& current,
const QVariant& previous);
virtual void onDataChanged(const QHash<QByteArray, QVariant>& current,
const QHash<QByteArray, QVariant>& previous);
private:
void initializeDevice(const QString& udi);
@ -64,12 +84,20 @@ private:
*/
void onAccessibilityChanged();
/**
* Applies the data-value from the role to m_bookmark.
*/
void updateBookmarkForRole(const QByteArray& role);
static QString generateNewId();
private:
Solid::Device m_device;
QPointer<Solid::StorageAccess> m_access;
QPointer<Solid::StorageVolume> m_volume;
QPointer<Solid::OpticalDisc> m_disc;
PlacesItemStorageAccessListener* m_accessListener;
QPointer<PlacesItemStorageAccessListener> m_accessListener;
KBookmark m_bookmark;
friend class PlacesItemStorageAccessListener; // Calls onAccessibilityChanged()
};

View file

@ -23,16 +23,6 @@
#include "placesitemmodel.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>
@ -53,6 +43,10 @@
#include <Solid/StorageAccess>
#include <Solid/StorageDrive>
#ifdef HAVE_NEPOMUK
#include <Nepomuk/ResourceManager>
#endif
PlacesItemModel::PlacesItemModel(QObject* parent) :
KStandardItemModel(parent),
m_nepomukRunning(false),
@ -172,15 +166,6 @@ bool PlacesItemModel::hiddenItemsShown() const
return m_hiddenItemsShown;
}
bool PlacesItemModel::isSystemItem(int index) const
{
if (index >= 0 && index < count()) {
const KUrl url = placesItem(index)->url();
return m_systemBookmarksIndexes.contains(url);
}
return false;
}
int PlacesItemModel::closestItem(const KUrl& url) const
{
int foundIndex = -1;
@ -303,8 +288,23 @@ void PlacesItemModel::requestTeardown(int index)
}
}
void PlacesItemModel::save()
{
// TODO: Temporary deactivated until 100 % backward compatibility is provided
// m_bookmarkManager->emitChanged(m_bookmarkManager->root());
}
void PlacesItemModel::onItemInserted(int index)
{
if (index == count() - 1) {
// The item has been appended as last item to the list. In this
// case assure that it is also appended after the hidden items and
// not before (like done otherwise).
m_hiddenItems.append(0);
return;
}
int modelIndex = 0;
int hiddenIndex = 0;
while (hiddenIndex < m_hiddenItems.count()) {
@ -336,20 +336,34 @@ void PlacesItemModel::onItemRemoved(int index)
#endif
}
void PlacesItemModel::onItemReplaced(int index)
{
Q_UNUSED(index);
}
void PlacesItemModel::slotDeviceAdded(const QString& udi)
{
appendItem(new PlacesItem(udi));
const Solid::Device device(udi);
if (m_predicate.matches(device)) {
m_availableDevices << udi;
const KBookmark bookmark = PlacesItem::createDeviceBookmark(m_bookmarkManager, udi);
appendItem(new PlacesItem(bookmark));
}
}
void PlacesItemModel::slotDeviceRemoved(const QString& udi)
{
for (int i = 0; i < m_hiddenItems.count(); ++i) {
PlacesItem* item = m_hiddenItems[i];
if (item && item->udi() == udi) {
m_hiddenItems.removeAt(i);
delete item;
return;
}
if (!m_availableDevices.contains(udi)) {
return;
}
for (int i = 0; i < m_hiddenItems.count(); ++i) {
PlacesItem* item = m_hiddenItems[i];
if (item && item->udi() == udi) {
m_hiddenItems.removeAt(i);
delete item;
return;
}
}
for (int i = 0; i < count(); ++i) {
@ -380,7 +394,7 @@ void PlacesItemModel::loadBookmarks()
// The bookmarks might have a mixed order of "places" and "devices". In
// Dolphin's places panel the devices should always be appended as last
// group.
// group, so they are collected as separate lists.
QList<PlacesItem*> placesItems;
QList<PlacesItem*> devicesItems;
@ -391,7 +405,8 @@ void PlacesItemModel::loadBookmarks()
const bool deviceAvailable = devices.remove(udi);
const bool allowedHere = (appName.isEmpty() || appName == KGlobal::mainComponent().componentName())
&& (m_nepomukRunning || url.protocol() != QLatin1String("timeline"));
&& (m_nepomukRunning || (url.protocol() != QLatin1String("timeline") &&
url.protocol() != QLatin1String("search")));
if ((udi.isEmpty() && allowedHere) || deviceAvailable) {
PlacesItem* item = new PlacesItem(bookmark);
@ -407,10 +422,8 @@ void PlacesItemModel::loadBookmarks()
// translation might be shown.
const int index = m_systemBookmarksIndexes.value(url);
item->setText(m_systemBookmarks[index].text);
// The system bookmarks don't contain "real" queries stored as URLs, so
// they must be translated first.
item->setUrl(translatedSystemBookmarkUrl(url));
item->setSystemItem(true);
item->setGroup(m_systemBookmarks[index].group);
}
}
}
@ -421,12 +434,24 @@ void PlacesItemModel::loadBookmarks()
addItems(placesItems);
if (!missingSystemBookmarks.isEmpty()) {
// The current bookmarks don't contain all system-bookmarks. Add the missing
// bookmarks.
foreach (const SystemBookmarkData& data, m_systemBookmarks) {
if (missingSystemBookmarks.contains(data.url)) {
PlacesItem* item = new PlacesItem();
item->setIcon(data.icon);
item->setText(data.text);
item->setUrl(translatedSystemBookmarkUrl(data.url));
KBookmark bookmark = PlacesItem::createBookmark(m_bookmarkManager,
data.text,
data.url,
data.icon);
const QString protocol = data.url.protocol();
if (protocol == QLatin1String("timeline") || protocol == QLatin1String("search")) {
// As long as the KFilePlacesView from kdelibs is available, the system-bookmarks
// for timeline and search should be a Dolphin-specific setting.
bookmark.setMetaDataItem("OnlyInApp", KGlobal::mainComponent().componentName());
}
PlacesItem* item = new PlacesItem(bookmark);
item->setSystemItem(true);
item->setGroup(data.group);
appendItem(item);
}
@ -435,8 +460,8 @@ void PlacesItemModel::loadBookmarks()
// Create items for devices that have not stored as bookmark yet
foreach (const QString& udi, devices) {
PlacesItem* item = new PlacesItem(udi);
devicesItems.append(item);
const KBookmark bookmark = PlacesItem::createDeviceBookmark(m_bookmarkManager, udi);
devicesItems.append(new PlacesItem(bookmark));
}
addItems(devicesItems);
@ -450,7 +475,7 @@ void PlacesItemModel::loadBookmarks()
void PlacesItemModel::addItems(const QList<PlacesItem*>& items)
{
foreach (PlacesItem* item, items) {
if (item->isHidden()) {
if (!m_hiddenItemsShown && item->isHidden()) {
m_hiddenItems.append(item);
} else {
appendItem(item);
@ -522,8 +547,7 @@ void PlacesItemModel::createSystemBookmarks()
}
for (int i = 0; i < m_systemBookmarks.count(); ++i) {
const KUrl url = translatedSystemBookmarkUrl(m_systemBookmarks[i].url);
m_systemBookmarksIndexes.insert(url, i);
m_systemBookmarksIndexes.insert(m_systemBookmarks[i].url, i);
}
}
@ -581,100 +605,6 @@ QString PlacesItemModel::searchForGroupName()
return i18nc("@item", "Search For");
}
KUrl PlacesItemModel::translatedSystemBookmarkUrl(const KUrl& url)
{
KUrl translatedUrl = url;
if (url.protocol() == QLatin1String("timeline")) {
translatedUrl = createTimelineUrl(url);
} else if (url.protocol() == QLatin1String("search")) {
translatedUrl = createSearchUrl(url);
}
return translatedUrl;
}
KUrl PlacesItemModel::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 PlacesItemModel::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 PlacesItemModel::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("audio")) {
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);
}
#else
Q_UNUSED(url);
#endif
return searchUrl;
}
#ifdef HAVE_NEPOMUK
KUrl PlacesItemModel::searchUrlForTerm(const Nepomuk::Query::Term& term)
{
const Nepomuk::Query::Query query(term);
return query.toSearchUrl();
}
#endif
#ifdef PLACESITEMMODEL_DEBUG
void PlacesItemModel::showModelState()
{

View file

@ -35,16 +35,6 @@ class KBookmarkManager;
class PlacesItem;
class QAction;
#ifdef HAVE_NEPOMUK
namespace Nepomuk
{
namespace Query
{
class Term;
}
}
#endif
#define PLACESITEMMODEL_DEBUG
/**
@ -71,12 +61,6 @@ public:
void setItemHidden(int index, bool hide);
bool isItemHidden(int index) const;
/**
* @return True if the item is a default item created by
* the system (e.g. the places for home, root, trash etc.)
*/
bool isSystemItem(int index) const;
/**
* Search the item which is equal to the URL or at least
* is a parent URL. If there are more than one possible
@ -98,12 +82,15 @@ public:
void requestEject(int index);
void requestTeardown(int index);
void save();
signals:
void errorMessage(const QString& message);
protected:
virtual void onItemInserted(int index);
virtual void onItemRemoved(int index);
virtual void onItemReplaced(int index);
private slots:
void slotDeviceAdded(const QString& udi);
@ -139,36 +126,6 @@ private:
static QString recentlyAccessedGroupName();
static QString searchForGroupName();
static KUrl translatedSystemBookmarkUrl(const KUrl& url);
/**
* @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
#ifdef PLACESITEMMODEL_DEBUG
void showModelState();
#endif

View file

@ -38,6 +38,7 @@
#include <KMenu>
#include <KMessageBox>
#include <KNotification>
#include "placesitem.h"
#include "placesitemeditdialog.h"
#include "placesitemlistgroupheader.h"
#include "placesitemlistwidget.h"
@ -46,6 +47,15 @@
#include <QVBoxLayout>
#include <QShowEvent>
#ifdef HAVE_NEPOMUK
#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
PlacesPanel::PlacesPanel(QWidget* parent) :
Panel(parent),
m_controller(0),
@ -107,7 +117,7 @@ void PlacesPanel::slotItemActivated(int index)
{
const KUrl url = m_model->data(index).value("url").value<KUrl>();
if (!url.isEmpty()) {
emit placeActivated(url);
emit placeActivated(convertedUrl(url));
}
}
@ -115,14 +125,16 @@ void PlacesPanel::slotItemMiddleClicked(int index)
{
const KUrl url = m_model->data(index).value("url").value<KUrl>();
if (!url.isEmpty()) {
emit placeMiddleClicked(url);
emit placeMiddleClicked(convertedUrl(url));
}
}
void PlacesPanel::slotItemContextMenuRequested(int index, const QPointF& pos)
{
const QHash<QByteArray, QVariant> data = m_model->data(index);
const QString label = data.value("text").toString();
const PlacesItem* item = m_model->placesItem(index);
if (!item) {
return;
}
KMenu menu(this);
@ -133,8 +145,9 @@ void PlacesPanel::slotItemContextMenuRequested(int index, const QPointF& pos)
QAction* teardownAction = 0;
QAction* ejectAction = 0;
const bool isSystemItem = m_model->isSystemItem(index);
const bool isDevice = !data.value("udi").toString().isEmpty();
const QString label = item->text();
const bool isDevice = !item->udi().isEmpty();
if (isDevice) {
ejectAction = m_model->ejectAction(index);
if (ejectAction) {
@ -152,7 +165,7 @@ void PlacesPanel::slotItemContextMenuRequested(int index, const QPointF& pos)
mainSeparator = menu.addSeparator();
}
} else {
if (data.value("url").value<KUrl>() == KUrl("trash:/")) {
if (item->url() == KUrl("trash:/")) {
emptyTrashAction = menu.addAction(KIcon("trash-empty"), i18nc("@action:inmenu", "Empty Trash"));
KConfig trashConfig("trashrc", KConfig::SimpleConfig);
emptyTrashAction->setEnabled(!trashConfig.group("Status").readEntry("Empty", true));
@ -171,13 +184,13 @@ void PlacesPanel::slotItemContextMenuRequested(int index, const QPointF& pos)
openInNewTabAction->setIcon(KIcon("tab-new"));
QAction* removeAction = 0;
if (!isDevice && !isSystemItem) {
if (!isDevice && !item->isSystemItem()) {
removeAction = menu.addAction(KIcon("edit-delete"), i18nc("@item:inmenu", "Remove '%1'", label));
}
QAction* hideAction = menu.addAction(i18nc("@item:inmenu", "Hide '%1'", label));
hideAction->setCheckable(true);
hideAction->setChecked(data.value("isHidden").toBool());
hideAction->setChecked(item->isHidden());
QAction* showAllAction = 0;
if (m_model->hiddenCount() > 0) {
@ -204,8 +217,10 @@ void PlacesPanel::slotItemContextMenuRequested(int index, const QPointF& pos)
editEntry(index);
} else if (action == removeAction) {
m_model->removeItem(index);
m_model->save();
} else if (action == hideAction) {
m_model->setItemHidden(index, hideAction->isChecked());
m_model->save();
} else if (action == openInNewTabAction) {
const KUrl url = m_model->item(index)->dataValue("url").value<KUrl>();
emit placeMiddleClicked(url);
@ -264,7 +279,7 @@ void PlacesPanel::slotUrlsDropped(const KUrl& dest, QDropEvent* event, QWidget*
void PlacesPanel::slotTrashUpdated(KJob* job)
{
if (job->error()) {
// TODO: Show error-string inside Dolphin, don't use job->ui->showErrorMessage().
emit errorMessage(job->errorString());
}
org::kde::KDirNotify::emitFilesAdded("trash:/");
}
@ -322,6 +337,8 @@ void PlacesPanel::addEntry()
}
delete dialog;
m_model->save();
}
void PlacesPanel::editEntry(int index)
@ -347,6 +364,8 @@ void PlacesPanel::editEntry(int index)
}
delete dialog;
m_model->save();
}
void PlacesPanel::selectClosestItem()
@ -372,4 +391,98 @@ KStandardItem* PlacesPanel::createStandardItemFromDialog(PlacesItemEditDialog* d
return item;
}
KUrl PlacesPanel::convertedUrl(const KUrl& url)
{
KUrl newUrl = url;
if (url.protocol() == QLatin1String("timeline")) {
newUrl = createTimelineUrl(url);
} else if (url.protocol() == QLatin1String("search")) {
newUrl = createSearchUrl(url);
}
return newUrl;
}
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("audio")) {
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);
}
#else
Q_UNUSED(url);
#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"

View file

@ -31,6 +31,16 @@ class KItemListController;
class PlacesItemEditDialog;
class PlacesItemModel;
#ifdef HAVE_NEPOMUK
namespace Nepomuk
{
namespace Query
{
class Term;
}
}
#endif
/**
* @brief Combines bookmarks and mounted devices as list.
*/
@ -76,6 +86,42 @@ private:
*/
KStandardItem* createStandardItemFromDialog(PlacesItemEditDialog* dialog) const;
/**
* @return Converts the URL, which contains "virtual" URLs for system-items like
* "search:/documents" into a Nepomuk-Query-URL that will be handled by
* the corresponding IO-slave. Virtual URLs for bookmarks are used to
* be independent from internal format changes.
*/
static KUrl convertedUrl(const KUrl& url);
/**
* @return URL using the timeline-protocol for searching (see convertedUrl()).
*/
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" (see convertedUrl()).
*/
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:
KItemListController* m_controller;
PlacesItemModel* m_model;