8#include "runnerresultsmodel_p.h"
12#include <KRunner/RunnerManager>
14#include "resultsmodel.h"
22 setRunnerManager(configGroup.
isValid() && stateConfigGroup.
isValid() ?
new RunnerManager(configGroup, stateConfigGroup,
this) :
new RunnerManager(
this));
28 return m_matches.value(category).value(idx.
row());
40 for (
const auto &match : matches) {
42 newCategories.
insert(category);
47 auto it = m_categories.
begin();
48 while (it != m_categories.end()) {
49 const int categoryNumber = int(std::distance(m_categories.begin(), it));
52 beginRemoveRows(
QModelIndex(), categoryNumber, categoryNumber);
53 m_matches.remove(*it);
54 it = m_categories.erase(it);
63 for (
auto it = m_categories.constBegin(); it != m_categories.constEnd(); ++it) {
64 Q_ASSERT(newCategories.
contains(*it));
66 const int categoryNumber = int(std::distance(m_categories.constBegin(), it));
67 const QModelIndex categoryIdx = index(categoryNumber, 0);
71 auto oldCategoryIt = m_matches.find(*it);
72 Q_ASSERT(oldCategoryIt != m_matches.end());
74 auto &oldMatchesInCategory = *oldCategoryIt;
75 const auto newMatchesInCategory = newMatches.value(*it);
77 Q_ASSERT(!oldMatchesInCategory.isEmpty());
78 Q_ASSERT(!newMatches.isEmpty());
82 bool emitDataChanged =
false;
84 const int oldCount = oldMatchesInCategory.count();
85 const int newCount = newMatchesInCategory.count();
87 const int countCeiling = qMin(oldCount, newCount);
89 for (
int i = 0; i < countCeiling; ++i) {
90 auto &oldMatch = oldMatchesInCategory[i];
91 if (oldMatch != newMatchesInCategory.at(i)) {
92 oldMatch = newMatchesInCategory.at(i);
93 emitDataChanged =
true;
98 if (emitDataChanged) {
99 Q_EMIT dataChanged(index(0, 0, categoryIdx), index(countCeiling - 1, 0, categoryIdx));
103 if (newCount > oldCount) {
104 beginInsertRows(categoryIdx, oldCount, newCount - 1);
105 oldMatchesInCategory = newMatchesInCategory;
107 }
else if (newCount < oldCount) {
108 beginRemoveRows(categoryIdx, newCount, oldCount - 1);
109 oldMatchesInCategory = newMatchesInCategory;
114 newCategories.
remove(*it);
118 if (!newCategories.
isEmpty()) {
119 beginInsertRows(
QModelIndex(), m_categories.count(), m_categories.count() + newCategories.
count() - 1);
121 for (
const QString &newCategory : newCategories) {
122 const auto matchesInNewCategory = newMatches.value(newCategory);
124 m_matches[newCategory] = matchesInNewCategory;
125 m_categories.append(newCategory);
131 Q_ASSERT(m_categories.count() == m_matches.count());
133 m_hasMatches = !m_matches.isEmpty();
135 Q_EMIT matchesChanged();
138QString RunnerResultsModel::queryString()
const
140 return m_queryString;
143void RunnerResultsModel::setQueryString(
const QString &queryString,
const QString &runner)
146 if (m_queryString.trimmed() == queryString.
trimmed() && m_prevRunner == runner) {
150 m_prevRunner = runner;
151 m_queryString = queryString;
152 m_hasMatches =
false;
156 m_manager->launchQuery(queryString, runner);
158 Q_EMIT queryStringChanged(queryString);
161void RunnerResultsModel::clear()
164 m_manager->matchSessionComplete();
168 if (!m_queryString.isEmpty()) {
169 m_queryString.clear();
170 Q_EMIT queryStringChanged(m_queryString);
174 m_categories.clear();
178 m_hasMatches =
false;
181bool RunnerResultsModel::run(
const QModelIndex &idx)
185 return m_manager->run(match);
190bool RunnerResultsModel::runAction(
const QModelIndex &idx,
int actionNumber)
197 if (actionNumber < 0 || actionNumber >=
match.actions().count()) {
201 return m_manager->run(match,
match.actions().at(actionNumber));
204int RunnerResultsModel::columnCount(
const QModelIndex &parent)
const
210int RunnerResultsModel::rowCount(
const QModelIndex &parent)
const
212 if (parent.
column() > 0) {
217 return m_categories.count();
225 return m_matches.value(category).count();
235 if (
int(index.
internalId() - 1) >= m_categories.count()) {
240 if (!
match.isValid()) {
248 if (!
match.iconName().isEmpty()) {
249 return match.iconName();
252 case ResultsModel::CategoryRelevanceRole:
253 return match.categoryRelevance();
254 case ResultsModel::RelevanceRole:
255 return match.relevance();
256 case ResultsModel::IdRole:
258 case ResultsModel::EnabledRole:
259 return match.isEnabled();
260 case ResultsModel::CategoryRole:
261 return match.matchCategory();
262 case ResultsModel::SubtextRole:
263 return match.subtext();
264 case ResultsModel::UrlsRole:
266 case ResultsModel::MultiLineRole:
267 return match.isMultiLine();
268 case ResultsModel::ActionsRole: {
269 const auto actions =
match.actions();
270 QVariantList actionsList;
271 actionsList.reserve(actions.size());
279 case ResultsModel::QueryMatchRole:
287 if (index.
row() >= m_categories.count()) {
293 return m_categories.at(index.
row());
295 case ResultsModel::FavoriteIndexRole: {
296 for (
int i = 0; i < rowCount(index); ++i) {
298 if (
match.isValid()) {
300 int idx = m_favoriteIds.indexOf(
id);
305 return m_favoriteIds.size();
307 case ResultsModel::FavoriteCountRole:
308 return m_favoriteIds.size();
310 case ResultsModel::CategoryRelevanceRole: {
312 for (
int i = 0; i < rowCount(index); ++i) {
313 const int type = this->index(i, 0, index).
data(ResultsModel::CategoryRelevanceRole).
toInt();
314 if (type > highestType) {
320 case ResultsModel::RelevanceRole: {
321 qreal highestRelevance = 0.0;
322 for (
int i = 0; i < rowCount(index); ++i) {
323 const qreal relevance = this->index(i, 0, index).
data(ResultsModel::RelevanceRole).
toReal();
324 if (relevance > highestRelevance) {
325 highestRelevance = relevance;
328 return highestRelevance;
337 if (row < 0 || column != 0) {
343 const auto matches = m_matches.value(category);
344 if (row < matches.count()) {
345 return createIndex(row, column,
int(parent.
row() + 1));
351 if (row < m_categories.count()) {
352 return createIndex(row, column,
nullptr);
361 return createIndex(
int(child.
internalId() - 1), 0,
nullptr);
374 disconnect(m_manager);
377 connect(m_manager, &RunnerManager::matchesChanged,
this, &RunnerResultsModel::onMatchesChanged);
378 connect(m_manager, &RunnerManager::requestUpdateQueryString,
this, &RunnerResultsModel::queryStringChangeRequested);
379 Q_EMIT runnerManagerChanged();
383#include "moc_runnerresultsmodel_p.cpp"
This class represents an action that will be shown next to a match.
A match returned by an AbstractRunner in response to a given RunnerContext.
The RunnerManager class decides what installed runners are runnable, and their ratings.
Type type(const QSqlDatabase &db)
KCOREADDONS_EXPORT Result match(QStringView pattern, QStringView str)
Category category(StandardShortcut id)
QVariant data(int role) const const
quintptr internalId() const const
bool isValid() const const
bool contains(const QSet< T > &other) const const
qsizetype count() const const
iterator insert(const T &value)
bool isEmpty() const const
bool remove(const T &value)
bool isEmpty() const const
QString trimmed() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QVariant fromValue(T &&value)
int toInt(bool *ok) const const
qreal toReal(bool *ok) const const