diff --git a/abstractrunner.cpp b/abstractrunner.cpp index f40c235bf..9715f0086 100644 --- a/abstractrunner.cpp +++ b/abstractrunner.cpp @@ -18,6 +18,7 @@ */ #include "abstractrunner.h" +#include "searchcontext.h" #include #include @@ -43,6 +44,28 @@ AbstractRunner::~AbstractRunner() delete d; } +void AbstractRunner::performMatch( Plasma::SearchContext &globalContext ) +{ + Plasma::SearchContext localContext( 0, globalContext ); + //Keep track of global context list sizes so we know which pointers are our responsibility to delete + int exactEnd = localContext.exactMatches().count(); + int possibleEnd = localContext.possibleMatches().count(); + int infoEnd = localContext.informationalMatches().count(); + + match( &localContext ); + + QList exact = localContext.exactMatches().mid(exactEnd); + QList possible = localContext.possibleMatches().mid(possibleEnd); + QList info = localContext.informationalMatches().mid(infoEnd); + + //If matches were not added, delete items on the heap + if (!globalContext.addMatches(localContext.searchTerm(), exact, possible, info)) { + qDeleteAll(exact); + qDeleteAll(possible); + qDeleteAll(info); + } +} + bool AbstractRunner::hasMatchOptions() { return d->hasMatchOptions; diff --git a/abstractrunner.h b/abstractrunner.h index aad8790aa..80b5c7840 100644 --- a/abstractrunner.h +++ b/abstractrunner.h @@ -71,6 +71,8 @@ class PLASMA_EXPORT AbstractRunner : public QObject */ virtual void match(Plasma::SearchContext *search) = 0; + void performMatch(Plasma::SearchContext &globalContext); + /** * If the runner has options that the user can interact with to modify * what happens when exec or one of the actions created in fillMatches diff --git a/searchaction.cpp b/searchaction.cpp index 439b0d8b8..ea819aa6b 100644 --- a/searchaction.cpp +++ b/searchaction.cpp @@ -28,26 +28,31 @@ class SearchAction::Private { public: Private(SearchContext* s, AbstractRunner *r) - : search(s), + : /*search(s),*/ runner(r), type(SearchAction::ExactMatch), + enabled(true), relevance(1) { + searchTerm = s->searchTerm(); + mimetype = s->mimetype(); } - + QString searchTerm; SearchContext *search; AbstractRunner *runner; SearchAction::Type type; QString mimetype; + QString text; + QIcon icon; + QVariant data; + bool enabled; qreal relevance; }; SearchAction::SearchAction(SearchContext *search, AbstractRunner *runner) - : QAction(search), - d(new Private(search, runner)) + : d(new Private(search, runner)) { - connect(this, SIGNAL(triggered(bool)), this, SLOT(exec())); } SearchAction::~SearchAction() @@ -72,12 +77,12 @@ void SearchAction::setMimetype(const QString &mimetype) QString SearchAction::mimetype() const { - return d->mimetype.isEmpty() ? d->search->mimetype() : d->mimetype; + return d->mimetype;//.isEmpty() ? d->search->mimetype() : d->mimetype; } QString SearchAction::searchTerm() const { - return d->search->searchTerm(); + return d->searchTerm;//->searchTerm(); } void SearchAction::setRelevance(qreal relevance) @@ -95,6 +100,46 @@ AbstractRunner* SearchAction::runner() const return d->runner; } +void SearchAction::setText(const QString& text) +{ + d->text = text; +} + +void SearchAction::setData(const QVariant& data) +{ + d->data = data; +} + +void SearchAction::setIcon(const QIcon& icon) +{ + d->icon = icon; +} + +QVariant SearchAction::data() const +{ + return d->data; +} + +QString SearchAction::text() const +{ + return d->text; +} + +QIcon SearchAction::icon() const +{ + return d->icon; +} + +void SearchAction::setEnabled( bool enabled ) +{ + d->enabled = enabled; +} + +bool SearchAction::isEnabled() const +{ + return d->enabled; +} + bool SearchAction::operator<(const SearchAction& other) const { return d->relevance < other.d->relevance; @@ -102,8 +147,10 @@ bool SearchAction::operator<(const SearchAction& other) const void SearchAction::exec() { + if(d->runner) { //TODO: this could be dangerous if the runner is deleted behind our backs. - d->runner->exec(this); + d->runner->exec(this); + } } } diff --git a/searchaction.h b/searchaction.h index 82e14a498..e671f4d56 100644 --- a/searchaction.h +++ b/searchaction.h @@ -30,9 +30,9 @@ namespace Plasma class SearchContext; class AbstractRunner; -class PLASMA_EXPORT SearchAction : public QAction +class PLASMA_EXPORT SearchAction /*: public QAction*/ { - Q_OBJECT +// Q_OBJECT public: enum Type { InformationalMatch, @@ -90,9 +90,20 @@ class PLASMA_EXPORT SearchAction : public QAction */ AbstractRunner* runner() const; + void setText(const QString& text); + void setData(const QVariant& data); + void setIcon(const QIcon& icon); + void setEnabled(bool enable); + + QString text() const; + QVariant data() const; + QIcon icon() const; + bool isEnabled() const; + bool operator<(const SearchAction& other) const; - protected Q_SLOTS: + //Pending a better solution, changing this to public +// public Q_SLOTS: void exec(); private: diff --git a/searchcontext.cpp b/searchcontext.cpp index 65f5d9f37..157192167 100644 --- a/searchcontext.cpp +++ b/searchcontext.cpp @@ -19,6 +19,8 @@ #include "searchcontext.h" +#include + #include #include @@ -49,6 +51,7 @@ class SearchContext::Private void resetState() { + lock.lockForWrite(); qDeleteAll(info); info.clear(); qDeleteAll(exact); @@ -62,6 +65,19 @@ class SearchContext::Private if (completer) { completer->clear(); } + lock.unlock(); + } + + void clearMatches() + { + lock.lockForWrite(); + qDeleteAll(info); + info.clear(); + qDeleteAll(exact); + exact.clear(); + qDeleteAll(possible); + possible.clear(); + lock.unlock(); } KCompletion* completionObject() @@ -73,6 +89,22 @@ class SearchContext::Private return completer; } + void lockForRead() + { + lock.lockForRead(); + } + + void lockForWrite() + { + lock.lockForWrite(); + } + + void unlock() + { + lock.unlock(); + } + + QReadWriteLock lock; QList info; QList exact; QList possible; @@ -89,6 +121,20 @@ SearchContext::SearchContext(QObject *parent) { } +SearchContext::SearchContext(QObject *parent, const SearchContext &other) + : QObject( parent ), + d( new Private ) +{ + other.d->lockForRead(); + d->info = other.d->info; + d->possible = other.d->possible; + d->exact = other.d->exact; + d->term = other.d->term; + d->mimetype = other.d->mimetype; + d->type = other.d->type; + other.d->unlock(); +} + SearchContext::~SearchContext() { delete d; @@ -102,7 +148,16 @@ void SearchContext::setSearchTerm(const QString &term) return; } + d->lockForWrite(); d->term = term; + d->unlock(); + determineType(); +} + +void SearchContext::determineType() +{ + d->lockForWrite(); + QString term = d->term; int space = term.indexOf(' '); if (space > 0) { @@ -133,11 +188,15 @@ void SearchContext::setSearchTerm(const QString &term) d->type = NetworkLocation; } } + d->unlock(); } QString SearchContext::searchTerm() const { - return d->term; + d->lockForRead(); + QString term = d->term; + d->unlock(); + return term; } SearchContext::Type SearchContext::type() const @@ -152,27 +211,36 @@ QString SearchContext::mimetype() const KCompletion* SearchContext::completionObject() const { - return d->completionObject(); + d->lockForRead(); + KCompletion* comp = d->completionObject(); + d->unlock(); + return comp; } void SearchContext::addStringCompletion(const QString &completion) { + d->lockForWrite(); if (!d->completer) { + d->unlock(); // if the completion object isn't actually used, don't bother return; } d->completer->addItem(completion); + d->unlock(); } void SearchContext::addStringCompletions(const QStringList &completion) { + d->lockForWrite(); if (!d->completer) { + d->unlock(); // if the completion object isn't actually used, don't bother return; } d->completer->insertItems(completion); + d->unlock(); } SearchAction* SearchContext::addInformationalMatch(AbstractRunner *runner) @@ -199,19 +267,49 @@ SearchAction* SearchContext::addPossibleMatch(AbstractRunner *runner) return action; } +bool SearchContext::addMatches( const QString& term, const QList &exactMatches, + const QList &possibleMatches, + const QList &informationalMatches ) +{ + if (searchTerm() != term) { + return false; + } + d->lockForWrite(); + d->exact << exactMatches; + d->possible << possibleMatches; + d->info << informationalMatches; + d->unlock(); + emit matchesChanged(); + return true; +} + QList SearchContext::informationalMatches() const { - return d->info; + d->lockForRead(); + QList matches = d->info; + d->unlock(); + return matches; } QList SearchContext::exactMatches() const { - return d->exact; + d->lockForRead(); + QList matches = d->exact; + d->unlock(); + return matches; } QList SearchContext::possibleMatches() const { - return d->possible; + d->lockForRead(); + QList matches = d->possible; + d->unlock(); + return matches; +} + +void SearchContext::clearMatches() +{ + d->clearMatches(); } } diff --git a/searchcontext.h b/searchcontext.h index e32afff4b..869ea0830 100644 --- a/searchcontext.h +++ b/searchcontext.h @@ -55,6 +55,8 @@ class PLASMA_EXPORT SearchContext : public QObject explicit SearchContext(QObject *parent = 0); ~SearchContext(); + SearchContext(QObject *parent, const SearchContext& other); + /** * Sets the search term for this object. This clears all current * matches in the process. @@ -116,6 +118,14 @@ class PLASMA_EXPORT SearchContext : public QObject */ SearchAction* addPossibleMatch(AbstractRunner *runner); + /** + * Appends lists of matches to the lists for exact, possible, and informational matches + * @return true if matches were added, false if matches were outdated + */ + bool addMatches( const QString& term, const QList &exactMatches, + const QList &possibleMatches, + const QList &informationalMatches ); + /** * Retrieves all available informational matches for the current * search term. @@ -134,6 +144,19 @@ class PLASMA_EXPORT SearchContext : public QObject */ QList possibleMatches() const; + /** + * Determines type of query + */ + void determineType(); + + /** + * Clears matches + */ + void clearMatches(); + + signals: + void matchesChanged(); + private: class Private; Private * const d;