diff --git a/src/resultwatcher.h b/src/resultwatcher.h index 13e14cf..957a24d 100644 --- a/src/resultwatcher.h +++ b/src/resultwatcher.h @@ -1,127 +1,127 @@ /* * 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_RESULTWATCHER #define KACTIVITIES_STATS_RESULTWATCHER #include #include "query.h" #include "resultset.h" namespace KActivities { namespace Stats { class ResultWatcherPrivate; /** * A very thin class that sends signals when new resources matching * a predefined query are available. */ class KACTIVITIESSTATS_EXPORT ResultWatcher: public QObject { Q_OBJECT public: explicit ResultWatcher(Query query, QObject *parent = nullptr); - ~ResultWatcher(); + ~ResultWatcher() override; Q_SIGNALS: /** * Emitted when a result has been added or updated. This either means * a new resource has appeared in the result set, or that * a previously existing one has some of the attributes changed. * @param result new data for the resource defined by result.resource */ void resultScoreUpdated(const QString &resource, double score, uint lastUpdate, uint firstUpdate); /** * Emitted when a result has been added or updated. This either means * a new resource has appeared in the result set, or that * a previously existing one has some of the attributes changed. * @param result new data for the resource defined by result.resource */ void resultRemoved(const QString &resource); /** * Emitted when a result has been linked to the activity */ void resultLinked(const QString &resource); /** * Emitted when a result has been linked to the activity */ void resultUnlinked(const QString &resource); /** * Emitted when the title of a resource has been changed. * @param resource URL of the resource that has a new title * @param title new title of the resource * @note This signal will be emitted even for the resources that * do not match the specified query. This is because the class is * lightweight, and it does not keep track of which resources match * the query to be able to filter this signal. */ void resourceTitleChanged(const QString &resource, const QString &title); /** * Emitted when the mimetype of a resource has been changed. * @param resource URL of the resource that has a new mimetype * @param mimetype new mimetype of the resource * @note This signal will be emitted even for the resources that * do not match the specified query. This is because the class is * lightweight, and it does not keep track of which resources match * the query to be able to filter this signal. */ void resourceMimetypeChanged(const QString &resource, const QString &mimetype); /** * Emitted when the client should forget about all the results it * knew about and reload them. This can happen when the user clears * the history, or when there are more significant changes to the data. */ void resultsInvalidated(); public: void linkToActivity(const QUrl &resource, const Terms::Activity &activity = Terms::Activity(QStringList()), const Terms::Agent &agent = Terms::Agent(QStringList())); void unlinkFromActivity(const QUrl &resource, const Terms::Activity &activity = Terms::Activity(QStringList()), const Terms::Agent &agent = Terms::Agent(QStringList())); private: ResultWatcherPrivate *const d; }; } // namespace Stats } // namespace KActivities #endif // KACTIVITIES_STATS_RESULTWATCHER diff --git a/tests/model/window.cpp b/tests/model/window.cpp index 365d786..bd98fe7 100644 --- a/tests/model/window.cpp +++ b/tests/model/window.cpp @@ -1,361 +1,361 @@ /* * 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. */ #include "window.h" #include "ui_window.h" #include "modeltest.h" #include #include #include #include #include #include #include #include #include #include #include #include namespace KAStats = KActivities::Stats; using namespace KAStats; using namespace KAStats::Terms; class Delegate: public QItemDelegate { public: void paint(QPainter *painter, const QStyleOptionViewItem &option, - const QModelIndex &index) const Q_DECL_OVERRIDE + const QModelIndex &index) const override { painter->save(); const QString title = index.data(ResultModel::TitleRole).toString(); QRect titleRect = painter->fontMetrics().boundingRect(title); int lineHeight = titleRect.height(); // Header background titleRect.moveTop(option.rect.top()); titleRect.setWidth(option.rect.width()); painter->fillRect(titleRect.x(), titleRect.y(), titleRect.width(), titleRect.height() + 16, QColor(32, 32, 32)); // Painting the title painter->setPen(QColor(255,255,255)); titleRect.moveTop(titleRect.top() + 8); titleRect.setLeft(8); titleRect.setWidth(titleRect.width() - 8); painter->drawText(titleRect, index.data(ResultModel::TitleRole).toString()); // Painting the score painter->drawText(titleRect, "Score: " + QString::number(index.data(ResultModel::ScoreRole).toDouble()), QTextOption(Qt::AlignRight)); // Painting the moification and creation times titleRect.moveTop(titleRect.bottom() + 16); painter->fillRect(titleRect.x() - 4, titleRect.y() - 8, titleRect.width() + 8, titleRect.height() + 8 + lineHeight, QColor(64, 64, 64)); titleRect.moveTop(titleRect.top() - 4); painter->drawText(titleRect, index.data(ResultModel::ResourceRole).toString() ); auto firstUpdate = QDateTime::fromTime_t(index.data(ResultModel::FirstUpdateRole).toUInt()); auto lastUpdate = QDateTime::fromTime_t(index.data(ResultModel::LastUpdateRole).toUInt()); titleRect.moveTop(titleRect.top() + lineHeight); painter->drawText(titleRect, "Modified: " + lastUpdate.toString() ); painter->drawText(titleRect, "Created: " + firstUpdate.toString(), QTextOption(Qt::AlignRight)); painter->restore(); } QSize sizeHint(const QStyleOptionViewItem &option, - const QModelIndex &index) const Q_DECL_OVERRIDE + const QModelIndex &index) const override { Q_UNUSED(option); Q_UNUSED(index); return QSize(0, 100); } }; Window::Window() : ui(new Ui::MainWindow()) , model(nullptr) , activities(new KActivities::Consumer()) { ui->setupUi(this); ui->viewResults->setItemDelegate(new Delegate()); // ui->viewResults->setUniformItemSizes(true); // ui->viewResults->setGridSize(QSize(200, 100)); while (activities->serviceStatus() == KActivities::Consumer::Unknown) { QCoreApplication::processEvents(); } connect(ui->buttonUpdate, SIGNAL(clicked()), this, SLOT(updateResults())); connect(ui->buttonReloadRowCount, SIGNAL(clicked()), this, SLOT(updateRowCount())); for (const auto &activity : (QStringList() << ":current" << ":any" << ":global") + activities->activities()) { ui->comboActivity->addItem(activity); } foreach (const auto &arg, QCoreApplication::arguments()) { if (arg == "--used") { ui->radioSelectUsedResources->setChecked(true); } else if (arg == "--linked") { ui->radioSelectLinkedResources->setChecked(true); } else if (arg == "--combined") { ui->radioSelectAllResources->setChecked(true); } else if (arg.startsWith("--activity=")) { ui->comboActivity->setCurrentText(arg.split("=")[1]); } else if (arg.startsWith("--agent=")) { ui->textAgent->setText(arg.split("=")[1]); } else if (arg.startsWith("--mimetype=")) { ui->textMimetype->setText(arg.split("=")[1]); } else if (arg == "--select") { updateResults(); } } auto redisplayAction = new QAction(this); addAction(redisplayAction); redisplayAction->setShortcut(Qt::Key_F5); connect(redisplayAction, SIGNAL(triggered()), this, SLOT(updateResults())); // loading the presets const auto recentQueryBase = UsedResources | RecentlyUsedFirst | Agent::any() | Type::any() | Activity::current(); const auto popularQueryBase = UsedResources | HighScoredFirst | Agent::any() | Type::any() | Activity::current(); presets = { { "kicker-favorites", LinkedResources | Agent { "org.kde.plasma.favorites.applications", "org.kde.plasma.favorites.documents", "org.kde.plasma.favorites.contacts" } | Type::any() | Activity::current() | Activity::global() | Limit(15) }, { "kicker-recent-apps-n-docs", recentQueryBase | Url::startsWith("applications:") | Url::file() | Limit(30) }, { "kicker-recent-apps", recentQueryBase | Url::startsWith("applications:") | Limit(15) }, { "kicker-recent-docs", recentQueryBase | Url::file() | Limit(15) }, { "kicker-popular-apps-n-docs", popularQueryBase | Url::startsWith("applications:") | Url::file() | Limit(30) }, { "kicker-popular-apps", popularQueryBase | Url::startsWith("applications:") | Limit(15) }, { "kicker-popular-docs", popularQueryBase | Url::file() | Limit(15) } }; ui->comboPreset->addItem("Choose a preset", QVariant()); for (const auto& presetId: presets.keys()) { ui->comboPreset->addItem(presetId, presetId); } connect(ui->comboPreset, SIGNAL(activated(int)), this, SLOT(selectPreset())); } Window::~Window() { } void Window::selectPreset() { const auto id = ui->comboPreset->currentData().toString(); if (id.isEmpty()) return; const auto &query = presets[id]; qDebug() << "Id: " << id; qDebug() << "Query: " << query; // Selection qDebug() << "\tSelection:" << query.selection(); ui->radioSelectUsedResources->setChecked(query.selection() == UsedResources); ui->radioSelectLinkedResources->setChecked(query.selection() == LinkedResources); ui->radioSelectAllResources->setChecked(query.selection() == AllResources); // Ordering qDebug() << "\tOrdering:" << query.ordering(); ui->radioOrderHighScoredFirst->setChecked(query.ordering() == HighScoredFirst); ui->radioOrderRecentlyUsedFirst->setChecked(query.ordering() == RecentlyUsedFirst); ui->radioOrderRecentlyCreatedFirst->setChecked(query.ordering() == RecentlyCreatedFirst); ui->radioOrderByUrl->setChecked(query.ordering() == OrderByUrl); ui->radioOrderByTitle->setChecked(query.ordering() == OrderByTitle); // Agents qDebug() << "\tAgents:" << query.agents(); ui->textAgent->setText(query.agents().join(',')); // Types qDebug() << "\tTypes:" << query.types(); ui->textMimetype->setText(query.types().join(',')); // Activities qDebug() << "\tActivities:" << query.activities(); ui->comboActivity->setEditText(query.activities().join(',')); // Url filters qDebug() << "\tUrl filters:" << query.urlFilters(); ui->textUrl->setText(query.urlFilters().join(',')); // Limit ui->spinLimitCount->setValue(query.limit()); updateResults(); } void Window::updateRowCount() { ui->labelRowCount->setText(QString::number( ui->viewResults->model()->rowCount() )); } void Window::setQuery(const KActivities::Stats::Query &query) { qDebug() << "Updating the results"; ui->viewResults->setModel(nullptr); // Log results using boost::accumulate; ui->textLog->setText( accumulate(ResultSet(query), QString(), [] (const QString &acc, const ResultSet::Result &result) { return acc + result.title() + " (" + result.resource() + ")\n"; }) ); model.reset(new ResultModel(query)); if (QCoreApplication::arguments().contains("--enable-model-test")) { modelTest.reset(); modelTest.reset(new ModelTest(new ResultModel(query))); } ui->viewResults->setModel(model.get()); // QML auto context = ui->viewResultsQML->rootContext(); ui->viewResultsQML->setResizeMode(QQuickWidget::SizeRootObjectToView); context->setContextProperty("kamdmodel", model.get()); ui->viewResultsQML->setSource(QUrl("qrc:/main.qml")); } void Window::updateResults() { qDebug() << "Updating the results"; setQuery( // What should we get ( ui->radioSelectUsedResources->isChecked() ? UsedResources : ui->radioSelectLinkedResources->isChecked() ? LinkedResources : AllResources ) | // How we should order it ( ui->radioOrderHighScoredFirst->isChecked() ? HighScoredFirst : ui->radioOrderRecentlyUsedFirst->isChecked() ? RecentlyUsedFirst : ui->radioOrderRecentlyCreatedFirst->isChecked() ? RecentlyCreatedFirst : ui->radioOrderByUrl->isChecked() ? OrderByUrl : OrderByTitle ) | // Which agents? Agent(ui->textAgent->text().split(',')) | // Which mime? Type(ui->textMimetype->text().split(',')) | // Which activities? Activity(ui->comboActivity->currentText().split(',')) | // And URL filters Url(ui->textUrl->text().split(',', QString::SkipEmptyParts)) | // And how many items Limit(ui->spinLimitCount->value()) ); } diff --git a/tests/model/window.h b/tests/model/window.h index 1aa191d..f3c3683 100644 --- a/tests/model/window.h +++ b/tests/model/window.h @@ -1,63 +1,63 @@ /* * 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. */ #pragma once #include #include #include #include class ModelTest; namespace Ui { class MainWindow; } namespace KActivities { class Consumer; namespace Stats { class ResultModel; } } class Window: public QMainWindow { Q_OBJECT public: Window(); - ~Window(); + ~Window() override; private Q_SLOTS: void updateResults(); void updateRowCount(); void selectPreset(); private: void setQuery(const KActivities::Stats::Query &query); std::unique_ptr ui; std::unique_ptr model; std::unique_ptr modelTest; std::unique_ptr activities; QMap presets; };