diff --git a/autotests/kfileplacesmodeltest.cpp b/autotests/kfileplacesmodeltest.cpp --- a/autotests/kfileplacesmodeltest.cpp +++ b/autotests/kfileplacesmodeltest.cpp @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include @@ -93,6 +95,12 @@ // Ensure we'll have a clean bookmark file to start QFile::remove(bookmarksFile()); + // disable baloo + KConfig config(QStringLiteral("baloofilerc")); + KConfigGroup basicSettings = config.group("Basic Settings"); + basicSettings.writeEntry("Indexing-Enabled", false); + config.sync(); + qRegisterMetaType(); const QString fakeHw = QFINDTESTDATA("fakecomputer.xml"); QVERIFY(!fakeHw.isEmpty()); diff --git a/src/filewidgets/kfileplacesmodel.cpp b/src/filewidgets/kfileplacesmodel.cpp --- a/src/filewidgets/kfileplacesmodel.cpp +++ b/src/filewidgets/kfileplacesmodel.cpp @@ -46,6 +46,9 @@ #include #include +#include +#include + #include #include #include @@ -59,7 +62,13 @@ class KFilePlacesModel::Private { public: - Private(KFilePlacesModel *self) : q(self), bookmarkManager(nullptr) {} + Private(KFilePlacesModel *self) + : q(self), + bookmarkManager(nullptr), + fileIndexingEnabled(isFileIndexingEnabled()) + { + } + ~Private() { qDeleteAll(items); @@ -74,6 +83,8 @@ Solid::Predicate predicate; KBookmarkManager *bookmarkManager; + bool fileIndexingEnabled; + void reloadAndSignal(); QList loadBookmarkList(); @@ -84,6 +95,10 @@ void _k_reloadBookmarks(); void _k_storageSetupDone(Solid::ErrorType error, QVariant errorData); void _k_storageTeardownDone(Solid::ErrorType error, QVariant errorData); + +private: + bool isFileIndexingEnabled() const; + bool isBalooUrl(const QUrl &url) const; }; KFilePlacesModel::KFilePlacesModel(QObject *parent) @@ -133,6 +148,39 @@ d->bookmarkManager->saveAs(file); } + // if baloo is enabled, add new urls even if the bookmark file is not empty + if (d->fileIndexingEnabled && + root.metaDataItem(QStringLiteral("withBaloo")) != QStringLiteral("true")) { + + root.setMetaDataItem(QStringLiteral("withBaloo"), QStringLiteral("true")); + KFilePlacesItem::createSystemBookmark(d->bookmarkManager, + QStringLiteral("Today"), I18N_NOOP2("KFile System Bookmarks", "Today"), + QUrl(QStringLiteral("timeline:/today")), QStringLiteral("go-jump-today")); + KFilePlacesItem::createSystemBookmark(d->bookmarkManager, + QStringLiteral("Yesterday"), I18N_NOOP2("KFile System Bookmarks", "Yesterday"), + QUrl(QStringLiteral("timeline:/yesterday")), QStringLiteral("view-calendar-day")); + KFilePlacesItem::createSystemBookmark(d->bookmarkManager, + QStringLiteral("This Month"), I18N_NOOP2("KFile System Bookmarks", "This Month"), + QUrl(QStringLiteral("timeline:/thismonth")), QStringLiteral("view-calendar-month")); + KFilePlacesItem::createSystemBookmark(d->bookmarkManager, + QStringLiteral("Last Month"), I18N_NOOP2("KFile System Bookmarks", "Last Month"), + QUrl(QStringLiteral("timeline:/lastmonth")), QStringLiteral("view-calendar-month")); + KFilePlacesItem::createSystemBookmark(d->bookmarkManager, + QStringLiteral("Documents"), I18N_NOOP2("KFile System Bookmarks", "Documents"), + QUrl(QStringLiteral("search:/documents")), QStringLiteral("folder-text")); + KFilePlacesItem::createSystemBookmark(d->bookmarkManager, + QStringLiteral("Images"), I18N_NOOP2("KFile System Bookmarks", "Images"), + QUrl(QStringLiteral("search:/images")), QStringLiteral("folder-images")); + KFilePlacesItem::createSystemBookmark(d->bookmarkManager, + QStringLiteral("Audio Files"), I18N_NOOP2("KFile System Bookmarks", "Audio Files"), + QUrl(QStringLiteral("search:/audio")), QStringLiteral("folder-sound")); + KFilePlacesItem::createSystemBookmark(d->bookmarkManager, + QStringLiteral("Videos"), I18N_NOOP2("KFile System Bookmarks", "Videos"), + QUrl(QStringLiteral("search:/videos")), QStringLiteral("folder-videos")); + + d->bookmarkManager->save(); + } + QString predicate(QString::fromLatin1("[[[[ StorageVolume.ignored == false AND [ StorageVolume.usage == 'FileSystem' OR StorageVolume.usage == 'Encrypted' ]]" " OR " "[ IS StorageAccess AND StorageDrive.driveType == 'Floppy' ]]" @@ -422,6 +470,13 @@ currentItems.clear(); } +bool KFilePlacesModel::Private::isBalooUrl(const QUrl &url) const +{ + const QString scheme = url.scheme(); + return ((scheme == QLatin1String("timeline")) || + (scheme == QLatin1String("search"))); +} + QList KFilePlacesModel::Private::loadBookmarkList() { QList items; @@ -433,15 +488,18 @@ while (!bookmark.isNull()) { QString udi = bookmark.metaDataItem(QStringLiteral("UDI")); QString appName = bookmark.metaDataItem(QStringLiteral("OnlyInApp")); + QUrl url = bookmark.url(); auto it = std::find(devices.begin(), devices.end(), udi); bool deviceAvailable = (it != devices.end()); if (it != devices.end()) { devices.erase(it); } - bool allowedHere = appName.isEmpty() || (appName == QCoreApplication::instance()->applicationName()); + bool allowedHere = appName.isEmpty() || (appName == QCoreApplication::instance()->applicationName()); + bool allowBalooUrl = isBalooUrl(url) ? fileIndexingEnabled : true; + + if ((allowBalooUrl && udi.isEmpty() && allowedHere) || deviceAvailable) { - if ((udi.isEmpty() && allowedHere) || deviceAvailable) { KFilePlacesItem *item; if (deviceAvailable) { item = new KFilePlacesItem(bookmarkManager, bookmark.address(), udi); @@ -906,4 +964,11 @@ } } +bool KFilePlacesModel::Private::isFileIndexingEnabled() const +{ + KConfig config(QStringLiteral("baloofilerc")); + KConfigGroup basicSettings = config.group("Basic Settings"); + return basicSettings.readEntry("Indexing-Enabled", true); +} + #include "moc_kfileplacesmodel.cpp" diff --git a/src/filewidgets/kfileplacesview.cpp b/src/filewidgets/kfileplacesview.cpp --- a/src/filewidgets/kfileplacesview.cpp +++ b/src/filewidgets/kfileplacesview.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include @@ -495,6 +496,13 @@ void fadeCapacityBar(const QModelIndex &index, FadeType fadeType); int sectionsCount() const; + // based on dolphin urls + QUrl convertUrl(const QUrl &url) const; + QUrl createTimelineUrl(const QUrl &url) const; + QUrl createSearchUrl(const QUrl &url) const; + QString timelineDateString(int year, int month, int day = 0) const; + QUrl searchUrlForType(const QString &type) const; + void _k_placeClicked(const QModelIndex &index); void _k_placeEntered(const QModelIndex &index); void _k_placeLeft(const QModelIndex &index); @@ -1086,7 +1094,7 @@ if (url.isValid()) { currentUrl = url; updateHiddenRows(); - emit q->urlChanged(url); + emit q->urlChanged(convertUrl(url)); if (showAll) { q->setShowAll(false); } @@ -1271,6 +1279,97 @@ return count; } +QUrl KFilePlacesView::Private::convertUrl(const QUrl &url) const +{ + QUrl newUrl = url; + if (url.scheme() == QLatin1String("timeline")) { + newUrl = createTimelineUrl(url); + } else if (url.scheme() == QLatin1String("search")) { + newUrl = createSearchUrl(url); + } + + return newUrl; +} + +QUrl KFilePlacesView::Private::createTimelineUrl(const QUrl &url) const +{ + // based on dolphin urls + const QString timelinePrefix = QStringLiteral("timeline:") + QLatin1Char('/'); + QUrl timelineUrl; + + const QString path = url.toDisplayString(QUrl::PreferLocalFile); + if (path.endsWith(QLatin1String("yesterday"))) { + const QDate date = QDate::currentDate().addDays(-1); + const int year = date.year(); + const int month = date.month(); + const int day = date.day(); + + timelineUrl = QUrl(timelinePrefix + timelineDateString(year, month) + + '/' + timelineDateString(year, month, day)); + } else if (path.endsWith(QLatin1String("thismonth"))) { + const QDate date = QDate::currentDate(); + timelineUrl = QUrl(timelinePrefix + timelineDateString(date.year(), date.month())); + } else if (path.endsWith(QLatin1String("lastmonth"))) { + const QDate date = QDate::currentDate().addMonths(-1); + timelineUrl = QUrl(timelinePrefix + timelineDateString(date.year(), date.month())); + } else { + Q_ASSERT(path.endsWith(QLatin1String("today"))); + timelineUrl = url; + } + + return timelineUrl; +} + +QString KFilePlacesView::Private::timelineDateString(int year, int month, int day) const +{ + const QString dateFormat("%1-%2%3"); + + QString date = dateFormat.arg(year).arg(month, 2, 10, QChar('0')); + if (day > 0) { + date = date.arg(QString("-%1").arg(day, 2, 10, QChar('0'))); + } else { + date = date.arg(""); + } + return date; +} + +QUrl KFilePlacesView::Private::createSearchUrl(const QUrl &url) const +{ + QUrl searchUrl; + + const QString path = url.toDisplayString(QUrl::PreferLocalFile); + + if (path.endsWith(QLatin1String("/documents"))) { + searchUrl = searchUrlForType(QStringLiteral("Document")); + } else if (path.endsWith(QLatin1String("/images"))) { + searchUrl = searchUrlForType(QStringLiteral("Image")); + } else if (path.endsWith(QLatin1String("/audio"))) { + searchUrl = searchUrlForType(QStringLiteral("Audio")); + } else if (path.endsWith(QLatin1String("/videos"))) { + searchUrl = searchUrlForType(QStringLiteral("Video")); + } + + return searchUrl; +} + + +QUrl KFilePlacesView::Private::searchUrlForType(const QString& type) const +{ + const QString jsonQuery(QStringLiteral("{\"dayFilter\": 0,\ + \"monthFilter\": 0, \ + \"yearFilter\": 0, \ + \"type\": [ \"%1\"]}")); + QUrl url; + url.setScheme(QStringLiteral("baloosearch")); + + QUrlQuery urlQuery; + urlQuery.addQueryItem(QStringLiteral("json"), jsonQuery.arg(type)); + url.setQuery(urlQuery); + + return url; +} + + void KFilePlacesView::Private::_k_placeClicked(const QModelIndex &index) { KFilePlacesModel *placesModel = qobject_cast(q->model());