* eliminate the three search lists and have just one

* remove add*Match since they broke the pattern of usage (who owns the match? do you have to add it again? etc..)
* add addMatch to compliment addMatches for those runners that just ever have one match
* make the default SearchMatch type Possible rather than Exact (making Exact and Informational the exceptions, which matches usage patterns)
* const'ify the API a bit better

generally more performant, lower memory usage and clearer API having seen what is beign done in the runners. also makes it a bit easier to turn the Matches into a qt model

svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=776931
This commit is contained in:
Aaron J. Seigo 2008-02-19 03:59:21 +00:00
parent 2eae59175c
commit 2954087e8d
8 changed files with 111 additions and 175 deletions

View File

@ -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);
}
}

View File

@ -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.

View File

@ -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)
}

View File

@ -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;

View File

@ -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<SearchMatch *> info;
QList<SearchMatch *> exact;
QList<SearchMatch *> possible;
QList<SearchMatch *> 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<SearchMatch*> 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<SearchMatch*> &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<SearchMatch *> &exactMatches,
const QList<SearchMatch *> &possibleMatches,
const QList<SearchMatch *> &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<SearchMatch *> SearchContext::informationalMatches() const
QList<SearchMatch *> SearchContext::matches() const
{
d->lockForRead();
QList<SearchMatch *> matches = d->info;
d->unlock();
return matches;
}
QList<SearchMatch *> SearchContext::exactMatches() const
{
d->lockForRead();
QList<SearchMatch *> matches = d->exact;
d->unlock();
return matches;
}
QList<SearchMatch *> SearchContext::possibleMatches() const
{
d->lockForRead();
QList<SearchMatch *> matches = d->possible;
QList<SearchMatch *> matches = d->matches;
d->unlock();
return matches;
}
void SearchContext::clearMatches()
{
d->clearMatches();
d->lockForWrite();
QList<SearchMatch*> 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);
}
}

View File

@ -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<SearchMatch *> &exactMatches,
const QList<SearchMatch *> &possibleMatches,
const QList<SearchMatch *> &informationalMatches);
bool addMatches(const QString& term, const QList<SearchMatch *> &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<SearchMatch *> informationalMatches() const;
/**
* Retrieves all available exact matches for the current
* search term.
*/
QList<SearchMatch *> exactMatches() const;
/**
* Retrieves all available possible matches for the current
* search term.
*/
QList<SearchMatch *> possibleMatches() const;
QList<SearchMatch *> matches() const;
/**
* Determines type of query

View File

@ -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);
}
}

View File

@ -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;