File indexing completed on 2024-05-05 04:40:55

0001 /*
0002     SPDX-FileCopyrightText: 2018 Amish K. Naidu <amhndu@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "scratchpadjob.h"
0008 #include "scratchpad.h"
0009 
0010 #include <debug.h>
0011 
0012 #include <outputview/outputmodel.h>
0013 #include <util/processlinemaker.h>
0014 
0015 #include <KProcess>
0016 #include <KLocalizedString>
0017 
0018 #include <QMetaEnum>
0019 
0020 ScratchpadJob::ScratchpadJob(const QString& command, const QString& title, QObject* parent)
0021     : KDevelop::OutputJob(parent)
0022     , m_process(new KProcess(this))
0023     , m_lineMaker(new KDevelop::ProcessLineMaker(m_process, this))
0024 {
0025     qCDebug(PLUGIN_SCRATCHPAD) << "Creating job for" << title;
0026 
0027     setCapabilities(Killable);
0028 
0029     if (!command.isEmpty()) {
0030         m_process->setShellCommand(command);
0031 
0032         setStandardToolView(KDevelop::IOutputView::RunView);
0033         setTitle(i18nc("prefix to distinguish scratch tabs", "scratch:%1", title));
0034 
0035         auto* model = new KDevelop::OutputModel(this);
0036         setModel(model);
0037 
0038         connect(m_lineMaker, &KDevelop::ProcessLineMaker::receivedStdoutLines,
0039                 model, &KDevelop::OutputModel::appendLines);
0040         connect(m_lineMaker, &KDevelop::ProcessLineMaker::receivedStderrLines,
0041                 model, &KDevelop::OutputModel::appendLines);
0042         m_process->setOutputChannelMode(KProcess::MergedChannels);
0043         connect(m_process, QOverload<int, QProcess::ExitStatus>::of(&KProcess::finished),
0044                 this, &ScratchpadJob::processFinished);
0045         connect(m_process, &KProcess::errorOccurred, this, &ScratchpadJob::processError);
0046     } else {
0047         qCCritical(PLUGIN_SCRATCHPAD) << "Empty command in scratch job.";
0048         deleteLater();
0049     }
0050 }
0051 
0052 void ScratchpadJob::start()
0053 {
0054     const auto program = m_process->program().join(QLatin1Char(' '));
0055     if (!program.trimmed().isEmpty()) {
0056         startOutput();
0057         outputModel()->appendLine(i18n("Running %1...", program));
0058         m_process->start();
0059     }
0060 }
0061 
0062 bool ScratchpadJob::doKill()
0063 {
0064     qCDebug(PLUGIN_SCRATCHPAD) << "killing process";
0065     m_process->kill();
0066     return true;
0067 }
0068 
0069 void ScratchpadJob::processFinished(int exitCode, QProcess::ExitStatus)
0070 {
0071     qCDebug(PLUGIN_SCRATCHPAD) << "finished process";
0072     m_lineMaker->flushBuffers();
0073     outputModel()->appendLine(i18n("Process finished with exit code %1.", exitCode));
0074     emitResult();
0075 }
0076 
0077 void ScratchpadJob::processError(QProcess::ProcessError error)
0078 {
0079     qCDebug(PLUGIN_SCRATCHPAD) << "process encountered error" << error;
0080     outputModel()->appendLine(i18n("Failed to run scratch: %1",
0081                                    QLatin1String(QMetaEnum::fromType<QProcess::ProcessError>().valueToKey(error))));
0082     emitResult();
0083 }
0084 
0085 KDevelop::OutputModel* ScratchpadJob::outputModel() const
0086 {
0087     return static_cast<KDevelop::OutputModel*>(model());
0088 }
0089 
0090 #include "moc_scratchpadjob.cpp"