Add adaptive search for KRunner
svn path=/trunk/KDE/kdelibs/; revision=967705
This commit is contained in:
parent
4ea997a9f1
commit
9b6304fcde
@ -98,7 +98,7 @@ QueryMatch::Type QueryMatch::type() const
|
||||
|
||||
void QueryMatch::setRelevance(qreal relevance)
|
||||
{
|
||||
d->relevance = qMax(qreal(0.0), qMin(qreal(1.0), relevance));
|
||||
d->relevance = qMax(qreal(0.0), relevance);
|
||||
}
|
||||
|
||||
qreal QueryMatch::relevance() const
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <QSharedData>
|
||||
|
||||
#include <kcompletion.h>
|
||||
#include <kconfiggroup.h>
|
||||
#include <kdebug.h>
|
||||
#include <kmimetype.h>
|
||||
#include <kshell.h>
|
||||
@ -157,6 +158,7 @@ class RunnerContextPrivate : public QSharedData
|
||||
|
||||
RunnerContextPrivate(const RunnerContextPrivate &p)
|
||||
: QSharedData(),
|
||||
launchCounts(p.launchCounts),
|
||||
type(RunnerContext::None),
|
||||
q(p.q)
|
||||
{
|
||||
@ -218,6 +220,7 @@ class RunnerContextPrivate : public QSharedData
|
||||
QReadWriteLock lock;
|
||||
QList<QueryMatch> matches;
|
||||
QMap<QString, const QueryMatch*> matchesById;
|
||||
QHash<QString, int> launchCounts;
|
||||
QString term;
|
||||
QString mimeType;
|
||||
RunnerContext::Type type;
|
||||
@ -323,7 +326,12 @@ bool RunnerContext::addMatches(const QString &term, const QList<QueryMatch> &mat
|
||||
}
|
||||
|
||||
LOCK_FOR_WRITE(this)
|
||||
foreach (const QueryMatch &match, matches) {
|
||||
foreach (QueryMatch match, matches) {
|
||||
// Give previously launched matches a slight boost in relevance
|
||||
if (int count = d->launchCounts.value(match.id())) {
|
||||
match.setRelevance(match.relevance() + 0.05 * count);
|
||||
}
|
||||
|
||||
d->matches.append(match);
|
||||
#ifndef NDEBUG
|
||||
if (d->matchesById.contains(match.id())) {
|
||||
@ -351,9 +359,16 @@ bool RunnerContext::addMatch(const QString &term, const QueryMatch &match)
|
||||
return false;
|
||||
}
|
||||
|
||||
QueryMatch m(match); // match must be non-const to modify relevance
|
||||
|
||||
LOCK_FOR_WRITE(this)
|
||||
d->matches.append(match);
|
||||
d->matchesById.insert(match.id(), &d->matches.at(d->matches.size() - 1));
|
||||
|
||||
if (int count = d->launchCounts.value(m.id())) {
|
||||
m.setRelevance(m.relevance() + 0.05 * count);
|
||||
}
|
||||
|
||||
d->matches.append(m);
|
||||
d->matchesById.insert(m.id(), &d->matches.at(d->matches.size() - 1));
|
||||
UNLOCK(this);
|
||||
//kDebug()<< "added match" << match->text();
|
||||
emit d->q->matchesChanged();
|
||||
@ -382,6 +397,39 @@ QueryMatch RunnerContext::match(const QString &id) const
|
||||
return QueryMatch(0);
|
||||
}
|
||||
|
||||
void RunnerContext::restore(const KConfigGroup &config)
|
||||
{
|
||||
QStringList cfgList = config.readEntry("LaunchCounts", QStringList());
|
||||
|
||||
QRegExp r("(\\d*) (.*)");
|
||||
foreach (QString entry, cfgList) {
|
||||
r.indexIn(entry);
|
||||
int count = r.cap(1).toInt();
|
||||
QString id = r.cap(2);
|
||||
d->launchCounts[id] = count;
|
||||
}
|
||||
}
|
||||
|
||||
void RunnerContext::save(KConfigGroup &config)
|
||||
{
|
||||
QStringList countList;
|
||||
|
||||
typedef QHash<QString, int>::const_iterator Iterator;
|
||||
Iterator end = d->launchCounts.constEnd();
|
||||
for (Iterator i = d->launchCounts.constBegin(); i != end; ++i) {
|
||||
countList << QString("%2 %1").arg(i.key()).arg(i.value());
|
||||
}
|
||||
|
||||
config.writeEntry("LaunchCounts", countList);
|
||||
config.sync();
|
||||
}
|
||||
|
||||
void RunnerContext::run(const QueryMatch &match)
|
||||
{
|
||||
++d->launchCounts[match.id()];
|
||||
match.run(*this);
|
||||
}
|
||||
|
||||
} // Plasma namespace
|
||||
|
||||
#include "runnercontext.moc"
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <plasma/plasma_export.h>
|
||||
|
||||
class KCompletion;
|
||||
class KConfigGroup;
|
||||
|
||||
namespace Plasma
|
||||
{
|
||||
@ -163,6 +164,33 @@ class PLASMA_EXPORT RunnerContext : public QObject
|
||||
*/
|
||||
QueryMatch match(const QString &id) const;
|
||||
|
||||
/**
|
||||
* Sets the launch counts for the associated match ids
|
||||
*
|
||||
* If a runner adds a match to this context, the context will check if the
|
||||
* match id has been launched before and increase the matches relevance
|
||||
* correspondingly. In this manner, any front end can implement adaptive search
|
||||
* by sorting items according to relevance.
|
||||
*
|
||||
* @param config the config group where launch data was stored
|
||||
*/
|
||||
void restore(const KConfigGroup &config);
|
||||
|
||||
/**
|
||||
* @param config the config group where launch data should be stored
|
||||
*/
|
||||
void save(KConfigGroup &config);
|
||||
|
||||
/**
|
||||
* Run a match using the information from this context
|
||||
*
|
||||
* The context will also keep track of the number of times the match was
|
||||
* launched to sort future matches according to user habits
|
||||
*
|
||||
* @param match the match to run
|
||||
*/
|
||||
void run(const QueryMatch &match);
|
||||
|
||||
Q_SIGNALS:
|
||||
void matchesChanged();
|
||||
|
||||
|
@ -66,6 +66,11 @@ public:
|
||||
QObject::connect(&delayTimer, SIGNAL(timeout()), q, SLOT(unblockJobs()));
|
||||
}
|
||||
|
||||
~RunnerManagerPrivate()
|
||||
{
|
||||
context.saveLaunchCounts(config);
|
||||
}
|
||||
|
||||
void scheduleMatchesChanged()
|
||||
{
|
||||
matchChangeTimer.start(50);
|
||||
@ -95,8 +100,7 @@ public:
|
||||
const int cap = qMax(2, numThreads/2);
|
||||
DefaultRunnerPolicy::instance().setCap(cap);
|
||||
|
||||
//If set, this list defines which runners won't be used at runtime
|
||||
//blacklist = config.readEntry("blacklist", QStringList());
|
||||
context.restoreLaunchCounts(config);
|
||||
}
|
||||
|
||||
void loadRunners()
|
||||
@ -308,7 +312,7 @@ void RunnerManager::run(const QueryMatch &match)
|
||||
d->deferredRun = QueryMatch(0);
|
||||
}
|
||||
|
||||
match.run(d->context);
|
||||
d->context.run(match);
|
||||
}
|
||||
|
||||
QList<QAction*> RunnerManager::actionsForMatch(const QueryMatch &match)
|
||||
|
Loading…
Reference in New Issue
Block a user