Remove KRunner from Plasma-Framework
Have it as a separate KRunner framework instead
This commit is contained in:
parent
dbbb1ed513
commit
18473c9e9e
@ -28,7 +28,6 @@ PLASMA_UNIT_TESTS(
|
|||||||
packagestructuretest
|
packagestructuretest
|
||||||
pluginloadertest
|
pluginloadertest
|
||||||
# plasmoidpackagetest
|
# plasmoidpackagetest
|
||||||
#runnercontexttest
|
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(storagetest storagetest.cpp ../src/plasma/private/storage.cpp ../src/plasma/private/storagethread.cpp)
|
add_executable(storagetest storagetest.cpp ../src/plasma/private/storage.cpp ../src/plasma/private/storagethread.cpp)
|
||||||
|
@ -1,60 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
* Copyright 2010 Aaron Seigo <aseigo@kde.org> *
|
|
||||||
* *
|
|
||||||
* This library is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Library General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* This library is distributed in the hope that it will be useful, *
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
|
||||||
* Library General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Library General Public License *
|
|
||||||
* along with this library; see the file COPYING.LIB. If not, write to *
|
|
||||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
|
|
||||||
* Boston, MA 02110-1301, USA. *
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#include "runnercontexttest.h"
|
|
||||||
|
|
||||||
#include <kprotocolinfo.h>
|
|
||||||
#include "plasma/runnercontext.h"
|
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(Plasma::RunnerContext::Type)
|
|
||||||
|
|
||||||
void RunnerContextTest::typeDetection_data()
|
|
||||||
{
|
|
||||||
QTest::addColumn<QString>("url");
|
|
||||||
QTest::addColumn<Plasma::RunnerContext::Type>("type");
|
|
||||||
|
|
||||||
if (KProtocolInfo::isKnownProtocol("man")) {
|
|
||||||
QTest::newRow("man page listing") << "man:/" << Plasma::RunnerContext::NetworkLocation;
|
|
||||||
QTest::newRow("ls man page listing") << "man://ls" << Plasma::RunnerContext::NetworkLocation;
|
|
||||||
}
|
|
||||||
QTest::newRow("http without host") << "http://" << Plasma::RunnerContext::UnknownType;
|
|
||||||
QTest::newRow("http with host") << "http://kde.org" << Plasma::RunnerContext::NetworkLocation;
|
|
||||||
QTest::newRow("file double slash") << "file://home" << Plasma::RunnerContext::Directory;
|
|
||||||
QTest::newRow("file triple slash") << "file:///home" << Plasma::RunnerContext::Directory;
|
|
||||||
QTest::newRow("file single slash") << "file:/home" << Plasma::RunnerContext::Directory;
|
|
||||||
QTest::newRow("file multiple path") << "file://usr/bin" << Plasma::RunnerContext::Directory;
|
|
||||||
QTest::newRow("invalid file path") << "file://bad/path" << Plasma::RunnerContext::UnknownType;
|
|
||||||
QTest::newRow("executable") << "ls" << Plasma::RunnerContext::Executable;
|
|
||||||
QTest::newRow("executable with params") << "ls -R" << Plasma::RunnerContext::ShellCommand;
|
|
||||||
QTest::newRow("full path executable") << "ls -R" << Plasma::RunnerContext::ShellCommand;
|
|
||||||
QTest::newRow("full path executable with params") << "/bin/ls -R" << Plasma::RunnerContext::ShellCommand;
|
|
||||||
QTest::newRow("protocol-less path") << "/home" << Plasma::RunnerContext::Directory;
|
|
||||||
QTest::newRow("invalid protocol-less path") << "/bad/path" << Plasma::RunnerContext::UnknownType;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerContextTest::typeDetection()
|
|
||||||
{
|
|
||||||
QFETCH(QString, url);
|
|
||||||
QFETCH(Plasma::RunnerContext::Type, type);
|
|
||||||
|
|
||||||
m_context.setQuery(url);
|
|
||||||
QCOMPARE(int(m_context.type()), int(type));
|
|
||||||
}
|
|
||||||
|
|
||||||
QTEST_MAIN(RunnerContextTest)
|
|
@ -1,39 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
* Copyright 2010 Aaron Seigo <aseigo@kde.org> *
|
|
||||||
* *
|
|
||||||
* This library is free software; you can redistribute it and/or *
|
|
||||||
* modify it under the terms of the GNU Library General Public *
|
|
||||||
* License as published by the Free Software Foundation; either *
|
|
||||||
* version 2 of the License, or (at your option) any later version. *
|
|
||||||
* *
|
|
||||||
* This library is distributed in the hope that it will be useful, *
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
|
||||||
* Library General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* You should have received a copy of the GNU Library General Public License *
|
|
||||||
* along with this library; see the file COPYING.LIB. If not, write to *
|
|
||||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
|
|
||||||
* Boston, MA 02110-1301, USA. *
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#ifndef PACKAGEMETADATATEST_H
|
|
||||||
|
|
||||||
#include <QtTest/QtTest>
|
|
||||||
|
|
||||||
#include "plasma/runnercontext.h"
|
|
||||||
|
|
||||||
class RunnerContextTest : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void typeDetection_data();
|
|
||||||
void typeDetection();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Plasma::RunnerContext m_context;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
|||||||
# Project Needs a name, of course
|
|
||||||
project(RunnerExample)
|
|
||||||
|
|
||||||
# We add our source code here
|
|
||||||
set(example_SRCS homefilesrunner.cpp)
|
|
||||||
|
|
||||||
# Now make sure all files get to the right place
|
|
||||||
add_library(plasma_runner_example_homefiles MODULE ${example_SRCS})
|
|
||||||
target_link_libraries(plasma_runner_example_homefiles KF5::Plasma KF5::KIOCore KF5::KIOWidgets)
|
|
||||||
|
|
||||||
# Install the library and .desktop file
|
|
||||||
install(TARGETS plasma_runner_example_homefiles DESTINATION ${PLUGIN_INSTALL_DIR})
|
|
||||||
install(FILES plasma-runner-example-homefiles.desktop DESTINATION ${SERVICES_INSTALL_DIR})
|
|
@ -1,2 +0,0 @@
|
|||||||
#! /usr/bin/env bash
|
|
||||||
$XGETTEXT *.cpp -o $podir/plasma_runner_example_homefiles.pot
|
|
@ -1,162 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2009 Aaron Seigo <aseigo@kde.org>
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "homefilesrunner.h"
|
|
||||||
|
|
||||||
#include <QCheckBox>
|
|
||||||
#include <QDir>
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
|
|
||||||
#include <KDebug>
|
|
||||||
#include <KMimeType>
|
|
||||||
#include <KRun>
|
|
||||||
|
|
||||||
HomeFilesRunner::HomeFilesRunner(QObject *parent, const QVariantList &args)
|
|
||||||
: AbstractRunner(parent, args)
|
|
||||||
{
|
|
||||||
setIgnoredTypes(Plasma::RunnerContext::NetworkLocation |
|
|
||||||
Plasma::RunnerContext::Executable |
|
|
||||||
Plasma::RunnerContext::ShellCommand);
|
|
||||||
setSpeed(SlowSpeed);
|
|
||||||
setPriority(LowPriority);
|
|
||||||
setHasRunOptions(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HomeFilesRunner::init()
|
|
||||||
{
|
|
||||||
reloadConfiguration();
|
|
||||||
connect(this, SIGNAL(prepare()), this, SLOT(prepareForMatchSession()));
|
|
||||||
connect(this, SIGNAL(teardown()), this, SLOT(matchSessionFinished()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void HomeFilesRunner::reloadConfiguration()
|
|
||||||
{
|
|
||||||
KConfigGroup c = config();
|
|
||||||
m_triggerWord = c.readEntry("trigger", QString());
|
|
||||||
if (!m_triggerWord.isEmpty()) {
|
|
||||||
m_triggerWord.append(' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
m_path = c.readPathEntry("path", QDir::homePath());
|
|
||||||
QFileInfo pathInfo(m_path);
|
|
||||||
if (!pathInfo.isDir()) {
|
|
||||||
m_path = QDir::homePath();
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<Plasma::RunnerSyntax> syntaxes;
|
|
||||||
Plasma::RunnerSyntax syntax(QString("%1:q:").arg(m_triggerWord),
|
|
||||||
i18n("Finds files matching :q: in the %1 folder", m_path));
|
|
||||||
syntaxes.append(syntax);
|
|
||||||
setSyntaxes(syntaxes);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HomeFilesRunner::prepareForMatchSession()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void HomeFilesRunner::match(Plasma::RunnerContext &context)
|
|
||||||
{
|
|
||||||
QString query = context.query();
|
|
||||||
if (query == QChar('.') || query == "..") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_triggerWord.isEmpty()) {
|
|
||||||
if (!query.startsWith(m_triggerWord)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
query.remove(0, m_triggerWord.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (query.length() > 2) {
|
|
||||||
query.prepend('*').append('*');
|
|
||||||
}
|
|
||||||
|
|
||||||
QDir dir(m_path);
|
|
||||||
QList<Plasma::QueryMatch> matches;
|
|
||||||
|
|
||||||
foreach (const QString &file, dir.entryList(QStringList(query))) {
|
|
||||||
const QString path = dir.absoluteFilePath(file);
|
|
||||||
if (!path.startsWith(m_path)) {
|
|
||||||
// this file isn't in our directory; looks like we got a query with some
|
|
||||||
// ..'s in it!
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!context.isValid()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Plasma::QueryMatch match(this);
|
|
||||||
match.setText(i18n("Open %1", path));
|
|
||||||
match.setData(path);
|
|
||||||
match.setId(path);
|
|
||||||
if (m_iconCache.contains(path)) {
|
|
||||||
match.setIcon(m_iconCache.value(path));
|
|
||||||
} else {
|
|
||||||
KIcon icon(KMimeType::iconNameForUrl(path));
|
|
||||||
m_iconCache.insert(path, icon);
|
|
||||||
match.setIcon(icon);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.compare(query, Qt::CaseInsensitive)) {
|
|
||||||
match.setRelevance(1.0);
|
|
||||||
match.setType(Plasma::QueryMatch::ExactMatch);
|
|
||||||
} else {
|
|
||||||
match.setRelevance(0.8);
|
|
||||||
}
|
|
||||||
|
|
||||||
matches.append(match);
|
|
||||||
}
|
|
||||||
|
|
||||||
context.addMatches(context.query(), matches);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HomeFilesRunner::matchSessionFinished()
|
|
||||||
{
|
|
||||||
m_iconCache.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void HomeFilesRunner::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match)
|
|
||||||
{
|
|
||||||
Q_UNUSED(context)
|
|
||||||
// KRun autodeletes itself, so we can just create it and forget it!
|
|
||||||
KRun *opener = new KRun(match.data().toString(), 0);
|
|
||||||
opener->setRunExecutables(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HomeFilesRunner::createRunOptions(QWidget *widget)
|
|
||||||
{
|
|
||||||
QVBoxLayout *layout = new QVBoxLayout(widget);
|
|
||||||
QCheckBox *cb = new QCheckBox(widget);
|
|
||||||
cb->setText(i18n("This is just for show"));
|
|
||||||
layout->addWidget(cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
K_EXPORT_PLASMA_RUNNER(example-homefiles, HomeFilesRunner)
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2009 Aaron Seigo <aseigo@kde.org>
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef HOMEFILES_H
|
|
||||||
#define HOMEFILES_H
|
|
||||||
|
|
||||||
#include <Plasma/AbstractRunner>
|
|
||||||
|
|
||||||
#include <QHash>
|
|
||||||
|
|
||||||
#include <KIcon>
|
|
||||||
|
|
||||||
class HomeFilesRunner : public Plasma::AbstractRunner
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
HomeFilesRunner(QObject *parent, const QVariantList &args);
|
|
||||||
|
|
||||||
void match(Plasma::RunnerContext &context);
|
|
||||||
void run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match);
|
|
||||||
void createRunOptions(QWidget *widget);
|
|
||||||
void reloadConfiguration();
|
|
||||||
|
|
||||||
protected Q_SLOTS:
|
|
||||||
void init();
|
|
||||||
void prepareForMatchSession();
|
|
||||||
void matchSessionFinished();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QHash<QString, KIcon> m_iconCache;
|
|
||||||
QString m_path;
|
|
||||||
QString m_triggerWord;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
|||||||
[Desktop Entry]
|
|
||||||
Name=Home Files
|
|
||||||
Name[bs]=Lične datoteke
|
|
||||||
Name[de]=Persönliche Dateien
|
|
||||||
Name[fi]=Kodin tiedostot
|
|
||||||
Name[fr]=Fichiers personnels
|
|
||||||
Name[nl]=Persoonlijke bestanden
|
|
||||||
Name[pt]=Ficheiros Pessoais
|
|
||||||
Name[pt_BR]=Arquivos pessoais
|
|
||||||
Name[sk]=Domáce súbory
|
|
||||||
Name[sv]=Hemfiler
|
|
||||||
Name[uk]=Файли у домашній теці
|
|
||||||
Name[x-test]=xxHome Filesxx
|
|
||||||
Comment=Part of a tutorial demonstrating how to create Runner plugins
|
|
||||||
Comment[bs]=Dio tutorijala demonstrira kako se kreiraju Runner priključci
|
|
||||||
Comment[de]=Teil einer Anleitung zur Demonstration, wie Runner-Module erstellt werden
|
|
||||||
Comment[fr]=Éléments d'un tutoriel montrant comment créer des modules « Runner »
|
|
||||||
Comment[nl]=Deel van een inleiding die demonstreert hoe Runner-plug-ins te maken
|
|
||||||
Comment[pt]=Parte de um tutorial que demonstra como criar 'plugins' do Runner
|
|
||||||
Comment[pt_BR]=Parte de um tutorial que demonstra como criar plugins do Runner
|
|
||||||
Comment[sk]=Časť kurzu demonštrujúceho ako vytvoriť pluginy Runnera
|
|
||||||
Comment[sv]=Del av en handledning som demonstrerar hur insticksprogram till Runner skapas
|
|
||||||
Comment[uk]=Частина підручника, який демонструє створення додатків до засобу запуску
|
|
||||||
Comment[x-test]=xxPart of a tutorial demonstrating how to create Runner pluginsxx
|
|
||||||
Icon=user-home
|
|
||||||
Type=Service
|
|
||||||
X-KDE-ServiceTypes=Plasma/Runner
|
|
||||||
|
|
||||||
X-KDE-Library=plasma_runner_example_homefiles
|
|
||||||
X-KDE-PluginInfo-Author=Aaron Seigo
|
|
||||||
X-KDE-PluginInfo-Email=aseigo@kde.org
|
|
||||||
X-KDE-PluginInfo-Name=example-homefiles
|
|
||||||
X-KDE-PluginInfo-Version=0.1
|
|
||||||
X-KDE-PluginInfo-Website=http://plasma.kde.org/
|
|
||||||
X-KDE-PluginInfo-Category=Examples
|
|
||||||
X-KDE-PluginInfo-Depends=
|
|
||||||
X-KDE-PluginInfo-License=GPL
|
|
||||||
X-KDE-PluginInfo-EnabledByDefault=true
|
|
@ -2,7 +2,6 @@ add_subdirectory(accessdenied)
|
|||||||
add_subdirectory(core)
|
add_subdirectory(core)
|
||||||
add_subdirectory(dirmodel)
|
add_subdirectory(dirmodel)
|
||||||
add_subdirectory(draganddrop)
|
add_subdirectory(draganddrop)
|
||||||
#add_subdirectory(krunnermodel)
|
|
||||||
add_subdirectory(qtextracomponents)
|
add_subdirectory(qtextracomponents)
|
||||||
add_subdirectory(plasmacomponents)
|
add_subdirectory(plasmacomponents)
|
||||||
add_subdirectory(plasmaextracomponents)
|
add_subdirectory(plasmaextracomponents)
|
||||||
|
@ -29,13 +29,10 @@
|
|||||||
|
|
||||||
#include <plasma/framesvg.h>
|
#include <plasma/framesvg.h>
|
||||||
#include <plasma/svg.h>
|
#include <plasma/svg.h>
|
||||||
#include <Plasma/QueryMatch>
|
|
||||||
#include <Plasma/ServiceJob>
|
|
||||||
|
|
||||||
#include "datasource.h"
|
#include "datasource.h"
|
||||||
#include "datamodel.h"
|
#include "datamodel.h"
|
||||||
#include "framesvgitem.h"
|
#include "framesvgitem.h"
|
||||||
#include "runnermodel.h"
|
|
||||||
#include "svgitem.h"
|
#include "svgitem.h"
|
||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
#include "dialog.h"
|
#include "dialog.h"
|
||||||
@ -46,6 +43,7 @@
|
|||||||
#include "tooltip.h"
|
#include "tooltip.h"
|
||||||
#include "units.h"
|
#include "units.h"
|
||||||
#include "windowthumbnail.h"
|
#include "windowthumbnail.h"
|
||||||
|
#include <plasma/servicejob.h>
|
||||||
|
|
||||||
// #include "dataenginebindings_p.h"
|
// #include "dataenginebindings_p.h"
|
||||||
|
|
||||||
@ -101,11 +99,7 @@ void CoreBindingsPlugin::registerTypes(const char *uri)
|
|||||||
qmlRegisterType<Formats>(uri, 2, 0, "Formats");
|
qmlRegisterType<Formats>(uri, 2, 0, "Formats");
|
||||||
qmlRegisterType<ServiceOperationStatus>(uri, 2, 0, "ServiceOperationStatus");
|
qmlRegisterType<ServiceOperationStatus>(uri, 2, 0, "ServiceOperationStatus");
|
||||||
qmlRegisterType<QAbstractItemModel>();
|
qmlRegisterType<QAbstractItemModel>();
|
||||||
#if 0
|
|
||||||
qmlRegisterType<RunnerModel>(uri, 2, 0, "RunnerModel");
|
|
||||||
qmlRegisterInterface<Plasma::QueryMatch>("QueryMatch");
|
|
||||||
qRegisterMetaType<Plasma::QueryMatch *>("QueryMatch");
|
|
||||||
#endif
|
|
||||||
qmlRegisterType<QQmlPropertyMap>();
|
qmlRegisterType<QQmlPropertyMap>();
|
||||||
qmlRegisterType<IconItem>(uri, 2, 0, "IconItem");
|
qmlRegisterType<IconItem>(uri, 2, 0, "IconItem");
|
||||||
|
|
||||||
|
@ -1,251 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2011 Aaron Seigo <aseigo@kde.org>
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public License
|
|
||||||
along with this library; see the file COPYING.LIB. If not, write to
|
|
||||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
||||||
Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "runnermodel.h"
|
|
||||||
|
|
||||||
#include <QIcon>
|
|
||||||
#include <QAction>
|
|
||||||
#include <QTimer>
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
#include <Plasma/RunnerManager>
|
|
||||||
|
|
||||||
RunnerModel::RunnerModel(QObject *parent)
|
|
||||||
: QAbstractListModel(parent),
|
|
||||||
m_manager(0),
|
|
||||||
m_startQueryTimer(new QTimer(this)),
|
|
||||||
m_runningChangedTimeout(new QTimer(this)),
|
|
||||||
m_running(false)
|
|
||||||
{
|
|
||||||
QHash<int, QByteArray> roles;
|
|
||||||
roles.insert(Qt::DisplayRole, "display");
|
|
||||||
roles.insert(Qt::DecorationRole, "decoration");
|
|
||||||
roles.insert(Label, "label");
|
|
||||||
roles.insert(Icon, "icon");
|
|
||||||
roles.insert(Type, "type");
|
|
||||||
roles.insert(Relevance, "relevance");
|
|
||||||
roles.insert(Data, "data");
|
|
||||||
roles.insert(Id, "id");
|
|
||||||
roles.insert(SubText, "description");
|
|
||||||
roles.insert(Enabled, "enabled");
|
|
||||||
roles.insert(RunnerId, "runnerid");
|
|
||||||
roles.insert(RunnerName, "runnerName");
|
|
||||||
roles.insert(Actions, "actions");
|
|
||||||
setRoleNames(roles);
|
|
||||||
|
|
||||||
m_startQueryTimer->setSingleShot(true);
|
|
||||||
m_startQueryTimer->setInterval(10);
|
|
||||||
connect(m_startQueryTimer, SIGNAL(timeout()), this, SLOT(startQuery()));
|
|
||||||
|
|
||||||
//FIXME: HACK: some runners stay in a running but finished state, not possible to say if it's actually over
|
|
||||||
m_runningChangedTimeout->setSingleShot(true);
|
|
||||||
connect(m_runningChangedTimeout, SIGNAL(timeout()), this, SLOT(queryHasFinished()));
|
|
||||||
}
|
|
||||||
|
|
||||||
int RunnerModel::rowCount(const QModelIndex& index) const
|
|
||||||
{
|
|
||||||
return index.isValid() ? 0 : m_matches.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
int RunnerModel::count() const
|
|
||||||
{
|
|
||||||
return m_matches.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList RunnerModel::runners() const
|
|
||||||
{
|
|
||||||
return m_manager ? m_manager->allowedRunners() : m_pendingRunnersList;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerModel::setRunners(const QStringList &allowedRunners)
|
|
||||||
{
|
|
||||||
//use sets to ensure comparison is order-independent
|
|
||||||
if (allowedRunners.toSet() == runners().toSet()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (m_manager) {
|
|
||||||
m_manager->setAllowedRunners(allowedRunners);
|
|
||||||
|
|
||||||
//automagically enter single runner mode if there's only 1 allowed runner
|
|
||||||
m_manager->setSingleMode(allowedRunners.count() == 1);
|
|
||||||
} else {
|
|
||||||
m_pendingRunnersList = allowedRunners;
|
|
||||||
// qDebug() << "runners set" << m_pendingRunnersList.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
// to trigger single runner fun!
|
|
||||||
if (allowedRunners.count() == 1) {
|
|
||||||
m_singleRunnerId = allowedRunners.first();
|
|
||||||
scheduleQuery(QString());
|
|
||||||
} else {
|
|
||||||
m_singleRunnerId.clear();
|
|
||||||
}
|
|
||||||
emit runnersChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerModel::run(int index)
|
|
||||||
{
|
|
||||||
if (index >= 0 && index < m_matches.count()) {
|
|
||||||
m_manager->run(m_matches.at(index));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RunnerModel::isRunning() const
|
|
||||||
{
|
|
||||||
return m_running;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant RunnerModel::data(const QModelIndex &index, int role) const
|
|
||||||
{
|
|
||||||
if (!index.isValid() || index.parent().isValid() ||
|
|
||||||
index.column() > 0 || index.row() < 0 || index.row() >= m_matches.count()) {
|
|
||||||
// index requested must be valid, but we have no child items!
|
|
||||||
//qDebug() << "invalid index requested";
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (role == Qt::DisplayRole || role == Label) {
|
|
||||||
return m_matches.at(index.row()).text();
|
|
||||||
} else if (role == Qt::DecorationRole || role == Icon) {
|
|
||||||
return m_matches.at(index.row()).icon();
|
|
||||||
} else if (role == Type) {
|
|
||||||
return m_matches.at(index.row()).type();
|
|
||||||
} else if (role == Relevance) {
|
|
||||||
return m_matches.at(index.row()).relevance();
|
|
||||||
} else if (role == Data) {
|
|
||||||
return m_matches.at(index.row()).data();
|
|
||||||
} else if (role == Id) {
|
|
||||||
return m_matches.at(index.row()).id();
|
|
||||||
} else if (role == SubText) {
|
|
||||||
return m_matches.at(index.row()).subtext();
|
|
||||||
} else if (role == Enabled) {
|
|
||||||
return m_matches.at(index.row()).isEnabled();
|
|
||||||
} else if (role == RunnerId) {
|
|
||||||
return m_matches.at(index.row()).runner()->id();
|
|
||||||
} else if (role == RunnerName) {
|
|
||||||
return m_matches.at(index.row()).runner()->name();
|
|
||||||
} else if (role == Actions) {
|
|
||||||
QVariantList actions;
|
|
||||||
Plasma::QueryMatch amatch = m_matches.at(index.row());
|
|
||||||
QList<QAction*> theactions = m_manager->actionsForMatch(amatch);
|
|
||||||
foreach(QAction* action, theactions) {
|
|
||||||
actions += qVariantFromValue<QObject*>(action);
|
|
||||||
}
|
|
||||||
return actions;
|
|
||||||
}
|
|
||||||
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString RunnerModel::currentQuery() const
|
|
||||||
{
|
|
||||||
return m_manager ? m_manager->query() : QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerModel::scheduleQuery(const QString &query)
|
|
||||||
{
|
|
||||||
m_pendingQuery = query;
|
|
||||||
m_startQueryTimer->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerModel::startQuery()
|
|
||||||
{
|
|
||||||
// avoid creating a manager just so we can run nothing
|
|
||||||
// however, if we have one pending runner, then we'll be in single query mode
|
|
||||||
// and a null query is a valid query
|
|
||||||
if (!m_manager && m_pendingRunnersList.count() != 1 && m_pendingQuery.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//qDebug() << "!!!!!!!!!!!!!" << m_pendingQuery << m_manager;
|
|
||||||
|
|
||||||
if (createManager() || m_pendingQuery != m_manager->query()) {
|
|
||||||
//qDebug() << "running query" << m_pendingQuery << m_manager;
|
|
||||||
m_manager->launchQuery(m_pendingQuery, m_singleRunnerId);
|
|
||||||
emit queryChanged();
|
|
||||||
m_running = true;
|
|
||||||
emit runningChanged(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RunnerModel::createManager()
|
|
||||||
{
|
|
||||||
if (!m_manager) {
|
|
||||||
m_manager = new Plasma::RunnerManager(this);
|
|
||||||
connect(m_manager, SIGNAL(matchesChanged(QList<Plasma::QueryMatch>)),
|
|
||||||
this, SLOT(matchesChanged(QList<Plasma::QueryMatch>)));
|
|
||||||
connect(m_manager, SIGNAL(queryFinished()),
|
|
||||||
this, SLOT(queryHasFinished()));
|
|
||||||
|
|
||||||
if (!m_pendingRunnersList.isEmpty()) {
|
|
||||||
setRunners(m_pendingRunnersList);
|
|
||||||
m_pendingRunnersList.clear();
|
|
||||||
}
|
|
||||||
//connect(m_manager, SIGNAL(queryFinished()), this, SLOT(queryFinished()));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerModel::matchesChanged(const QList<Plasma::QueryMatch> &matches)
|
|
||||||
{
|
|
||||||
//qDebug() << "got matches:" << matches.count();
|
|
||||||
bool fullReset = false;
|
|
||||||
int oldCount = m_matches.count();
|
|
||||||
int newCount = matches.count();
|
|
||||||
if (newCount > oldCount) {
|
|
||||||
// We received more matches than we had. If all common matches are the
|
|
||||||
// same, we can just append new matches instead of resetting the whole
|
|
||||||
// model
|
|
||||||
for (int row = 0; row < oldCount; ++row) {
|
|
||||||
if (!(m_matches.at(row) == matches.at(row))) {
|
|
||||||
fullReset = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!fullReset) {
|
|
||||||
// Not a full reset, inserting rows
|
|
||||||
beginInsertRows(QModelIndex(), oldCount, newCount-1);
|
|
||||||
m_matches = matches;
|
|
||||||
endInsertRows();
|
|
||||||
emit countChanged();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fullReset = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fullReset) {
|
|
||||||
beginResetModel();
|
|
||||||
m_matches = matches;
|
|
||||||
endResetModel();
|
|
||||||
emit countChanged();
|
|
||||||
}
|
|
||||||
m_runningChangedTimeout->start(3000);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerModel::queryHasFinished()
|
|
||||||
{
|
|
||||||
m_running = false;
|
|
||||||
emit runningChanged(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "runnermodel.moc"
|
|
||||||
|
|
@ -1,128 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2011 Aaron Seigo <aseigo@kde.org>
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public License
|
|
||||||
along with this library; see the file COPYING.LIB. If not, write to
|
|
||||||
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
||||||
Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef RUNNERMODEL_H
|
|
||||||
#define RUNNERMODEL_H
|
|
||||||
|
|
||||||
#include <QAbstractListModel>
|
|
||||||
#include <QStringList>
|
|
||||||
|
|
||||||
#include <Plasma/QueryMatch>
|
|
||||||
|
|
||||||
namespace Plasma
|
|
||||||
{
|
|
||||||
class RunnerManager;
|
|
||||||
class QueryMatch;
|
|
||||||
} // namespace Plasma
|
|
||||||
|
|
||||||
class QTimer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This model provides bindings to use KRunner from QML
|
|
||||||
*
|
|
||||||
* @author Aaron Seigo <aseigo@kde.org>
|
|
||||||
*/
|
|
||||||
class RunnerModel : public QAbstractListModel
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @property string set the KRunner query
|
|
||||||
*/
|
|
||||||
Q_PROPERTY(QString query WRITE scheduleQuery READ currentQuery NOTIFY queryChanged)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @property Array The list of all allowed runner plugins that will be executed
|
|
||||||
*/
|
|
||||||
Q_PROPERTY(QStringList runners WRITE setRunners READ runners NOTIFY runnersChanged)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @property int The number of rows of the model
|
|
||||||
*/
|
|
||||||
Q_PROPERTY(int count READ count NOTIFY countChanged)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @property bool running: true when queries are in execution
|
|
||||||
*/
|
|
||||||
Q_PROPERTY(bool running READ isRunning NOTIFY runningChanged)
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @enum Roles of the model, they will be accessible from delegates
|
|
||||||
*/
|
|
||||||
enum Roles {
|
|
||||||
Type = Qt::UserRole + 1,
|
|
||||||
Label,
|
|
||||||
Icon,
|
|
||||||
Relevance,
|
|
||||||
Data,
|
|
||||||
Id,
|
|
||||||
SubText,
|
|
||||||
Enabled,
|
|
||||||
RunnerId,
|
|
||||||
RunnerName,
|
|
||||||
Actions
|
|
||||||
};
|
|
||||||
|
|
||||||
RunnerModel(QObject *parent = 0);
|
|
||||||
|
|
||||||
QString currentQuery() const;
|
|
||||||
|
|
||||||
QStringList runners() const;
|
|
||||||
void setRunners(const QStringList &allowedRunners);
|
|
||||||
|
|
||||||
Q_SCRIPTABLE void run(int row);
|
|
||||||
|
|
||||||
bool isRunning() const;
|
|
||||||
|
|
||||||
int rowCount(const QModelIndex&) const;
|
|
||||||
int count() const;
|
|
||||||
QVariant data(const QModelIndex&, int) const;
|
|
||||||
|
|
||||||
public Q_SLOTS:
|
|
||||||
void scheduleQuery(const QString &query);
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void queryChanged();
|
|
||||||
void countChanged();
|
|
||||||
void runnersChanged();
|
|
||||||
void runningChanged(bool running);
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void startQuery();
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool createManager();
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void matchesChanged(const QList<Plasma::QueryMatch> &matches);
|
|
||||||
void queryHasFinished();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Plasma::RunnerManager *m_manager;
|
|
||||||
QList<Plasma::QueryMatch> m_matches;
|
|
||||||
QStringList m_pendingRunnersList;
|
|
||||||
QString m_singleRunnerId;
|
|
||||||
QString m_pendingQuery;
|
|
||||||
QTimer *m_startQueryTimer;
|
|
||||||
QTimer *m_runningChangedTimeout;
|
|
||||||
bool m_running;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -23,14 +23,3 @@ target_link_libraries(sortfiltermodeltest
|
|||||||
|
|
||||||
add_test(plasma-sortfiltermodeltest sortfiltermodeltest)
|
add_test(plasma-sortfiltermodeltest sortfiltermodeltest)
|
||||||
ecm_mark_as_test(sortfiltermodeltest)
|
ecm_mark_as_test(sortfiltermodeltest)
|
||||||
|
|
||||||
#set(runnermodeltest_SRCS
|
|
||||||
# main.cpp
|
|
||||||
# dynamictreemodel.cpp
|
|
||||||
# modeltest.cpp
|
|
||||||
# ../runnermodel.cpp
|
|
||||||
# )
|
|
||||||
|
|
||||||
#add_executable(runnermodeltest ${runnermodeltest_SRCS})
|
|
||||||
#target_link_libraries(runnermodeltest Qt5::Test ${plasma_LIBRARIES} plasma)
|
|
||||||
#ecm_mark_as_test(runnermodeltest)
|
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
#include <QAction>
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QDialog>
|
|
||||||
#include <QLineEdit>
|
|
||||||
#include <QTreeView>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
|
|
||||||
#include "../runnermodel.h"
|
|
||||||
#include "modeltest.h"
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
QApplication app(argc, argv);
|
|
||||||
QWidget *widget = new QWidget;
|
|
||||||
QVBoxLayout *layout = new QVBoxLayout(widget);
|
|
||||||
|
|
||||||
RunnerModel *runnerModel = new RunnerModel(widget);
|
|
||||||
new ModelTest(runnerModel, widget);
|
|
||||||
|
|
||||||
QLineEdit *input = new QLineEdit(widget);
|
|
||||||
QObject::connect(input, SIGNAL(textChanged(QString)), runnerModel, SLOT(startQuery(QString)));
|
|
||||||
layout->addWidget(input);
|
|
||||||
|
|
||||||
QTreeView *view = new QTreeView(widget);
|
|
||||||
view->setModel(runnerModel);
|
|
||||||
layout->addWidget(view);
|
|
||||||
|
|
||||||
QAction *quit = new QAction(widget);
|
|
||||||
quit->setShortcut(Qt::CTRL + Qt::Key_Q);
|
|
||||||
QObject::connect(quit, SIGNAL(triggered()), &app, SLOT(quit()));
|
|
||||||
|
|
||||||
widget->addAction(quit);
|
|
||||||
widget->show();
|
|
||||||
return app.exec();
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
project(runnermodel)
|
|
||||||
|
|
||||||
set(runnermodel_SRCS
|
|
||||||
../core/runnermodel.cpp
|
|
||||||
runnermodelplugin.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(runnermodelplugin SHARED ${runnermodel_SRCS})
|
|
||||||
target_link_libraries(runnermodelplugin
|
|
||||||
Qt5::Quick
|
|
||||||
Qt5::Qml
|
|
||||||
KF5::I18n
|
|
||||||
KF5::Plasma
|
|
||||||
)
|
|
||||||
|
|
||||||
install(TARGETS runnermodelplugin DESTINATION ${QML_INSTALL_DIR}/org/kde/runnermodel)
|
|
||||||
install(FILES qmldir DESTINATION ${QML_INSTALL_DIR}/org/kde/runnermodel)
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
|||||||
module org.kde.runnermodel
|
|
||||||
plugin runnermodelplugin
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2011 by Marco Martin <mart@kde.org>
|
|
||||||
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Library General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Library General Public License for more details
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Library General Public
|
|
||||||
* License along with this program; if not, write to the
|
|
||||||
* Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "runnermodelplugin.h"
|
|
||||||
|
|
||||||
#include <QtQml>
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
#include <Plasma/QueryMatch>
|
|
||||||
|
|
||||||
#include "../core/runnermodel.h"
|
|
||||||
|
|
||||||
void RunnerModelPlugin::registerTypes(const char *uri)
|
|
||||||
{
|
|
||||||
qWarning() << "Using deprecated import org.kde.runnermodel, please port to org.kde.plasma.core";
|
|
||||||
Q_ASSERT(uri == QLatin1String("org.kde.runnermodel"));
|
|
||||||
qmlRegisterType<RunnerModel>(uri, 2, 0, "RunnerModel");
|
|
||||||
qmlRegisterInterface<Plasma::QueryMatch>("QueryMatch");
|
|
||||||
qRegisterMetaType<Plasma::QueryMatch *>("QueryMatch");
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "runnermodelplugin.moc"
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2011 by Marco Martin <mart@kde.org>
|
|
||||||
* Copyright 2011 by Aaron Seigo <aseigo@kde.org>
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Library General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Library General Public License for more details
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Library General Public
|
|
||||||
* License along with this program; if not, write to the
|
|
||||||
* Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef RUNNERMODELPLUGIN_H
|
|
||||||
#define RUNNERMODELPLUGIN_H
|
|
||||||
|
|
||||||
#include <QQmlExtensionPlugin>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FIXME: This plugin is deprecated, it should be removed for plasma2
|
|
||||||
*/
|
|
||||||
class RunnerModelPlugin : public QQmlExtensionPlugin
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
|
|
||||||
|
|
||||||
public:
|
|
||||||
void registerTypes(const char *uri);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -47,14 +47,6 @@ set(Plasma_LIB_SRCS
|
|||||||
version.cpp
|
version.cpp
|
||||||
private/componentinstaller.cpp
|
private/componentinstaller.cpp
|
||||||
|
|
||||||
#runners
|
|
||||||
abstractrunner.cpp
|
|
||||||
querymatch.cpp
|
|
||||||
runnercontext.cpp
|
|
||||||
runnermanager.cpp
|
|
||||||
runnersyntax.cpp
|
|
||||||
private/runnerjobs.cpp
|
|
||||||
|
|
||||||
#applets,containments,corona
|
#applets,containments,corona
|
||||||
applet.cpp
|
applet.cpp
|
||||||
configloader.cpp
|
configloader.cpp
|
||||||
@ -92,7 +84,6 @@ set(Plasma_LIB_SRCS
|
|||||||
#scripting
|
#scripting
|
||||||
scripting/appletscript.cpp
|
scripting/appletscript.cpp
|
||||||
scripting/dataenginescript.cpp
|
scripting/dataenginescript.cpp
|
||||||
scripting/runnerscript.cpp
|
|
||||||
scripting/scriptengine.cpp
|
scripting/scriptengine.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -166,7 +157,6 @@ set_target_properties(KF5Plasma PROPERTIES
|
|||||||
generate_export_header(KF5Plasma BASE_NAME Plasma)
|
generate_export_header(KF5Plasma BASE_NAME Plasma)
|
||||||
|
|
||||||
set(Plasma_LIB_INCLUDES
|
set(Plasma_LIB_INCLUDES
|
||||||
abstractrunner.h
|
|
||||||
applet.h
|
applet.h
|
||||||
configloader.h
|
configloader.h
|
||||||
containment.h
|
containment.h
|
||||||
@ -181,10 +171,6 @@ set(Plasma_LIB_INCLUDES
|
|||||||
packagestructure.h
|
packagestructure.h
|
||||||
plasma.h
|
plasma.h
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/plasma_export.h
|
${CMAKE_CURRENT_BINARY_DIR}/plasma_export.h
|
||||||
querymatch.h
|
|
||||||
runnercontext.h
|
|
||||||
runnermanager.h
|
|
||||||
runnersyntax.h
|
|
||||||
service.h
|
service.h
|
||||||
servicejob.h
|
servicejob.h
|
||||||
svg.h
|
svg.h
|
||||||
@ -204,7 +190,6 @@ install(DIRECTORY
|
|||||||
install(FILES
|
install(FILES
|
||||||
scripting/appletscript.h
|
scripting/appletscript.h
|
||||||
scripting/dataenginescript.h
|
scripting/dataenginescript.h
|
||||||
#scripting/runnerscript.h
|
|
||||||
scripting/scriptengine.h
|
scripting/scriptengine.h
|
||||||
DESTINATION ${INCLUDE_INSTALL_DIR}/plasma/scripting COMPONENT Devel)
|
DESTINATION ${INCLUDE_INSTALL_DIR}/plasma/scripting COMPONENT Devel)
|
||||||
|
|
||||||
@ -215,7 +200,6 @@ install(FILES
|
|||||||
data/servicetypes/plasma-dataengine.desktop
|
data/servicetypes/plasma-dataengine.desktop
|
||||||
data/servicetypes/plasma-generic.desktop
|
data/servicetypes/plasma-generic.desktop
|
||||||
data/servicetypes/plasma-packagestructure.desktop
|
data/servicetypes/plasma-packagestructure.desktop
|
||||||
data/servicetypes/plasma-runner.desktop
|
|
||||||
data/servicetypes/plasma-scriptengine.desktop
|
data/servicetypes/plasma-scriptengine.desktop
|
||||||
data/servicetypes/plasma-service.desktop
|
data/servicetypes/plasma-service.desktop
|
||||||
data/servicetypes/plasma-shell.desktop
|
data/servicetypes/plasma-shell.desktop
|
||||||
|
@ -1,458 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2006-2007 Aaron Seigo <aseigo@kde.org>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Library General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Library General Public
|
|
||||||
* License along with this program; if not, write to the
|
|
||||||
* Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "abstractrunner.h"
|
|
||||||
|
|
||||||
#include <QtWidgets/QAction>
|
|
||||||
#include <QHash>
|
|
||||||
#include <QMenu>
|
|
||||||
#include <QMimeData>
|
|
||||||
#include <QMutex>
|
|
||||||
#include <QMutexLocker>
|
|
||||||
#include <QTimer>
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
#include <kplugininfo.h>
|
|
||||||
#include <kservicetypetrader.h>
|
|
||||||
#include <klocalizedstring.h>
|
|
||||||
#include <kiconloader.h>
|
|
||||||
#include <qstandardpaths.h>
|
|
||||||
|
|
||||||
#include "package.h"
|
|
||||||
#include "pluginloader.h"
|
|
||||||
#include "private/abstractrunner_p.h"
|
|
||||||
#include "querymatch.h"
|
|
||||||
#include "runnercontext.h"
|
|
||||||
#include "scripting/runnerscript.h"
|
|
||||||
|
|
||||||
namespace Plasma
|
|
||||||
{
|
|
||||||
|
|
||||||
AbstractRunner::AbstractRunner(QObject *parent, const QString &path)
|
|
||||||
: QObject(parent),
|
|
||||||
d(new AbstractRunnerPrivate(this))
|
|
||||||
{
|
|
||||||
d->init(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractRunner::AbstractRunner(const KService::Ptr service, QObject *parent)
|
|
||||||
: QObject(parent),
|
|
||||||
d(new AbstractRunnerPrivate(this))
|
|
||||||
{
|
|
||||||
d->init(service);
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractRunner::AbstractRunner(QObject *parent, const QVariantList &args)
|
|
||||||
: QObject(parent),
|
|
||||||
d(new AbstractRunnerPrivate(this))
|
|
||||||
{
|
|
||||||
if (args.count() > 0) {
|
|
||||||
KService::Ptr service = KService::serviceByStorageId(args[0].toString());
|
|
||||||
if (service) {
|
|
||||||
d->init(service);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractRunner::~AbstractRunner()
|
|
||||||
{
|
|
||||||
delete d;
|
|
||||||
}
|
|
||||||
|
|
||||||
KConfigGroup AbstractRunner::config() const
|
|
||||||
{
|
|
||||||
QString group = id();
|
|
||||||
if (group.isEmpty()) {
|
|
||||||
group = "UnnamedRunner";
|
|
||||||
}
|
|
||||||
|
|
||||||
KConfigGroup runners(KSharedConfig::openConfig(), "Runners");
|
|
||||||
return KConfigGroup(&runners, group);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRunner::reloadConfiguration()
|
|
||||||
{
|
|
||||||
if (d->script) {
|
|
||||||
emit d->script->reloadConfiguration();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRunner::addSyntax(const RunnerSyntax &syntax)
|
|
||||||
{
|
|
||||||
d->syntaxes.append(syntax);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRunner::setDefaultSyntax(const RunnerSyntax &syntax)
|
|
||||||
{
|
|
||||||
d->syntaxes.append(syntax);
|
|
||||||
d->defaultSyntax = &(d->syntaxes.last());
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRunner::setSyntaxes(const QList<RunnerSyntax> &syntaxes)
|
|
||||||
{
|
|
||||||
d->syntaxes = syntaxes;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<RunnerSyntax> AbstractRunner::syntaxes() const
|
|
||||||
{
|
|
||||||
return d->syntaxes;
|
|
||||||
}
|
|
||||||
|
|
||||||
RunnerSyntax *AbstractRunner::defaultSyntax() const
|
|
||||||
{
|
|
||||||
return d->defaultSyntax;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRunner::performMatch(Plasma::RunnerContext &localContext)
|
|
||||||
{
|
|
||||||
static const int reasonableRunTime = 1500;
|
|
||||||
static const int fastEnoughTime = 250;
|
|
||||||
|
|
||||||
if (d->suspendMatching) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QTime time;
|
|
||||||
time.restart();
|
|
||||||
|
|
||||||
//The local copy is already obtained in the job
|
|
||||||
match(localContext);
|
|
||||||
|
|
||||||
// automatically rate limit runners that become slooow
|
|
||||||
const int runtime = time.elapsed();
|
|
||||||
bool slowed = speed() == SlowSpeed;
|
|
||||||
|
|
||||||
if (!slowed && runtime > reasonableRunTime) {
|
|
||||||
// we punish runners that return too slowly, even if they don't bring
|
|
||||||
// back matches
|
|
||||||
#ifndef NDEBUG
|
|
||||||
// qDebug() << id() << "runner is too slow, putting it on the back burner.";
|
|
||||||
#endif
|
|
||||||
d->fastRuns = 0;
|
|
||||||
setSpeed(SlowSpeed);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (slowed && runtime < fastEnoughTime && localContext.query().size() > 2) {
|
|
||||||
++d->fastRuns;
|
|
||||||
|
|
||||||
if (d->fastRuns > 2) {
|
|
||||||
// we reward slowed runners who bring back matches fast enough
|
|
||||||
// 3 times in a row
|
|
||||||
#ifndef NDEBUG
|
|
||||||
// qDebug() << id() << "runner is faster than we thought, kicking it up a notch";
|
|
||||||
#endif
|
|
||||||
setSpeed(NormalSpeed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<QAction*> AbstractRunner::actionsForMatch(const Plasma::QueryMatch &match)
|
|
||||||
{
|
|
||||||
Q_UNUSED(match)
|
|
||||||
QList<QAction*> ret;
|
|
||||||
if (d->script) {
|
|
||||||
emit d->script->actionsForMatch(match, &ret);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* AbstractRunner::addAction(const QString &id, const QIcon &icon, const QString &text)
|
|
||||||
{
|
|
||||||
QAction *a = new QAction(icon, text, this);
|
|
||||||
d->actions.insert(id, a);
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRunner::addAction(const QString &id, QAction *action)
|
|
||||||
{
|
|
||||||
d->actions.insert(id, action);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRunner::removeAction(const QString &id)
|
|
||||||
{
|
|
||||||
QAction *a = d->actions.take(id);
|
|
||||||
delete a;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* AbstractRunner::action(const QString &id) const
|
|
||||||
{
|
|
||||||
return d->actions.value(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
QHash<QString, QAction*> AbstractRunner::actions() const
|
|
||||||
{
|
|
||||||
return d->actions;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRunner::clearActions()
|
|
||||||
{
|
|
||||||
qDeleteAll(d->actions);
|
|
||||||
d->actions.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
QMimeData *AbstractRunner::mimeDataForMatch(const QueryMatch &match)
|
|
||||||
{
|
|
||||||
Q_UNUSED(match)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AbstractRunner::hasRunOptions()
|
|
||||||
{
|
|
||||||
return d->hasRunOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRunner::setHasRunOptions(bool hasRunOptions)
|
|
||||||
{
|
|
||||||
d->hasRunOptions = hasRunOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRunner::createRunOptions(QWidget *parent)
|
|
||||||
{
|
|
||||||
if (d->script) {
|
|
||||||
emit d->script->createRunOptions(parent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractRunner::Speed AbstractRunner::speed() const
|
|
||||||
{
|
|
||||||
// the only time the read lock will fail is if we were slow are going to speed up
|
|
||||||
// or if we were fast and are going to slow down; so don't wait in this case, just
|
|
||||||
// say we're slow. we either will be soon or were just a moment ago and it doesn't
|
|
||||||
// hurt to do one more run the slow way
|
|
||||||
if (!d->speedLock.tryLockForRead()) {
|
|
||||||
return SlowSpeed;
|
|
||||||
}
|
|
||||||
Speed s = d->speed;
|
|
||||||
d->speedLock.unlock();
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRunner::setSpeed(Speed speed)
|
|
||||||
{
|
|
||||||
d->speedLock.lockForWrite();
|
|
||||||
d->speed = speed;
|
|
||||||
d->speedLock.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractRunner::Priority AbstractRunner::priority() const
|
|
||||||
{
|
|
||||||
return d->priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRunner::setPriority(Priority priority)
|
|
||||||
{
|
|
||||||
d->priority = priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
RunnerContext::Types AbstractRunner::ignoredTypes() const
|
|
||||||
{
|
|
||||||
return d->blackListed;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRunner::setIgnoredTypes(RunnerContext::Types types)
|
|
||||||
{
|
|
||||||
d->blackListed = types;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRunner::run(const Plasma::RunnerContext &search, const Plasma::QueryMatch &action)
|
|
||||||
{
|
|
||||||
if (d->script) {
|
|
||||||
return d->script->run(search, action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRunner::match(Plasma::RunnerContext &search)
|
|
||||||
{
|
|
||||||
if (d->script) {
|
|
||||||
return d->script->match(search);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AbstractRunner::name() const
|
|
||||||
{
|
|
||||||
if (d->runnerDescription.isValid()) {
|
|
||||||
return d->runnerDescription.name();
|
|
||||||
}
|
|
||||||
|
|
||||||
return objectName();
|
|
||||||
}
|
|
||||||
|
|
||||||
QIcon AbstractRunner::icon() const
|
|
||||||
{
|
|
||||||
if (d->runnerDescription.isValid()) {
|
|
||||||
return QIcon::fromTheme(d->runnerDescription.icon());
|
|
||||||
}
|
|
||||||
|
|
||||||
return QIcon();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AbstractRunner::id() const
|
|
||||||
{
|
|
||||||
if (d->runnerDescription.isValid()) {
|
|
||||||
return d->runnerDescription.pluginName();
|
|
||||||
}
|
|
||||||
|
|
||||||
return objectName();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AbstractRunner::description() const
|
|
||||||
{
|
|
||||||
if (d->runnerDescription.isValid()) {
|
|
||||||
return d->runnerDescription.property("Comment").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
return objectName();
|
|
||||||
}
|
|
||||||
|
|
||||||
Package AbstractRunner::package() const
|
|
||||||
{
|
|
||||||
return d->package ? *d->package : Package();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void AbstractRunner::init()
|
|
||||||
{
|
|
||||||
if (d->script) {
|
|
||||||
d->setupScriptSupport();
|
|
||||||
d->script->init();
|
|
||||||
}
|
|
||||||
|
|
||||||
reloadConfiguration();
|
|
||||||
}
|
|
||||||
|
|
||||||
DataEngine *AbstractRunner::dataEngine(const QString &name) const
|
|
||||||
{
|
|
||||||
return d->dataEngine(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AbstractRunner::isMatchingSuspended() const
|
|
||||||
{
|
|
||||||
return d->suspendMatching;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRunner::suspendMatching(bool suspend)
|
|
||||||
{
|
|
||||||
if (d->suspendMatching == suspend) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->suspendMatching = suspend;
|
|
||||||
emit matchingSuspended(suspend);
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractRunnerPrivate::AbstractRunnerPrivate(AbstractRunner *r)
|
|
||||||
: priority(AbstractRunner::NormalPriority),
|
|
||||||
speed(AbstractRunner::NormalSpeed),
|
|
||||||
blackListed(0),
|
|
||||||
script(0),
|
|
||||||
runner(r),
|
|
||||||
fastRuns(0),
|
|
||||||
package(0),
|
|
||||||
defaultSyntax(0),
|
|
||||||
hasRunOptions(false),
|
|
||||||
suspendMatching(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractRunnerPrivate::~AbstractRunnerPrivate()
|
|
||||||
{
|
|
||||||
delete script;
|
|
||||||
script = 0;
|
|
||||||
delete package;
|
|
||||||
package = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRunnerPrivate::init(const KService::Ptr service)
|
|
||||||
{
|
|
||||||
runnerDescription = KPluginInfo(service);
|
|
||||||
if (runnerDescription.isValid()) {
|
|
||||||
const QString api = runnerDescription.property("X-Plasma-API").toString();
|
|
||||||
if (!api.isEmpty()) {
|
|
||||||
const QString path = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "plasma/runners/" + runnerDescription.pluginName() + '/');
|
|
||||||
prepScripting(path, api);
|
|
||||||
if (!script) {
|
|
||||||
#ifndef NDEBUG
|
|
||||||
// qDebug() << "Could not create a(n)" << api << "ScriptEngine for the" << runnerDescription.name() << "Runner.";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRunnerPrivate::init(const QString &path)
|
|
||||||
{
|
|
||||||
runnerDescription = KPluginInfo(path + "/metadata.desktop");
|
|
||||||
const QString api = runnerDescription.property("X-Plasma-API").toString();
|
|
||||||
prepScripting(path, api);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AbstractRunnerPrivate::prepScripting(const QString &path, const QString &api)
|
|
||||||
{
|
|
||||||
if (script) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete package;
|
|
||||||
package = 0;
|
|
||||||
|
|
||||||
if (api.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
package = new Package(PluginLoader::self()->loadPackage("Plasma/Runner", api));
|
|
||||||
package->setPath(path);
|
|
||||||
|
|
||||||
if (!package->isValid()) {
|
|
||||||
#ifndef NDEBUG
|
|
||||||
// qDebug() << "Invalid Runner package at" << path;
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
script = Plasma::loadScriptEngine(api, runner);
|
|
||||||
if (!script) {
|
|
||||||
delete package;
|
|
||||||
package = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// put all setup routines for script here. at this point we can assume that
|
|
||||||
// package exists and that we have a script engine
|
|
||||||
void AbstractRunnerPrivate::setupScriptSupport()
|
|
||||||
{
|
|
||||||
if (!package) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
// qDebug() << "setting up script support, package is in" << package->path()
|
|
||||||
// << ", main script is" << package->filePath("mainscript");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// FIXME: Replace with ki18n functionality once semantics is clear.
|
|
||||||
// const QString translationsPath = package->filePath("translations");
|
|
||||||
// if (!translationsPath.isEmpty()) {
|
|
||||||
// KGlobal::dirs()->addResourceDir("locale", translationsPath);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
} // Plasma namespace
|
|
||||||
|
|
||||||
|
|
||||||
#include "moc_abstractrunner.cpp"
|
|
@ -1,472 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2006-2007 Aaron Seigo <aseigo@kde.org>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Library General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Library General Public License for more details
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Library General Public
|
|
||||||
* License along with this program; if not, write to the
|
|
||||||
* Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PLASMA_ABSTRACTRUNNER_H
|
|
||||||
#define PLASMA_ABSTRACTRUNNER_H
|
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <QtCore/QMutex>
|
|
||||||
#include <QtCore/QStringList>
|
|
||||||
#include <QIcon>
|
|
||||||
|
|
||||||
#include <kconfiggroup.h>
|
|
||||||
#include <kservice.h>
|
|
||||||
|
|
||||||
#include <plasma/plasma_export.h>
|
|
||||||
#include <plasma/querymatch.h>
|
|
||||||
#include <plasma/runnercontext.h>
|
|
||||||
#include <plasma/runnersyntax.h>
|
|
||||||
#include <plasma/version.h>
|
|
||||||
|
|
||||||
class QAction;
|
|
||||||
class QMimeData;
|
|
||||||
|
|
||||||
class KCompletion;
|
|
||||||
|
|
||||||
namespace Plasma
|
|
||||||
{
|
|
||||||
|
|
||||||
class DataEngine;
|
|
||||||
class Package;
|
|
||||||
class RunnerScript;
|
|
||||||
class QueryMatch;
|
|
||||||
class AbstractRunnerPrivate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @class AbstractRunner plasma/abstractrunner.h <Plasma/AbstractRunner>
|
|
||||||
*
|
|
||||||
* @short An abstract base class for Plasma Runner plugins.
|
|
||||||
*
|
|
||||||
* Be aware that runners have to be thread-safe. This is due to the fact that
|
|
||||||
* each runner is executed in its own thread for each new term. Thus, a runner
|
|
||||||
* may be executed more than once at the same time. See match() for details.
|
|
||||||
* To let krunner expose a global shortcut for the single runner query mode, the runner
|
|
||||||
* must set the "X-Plasma-AdvertiseSingleRunnerMode" key to true in the .desktop file
|
|
||||||
* and set a default syntax. See setDefaultSyntax() for details.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class PLASMA_EXPORT AbstractRunner : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
Q_PROPERTY(bool matchingSuspended READ isMatchingSuspended WRITE suspendMatching NOTIFY matchingSuspended)
|
|
||||||
Q_PROPERTY(QString id READ id)
|
|
||||||
Q_PROPERTY(QString description READ description)
|
|
||||||
Q_PROPERTY(QString name READ name)
|
|
||||||
Q_PROPERTY(QIcon icon READ icon)
|
|
||||||
public:
|
|
||||||
/** Specifies a nominal speed for the runner */
|
|
||||||
enum Speed {
|
|
||||||
SlowSpeed,
|
|
||||||
NormalSpeed
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Specifies a priority for the runner */
|
|
||||||
enum Priority {
|
|
||||||
LowestPriority = 0,
|
|
||||||
LowPriority,
|
|
||||||
NormalPriority,
|
|
||||||
HighPriority,
|
|
||||||
HighestPriority
|
|
||||||
};
|
|
||||||
|
|
||||||
/** An ordered list of runners */
|
|
||||||
typedef QList<AbstractRunner*> List;
|
|
||||||
|
|
||||||
virtual ~AbstractRunner();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is the main query method. It should trigger creation of
|
|
||||||
* QueryMatch instances through RunnerContext::addMatch and
|
|
||||||
* RunnerContext::addMatches. It is called internally by performMatch().
|
|
||||||
*
|
|
||||||
* If the runner can run precisely the requested term (RunnerContext::query()),
|
|
||||||
* it should create an exact match by setting the type to RunnerContext::ExactMatch.
|
|
||||||
* The first runner that creates a QueryMatch will be the
|
|
||||||
* default runner. Other runner's matches will be suggested in the
|
|
||||||
* interface. Non-exact matches should be offered via RunnerContext::PossibleMatch.
|
|
||||||
*
|
|
||||||
* The match will be activated via run() if the user selects it.
|
|
||||||
*
|
|
||||||
* Each runner is executed in its own thread. Whenever the user input changes this
|
|
||||||
* method is called again. Thus, it needs to be thread-safe. Also, all matches need
|
|
||||||
* to be reported once this method returns. Asynchronous runners therefore need
|
|
||||||
* to make use of a local event loop to wait for all matches.
|
|
||||||
*
|
|
||||||
* It is recommended to use local status data in async runners. The simplest way is
|
|
||||||
* to have a separate class doing all the work like so:
|
|
||||||
*
|
|
||||||
* \code
|
|
||||||
* void MyFancyAsyncRunner::match( RunnerContext& context )
|
|
||||||
* {
|
|
||||||
* QEventLoop loop;
|
|
||||||
* MyAsyncWorker worker( context );
|
|
||||||
* connect( &worker, SIGNAL(finished()),
|
|
||||||
* &loop, SLOT(quit()) );
|
|
||||||
* worker.work();
|
|
||||||
* loop.exec();
|
|
||||||
* }
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* Here MyAsyncWorker creates all the matches and calls RunnerContext::addMatch
|
|
||||||
* in some internal slot. It emits the finished() signal once done which will
|
|
||||||
* quit the loop and make the match() method return. The local status is kept
|
|
||||||
* entirely in MyAsyncWorker which makes match() trivially thread-safe.
|
|
||||||
*
|
|
||||||
* If a particular match supports multiple actions, set up the corresponding
|
|
||||||
* actions in the actionsForMatch method. Do not call any of the action methods
|
|
||||||
* within this method!
|
|
||||||
*
|
|
||||||
* Execution of the correct action should be handled in the run method.
|
|
||||||
* @caution This method needs to be thread-safe since KRunner will simply
|
|
||||||
* start a new thread for each new term.
|
|
||||||
*
|
|
||||||
* @warning Returning from this method means to end execution of the runner.
|
|
||||||
*
|
|
||||||
* @sa run(), RunnerContext::addMatch, RunnerContext::addMatches, QueryMatch
|
|
||||||
*/
|
|
||||||
virtual void match(Plasma::RunnerContext &context);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Triggers a call to match. This will call match() internally.
|
|
||||||
*
|
|
||||||
* @param context the search context used in executing this match.
|
|
||||||
*/
|
|
||||||
void performMatch(Plasma::RunnerContext &context);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the runner has options that the user can interact with to modify
|
|
||||||
* what happens when run or one of the actions created in match
|
|
||||||
* is called, the runner should return true
|
|
||||||
*/
|
|
||||||
bool hasRunOptions();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If hasRunOptions() returns true, this method may be called to get
|
|
||||||
* a widget displaying the options the user can interact with to modify
|
|
||||||
* the behaviour of what happens when a given match is selected.
|
|
||||||
*
|
|
||||||
* @param widget the parent of the options widgets.
|
|
||||||
*/
|
|
||||||
virtual void createRunOptions(QWidget *widget);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called whenever an exact or possible match associated with this
|
|
||||||
* runner is triggered.
|
|
||||||
*
|
|
||||||
* @param context The context in which the match is triggered, i.e. for which
|
|
||||||
* the match was created.
|
|
||||||
* @param match The actual match to run/execute.
|
|
||||||
*/
|
|
||||||
virtual void run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The nominal speed of the runner.
|
|
||||||
* @see setSpeed
|
|
||||||
*/
|
|
||||||
Speed speed() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The priority of the runner.
|
|
||||||
* @see setPriority
|
|
||||||
*/
|
|
||||||
Priority priority() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the OR'ed value of all the Information types (as defined in RunnerContext::Type)
|
|
||||||
* this runner is not interested in.
|
|
||||||
* @return OR'ed value of black listed types
|
|
||||||
*/
|
|
||||||
RunnerContext::Types ignoredTypes() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the types this runner will ignore
|
|
||||||
* @param types OR'ed listed of ignored types
|
|
||||||
*/
|
|
||||||
void setIgnoredTypes(RunnerContext::Types types);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the user visible engine name for the Runner
|
|
||||||
*/
|
|
||||||
QString name() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return an id string for the Runner
|
|
||||||
*/
|
|
||||||
QString id() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the description of this Runner
|
|
||||||
*/
|
|
||||||
QString description() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the icon for this Runner
|
|
||||||
*/
|
|
||||||
QIcon icon() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Accessor for the associated Package object if any.
|
|
||||||
*
|
|
||||||
* Note that the returned pointer is only valid for the lifetime of
|
|
||||||
* the runner.
|
|
||||||
*
|
|
||||||
* @return the Package object, which may be invalid
|
|
||||||
**/
|
|
||||||
Package package() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Signal runner to reload its configuration.
|
|
||||||
*/
|
|
||||||
virtual void reloadConfiguration();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the syntaxes the runner has registered that it accepts and understands
|
|
||||||
* @since 4.3
|
|
||||||
*/
|
|
||||||
QList<RunnerSyntax> syntaxes() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the default syntax for the runner or 0 if no default syntax has been defined
|
|
||||||
*
|
|
||||||
* @since 4.4
|
|
||||||
*/
|
|
||||||
RunnerSyntax *defaultSyntax() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true if the runner is currently busy with non-interuptable work, signaling that
|
|
||||||
* new threads should not be created for it at this time
|
|
||||||
* @since 4.6
|
|
||||||
*/
|
|
||||||
bool isMatchingSuspended() const;
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
/**
|
|
||||||
* This signal is emitted when matching is about to commence, giving runners
|
|
||||||
* an opportunity to prepare themselves, e.g. loading data sets or preparing
|
|
||||||
* IPC or network connections. This method should be fast so as not to cause
|
|
||||||
* slow downs. Things that take longer or which should be loaded once and
|
|
||||||
* remain extant for the lifespan of the AbstractRunner should be done in init().
|
|
||||||
* @see init()
|
|
||||||
* @since 4.4
|
|
||||||
*/
|
|
||||||
void prepare();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This signal is emitted when a session of matches is complete, giving runners
|
|
||||||
* the opportunity to tear down anything set up as a result of the prepare()
|
|
||||||
* method.
|
|
||||||
* @since 4.4
|
|
||||||
*/
|
|
||||||
void teardown();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Emitted when the runner enters or exits match suspension
|
|
||||||
* @see matchingSuspended
|
|
||||||
* @since 4.6
|
|
||||||
*/
|
|
||||||
void matchingSuspended(bool suspended);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
friend class RunnerManager;
|
|
||||||
friend class RunnerManagerPrivate;
|
|
||||||
|
|
||||||
explicit AbstractRunner(QObject *parent = 0, const QString &path = QString());
|
|
||||||
explicit AbstractRunner(const KService::Ptr service, QObject *parent = 0);
|
|
||||||
|
|
||||||
AbstractRunner(QObject *parent, const QVariantList &args);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets whether or not the runner is available for match requests. Useful to
|
|
||||||
* prevent more thread spawning when the thread is in a busy state.
|
|
||||||
*/
|
|
||||||
void suspendMatching(bool suspend);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides access to the runner's configuration object.
|
|
||||||
*/
|
|
||||||
KConfigGroup config() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets whether or not the runner has options for matches
|
|
||||||
*/
|
|
||||||
void setHasRunOptions(bool hasRunOptions);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the nominal speed of the runner. Only slow runners need
|
|
||||||
* to call this within their constructor because the default
|
|
||||||
* speed is NormalSpeed. Runners that use DBUS should call
|
|
||||||
* this within their constructors.
|
|
||||||
*/
|
|
||||||
void setSpeed(Speed newSpeed);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the priority of the runner. Lower priority runners are executed
|
|
||||||
* only after higher priority runners.
|
|
||||||
*/
|
|
||||||
void setPriority(Priority newPriority);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A given match can have more than action that can be performed on it.
|
|
||||||
* For example, a song match returned by a music player runner can be queued,
|
|
||||||
* added to the playlist, or played.
|
|
||||||
*
|
|
||||||
* Call this method to add actions that can be performed by the runner.
|
|
||||||
* Actions must first be added to the runner's action registry.
|
|
||||||
* Note: execution of correct action is left up to the runner.
|
|
||||||
*/
|
|
||||||
virtual QList<QAction*> actionsForMatch(const Plasma::QueryMatch &match);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates and then adds an action to the action registry.
|
|
||||||
* AbstractRunner assumes ownership of the created action.
|
|
||||||
*
|
|
||||||
* @param id A unique identifier string
|
|
||||||
* @param icon The icon to display
|
|
||||||
* @param text The text to display
|
|
||||||
* @return the created QAction
|
|
||||||
*/
|
|
||||||
QAction* addAction(const QString &id, const QIcon &icon, const QString &text);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an action to the runner's action registry.
|
|
||||||
*
|
|
||||||
* The QAction must be created within the GUI thread;
|
|
||||||
* do not create it within the match method of AbstractRunner.
|
|
||||||
*
|
|
||||||
* @param id A unique identifier string
|
|
||||||
* @param action The QAction to be stored
|
|
||||||
*/
|
|
||||||
void addAction(const QString &id, QAction *action);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes the action from the action registry.
|
|
||||||
* AbstractRunner deletes the action once removed.
|
|
||||||
*
|
|
||||||
* @param id The id of the action to be removed
|
|
||||||
*/
|
|
||||||
void removeAction(const QString &id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the action associated with the id
|
|
||||||
*/
|
|
||||||
QAction* action(const QString &id) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns all registered actions
|
|
||||||
*/
|
|
||||||
QHash<QString, QAction*> actions() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clears the action registry.
|
|
||||||
* The action pool deletes the actions.
|
|
||||||
*/
|
|
||||||
void clearActions();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a registered syntax that this runner understands. This is used to
|
|
||||||
* display to the user what this runner can understand and how it can be
|
|
||||||
* used.
|
|
||||||
*
|
|
||||||
* @param syntax the syntax to register
|
|
||||||
* @since 4.3
|
|
||||||
*/
|
|
||||||
void addSyntax(const RunnerSyntax &syntax);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set @p syntax as the default syntax for the runner; the default syntax will be
|
|
||||||
* substituted to the empty query in single runner mode. This is also used to
|
|
||||||
* display to the user what this runner can understand and how it can be
|
|
||||||
* used.
|
|
||||||
* The default syntax is automatically added to the list of registered syntaxes, there
|
|
||||||
* is no need to add it using addSyntax.
|
|
||||||
* Note that there can be only one default syntax; if called more than once, the last
|
|
||||||
* call will determine the default syntax.
|
|
||||||
* A default syntax (even trivial) is required to advertise single runner mode
|
|
||||||
*
|
|
||||||
* @param syntax the syntax to register and to set as default
|
|
||||||
* @since 4.4
|
|
||||||
**/
|
|
||||||
void setDefaultSyntax(const RunnerSyntax &syntax);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the list of syntaxes; passing in an empty list effectively clears
|
|
||||||
* the syntaxes.
|
|
||||||
*
|
|
||||||
* @param the syntaxes to register for this runner
|
|
||||||
* @since 4.3
|
|
||||||
*/
|
|
||||||
void setSyntaxes(const QList<RunnerSyntax> &syns);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads the given DataEngine
|
|
||||||
*
|
|
||||||
* Tries to load the data engine given by @p name. Each engine is
|
|
||||||
* only loaded once, and that instance is re-used on all subsequent
|
|
||||||
* requests.
|
|
||||||
*
|
|
||||||
* If the data engine was not found, an invalid data engine is returned
|
|
||||||
* (see DataEngine::isValid()).
|
|
||||||
*
|
|
||||||
* Note that you should <em>not</em> delete the returned engine.
|
|
||||||
*
|
|
||||||
* @param name Name of the data engine to load
|
|
||||||
* @return pointer to the data engine if it was loaded,
|
|
||||||
* or an invalid data engine if the requested engine
|
|
||||||
* could not be loaded
|
|
||||||
*
|
|
||||||
* @since 4.4
|
|
||||||
*/
|
|
||||||
Q_INVOKABLE DataEngine *dataEngine(const QString &name) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reimplement this slot to run any initialization routines on first load.
|
|
||||||
* By default, it calls reloadConfiguration(); for scripted Runners this
|
|
||||||
* method also sets up the ScriptEngine.
|
|
||||||
*/
|
|
||||||
virtual void init();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reimplement this slot if you want your runner
|
|
||||||
* to support serialization and drag and drop
|
|
||||||
* @since 4.5
|
|
||||||
*/
|
|
||||||
virtual QMimeData *mimeDataForMatch(const Plasma::QueryMatch &match);
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class RunnerScript;
|
|
||||||
|
|
||||||
AbstractRunnerPrivate *const d;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // Plasma namespace
|
|
||||||
|
|
||||||
#define K_EXPORT_PLASMA_RUNNER( libname, classname ) \
|
|
||||||
K_PLUGIN_FACTORY(factory, registerPlugin<classname>();) \
|
|
||||||
K_EXPORT_PLUGIN_VERSION(PLASMA_VERSION)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* These plugins are Used by the plugin selector dialog to show
|
|
||||||
* configuration options specific to this runner. These options
|
|
||||||
* must be runner global and not pertain to a specific match.
|
|
||||||
*/
|
|
||||||
#define K_EXPORT_RUNNER_CONFIG( name, classname ) \
|
|
||||||
K_PLUGIN_FACTORY(ConfigFactory, registerPlugin<classname>();) \
|
|
||||||
K_EXPORT_PLUGIN_VERSION(PLASMA_VERSION)
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,32 +0,0 @@
|
|||||||
[Desktop Entry]
|
|
||||||
Type=ServiceType
|
|
||||||
X-KDE-ServiceType=Plasma/Runner
|
|
||||||
|
|
||||||
Comment=KRunner plugin
|
|
||||||
Comment[bs]=Priključak za KRunner
|
|
||||||
Comment[cs]=Modul KRunneru
|
|
||||||
Comment[de]=KRunner-Modul
|
|
||||||
Comment[es]=Complemento para KRunner
|
|
||||||
Comment[fi]=KRunner-liitännäinen
|
|
||||||
Comment[fr]=Module externe de KRunner
|
|
||||||
Comment[mr]=KRunner प्लगइन
|
|
||||||
Comment[nl]=KRunner-plugin
|
|
||||||
Comment[pl]=Wtyczka KRunner
|
|
||||||
Comment[pt]='Plugin' do KRunner
|
|
||||||
Comment[pt_BR]=Plugin do KRunner
|
|
||||||
Comment[sk]=KRunner modul
|
|
||||||
Comment[sv]=Krunner-insticksprogram
|
|
||||||
Comment[tr]=KRunner eklentisi
|
|
||||||
Comment[ug]=KRunner قىستۇرما
|
|
||||||
Comment[uk]=Додаток до KRunner
|
|
||||||
Comment[x-test]=xxKRunner pluginxx
|
|
||||||
|
|
||||||
[PropertyDef::X-Plasma-AdvertiseSingleRunnerQueryMode]
|
|
||||||
Type=bool
|
|
||||||
|
|
||||||
[PropertyDef::TryExec]
|
|
||||||
Type=QString
|
|
||||||
|
|
||||||
[PropertyDef::X-Plasma-Args]
|
|
||||||
Type=QStringList
|
|
||||||
|
|
@ -1 +0,0 @@
|
|||||||
#include "../../plasma/abstractrunner.h"
|
|
@ -1 +0,0 @@
|
|||||||
#include "../../plasma/querymatch.h"
|
|
@ -1 +0,0 @@
|
|||||||
#include "../../plasma/runnercontext.h"
|
|
@ -1 +0,0 @@
|
|||||||
#include "../../plasma/runnermanager.h"
|
|
@ -1 +0,0 @@
|
|||||||
#include "../../plasma/scripting/runnerscript.h"
|
|
@ -33,7 +33,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "applet.h"
|
#include "applet.h"
|
||||||
#include "abstractrunner.h"
|
|
||||||
#include "containment.h"
|
#include "containment.h"
|
||||||
#include "containmentactions.h"
|
#include "containmentactions.h"
|
||||||
#include "dataengine.h"
|
#include "dataengine.h"
|
||||||
|
@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2006-2009 Aaron Seigo <aseigo@kde.org>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Library General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Library General Public
|
|
||||||
* License along with this program; if not, write to the
|
|
||||||
* Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ABSTRACTRUNNER_P_H
|
|
||||||
#define ABSTRACTRUNNER_P_H
|
|
||||||
|
|
||||||
#include <QReadWriteLock>
|
|
||||||
|
|
||||||
#include "dataengineconsumer.h"
|
|
||||||
|
|
||||||
namespace Plasma
|
|
||||||
{
|
|
||||||
|
|
||||||
class AbstractRunner;
|
|
||||||
|
|
||||||
class AbstractRunnerPrivate : public DataEngineConsumer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AbstractRunnerPrivate(AbstractRunner *r);
|
|
||||||
~AbstractRunnerPrivate();
|
|
||||||
void init(const KService::Ptr service);
|
|
||||||
void init(const QString &path);
|
|
||||||
void prepScripting(const QString &path, const QString &api);
|
|
||||||
void setupScriptSupport();
|
|
||||||
|
|
||||||
AbstractRunner::Priority priority;
|
|
||||||
AbstractRunner::Speed speed;
|
|
||||||
RunnerContext::Types blackListed;
|
|
||||||
RunnerScript *script;
|
|
||||||
KPluginInfo runnerDescription;
|
|
||||||
AbstractRunner *runner;
|
|
||||||
int fastRuns;
|
|
||||||
QReadWriteLock speedLock;
|
|
||||||
Package *package;
|
|
||||||
QHash<QString, QAction*> actions;
|
|
||||||
QList<RunnerSyntax> syntaxes;
|
|
||||||
RunnerSyntax *defaultSyntax;
|
|
||||||
bool hasRunOptions : 1;
|
|
||||||
bool suspendMatching : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Plasma
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
@ -1,214 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007, 2009 Ryan P. Bitanga <ryan.bitanga@gmail.com>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Library General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Library General Public
|
|
||||||
* License along with this program; if not, write to the
|
|
||||||
* Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "runnerjobs_p.h"
|
|
||||||
|
|
||||||
#include <QTimer>
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
#include "runnermanager.h"
|
|
||||||
#include "plasma/querymatch.h"
|
|
||||||
|
|
||||||
using ThreadWeaver::Job;
|
|
||||||
using ThreadWeaver::Queue;
|
|
||||||
|
|
||||||
namespace Plasma {
|
|
||||||
|
|
||||||
DelayedRunnerPolicy::DelayedRunnerPolicy()
|
|
||||||
: QueuePolicy()
|
|
||||||
{}
|
|
||||||
|
|
||||||
DelayedRunnerPolicy::~DelayedRunnerPolicy()
|
|
||||||
{}
|
|
||||||
|
|
||||||
DelayedRunnerPolicy& DelayedRunnerPolicy::instance()
|
|
||||||
{
|
|
||||||
static DelayedRunnerPolicy policy;
|
|
||||||
return policy;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DelayedRunnerPolicy::canRun(ThreadWeaver::JobPointer job)
|
|
||||||
{
|
|
||||||
QSharedPointer<FindMatchesJob> aJob(job.dynamicCast<FindMatchesJob>());
|
|
||||||
if (QTimer *t = aJob->delayTimer()) {
|
|
||||||
// If the timer is active, the required delay has not been reached
|
|
||||||
//qDebug() << "delayed timer" << aJob->runner()->name() << !t->isActive();
|
|
||||||
return !t->isActive();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DelayedRunnerPolicy::free(ThreadWeaver::JobPointer job)
|
|
||||||
{
|
|
||||||
Q_UNUSED(job)
|
|
||||||
}
|
|
||||||
|
|
||||||
void DelayedRunnerPolicy::release(ThreadWeaver::JobPointer job)
|
|
||||||
{
|
|
||||||
free(job);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DelayedRunnerPolicy::destructed(ThreadWeaver::JobInterface* job)
|
|
||||||
{
|
|
||||||
Q_UNUSED(job)
|
|
||||||
}
|
|
||||||
|
|
||||||
DefaultRunnerPolicy::DefaultRunnerPolicy()
|
|
||||||
: QueuePolicy(),
|
|
||||||
m_cap(2)
|
|
||||||
{}
|
|
||||||
|
|
||||||
DefaultRunnerPolicy::~DefaultRunnerPolicy()
|
|
||||||
{}
|
|
||||||
|
|
||||||
DefaultRunnerPolicy& DefaultRunnerPolicy::instance()
|
|
||||||
{
|
|
||||||
static DefaultRunnerPolicy policy;
|
|
||||||
return policy;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DefaultRunnerPolicy::canRun(ThreadWeaver::JobPointer job)
|
|
||||||
{
|
|
||||||
Plasma::AbstractRunner *runner = job.dynamicCast<FindMatchesJob>()->runner();
|
|
||||||
QMutexLocker l(&m_mutex);
|
|
||||||
|
|
||||||
if (m_runCounts[runner->name()] > m_cap) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
++m_runCounts[runner->name()];
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DefaultRunnerPolicy::free(ThreadWeaver::JobPointer job)
|
|
||||||
{
|
|
||||||
Plasma::AbstractRunner *runner = job.dynamicCast<FindMatchesJob>()->runner();
|
|
||||||
QMutexLocker l(&m_mutex);
|
|
||||||
|
|
||||||
--m_runCounts[runner->name()];
|
|
||||||
}
|
|
||||||
|
|
||||||
void DefaultRunnerPolicy::release(ThreadWeaver::JobPointer job)
|
|
||||||
{
|
|
||||||
free(job);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DefaultRunnerPolicy::destructed(ThreadWeaver::JobInterface* job)
|
|
||||||
{
|
|
||||||
Q_UNUSED(job)
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////
|
|
||||||
// Jobs
|
|
||||||
////////////////////
|
|
||||||
|
|
||||||
FindMatchesJob::FindMatchesJob(Plasma::AbstractRunner *runner,
|
|
||||||
Plasma::RunnerContext *context, QObject *parent)
|
|
||||||
: ThreadWeaver::Job(),
|
|
||||||
m_context(*context, 0),
|
|
||||||
m_runner(runner),
|
|
||||||
m_timer(0),
|
|
||||||
m_decorator(new ThreadWeaver::QObjectDecorator(this, true))
|
|
||||||
{
|
|
||||||
if (runner->speed() == Plasma::AbstractRunner::SlowSpeed) {
|
|
||||||
assignQueuePolicy(&DelayedRunnerPolicy::instance());
|
|
||||||
} else {
|
|
||||||
assignQueuePolicy(&DefaultRunnerPolicy::instance());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FindMatchesJob::~FindMatchesJob()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QTimer* FindMatchesJob::delayTimer() const
|
|
||||||
{
|
|
||||||
return m_timer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FindMatchesJob::setDelayTimer(QTimer *timer)
|
|
||||||
{
|
|
||||||
m_timer = timer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FindMatchesJob::run(ThreadWeaver::JobPointer, ThreadWeaver::Thread*)
|
|
||||||
{
|
|
||||||
// qDebug() << "Running match for " << m_runner->objectName()
|
|
||||||
// << " in Thread " << thread()->id() << endl;
|
|
||||||
if (m_context.isValid()) {
|
|
||||||
m_runner->performMatch(m_context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int FindMatchesJob::priority() const
|
|
||||||
{
|
|
||||||
return m_runner->priority();
|
|
||||||
}
|
|
||||||
|
|
||||||
Plasma::AbstractRunner* FindMatchesJob::runner() const
|
|
||||||
{
|
|
||||||
return m_runner;
|
|
||||||
}
|
|
||||||
|
|
||||||
DelayedJobCleaner::DelayedJobCleaner(const QSet<QSharedPointer<FindMatchesJob> > &jobs, const QSet<AbstractRunner *> &runners)
|
|
||||||
: QObject(Queue::instance()),
|
|
||||||
m_weaver(Queue::instance()),
|
|
||||||
m_jobs(jobs),
|
|
||||||
m_runners(runners)
|
|
||||||
{
|
|
||||||
connect(m_weaver, SIGNAL(finished()), this, SLOT(checkIfFinished()));
|
|
||||||
|
|
||||||
for (auto it = m_jobs.constBegin(); it != m_jobs.constEnd(); ++it) {
|
|
||||||
connect((*it)->decorator(), &ThreadWeaver::QObjectDecorator::done, this, &DelayedJobCleaner::jobDone);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DelayedJobCleaner::~DelayedJobCleaner()
|
|
||||||
{
|
|
||||||
qDeleteAll(m_runners);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DelayedJobCleaner::jobDone(ThreadWeaver::JobPointer job)
|
|
||||||
{
|
|
||||||
auto runJob = job.dynamicCast<FindMatchesJob>();
|
|
||||||
|
|
||||||
if (!runJob) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_jobs.remove(runJob);
|
|
||||||
|
|
||||||
if (m_jobs.isEmpty()) {
|
|
||||||
deleteLater();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DelayedJobCleaner::checkIfFinished()
|
|
||||||
{
|
|
||||||
if (m_weaver->isIdle()) {
|
|
||||||
m_jobs.clear();
|
|
||||||
deleteLater();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // Plasma namespace
|
|
||||||
|
|
@ -1,135 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007, 2009 Ryan P. Bitanga <ryan.bitanga@gmail.com>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Library General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Library General Public
|
|
||||||
* License along with this program; if not, write to the
|
|
||||||
* Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PLASMA_RUNNERJOBS_P_H
|
|
||||||
#define PLASMA_RUNNERJOBS_P_H
|
|
||||||
|
|
||||||
#include <QHash>
|
|
||||||
#include <QMutex>
|
|
||||||
#include <QSet>
|
|
||||||
|
|
||||||
#include <ThreadWeaver/Job>
|
|
||||||
#include <ThreadWeaver/QueuePolicy>
|
|
||||||
#include <ThreadWeaver/Queue>
|
|
||||||
#include <ThreadWeaver/QObjectDecorator>
|
|
||||||
|
|
||||||
#include "abstractrunner.h"
|
|
||||||
|
|
||||||
using ThreadWeaver::Job;
|
|
||||||
|
|
||||||
class QTimer;
|
|
||||||
|
|
||||||
namespace Plasma {
|
|
||||||
// Queue policies
|
|
||||||
|
|
||||||
// QueuePolicy that only allows a job to be executed after
|
|
||||||
// waiting in the queue for the specified timeout
|
|
||||||
class DelayedRunnerPolicy : public ThreadWeaver::QueuePolicy
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
~DelayedRunnerPolicy();
|
|
||||||
|
|
||||||
static DelayedRunnerPolicy &instance();
|
|
||||||
|
|
||||||
bool canRun(ThreadWeaver::JobPointer job);
|
|
||||||
void free(ThreadWeaver::JobPointer job);
|
|
||||||
void release(ThreadWeaver::JobPointer job);
|
|
||||||
virtual void destructed(ThreadWeaver::JobInterface* job);
|
|
||||||
|
|
||||||
private:
|
|
||||||
DelayedRunnerPolicy();
|
|
||||||
QMutex m_mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
// QueuePolicy that limits the instances of a particular runner
|
|
||||||
class DefaultRunnerPolicy : public ThreadWeaver::QueuePolicy
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
~DefaultRunnerPolicy();
|
|
||||||
|
|
||||||
static DefaultRunnerPolicy &instance();
|
|
||||||
|
|
||||||
void setCap(int cap)
|
|
||||||
{
|
|
||||||
m_cap = cap;
|
|
||||||
}
|
|
||||||
int cap() const
|
|
||||||
{
|
|
||||||
return m_cap;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool canRun(ThreadWeaver::JobPointer job);
|
|
||||||
void free(ThreadWeaver::JobPointer job);
|
|
||||||
void release(ThreadWeaver::JobPointer job);
|
|
||||||
void destructed(ThreadWeaver::JobInterface* job);
|
|
||||||
private:
|
|
||||||
DefaultRunnerPolicy();
|
|
||||||
|
|
||||||
int m_cap;
|
|
||||||
QHash<QString, int> m_runCounts;
|
|
||||||
QMutex m_mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FindMatchesJob class
|
|
||||||
* Class to run queries in different threads
|
|
||||||
*/
|
|
||||||
class FindMatchesJob : public Job
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FindMatchesJob(Plasma::AbstractRunner *runner,
|
|
||||||
Plasma::RunnerContext *context, QObject *parent = 0);
|
|
||||||
~FindMatchesJob();
|
|
||||||
|
|
||||||
int priority() const;
|
|
||||||
Plasma::AbstractRunner* runner() const;
|
|
||||||
|
|
||||||
QTimer* delayTimer() const;
|
|
||||||
void setDelayTimer(QTimer *timer);
|
|
||||||
ThreadWeaver::QObjectDecorator* decorator() const { return m_decorator; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void run(ThreadWeaver::JobPointer self, ThreadWeaver::Thread* thread);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Plasma::RunnerContext m_context;
|
|
||||||
Plasma::AbstractRunner *m_runner;
|
|
||||||
QTimer *m_timer;
|
|
||||||
ThreadWeaver::QObjectDecorator* m_decorator;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DelayedJobCleaner : public QObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
DelayedJobCleaner(const QSet<QSharedPointer<FindMatchesJob> > &jobs, const QSet<AbstractRunner *> &runners = QSet<AbstractRunner *>());
|
|
||||||
~DelayedJobCleaner();
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void jobDone(ThreadWeaver::JobPointer);
|
|
||||||
void checkIfFinished();
|
|
||||||
|
|
||||||
private:
|
|
||||||
ThreadWeaver::Queue *m_weaver;
|
|
||||||
QSet<QSharedPointer<FindMatchesJob> > m_jobs;
|
|
||||||
QSet<AbstractRunner *> m_runners;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // PLASMA_RUNNERJOBS_P_H
|
|
@ -36,7 +36,6 @@
|
|||||||
//Plasma
|
//Plasma
|
||||||
#include "applet.h"
|
#include "applet.h"
|
||||||
#include "dataengine.h"
|
#include "dataengine.h"
|
||||||
#include "abstractrunner.h"
|
|
||||||
#include "storagethread_p.h"
|
#include "storagethread_p.h"
|
||||||
|
|
||||||
|
|
||||||
@ -137,12 +136,6 @@ Storage::Storage(QObject* parent)
|
|||||||
m_clientName = engine->pluginInfo().pluginName();
|
m_clientName = engine->pluginInfo().pluginName();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Plasma::AbstractRunner *runner = qobject_cast<Plasma::AbstractRunner *>(parentObject);
|
|
||||||
if (runner) {
|
|
||||||
m_clientName = runner->id();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_clientName = m_clientName.replace('.', "_");
|
m_clientName = m_clientName.replace('.', "_");
|
||||||
|
@ -1,322 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2006-2007 Aaron Seigo <aseigo@kde.org>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Library General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Library General Public
|
|
||||||
* License along with this program; if not, write to the
|
|
||||||
* Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "querymatch.h"
|
|
||||||
|
|
||||||
#include <QtWidgets/QAction>
|
|
||||||
#include <QIcon>
|
|
||||||
#include <QReadWriteLock>
|
|
||||||
#include <QSharedData>
|
|
||||||
#include <QStringList>
|
|
||||||
#include <QVariant>
|
|
||||||
#include <QWeakPointer>
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
#include "abstractrunner.h"
|
|
||||||
|
|
||||||
namespace Plasma
|
|
||||||
{
|
|
||||||
|
|
||||||
class QueryMatchPrivate : public QSharedData
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
QueryMatchPrivate(AbstractRunner *r)
|
|
||||||
: QSharedData(),
|
|
||||||
lock(new QReadWriteLock(QReadWriteLock::Recursive)),
|
|
||||||
runner(r),
|
|
||||||
type(QueryMatch::ExactMatch),
|
|
||||||
relevance(.7),
|
|
||||||
selAction(0),
|
|
||||||
enabled(true),
|
|
||||||
idSetByData(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryMatchPrivate(const QueryMatchPrivate &other)
|
|
||||||
: QSharedData(other),
|
|
||||||
lock(new QReadWriteLock(QReadWriteLock::Recursive))
|
|
||||||
{
|
|
||||||
QReadLocker lock(other.lock);
|
|
||||||
runner = other.runner;
|
|
||||||
type = other.type;
|
|
||||||
relevance = other.relevance;
|
|
||||||
selAction = other.selAction;
|
|
||||||
enabled = other.enabled;
|
|
||||||
idSetByData = other.idSetByData;
|
|
||||||
id = other.id;
|
|
||||||
text = other.text;
|
|
||||||
subtext = other.subtext;
|
|
||||||
icon = other.icon;
|
|
||||||
data = other.data;
|
|
||||||
mimeType = other.mimeType;
|
|
||||||
urls = other.urls;
|
|
||||||
}
|
|
||||||
|
|
||||||
~QueryMatchPrivate()
|
|
||||||
{
|
|
||||||
delete lock;
|
|
||||||
}
|
|
||||||
|
|
||||||
QReadWriteLock *lock;
|
|
||||||
QWeakPointer<AbstractRunner> runner;
|
|
||||||
QueryMatch::Type type;
|
|
||||||
QString id;
|
|
||||||
QString text;
|
|
||||||
QString subtext;
|
|
||||||
QString mimeType;
|
|
||||||
QList<QUrl> urls;
|
|
||||||
QIcon icon;
|
|
||||||
QVariant data;
|
|
||||||
qreal relevance;
|
|
||||||
QAction *selAction;
|
|
||||||
bool enabled : 1;
|
|
||||||
bool idSetByData : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
QueryMatch::QueryMatch(AbstractRunner *runner)
|
|
||||||
: d(new QueryMatchPrivate(runner))
|
|
||||||
{
|
|
||||||
// qDebug() << "new match created";
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryMatch::QueryMatch(const QueryMatch &other)
|
|
||||||
: d(other.d)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryMatch::~QueryMatch()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QueryMatch::isValid() const
|
|
||||||
{
|
|
||||||
return d->runner != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString QueryMatch::id() const
|
|
||||||
{
|
|
||||||
if (d->id.isEmpty() && d->runner) {
|
|
||||||
return d->runner.data()->id();
|
|
||||||
}
|
|
||||||
|
|
||||||
return d->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QueryMatch::setType(Type type)
|
|
||||||
{
|
|
||||||
d->type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryMatch::Type QueryMatch::type() const
|
|
||||||
{
|
|
||||||
return d->type;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QueryMatch::setRelevance(qreal relevance)
|
|
||||||
{
|
|
||||||
d->relevance = qMax(qreal(0.0), relevance);
|
|
||||||
}
|
|
||||||
|
|
||||||
qreal QueryMatch::relevance() const
|
|
||||||
{
|
|
||||||
return d->relevance;
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractRunner* QueryMatch::runner() const
|
|
||||||
{
|
|
||||||
return d->runner.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QueryMatch::setText(const QString &text)
|
|
||||||
{
|
|
||||||
QWriteLocker locker(d->lock);
|
|
||||||
d->text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QueryMatch::setSubtext(const QString &subtext)
|
|
||||||
{
|
|
||||||
QWriteLocker locker(d->lock);
|
|
||||||
d->subtext = subtext;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QueryMatch::setData(const QVariant & data)
|
|
||||||
{
|
|
||||||
QWriteLocker locker(d->lock);
|
|
||||||
d->data = data;
|
|
||||||
|
|
||||||
if (d->id.isEmpty() || d->idSetByData) {
|
|
||||||
const QString id = data.toString();
|
|
||||||
if (!id.isEmpty()) {
|
|
||||||
setId(data.toString());
|
|
||||||
d->idSetByData = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void QueryMatch::setId(const QString &id)
|
|
||||||
{
|
|
||||||
QWriteLocker locker(d->lock);
|
|
||||||
if (d->runner) {
|
|
||||||
d->id = d->runner.data()->id();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!id.isEmpty()) {
|
|
||||||
d->id.append('_').append(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
d->idSetByData = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QueryMatch::setIcon(const QIcon &icon)
|
|
||||||
{
|
|
||||||
QWriteLocker locker(d->lock);
|
|
||||||
d->icon = icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant QueryMatch::data() const
|
|
||||||
{
|
|
||||||
QReadLocker locker(d->lock);
|
|
||||||
return d->data;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString QueryMatch::text() const
|
|
||||||
{
|
|
||||||
QReadLocker locker(d->lock);
|
|
||||||
return d->text;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString QueryMatch::subtext() const
|
|
||||||
{
|
|
||||||
QReadLocker locker(d->lock);
|
|
||||||
return d->subtext;
|
|
||||||
}
|
|
||||||
|
|
||||||
QIcon QueryMatch::icon() const
|
|
||||||
{
|
|
||||||
QReadLocker locker(d->lock);
|
|
||||||
return d->icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QueryMatch::setMimeType(const QString &mimeType)
|
|
||||||
{
|
|
||||||
QWriteLocker locker(d->lock);
|
|
||||||
d->mimeType = mimeType;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString QueryMatch::mimeType() const
|
|
||||||
{
|
|
||||||
QReadLocker locker(d->lock);
|
|
||||||
return d->mimeType;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QueryMatch::setUrls(const QList<QUrl> &urls)
|
|
||||||
{
|
|
||||||
QWriteLocker locker(d->lock);
|
|
||||||
d->urls = urls;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<QUrl> QueryMatch::urls() const
|
|
||||||
{
|
|
||||||
QReadLocker locker(d->lock);
|
|
||||||
return d->urls;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QueryMatch::setEnabled(bool enabled)
|
|
||||||
{
|
|
||||||
d->enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QueryMatch::isEnabled() const
|
|
||||||
{
|
|
||||||
return d->enabled && d->runner;
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* QueryMatch::selectedAction() const
|
|
||||||
{
|
|
||||||
return d->selAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QueryMatch::setSelectedAction(QAction *action)
|
|
||||||
{
|
|
||||||
d->selAction = action;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QueryMatch::operator<(const QueryMatch &other) const
|
|
||||||
{
|
|
||||||
if (d->type == other.d->type) {
|
|
||||||
if (isEnabled() != other.isEnabled()) {
|
|
||||||
return other.isEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d->relevance != other.d->relevance) {
|
|
||||||
return d->relevance < other.d->relevance;
|
|
||||||
}
|
|
||||||
|
|
||||||
QReadLocker locker(d->lock);
|
|
||||||
QReadLocker otherLocker(other.d->lock);
|
|
||||||
// when resorting to sort by alpha, we want the
|
|
||||||
// reverse sort order!
|
|
||||||
return d->text > other.d->text;
|
|
||||||
}
|
|
||||||
|
|
||||||
return d->type < other.d->type;
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryMatch &QueryMatch::operator=(const QueryMatch &other)
|
|
||||||
{
|
|
||||||
if (d != other.d) {
|
|
||||||
d = other.d;
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QueryMatch::operator==(const QueryMatch &other) const
|
|
||||||
{
|
|
||||||
return (d == other.d);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QueryMatch::operator!=(const QueryMatch &other) const
|
|
||||||
{
|
|
||||||
return (d != other.d);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QueryMatch::run(const RunnerContext &context) const
|
|
||||||
{
|
|
||||||
//qDebug() << "we run the term" << context->query() << "whose type is" << context->mimetype();
|
|
||||||
if (d->runner) {
|
|
||||||
d->runner.data()->run(context, *this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QueryMatch::hasConfigurationInterface() const
|
|
||||||
{
|
|
||||||
return d->runner && d->runner.data()->hasRunOptions();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QueryMatch::createConfigurationInterface(QWidget *parent)
|
|
||||||
{
|
|
||||||
if (hasConfigurationInterface()) {
|
|
||||||
d->runner.data()->createRunOptions(parent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // Plasma namespace
|
|
||||||
|
|
@ -1,278 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2006-2007 Aaron Seigo <aseigo@kde.org>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Library General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Library General Public
|
|
||||||
* License along with this program; if not, write to the
|
|
||||||
* Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PLASMA_QUERYMATCH_H
|
|
||||||
#define PLASMA_QUERYMATCH_H
|
|
||||||
|
|
||||||
#include <QtCore/QList>
|
|
||||||
#include <QtCore/QUrl>
|
|
||||||
#include <QtCore/QSharedDataPointer>
|
|
||||||
|
|
||||||
#include <plasma/plasma_export.h>
|
|
||||||
|
|
||||||
class QAction;
|
|
||||||
class QIcon;
|
|
||||||
class QString;
|
|
||||||
class QVariant;
|
|
||||||
class QWidget;
|
|
||||||
|
|
||||||
namespace Plasma
|
|
||||||
{
|
|
||||||
|
|
||||||
class RunnerContext;
|
|
||||||
class AbstractRunner;
|
|
||||||
class QueryMatchPrivate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @class QueryMatch plasma/querymatch.h <Plasma/QueryMatch>
|
|
||||||
*
|
|
||||||
* @short A match returned by an AbstractRunner in response to a given
|
|
||||||
* RunnerContext.
|
|
||||||
*/
|
|
||||||
class PLASMA_EXPORT QueryMatch
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* The type of match. Value is important here as it is used for sorting
|
|
||||||
*/
|
|
||||||
enum Type {
|
|
||||||
NoMatch = 0, /**< Null match */
|
|
||||||
CompletionMatch = 10, /**< Possible completion for the data of the query */
|
|
||||||
PossibleMatch = 30, /**< Something that may match the query */
|
|
||||||
InformationalMatch = 50, /**< A purely informational, non-actionable match,
|
|
||||||
such as the answer to a question or calculation*/
|
|
||||||
HelperMatch = 70, /**< A match that represents an action not directly related
|
|
||||||
to activating the given search term, such as a search
|
|
||||||
in an external tool or a command learning trigger. Helper
|
|
||||||
matches tend to be generic to the query and should not
|
|
||||||
be autoactivated just because the user hits "Enter"
|
|
||||||
while typing. They must be explicitly selected to
|
|
||||||
be activated, but unlike InformationalMatch cause
|
|
||||||
an action to be triggered. */
|
|
||||||
ExactMatch = 100 /**< An exact match to the query */
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a PossibleMatch associated with a given RunnerContext
|
|
||||||
* and runner.
|
|
||||||
*
|
|
||||||
* @param runner the runner this match belongs to
|
|
||||||
*/
|
|
||||||
explicit QueryMatch(AbstractRunner *runner);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy constructor
|
|
||||||
*/
|
|
||||||
QueryMatch(const QueryMatch &other);
|
|
||||||
|
|
||||||
~QueryMatch();
|
|
||||||
QueryMatch &operator=(const QueryMatch &other);
|
|
||||||
bool operator==(const QueryMatch &other) const;
|
|
||||||
bool operator!=(const QueryMatch &other) const;
|
|
||||||
bool operator<(const QueryMatch &other) const;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the runner associated with this action
|
|
||||||
*/
|
|
||||||
AbstractRunner *runner() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Requests this match to activae using the given context
|
|
||||||
*
|
|
||||||
* @param context the context to use in conjunction with this run
|
|
||||||
*
|
|
||||||
* @sa AbstractRunner::run
|
|
||||||
*/
|
|
||||||
void run(const RunnerContext &context) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true if the match is valid and can therefore be run,
|
|
||||||
* an invalid match does not have an associated AbstractRunner
|
|
||||||
*/
|
|
||||||
bool isValid() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the type of match this action represents.
|
|
||||||
*/
|
|
||||||
void setType(Type type);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The type of action this is. Defaults to PossibleMatch.
|
|
||||||
*/
|
|
||||||
Type type() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the relevance of this action for the search
|
|
||||||
* it was created for.
|
|
||||||
*
|
|
||||||
* @param relevance a number between 0 and 1.
|
|
||||||
*/
|
|
||||||
void setRelevance(qreal relevance);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The relevance of this action to the search. By default,
|
|
||||||
* the relevance is 1.
|
|
||||||
*
|
|
||||||
* @return a number between 0 and 1
|
|
||||||
*/
|
|
||||||
qreal relevance() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets data to be used internally by the associated
|
|
||||||
* AbstractRunner.
|
|
||||||
*
|
|
||||||
* When set, it is also used to form
|
|
||||||
* part of the id() for this match. If that is innapropriate
|
|
||||||
* as an id, the runner may generate its own id and set that
|
|
||||||
* with setId(const QString&) directly after calling setData
|
|
||||||
*/
|
|
||||||
void setData(const QVariant &data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the data associated with this match; usually runner-specific
|
|
||||||
*/
|
|
||||||
QVariant data() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the id for this match; useful if the id does not
|
|
||||||
* match data().toString(). The id must be unique to all
|
|
||||||
* matches from this runner, and should remain constant
|
|
||||||
* for the same query for best results.
|
|
||||||
*
|
|
||||||
* @param id the new identifying string to use to refer
|
|
||||||
* to this entry
|
|
||||||
*/
|
|
||||||
void setId(const QString &id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ruetnr a string that can be used as an ID for this match,
|
|
||||||
* even between different queries. It is based in part
|
|
||||||
* on the source of the match (the AbstractRunner) and
|
|
||||||
* distinguishing information provided by the runner,
|
|
||||||
* ensuring global uniqueness as well as consistency
|
|
||||||
* between query matches.
|
|
||||||
*/
|
|
||||||
QString id() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the main title text for this match; should be short
|
|
||||||
* enough to fit nicely on one line in a user interface
|
|
||||||
*
|
|
||||||
* @param text the text to use as the title
|
|
||||||
*/
|
|
||||||
void setText(const QString &text);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the title text for this match
|
|
||||||
*/
|
|
||||||
QString text() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the descriptive text for this match; can be longer
|
|
||||||
* than the main title text
|
|
||||||
*
|
|
||||||
* @param text the text to use as the description
|
|
||||||
*/
|
|
||||||
void setSubtext(const QString &text);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the descriptive text for this match
|
|
||||||
*/
|
|
||||||
QString subtext() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the icon associated with this match
|
|
||||||
*
|
|
||||||
* @param icon the icon to show along with the match
|
|
||||||
*/
|
|
||||||
void setIcon(const QIcon &icon);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the icon for this match
|
|
||||||
*/
|
|
||||||
QIcon icon() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the MimeType, if any, associated with this match.
|
|
||||||
* This overrides the MimeType provided by QueryContext, and should only be
|
|
||||||
* set when it is different from the QueryContext MimeType
|
|
||||||
*/
|
|
||||||
void setMimeType(const QString &mimeType);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the mimtype for this match, or QString() is none
|
|
||||||
*/
|
|
||||||
QString mimeType() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the urls, if any, associated with this match
|
|
||||||
*/
|
|
||||||
void setUrls(const QList<QUrl> &urls);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the mimtype for this match, or QString() is none
|
|
||||||
*/
|
|
||||||
QList<QUrl> urls() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets whether or not this match can be activited
|
|
||||||
*
|
|
||||||
* @param enable true if the match is enabled and therefore runnable
|
|
||||||
*/
|
|
||||||
void setEnabled(bool enable);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true if the match is enabled and therefore runnable, otherwise false
|
|
||||||
*/
|
|
||||||
bool isEnabled() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The current action.
|
|
||||||
*/
|
|
||||||
QAction* selectedAction() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the selected action
|
|
||||||
*/
|
|
||||||
void setSelectedAction(QAction *action);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true if this match can be configured before being run
|
|
||||||
* @since 4.3
|
|
||||||
*/
|
|
||||||
bool hasConfigurationInterface() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If hasConfigurationInterface() returns true, this method may be called to get
|
|
||||||
* a widget displaying the options the user can interact with to modify
|
|
||||||
* the behaviour of what happens when the match is run.
|
|
||||||
*
|
|
||||||
* @param widget the parent of the options widgets.
|
|
||||||
* @since 4.3
|
|
||||||
*/
|
|
||||||
void createConfigurationInterface(QWidget *parent);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QSharedDataPointer<QueryMatchPrivate> d;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,583 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2006-2007 Aaron Seigo <aseigo@kde.org>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Library General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Library General Public
|
|
||||||
* License along with this program; if not, write to the
|
|
||||||
* Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "runnercontext.h"
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
#include <QReadWriteLock>
|
|
||||||
|
|
||||||
#include <QDir>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <QSharedData>
|
|
||||||
|
|
||||||
#include <kcompletion.h>
|
|
||||||
#include <kconfiggroup.h>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <qmimedatabase.h>
|
|
||||||
#include <kshell.h>
|
|
||||||
#include <qstandardpaths.h>
|
|
||||||
#include <qurl.h>
|
|
||||||
#include <kprotocolinfo.h>
|
|
||||||
|
|
||||||
#include "abstractrunner.h"
|
|
||||||
#include "querymatch.h"
|
|
||||||
|
|
||||||
//#define LOCK_FOR_READ(d) if (d->policy == Shared) { d->lock.lockForRead(); }
|
|
||||||
//#define LOCK_FOR_WRITE(d) if (d->policy == Shared) { d->lock.lockForWrite(); }
|
|
||||||
//#define UNLOCK(d) if (d->policy == Shared) { d->lock.unlock(); }
|
|
||||||
|
|
||||||
#define LOCK_FOR_READ(d) d->lock.lockForRead();
|
|
||||||
#define LOCK_FOR_WRITE(d) d->lock.lockForWrite();
|
|
||||||
#define UNLOCK(d) d->lock.unlock();
|
|
||||||
|
|
||||||
namespace Plasma
|
|
||||||
{
|
|
||||||
|
|
||||||
/*
|
|
||||||
Corrects the case of the last component in a path (e.g. /usr/liB -> /usr/lib)
|
|
||||||
path: The path to be processed.
|
|
||||||
correctCasePath: The corrected-case path
|
|
||||||
mustBeDir: Tells whether the last component is a folder or doesn't matter
|
|
||||||
Returns true on success and false on error, in case of error, correctCasePath is not modified
|
|
||||||
*/
|
|
||||||
bool correctLastComponentCase(const QString &path, QString &correctCasePath, const bool mustBeDir)
|
|
||||||
{
|
|
||||||
//qDebug() << "Correcting " << path;
|
|
||||||
|
|
||||||
// If the file already exists then no need to search for it.
|
|
||||||
if (QFile::exists(path)) {
|
|
||||||
correctCasePath = path;
|
|
||||||
//qDebug() << "Correct path is" << correctCasePath;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QFileInfo pathInfo(path);
|
|
||||||
|
|
||||||
const QDir fileDir = pathInfo.dir();
|
|
||||||
//qDebug() << "Directory is" << fileDir;
|
|
||||||
|
|
||||||
const QString filename = pathInfo.fileName();
|
|
||||||
//qDebug() << "Filename is" << filename;
|
|
||||||
|
|
||||||
//qDebug() << "searching for a" << (mustBeDir ? "directory" : "directory/file");
|
|
||||||
|
|
||||||
const QStringList matchingFilenames = fileDir.entryList(QStringList(filename),
|
|
||||||
mustBeDir ? QDir::Dirs : QDir::NoFilter);
|
|
||||||
|
|
||||||
if (matchingFilenames.empty()) {
|
|
||||||
//qDebug() << "No matches found!!\n";
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
/*if (matchingFilenames.size() > 1) {
|
|
||||||
#ifndef NDEBUG
|
|
||||||
// qDebug() << "Found multiple matches!!\n";
|
|
||||||
#endif
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (fileDir.path().endsWith(QDir::separator())) {
|
|
||||||
correctCasePath = fileDir.path() + matchingFilenames[0];
|
|
||||||
} else {
|
|
||||||
correctCasePath = fileDir.path() + QDir::separator() + matchingFilenames[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
//qDebug() << "Correct path is" << correctCasePath;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Corrects the case of a path (e.g. /uSr/loCAL/bIN -> /usr/local/bin)
|
|
||||||
path: The path to be processed.
|
|
||||||
corrected: The corrected-case path
|
|
||||||
Returns true on success and false on error, in case of error, corrected is not modified
|
|
||||||
*/
|
|
||||||
bool correctPathCase(const QString& path, QString &corrected)
|
|
||||||
{
|
|
||||||
// early exit check
|
|
||||||
if (QFile::exists(path)) {
|
|
||||||
corrected = path;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// path components
|
|
||||||
QStringList components = QString(path).split(QDir::separator());
|
|
||||||
|
|
||||||
if (components.size() < 1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool mustBeDir = components.back().isEmpty();
|
|
||||||
|
|
||||||
//qDebug() << "Components are" << components;
|
|
||||||
|
|
||||||
if (mustBeDir) {
|
|
||||||
components.pop_back();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (components.isEmpty()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString correctPath;
|
|
||||||
const unsigned initialComponents = components.size();
|
|
||||||
for (unsigned i = 0; i < initialComponents - 1; i ++) {
|
|
||||||
const QString tmp = components[0] + QDir::separator() + components[1];
|
|
||||||
|
|
||||||
if (!correctLastComponentCase(tmp, correctPath, components.size() > 2 || mustBeDir)) {
|
|
||||||
//qDebug() << "search was not successful";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
components.removeFirst();
|
|
||||||
components[0] = correctPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
corrected = correctPath;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
class RunnerContextPrivate : public QSharedData
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RunnerContextPrivate(RunnerContext *context)
|
|
||||||
: QSharedData(),
|
|
||||||
type(RunnerContext::UnknownType),
|
|
||||||
q(context),
|
|
||||||
singleRunnerQueryMode(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
RunnerContextPrivate(const RunnerContextPrivate &p)
|
|
||||||
: QSharedData(),
|
|
||||||
launchCounts(p.launchCounts),
|
|
||||||
type(RunnerContext::None),
|
|
||||||
q(p.q),
|
|
||||||
singleRunnerQueryMode(false)
|
|
||||||
{
|
|
||||||
//qDebug() << "¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿¿boo yeah" << type;
|
|
||||||
}
|
|
||||||
|
|
||||||
~RunnerContextPrivate()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines type of query
|
|
||||||
&&
|
|
||||||
*/
|
|
||||||
void determineType()
|
|
||||||
{
|
|
||||||
// NOTE! this method must NEVER be called from
|
|
||||||
// code that may be running in multiple threads
|
|
||||||
// with the same data.
|
|
||||||
type = RunnerContext::UnknownType;
|
|
||||||
QString path = QDir::cleanPath(KShell::tildeExpand(term));
|
|
||||||
|
|
||||||
int space = path.indexOf(' ');
|
|
||||||
if (!QStandardPaths::findExecutable(path.left(space)).isEmpty()) {
|
|
||||||
// it's a shell command if there's a space because that implies
|
|
||||||
// that it has arguments!
|
|
||||||
type = (space > 0) ? RunnerContext::ShellCommand :
|
|
||||||
RunnerContext::Executable;
|
|
||||||
} else {
|
|
||||||
QUrl url = QUrl::fromUserInput(term);
|
|
||||||
// check for a normal URL first
|
|
||||||
//qDebug() << url << KProtocolInfo::protocolClass(url.scheme()) << url.hasHost() <<
|
|
||||||
// url.host() << url.isLocalFile() << path << path.indexOf('/');
|
|
||||||
const bool hasProtocol = !url.scheme().isEmpty();
|
|
||||||
const bool isLocalProtocol = KProtocolInfo::protocolClass(url.scheme()) == ":local";
|
|
||||||
if (hasProtocol &&
|
|
||||||
((!isLocalProtocol && !url.host().isEmpty()) ||
|
|
||||||
(isLocalProtocol && url.scheme() != "file"))) {
|
|
||||||
// we either have a network protocol with a host, so we can show matches for it
|
|
||||||
// or we have a non-file url that may be local so a host isn't required
|
|
||||||
type = RunnerContext::NetworkLocation;
|
|
||||||
} else if (isLocalProtocol) {
|
|
||||||
// at this point in the game, we assume we have a path,
|
|
||||||
// but if a path doesn't have any slashes
|
|
||||||
// it's too ambiguous to be sure we're in a filesystem context
|
|
||||||
path = QDir::cleanPath(url.toLocalFile());
|
|
||||||
//qDebug()<< "slash check" << path;
|
|
||||||
if (hasProtocol || ((path.indexOf('/') != -1 || path.indexOf('\\') != -1))) {
|
|
||||||
QString correctCasePath;
|
|
||||||
if (correctPathCase(path, correctCasePath)) {
|
|
||||||
path = correctCasePath;
|
|
||||||
QFileInfo info(path);
|
|
||||||
//qDebug()<< "correct cas epath is" << correctCasePath << info.isSymLink() <<
|
|
||||||
// info.isDir() << info.isFile();
|
|
||||||
|
|
||||||
if (info.isSymLink()) {
|
|
||||||
path = info.canonicalFilePath();
|
|
||||||
info = QFileInfo(path);
|
|
||||||
}
|
|
||||||
if (info.isDir()) {
|
|
||||||
type = RunnerContext::Directory;
|
|
||||||
mimeType = "inode/folder";
|
|
||||||
} else if (info.isFile()) {
|
|
||||||
type = RunnerContext::File;
|
|
||||||
QMimeDatabase db;
|
|
||||||
QMimeType mime = db.mimeTypeForFile(path);
|
|
||||||
if (!mime.isDefault()) {
|
|
||||||
mimeType = mime.name();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//qDebug() << "term2type" << term << type;
|
|
||||||
}
|
|
||||||
|
|
||||||
void invalidate()
|
|
||||||
{
|
|
||||||
q = &s_dummyContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
QReadWriteLock lock;
|
|
||||||
QList<QueryMatch> matches;
|
|
||||||
QMap<QString, const QueryMatch*> matchesById;
|
|
||||||
QHash<QString, int> launchCounts;
|
|
||||||
QString term;
|
|
||||||
QString mimeType;
|
|
||||||
RunnerContext::Type type;
|
|
||||||
RunnerContext * q;
|
|
||||||
static RunnerContext s_dummyContext;
|
|
||||||
bool singleRunnerQueryMode;
|
|
||||||
};
|
|
||||||
|
|
||||||
RunnerContext RunnerContextPrivate::s_dummyContext;
|
|
||||||
|
|
||||||
RunnerContext::RunnerContext(QObject *parent)
|
|
||||||
: QObject(parent),
|
|
||||||
d(new RunnerContextPrivate(this))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
//copy ctor
|
|
||||||
RunnerContext::RunnerContext(RunnerContext &other, QObject *parent)
|
|
||||||
: QObject(parent)
|
|
||||||
{
|
|
||||||
LOCK_FOR_READ(other.d)
|
|
||||||
d = other.d;
|
|
||||||
UNLOCK(other.d)
|
|
||||||
}
|
|
||||||
|
|
||||||
RunnerContext::~RunnerContext()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
RunnerContext &RunnerContext::operator=(const RunnerContext &other)
|
|
||||||
{
|
|
||||||
if (this->d == other.d) {
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
QExplicitlySharedDataPointer<Plasma::RunnerContextPrivate> oldD = d;
|
|
||||||
LOCK_FOR_WRITE(d)
|
|
||||||
LOCK_FOR_READ(other.d)
|
|
||||||
d = other.d;
|
|
||||||
UNLOCK(other.d)
|
|
||||||
UNLOCK(oldD)
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerContext::reset()
|
|
||||||
{
|
|
||||||
// We will detach if we are a copy of someone. But we will reset
|
|
||||||
// if we are the 'main' context others copied from. Resetting
|
|
||||||
// one RunnerContext makes all the copies obsolete.
|
|
||||||
|
|
||||||
// We need to mark the q pointer of the detached RunnerContextPrivate
|
|
||||||
// as dirty on detach to avoid receiving results for old queries
|
|
||||||
d->invalidate();
|
|
||||||
|
|
||||||
d.detach();
|
|
||||||
|
|
||||||
// Now that we detached the d pointer we need to reset its q pointer
|
|
||||||
|
|
||||||
d->q = this;
|
|
||||||
|
|
||||||
// we still have to remove all the matches, since if the
|
|
||||||
// ref count was 1 (e.g. only the RunnerContext is using
|
|
||||||
// the dptr) then we won't get a copy made
|
|
||||||
if (!d->matches.isEmpty()) {
|
|
||||||
d->matchesById.clear();
|
|
||||||
d->matches.clear();
|
|
||||||
emit matchesChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
d->term.clear();
|
|
||||||
d->mimeType.clear();
|
|
||||||
d->type = UnknownType;
|
|
||||||
d->singleRunnerQueryMode = false;
|
|
||||||
//qDebug() << "match count" << d->matches.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerContext::setQuery(const QString &term)
|
|
||||||
{
|
|
||||||
reset();
|
|
||||||
|
|
||||||
if (term.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->term = term;
|
|
||||||
d->determineType();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString RunnerContext::query() const
|
|
||||||
{
|
|
||||||
// the query term should never be set after
|
|
||||||
// a search starts. in fact, reset() ensures this
|
|
||||||
// and setQuery(QString) calls reset()
|
|
||||||
return d->term;
|
|
||||||
}
|
|
||||||
|
|
||||||
RunnerContext::Type RunnerContext::type() const
|
|
||||||
{
|
|
||||||
return d->type;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString RunnerContext::mimeType() const
|
|
||||||
{
|
|
||||||
return d->mimeType;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RunnerContext::isValid() const
|
|
||||||
{
|
|
||||||
// if our qptr is dirty, we aren't useful anymore
|
|
||||||
return (d->q != &(d->s_dummyContext));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RunnerContext::addMatches(const QList<QueryMatch> &matches)
|
|
||||||
{
|
|
||||||
if (matches.isEmpty() || !isValid()) {
|
|
||||||
//Bail out if the query is empty or the qptr is dirty
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOCK_FOR_WRITE(d)
|
|
||||||
foreach (QueryMatch match, matches) {
|
|
||||||
// Give previously launched matches a slight boost in relevance
|
|
||||||
// The boost smoothly saturates to 0.5;
|
|
||||||
if (int count = d->launchCounts.value(match.id())) {
|
|
||||||
match.setRelevance(match.relevance() + 0.5 * (1-exp(-count*0.3)));
|
|
||||||
}
|
|
||||||
|
|
||||||
d->matches.append(match);
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (d->matchesById.contains(match.id())) {
|
|
||||||
// qDebug() << "Duplicate match id " << match.id() << "from" << match.runner()->name();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
d->matchesById.insert(match.id(), &d->matches.at(d->matches.size() - 1));
|
|
||||||
}
|
|
||||||
UNLOCK(d);
|
|
||||||
//qDebug()<< "add matches";
|
|
||||||
// A copied searchContext may share the d pointer,
|
|
||||||
// we always want to sent the signal of the object that created
|
|
||||||
// the d pointer
|
|
||||||
emit d->q->matchesChanged();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RunnerContext::addMatch(const QueryMatch &match)
|
|
||||||
{
|
|
||||||
if (!isValid()) {
|
|
||||||
// Bail out if the qptr is dirty
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryMatch m(match); // match must be non-const to modify relevance
|
|
||||||
|
|
||||||
LOCK_FOR_WRITE(d)
|
|
||||||
|
|
||||||
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(d);
|
|
||||||
//qDebug()<< "added match" << match->text();
|
|
||||||
emit d->q->matchesChanged();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RunnerContext::removeMatches(const QStringList matchIdList)
|
|
||||||
{
|
|
||||||
if (!isValid()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList presentMatchIdList;
|
|
||||||
QList<const QueryMatch*> presentMatchList;
|
|
||||||
|
|
||||||
LOCK_FOR_READ(d)
|
|
||||||
foreach(const QString &matchId, matchIdList) {
|
|
||||||
const QueryMatch* match = d->matchesById.value(matchId, 0);
|
|
||||||
if (match) {
|
|
||||||
presentMatchList << match;
|
|
||||||
presentMatchIdList << matchId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UNLOCK(d)
|
|
||||||
|
|
||||||
if (presentMatchIdList.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOCK_FOR_WRITE(d)
|
|
||||||
foreach(const QueryMatch *match, presentMatchList) {
|
|
||||||
d->matches.removeAll(*match);
|
|
||||||
}
|
|
||||||
foreach(const QString &matchId, presentMatchIdList) {
|
|
||||||
d->matchesById.remove(matchId);
|
|
||||||
}
|
|
||||||
UNLOCK(d)
|
|
||||||
|
|
||||||
emit d->q->matchesChanged();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RunnerContext::removeMatch(const QString matchId)
|
|
||||||
{
|
|
||||||
if (!isValid()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
LOCK_FOR_READ(d)
|
|
||||||
const QueryMatch* match = d->matchesById.value(matchId, 0);
|
|
||||||
UNLOCK(d)
|
|
||||||
if (!match) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
LOCK_FOR_WRITE(d)
|
|
||||||
d->matches.removeAll(*match);
|
|
||||||
d->matchesById.remove(matchId);
|
|
||||||
UNLOCK(d)
|
|
||||||
emit d->q->matchesChanged();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RunnerContext::removeMatches(Plasma::AbstractRunner *runner)
|
|
||||||
{
|
|
||||||
if (!isValid()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<QueryMatch> presentMatchList;
|
|
||||||
|
|
||||||
LOCK_FOR_READ(d)
|
|
||||||
foreach(const QueryMatch &match, d->matches) {
|
|
||||||
if (match.runner() == runner) {
|
|
||||||
presentMatchList << match;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UNLOCK(d)
|
|
||||||
|
|
||||||
if (presentMatchList.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOCK_FOR_WRITE(d)
|
|
||||||
foreach (const QueryMatch &match, presentMatchList) {
|
|
||||||
d->matchesById.remove(match.id());
|
|
||||||
d->matches.removeAll(match);
|
|
||||||
}
|
|
||||||
UNLOCK(d)
|
|
||||||
|
|
||||||
emit d->q->matchesChanged();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<QueryMatch> RunnerContext::matches() const
|
|
||||||
{
|
|
||||||
LOCK_FOR_READ(d)
|
|
||||||
QList<QueryMatch> matches = d->matches;
|
|
||||||
UNLOCK(d);
|
|
||||||
return matches;
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryMatch RunnerContext::match(const QString &id) const
|
|
||||||
{
|
|
||||||
LOCK_FOR_READ(d)
|
|
||||||
const QueryMatch *match = d->matchesById.value(id, 0);
|
|
||||||
UNLOCK(d)
|
|
||||||
|
|
||||||
if (match) {
|
|
||||||
return *match;
|
|
||||||
}
|
|
||||||
|
|
||||||
return QueryMatch(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerContext::setSingleRunnerQueryMode(bool enabled)
|
|
||||||
{
|
|
||||||
d->singleRunnerQueryMode = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RunnerContext::singleRunnerQueryMode() const
|
|
||||||
{
|
|
||||||
return d->singleRunnerQueryMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerContext::restore(const KConfigGroup &config)
|
|
||||||
{
|
|
||||||
const QStringList cfgList = config.readEntry("LaunchCounts", QStringList());
|
|
||||||
|
|
||||||
const QRegExp r("(\\d*) (.*)");
|
|
||||||
foreach (const 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 "moc_runnercontext.cpp"
|
|
@ -1,256 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2006-2007 Aaron Seigo <aseigo@kde.org>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Library General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Library General Public
|
|
||||||
* License along with this program; if not, write to the
|
|
||||||
* Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PLASMA_RUNNERCONTEXT_H
|
|
||||||
#define PLASMA_RUNNERCONTEXT_H
|
|
||||||
|
|
||||||
#include <QtCore/QList>
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <QtCore/QSharedDataPointer>
|
|
||||||
|
|
||||||
#include <plasma/plasma_export.h>
|
|
||||||
|
|
||||||
class KCompletion;
|
|
||||||
class KConfigGroup;
|
|
||||||
|
|
||||||
namespace Plasma
|
|
||||||
{
|
|
||||||
|
|
||||||
class QueryMatch;
|
|
||||||
class AbstractRunner;
|
|
||||||
class RunnerContextPrivate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @class RunnerContext plasma/runnercontext.h <Plasma/RunnerContext>
|
|
||||||
*
|
|
||||||
* @short The RunnerContext class provides information related to a search,
|
|
||||||
* including the search term, metadata on the search term and collected
|
|
||||||
* matches.
|
|
||||||
*/
|
|
||||||
class PLASMA_EXPORT RunnerContext : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum Type {
|
|
||||||
None = 0,
|
|
||||||
UnknownType = 1,
|
|
||||||
Directory = 2,
|
|
||||||
File = 4,
|
|
||||||
NetworkLocation = 8,
|
|
||||||
Executable = 16,
|
|
||||||
ShellCommand = 32,
|
|
||||||
Help = 64,
|
|
||||||
FileSystem = Directory | File | Executable | ShellCommand
|
|
||||||
};
|
|
||||||
|
|
||||||
Q_DECLARE_FLAGS(Types, Type)
|
|
||||||
|
|
||||||
explicit RunnerContext(QObject *parent = 0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy constructor
|
|
||||||
*/
|
|
||||||
RunnerContext(RunnerContext &other, QObject *parent = 0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assignment operator
|
|
||||||
* @since 4.4
|
|
||||||
*/
|
|
||||||
RunnerContext &operator=(const RunnerContext &other);
|
|
||||||
|
|
||||||
~RunnerContext();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the search term for this object.
|
|
||||||
* This removes all current matches in the process and
|
|
||||||
* turns off single runner query mode.
|
|
||||||
*/
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the query term for this object and attempts to determine
|
|
||||||
* the type of the search.
|
|
||||||
*/
|
|
||||||
void setQuery(const QString &term);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the current search query term.
|
|
||||||
*/
|
|
||||||
QString query() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The type of item the search term might refer to.
|
|
||||||
* @see Type
|
|
||||||
*/
|
|
||||||
Type type() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The mimetype that the search term refers to, if discoverable.
|
|
||||||
*
|
|
||||||
* @return QString() if the mimetype can not be determined, otherwise
|
|
||||||
* the mimetype of the object being referred to by the search
|
|
||||||
* string.
|
|
||||||
*/
|
|
||||||
QString mimeType() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns true if this context is no longer valid and therefore
|
|
||||||
* matching using it should abort. Most useful as an optimization technique
|
|
||||||
* inside of AbstractRunner subclasses in the match method, e.g.:
|
|
||||||
*
|
|
||||||
* while (.. a possibly large iteration) {
|
|
||||||
* if (!context.isValid()) {
|
|
||||||
* return;
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* ... some processing ...
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* While not required to be used within runners, it provies a nice way
|
|
||||||
* to avoid unnecessary processing in runners that may run for an extended
|
|
||||||
* period (as measured in 10s of ms) and therefore improve the user experience.
|
|
||||||
* @since 4.2.3
|
|
||||||
*/
|
|
||||||
bool isValid() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Appends lists of matches to the list of matches.
|
|
||||||
*
|
|
||||||
* @param matches the matches to add
|
|
||||||
* @return true if matches were added, false if matches were e.g. outdated
|
|
||||||
*/
|
|
||||||
bool addMatches(const QList<QueryMatch> &matches);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Appends a match to the existing list of matches.
|
|
||||||
*
|
|
||||||
* If you are going to be adding multiple matches, use @see addMatches instead.
|
|
||||||
*
|
|
||||||
* @param match the match to add
|
|
||||||
* @return true if the match was added, false otherwise.
|
|
||||||
*/
|
|
||||||
bool addMatch(const QueryMatch &match);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes a match from the existing list of matches.
|
|
||||||
*
|
|
||||||
* If you are going to be removing multiple matches, use removeMatches instead.
|
|
||||||
*
|
|
||||||
* @param matchId the id of match to remove
|
|
||||||
*
|
|
||||||
* @return true if the match was removed, false otherwise.
|
|
||||||
* @since 4.4
|
|
||||||
*/
|
|
||||||
bool removeMatch(const QString matchId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes lists of matches from the existing list of matches.
|
|
||||||
*
|
|
||||||
* This method is thread safe and causes the matchesChanged() signal to be emitted.
|
|
||||||
*
|
|
||||||
* @param matchIdList the list of matches id to remove
|
|
||||||
*
|
|
||||||
* @return true if at least one match was removed, false otherwise.
|
|
||||||
* @since 4.4
|
|
||||||
*/
|
|
||||||
bool removeMatches(const QStringList matchIdList);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes lists of matches from a given AbstractRunner
|
|
||||||
*
|
|
||||||
* This method is thread safe and causes the matchesChanged() signal to be emitted.
|
|
||||||
*
|
|
||||||
* @param runner the AbstractRunner from which to remove matches
|
|
||||||
*
|
|
||||||
* @return true if at least one match was removed, false otherwise.
|
|
||||||
* @since 4.10
|
|
||||||
*/
|
|
||||||
bool removeMatches(AbstractRunner *runner);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves all available matches for the current search term.
|
|
||||||
*
|
|
||||||
* @return a list of matches
|
|
||||||
*/
|
|
||||||
QList<QueryMatch> matches() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves a match by id.
|
|
||||||
*
|
|
||||||
* @param id the id of the match to return
|
|
||||||
* @return the match associated with this id, or an invalid QueryMatch object
|
|
||||||
* if the id does not eixst
|
|
||||||
*/
|
|
||||||
QueryMatch match(const QString &id) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets single runner query mode. Note that a call to reset() will
|
|
||||||
* turn off single runner query mode.
|
|
||||||
*
|
|
||||||
* @see reset()
|
|
||||||
* @since 4.4
|
|
||||||
*/
|
|
||||||
void setSingleRunnerQueryMode(bool enabled);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true if the current query is a single runner query
|
|
||||||
* @since 4.4
|
|
||||||
*/
|
|
||||||
bool singleRunnerQueryMode() 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();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QExplicitlySharedDataPointer<RunnerContextPrivate> d;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(Plasma::RunnerContext::Types)
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,801 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2006 Aaron Seigo <aseigo@kde.org>
|
|
||||||
* Copyright (C) 2007, 2009 Ryan P. Bitanga <ryan.bitanga@gmail.com>
|
|
||||||
* Copyright (C) 2008 Jordi Polo <mumismo@gmail.com>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Library General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Library General Public
|
|
||||||
* License along with this program; if not, write to the
|
|
||||||
* Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "runnermanager.h"
|
|
||||||
|
|
||||||
#include "config-plasma.h"
|
|
||||||
|
|
||||||
#include <QMutex>
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QCoreApplication>
|
|
||||||
#include <qstandardpaths.h>
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
#include <kplugininfo.h>
|
|
||||||
#include <kservicetypetrader.h>
|
|
||||||
|
|
||||||
#if !PLASMA_NO_SOLID
|
|
||||||
#include <solid/device.h>
|
|
||||||
#include <solid/deviceinterface.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <ThreadWeaver/DebuggingAids>
|
|
||||||
#include <ThreadWeaver/Queue>
|
|
||||||
#include <ThreadWeaver/Thread>
|
|
||||||
|
|
||||||
#include "private/runnerjobs_p.h"
|
|
||||||
#include "pluginloader.h"
|
|
||||||
#include "querymatch.h"
|
|
||||||
|
|
||||||
using ThreadWeaver::Queue;
|
|
||||||
using ThreadWeaver::Job;
|
|
||||||
|
|
||||||
//#define MEASURE_PREPTIME
|
|
||||||
|
|
||||||
namespace Plasma
|
|
||||||
{
|
|
||||||
|
|
||||||
/*****************************************************
|
|
||||||
* RunnerManager::Private class
|
|
||||||
*
|
|
||||||
*****************************************************/
|
|
||||||
class RunnerManagerPrivate
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
RunnerManagerPrivate(RunnerManager *parent)
|
|
||||||
: q(parent),
|
|
||||||
deferredRun(0),
|
|
||||||
currentSingleRunner(0),
|
|
||||||
prepped(false),
|
|
||||||
allRunnersPrepped(false),
|
|
||||||
singleRunnerPrepped(false),
|
|
||||||
teardownRequested(false),
|
|
||||||
singleMode(false),
|
|
||||||
singleRunnerWasLoaded(false)
|
|
||||||
{
|
|
||||||
matchChangeTimer.setSingleShot(true);
|
|
||||||
delayTimer.setSingleShot(true);
|
|
||||||
|
|
||||||
QObject::connect(&matchChangeTimer, SIGNAL(timeout()), q, SLOT(matchesChanged()));
|
|
||||||
QObject::connect(&context, SIGNAL(matchesChanged()), q, SLOT(scheduleMatchesChanged()));
|
|
||||||
QObject::connect(&delayTimer, SIGNAL(timeout()), q, SLOT(unblockJobs()));
|
|
||||||
}
|
|
||||||
|
|
||||||
~RunnerManagerPrivate()
|
|
||||||
{
|
|
||||||
KConfigGroup config = configGroup();
|
|
||||||
context.save(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
void scheduleMatchesChanged()
|
|
||||||
{
|
|
||||||
matchChangeTimer.start(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
void matchesChanged()
|
|
||||||
{
|
|
||||||
emit q->matchesChanged(context.matches());
|
|
||||||
}
|
|
||||||
|
|
||||||
void loadConfiguration()
|
|
||||||
{
|
|
||||||
KConfigGroup config = configGroup();
|
|
||||||
|
|
||||||
//The number of threads used scales with the number of processors.
|
|
||||||
#if !PLASMA_NO_SOLID
|
|
||||||
const int numProcs =
|
|
||||||
qMax(Solid::Device::listFromType(Solid::DeviceInterface::Processor).count(), 1);
|
|
||||||
#else
|
|
||||||
const int numProcs = 1;
|
|
||||||
#endif
|
|
||||||
//This entry allows to define a hard upper limit independent of the number of processors.
|
|
||||||
const int maxThreads = config.readEntry("maxThreads", 16);
|
|
||||||
const int numThreads = qMin(maxThreads, 2 + ((numProcs - 1) * 2));
|
|
||||||
//qDebug() << "setting up" << numThreads << "threads for" << numProcs << "processors";
|
|
||||||
if (numThreads > Queue::instance()->maximumNumberOfThreads()) {
|
|
||||||
Queue::instance()->setMaximumNumberOfThreads(numThreads);
|
|
||||||
}
|
|
||||||
// Limit the number of instances of a single normal speed runner and all of the slow runners
|
|
||||||
// to half the number of threads
|
|
||||||
const int cap = qMax(2, numThreads/2);
|
|
||||||
DefaultRunnerPolicy::instance().setCap(cap);
|
|
||||||
|
|
||||||
context.restore(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
KConfigGroup configGroup()
|
|
||||||
{
|
|
||||||
return conf.isValid() ? conf : KConfigGroup(KSharedConfig::openConfig(), "PlasmaRunnerManager");
|
|
||||||
}
|
|
||||||
|
|
||||||
void clearSingleRunner()
|
|
||||||
{
|
|
||||||
if (singleRunnerWasLoaded) {
|
|
||||||
delete currentSingleRunner;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentSingleRunner = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void loadSingleRunner()
|
|
||||||
{
|
|
||||||
if (!singleMode || singleModeRunnerId.isEmpty()) {
|
|
||||||
clearSingleRunner();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentSingleRunner) {
|
|
||||||
if (currentSingleRunner->id() == singleModeRunnerId) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
clearSingleRunner();
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractRunner *loadedRunner = q->runner(singleModeRunnerId);
|
|
||||||
if (loadedRunner) {
|
|
||||||
singleRunnerWasLoaded = false;
|
|
||||||
currentSingleRunner = loadedRunner;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
KService::List offers = KServiceTypeTrader::self()->query("Plasma/Runner", QString("[X-KDE-PluginInfo-Name] == '%1'").arg(singleModeRunnerId));
|
|
||||||
if (!offers.isEmpty()) {
|
|
||||||
const KService::Ptr &service = offers[0];
|
|
||||||
currentSingleRunner = loadInstalledRunner(service);
|
|
||||||
|
|
||||||
if (currentSingleRunner) {
|
|
||||||
emit currentSingleRunner->prepare();
|
|
||||||
singleRunnerWasLoaded = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void loadRunners()
|
|
||||||
{
|
|
||||||
KConfigGroup config = configGroup();
|
|
||||||
KPluginInfo::List offers = RunnerManager::listRunnerInfo();
|
|
||||||
|
|
||||||
const bool loadAll = config.readEntry("loadAll", false);
|
|
||||||
const QStringList whiteList = config.readEntry("pluginWhiteList", QStringList());
|
|
||||||
const bool noWhiteList = whiteList.isEmpty();
|
|
||||||
KConfigGroup pluginConf;
|
|
||||||
if (conf.isValid()) {
|
|
||||||
pluginConf = KConfigGroup(&conf, "Plugins");
|
|
||||||
} else {
|
|
||||||
pluginConf = KConfigGroup(KSharedConfig::openConfig(), "Plugins");
|
|
||||||
}
|
|
||||||
|
|
||||||
advertiseSingleRunnerIds.clear();
|
|
||||||
|
|
||||||
QSet<AbstractRunner *> deadRunners;
|
|
||||||
QMutableListIterator<KPluginInfo> it(offers);
|
|
||||||
while (it.hasNext()) {
|
|
||||||
KPluginInfo &description = it.next();
|
|
||||||
//qDebug() << "Loading runner: " << service->name() << service->storageId();
|
|
||||||
QString tryExec = description.property("TryExec").toString();
|
|
||||||
//qDebug() << "TryExec is" << tryExec;
|
|
||||||
if (!tryExec.isEmpty() && QStandardPaths::findExecutable(tryExec).isEmpty()) {
|
|
||||||
// we don't actually have this application!
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString runnerName = description.pluginName();
|
|
||||||
description.load(pluginConf);
|
|
||||||
|
|
||||||
const bool loaded = runners.contains(runnerName);
|
|
||||||
const bool selected = loadAll || (description.isPluginEnabled() && (noWhiteList || whiteList.contains(runnerName)));
|
|
||||||
|
|
||||||
const bool singleQueryModeEnabled = description.property("X-Plasma-AdvertiseSingleRunnerQueryMode").toBool();
|
|
||||||
|
|
||||||
if (singleQueryModeEnabled) {
|
|
||||||
advertiseSingleRunnerIds.insert(runnerName, description.name());
|
|
||||||
}
|
|
||||||
|
|
||||||
//qDebug() << loadAll << description.isPluginEnabled() << noWhiteList << whiteList.contains(runnerName);
|
|
||||||
if (selected) {
|
|
||||||
if (!loaded) {
|
|
||||||
AbstractRunner *runner = loadInstalledRunner(description.service());
|
|
||||||
|
|
||||||
if (runner) {
|
|
||||||
runners.insert(runnerName, runner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (loaded) {
|
|
||||||
//Remove runner
|
|
||||||
deadRunners.insert(runners.take(runnerName));
|
|
||||||
#ifndef NDEBUG
|
|
||||||
// qDebug() << "Removing runner: " << runnerName;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!deadRunners.isEmpty()) {
|
|
||||||
QSet<QSharedPointer<FindMatchesJob> > deadJobs;
|
|
||||||
auto it = searchJobs.begin();
|
|
||||||
while (it != searchJobs.end()) {
|
|
||||||
auto &job = (*it);
|
|
||||||
if (deadRunners.contains(job->runner())) {
|
|
||||||
QObject::disconnect(job->decorator(), SIGNAL(done(ThreadWeaver::JobPointer)), q, SLOT(jobDone(ThreadWeaver::JobPointer)));
|
|
||||||
it = searchJobs.erase(it);
|
|
||||||
deadJobs.insert(job);
|
|
||||||
} else {
|
|
||||||
it++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
it = oldSearchJobs.begin();
|
|
||||||
while (it != oldSearchJobs.end()) {
|
|
||||||
auto &job = (*it);
|
|
||||||
if (deadRunners.contains(job->runner())) {
|
|
||||||
it = oldSearchJobs.erase(it);
|
|
||||||
deadJobs.insert(job);
|
|
||||||
} else {
|
|
||||||
it++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (deadJobs.isEmpty()) {
|
|
||||||
qDeleteAll(deadRunners);
|
|
||||||
} else {
|
|
||||||
new DelayedJobCleaner(deadJobs, deadRunners);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!singleRunnerWasLoaded) {
|
|
||||||
// in case we deleted it up above
|
|
||||||
clearSingleRunner();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
// qDebug() << "All runners loaded, total:" << runners.count();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractRunner *loadInstalledRunner(const KService::Ptr service)
|
|
||||||
{
|
|
||||||
if (!service) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractRunner *runner = PluginLoader::self()->loadRunner(service->property("X-KDE-PluginInfo-Name", QVariant::String).toString());
|
|
||||||
|
|
||||||
if (runner) {
|
|
||||||
runner->setParent(q);
|
|
||||||
} else {
|
|
||||||
const QString api = service->property("X-Plasma-API").toString();
|
|
||||||
|
|
||||||
if (api.isEmpty()) {
|
|
||||||
QVariantList args;
|
|
||||||
args << service->storageId();
|
|
||||||
if (Plasma::isPluginVersionCompatible(KPluginLoader(*service).pluginVersion())) {
|
|
||||||
QString error;
|
|
||||||
runner = service->createInstance<AbstractRunner>(q, args, &error);
|
|
||||||
if (!runner) {
|
|
||||||
#ifndef NDEBUG
|
|
||||||
// qDebug() << "Failed to load runner:" << service->name() << ". error reported:" << error;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//qDebug() << "got a script runner known as" << api;
|
|
||||||
runner = new AbstractRunner(service, q);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (runner) {
|
|
||||||
#ifndef NDEBUG
|
|
||||||
// qDebug() << "================= loading runner:" << service->name() << "=================";
|
|
||||||
#endif
|
|
||||||
QObject::connect(runner, SIGNAL(matchingSuspended(bool)), q, SLOT(runnerMatchingSuspended(bool)));
|
|
||||||
runner->init();
|
|
||||||
if (prepped) {
|
|
||||||
emit runner->prepare();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return runner;
|
|
||||||
}
|
|
||||||
|
|
||||||
void jobDone(ThreadWeaver::JobPointer job)
|
|
||||||
{
|
|
||||||
auto runJob = job.dynamicCast<FindMatchesJob>();
|
|
||||||
|
|
||||||
if (!runJob) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (deferredRun.isEnabled() && runJob->runner() == deferredRun.runner()) {
|
|
||||||
//qDebug() << "job actually done, running now **************";
|
|
||||||
QueryMatch tmpRun = deferredRun;
|
|
||||||
deferredRun = QueryMatch(0);
|
|
||||||
tmpRun.run(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
searchJobs.remove(runJob);
|
|
||||||
oldSearchJobs.remove(runJob);
|
|
||||||
|
|
||||||
if (searchJobs.isEmpty() && context.matches().isEmpty()) {
|
|
||||||
// we finished our run, and there are no valid matches, and so no
|
|
||||||
// signal will have been sent out. so we need to emit the signal
|
|
||||||
// ourselves here
|
|
||||||
emit q->matchesChanged(context.matches());
|
|
||||||
}
|
|
||||||
|
|
||||||
checkTearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkTearDown()
|
|
||||||
{
|
|
||||||
//qDebug() << prepped << teardownRequested << searchJobs.count() << oldSearchJobs.count();
|
|
||||||
|
|
||||||
if (!prepped || !teardownRequested) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Queue::instance()->isIdle()) {
|
|
||||||
searchJobs.clear();
|
|
||||||
oldSearchJobs.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (searchJobs.isEmpty() && oldSearchJobs.isEmpty()) {
|
|
||||||
if (allRunnersPrepped) {
|
|
||||||
foreach (AbstractRunner *runner, runners) {
|
|
||||||
emit runner->teardown();
|
|
||||||
}
|
|
||||||
|
|
||||||
allRunnersPrepped = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (singleRunnerPrepped) {
|
|
||||||
if (currentSingleRunner) {
|
|
||||||
emit currentSingleRunner->teardown();
|
|
||||||
}
|
|
||||||
|
|
||||||
singleRunnerPrepped = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
emit q->queryFinished();
|
|
||||||
|
|
||||||
prepped = false;
|
|
||||||
teardownRequested = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void unblockJobs()
|
|
||||||
{
|
|
||||||
if (searchJobs.isEmpty() && Queue::instance()->isIdle()) {
|
|
||||||
oldSearchJobs.clear();
|
|
||||||
checkTearDown();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Queue::instance()->reschedule();
|
|
||||||
}
|
|
||||||
|
|
||||||
void runnerMatchingSuspended(bool suspended)
|
|
||||||
{
|
|
||||||
if (suspended || !prepped || teardownRequested) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractRunner *runner = qobject_cast<AbstractRunner *>(q->sender());
|
|
||||||
|
|
||||||
if (runner) {
|
|
||||||
startJob(runner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void startJob(AbstractRunner *runner)
|
|
||||||
{
|
|
||||||
if ((runner->ignoredTypes() & context.type()) == 0) {
|
|
||||||
QSharedPointer<FindMatchesJob> job(new FindMatchesJob(runner, &context, Queue::instance()));
|
|
||||||
QObject::connect(job->decorator(), SIGNAL(done(ThreadWeaver::JobPointer)), q, SLOT(jobDone(ThreadWeaver::JobPointer)));
|
|
||||||
if (runner->speed() == AbstractRunner::SlowSpeed) {
|
|
||||||
job->setDelayTimer(&delayTimer);
|
|
||||||
}
|
|
||||||
Queue::instance()->enqueue(job);
|
|
||||||
searchJobs.insert(job);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delay in ms before slow runners are allowed to run
|
|
||||||
static const int slowRunDelay = 400;
|
|
||||||
|
|
||||||
RunnerManager *q;
|
|
||||||
QueryMatch deferredRun;
|
|
||||||
RunnerContext context;
|
|
||||||
QTimer matchChangeTimer;
|
|
||||||
QTimer delayTimer; // Timer to control when to run slow runners
|
|
||||||
QHash<QString, AbstractRunner*> runners;
|
|
||||||
QHash<QString, QString> advertiseSingleRunnerIds;
|
|
||||||
AbstractRunner* currentSingleRunner;
|
|
||||||
QSet<QSharedPointer<FindMatchesJob> > searchJobs;
|
|
||||||
QSet<QSharedPointer<FindMatchesJob> > oldSearchJobs;
|
|
||||||
KConfigGroup conf;
|
|
||||||
QString singleModeRunnerId;
|
|
||||||
bool loadAll : 1;
|
|
||||||
bool prepped : 1;
|
|
||||||
bool allRunnersPrepped : 1;
|
|
||||||
bool singleRunnerPrepped : 1;
|
|
||||||
bool teardownRequested : 1;
|
|
||||||
bool singleMode : 1;
|
|
||||||
bool singleRunnerWasLoaded : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*****************************************************
|
|
||||||
* RunnerManager::Public class
|
|
||||||
*
|
|
||||||
*****************************************************/
|
|
||||||
RunnerManager::RunnerManager(QObject *parent)
|
|
||||||
: QObject(parent),
|
|
||||||
d(new RunnerManagerPrivate(this))
|
|
||||||
{
|
|
||||||
d->loadConfiguration();
|
|
||||||
//ThreadWeaver::setDebugLevel(true, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
RunnerManager::RunnerManager(KConfigGroup &c, QObject *parent)
|
|
||||||
: QObject(parent),
|
|
||||||
d(new RunnerManagerPrivate(this))
|
|
||||||
{
|
|
||||||
// Should this be really needed? Maybe d->loadConfiguration(c) would make
|
|
||||||
// more sense.
|
|
||||||
d->conf = KConfigGroup(&c, "PlasmaRunnerManager");
|
|
||||||
d->loadConfiguration();
|
|
||||||
//ThreadWeaver::setDebugLevel(true, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
RunnerManager::~RunnerManager()
|
|
||||||
{
|
|
||||||
if (!qApp->closingDown() && (!d->searchJobs.isEmpty() || !d->oldSearchJobs.isEmpty())) {
|
|
||||||
new DelayedJobCleaner(d->searchJobs + d->oldSearchJobs);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete d;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerManager::reloadConfiguration()
|
|
||||||
{
|
|
||||||
d->loadConfiguration();
|
|
||||||
d->loadRunners();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerManager::setAllowedRunners(const QStringList &runners)
|
|
||||||
{
|
|
||||||
KConfigGroup config = d->configGroup();
|
|
||||||
config.writeEntry("pluginWhiteList", runners);
|
|
||||||
|
|
||||||
if (!d->runners.isEmpty()) {
|
|
||||||
// this has been called with runners already created. so let's do an instant reload
|
|
||||||
d->loadRunners();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList RunnerManager::allowedRunners() const
|
|
||||||
{
|
|
||||||
KConfigGroup config = d->configGroup();
|
|
||||||
return config.readEntry("pluginWhiteList", QStringList());
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerManager::loadRunner(const KService::Ptr service)
|
|
||||||
{
|
|
||||||
KPluginInfo description(service);
|
|
||||||
const QString runnerName = description.pluginName();
|
|
||||||
if (!runnerName.isEmpty() && !d->runners.contains(runnerName)) {
|
|
||||||
AbstractRunner *runner = d->loadInstalledRunner(service);
|
|
||||||
if (runner) {
|
|
||||||
d->runners.insert(runnerName, runner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerManager::loadRunner(const QString &path)
|
|
||||||
{
|
|
||||||
if (!d->runners.contains(path)) {
|
|
||||||
AbstractRunner *runner = new AbstractRunner(this, path);
|
|
||||||
connect(runner, SIGNAL(matchingSuspended(bool)), this, SLOT(runnerMatchingSuspended(bool)));
|
|
||||||
d->runners.insert(path, runner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractRunner* RunnerManager::runner(const QString &name) const
|
|
||||||
{
|
|
||||||
if (d->runners.isEmpty()) {
|
|
||||||
d->loadRunners();
|
|
||||||
}
|
|
||||||
|
|
||||||
return d->runners.value(name, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractRunner *RunnerManager::singleModeRunner() const
|
|
||||||
{
|
|
||||||
return d->currentSingleRunner;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerManager::setSingleModeRunnerId(const QString &id)
|
|
||||||
{
|
|
||||||
d->singleModeRunnerId = id;
|
|
||||||
d->loadSingleRunner();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString RunnerManager::singleModeRunnerId() const
|
|
||||||
{
|
|
||||||
return d->singleModeRunnerId;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RunnerManager::singleMode() const
|
|
||||||
{
|
|
||||||
return d->singleMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerManager::setSingleMode(bool singleMode)
|
|
||||||
{
|
|
||||||
if (d->singleMode == singleMode) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Plasma::AbstractRunner *prevSingleRunner = d->currentSingleRunner;
|
|
||||||
d->singleMode = singleMode;
|
|
||||||
d->loadSingleRunner();
|
|
||||||
d->singleMode = d->currentSingleRunner;
|
|
||||||
|
|
||||||
if (prevSingleRunner != d->currentSingleRunner) {
|
|
||||||
if (d->prepped) {
|
|
||||||
matchSessionComplete();
|
|
||||||
|
|
||||||
if (d->singleMode) {
|
|
||||||
setupMatchSession();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<AbstractRunner *> RunnerManager::runners() const
|
|
||||||
{
|
|
||||||
return d->runners.values();
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList RunnerManager::singleModeAdvertisedRunnerIds() const
|
|
||||||
{
|
|
||||||
return d->advertiseSingleRunnerIds.keys();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString RunnerManager::runnerName(const QString &id) const
|
|
||||||
{
|
|
||||||
if (runner(id)) {
|
|
||||||
return runner(id)->name();
|
|
||||||
} else {
|
|
||||||
return d->advertiseSingleRunnerIds.value(id, QString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RunnerContext* RunnerManager::searchContext() const
|
|
||||||
{
|
|
||||||
return &d->context;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Reordering is here so data is not reordered till strictly needed
|
|
||||||
QList<QueryMatch> RunnerManager::matches() const
|
|
||||||
{
|
|
||||||
return d->context.matches();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerManager::run(const QString &matchId)
|
|
||||||
{
|
|
||||||
run(d->context.match(matchId));
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerManager::run(const QueryMatch &match)
|
|
||||||
{
|
|
||||||
if (!match.isEnabled()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: this function is not const as it may be used for learning
|
|
||||||
AbstractRunner *runner = match.runner();
|
|
||||||
|
|
||||||
for (auto it = d->searchJobs.constBegin(); it != d->searchJobs.constEnd(); ++it) {
|
|
||||||
if ((*it)->runner() == runner && !(*it)->isFinished()) {
|
|
||||||
#ifndef NDEBUG
|
|
||||||
// qDebug() << "deferred run";
|
|
||||||
#endif
|
|
||||||
d->deferredRun = match;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d->deferredRun.isValid()) {
|
|
||||||
d->deferredRun = QueryMatch(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
d->context.run(match);
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<QAction*> RunnerManager::actionsForMatch(const QueryMatch &match)
|
|
||||||
{
|
|
||||||
AbstractRunner *runner = match.runner();
|
|
||||||
if (runner) {
|
|
||||||
return runner->actionsForMatch(match);
|
|
||||||
}
|
|
||||||
|
|
||||||
return QList<QAction*>();
|
|
||||||
}
|
|
||||||
|
|
||||||
QMimeData * RunnerManager::mimeDataForMatch(const QString &id) const
|
|
||||||
{
|
|
||||||
return mimeDataForMatch(d->context.match(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QMimeData * RunnerManager::mimeDataForMatch(const QueryMatch &match) const
|
|
||||||
{
|
|
||||||
AbstractRunner *runner = match.runner();
|
|
||||||
if (runner) {
|
|
||||||
return runner->mimeDataForMatch(match);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
KPluginInfo::List RunnerManager::listRunnerInfo(const QString &parentApp)
|
|
||||||
{
|
|
||||||
return PluginLoader::self()->listRunnerInfo(parentApp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerManager::setupMatchSession()
|
|
||||||
{
|
|
||||||
d->teardownRequested = false;
|
|
||||||
|
|
||||||
if (d->prepped) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->prepped = true;
|
|
||||||
if (d->singleMode) {
|
|
||||||
if (d->currentSingleRunner) {
|
|
||||||
emit d->currentSingleRunner->prepare();
|
|
||||||
d->singleRunnerPrepped = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
foreach (AbstractRunner *runner, d->runners) {
|
|
||||||
#ifdef MEASURE_PREPTIME
|
|
||||||
QTime t;
|
|
||||||
t.start();
|
|
||||||
#endif
|
|
||||||
emit runner->prepare();
|
|
||||||
#ifdef MEASURE_PREPTIME
|
|
||||||
#ifndef NDEBUG
|
|
||||||
// qDebug() << t.elapsed() << runner->name();
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
d->allRunnersPrepped = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerManager::matchSessionComplete()
|
|
||||||
{
|
|
||||||
if (!d->prepped) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->teardownRequested = true;
|
|
||||||
d->checkTearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerManager::launchQuery(const QString &term)
|
|
||||||
{
|
|
||||||
launchQuery(term, QString());
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerManager::launchQuery(const QString &untrimmedTerm, const QString &runnerName)
|
|
||||||
{
|
|
||||||
setupMatchSession();
|
|
||||||
QString term = untrimmedTerm.trimmed();
|
|
||||||
|
|
||||||
setSingleModeRunnerId(runnerName);
|
|
||||||
setSingleMode(d->currentSingleRunner);
|
|
||||||
if (!runnerName.isEmpty() && !d->currentSingleRunner) {
|
|
||||||
reset();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (term.isEmpty()) {
|
|
||||||
if (d->singleMode && d->currentSingleRunner->defaultSyntax()) {
|
|
||||||
term = d->currentSingleRunner->defaultSyntax()->exampleQueries().first().remove(QRegExp(":q:"));
|
|
||||||
} else {
|
|
||||||
reset();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d->context.query() == term) {
|
|
||||||
// we already are searching for this!
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!d->singleMode && d->runners.isEmpty()) {
|
|
||||||
d->loadRunners();
|
|
||||||
}
|
|
||||||
|
|
||||||
reset();
|
|
||||||
// qDebug() << "runners searching for" << term << "on" << runnerName;
|
|
||||||
d->context.setQuery(term);
|
|
||||||
|
|
||||||
QHash<QString, AbstractRunner*> runable;
|
|
||||||
|
|
||||||
//if the name is not empty we will launch only the specified runner
|
|
||||||
if (d->singleMode) {
|
|
||||||
runable.insert(QString(), d->currentSingleRunner);
|
|
||||||
d->context.setSingleRunnerQueryMode(true);
|
|
||||||
} else {
|
|
||||||
runable = d->runners;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (Plasma::AbstractRunner *r, runable) {
|
|
||||||
if (r->isMatchingSuspended()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->startJob(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start timer to unblock slow runners
|
|
||||||
d->delayTimer.start(RunnerManagerPrivate::slowRunDelay);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString RunnerManager::query() const
|
|
||||||
{
|
|
||||||
return d->context.query();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerManager::reset()
|
|
||||||
{
|
|
||||||
// If ThreadWeaver is idle, it is safe to clear previous jobs
|
|
||||||
if (Queue::instance()->isIdle()) {
|
|
||||||
d->oldSearchJobs.clear();
|
|
||||||
} else {
|
|
||||||
for (auto it = d->searchJobs.constBegin(); it != d->searchJobs.constEnd(); ++it) {
|
|
||||||
Queue::instance()->dequeue((*it));
|
|
||||||
}
|
|
||||||
d->oldSearchJobs += d->searchJobs;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->searchJobs.clear();
|
|
||||||
|
|
||||||
if (d->deferredRun.isEnabled()) {
|
|
||||||
//qDebug() << "job actually done, running now **************";
|
|
||||||
QueryMatch tmpRun = d->deferredRun;
|
|
||||||
d->deferredRun = QueryMatch(0);
|
|
||||||
tmpRun.run(d->context);
|
|
||||||
}
|
|
||||||
|
|
||||||
d->context.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // Plasma namespace
|
|
||||||
|
|
||||||
|
|
||||||
#include "moc_runnermanager.cpp"
|
|
@ -1,287 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2006 Aaron Seigo <aseigo@kde.org>
|
|
||||||
* Copyright (C) 2007 Ryan P. Bitanga <ryan.bitanga@gmail.com>
|
|
||||||
* Copyright (C) 2008 Jordi Polo <mumismo@gmail.com>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Library General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Library General Public
|
|
||||||
* License along with this program; if not, write to the
|
|
||||||
* Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PLASMA_RUNNERMANAGER_H
|
|
||||||
#define PLASMA_RUNNERMANAGER_H
|
|
||||||
|
|
||||||
#include <QtCore/QList>
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
|
|
||||||
#include <kplugininfo.h>
|
|
||||||
|
|
||||||
#include <plasma/plasma_export.h>
|
|
||||||
#include "abstractrunner.h"
|
|
||||||
|
|
||||||
class QAction;
|
|
||||||
class KConfigGroup;
|
|
||||||
|
|
||||||
namespace Plasma
|
|
||||||
{
|
|
||||||
class QueryMatch;
|
|
||||||
class AbstractRunner;
|
|
||||||
class RunnerContext;
|
|
||||||
class RunnerManagerPrivate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @class RunnerManager plasma/runnermanager.h <Plasma/RunnerManager>
|
|
||||||
*
|
|
||||||
* @short The RunnerManager class decides what installed runners are runnable,
|
|
||||||
* and their ratings. It is the main proxy to the runners.
|
|
||||||
*/
|
|
||||||
class PLASMA_EXPORT RunnerManager : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit RunnerManager(QObject *parent=0);
|
|
||||||
explicit RunnerManager(KConfigGroup &config, QObject *parent=0);
|
|
||||||
~RunnerManager();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds and returns a loaded runner or NULL
|
|
||||||
* @param pluginName the name of the runner plugin
|
|
||||||
* @return Pointer to the runner
|
|
||||||
*/
|
|
||||||
AbstractRunner *runner(const QString &pluginName) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the currently active "single mode" runner, or null if none
|
|
||||||
* @since 4.4
|
|
||||||
*/
|
|
||||||
AbstractRunner *singleModeRunner() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Puts the manager into "single runner" mode using the given
|
|
||||||
* runner; if the runner does not exist or can not be loaded then
|
|
||||||
* the single runner mode will not be started and singleModeRunner()
|
|
||||||
* will return NULL
|
|
||||||
* @param id the id of the runner to use
|
|
||||||
* @since 4.4
|
|
||||||
*/
|
|
||||||
void setSingleModeRunnerId(const QString &id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the id of the runner to use in single mode
|
|
||||||
* @since 4.4
|
|
||||||
*/
|
|
||||||
QString singleModeRunnerId() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true if the manager is set to run in single runner mode
|
|
||||||
* @since 4.4
|
|
||||||
*/
|
|
||||||
bool singleMode() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets whether or not the manager is in single mode.
|
|
||||||
*
|
|
||||||
* @param singleMode true if the manager should be in single mode, false otherwise
|
|
||||||
* @since 4.4
|
|
||||||
*/
|
|
||||||
void setSingleMode(bool singleMode);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the translated name of a runner
|
|
||||||
* @param id the id of the runner
|
|
||||||
*
|
|
||||||
* @since 4.4
|
|
||||||
*/
|
|
||||||
QString runnerName(const QString &id) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the list of all currently loaded runners
|
|
||||||
*/
|
|
||||||
QList<AbstractRunner *> runners() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the names of all runners that advertise single query mode
|
|
||||||
* @since 4.4
|
|
||||||
*/
|
|
||||||
QStringList singleModeAdvertisedRunnerIds() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the current context
|
|
||||||
* @return pointer to the current context
|
|
||||||
*/
|
|
||||||
RunnerContext *searchContext() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves all available matches found so far for the previously launched query
|
|
||||||
* @return List of matches
|
|
||||||
*/
|
|
||||||
QList<QueryMatch> matches() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs a given match
|
|
||||||
* @param match the match to be executed
|
|
||||||
*/
|
|
||||||
void run(const QueryMatch &match);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs a given match
|
|
||||||
* @param id the id of the match to run
|
|
||||||
*/
|
|
||||||
void run(const QString &id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the list of actions, if any, for a match
|
|
||||||
*/
|
|
||||||
QList<QAction*> actionsForMatch(const QueryMatch &match);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the current query term
|
|
||||||
*/
|
|
||||||
QString query() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Causes a reload of the current configuration
|
|
||||||
*/
|
|
||||||
void reloadConfiguration();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a whitelist for the plugins that can be loaded
|
|
||||||
*
|
|
||||||
* @param plugins the plugin names of allowed runners
|
|
||||||
* @since 4.4
|
|
||||||
*/
|
|
||||||
void setAllowedRunners(const QStringList &runners);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempts to add the AbstractRunner plugin represented
|
|
||||||
* by the KService passed in. Usually one can simply let
|
|
||||||
* the configuration of plugins handle loading Runner plugins,
|
|
||||||
* but in cases where specific runners should be loaded this
|
|
||||||
* allows for that to take place
|
|
||||||
*
|
|
||||||
* @param service the service to use to load the plugin
|
|
||||||
* @since 4.5
|
|
||||||
*/
|
|
||||||
void loadRunner(const KService::Ptr service);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempts to add the AbstractRunner from a Plasma::Package on disk.
|
|
||||||
* Usually one can simply let the configuration of plugins
|
|
||||||
* handle loading Runner plugins, but in cases where specific
|
|
||||||
* runners should be loaded this allows for that to take place
|
|
||||||
*
|
|
||||||
* @param path the path to a Runner package to load
|
|
||||||
* @since 4.5
|
|
||||||
*/
|
|
||||||
void loadRunner(const QString &path);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the list of allowed plugins
|
|
||||||
* @since 4.4
|
|
||||||
*/
|
|
||||||
QStringList allowedRunners() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return mime data of the specified match
|
|
||||||
* @since 4.5
|
|
||||||
*/
|
|
||||||
QMimeData * mimeDataForMatch(const QueryMatch &match) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return mime data of the specified match
|
|
||||||
* @since 4.5
|
|
||||||
*/
|
|
||||||
QMimeData * mimeDataForMatch(const QString &matchId) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of all known Runner implementations
|
|
||||||
*
|
|
||||||
* @param parentApp the application to filter applets on. Uses the
|
|
||||||
* X-KDE-ParentApp entry (if any) in the plugin info.
|
|
||||||
* The default value of QString() will result in a
|
|
||||||
* list containing only applets not specifically
|
|
||||||
* registered to an application.
|
|
||||||
* @return list of AbstractRunners
|
|
||||||
* @since 4.6
|
|
||||||
**/
|
|
||||||
static KPluginInfo::List listRunnerInfo(const QString &parentApp = QString());
|
|
||||||
|
|
||||||
public Q_SLOTS:
|
|
||||||
/**
|
|
||||||
* Call this method when the runners should be prepared for a query session.
|
|
||||||
* Call matchSessionComplete when the query session is finished for the time
|
|
||||||
* being.
|
|
||||||
* @since 4.4
|
|
||||||
* @see matchSessionComplete
|
|
||||||
*/
|
|
||||||
void setupMatchSession();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call this method when the query session is finished for the time
|
|
||||||
* being.
|
|
||||||
* @since 4.4
|
|
||||||
* @see prepareForMatchSession
|
|
||||||
*/
|
|
||||||
void matchSessionComplete();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Launch a query, this will create threads and return inmediately.
|
|
||||||
* When the information will be available can be known using the
|
|
||||||
* matchesChanged signal.
|
|
||||||
*
|
|
||||||
* @param term the term we want to find matches for
|
|
||||||
* @param runnerId optional, if only one specific runner is to be used;
|
|
||||||
* providing an id will put the manager into single runner mode
|
|
||||||
*/
|
|
||||||
void launchQuery(const QString &term, const QString &runnerId);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convenience version of above
|
|
||||||
*/
|
|
||||||
void launchQuery(const QString &term);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset the current data and stops the query
|
|
||||||
*/
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
/**
|
|
||||||
* Emitted each time a new match is added to the list
|
|
||||||
*/
|
|
||||||
void matchesChanged(const QList<Plasma::QueryMatch> &matches);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Emitted when the launchQuery finish
|
|
||||||
* @since 4.5
|
|
||||||
*/
|
|
||||||
void queryFinished();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Q_PRIVATE_SLOT(d, void scheduleMatchesChanged())
|
|
||||||
Q_PRIVATE_SLOT(d, void matchesChanged())
|
|
||||||
Q_PRIVATE_SLOT(d, void jobDone(ThreadWeaver::JobPointer))
|
|
||||||
Q_PRIVATE_SLOT(d, void unblockJobs())
|
|
||||||
Q_PRIVATE_SLOT(d, void runnerMatchingSuspended(bool))
|
|
||||||
|
|
||||||
RunnerManagerPrivate * const d;
|
|
||||||
|
|
||||||
friend class RunnerManagerPrivate;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,110 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2009 Aaron Seigo <aseigo@kde.org>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Library General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Library General Public
|
|
||||||
* License along with this program; if not, write to the
|
|
||||||
* Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "runnersyntax.h"
|
|
||||||
|
|
||||||
#include <klocalizedstring.h>
|
|
||||||
|
|
||||||
namespace Plasma
|
|
||||||
{
|
|
||||||
|
|
||||||
class RunnerSyntaxPrivate
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RunnerSyntaxPrivate(const QString &s, const QString &d)
|
|
||||||
: description(d)
|
|
||||||
{
|
|
||||||
exampleQueries.append(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList exampleQueries;
|
|
||||||
QString description;
|
|
||||||
QString termDescription;
|
|
||||||
};
|
|
||||||
|
|
||||||
RunnerSyntax::RunnerSyntax(const QString &exampleQuery, const QString &description)
|
|
||||||
: d(new RunnerSyntaxPrivate(exampleQuery, description))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
RunnerSyntax::RunnerSyntax(const RunnerSyntax &other)
|
|
||||||
: d(new RunnerSyntaxPrivate(*other.d))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
RunnerSyntax::~RunnerSyntax()
|
|
||||||
{
|
|
||||||
delete d;
|
|
||||||
}
|
|
||||||
|
|
||||||
RunnerSyntax &RunnerSyntax::operator=(const RunnerSyntax &rhs)
|
|
||||||
{
|
|
||||||
*d = *rhs.d;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerSyntax::addExampleQuery(const QString &exampleQuery)
|
|
||||||
{
|
|
||||||
d->exampleQueries.append(exampleQuery);
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList RunnerSyntax::exampleQueries() const
|
|
||||||
{
|
|
||||||
return d->exampleQueries;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList RunnerSyntax::exampleQueriesWithTermDescription() const
|
|
||||||
{
|
|
||||||
QStringList queries;
|
|
||||||
const QString termDesc('<' + searchTermDescription() + '>');
|
|
||||||
foreach (QString query, d->exampleQueries) {
|
|
||||||
queries << query.replace(":q:", termDesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return queries;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerSyntax::setDescription(const QString &description)
|
|
||||||
{
|
|
||||||
d->description = description;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString RunnerSyntax::description() const
|
|
||||||
{
|
|
||||||
QString description = d->description;
|
|
||||||
description.replace(":q:", '<' + searchTermDescription() + '>');
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerSyntax::setSearchTermDescription(const QString &description)
|
|
||||||
{
|
|
||||||
d->termDescription = description;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString RunnerSyntax::searchTermDescription() const
|
|
||||||
{
|
|
||||||
if (d->termDescription.isEmpty()) {
|
|
||||||
return i18n("search term");
|
|
||||||
}
|
|
||||||
|
|
||||||
return d->termDescription;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // Plasma namespace
|
|
||||||
|
|
@ -1,125 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2009 Aaron Seigo <aseigo@kde.org>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Library General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Library General Public
|
|
||||||
* License along with this program; if not, write to the
|
|
||||||
* Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PLASMA_RUNNERSYNTAX_H
|
|
||||||
#define PLASMA_RUNNERSYNTAX_H
|
|
||||||
|
|
||||||
#include <QtCore/QStringList>
|
|
||||||
|
|
||||||
#include <plasma/plasma.h>
|
|
||||||
|
|
||||||
namespace Plasma
|
|
||||||
{
|
|
||||||
|
|
||||||
class RunnerSyntaxPrivate;
|
|
||||||
/**
|
|
||||||
* @class RunnerSyntax
|
|
||||||
* @since 4.3
|
|
||||||
*
|
|
||||||
* Represents a query prototype that the runner accepts. These can be
|
|
||||||
* created and registered with AbstractRunner::addSyntax(Syntax &) to
|
|
||||||
* allow applications to show to the user what the runner is currently
|
|
||||||
* capable of doing
|
|
||||||
*/
|
|
||||||
class PLASMA_EXPORT RunnerSyntax
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Constructs a simple syntax object
|
|
||||||
*
|
|
||||||
* @param exampleQuery an example of the query, with :q: placed wherever
|
|
||||||
* search term text might appear. e.g. if the runner
|
|
||||||
* accepts "keyword some random text" then the value
|
|
||||||
* of this parameter should be "keyword :q:"
|
|
||||||
* @param descrition A description of what the described syntax does from
|
|
||||||
* the user's point of view.
|
|
||||||
*/
|
|
||||||
RunnerSyntax(const QString &exampleQuery, const QString &description);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy constructor
|
|
||||||
*/
|
|
||||||
RunnerSyntax(const RunnerSyntax &other);
|
|
||||||
|
|
||||||
~RunnerSyntax();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assignment operator
|
|
||||||
*/
|
|
||||||
RunnerSyntax &operator=(const RunnerSyntax &rhs);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a synonymous example query to this Syntax. Some runners may
|
|
||||||
* accept multiple formulations of keywords to trigger the same behaviour.
|
|
||||||
* This allows the runner to show these relationships by grouping the
|
|
||||||
* example queries into one Syntax object
|
|
||||||
*
|
|
||||||
* @param exampleQuery an example of the query, with :q: placed wherever
|
|
||||||
* search term text might appear. e.g. if the runner
|
|
||||||
* accepts "keyword some random text" then the value
|
|
||||||
* of this parameter should be "keyword :q:"
|
|
||||||
*/
|
|
||||||
void addExampleQuery(const QString &exampleQuery);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the example queries associated with this Syntax object
|
|
||||||
*/
|
|
||||||
QStringList exampleQueries() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the example queries associated with this Syntax object, with
|
|
||||||
* the searchTermDescription replacing instances of :q:. Used for showing
|
|
||||||
* the queries in the user interface.
|
|
||||||
*/
|
|
||||||
QStringList exampleQueriesWithTermDescription() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the description for the syntax, describing what it does from
|
|
||||||
* the user's point of view.
|
|
||||||
*/
|
|
||||||
void setDescription(const QString &description);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the description of what the syntax does from the user's
|
|
||||||
* point of view
|
|
||||||
*/
|
|
||||||
QString description() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the text that should be used to replace instances of :q:
|
|
||||||
* in the text. By default this is the generic phrase "search term".
|
|
||||||
* If the syntax expects a specific kind of input, it may be defined
|
|
||||||
* here. A syntax used by a runner that changes the brightness of the display
|
|
||||||
* may set this to "brightness" for instance.
|
|
||||||
*/
|
|
||||||
void setSearchTermDescription(const QString &description);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return a description of the search term for this syntax
|
|
||||||
*/
|
|
||||||
QString searchTermDescription() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
RunnerSyntaxPrivate *const d;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Plasma
|
|
||||||
|
|
||||||
#endif // multiple inclusion guard
|
|
||||||
|
|
@ -1,194 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2007 by Aaron Seigo <aseigo@kde.org>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Library General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Library General Public
|
|
||||||
* License along with this program; if not, write to the
|
|
||||||
* Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "scripting/runnerscript.h"
|
|
||||||
|
|
||||||
#include "abstractrunner.h"
|
|
||||||
#include "package.h"
|
|
||||||
#include "private/dataenginemanager_p.h"
|
|
||||||
#include "private/abstractrunner_p.h"
|
|
||||||
|
|
||||||
namespace Plasma
|
|
||||||
{
|
|
||||||
|
|
||||||
class RunnerScriptPrivate
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RunnerScriptPrivate()
|
|
||||||
: runner(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractRunner *runner;
|
|
||||||
};
|
|
||||||
|
|
||||||
RunnerScript::RunnerScript(QObject *parent)
|
|
||||||
: ScriptEngine(parent),
|
|
||||||
d(new RunnerScriptPrivate)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
RunnerScript::~RunnerScript()
|
|
||||||
{
|
|
||||||
delete d;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerScript::setRunner(AbstractRunner *runner)
|
|
||||||
{
|
|
||||||
d->runner = runner;
|
|
||||||
connect(runner, SIGNAL(prepare()), this, SIGNAL(prepare()));
|
|
||||||
connect(runner, SIGNAL(teardown()), this, SIGNAL(teardown()));
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractRunner *RunnerScript::runner() const
|
|
||||||
{
|
|
||||||
return d->runner;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerScript::match(Plasma::RunnerContext &search)
|
|
||||||
{
|
|
||||||
Q_UNUSED(search);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerScript::run(const Plasma::RunnerContext &search, const Plasma::QueryMatch &action)
|
|
||||||
{
|
|
||||||
Q_UNUSED(search);
|
|
||||||
Q_UNUSED(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
DataEngine *RunnerScript::dataEngine(const QString &name)
|
|
||||||
{
|
|
||||||
if (d->runner) {
|
|
||||||
return d->runner->dataEngine(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return DataEngineManager::self()->engine(QString());
|
|
||||||
}
|
|
||||||
|
|
||||||
KConfigGroup RunnerScript::config() const
|
|
||||||
{
|
|
||||||
if (d->runner) {
|
|
||||||
return d->runner->config();
|
|
||||||
}
|
|
||||||
return KConfigGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerScript::setIgnoredTypes(RunnerContext::Types types)
|
|
||||||
{
|
|
||||||
if (d->runner) {
|
|
||||||
d->runner->setIgnoredTypes(types);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerScript::setHasRunOptions(bool hasRunOptions)
|
|
||||||
{
|
|
||||||
if (d->runner) {
|
|
||||||
d->runner->setHasRunOptions(hasRunOptions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerScript::setSpeed(AbstractRunner::Speed newSpeed)
|
|
||||||
{
|
|
||||||
if (d->runner) {
|
|
||||||
d->runner->setSpeed(newSpeed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerScript::setPriority(AbstractRunner::Priority newPriority)
|
|
||||||
{
|
|
||||||
if (d->runner) {
|
|
||||||
d->runner->setPriority(newPriority);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* RunnerScript::addAction(const QString &id, const QIcon &icon, const QString &text)
|
|
||||||
{
|
|
||||||
if (d->runner) {
|
|
||||||
return d->runner->addAction(id, icon, text);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerScript::addAction(const QString &id, QAction *action)
|
|
||||||
{
|
|
||||||
if (d->runner) {
|
|
||||||
d->runner->addAction(id, action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerScript::removeAction(const QString &id)
|
|
||||||
{
|
|
||||||
if (d->runner) {
|
|
||||||
d->runner->removeAction(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QAction* RunnerScript::action(const QString &id) const
|
|
||||||
{
|
|
||||||
if (d->runner) {
|
|
||||||
return d->runner->action(id);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
QHash<QString, QAction*> RunnerScript::actions() const
|
|
||||||
{
|
|
||||||
if (d->runner) {
|
|
||||||
return d->runner->actions();
|
|
||||||
}
|
|
||||||
return QHash<QString, QAction*>();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerScript::clearActions()
|
|
||||||
{
|
|
||||||
if (d->runner) {
|
|
||||||
d->runner->clearActions();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerScript::addSyntax(const RunnerSyntax &syntax)
|
|
||||||
{
|
|
||||||
if (d->runner) {
|
|
||||||
d->runner->addSyntax(syntax);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunnerScript::setSyntaxes(const QList<RunnerSyntax> &syns)
|
|
||||||
{
|
|
||||||
if (d->runner) {
|
|
||||||
d->runner->setSyntaxes(syns);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Package RunnerScript::package() const
|
|
||||||
{
|
|
||||||
return d->runner ? d->runner->package() : Package();
|
|
||||||
}
|
|
||||||
|
|
||||||
KPluginInfo RunnerScript::description() const
|
|
||||||
{
|
|
||||||
return d->runner ? d->runner->d->runnerDescription : KPluginInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString RunnerScript::mainScript() const
|
|
||||||
{
|
|
||||||
return package().filePath("mainscript");
|
|
||||||
}
|
|
||||||
|
|
||||||
} // Plasma namespace
|
|
@ -1,134 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2007 by Aaron Seigo <aseigo@kde.org>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Library General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Library General Public
|
|
||||||
* License along with this program; if not, write to the
|
|
||||||
* Free Software Foundation, Inc.,
|
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PLASMA_RUNNERSCRIPT_H
|
|
||||||
#define PLASMA_RUNNERSCRIPT_H
|
|
||||||
|
|
||||||
#include <kplugininfo.h>
|
|
||||||
|
|
||||||
#include <plasma/plasma_export.h>
|
|
||||||
#include <plasma/abstractrunner.h>
|
|
||||||
#include <plasma/scripting/scriptengine.h>
|
|
||||||
|
|
||||||
namespace Plasma
|
|
||||||
{
|
|
||||||
|
|
||||||
class RunnerScriptPrivate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @class RunnerScript plasma/scripting/runnerscript.h <Plasma/Scripting/RunnerScript>
|
|
||||||
*
|
|
||||||
* @short Provides a restricted interface for scripting a runner.
|
|
||||||
*/
|
|
||||||
class PLASMA_EXPORT RunnerScript : public ScriptEngine
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Default constructor for a RunnerScript.
|
|
||||||
* Subclasses should not attempt to access the Plasma::AbstractRunner
|
|
||||||
* associated with this RunnerScript in the constructor. All
|
|
||||||
* such set up that requires the AbstractRunner itself should be done
|
|
||||||
* in the init() method.
|
|
||||||
*/
|
|
||||||
explicit RunnerScript(QObject *parent = 0);
|
|
||||||
~RunnerScript();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the Plasma::AbstractRunner associated with this RunnerScript
|
|
||||||
*/
|
|
||||||
void setRunner(AbstractRunner *runner);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the Plasma::AbstractRunner associated with this script component
|
|
||||||
*/
|
|
||||||
AbstractRunner *runner() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the script should create QueryMatch instances through
|
|
||||||
* RunnerContext::addInformationalMatch, RunnerContext::addExactMatch, and
|
|
||||||
* RunnerContext::addPossibleMatch.
|
|
||||||
*/
|
|
||||||
virtual void match(Plasma::RunnerContext &search);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called whenever an exact or possible match associated with this
|
|
||||||
* runner is triggered.
|
|
||||||
*/
|
|
||||||
virtual void run(const Plasma::RunnerContext &search, const Plasma::QueryMatch &action);
|
|
||||||
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void prepare();
|
|
||||||
void teardown();
|
|
||||||
void createRunOptions(QWidget *widget);
|
|
||||||
void reloadConfiguration();
|
|
||||||
void actionsForMatch(const Plasma::QueryMatch &match, QList<QAction*>* actions);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/**
|
|
||||||
* @return absolute path to the main script file for this plasmoid
|
|
||||||
*/
|
|
||||||
QString mainScript() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the Package associated with this plasmoid which can
|
|
||||||
* be used to request resources, such as images and
|
|
||||||
* interface files.
|
|
||||||
*/
|
|
||||||
Package package() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the KPluginInfo associated with this plasmoid
|
|
||||||
*/
|
|
||||||
KPluginInfo description() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return a Plasma::DataEngine matchin name
|
|
||||||
* @since 4.4
|
|
||||||
*/
|
|
||||||
DataEngine *dataEngine(const QString &name);
|
|
||||||
|
|
||||||
KConfigGroup config() const;
|
|
||||||
void setIgnoredTypes(RunnerContext::Types types);
|
|
||||||
void setHasRunOptions(bool hasRunOptions);
|
|
||||||
void setSpeed(AbstractRunner::Speed newSpeed);
|
|
||||||
void setPriority(AbstractRunner::Priority newPriority);
|
|
||||||
QAction* addAction(const QString &id, const QIcon &icon, const QString &text);
|
|
||||||
void addAction(const QString &id, QAction *action);
|
|
||||||
void removeAction(const QString &id);
|
|
||||||
QAction* action(const QString &id) const;
|
|
||||||
QHash<QString, QAction*> actions() const;
|
|
||||||
void clearActions();
|
|
||||||
void addSyntax(const RunnerSyntax &syntax);
|
|
||||||
void setSyntaxes(const QList<RunnerSyntax> &syns);
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class AbstractRunner;
|
|
||||||
|
|
||||||
RunnerScriptPrivate *const d;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define K_EXPORT_PLASMA_RUNNERSCRIPTENGINE(libname, classname) \
|
|
||||||
K_PLUGIN_FACTORY(factory, registerPlugin<classname>();)
|
|
||||||
|
|
||||||
} //Plasma namespace
|
|
||||||
|
|
||||||
#endif
|
|
@ -23,14 +23,12 @@
|
|||||||
#include <kservice.h>
|
#include <kservice.h>
|
||||||
#include <kservicetypetrader.h>
|
#include <kservicetypetrader.h>
|
||||||
|
|
||||||
#include "abstractrunner.h"
|
|
||||||
#include "applet.h"
|
#include "applet.h"
|
||||||
#include "dataengine.h"
|
#include "dataengine.h"
|
||||||
#include "package.h"
|
#include "package.h"
|
||||||
#include "private/componentinstaller_p.h"
|
#include "private/componentinstaller_p.h"
|
||||||
#include "scripting/appletscript.h"
|
#include "scripting/appletscript.h"
|
||||||
#include "scripting/dataenginescript.h"
|
#include "scripting/dataenginescript.h"
|
||||||
#include "scripting/runnerscript.h"
|
|
||||||
|
|
||||||
namespace Plasma
|
namespace Plasma
|
||||||
{
|
{
|
||||||
@ -218,17 +216,6 @@ DataEngineScript *loadScriptEngine(const QString &language, DataEngine *dataEngi
|
|||||||
return engine;
|
return engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
RunnerScript *loadScriptEngine(const QString &language, AbstractRunner *runner)
|
|
||||||
{
|
|
||||||
RunnerScript *engine = static_cast<RunnerScript*>(loadEngine(language, Types::RunnerComponent, runner));
|
|
||||||
|
|
||||||
if (engine) {
|
|
||||||
//engine->setRunner(runner);
|
|
||||||
}
|
|
||||||
|
|
||||||
return engine;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Plasma
|
} // namespace Plasma
|
||||||
|
|
||||||
#include "moc_scriptengine.cpp"
|
#include "moc_scriptengine.cpp"
|
||||||
|
@ -106,16 +106,6 @@ PLASMA_EXPORT AppletScript *loadScriptEngine(const QString &language, Applet *ap
|
|||||||
**/
|
**/
|
||||||
PLASMA_EXPORT DataEngineScript *loadScriptEngine(const QString &language, DataEngine *dataEngine);
|
PLASMA_EXPORT DataEngineScript *loadScriptEngine(const QString &language, DataEngine *dataEngine);
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads an Applet script engine for the given language.
|
|
||||||
*
|
|
||||||
* @param language the language to load for
|
|
||||||
* @param runner the Plasma::AbstractRunner for this script
|
|
||||||
* @return pointer to the RunnerScript or 0 on failure; the caller is responsible
|
|
||||||
* for the return object which will be parented to the AbstractRunner
|
|
||||||
**/
|
|
||||||
PLASMA_EXPORT RunnerScript *loadScriptEngine(const QString &language, AbstractRunner *runner);
|
|
||||||
|
|
||||||
} // namespace Plasma
|
} // namespace Plasma
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -40,7 +40,7 @@ unsigned int versionMinor()
|
|||||||
|
|
||||||
unsigned int versionRelease()
|
unsigned int versionRelease()
|
||||||
{
|
{
|
||||||
return PLASMA_VERSION_RELEASE;
|
return PLASMA_VERSION_PATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *versionString()
|
const char *versionString()
|
||||||
|
@ -17,34 +17,16 @@
|
|||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PLASMA_VERSION_H
|
#ifndef PLASMAVERSION_H
|
||||||
#define PLASMA_VERSION_H
|
#define PLASMAVERSION_H
|
||||||
|
|
||||||
/** @file plasma/version.h <Plasma/Version> */
|
/** @file plasma/version.h <Plasma/Version> */
|
||||||
|
|
||||||
#include <plasma/plasma_export.h>
|
#include <plasma/plasma_export.h>
|
||||||
|
#include <plasma_version.h>
|
||||||
/**
|
|
||||||
* String version of libplasma version, suitable for use in
|
|
||||||
* file formats or network protocols
|
|
||||||
*/
|
|
||||||
#define PLASMA_VERSION_STRING "3.80.0"
|
|
||||||
|
|
||||||
/// @brief Major version of libplasma, at compile time
|
|
||||||
#define PLASMA_VERSION_MAJOR 3
|
|
||||||
/// @brief Minor version of libplasma, at compile time
|
|
||||||
#define PLASMA_VERSION_MINOR 80
|
|
||||||
/// @brief Release version of libplasma, at compile time
|
|
||||||
#define PLASMA_VERSION_RELEASE 0
|
|
||||||
|
|
||||||
#define PLASMA_MAKE_VERSION(a,b,c) (((a) << 16) | ((b) << 8) | (c))
|
#define PLASMA_MAKE_VERSION(a,b,c) (((a) << 16) | ((b) << 8) | (c))
|
||||||
|
|
||||||
/**
|
|
||||||
* Compile time macro for the version number of libplasma
|
|
||||||
*/
|
|
||||||
#define PLASMA_VERSION \
|
|
||||||
PLASMA_MAKE_VERSION(PLASMA_VERSION_MAJOR, PLASMA_VERSION_MINOR, PLASMA_VERSION_RELEASE)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compile-time macro for checking the plasma version. Not useful for
|
* Compile-time macro for checking the plasma version. Not useful for
|
||||||
* detecting the version of libplasma at runtime.
|
* detecting the version of libplasma at runtime.
|
||||||
|
@ -5,7 +5,6 @@ include(PythonMacros)
|
|||||||
# install the library, .desktop, and plasma.py
|
# install the library, .desktop, and plasma.py
|
||||||
python_install(plasma_importer.py ${DATA_INSTALL_DIR}/plasma_scriptengine_python)
|
python_install(plasma_importer.py ${DATA_INSTALL_DIR}/plasma_scriptengine_python)
|
||||||
python_install(pydataengine.py ${DATA_INSTALL_DIR}/plasma_scriptengine_python)
|
python_install(pydataengine.py ${DATA_INSTALL_DIR}/plasma_scriptengine_python)
|
||||||
python_install(pyrunner.py ${DATA_INSTALL_DIR}/plasma_scriptengine_python)
|
|
||||||
|
|
||||||
# remove the following three lines once we branch 4.5, they are only necessary as long
|
# remove the following three lines once we branch 4.5, they are only necessary as long
|
||||||
# as people update kdebase but not yet kdelibs (PYTHON_SITE_PACKAGES_INSTALL_DIR has just
|
# as people update kdebase but not yet kdelibs (PYTHON_SITE_PACKAGES_INSTALL_DIR has just
|
||||||
@ -18,6 +17,4 @@ python_install(plasmascript.py ${PYTHON_SITE_PACKAGES_INSTALL_DIR}/PyKDE4)
|
|||||||
|
|
||||||
install(FILES plasma-scriptengine-dataengine-python.desktop
|
install(FILES plasma-scriptengine-dataengine-python.desktop
|
||||||
DESTINATION ${SERVICES_INSTALL_DIR})
|
DESTINATION ${SERVICES_INSTALL_DIR})
|
||||||
install(FILES plasma-scriptengine-runner-python.desktop
|
|
||||||
DESTINATION ${SERVICES_INSTALL_DIR})
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user