diff --git a/src/common/specialvalues.h b/src/common/specialvalues.h index 35cf23b..5e13035 100644 --- a/src/common/specialvalues.h +++ b/src/common/specialvalues.h @@ -1,37 +1,39 @@ /* * Copyright (C) 2015 Ivan Cukic * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * or (at your option) any later version, as published by the Free * Software Foundation * * 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 SPECIALVALUES_H #define SPECIALVALUES_H #include #define GLOBAL_ACTIVITY_TAG QStringLiteral(":global") #define ANY_ACTIVITY_TAG QStringLiteral(":any") #define CURRENT_ACTIVITY_TAG QStringLiteral(":current") #define GLOBAL_AGENT_TAG QStringLiteral(":global") #define ANY_AGENT_TAG QStringLiteral(":any") #define CURRENT_AGENT_TAG QStringLiteral(":current") #define ANY_TYPE_TAG QStringLiteral(":any") +#define FILES_TYPE_TAG QStringLiteral(":files") +#define DIRECTORIES_TYPE_TAG QStringLiteral(":directories") #endif // SPECIALVALUES_H diff --git a/src/resultset.cpp b/src/resultset.cpp index 81c38e4..d204452 100644 --- a/src/resultset.cpp +++ b/src/resultset.cpp @@ -1,573 +1,577 @@ /* * Copyright (C) 2015, 2016 Ivan Cukic * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. * If not, see . */ #include "resultset.h" // Qt #include #include #include // Local #include +#include #include #include #include "kactivities-stats-logsettings.h" // Boost and STL #include #include #include #include // KActivities #include "activitiessync_p.h" #define DEBUG_QUERIES 0 namespace KActivities { namespace Stats { using namespace Terms; class ResultSet_ResultPrivate { public: QString resource; QString title; QString mimetype; double score; uint lastUpdate; uint firstUpdate; ResultSet::Result::LinkStatus linkStatus; QStringList linkedActivities; }; ResultSet::Result::Result() : d(new ResultSet_ResultPrivate()) { } ResultSet::Result::Result(Result &&result) : d(result.d) { result.d = nullptr; } ResultSet::Result::Result(const Result &result) : d(new ResultSet_ResultPrivate(*result.d)) { } ResultSet::Result &ResultSet::Result::operator=(Result result) { std::swap(d, result.d); return *this; } ResultSet::Result::~Result() { delete d; } #define CREATE_GETTER_AND_SETTER(Type, Name, Set) \ Type ResultSet::Result::Name() const \ { \ return d->Name; \ } \ \ void ResultSet::Result::Set(Type Name) \ { \ d->Name = Name; \ } CREATE_GETTER_AND_SETTER(QString, resource, setResource) CREATE_GETTER_AND_SETTER(QString, title, setTitle) CREATE_GETTER_AND_SETTER(QString, mimetype, setMimetype) CREATE_GETTER_AND_SETTER(double, score, setScore) CREATE_GETTER_AND_SETTER(uint, lastUpdate, setLastUpdate) CREATE_GETTER_AND_SETTER(uint, firstUpdate, setFirstUpdate) CREATE_GETTER_AND_SETTER(ResultSet::Result::LinkStatus, linkStatus, setLinkStatus) CREATE_GETTER_AND_SETTER(QStringList, linkedActivities, setLinkedActivities) #undef CREATE_GETTER_AND_SETTER class ResultSetPrivate { public: Common::Database::Ptr database; QSqlQuery query; Query queryDefinition; mutable ActivitiesSync::ConsumerPtr activities; void initQuery() { if (!database || query.isActive()) { return; } auto selection = queryDefinition.selection(); query = database->execQuery(replaceQueryParameters( selection == LinkedResources ? linkedResourcesQuery() : selection == UsedResources ? usedResourcesQuery() : selection == AllResources ? allResourcesQuery() : QString())); if (query.lastError().isValid()) { qCWarning(KACTIVITIES_STATS_LOG) << "[Error at ResultSetPrivate::initQuery]: " << query.lastError(); } } QString agentClause(const QString &agent) const { if (agent == QLatin1String(":any")) return QStringLiteral("1"); return QStringLiteral("agent = '") + ( agent == QLatin1String(":current") ? QCoreApplication::instance()->applicationName() : agent ) + QStringLiteral("'"); } QString activityClause(const QString &activity) const { if (activity == QLatin1String(":any")) return QStringLiteral("1"); return QStringLiteral("activity = '") + ( activity == QLatin1String(":current") ? ActivitiesSync::currentActivity(activities) : activity ) + QStringLiteral("'"); } inline QString starPattern(const QString &pattern) const { return Common::parseStarPattern(pattern, QStringLiteral("%"), [] (QString str) { return str.replace(QLatin1String("%"), QLatin1String("\\%")).replace(QLatin1String("_"), QLatin1String("\\_")); }); } QString urlFilterClause(const QString &urlFilter) const { if (urlFilter == QLatin1String("*")) return QStringLiteral("1"); return QStringLiteral("resource LIKE '") + Common::starPatternToLike(urlFilter) + QStringLiteral("' ESCAPE '\\'"); } QString mimetypeClause(const QString &mimetype) const { - if (mimetype == QLatin1String(":any") || mimetype == QLatin1String("*")) return QStringLiteral("1"); + if (mimetype == ANY_TYPE_TAG || mimetype == QLatin1String("*")) return QStringLiteral("1"); + + else if (mimetype == FILES_TYPE_TAG) return QStringLiteral("mimetype != 'inode/directory' AND mimetype != ''"); + else if (mimetype == DIRECTORIES_TYPE_TAG) return QStringLiteral("mimetype = 'inode/directory'"); return QStringLiteral("mimetype LIKE '") + Common::starPatternToLike(mimetype) + QStringLiteral("' ESCAPE '\\'"); } QString dateClause(QDate start, QDate end) const { if (end.isNull()) { // only date filtering return QStringLiteral("DATE(re.start, 'unixepoch') = '") + start.toString(Qt::ISODate) + QStringLiteral("' "); } else { // date range filtering return QStringLiteral("DATE(re.start, 'unixepoch') >= '") + start.toString(Qt::ISODate) + QStringLiteral("' AND DATE(re.start, 'unixepoch') <= '") + end.toString(Qt::ISODate) + QStringLiteral("' "); } } QString resourceEventJoinClause() const { return QStringLiteral(R"sql( LEFT JOIN ResourceEvent re ON from_table.targettedResource = re.targettedResource AND from_table.usedActivity = re.usedActivity AND from_table.initiatingAgent = re.initiatingAgent )sql"); } /** * Transforms the input list's elements with the f member method, * and returns the resulting list */ template inline QStringList transformedList(const QStringList &input, F f) const { using namespace std::placeholders; QStringList result; boost::transform(input, std::back_inserter(result), std::bind(f, this, _1)); return result; } QString limitOffsetSuffix() const { QString result; const int limit = queryDefinition.limit(); if (limit > 0) { result += QStringLiteral(" LIMIT ") + QString::number(limit); const int offset = queryDefinition.offset(); if (offset > 0) { result += QStringLiteral(" OFFSET ") + QString::number(offset); } } return result; } inline QString replaceQueryParameters(const QString &_query) const { // ORDER BY column auto ordering = queryDefinition.ordering(); QString orderingColumn = QStringLiteral("linkStatus DESC, ") + ( ordering == HighScoredFirst ? QStringLiteral("score DESC,") : ordering == RecentlyCreatedFirst ? QStringLiteral("firstUpdate DESC,") : ordering == RecentlyUsedFirst ? QStringLiteral("lastUpdate DESC,") : ordering == OrderByTitle ? QStringLiteral("title ASC,") : QString() ); // WHERE clause for filtering on agents QStringList agentsFilter = transformedList( queryDefinition.agents(), &ResultSetPrivate::agentClause); // WHERE clause for filtering on activities QStringList activitiesFilter = transformedList( queryDefinition.activities(), &ResultSetPrivate::activityClause); // WHERE clause for filtering on resource URLs QStringList urlFilter = transformedList( queryDefinition.urlFilters(), &ResultSetPrivate::urlFilterClause); // WHERE clause for filtering on resource mime QStringList mimetypeFilter = transformedList( queryDefinition.types(), &ResultSetPrivate::mimetypeClause); QString dateColumn = QStringLiteral("1"), resourceEventJoin; // WHERE clause for access date filtering and ResourceEvent table Join if (!queryDefinition.dateStart().isNull()) { dateColumn = dateClause(queryDefinition.dateStart(), queryDefinition.dateEnd()); resourceEventJoin = resourceEventJoinClause(); } auto queryString = _query; queryString.replace(QStringLiteral("ORDER_BY_CLAUSE"), QStringLiteral("ORDER BY $orderingColumn resource ASC")) .replace(QStringLiteral("LIMIT_CLAUSE"), limitOffsetSuffix()); return kamd::utils::debug_and_return(DEBUG_QUERIES, "Query: ", queryString .replace(QLatin1String("$orderingColumn"), orderingColumn) .replace(QLatin1String("$agentsFilter"), agentsFilter.join(QStringLiteral(" OR "))) .replace(QLatin1String("$activitiesFilter"), activitiesFilter.join(QStringLiteral(" OR "))) .replace(QLatin1String("$urlFilter"), urlFilter.join(QStringLiteral(" OR "))) .replace(QLatin1String("$mimetypeFilter"), mimetypeFilter.join(QStringLiteral(" OR "))) .replace(QLatin1String("$resourceEventJoin"), resourceEventJoin) .replace(QLatin1String("$dateFilter"), dateColumn) ); } static const QString &linkedResourcesQuery() { // TODO: We need to correct the scores based on the time that passed // since the cache was last updated, although, for this query, // scores are not that important. static const QString queryString = QStringLiteral(R"sql( SELECT from_table.targettedResource as resource , SUM(rsc.cachedScore) as score , MIN(rsc.firstUpdate) as firstUpdate , MAX(rsc.lastUpdate) as lastUpdate , from_table.usedActivity as activity , from_table.initiatingAgent as agent , COALESCE(ri.title, from_table.targettedResource) as title , ri.mimetype as mimetype , 2 as linkStatus FROM ResourceLink from_table LEFT JOIN ResourceScoreCache rsc ON from_table.targettedResource = rsc.targettedResource AND from_table.usedActivity = rsc.usedActivity AND from_table.initiatingAgent = rsc.initiatingAgent LEFT JOIN ResourceInfo ri ON from_table.targettedResource = ri.targettedResource $resourceEventJoin WHERE ($agentsFilter) AND ($activitiesFilter) AND ($urlFilter) AND ($mimetypeFilter) AND ($dateFilter) GROUP BY resource, title ORDER_BY_CLAUSE LIMIT_CLAUSE )sql") ; return queryString; } static const QString &usedResourcesQuery() { // TODO: We need to correct the scores based on the time that passed // since the cache was last updated static const QString queryString = QStringLiteral(R"sql( SELECT from_table.targettedResource as resource , SUM(from_table.cachedScore) as score , MIN(from_table.firstUpdate) as firstUpdate , MAX(from_table.lastUpdate) as lastUpdate , from_table.usedActivity as activity , from_table.initiatingAgent as agent , COALESCE(ri.title, from_table.targettedResource) as title , ri.mimetype as mimetype , 1 as linkStatus FROM ResourceScoreCache from_table LEFT JOIN ResourceInfo ri ON from_table.targettedResource = ri.targettedResource $resourceEventJoin WHERE ($agentsFilter) AND ($activitiesFilter) AND ($urlFilter) AND ($mimetypeFilter) AND ($dateFilter) GROUP BY resource, title ORDER_BY_CLAUSE LIMIT_CLAUSE )sql") ; return queryString; } static const QString &allResourcesQuery() { // TODO: We need to correct the scores based on the time that passed // since the cache was last updated, although, for this query, // scores are not that important. static const QString queryString = QStringLiteral(R"sql( WITH LinkedResourcesResults AS ( SELECT from_table.targettedResource as resource , rsc.cachedScore as score , rsc.firstUpdate as firstUpdate , rsc.lastUpdate as lastUpdate , from_table.usedActivity as activity , from_table.initiatingAgent as agent , 2 as linkStatus FROM ResourceLink from_table LEFT JOIN ResourceScoreCache rsc ON from_table.targettedResource = rsc.targettedResource AND from_table.usedActivity = rsc.usedActivity AND rl.initiatingAgent = rsc.initiatingAgent $resourceEventJoin WHERE ($agentsFilter) AND ($activitiesFilter) AND ($urlFilter) AND ($mimetypeFilter) AND ($dateFilter) ), UsedResourcesResults AS ( SELECT from_table.targettedResource as resource , from_table.cachedScore as score , from_table.firstUpdate as firstUpdate , from_table.lastUpdate as lastUpdate , from_table.usedActivity as activity , from_table.initiatingAgent as agent , 0 as linkStatus FROM ResourceScoreCache from_table $resourceEventJoin WHERE ($agentsFilter) AND ($activitiesFilter) AND ($urlFilter) AND ($mimetypeFilter) AND ($dateFilter) ), CollectedResults AS ( SELECT * FROM LinkedResourcesResults UNION SELECT * FROM UsedResourcesResults WHERE resource NOT IN (SELECT resource FROM LinkedResourcesResults) ) SELECT resource , SUM(score) as score , MIN(firstUpdate) as firstUpdate , MAX(lastUpdate) as lastUpdate , activity , agent , COALESCE(ri.title, resource) as title , ri.mimetype as mimetype , linkStatus FROM CollectedResults cr LEFT JOIN ResourceInfo ri ON cr.resource = ri.targettedResource GROUP BY resource, title ORDER_BY_CLAUSE LIMIT_CLAUSE )sql") ; return queryString; } ResultSet::Result currentResult() const { ResultSet::Result result; if (!database || !query.isActive()) return result; result.setResource(query.value(QStringLiteral("resource")).toString()); result.setTitle(query.value(QStringLiteral("title")).toString()); result.setMimetype(query.value(QStringLiteral("mimetype")).toString()); result.setScore(query.value(QStringLiteral("score")).toDouble()); result.setLastUpdate(query.value(QStringLiteral("lastUpdate")).toUInt()); result.setFirstUpdate(query.value(QStringLiteral("firstUpdate")).toUInt()); result.setLinkStatus( static_cast(query.value(QStringLiteral("linkStatus")).toUInt())); auto linkedActivitiesQuery = database->createQuery(); linkedActivitiesQuery.prepare(QStringLiteral(R"sql( SELECT usedActivity FROM ResourceLink WHERE targettedResource = :resource )sql")); linkedActivitiesQuery.bindValue(QStringLiteral(":resource"), result.resource()); linkedActivitiesQuery.exec(); QStringList linkedActivities; for (const auto &item: linkedActivitiesQuery) { linkedActivities << item[0].toString(); } result.setLinkedActivities(linkedActivities); // qDebug(KACTIVITIES_STATS_LOG) << result.resource() << "linked to activities" << result.linkedActivities(); return result; } }; ResultSet::ResultSet(Query queryDefinition) : d(new ResultSetPrivate()) { using namespace Common; d->database = Database::instance(Database::ResourcesDatabase, Database::ReadOnly); if (!(d->database)) { qCWarning(KACTIVITIES_STATS_LOG) << "KActivities ERROR: There is no database. This probably means " "that you do not have the Activity Manager running, or that " "something else is broken on your system. Recent documents and " "alike will not work!"; } d->queryDefinition = queryDefinition; d->initQuery(); } ResultSet::ResultSet(ResultSet &&source) : d(nullptr) { std::swap(d, source.d); } ResultSet::ResultSet(const ResultSet &source) : d(new ResultSetPrivate(*source.d)) { } ResultSet &ResultSet::operator= (ResultSet source) { std::swap(d, source.d); return *this; } ResultSet::~ResultSet() { delete d; } ResultSet::Result ResultSet::at(int index) const { if (!d->query.isActive()) return Result(); d->query.seek(index); return d->currentResult(); } } // namespace Stats } // namespace KActivities #include "resultset_iterator.cpp" diff --git a/src/terms.cpp b/src/terms.cpp index 7c842c1..1f90102 100644 --- a/src/terms.cpp +++ b/src/terms.cpp @@ -1,173 +1,175 @@ /* * Copyright (C) 2015, 2016 Ivan Cukic * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. * If not, see . */ #include "terms.h" #include "common/specialvalues.h" #include namespace KActivities { namespace Stats { // Term classes #define IMPLEMENT_TERM_CONSTRUCTORS(TYPE) \ Terms::TYPE::TYPE(QStringList values) \ : values(values) \ {} \ \ Terms::TYPE::TYPE(QString value) \ : values(QStringList() << value) \ {} #define IMPLEMENT_SPECIAL_TERM_VALUE(TYPE, VALUE_NAME, VALUE) \ Terms::TYPE Terms::TYPE::VALUE_NAME() \ { \ return Terms::TYPE(VALUE); \ } IMPLEMENT_TERM_CONSTRUCTORS(Type) -IMPLEMENT_SPECIAL_TERM_VALUE(Type, any, ANY_TYPE_TAG) +IMPLEMENT_SPECIAL_TERM_VALUE(Type, any, ANY_TYPE_TAG) +IMPLEMENT_SPECIAL_TERM_VALUE(Type, files, FILES_TYPE_TAG) +IMPLEMENT_SPECIAL_TERM_VALUE(Type, directories, DIRECTORIES_TYPE_TAG) IMPLEMENT_TERM_CONSTRUCTORS(Agent) IMPLEMENT_SPECIAL_TERM_VALUE(Agent, any, ANY_AGENT_TAG) IMPLEMENT_SPECIAL_TERM_VALUE(Agent, global, GLOBAL_AGENT_TAG) IMPLEMENT_SPECIAL_TERM_VALUE(Agent, current, CURRENT_AGENT_TAG) IMPLEMENT_TERM_CONSTRUCTORS(Activity) IMPLEMENT_SPECIAL_TERM_VALUE(Activity, any, ANY_ACTIVITY_TAG) IMPLEMENT_SPECIAL_TERM_VALUE(Activity, global, GLOBAL_ACTIVITY_TAG) IMPLEMENT_SPECIAL_TERM_VALUE(Activity, current, CURRENT_ACTIVITY_TAG) IMPLEMENT_TERM_CONSTRUCTORS(Url) IMPLEMENT_SPECIAL_TERM_VALUE(Url, localFile, QStringLiteral("/*")) IMPLEMENT_SPECIAL_TERM_VALUE(Url, file, QStringList() << QStringLiteral("/*") << QStringLiteral("smb:*") << QStringLiteral("fish:*") << QStringLiteral("sftp:*") << QStringLiteral("ftp:*")) #undef IMPLEMENT_TERM_CONSTRUCTORS #undef IMPLEMENT_SPECIAL_TERM_VALUE Terms::Limit::Limit(int value) : value(value) { } Terms::Limit Terms::Limit::all() { return Limit(0); } Terms::Offset::Offset(int value) : value(value) { } Terms::Date::Date(QDate value) : start(value) { } Terms::Date::Date(QDate start, QDate end) : start(start), end(end) { } Terms::Date Terms::Date::today() { return Date(QDate::currentDate()); } Terms::Date Terms::Date::yesterday() { auto date = QDate::currentDate(); return Date(date.addDays(-1)); } Terms::Date Terms::Date::currentWeek() { auto start = QDate::currentDate(); auto end = start.addDays(-7); return Date(start, end); } Terms::Date Terms::Date::previousWeek() { auto start = QDate::currentDate().addDays(-7); auto end = start.addDays(-7); return Date(start, end); } Terms::Date Terms::Date::fromString(QString string) { auto splitted = string.split(QStringLiteral(",")); if (splitted.count() == 2) { // date range case auto start = QDate::fromString(splitted[0], Qt::ISODate); auto end = QDate::fromString(splitted[1], Qt::ISODate); return Date(start, end); } else { auto date = QDate::fromString(string, Qt::ISODate); return Date(date); } } Terms::Url Terms::Url::startsWith(const QString &prefix) { return Url(prefix + QStringLiteral("*")); } Terms::Url Terms::Url::contains(const QString &infix) { return Url(QStringLiteral("*") + infix + QStringLiteral("*")); } } // namespace Stats } // namespace KActivities namespace KAStats = KActivities::Stats; #define QDEBUG_TERM_OUT(TYPE, OUT) \ QDebug operator<<(QDebug dbg, const KAStats::Terms::TYPE &_) \ { \ using namespace KAStats::Terms; \ dbg.nospace() << #TYPE << ": " << (OUT); \ return dbg; \ } QDEBUG_TERM_OUT(Order, _ == HighScoredFirst ? "HighScore" : _ == RecentlyUsedFirst ? "RecentlyUsed" : _ == RecentlyCreatedFirst ? "RecentlyCreated" : "Alphabetical" ) QDEBUG_TERM_OUT(Select, _ == LinkedResources ? "LinkedResources" : _ == UsedResources ? "UsedResources" : "AllResources" ) QDEBUG_TERM_OUT(Type, _.values) QDEBUG_TERM_OUT(Agent, _.values) QDEBUG_TERM_OUT(Activity, _.values) QDEBUG_TERM_OUT(Url, _.values) QDEBUG_TERM_OUT(Limit, _.value) QDEBUG_TERM_OUT(Offset, _.value) QDEBUG_TERM_OUT(Date, _.end.isNull() ? _.start.toString(Qt::ISODate) : _.start.toString(Qt::ISODate) + QStringLiteral(",") + _.end.toString(Qt::ISODate)) #undef QDEBUG_TERM_OUT diff --git a/src/terms.h b/src/terms.h index 6ea3614..2e40801 100644 --- a/src/terms.h +++ b/src/terms.h @@ -1,274 +1,282 @@ /* * Copyright (C) 2015, 2016 Ivan Cukic * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. * If not, see . */ #ifndef KACTIVITIES_STATS_TERMS_H #define KACTIVITIES_STATS_TERMS_H #include #ifdef Q_COMPILER_INITIALIZER_LISTS #include #endif #include #include #include #include "kactivitiesstats_export.h" namespace KActivities { namespace Stats { /** * @namespace KActivities::Stats::Terms * Provides enums and strucss to use.for building queries with @c Query. */ namespace Terms { /** * Enumerator specifying the ordering in which the * results of the query should be listed */ enum KACTIVITIESSTATS_EXPORT Order { HighScoredFirst, ///< Resources with the highest scores first RecentlyUsedFirst, ///< Recently used resources first RecentlyCreatedFirst, ///< Recently created resources first OrderByUrl, ///< Order by uri, alphabetically OrderByTitle ///< Order by uri, alphabetically }; /** * Which resources should be returned */ enum KACTIVITIESSTATS_EXPORT Select { LinkedResources, ///< Resources linked to an activity, or globally UsedResources, ///< Resources that have been accessed AllResources ///< Combined set of accessed and linked resources }; /** * @struct KActivities::Stats::Terms::Limit terms.h * * How many items do you need? */ struct KACTIVITIESSTATS_EXPORT Limit { Limit(int value); static Limit all(); int value; }; /** * @struct KActivities::Stats::Terms::Offset terms.h * * How many items to skip? * This can be specified only if limit is also set to a finite value. */ struct KACTIVITIESSTATS_EXPORT Offset { Offset(int value); int value; }; /** * @struct KActivities::Stats::Terms::Type terms.h * * Term to filter the resources according to their types */ struct KACTIVITIESSTATS_EXPORT Type { /** * Show resources of any type */ static Type any(); + /** + * Show non-directory resources + */ + static Type files(); + /** + * Show directory resources aka folders + */ + static Type directories(); #ifdef Q_COMPILER_INITIALIZER_LISTS inline Type(std::initializer_list types) : values(types) { } #endif Type(QStringList types); Type(QString type); const QStringList values; }; /** * @struct KActivities::Stats::Terms::Agent terms.h * * Term to filter the resources according the agent (application) which * accessed it */ struct KACTIVITIESSTATS_EXPORT Agent { /** * Show resources accessed/linked by any application */ static Agent any(); /** * Show resources not tied to a specific agent */ static Agent global(); /** * Show resources accessed/linked by the current application */ static Agent current(); #ifdef Q_COMPILER_INITIALIZER_LISTS inline Agent(std::initializer_list agents) : values(agents) { } #endif Agent(QStringList agents); Agent(QString agent); const QStringList values; }; /** * @struct KActivities::Stats::Terms::Activity terms.h * * Term to filter the resources according the activity in which they * were accessed */ struct KACTIVITIESSTATS_EXPORT Activity { /** * Show resources accessed in / linked to any activity */ static Activity any(); /** * Show resources linked to all activities */ static Activity global(); /** * Show resources linked to all activities */ static Activity current(); #ifdef Q_COMPILER_INITIALIZER_LISTS inline Activity(std::initializer_list activities) : values(activities) { } #endif Activity(QStringList activities); Activity(QString activity); const QStringList values; }; /** * @struct KActivities::Stats::Terms::Url terms.h * * Url filtering. */ struct KACTIVITIESSTATS_EXPORT Url { /** * Show only resources that start with the specified prefix */ static Url startsWith(const QString &prefix); /** * Show resources that contain the specified infix */ static Url contains(const QString &infix); /** * Show local files */ static Url localFile(); /** * Show local files, smb, fish, ftp and stfp */ static Url file(); #ifdef Q_COMPILER_INITIALIZER_LISTS inline Url(std::initializer_list urlPatterns) : values(urlPatterns) { } #endif Url(QStringList urlPatterns); Url(QString urlPattern); const QStringList values; }; /** * @struct KActivities::Stats::Terms::Date terms.h * * On which start access date do you want to filter ? */ struct KACTIVITIESSTATS_EXPORT Date { Date(QDate value); Date(QDate start, QDate end); static Date today(); static Date yesterday(); static Date currentWeek(); static Date previousWeek(); static Date fromString(QString); QDate start, end; }; } // namespace Terms } // namespace Stats } // namespace KActivities KACTIVITIESSTATS_EXPORT QDebug operator<<(QDebug dbg, const KActivities::Stats::Terms::Order &order); KACTIVITIESSTATS_EXPORT QDebug operator<<(QDebug dbg, const KActivities::Stats::Terms::Select &select); KACTIVITIESSTATS_EXPORT QDebug operator<<(QDebug dbg, const KActivities::Stats::Terms::Type &type); KACTIVITIESSTATS_EXPORT QDebug operator<<(QDebug dbg, const KActivities::Stats::Terms::Agent &agent); KACTIVITIESSTATS_EXPORT QDebug operator<<(QDebug dbg, const KActivities::Stats::Terms::Activity &activity); KACTIVITIESSTATS_EXPORT QDebug operator<<(QDebug dbg, const KActivities::Stats::Terms::Url &url); KACTIVITIESSTATS_EXPORT QDebug operator<<(QDebug dbg, const KActivities::Stats::Terms::Limit &limit); KACTIVITIESSTATS_EXPORT QDebug operator<<(QDebug dbg, const KActivities::Stats::Terms::Offset &offset); KACTIVITIESSTATS_EXPORT QDebug operator<<(QDebug dbg, const KActivities::Stats::Terms::Date &date); #endif // KACTIVITIES_STATS_TERMS_H