diff --git a/src/kitemviews/kstandarditem.cpp b/src/kitemviews/kstandarditem.cpp index d7f9217bf1..22c3a03e99 100644 --- a/src/kitemviews/kstandarditem.cpp +++ b/src/kitemviews/kstandarditem.cpp @@ -142,3 +142,20 @@ QList 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& current, + const QHash& previous) +{ + Q_UNUSED(current); + Q_UNUSED(previous); +} + diff --git a/src/kitemviews/kstandarditem.h b/src/kitemviews/kstandarditem.h index f296c7666f..689db42519 100644 --- a/src/kitemviews/kstandarditem.h +++ b/src/kitemviews/kstandarditem.h @@ -79,6 +79,14 @@ public: QList children() const; +protected: + virtual void onDataValueChanged(const QByteArray& role, + const QVariant& current, + const QVariant& previous); + + virtual void onDataChanged(const QHash& current, + const QHash& previous); + private: KStandardItem* m_parent; QList m_children; diff --git a/src/panels/places/placesitem.cpp b/src/panels/places/placesitem.cpp index c865aa11db..292312d0a0 100644 --- a/src/panels/places/placesitem.cpp +++ b/src/panels/places/placesitem.cpp @@ -22,53 +22,24 @@ #include "placesitem.h" -#include +#include +#include #include #include #include "placesitemstorageaccesslistener.h" +#include #include -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& current, + const QHash& previous) +{ + Q_UNUSED(previous); + + if (!m_bookmark.isNull()) { + QHashIterator 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()->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++); +} diff --git a/src/panels/places/placesitem.h b/src/panels/places/placesitem.h index 878d14a7d0..c21a8ca9ac 100644 --- a/src/panels/places/placesitem.h +++ b/src/panels/places/placesitem.h @@ -20,6 +20,7 @@ #ifndef PLACESITEM_H #define PLACESITEM_H +#include #include #include #include @@ -28,7 +29,6 @@ #include #include -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& current, + const QHash& 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 m_access; QPointer m_volume; QPointer m_disc; - PlacesItemStorageAccessListener* m_accessListener; + QPointer m_accessListener; + KBookmark m_bookmark; friend class PlacesItemStorageAccessListener; // Calls onAccessibilityChanged() }; diff --git a/src/panels/places/placesitemmodel.cpp b/src/panels/places/placesitemmodel.cpp index 8153387634..69236e9203 100644 --- a/src/panels/places/placesitemmodel.cpp +++ b/src/panels/places/placesitemmodel.cpp @@ -23,16 +23,6 @@ #include "placesitemmodel.h" -#ifdef HAVE_NEPOMUK - #include - #include - #include - #include - #include - #include - #include -#endif - #include #include #include @@ -53,6 +43,10 @@ #include #include +#ifdef HAVE_NEPOMUK + #include +#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 placesItems; QList 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& 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() { diff --git a/src/panels/places/placesitemmodel.h b/src/panels/places/placesitemmodel.h index ae111a58dd..14d0accc1a 100644 --- a/src/panels/places/placesitemmodel.h +++ b/src/panels/places/placesitemmodel.h @@ -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 diff --git a/src/panels/places/placespanel.cpp b/src/panels/places/placespanel.cpp index 979ef25a64..0ddb05bf70 100644 --- a/src/panels/places/placespanel.cpp +++ b/src/panels/places/placespanel.cpp @@ -38,6 +38,7 @@ #include #include #include +#include "placesitem.h" #include "placesitemeditdialog.h" #include "placesitemlistgroupheader.h" #include "placesitemlistwidget.h" @@ -46,6 +47,15 @@ #include #include +#ifdef HAVE_NEPOMUK + #include + #include + #include + #include + #include + #include +#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(); 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(); if (!url.isEmpty()) { - emit placeMiddleClicked(url); + emit placeMiddleClicked(convertedUrl(url)); } } void PlacesPanel::slotItemContextMenuRequested(int index, const QPointF& pos) { - const QHash 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("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(); 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" diff --git a/src/panels/places/placespanel.h b/src/panels/places/placespanel.h index 7baefd9e8c..780d3f09f1 100644 --- a/src/panels/places/placespanel.h +++ b/src/panels/places/placespanel.h @@ -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;