File indexing completed on 2024-04-28 05:48:38

0001 #pragma once
0002 /* plugin_katebuild.h                    Kate Plugin
0003 **
0004 ** SPDX-FileCopyrightText: 2008-2015 Kåre Särs <kare.sars@iki.fi>
0005 **
0006 ** This code is almost a total rewrite of the GPL'ed Make plugin
0007 ** by Adriaan de Groot.
0008 */
0009 
0010 /*
0011 ** SPDX-License-Identifier: GPL-2.0-or-later
0012 **
0013 ** This program is distributed in the hope that it will be useful,
0014 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
0015 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0016 ** GNU General Public License for more details.
0017 **
0018 ** You should have received a copy of the GNU General Public License
0019 ** along with this program in a file called COPYING; if not, write to
0020 ** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
0021 ** MA 02110-1301, USA.
0022 */
0023 
0024 #include <KProcess>
0025 #include <QHash>
0026 #include <QPointer>
0027 #include <QRegularExpression>
0028 #include <QStack>
0029 #include <QString>
0030 #include <QTimer>
0031 
0032 #include <KTextEditor/ConfigPage>
0033 #include <KTextEditor/Document>
0034 #include <KTextEditor/MainWindow>
0035 #include <KTextEditor/Message>
0036 #include <KTextEditor/Plugin>
0037 #include <KTextEditor/SessionConfigInterface>
0038 #include <KTextEditor/View>
0039 
0040 #include <KConfigGroup>
0041 #include <KXMLGUIClient>
0042 
0043 #include "diagnostics/diagnosticview.h"
0044 #include "targets.h"
0045 #include "ui_build.h"
0046 
0047 /******************************************************************/
0048 class KateBuildView : public QObject, public KXMLGUIClient, public KTextEditor::SessionConfigInterface
0049 {
0050     Q_OBJECT
0051     Q_INTERFACES(KTextEditor::SessionConfigInterface)
0052     Q_PROPERTY(QUrl docUrl READ docUrl)
0053 
0054 public:
0055     enum ResultDetails { FullOutput, ParsedOutput, ErrorsAndWarnings, OnlyErrors };
0056 
0057     enum TreeWidgetRoles { ErrorRole = Qt::UserRole + 1, DataRole };
0058 
0059     enum class Category { Normal, Info, Warning, Error };
0060 
0061     KateBuildView(KTextEditor::Plugin *plugin, KTextEditor::MainWindow *mw);
0062     ~KateBuildView() override;
0063 
0064     void readSessionConfig(const KConfigGroup &config) override;
0065     void writeSessionConfig(KConfigGroup &config) override;
0066 
0067     bool buildCurrentTarget();
0068 
0069     QUrl docUrl();
0070 
0071 private Q_SLOTS:
0072 
0073     // Building
0074     void slotSelectTarget();
0075     void slotBuildSelectedTarget();
0076     void slotBuildAndRunSelectedTarget();
0077     void slotBuildPreviousTarget();
0078     bool slotStop();
0079 
0080     // Parse output
0081     void slotProcExited(int exitCode, QProcess::ExitStatus exitStatus);
0082     void slotReadReadyStdErr();
0083     void slotReadReadyStdOut();
0084     void slotRunAfterBuild();
0085     void updateTextBrowser();
0086 
0087     // Settings
0088     void targetSetNew();
0089     void targetOrSetCopy();
0090     void targetDelete();
0091 
0092     void slotAddTargetClicked();
0093 
0094     void handleEsc(QEvent *e);
0095 
0096     /**
0097      * keep track if the project plugin is alive and if the project map did change
0098      */
0099     void slotPluginViewCreated(const QString &name, QObject *pluginView);
0100     void slotPluginViewDeleted(const QString &name, QObject *pluginView);
0101     void slotProjectMapChanged();
0102 
0103     /**
0104      * Read the non-session configurations
0105      */
0106     void readConfig();
0107 
0108     /**
0109      * Save the project build target updates
0110      */
0111     void saveProjectTargets();
0112 
0113 protected:
0114     bool eventFilter(QObject *obj, QEvent *ev) override;
0115 
0116 private:
0117     struct OutputLine {
0118         Category category = Category::Normal;
0119         QString lineStr;
0120         QString message;
0121         QString file;
0122         int lineNr;
0123         int column;
0124     };
0125 
0126     OutputLine processOutputLine(QString line);
0127     QString toOutputHtml(const KateBuildView::OutputLine &out);
0128     void addError(const OutputLine &err);
0129     void updateDiagnostics(Diagnostic diagnostic, const QUrl uri);
0130     void clearDiagnostics();
0131     bool startProcess(const QString &dir, const QString &command);
0132     bool checkLocal(const QUrl &dir);
0133     void clearBuildResults();
0134 
0135     void displayBuildResult(const QString &message, KTextEditor::Message::MessageType level);
0136     void displayMessage(const QString &message, KTextEditor::Message::MessageType level);
0137 
0138     void addProjectTarget();
0139 
0140     KTextEditor::MainWindow *m_win;
0141     QWidget *m_toolView;
0142     Ui::build m_buildUi{};
0143     QWidget *m_buildWidget;
0144     TargetsUi *m_targetsUi;
0145     KProcess m_proc;
0146     QString m_stdOut;
0147     QString m_stdErr;
0148     QString m_htmlOutput;
0149     int m_scrollStopPos = -1;
0150     int m_numOutputLines = 0;
0151     QTimer m_outputTimer;
0152     QString m_currentlyBuildingTarget;
0153     bool m_buildCancelled;
0154     bool m_runAfterBuild = false;
0155     QString m_makeDir;
0156     QStack<QString> m_makeDirStack;
0157     QStringList m_searchPaths;
0158     QRegularExpression m_filenameDetector;
0159     QRegularExpression m_newDirDetector;
0160     unsigned int m_numErrors = 0;
0161     unsigned int m_numWarnings = 0;
0162     unsigned int m_numNotes = 0;
0163     QPersistentModelIndex m_previousIndex;
0164     QPointer<KTextEditor::Message> m_infoMessage;
0165     int m_projectTargetsetRow = 0;
0166     bool m_firstBuild = true;
0167     DiagnosticsProvider m_diagnosticsProvider;
0168     bool m_addDiagnostics = true;
0169     bool m_autoSwitchToOutput = true;
0170 
0171     /**
0172      * current project plugin view, if any
0173      */
0174     QObject *m_projectPluginView = nullptr;
0175 };
0176 
0177 typedef QVariantList VariantList;
0178 
0179 /******************************************************************/
0180 class KateBuildPlugin : public KTextEditor::Plugin
0181 {
0182     Q_OBJECT
0183 
0184 public:
0185     explicit KateBuildPlugin(QObject *parent = nullptr, const VariantList & = VariantList());
0186     ~KateBuildPlugin() override
0187     {
0188     }
0189 
0190     QObject *createView(KTextEditor::MainWindow *mainWindow) override;
0191     int configPages() const override;
0192     KTextEditor::ConfigPage *configPage(int number = 0, QWidget *parent = nullptr) override;
0193 
0194 Q_SIGNALS:
0195     void configChanged();
0196 };