CompilerExplorer: Move to new editor factory setup scheme

Also clean up #includes a bit.

Change-Id: Ia8793e1eb549209df31cdfbd6d9290f5d42360d3
Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
This commit is contained in:
hjk
2024-07-18 13:17:33 +02:00
parent 1f75b35bb2
commit 42e327f960
3 changed files with 286 additions and 304 deletions

View File

@@ -2,6 +2,8 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "compilerexplorereditor.h"
#include "api/compile.h"
#include "compilerexplorerconstants.h"
#include "compilerexploreroptions.h"
#include "compilerexplorersettings.h"
@@ -14,6 +16,11 @@
#include <coreplugin/icontext.h>
#include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
#include <coreplugin/terminal/searchableterminal.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <solutions/spinner/spinner.h>
#include <texteditor/fontsettings.h>
#include <texteditor/textdocument.h>
@@ -21,9 +28,8 @@
#include <texteditor/texteditorsettings.h>
#include <texteditor/textmark.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <utils/algorithm.h>
#include <utils/fancymainwindow.h>
#include <utils/hostosinfo.h>
#include <utils/layoutbuilder.h>
#include <utils/mimetypes2/mimetype.h>
@@ -32,21 +38,16 @@
#include <utils/styledbar.h>
#include <utils/utilsicons.h>
#include <QCompleter>
#include <QDesktopServices>
#include <QDockWidget>
#include <QFutureWatcher>
#include <QPushButton>
#include <QSplitter>
#include <QStackedLayout>
#include <QStandardItemModel>
#include <QTemporaryFile>
#include <QTimer>
#include <QToolBar>
#include <QToolButton>
#include <QUndoStack>
#include <chrono>
#include <iostream>
#include <memory>
using namespace std::chrono_literals;
using namespace Aggregation;
@@ -63,6 +64,258 @@ enum {
constexpr char AsmEditorLinks[] = "AsmEditor.Links";
constexpr char SourceEditorHoverLine[] = "SourceEditor.HoveredLine";
class CodeEditorWidget : public TextEditor::TextEditorWidget
{
Q_OBJECT
public:
CodeEditorWidget(const std::shared_ptr<SourceSettings> &settings, QUndoStack *undoStack);
void updateHighlighter();
void undo() override { m_undoStack->undo(); }
void redo() override { m_undoStack->redo(); }
bool isUndoAvailable() const override { return m_undoStack->canUndo(); }
bool isRedoAvailable() const override { return m_undoStack->canRedo(); }
void focusInEvent(QFocusEvent *event) override
{
TextEditorWidget::focusInEvent(event);
emit gotFocus();
}
signals:
void gotFocus();
private:
std::shared_ptr<SourceSettings> m_settings;
QUndoStack *m_undoStack;
};
class AsmDocument : public TextEditor::TextDocument
{
public:
using TextEditor::TextDocument::TextDocument;
QList<QTextEdit::ExtraSelection> setCompileResult(const Api::CompileResult &compileResult);
QList<Api::CompileResult::AssemblyLine> &asmLines() { return m_assemblyLines; }
private:
QList<Api::CompileResult::AssemblyLine> m_assemblyLines;
QList<TextEditor::TextMark *> m_marks;
};
class AsmEditorWidget : public TextEditor::TextEditorWidget
{
Q_OBJECT
public:
AsmEditorWidget(QUndoStack *undoStack);
void focusInEvent(QFocusEvent *event) override
{
TextEditorWidget::focusInEvent(event);
emit gotFocus();
updateUndoRedoActions();
}
void findLinkAt(const QTextCursor &,
const Utils::LinkHandler &processLinkCallback,
bool resolveTarget = true,
bool inNextSplit = false) override;
void undo() override { m_undoStack->undo(); }
void redo() override { m_undoStack->redo(); }
bool isUndoAvailable() const override { return m_undoStack->canUndo(); }
bool isRedoAvailable() const override { return m_undoStack->canRedo(); }
protected:
void mouseMoveEvent(QMouseEvent *event) override;
void leaveEvent(QEvent *event) override;
signals:
void gotFocus();
void hoveredLineChanged(const std::optional<Api::CompileResult::AssemblyLine> &assemblyLine);
private:
QUndoStack *m_undoStack;
std::optional<Api::CompileResult::AssemblyLine> m_currentlyHoveredLine;
};
class JsonSettingsDocument : public Core::IDocument
{
Q_OBJECT
public:
JsonSettingsDocument(QUndoStack *undoStack);
OpenResult open(QString *errorString,
const Utils::FilePath &filePath,
const Utils::FilePath &realFilePath) override;
bool saveImpl(QString *errorString,
const Utils::FilePath &filePath = Utils::FilePath(),
bool autoSave = false) override;
bool setContents(const QByteArray &contents) override;
QString fallbackSaveAsFileName() const override;
bool shouldAutoSave() const override { return !filePath().isEmpty(); }
bool isModified() const override;
bool isSaveAsAllowed() const override { return true; }
CompilerExplorerSettings *settings() { return &m_ceSettings; }
void setWindowStateCallback(std::function<Utils::Store()> callback)
{
m_windowStateCallback = callback;
}
signals:
void settingsChanged();
private:
mutable CompilerExplorerSettings m_ceSettings;
std::function<Utils::Store()> m_windowStateCallback;
QUndoStack *m_undoStack;
};
class SourceEditorWidget : public QWidget
{
Q_OBJECT
public:
SourceEditorWidget(const std::shared_ptr<SourceSettings> &settings, QUndoStack *undoStack);
QString sourceCode();
SourceSettings *sourceSettings() { return m_sourceSettings.get(); }
void focusInEvent(QFocusEvent *) override { emit gotFocus(); }
TextEditor::TextEditorWidget *textEditor() { return m_codeEditor; }
public slots:
void markSourceLocation(const std::optional<Api::CompileResult::AssemblyLine> &assemblyLine);
signals:
void sourceCodeChanged();
void remove();
void gotFocus();
private:
CodeEditorWidget *m_codeEditor{nullptr};
std::shared_ptr<SourceSettings> m_sourceSettings;
};
class CompilerWidget : public QWidget
{
Q_OBJECT
public:
CompilerWidget(const std::shared_ptr<SourceSettings> &sourceSettings,
const std::shared_ptr<CompilerSettings> &compilerSettings,
QUndoStack *undoStack);
Core::SearchableTerminal *createTerminal();
void compile(const QString &source);
std::shared_ptr<SourceSettings> m_sourceSettings;
std::shared_ptr<CompilerSettings> m_compilerSettings;
void focusInEvent(QFocusEvent *) override { emit gotFocus(); }
TextEditor::TextEditorWidget *textEditor() { return m_asmEditor; }
private:
void doCompile();
signals:
void remove();
void gotFocus();
void hoveredLineChanged(const std::optional<Api::CompileResult::AssemblyLine> &assemblyLine);
private:
AsmEditorWidget *m_asmEditor{nullptr};
Core::SearchableTerminal *m_resultTerminal{nullptr};
SpinnerSolution::Spinner *m_spinner{nullptr};
QSharedPointer<AsmDocument> m_asmDocument;
std::unique_ptr<QFutureWatcher<Api::CompileResult>> m_compileWatcher;
QString m_source;
QTimer *m_delayTimer{nullptr};
};
class HelperWidget : public QWidget
{
Q_OBJECT
public:
HelperWidget();
protected:
void mousePressEvent(QMouseEvent *event) override;
signals:
void addSource();
};
class EditorWidget : public Utils::FancyMainWindow
{
Q_OBJECT
public:
EditorWidget(const std::shared_ptr<JsonSettingsDocument> &document,
QUndoStack *undoStack,
QWidget *parent = nullptr);
~EditorWidget() override;
TextEditor::TextEditorWidget *focusedEditorWidget() const;
signals:
void sourceCodeChanged();
void gotFocus();
protected:
void focusInEvent(QFocusEvent *event) override;
void setupHelpWidget();
QWidget *createHelpWidget() const;
CompilerWidget *addCompiler(const std::shared_ptr<SourceSettings> &sourceSettings,
const std::shared_ptr<CompilerSettings> &compilerSettings,
int idx);
void addSourceEditor(const std::shared_ptr<SourceSettings> &sourceSettings);
void removeSourceEditor(const std::shared_ptr<SourceSettings> &sourceSettings);
void recreateEditors();
QVariantMap windowStateCallback();
private:
std::shared_ptr<JsonSettingsDocument> m_document;
QUndoStack *m_undoStack;
QList<QDockWidget *> m_compilerWidgets;
QList<QDockWidget *> m_sourceWidgets;
};
class Editor : public Core::IEditor
{
public:
Editor();
~Editor();
Core::IDocument *document() const override { return m_document.get(); }
QWidget *toolBar() override;
std::shared_ptr<JsonSettingsDocument> m_document;
QUndoStack m_undoStack;
std::unique_ptr<QToolBar> m_toolBar;
QAction *m_undoAction = nullptr;
QAction *m_redoAction = nullptr;
};
CodeEditorWidget::CodeEditorWidget(const std::shared_ptr<SourceSettings> &settings,
QUndoStack *undoStack)
: m_settings(settings)
@@ -890,14 +1143,6 @@ QWidget *Editor::toolBar()
return m_toolBar.get();
}
EditorFactory::EditorFactory()
{
setId(Constants::CE_EDITOR_ID);
setDisplayName(Tr::tr("Compiler Explorer Editor"));
setMimeTypes({"application/compiler-explorer"});
setEditorCreator([] { return new Editor; });
}
QList<QTextEdit::ExtraSelection> AsmDocument::setCompileResult(
const Api::CompileResult &compileResult)
{
@@ -1022,4 +1267,25 @@ void AsmEditorWidget::findLinkAt(const QTextCursor &cursor,
}
}
// CompilerExplorerEditorFactory
class CompilerExplorerEditorFactory final : public IEditorFactory
{
public:
CompilerExplorerEditorFactory()
{
setId(Constants::CE_EDITOR_ID);
setDisplayName(Tr::tr("Compiler Explorer Editor"));
setMimeTypes({"application/compiler-explorer"});
setEditorCreator([] { return new Editor; });
}
};
void setupCompilerExplorerEditor()
{
static CompilerExplorerEditorFactory theCompilerExplorerEditorFactory;
}
} // namespace CompilerExplorer
#include "compilerexplorereditor.moc"

