Even though the last alpha was .91 this one is going to be 82 as I'd like to have...
[kdevelopdvcssupport.git] / plugins / execute / executeplugin.cpp
blobb8a950352ed013692ff73b225e4568d600b67de0
1 /*
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>
26 #include <klocale.h>
27 #include <kpluginfactory.h>
28 #include <kpluginloader.h>
29 #include <kdebug.h>
30 #include <kjob.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
62 return i18n("Run");
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();
87 return true;
90 void ExecutePlugin::abort(KJob* job)
92 if (m_runners.contains(job)) {
93 QProcess* process = m_runners.take(job);
94 process->close();
95 delete process;
99 void ExecutePlugin::readyReadStandardError()
101 QProcess* process = qobject_cast<QProcess*>(sender());
102 if (!process)
103 return;
105 readFrom(process, QProcess::StandardError);
108 void ExecutePlugin::readyReadStandardOutput()
110 QProcess* process = qobject_cast<QProcess*>(sender());
111 if (!process)
112 return;
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());
132 if (!process)
133 return;
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);
139 else
140 if (exitStatus == QProcess::NormalExit)
141 emit output(job, i18n("*** Exited with return code: %1 ***", QString::number(exitCode)), IRunProvider::RunProvider);
142 else
143 if (job->error() == KJob::KilledJobError)
144 emit output(job, i18n("*** Process aborted ***"), IRunProvider::RunProvider);
145 else
146 emit output(job, i18n("*** Crashed with return code: %1 ***", QString::number(exitCode)), IRunProvider::RunProvider);
148 emit finished(job);
151 void ExecutePlugin::error(QProcess::ProcessError error)
153 const QProcess* process = qobject_cast<const QProcess*>(sender());
154 Q_ASSERT(process);
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")));
168 Q_ASSERT(job);
170 emit finished(job);
173 #include "executeplugin.moc"
175 // kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on; auto-insert-doxygen on