2 * This file is part of KDevelop
4 * Copyright 2007 Hamish Rodda <rodda@kde.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Library General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the
18 * Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include "executeplugin.h"
24 #include <QApplication>
27 #include <kpluginfactory.h>
28 #include <kpluginloader.h>
31 #include <kmessagebox.h>
32 #include <kaboutdata.h>
34 #include <util/environmentgrouplist.h>
36 using namespace KDevelop
;
38 K_PLUGIN_FACTORY(KDevExecuteFactory
, registerPlugin
<ExecutePlugin
>(); )
39 K_EXPORT_PLUGIN(KDevExecuteFactory(KAboutData("kdevexecute", "kdevexecute", ki18n("Execute support"), "0.1", ki18n("Allows running of native apps"), KAboutData::License_GPL
)))
41 ExecutePlugin::ExecutePlugin(QObject
*parent
, const QVariantList
&)
42 : KDevelop::IPlugin(KDevExecuteFactory::componentData(), parent
)
44 KDEV_USE_EXTENSION_INTERFACE( KDevelop::IRunProvider
)
47 ExecutePlugin::~ExecutePlugin()
51 void ExecutePlugin::unload()
55 QStringList
ExecutePlugin::instrumentorsProvided() const
57 return QStringList() << "default";
60 QString
ExecutePlugin::translatedInstrumentor(const QString
&) const
65 bool ExecutePlugin::execute(const IRun
& run
, KJob
* job
)
67 Q_ASSERT(instrumentorsProvided().contains(run
.instrumentor()));
69 QProcess
* process
= new QProcess(this);
70 connect(process
, SIGNAL(readyReadStandardOutput()), SLOT(readyReadStandardOutput()));
71 connect(process
, SIGNAL(readyReadStandardError()), SLOT(readyReadStandardError()));
72 connect(process
, SIGNAL(finished(int, QProcess::ExitStatus
)), SLOT(processFinished(int, QProcess::ExitStatus
)));
73 connect(process
, SIGNAL(error(QProcess::ProcessError
)), SLOT(error(QProcess::ProcessError
)));
75 m_runners
.insert(job
, process
);
77 KDevelop::EnvironmentGroupList
l(KGlobal::config());
78 process
->setProperty("job", QVariant::fromValue(static_cast<void*>(job
)));
79 process
->setEnvironment(l
.createEnvironment(run
.environmentKey(), process
->systemEnvironment()));
80 process
->setWorkingDirectory(run
.workingDirectory().path());
82 process
->setProperty("executable", run
.executable().path());
83 process
->start(run
.executable().path(), run
.arguments());
85 kDebug() << "Started process" << run
.executable().path() << "with arguments" << run
.arguments();
90 void ExecutePlugin::abort(KJob
* job
)
92 if (m_runners
.contains(job
)) {
93 QProcess
* process
= m_runners
.take(job
);
99 void ExecutePlugin::readyReadStandardError()
101 QProcess
* process
= qobject_cast
<QProcess
*>(sender());
105 readFrom(process
, QProcess::StandardError
);
108 void ExecutePlugin::readyReadStandardOutput()
110 QProcess
* process
= qobject_cast
<QProcess
*>(sender());
114 readFrom(process
, QProcess::StandardOutput
);
117 void ExecutePlugin::readFrom(QProcess
* process
, QProcess::ProcessChannel channel
)
119 process
->setReadChannel(channel
);
120 KJob
* job
= static_cast<KJob
*>(qvariant_cast
<void*>(process
->property("job")));
122 while (process
->canReadLine()) {
123 QByteArray line
= process
->readLine() + '\n';
124 QString string
= QString::fromLocal8Bit(line
, line
.length() - 2);
125 emit
output(job
, string
, channel
== QProcess::StandardOutput
? IRunProvider::StandardOutput
: IRunProvider::StandardError
);
129 void ExecutePlugin::processFinished(int exitCode
, QProcess::ExitStatus exitStatus
)
131 QProcess
* process
= qobject_cast
<QProcess
*>(sender());
135 KJob
* job
= static_cast<KJob
*>(qvariant_cast
<void*>(process
->property("job")));
137 if (exitCode
== 0 && exitStatus
== QProcess::NormalExit
)
138 emit
output(job
, i18n("*** Exited normally ***"), IRunProvider::RunProvider
);
140 if (exitStatus
== QProcess::NormalExit
)
141 emit
output(job
, i18n("*** Exited with return code: %1 ***", QString::number(exitCode
)), IRunProvider::RunProvider
);
143 if (job
->error() == KJob::KilledJobError
)
144 emit
output(job
, i18n("*** Process aborted ***"), IRunProvider::RunProvider
);
146 emit
output(job
, i18n("*** Crashed with return code: %1 ***", QString::number(exitCode
)), IRunProvider::RunProvider
);
151 void ExecutePlugin::error(QProcess::ProcessError error
)
153 const QProcess
* process
= qobject_cast
<const QProcess
*>(sender());
156 if( error
== QProcess::FailedToStart
)
158 KMessageBox::information(
159 qApp
->activeWindow(),
160 i18n("<b>Could not start program.</b>"
161 "<p>Could not run '%1'. "
162 "Make sure that the path name is specified correctly.",
163 process
->property("executable").toString()),
164 i18n("Could not start program"));
167 KJob
* job
= static_cast<KJob
*>(qvariant_cast
<void*>(process
->property("job")));
173 #include "executeplugin.moc"
175 // kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on; auto-insert-doxygen on