View File

@@ -3,290 +3,8 @@
#pragma once
#include "api/compile.h"
#include "compilerexplorersettings.h"
#include <coreplugin/terminal/searchableterminal.h>
#include <solutions/spinner/spinner.h>
#include <texteditor/texteditor.h>
#include <utils/fancymainwindow.h>
#include <QFutureWatcher>
#include <QMainWindow>
#include <QSplitter>
#include <QUndoStack>
#include <memory>
namespace CompilerExplorer {
class JsonSettingsDocument;
class SourceEditorWidget;
class AsmDocument;
void setupCompilerExplorerEditor();
class CodeEditorWidget : public TextEditor::TextEditorWidget
{
Q_OBJECT
public:
CodeEditorWidget(const std::shared_ptr<SourceSettings> &settings, QUndoStack *undoStack);
void updateHighlighter();
void undo() override { m_undoStack->undo(); }
void redo() override { m_undoStack->redo(); }
bool isUndoAvailable() const override { return m_undoStack->canUndo(); }
bool isRedoAvailable() const override { return m_undoStack->canRedo(); }
void focusInEvent(QFocusEvent *event) override
{
TextEditorWidget::focusInEvent(event);
emit gotFocus();
}
signals:
void gotFocus();
private:
std::shared_ptr<SourceSettings> m_settings;
QUndoStack *m_undoStack;
};
class AsmDocument : public TextEditor::TextDocument
{
public:
using TextEditor::TextDocument::TextDocument;
QList<QTextEdit::ExtraSelection> setCompileResult(const Api::CompileResult &compileResult);
QList<Api::CompileResult::AssemblyLine> &asmLines() { return m_assemblyLines; }
private:
QList<Api::CompileResult::AssemblyLine> m_assemblyLines;
QList<TextEditor::TextMark *> m_marks;
};
class AsmEditorWidget : public TextEditor::TextEditorWidget
{
Q_OBJECT
public:
AsmEditorWidget(QUndoStack *undoStack);
void focusInEvent(QFocusEvent *event) override
{
TextEditorWidget::focusInEvent(event);
emit gotFocus();
updateUndoRedoActions();
}
void findLinkAt(const QTextCursor &,
const Utils::LinkHandler &processLinkCallback,
bool resolveTarget = true,
bool inNextSplit = false) override;
void undo() override { m_undoStack->undo(); }
void redo() override { m_undoStack->redo(); }
bool isUndoAvailable() const override { return m_undoStack->canUndo(); }
bool isRedoAvailable() const override { return m_undoStack->canRedo(); }
protected:
void mouseMoveEvent(QMouseEvent *event) override;
void leaveEvent(QEvent *event) override;
signals:
void gotFocus();
void hoveredLineChanged(const std::optional<Api::CompileResult::AssemblyLine> &assemblyLine);
private:
QUndoStack *m_undoStack;
std::optional<Api::CompileResult::AssemblyLine> m_currentlyHoveredLine;
};
class JsonSettingsDocument : public Core::IDocument
{
Q_OBJECT
public:
JsonSettingsDocument(QUndoStack *undoStack);
OpenResult open(QString *errorString,
const Utils::FilePath &filePath,
const Utils::FilePath &realFilePath) override;
bool saveImpl(QString *errorString,
const Utils::FilePath &filePath = Utils::FilePath(),
bool autoSave = false) override;
bool setContents(const QByteArray &contents) override;
QString fallbackSaveAsFileName() const override;
bool shouldAutoSave() const override { return !filePath().isEmpty(); }
bool isModified() const override;
bool isSaveAsAllowed() const override { return true; }
CompilerExplorerSettings *settings() { return &m_ceSettings; }
void setWindowStateCallback(std::function<Utils::Store()> callback)
{
m_windowStateCallback = callback;
}
signals:
void settingsChanged();
private:
mutable CompilerExplorerSettings m_ceSettings;
std::function<Utils::Store()> m_windowStateCallback;
QUndoStack *m_undoStack;
};
class SourceEditorWidget : public QWidget
{
Q_OBJECT
public:
SourceEditorWidget(const std::shared_ptr<SourceSettings> &settings, QUndoStack *undoStack);
QString sourceCode();
SourceSettings *sourceSettings() { return m_sourceSettings.get(); }
void focusInEvent(QFocusEvent *) override { emit gotFocus(); }
TextEditor::TextEditorWidget *textEditor() { return m_codeEditor; }
public slots:
void markSourceLocation(const std::optional<Api::CompileResult::AssemblyLine> &assemblyLine);
signals:
void sourceCodeChanged();
void remove();
void gotFocus();
private:
CodeEditorWidget *m_codeEditor{nullptr};
std::shared_ptr<SourceSettings> m_sourceSettings;
};
class CompilerWidget : public QWidget
{
Q_OBJECT
public:
CompilerWidget(const std::shared_ptr<SourceSettings> &sourceSettings,
const std::shared_ptr<CompilerSettings> &compilerSettings,
QUndoStack *undoStack);
Core::SearchableTerminal *createTerminal();
void compile(const QString &source);
std::shared_ptr<SourceSettings> m_sourceSettings;
std::shared_ptr<CompilerSettings> m_compilerSettings;
void focusInEvent(QFocusEvent *) override { emit gotFocus(); }
TextEditor::TextEditorWidget *textEditor() { return m_asmEditor; }
private:
void doCompile();
signals:
void remove();
void gotFocus();
void hoveredLineChanged(const std::optional<Api::CompileResult::AssemblyLine> &assemblyLine);
private:
AsmEditorWidget *m_asmEditor{nullptr};
Core::SearchableTerminal *m_resultTerminal{nullptr};
SpinnerSolution::Spinner *m_spinner{nullptr};
QSharedPointer<AsmDocument> m_asmDocument;
std::unique_ptr<QFutureWatcher<Api::CompileResult>> m_compileWatcher;
QString m_source;
QTimer *m_delayTimer{nullptr};
};
class HelperWidget : public QWidget
{
Q_OBJECT
public:
HelperWidget();
protected:
void mousePressEvent(QMouseEvent *event) override;
signals:
void addSource();
};
class EditorWidget : public Utils::FancyMainWindow
{
Q_OBJECT
public:
EditorWidget(const std::shared_ptr<JsonSettingsDocument> &document,
QUndoStack *undoStack,
QWidget *parent = nullptr);
~EditorWidget() override;
TextEditor::TextEditorWidget *focusedEditorWidget() const;
signals:
void sourceCodeChanged();
void gotFocus();
protected:
void focusInEvent(QFocusEvent *event) override;
void setupHelpWidget();
QWidget *createHelpWidget() const;
CompilerWidget *addCompiler(const std::shared_ptr<SourceSettings> &sourceSettings,
const std::shared_ptr<CompilerSettings> &compilerSettings,
int idx);
void addSourceEditor(const std::shared_ptr<SourceSettings> &sourceSettings);
void removeSourceEditor(const std::shared_ptr<SourceSettings> &sourceSettings);
void recreateEditors();
QVariantMap windowStateCallback();
private:
std::shared_ptr<JsonSettingsDocument> m_document;
QUndoStack *m_undoStack;
QList<QDockWidget *> m_compilerWidgets;
QList<QDockWidget *> m_sourceWidgets;
};
class Editor : public Core::IEditor
{
public:
Editor();
~Editor();
Core::IDocument *document() const override { return m_document.get(); }
QWidget *toolBar() override;
std::shared_ptr<JsonSettingsDocument> m_document;
QUndoStack m_undoStack;
std::unique_ptr<QToolBar> m_toolBar;
QAction *m_undoAction = nullptr;
QAction *m_redoAction = nullptr;
};
class EditorFactory : public Core::IEditorFactory
{
public:
EditorFactory();
private:
QAction m_undoAction;
QAction m_redoAction;
};
} // namespace CompilerExplorer
} // CompilerExplorer

View File

@@ -15,8 +15,6 @@
#include <extensionsystem/iplugin.h>
#include <projectexplorer/jsonwizard/jsonwizardfactory.h>
#include <utils/fsengine/fileiconprovider.h>
using namespace Core;
@@ -32,7 +30,7 @@ class CompilerExplorerPlugin final : public ExtensionSystem::IPlugin
public:
void initialize() final
{
static CompilerExplorer::EditorFactory ceEditorFactory;
setupCompilerExplorerEditor();
FileIconProvider::registerIconForMimeType(QIcon(":/compilerexplorer/logos/ce.ico"),
"application/compiler-explorer");