24#include <QReadWriteLock>
31#include <kcompletion.h>
32#include <kconfiggroup.h>
36#include <kstandarddirs.h>
38#include <kprotocolinfo.h>
47#define LOCK_FOR_READ(d) d->lock.lockForRead();
48#define LOCK_FOR_WRITE(d) d->lock.lockForWrite();
49#define UNLOCK(d) d->lock.unlock();
66 if (QFile::exists(path)) {
67 correctCasePath = path;
72 const QFileInfo pathInfo(path);
74 const QDir fileDir = pathInfo.dir();
77 const QString filename = pathInfo.fileName();
82 const QStringList matchingFilenames = fileDir.entryList(QStringList(filename),
83 mustBeDir ? QDir::Dirs : QDir::NoFilter);
85 if (matchingFilenames.empty()) {
93 if (fileDir.path().endsWith(QDir::separator())) {
94 correctCasePath = fileDir.path() + matchingFilenames[0];
96 correctCasePath = fileDir.path() + QDir::separator() + matchingFilenames[0];
113 if (QFile::exists(path)) {
119 QStringList components = QString(path).split(QDir::separator());
121 if (components.size() < 1) {
125 const bool mustBeDir = components.back().isEmpty();
130 components.pop_back();
133 if (components.isEmpty()) {
138 const unsigned initialComponents = components.size();
139 for (
unsigned i = 0; i < initialComponents - 1; i ++) {
140 const QString tmp = components[0] + QDir::separator() + components[1];
147 components.removeFirst();
148 components[0] = correctPath;
151 corrected = correctPath;
158 RunnerContextPrivate(RunnerContext *context)
160 type(RunnerContext::UnknownType),
162 singleRunnerQueryMode(false)
166 RunnerContextPrivate(
const RunnerContextPrivate &p)
168 launchCounts(p.launchCounts),
169 type(RunnerContext::None),
171 singleRunnerQueryMode(false)
176 ~RunnerContextPrivate()
190 QString path = QDir::cleanPath(KShell::tildeExpand(term));
192 int space = path.indexOf(
' ');
193 if (!KStandardDirs::findExe(path.left(space)).isEmpty()) {
203 const bool hasProtocol = !url.protocol().isEmpty();
204 const bool isLocalProtocol = KProtocolInfo::protocolClass(url.protocol()) ==
":local";
206 ((!isLocalProtocol && url.hasHost()) ||
207 (isLocalProtocol && url.protocol() !=
"file"))) {
211 }
else if (isLocalProtocol) {
215 path = QDir::cleanPath(url.toLocalFile());
217 if (hasProtocol || ((path.indexOf(
'/') != -1 || path.indexOf(
'\\') != -1))) {
218 QString correctCasePath;
220 path = correctCasePath;
221 QFileInfo info(path);
225 if (info.isSymLink()) {
226 path = info.canonicalFilePath();
227 info = QFileInfo(path);
231 mimeType =
"inode/folder";
232 }
else if (info.isFile()) {
234 KMimeType::Ptr mimeTypePtr = KMimeType::findByPath(path);
236 mimeType = mimeTypePtr->name();
253 QList<QueryMatch> matches;
254 QMap<QString, const QueryMatch*> matchesById;
255 QHash<QString, int> launchCounts;
260 static RunnerContext s_dummyContext;
261 bool singleRunnerQueryMode;
264RunnerContext RunnerContextPrivate::s_dummyContext;
268 d(new RunnerContextPrivate(this))
281RunnerContext::~RunnerContext()
287 if (this->d == other.d) {
291 QExplicitlySharedDataPointer<Plasma::RunnerContextPrivate> oldD = d;
300void RunnerContext::reset()
321 if (!d->matches.isEmpty()) {
322 d->matchesById.clear();
330 d->singleRunnerQueryMode =
false;
334void RunnerContext::setQuery(
const QString &term)
338 if (term.isEmpty()) {
346QString RunnerContext::query()
const
359QString RunnerContext::mimeType()
const
364bool RunnerContext::isValid()
const
368 const bool valid = (d->q != &(d->s_dummyContext));
373bool RunnerContext::addMatches(
const QString &term,
const QList<QueryMatch> &matches)
386 if (
int count = d->launchCounts.value(
match.
id())) {
390 d->matches.append(
match);
392 if (d->matchesById.contains(
match.
id())) {
396 d->matchesById.insert(
match.
id(), &d->matches.at(d->matches.size() - 1));
403 emit d->q->matchesChanged();
408bool RunnerContext::addMatch(
const QString &term,
const QueryMatch &match)
421 if (
int count = d->launchCounts.value(m.
id())) {
425 d->matches.append(m);
426 d->matchesById.insert(m.
id(), &d->matches.at(d->matches.size() - 1));
429 emit d->q->matchesChanged();
434bool RunnerContext::removeMatches(
const QStringList matchIdList)
440 QStringList presentMatchIdList;
441 QList<const QueryMatch*> presentMatchList;
444 foreach(
const QString &matchId, matchIdList) {
447 presentMatchList <<
match;
448 presentMatchIdList << matchId;
453 if (presentMatchIdList.isEmpty()) {
459 d->matches.removeAll(*
match);
461 foreach(
const QString &matchId, presentMatchIdList) {
462 d->matchesById.remove(matchId);
466 emit d->q->matchesChanged();
471bool RunnerContext::removeMatch(
const QString matchId)
483 d->matches.removeAll(*
match);
484 d->matchesById.remove(matchId);
486 emit d->q->matchesChanged();
497 QList<QueryMatch> presentMatchList;
502 presentMatchList <<
match;
507 if (presentMatchList.isEmpty()) {
513 d->matchesById.remove(
match.
id());
514 d->matches.removeAll(
match);
518 emit d->q->matchesChanged();
522QList<QueryMatch> RunnerContext::matches()
const
525 QList<QueryMatch>
matches = d->matches;
543void RunnerContext::setSingleRunnerQueryMode(
bool enabled)
545 d->singleRunnerQueryMode = enabled;
548bool RunnerContext::singleRunnerQueryMode()
const
550 return d->singleRunnerQueryMode;
553void RunnerContext::restore(
const KConfigGroup &config)
555 const QStringList cfgList = config.readEntry(
"LaunchCounts", QStringList());
557 const QRegExp r(
"(\\d*) (.*)");
558 foreach (
const QString& entry, cfgList) {
560 int count = r.cap(1).toInt();
561 QString
id = r.cap(2);
562 d->launchCounts[id] = count;
566void RunnerContext::save(KConfigGroup &config)
568 QStringList countList;
570 typedef QHash<QString, int>::const_iterator Iterator;
571 Iterator end = d->launchCounts.constEnd();
572 for (Iterator i = d->launchCounts.constBegin(); i != end; ++i) {
573 countList << QString(
"%2 %1").arg(i.key()).arg(i.value());
576 config.writeEntry(
"LaunchCounts", countList);
588#include "runnercontext.moc"
An abstract base class for Plasma Runner plugins.
A match returned by an AbstractRunner in response to a given RunnerContext.
QString id() const
@ruetnr a string that can be used as an ID for this match, even between different queries.
void setRelevance(qreal relevance)
Sets the relevance of this action for the search it was created for.
qreal relevance() const
The relevance of this action to the search.
void run(const RunnerContext &context) const
Requests this match to activae using the given context.
AbstractRunner * runner() const
The RunnerContext class provides information related to a search, including the search term,...
QueryMatch match(const QString &id) const
Retrieves a match by id.
void reset()
Resets the search term for this object.
QList< QueryMatch > matches() const
Retrieves all available matches for the current search term.
Namespace for everything in libplasma.
bool correctPathCase(const QString &path, QString &corrected)
bool correctLastComponentCase(const QString &path, QString &correctCasePath, const bool mustBeDir)
#define LOCK_FOR_WRITE(d)