diff --git a/abstractrunner.cpp b/abstractrunner.cpp index ce360dbdf..2056400ba 100644 --- a/abstractrunner.cpp +++ b/abstractrunner.cpp @@ -199,10 +199,10 @@ const QMutex& AbstractRunner::bigLock() const return Private::bigLock; } -void AbstractRunner::exec(Plasma::SearchMatch *action) +void AbstractRunner::exec(const Plasma::SearchContext *search, const Plasma::SearchMatch *action) { if (d->script) { - return d->script->exec(action); + return d->script->exec(search, action); } } diff --git a/abstractrunner.h b/abstractrunner.h index c6495980a..4c9c64111 100644 --- a/abstractrunner.h +++ b/abstractrunner.h @@ -149,7 +149,7 @@ class PLASMA_EXPORT AbstractRunner : public QObject * Called whenever an exact or possible match associated with this * runner is triggered. */ - virtual void exec(Plasma::SearchMatch *action); + virtual void exec(const Plasma::SearchContext *context, const Plasma::SearchMatch *action); /** * The nominal speed of the runner. diff --git a/scripting/runnerscript.cpp b/scripting/runnerscript.cpp index 0aa6db530..1d71b632f 100644 --- a/scripting/runnerscript.cpp +++ b/scripting/runnerscript.cpp @@ -51,12 +51,12 @@ AbstractRunner* RunnerScript::runner() const return d->runner; } -void RunnerScript::match(Plasma::SearchContext *search) +void RunnerScript::match(const Plasma::SearchContext *search) { Q_UNUSED(search) } -void RunnerScript::exec(Plasma::SearchMatch *action) +void RunnerScript::exec(const Plasma::SearchContext *search, const Plasma::SearchMatch *action) { Q_UNUSED(action) } diff --git a/scripting/runnerscript.h b/scripting/runnerscript.h index b8b621d97..cd8ca5b36 100644 --- a/scripting/runnerscript.h +++ b/scripting/runnerscript.h @@ -60,13 +60,13 @@ public: * SearchContext::addInformationalMatch, SearchContext::addExactMatch, and * SearchContext::addPossibleMatch. */ - virtual void match(Plasma::SearchContext *search); + void match(const Plasma::SearchContext *search); /** * Called whenever an exact or possible match associated with this * runner is triggered. */ - virtual void exec(Plasma::SearchMatch *action); + void exec(const Plasma::SearchContext *search, const Plasma::SearchMatch *action); private: class Private; diff --git a/searchcontext.cpp b/searchcontext.cpp index 204aef8a8..12ad1e3ea 100644 --- a/searchcontext.cpp +++ b/searchcontext.cpp @@ -48,39 +48,13 @@ class SearchContext::Private ~Private() { - clearMatches(); + qDeleteAll(matches); + matches.clear(); delete completer; } void resetState() { - lockForWrite(); - qDeleteAll(info); - info.clear(); - qDeleteAll(exact); - exact.clear(); - qDeleteAll(possible); - possible.clear(); - type = SearchContext::UnknownType; - term.clear(); - mimetype.clear(); - - if (completer) { - completer->clear(); - } - unlock(); - } - - void clearMatches() - { - lockForWrite(); - qDeleteAll(info); - info.clear(); - qDeleteAll(exact); - exact.clear(); - qDeleteAll(possible); - possible.clear(); - unlock(); } KCompletion* completionObject() @@ -114,9 +88,7 @@ class SearchContext::Private } QReadWriteLock lock; - QList info; - QList exact; - QList possible; + QList matches; QString term; QString mimetype; SearchContext::Type type; @@ -149,8 +121,28 @@ SearchContext::~SearchContext() void SearchContext::resetSearchTerm(const QString &term) { - d->resetState(); + d->lockForWrite(); + QList matches = d->matches; + + d->matches.clear(); + d->type = SearchContext::UnknownType; + d->term.clear(); + d->mimetype.clear(); + + if (d->completer) { + d->completer->clear(); + } + + d->unlock(); + emit matchesChanged(); + + // in case someone is still holding on to the Matches + // when we emit the matchesChanged() signal, we don't + // delete the matches until after the signal is handled. + // a bit safer. + qDeleteAll(matches); + setSearchTerm(term); } @@ -256,101 +248,81 @@ void SearchContext::addStringCompletions(const QStringList &completion) d->unlock(); } -SearchMatch* SearchContext::addInformationalMatch(AbstractRunner *runner) +bool SearchContext::addMatches(const QString& term, const QList &matches) { - Q_ASSERT(d->policy == SingleConsumer); - SearchMatch *action = new SearchMatch(this, runner); - action->setType(SearchMatch::InformationalMatch); - d->info.append(action); - return action; + if (searchTerm() != term || matches.isEmpty()) { + return false; + } + + d->lockForWrite(); + d->matches << matches; + d->unlock(); + + // TODO: perhaps queue this signal so that it is only emitted after a small delay? + // currently we do this in krunner's Interface class, but it would probably + // be better to move that detail to SearchContext so that other apps that + // use SearchContext can also benefit from it + emit matchesChanged(); + return true; } -SearchMatch* SearchContext::addExactMatch(AbstractRunner *runner) -{ - Q_ASSERT(d->policy == SingleConsumer); - SearchMatch *action = new SearchMatch(this, runner); - action->setType(SearchMatch::ExactMatch); - d->exact.append(action); - return action; -} - -SearchMatch* SearchContext::addPossibleMatch(AbstractRunner *runner) -{ - Q_ASSERT(d->policy == SingleConsumer); - SearchMatch *action = new SearchMatch(this, runner); - action->setType(SearchMatch::PossibleMatch); - d->possible.append(action); - return action; -} - -bool SearchContext::addMatches( const QString& term, const QList &exactMatches, - const QList &possibleMatches, - const QList &informationalMatches ) +bool SearchContext::addMatch(const QString &term, SearchMatch *match) { if (searchTerm() != term) { return false; } - if (exactMatches.isEmpty() && - possibleMatches.isEmpty() && - informationalMatches.isEmpty()) { - return false; - } - d->lockForWrite(); - d->exact << exactMatches; - d->possible << possibleMatches; - d->info << informationalMatches; + d->matches << match; d->unlock(); emit matchesChanged(); + return true; } bool SearchContext::addMatchesTo(SearchContext &other) { - d->lockForRead(); - if (other.addMatches(d->term, d->exact, d->possible, d->info)) { + //NOTE: we have addMatchesTo instead of the more 'natural' addMatches + // because we can get away with one write lock on the local object + // this way, otherwise we'd need to lock once for searchTerm, once + // for matches() and again for clearMatches() (2 read, one write) + d->lockForWrite(); + + const bool success = other.addMatches(d->term, d->matches); + + if (success) { // the matches no longer belong to this SearchContext, // so remove them from the data - d->exact.clear(); - d->possible.clear(); - d->info.clear(); - d->unlock(); - return true; + d->matches.clear(); } d->unlock(); - return false; + return success; } -QList SearchContext::informationalMatches() const +QList SearchContext::matches() const { d->lockForRead(); - QList matches = d->info; - d->unlock(); - return matches; -} - -QList SearchContext::exactMatches() const -{ - d->lockForRead(); - QList matches = d->exact; - d->unlock(); - return matches; -} - -QList SearchContext::possibleMatches() const -{ - d->lockForRead(); - QList matches = d->possible; + QList matches = d->matches; d->unlock(); return matches; } void SearchContext::clearMatches() { - d->clearMatches(); + d->lockForWrite(); + + QList matches = d->matches; + d->matches.clear(); + d->unlock(); + emit matchesChanged(); + + // in case someone is still holding on to the Matches + // when we emit the matchesChanged() signal, we don't + // delete the matches until after the signal is handled. + // a bit safer. + qDeleteAll(matches); } } diff --git a/searchcontext.h b/searchcontext.h index 7976d79e0..b99f80dcd 100644 --- a/searchcontext.h +++ b/searchcontext.h @@ -117,50 +117,28 @@ class PLASMA_EXPORT SearchContext : public QObject void addStringCompletions(const QStringList& completions); /** - * Adds an action that represents a match to the current search term. - * This action is informational in nature and does not represent an actionable - * match. - * - * If string data is added to the action using QAction::setData(), that - * string may be used in user interfaces when the item is selected. - * - * This may only be used from SingleConsumer SearchContexts, and - * does not result in the matchesChanged() signal being emitted. - * @see addMatches - */ - SearchMatch* addInformationalMatch(AbstractRunner *runner); - - /** - * Adds an action that represents an exact match to the current search term. - * - * This may only be used from SingleConsumer SearchContexts, and - * does not result in the matchesChanged() signal being emitted. - * @see addMatches - */ - SearchMatch* addExactMatch(AbstractRunner *runner); - - /** - * Adds an action that represents a possible match to the current search term. - * - * This may only be used from SingleConsumer SearchContexts, and - * does not result in the matchesChanged() signal being emitted. - * @see addMatches - */ - SearchMatch* addPossibleMatch(AbstractRunner *runner); - - /** - * Appends lists of matches to the lists for exact, possible, and - * informational matches. The SearchContext takes over ownership of the - * items on successful addition. + * Appends lists of matches to the list of matches. + * The SearchContext takes over ownership of the matches on successful addition. * * This method is thread safe and causes the matchesChanged() signal to be emitted. * * @return true if matches were added, false if matches were e.g. outdated */ - bool addMatches(const QString& term, - const QList &exactMatches, - const QList &possibleMatches, - const QList &informationalMatches); + bool addMatches(const QString& term, const QList &matches); + + /** + * Appends a match to the existing list of matches. + * The SearchContext takes over ownership of the match on successful addition. + * + * If you are going to be adding multiple matches, it is better to use + * addMatches instead. + * + * @arg term the search term that this match was generated for + * @arg match the match to add + * + * @return true if the match was added, false otherwise. + */ + bool addMatch(const QString &term, SearchMatch *match); /** * Takes the matches from this SearchContext and adds to them another. @@ -173,22 +151,9 @@ class PLASMA_EXPORT SearchContext : public QObject bool addMatchesTo(SearchContext &other); /** - * Retrieves all available informational matches for the current - * search term. + * Retrieves all available matches for the current search term. */ - QList informationalMatches() const; - - /** - * Retrieves all available exact matches for the current - * search term. - */ - QList exactMatches() const; - - /** - * Retrieves all available possible matches for the current - * search term. - */ - QList possibleMatches() const; + QList matches() const; /** * Determines type of query diff --git a/searchmatch.cpp b/searchmatch.cpp index 22854d589..846f82bd5 100644 --- a/searchmatch.cpp +++ b/searchmatch.cpp @@ -34,14 +34,12 @@ namespace Plasma class SearchMatch::Private { public: - Private(const SearchContext *s, AbstractRunner *r) + Private(AbstractRunner *r) : runner(r), type(SearchMatch::ExactMatch), enabled(true), relevance(.7) { - searchTerm = s->searchTerm(); - mimetype = s->mimetype(); } QString searchTerm; @@ -56,8 +54,8 @@ class SearchMatch::Private }; -SearchMatch::SearchMatch(const SearchContext *search, AbstractRunner *runner) - : d(new Private(search, runner)) +SearchMatch::SearchMatch(AbstractRunner *runner) + : d(new Private(runner)) { } @@ -85,12 +83,12 @@ QString SearchMatch::mimetype() const { return d->mimetype; } - +/* QString SearchMatch::searchTerm() const { return d->searchTerm; } - +*/ void SearchMatch::setRelevance(qreal relevance) { d->relevance = qMax(qreal(0.0), qMin(qreal(1.0), relevance)); @@ -151,18 +149,14 @@ bool SearchMatch::operator<(const SearchMatch& other) const return d->relevance < other.d->relevance; } -void SearchMatch::exec(const SearchContext *context) +void SearchMatch::exec(const SearchContext *context) const { Q_ASSERT(context); - //kDebug() << "reseting the terms to the most recent status" << context; - d->searchTerm = context->searchTerm(); - d->mimetype = context->mimetype(); - //kDebug() << "we have" << d->searchTerm << d->mimetype; if (d->runner) { //TODO: this could be dangerous if the runner is deleted behind our backs. - d->runner->exec(this); + d->runner->exec(context, this); } } diff --git a/searchmatch.h b/searchmatch.h index a00d5d3a8..0fb1df3ef 100644 --- a/searchmatch.h +++ b/searchmatch.h @@ -43,7 +43,14 @@ class PLASMA_EXPORT SearchMatch such as the answer to a question or calculation*/, ExactMatch = 100 /**< An exact matcht to the query */}; - SearchMatch(const SearchContext *search, AbstractRunner *runner); + /** + * Constructs a PossibleMatch associated with a given SearchContext + * and runner. + * + * @arg search the SearchContext this match belongs to + * @arg runner the runner this match belongs to + */ + explicit SearchMatch(AbstractRunner *runner); ~SearchMatch(); /** @@ -52,7 +59,7 @@ class PLASMA_EXPORT SearchMatch void setType(Type type); /** - * The type of action this is. Defaults to ExactMatch. + * The type of action this is. Defaults to PossibleMatch. */ Type type() const; @@ -71,7 +78,7 @@ class PLASMA_EXPORT SearchMatch /** * The search term that triggered this action */ - QString searchTerm() const; + //QString searchTerm() const; /** * Sets the relevance of this action for the search @@ -106,9 +113,7 @@ class PLASMA_EXPORT SearchMatch bool operator<(const SearchMatch& other) const; - //Pending a better solution, changing this to public -// public Q_SLOTS: - void exec(const SearchContext *context); + void exec(const SearchContext *context) const; private: class Private;