forked from qt-creator/qt-creator
CompilerExplorer: Enable undo/redo
Change-Id: I06bba06181784de07f89f01a3bfe586513d63c66 Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "api/library.h"
|
#include "api/library.h"
|
||||||
|
|
||||||
|
#include <utils/algorithm.h>
|
||||||
#include <utils/layoutbuilder.h>
|
#include <utils/layoutbuilder.h>
|
||||||
|
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
@@ -58,6 +59,35 @@ bool LibrarySelectionAspect::guiToBuffer()
|
|||||||
return oldBuffer != m_buffer;
|
return oldBuffer != m_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariantMap toVariantMap(const QMap<QString, QString> &map)
|
||||||
|
{
|
||||||
|
QVariantMap variant;
|
||||||
|
for (const auto &key : map.keys())
|
||||||
|
variant.insert(key, map[key]);
|
||||||
|
|
||||||
|
return variant;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant LibrarySelectionAspect::variantValue() const
|
||||||
|
{
|
||||||
|
return toVariantMap(m_internal);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant LibrarySelectionAspect::volatileVariantValue() const
|
||||||
|
{
|
||||||
|
return toVariantMap(m_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LibrarySelectionAspect::setVariantValue(const QVariant &value, Announcement howToAnnounce)
|
||||||
|
{
|
||||||
|
QMap<QString, QString> map;
|
||||||
|
QVariantMap variant = value.toMap();
|
||||||
|
for (const auto &key : variant.keys())
|
||||||
|
map[key] = variant[key].toString();
|
||||||
|
|
||||||
|
setValue(map, howToAnnounce);
|
||||||
|
}
|
||||||
|
|
||||||
void LibrarySelectionAspect::addToLayout(Layouting::LayoutItem &parent)
|
void LibrarySelectionAspect::addToLayout(Layouting::LayoutItem &parent)
|
||||||
{
|
{
|
||||||
using namespace Layouting;
|
using namespace Layouting;
|
||||||
@@ -110,6 +140,18 @@ void LibrarySelectionAspect::addToLayout(Layouting::LayoutItem &parent)
|
|||||||
connect(nameCombo, &QComboBox::currentIndexChanged, this, refreshVersionCombo);
|
connect(nameCombo, &QComboBox::currentIndexChanged, this, refreshVersionCombo);
|
||||||
|
|
||||||
connect(versionCombo, &QComboBox::activated, this, [this, nameCombo, versionCombo] {
|
connect(versionCombo, &QComboBox::activated, this, [this, nameCombo, versionCombo] {
|
||||||
|
if (undoStack()) {
|
||||||
|
QVariant old = m_model->data(m_model->index(nameCombo->currentIndex(), 0),
|
||||||
|
SelectedVersion);
|
||||||
|
undoStack()->push(new SelectLibraryVersionCommand(this,
|
||||||
|
nameCombo->currentIndex(),
|
||||||
|
versionCombo->currentData(),
|
||||||
|
old));
|
||||||
|
|
||||||
|
handleGuiChanged();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_model->setData(m_model->index(nameCombo->currentIndex(), 0),
|
m_model->setData(m_model->index(nameCombo->currentIndex(), 0),
|
||||||
versionCombo->currentData(),
|
versionCombo->currentData(),
|
||||||
SelectedVersion);
|
SelectedVersion);
|
||||||
@@ -118,6 +160,23 @@ void LibrarySelectionAspect::addToLayout(Layouting::LayoutItem &parent)
|
|||||||
|
|
||||||
QPushButton *clearBtn = new QPushButton("Clear All");
|
QPushButton *clearBtn = new QPushButton("Clear All");
|
||||||
connect(clearBtn, &QPushButton::clicked, clearBtn, [this, refreshVersionCombo] {
|
connect(clearBtn, &QPushButton::clicked, clearBtn, [this, refreshVersionCombo] {
|
||||||
|
if (undoStack()) {
|
||||||
|
undoStack()->beginMacro(Tr::tr("Reset used libraries"));
|
||||||
|
for (int i = 0; i < m_model->rowCount(); i++) {
|
||||||
|
QModelIndex idx = m_model->index(i, 0);
|
||||||
|
if (idx.data(SelectedVersion).isValid())
|
||||||
|
undoStack()->push(new SelectLibraryVersionCommand(this,
|
||||||
|
i,
|
||||||
|
QVariant(),
|
||||||
|
idx.data(SelectedVersion)));
|
||||||
|
}
|
||||||
|
undoStack()->endMacro();
|
||||||
|
|
||||||
|
handleGuiChanged();
|
||||||
|
refreshVersionCombo();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < m_model->rowCount(); i++)
|
for (int i = 0; i < m_model->rowCount(); i++)
|
||||||
m_model->setData(m_model->index(i, 0), QVariant(), SelectedVersion);
|
m_model->setData(m_model->index(i, 0), QVariant(), SelectedVersion);
|
||||||
handleGuiChanged();
|
handleGuiChanged();
|
||||||
@@ -130,11 +189,12 @@ void LibrarySelectionAspect::addToLayout(Layouting::LayoutItem &parent)
|
|||||||
QStringList libs;
|
QStringList libs;
|
||||||
for (int i = 0; i < m_model->rowCount(); i++) {
|
for (int i = 0; i < m_model->rowCount(); i++) {
|
||||||
QModelIndex idx = m_model->index(i, 0);
|
QModelIndex idx = m_model->index(i, 0);
|
||||||
if (idx.data(SelectedVersion).isValid())
|
if (idx.data(SelectedVersion).isValid()) {
|
||||||
libs.append(QString("%1 %2")
|
libs.append(QString("%1 %2")
|
||||||
.arg(idx.data().toString())
|
.arg(idx.data().toString())
|
||||||
.arg(idx.data(SelectedVersion).toString()));
|
.arg(idx.data(SelectedVersion).toString()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (libs.empty())
|
if (libs.empty())
|
||||||
displayLabel->setText(Tr::tr("No libraries selected"));
|
displayLabel->setText(Tr::tr("No libraries selected"));
|
||||||
else
|
else
|
||||||
@@ -157,7 +217,10 @@ void LibrarySelectionAspect::addToLayout(Layouting::LayoutItem &parent)
|
|||||||
Row { noMargin, nameCombo, versionCombo, clearBtn }.emerge()
|
Row { noMargin, nameCombo, versionCombo, clearBtn }.emerge()
|
||||||
}.emerge();
|
}.emerge();
|
||||||
// clang-format on
|
// clang-format on
|
||||||
connect(editBtn, &QPushButton::clicked, this, [stack] { stack->setCurrentIndex(1); });
|
connect(editBtn, &QPushButton::clicked, stack, [stack] { stack->setCurrentIndex(1); });
|
||||||
|
connect(this, &LibrarySelectionAspect::returnToDisplay, stack, [stack] {
|
||||||
|
stack->setCurrentIndex(0);
|
||||||
|
});
|
||||||
|
|
||||||
addLabeledItem(parent, s);
|
addLabeledItem(parent, s);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,48 @@ public:
|
|||||||
SelectedVersion,
|
SelectedVersion,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SelectLibraryVersionCommand : public QUndoCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SelectLibraryVersionCommand(LibrarySelectionAspect *aspect,
|
||||||
|
int libraryIndex,
|
||||||
|
const QVariant &versionId,
|
||||||
|
const QVariant &oldVersionId = QVariant())
|
||||||
|
: m_aspect(aspect)
|
||||||
|
, m_libraryIndex(libraryIndex)
|
||||||
|
, m_versionId(versionId)
|
||||||
|
, m_oldVersionId(oldVersionId)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void undo() override
|
||||||
|
{
|
||||||
|
m_aspect->m_model->setData(m_aspect->m_model->index(m_libraryIndex, 0),
|
||||||
|
m_oldVersionId,
|
||||||
|
LibrarySelectionAspect::SelectedVersion);
|
||||||
|
m_aspect->handleGuiChanged();
|
||||||
|
emit m_aspect->returnToDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
void redo() override
|
||||||
|
{
|
||||||
|
m_aspect->m_model->setData(m_aspect->m_model->index(m_libraryIndex, 0),
|
||||||
|
m_versionId,
|
||||||
|
LibrarySelectionAspect::SelectedVersion);
|
||||||
|
if (!m_firstTime) {
|
||||||
|
emit m_aspect->returnToDisplay();
|
||||||
|
m_aspect->handleGuiChanged();
|
||||||
|
}
|
||||||
|
m_firstTime = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
LibrarySelectionAspect *m_aspect;
|
||||||
|
int m_libraryIndex;
|
||||||
|
QVariant m_versionId;
|
||||||
|
QVariant m_oldVersionId;
|
||||||
|
bool m_firstTime{true};
|
||||||
|
};
|
||||||
|
|
||||||
LibrarySelectionAspect(Utils::AspectContainer *container = nullptr);
|
LibrarySelectionAspect(Utils::AspectContainer *container = nullptr);
|
||||||
|
|
||||||
void addToLayout(Layouting::LayoutItem &parent) override;
|
void addToLayout(Layouting::LayoutItem &parent) override;
|
||||||
@@ -36,8 +78,14 @@ public:
|
|||||||
void bufferToGui() override;
|
void bufferToGui() override;
|
||||||
bool guiToBuffer() override;
|
bool guiToBuffer() override;
|
||||||
|
|
||||||
|
QVariant variantValue() const override;
|
||||||
|
QVariant volatileVariantValue() const override;
|
||||||
|
|
||||||
|
void setVariantValue(const QVariant &value, Announcement howToAnnounce = DoEmit) override;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void refillRequested();
|
void refillRequested();
|
||||||
|
void returnToDisplay();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FillCallback m_fillCallback;
|
FillCallback m_fillCallback;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include <aggregation/aggregate.h>
|
#include <aggregation/aggregate.h>
|
||||||
|
|
||||||
|
#include <coreplugin/actionmanager/actionmanager.h>
|
||||||
#include <coreplugin/coreconstants.h>
|
#include <coreplugin/coreconstants.h>
|
||||||
#include <coreplugin/icontext.h>
|
#include <coreplugin/icontext.h>
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
@@ -25,6 +26,7 @@
|
|||||||
#include <utils/layoutbuilder.h>
|
#include <utils/layoutbuilder.h>
|
||||||
#include <utils/mimetypes2/mimetype.h>
|
#include <utils/mimetypes2/mimetype.h>
|
||||||
#include <utils/mimeutils.h>
|
#include <utils/mimeutils.h>
|
||||||
|
#include <utils/store.h>
|
||||||
#include <utils/utilsicons.h>
|
#include <utils/utilsicons.h>
|
||||||
|
|
||||||
#include <QCompleter>
|
#include <QCompleter>
|
||||||
@@ -37,6 +39,7 @@
|
|||||||
#include <QTemporaryFile>
|
#include <QTemporaryFile>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QToolButton>
|
#include <QToolButton>
|
||||||
|
#include <QUndoStack>
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -48,30 +51,36 @@ using namespace Utils;
|
|||||||
|
|
||||||
namespace CompilerExplorer {
|
namespace CompilerExplorer {
|
||||||
|
|
||||||
class CodeEditorWidget : public TextEditorWidget
|
CodeEditorWidget::CodeEditorWidget(const std::shared_ptr<SourceSettings> &settings,
|
||||||
{
|
QUndoStack *undoStack)
|
||||||
public:
|
|
||||||
CodeEditorWidget(const std::shared_ptr<SourceSettings> &settings)
|
|
||||||
: m_settings(settings)
|
: m_settings(settings)
|
||||||
{}
|
, m_undoStack(undoStack){};
|
||||||
|
|
||||||
void updateHighlighter()
|
void CodeEditorWidget::updateHighlighter()
|
||||||
{
|
{
|
||||||
const QString ext = m_settings->languageExtension();
|
const QString ext = m_settings->languageExtension();
|
||||||
if (ext.isEmpty())
|
if (ext.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Utils::MimeType mimeType = Utils::mimeTypeForFile("foo" + ext);
|
Utils::MimeType mimeType = Utils::mimeTypeForFile("foo" + ext);
|
||||||
configureGenericHighlighter(mimeType);
|
configureGenericHighlighter(mimeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<SourceSettings> m_settings;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SourceTextDocument : public TextDocument
|
class SourceTextDocument : public TextDocument
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SourceTextDocument(const std::shared_ptr<SourceSettings> &settings)
|
class OpaqueUndoCommand : public QUndoCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OpaqueUndoCommand(SourceTextDocument *doc)
|
||||||
|
: m_doc(doc)
|
||||||
|
{}
|
||||||
|
void undo() override { m_doc->undo(); }
|
||||||
|
void redo() override { m_doc->redo(); }
|
||||||
|
SourceTextDocument *m_doc;
|
||||||
|
};
|
||||||
|
|
||||||
|
SourceTextDocument(const std::shared_ptr<SourceSettings> &settings, QUndoStack *undoStack)
|
||||||
{
|
{
|
||||||
setPlainText(settings->source());
|
setPlainText(settings->source());
|
||||||
|
|
||||||
@@ -83,18 +92,26 @@ public:
|
|||||||
if (settings->source.volatileValue() != plainText())
|
if (settings->source.volatileValue() != plainText())
|
||||||
setPlainText(settings->source.volatileValue());
|
setPlainText(settings->source.volatileValue());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
connect(this->document(), &QTextDocument::undoCommandAdded, this, [this, undoStack] {
|
||||||
|
undoStack->push(new OpaqueUndoCommand(this));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void undo() { document()->undo(); }
|
||||||
|
void redo() { document()->redo(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
JsonSettingsDocument::JsonSettingsDocument()
|
JsonSettingsDocument::JsonSettingsDocument(QUndoStack *undoStack)
|
||||||
|
: m_undoStack(undoStack)
|
||||||
{
|
{
|
||||||
setId(Constants::CE_EDITOR_ID);
|
setId(Constants::CE_EDITOR_ID);
|
||||||
setMimeType("application/compiler-explorer");
|
setMimeType("application/compiler-explorer");
|
||||||
connect(&m_ceSettings, &CompilerExplorerSettings::changed, this, [this] { emit changed(); });
|
connect(&m_ceSettings, &CompilerExplorerSettings::changed, this, [this] { emit changed(); });
|
||||||
|
m_ceSettings.setAutoApply(true);
|
||||||
|
m_ceSettings.setUndoStack(undoStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonSettingsDocument::~JsonSettingsDocument() {}
|
|
||||||
|
|
||||||
Core::IDocument::OpenResult JsonSettingsDocument::open(QString *errorString,
|
Core::IDocument::OpenResult JsonSettingsDocument::open(QString *errorString,
|
||||||
const FilePath &filePath,
|
const FilePath &filePath,
|
||||||
const FilePath &realFilePath)
|
const FilePath &realFilePath)
|
||||||
@@ -121,23 +138,21 @@ Core::IDocument::OpenResult JsonSettingsDocument::open(QString *errorString,
|
|||||||
return OpenResult::Success;
|
return OpenResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JsonSettingsDocument::saveImpl(QString *errorString,
|
bool JsonSettingsDocument::saveImpl(QString *errorString, const FilePath &newFilePath, bool autoSave)
|
||||||
const FilePath &newFilePath,
|
|
||||||
bool autoSave)
|
|
||||||
{
|
{
|
||||||
Store map;
|
Store store;
|
||||||
|
|
||||||
if (autoSave) {
|
if (autoSave) {
|
||||||
if (m_windowStateCallback)
|
if (m_windowStateCallback)
|
||||||
m_ceSettings.windowState.setVolatileValue(m_windowStateCallback());
|
m_ceSettings.windowState.setVolatileValue(m_windowStateCallback());
|
||||||
|
|
||||||
m_ceSettings.volatileToMap(map);
|
m_ceSettings.volatileToMap(store);
|
||||||
} else {
|
} else {
|
||||||
if (m_windowStateCallback)
|
if (m_windowStateCallback)
|
||||||
m_ceSettings.windowState.setValue(m_windowStateCallback());
|
m_ceSettings.windowState.setValue(m_windowStateCallback());
|
||||||
|
|
||||||
m_ceSettings.apply();
|
m_ceSettings.apply();
|
||||||
m_ceSettings.toMap(map);
|
m_ceSettings.toMap(store);
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::FilePath path = newFilePath.isEmpty() ? filePath() : newFilePath;
|
Utils::FilePath path = newFilePath.isEmpty() ? filePath() : newFilePath;
|
||||||
@@ -145,7 +160,7 @@ bool JsonSettingsDocument::saveImpl(QString *errorString,
|
|||||||
if (!newFilePath.isEmpty() && !autoSave)
|
if (!newFilePath.isEmpty() && !autoSave)
|
||||||
setFilePath(newFilePath);
|
setFilePath(newFilePath);
|
||||||
|
|
||||||
auto result = path.writeFileContents(jsonFromStore(map));
|
auto result = path.writeFileContents(jsonFromStore(store));
|
||||||
if (!result && errorString) {
|
if (!result && errorString) {
|
||||||
*errorString = result.error();
|
*errorString = result.error();
|
||||||
return false;
|
return false;
|
||||||
@@ -170,12 +185,15 @@ bool JsonSettingsDocument::setContents(const QByteArray &contents)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SourceEditorWidget::SourceEditorWidget(const std::shared_ptr<SourceSettings> &settings)
|
SourceEditorWidget::SourceEditorWidget(const std::shared_ptr<SourceSettings> &settings,
|
||||||
|
QUndoStack *undoStack)
|
||||||
: m_sourceSettings(settings)
|
: m_sourceSettings(settings)
|
||||||
{
|
{
|
||||||
m_codeEditor = new CodeEditorWidget(m_sourceSettings);
|
m_codeEditor = new CodeEditorWidget(m_sourceSettings, undoStack);
|
||||||
|
|
||||||
TextDocumentPtr document = TextDocumentPtr(new SourceTextDocument(m_sourceSettings));
|
connect(m_codeEditor, &CodeEditorWidget::gotFocus, this, &SourceEditorWidget::gotFocus);
|
||||||
|
|
||||||
|
TextDocumentPtr document = TextDocumentPtr(new SourceTextDocument(m_sourceSettings, undoStack));
|
||||||
|
|
||||||
connect(document.get(),
|
connect(document.get(),
|
||||||
&SourceTextDocument::changed,
|
&SourceTextDocument::changed,
|
||||||
@@ -187,11 +205,12 @@ SourceEditorWidget::SourceEditorWidget(const std::shared_ptr<SourceSettings> &se
|
|||||||
|
|
||||||
auto addCompilerButton = new QPushButton;
|
auto addCompilerButton = new QPushButton;
|
||||||
addCompilerButton->setText(Tr::tr("Add compiler"));
|
addCompilerButton->setText(Tr::tr("Add compiler"));
|
||||||
connect(addCompilerButton, &QPushButton::clicked, this, [this] {
|
connect(addCompilerButton, &QPushButton::clicked, this, &SourceEditorWidget::addCompiler);
|
||||||
auto newCompiler = std::make_shared<CompilerSettings>(m_sourceSettings->apiConfigFunction());
|
|
||||||
newCompiler->setLanguageId(m_sourceSettings->languageId());
|
auto removeSourceButton = new QPushButton;
|
||||||
m_sourceSettings->compilers.addItem(newCompiler);
|
removeSourceButton->setIcon(Utils::Icons::EDIT_CLEAR.icon());
|
||||||
});
|
removeSourceButton->setToolTip(Tr::tr("Remove source"));
|
||||||
|
connect(removeSourceButton, &QPushButton::clicked, this, &SourceEditorWidget::remove);
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
using namespace Layouting;
|
using namespace Layouting;
|
||||||
@@ -200,6 +219,7 @@ SourceEditorWidget::SourceEditorWidget(const std::shared_ptr<SourceSettings> &se
|
|||||||
Row {
|
Row {
|
||||||
settings->languageId,
|
settings->languageId,
|
||||||
addCompilerButton,
|
addCompilerButton,
|
||||||
|
removeSourceButton,
|
||||||
},
|
},
|
||||||
m_codeEditor,
|
m_codeEditor,
|
||||||
}.attachTo(this);
|
}.attachTo(this);
|
||||||
@@ -208,13 +228,6 @@ SourceEditorWidget::SourceEditorWidget(const std::shared_ptr<SourceSettings> &se
|
|||||||
setWindowTitle("Source code");
|
setWindowTitle("Source code");
|
||||||
setObjectName("source_code");
|
setObjectName("source_code");
|
||||||
|
|
||||||
Aggregate *agg = Aggregate::parentAggregate(m_codeEditor);
|
|
||||||
if (!agg) {
|
|
||||||
agg = new Aggregate;
|
|
||||||
agg->add(m_codeEditor);
|
|
||||||
}
|
|
||||||
agg->add(this);
|
|
||||||
|
|
||||||
setFocusProxy(m_codeEditor);
|
setFocusProxy(m_codeEditor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,11 +256,14 @@ CompilerWidget::CompilerWidget(const std::shared_ptr<SourceSettings> &sourceSett
|
|||||||
m_delayTimer,
|
m_delayTimer,
|
||||||
qOverload<>(&QTimer::start));
|
qOverload<>(&QTimer::start));
|
||||||
|
|
||||||
m_asmEditor = new TextEditorWidget;
|
m_asmEditor = new AsmEditorWidget;
|
||||||
m_asmDocument = QSharedPointer<TextDocument>(new TextDocument);
|
m_asmDocument = QSharedPointer<TextDocument>(new TextDocument);
|
||||||
m_asmDocument->setFilePath("asm.asm");
|
m_asmDocument->setFilePath("asm.asm");
|
||||||
m_asmEditor->setTextDocument(m_asmDocument);
|
m_asmEditor->setTextDocument(m_asmDocument);
|
||||||
m_asmEditor->configureGenericHighlighter(Utils::mimeTypeForName("text/x-asm"));
|
m_asmEditor->configureGenericHighlighter(Utils::mimeTypeForName("text/x-asm"));
|
||||||
|
m_asmEditor->setReadOnly(true);
|
||||||
|
|
||||||
|
connect(m_asmEditor, &AsmEditorWidget::gotFocus, this, &CompilerWidget::gotFocus);
|
||||||
|
|
||||||
auto advButton = new QPushButton;
|
auto advButton = new QPushButton;
|
||||||
QSplitter *splitter{nullptr};
|
QSplitter *splitter{nullptr};
|
||||||
@@ -268,6 +284,11 @@ CompilerWidget::CompilerWidget(const std::shared_ptr<SourceSettings> &sourceSett
|
|||||||
connect(advButton, &QPushButton::clicked, advDlg, &QAction::trigger);
|
connect(advButton, &QPushButton::clicked, advDlg, &QAction::trigger);
|
||||||
advButton->setIcon(advDlg->icon());
|
advButton->setIcon(advDlg->icon());
|
||||||
|
|
||||||
|
auto removeCompilerBtn = new QPushButton;
|
||||||
|
removeCompilerBtn->setIcon(Utils::Icons::EDIT_CLEAR.icon());
|
||||||
|
removeCompilerBtn->setToolTip(Tr::tr("Remove compiler"));
|
||||||
|
connect(removeCompilerBtn, &QPushButton::clicked, this, &CompilerWidget::remove);
|
||||||
|
|
||||||
compile(m_sourceSettings->source());
|
compile(m_sourceSettings->source());
|
||||||
|
|
||||||
connect(&m_sourceSettings->source, &Utils::StringAspect::volatileValueChanged, this, [this] {
|
connect(&m_sourceSettings->source, &Utils::StringAspect::volatileValueChanged, this, [this] {
|
||||||
@@ -279,6 +300,7 @@ CompilerWidget::CompilerWidget(const std::shared_ptr<SourceSettings> &sourceSett
|
|||||||
Row {
|
Row {
|
||||||
m_compilerSettings->compiler,
|
m_compilerSettings->compiler,
|
||||||
advButton,
|
advButton,
|
||||||
|
removeCompilerBtn,
|
||||||
},
|
},
|
||||||
Splitter {
|
Splitter {
|
||||||
bindTo(&splitter),
|
bindTo(&splitter),
|
||||||
@@ -368,8 +390,7 @@ void CompilerWidget::doCompile()
|
|||||||
|
|
||||||
m_compileWatcher.reset(new QFutureWatcher<CompileResult>);
|
m_compileWatcher.reset(new QFutureWatcher<CompileResult>);
|
||||||
|
|
||||||
connect(
|
connect(m_compileWatcher.get(), &QFutureWatcher<CompileResult>::finished, this, [this] {
|
||||||
m_compileWatcher.get(), &QFutureWatcher<CompileResult>::finished, this, [this] {
|
|
||||||
m_spinner->setVisible(false);
|
m_spinner->setVisible(false);
|
||||||
m_asmEditor->setEnabled(true);
|
m_asmEditor->setEnabled(true);
|
||||||
|
|
||||||
@@ -385,8 +406,7 @@ void CompilerWidget::doCompile()
|
|||||||
m_resultTerminal->writeToTerminal((out.text + "\r\n").toUtf8(), false);
|
m_resultTerminal->writeToTerminal((out.text + "\r\n").toUtf8(), false);
|
||||||
|
|
||||||
m_resultTerminal->writeToTerminal(
|
m_resultTerminal->writeToTerminal(
|
||||||
QString("ASM generation compiler returned: %1\r\n\r\n").arg(r.code).toUtf8(),
|
QString("ASM generation compiler returned: %1\r\n\r\n").arg(r.code).toUtf8(), true);
|
||||||
true);
|
|
||||||
|
|
||||||
if (r.execResult) {
|
if (r.execResult) {
|
||||||
for (const auto &err : r.execResult->buildResult.stdErr)
|
for (const auto &err : r.execResult->buildResult.stdErr)
|
||||||
@@ -408,15 +428,13 @@ void CompilerWidget::doCompile()
|
|||||||
|
|
||||||
for (const auto &err : r.execResult->stdErrLines)
|
for (const auto &err : r.execResult->stdErrLines)
|
||||||
m_resultTerminal
|
m_resultTerminal
|
||||||
->writeToTerminal((" \033[0;31m" + err + "\033[0m\r\n").toUtf8(),
|
->writeToTerminal((" \033[0;31m" + err + "\033[0m\r\n\r\n").toUtf8(),
|
||||||
false);
|
false);
|
||||||
for (const auto &out : r.execResult->stdOutLines)
|
for (const auto &out : r.execResult->stdOutLines)
|
||||||
m_resultTerminal->writeToTerminal((" " + out + "\r\n").toUtf8(), false);
|
m_resultTerminal->writeToTerminal((out + "\r\n").toUtf8(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto mark : m_marks) {
|
qDeleteAll(m_marks);
|
||||||
delete mark;
|
|
||||||
}
|
|
||||||
m_marks.clear();
|
m_marks.clear();
|
||||||
|
|
||||||
QString asmText;
|
QString asmText;
|
||||||
@@ -431,9 +449,7 @@ void CompilerWidget::doCompile()
|
|||||||
if (l.opcodes.empty())
|
if (l.opcodes.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto mark = new TextMark(m_asmDocument.get(),
|
auto mark = new TextMark(m_asmDocument.get(), i, TextMarkCategory{"Bytes", "Bytes"});
|
||||||
i,
|
|
||||||
TextMarkCategory{"Bytes", "Bytes"});
|
|
||||||
mark->setLineAnnotation(l.opcodes.join(' '));
|
mark->setLineAnnotation(l.opcodes.join(' '));
|
||||||
m_marks.append(mark);
|
m_marks.append(mark);
|
||||||
}
|
}
|
||||||
@@ -445,7 +461,10 @@ void CompilerWidget::doCompile()
|
|||||||
m_compileWatcher->setFuture(f);
|
m_compileWatcher->setFuture(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
EditorWidget::EditorWidget(const QSharedPointer<JsonSettingsDocument> &document, QWidget *parent)
|
EditorWidget::EditorWidget(const QSharedPointer<JsonSettingsDocument> &document,
|
||||||
|
QUndoStack *undoStack,
|
||||||
|
TextEditorActionHandler &actionHandler,
|
||||||
|
QWidget *parent)
|
||||||
: Utils::FancyMainWindow(parent)
|
: Utils::FancyMainWindow(parent)
|
||||||
, m_document(document)
|
, m_document(document)
|
||||||
{
|
{
|
||||||
@@ -473,7 +492,8 @@ EditorWidget::EditorWidget(const QSharedPointer<JsonSettingsDocument> &document,
|
|||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
|
|
||||||
auto addCompiler = [this](const std::shared_ptr<SourceSettings> &sourceSettings,
|
auto addCompiler = [this,
|
||||||
|
&actionHandler](const std::shared_ptr<SourceSettings> &sourceSettings,
|
||||||
const std::shared_ptr<CompilerSettings> &compilerSettings,
|
const std::shared_ptr<CompilerSettings> &compilerSettings,
|
||||||
int idx) {
|
int idx) {
|
||||||
auto compiler = new CompilerWidget(sourceSettings, compilerSettings);
|
auto compiler = new CompilerWidget(sourceSettings, compilerSettings);
|
||||||
@@ -482,23 +502,43 @@ EditorWidget::EditorWidget(const QSharedPointer<JsonSettingsDocument> &document,
|
|||||||
QDockWidget *dockWidget = addDockForWidget(compiler);
|
QDockWidget *dockWidget = addDockForWidget(compiler);
|
||||||
addDockWidget(Qt::RightDockWidgetArea, dockWidget);
|
addDockWidget(Qt::RightDockWidgetArea, dockWidget);
|
||||||
m_compilerWidgets.append(dockWidget);
|
m_compilerWidgets.append(dockWidget);
|
||||||
|
|
||||||
|
connect(compiler,
|
||||||
|
&CompilerWidget::remove,
|
||||||
|
this,
|
||||||
|
[sourceSettings = sourceSettings.get(), compilerSettings = compilerSettings.get()] {
|
||||||
|
sourceSettings->compilers.removeItem(compilerSettings->shared_from_this());
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(compiler, &CompilerWidget::gotFocus, this, [&actionHandler] {
|
||||||
|
actionHandler.updateCurrentEditor();
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
auto addSourceEditor = [this, document = document.get(), addCompiler](
|
auto addSourceEditor = [this, &actionHandler, document = document.get(), addCompiler, undoStack](
|
||||||
const std::shared_ptr<SourceSettings> &sourceSettings) {
|
const std::shared_ptr<SourceSettings> &sourceSettings) {
|
||||||
auto sourceEditor = new SourceEditorWidget(sourceSettings);
|
auto sourceEditor = new SourceEditorWidget(sourceSettings, undoStack);
|
||||||
sourceEditor->setWindowTitle("Source Code #" + QString::number(m_sourceWidgets.size() + 1));
|
sourceEditor->setWindowTitle("Source Code #" + QString::number(m_sourceWidgets.size() + 1));
|
||||||
sourceEditor->setObjectName("source_code_editor_"
|
sourceEditor->setObjectName("source_code_editor_"
|
||||||
+ QString::number(m_sourceWidgets.size() + 1));
|
+ QString::number(m_sourceWidgets.size() + 1));
|
||||||
|
|
||||||
QDockWidget *dockWidget = addDockForWidget(sourceEditor);
|
QDockWidget *dockWidget = addDockForWidget(sourceEditor);
|
||||||
connect(dockWidget,
|
connect(sourceEditor,
|
||||||
&QDockWidget::visibilityChanged,
|
&SourceEditorWidget::remove,
|
||||||
this,
|
this,
|
||||||
[document, sourceSettings = sourceSettings.get(), dockWidget] {
|
[document, sourceSettings = sourceSettings.get()] {
|
||||||
if (!dockWidget->isVisible())
|
document->settings()->m_sources.removeItem(sourceSettings->shared_from_this());
|
||||||
document->settings()->m_sources.removeItem(
|
});
|
||||||
sourceSettings->shared_from_this());
|
|
||||||
|
connect(sourceEditor, &SourceEditorWidget::addCompiler, this, [sourceSettings] {
|
||||||
|
auto newCompiler = std::make_shared<CompilerSettings>(
|
||||||
|
sourceSettings->apiConfigFunction());
|
||||||
|
newCompiler->setLanguageId(sourceSettings->languageId());
|
||||||
|
sourceSettings->compilers.addItem(newCompiler);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(sourceEditor, &SourceEditorWidget::gotFocus, this, [&actionHandler] {
|
||||||
|
actionHandler.updateCurrentEditor();
|
||||||
});
|
});
|
||||||
|
|
||||||
addDockWidget(Qt::LeftDockWidgetArea, dockWidget);
|
addDockWidget(Qt::LeftDockWidgetArea, dockWidget);
|
||||||
@@ -519,13 +559,19 @@ EditorWidget::EditorWidget(const QSharedPointer<JsonSettingsDocument> &document,
|
|||||||
|
|
||||||
sourceSettings->compilers.setItemRemovedCallback<CompilerSettings>(
|
sourceSettings->compilers.setItemRemovedCallback<CompilerSettings>(
|
||||||
[this](const std::shared_ptr<CompilerSettings> &compilerSettings) {
|
[this](const std::shared_ptr<CompilerSettings> &compilerSettings) {
|
||||||
m_compilerWidgets.removeIf([compilerSettings](const QDockWidget *c) {
|
auto it = std::find_if(m_compilerWidgets.begin(),
|
||||||
return static_cast<CompilerWidget *>(c->widget())->m_compilerSettings
|
m_compilerWidgets.end(),
|
||||||
|
[compilerSettings](const QDockWidget *c) {
|
||||||
|
return static_cast<CompilerWidget *>(c->widget())
|
||||||
|
->m_compilerSettings
|
||||||
== compilerSettings;
|
== compilerSettings;
|
||||||
});
|
});
|
||||||
|
QTC_ASSERT(it != m_compilerWidgets.end(), return);
|
||||||
|
delete *it;
|
||||||
|
m_compilerWidgets.erase(it);
|
||||||
});
|
});
|
||||||
|
|
||||||
Aggregate *agg = Aggregate::parentAggregate(sourceEditor);
|
/*Aggregate *agg = Aggregate::parentAggregate(sourceEditor);
|
||||||
if (!agg) {
|
if (!agg) {
|
||||||
agg = new Aggregate;
|
agg = new Aggregate;
|
||||||
agg->add(sourceEditor);
|
agg->add(sourceEditor);
|
||||||
@@ -533,15 +579,21 @@ EditorWidget::EditorWidget(const QSharedPointer<JsonSettingsDocument> &document,
|
|||||||
agg->add(this);
|
agg->add(this);
|
||||||
|
|
||||||
setFocusProxy(sourceEditor);
|
setFocusProxy(sourceEditor);
|
||||||
|
*/
|
||||||
m_sourceWidgets.append(dockWidget);
|
m_sourceWidgets.append(dockWidget);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto removeSourceEditor = [this](const std::shared_ptr<SourceSettings> &sourceSettings) {
|
auto removeSourceEditor = [this](const std::shared_ptr<SourceSettings> &sourceSettings) {
|
||||||
m_sourceWidgets.removeIf([sourceSettings = sourceSettings.get()](const QDockWidget *c) {
|
auto it = std::find_if(m_sourceWidgets.begin(),
|
||||||
return static_cast<SourceEditorWidget *>(c->widget())->m_sourceSettings
|
m_sourceWidgets.end(),
|
||||||
== sourceSettings->shared_from_this();
|
[sourceSettings](const QDockWidget *c) {
|
||||||
|
return static_cast<SourceEditorWidget *>(c->widget())
|
||||||
|
->sourceSettings()
|
||||||
|
== sourceSettings.get();
|
||||||
});
|
});
|
||||||
|
QTC_ASSERT(it != m_sourceWidgets.end(), return);
|
||||||
|
delete *it;
|
||||||
|
m_sourceWidgets.erase(it);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto recreateEditors = [this, addSourceEditor]() {
|
auto recreateEditors = [this, addSourceEditor]() {
|
||||||
@@ -593,21 +645,63 @@ EditorWidget::~EditorWidget()
|
|||||||
m_sourceWidgets.clear();
|
m_sourceWidgets.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextEditor::TextEditorWidget *EditorWidget::focusedEditorWidget() const
|
||||||
|
{
|
||||||
|
for (const QDockWidget *sourceWidget : m_sourceWidgets) {
|
||||||
|
TextEditorWidget *textEditor
|
||||||
|
= qobject_cast<SourceEditorWidget *>(sourceWidget->widget())->textEditor();
|
||||||
|
if (textEditor->hasFocus())
|
||||||
|
return textEditor;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const QDockWidget *compilerWidget : m_compilerWidgets) {
|
||||||
|
TextEditorWidget *textEditor
|
||||||
|
= qobject_cast<CompilerWidget *>(compilerWidget->widget())->textEditor();
|
||||||
|
if (textEditor->hasFocus())
|
||||||
|
return textEditor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
class Editor : public Core::IEditor
|
class Editor : public Core::IEditor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Editor()
|
Editor(TextEditorActionHandler &actionHandler)
|
||||||
: m_document(new JsonSettingsDocument())
|
: m_document(new JsonSettingsDocument(&m_undoStack))
|
||||||
{
|
{
|
||||||
setWidget(new EditorWidget(m_document));
|
setWidget(new EditorWidget(m_document, &m_undoStack, actionHandler));
|
||||||
|
|
||||||
|
connect(&m_undoStack, &QUndoStack::canUndoChanged, this, [&actionHandler] {
|
||||||
|
actionHandler.updateActions();
|
||||||
|
});
|
||||||
|
connect(&m_undoStack, &QUndoStack::canRedoChanged, this, [&actionHandler] {
|
||||||
|
actionHandler.updateActions();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
~Editor() { delete widget(); }
|
~Editor()
|
||||||
|
{
|
||||||
|
if (m_document->isModified()) {
|
||||||
|
auto settings = m_document->settings();
|
||||||
|
if (settings->isDirty()) {
|
||||||
|
settings->apply();
|
||||||
|
Utils::Store store;
|
||||||
|
settings->toMap(store);
|
||||||
|
QJsonDocument doc = QJsonDocument::fromVariant(Utils::mapFromStore(store));
|
||||||
|
|
||||||
|
CompilerExplorer::settings().defaultDocument.setValue(
|
||||||
|
QString::fromUtf8(doc.toJson()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete widget();
|
||||||
|
}
|
||||||
|
|
||||||
Core::IDocument *document() const override { return m_document.data(); }
|
Core::IDocument *document() const override { return m_document.data(); }
|
||||||
QWidget *toolBar() override { return nullptr; }
|
QWidget *toolBar() override { return nullptr; }
|
||||||
|
|
||||||
QSharedPointer<JsonSettingsDocument> m_document;
|
QSharedPointer<JsonSettingsDocument> m_document;
|
||||||
|
QUndoStack m_undoStack;
|
||||||
};
|
};
|
||||||
|
|
||||||
EditorFactory::EditorFactory()
|
EditorFactory::EditorFactory()
|
||||||
@@ -615,14 +709,32 @@ EditorFactory::EditorFactory()
|
|||||||
Constants::CE_EDITOR_CONTEXT_ID,
|
Constants::CE_EDITOR_CONTEXT_ID,
|
||||||
TextEditor::TextEditorActionHandler::None,
|
TextEditor::TextEditorActionHandler::None,
|
||||||
[](Core::IEditor *editor) -> TextEditorWidget * {
|
[](Core::IEditor *editor) -> TextEditorWidget * {
|
||||||
return Aggregation::query<TextEditorWidget>(editor->widget());
|
return static_cast<EditorWidget *>(editor->widget())->focusedEditorWidget();
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
setId(Constants::CE_EDITOR_ID);
|
setId(Constants::CE_EDITOR_ID);
|
||||||
setDisplayName(Tr::tr("Compiler Explorer Editor"));
|
setDisplayName(Tr::tr("Compiler Explorer Editor"));
|
||||||
setMimeTypes({"application/compiler-explorer"});
|
setMimeTypes({"application/compiler-explorer"});
|
||||||
|
|
||||||
setEditorCreator([]() { return new Editor(); });
|
auto undoStackFromEditor = [](Core::IEditor *editor) -> QUndoStack * {
|
||||||
|
if (!editor)
|
||||||
|
return nullptr;
|
||||||
|
return &static_cast<Editor *>(editor)->m_undoStack;
|
||||||
|
};
|
||||||
|
|
||||||
|
m_actionHandler.setCanUndoCallback([undoStackFromEditor](Core::IEditor *editor) {
|
||||||
|
if (auto undoStack = undoStackFromEditor(editor))
|
||||||
|
return undoStack->canUndo();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
m_actionHandler.setCanRedoCallback([undoStackFromEditor](Core::IEditor *editor) {
|
||||||
|
if (auto undoStack = undoStackFromEditor(editor))
|
||||||
|
return undoStack->canRedo();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
setEditorCreator([this]() { return new Editor(m_actionHandler); });
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace CompilerExplorer
|
} // namespace CompilerExplorer
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include <QFutureWatcher>
|
#include <QFutureWatcher>
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QSplitter>
|
#include <QSplitter>
|
||||||
|
#include <QUndoStack>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@@ -29,14 +30,54 @@ namespace CompilerExplorer {
|
|||||||
|
|
||||||
class JsonSettingsDocument;
|
class JsonSettingsDocument;
|
||||||
class SourceEditorWidget;
|
class SourceEditorWidget;
|
||||||
class CodeEditorWidget;
|
|
||||||
|
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(); }
|
||||||
|
|
||||||
|
void focusInEvent(QFocusEvent *event) override
|
||||||
|
{
|
||||||
|
TextEditorWidget::focusInEvent(event);
|
||||||
|
emit gotFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void gotFocus();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<SourceSettings> m_settings;
|
||||||
|
QUndoStack *m_undoStack;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AsmEditorWidget : public TextEditor::TextEditorWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
using TextEditor::TextEditorWidget::TextEditorWidget;
|
||||||
|
|
||||||
|
void focusInEvent(QFocusEvent *event) override
|
||||||
|
{
|
||||||
|
TextEditorWidget::focusInEvent(event);
|
||||||
|
emit gotFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void gotFocus();
|
||||||
|
};
|
||||||
|
|
||||||
class JsonSettingsDocument : public Core::IDocument
|
class JsonSettingsDocument : public Core::IDocument
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
JsonSettingsDocument();
|
JsonSettingsDocument(QUndoStack *undoStack);
|
||||||
~JsonSettingsDocument() override;
|
|
||||||
|
|
||||||
OpenResult open(QString *errorString,
|
OpenResult open(QString *errorString,
|
||||||
const Utils::FilePath &filePath,
|
const Utils::FilePath &filePath,
|
||||||
@@ -65,22 +106,31 @@ signals:
|
|||||||
private:
|
private:
|
||||||
mutable CompilerExplorerSettings m_ceSettings;
|
mutable CompilerExplorerSettings m_ceSettings;
|
||||||
std::function<QVariantMap()> m_windowStateCallback;
|
std::function<QVariantMap()> m_windowStateCallback;
|
||||||
|
QUndoStack *m_undoStack;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SourceEditorWidget : public QWidget
|
class SourceEditorWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
SourceEditorWidget(const std::shared_ptr<SourceSettings> &settings);
|
SourceEditorWidget(const std::shared_ptr<SourceSettings> &settings, QUndoStack *undoStack);
|
||||||
|
|
||||||
QString sourceCode();
|
QString sourceCode();
|
||||||
|
SourceSettings *sourceSettings() { return m_sourceSettings.get(); }
|
||||||
|
|
||||||
|
void focusInEvent(QFocusEvent *) override { emit gotFocus(); }
|
||||||
|
|
||||||
|
TextEditor::TextEditorWidget *textEditor() { return m_codeEditor; }
|
||||||
|
|
||||||
std::shared_ptr<SourceSettings> m_sourceSettings;
|
|
||||||
signals:
|
signals:
|
||||||
void sourceCodeChanged();
|
void sourceCodeChanged();
|
||||||
|
void addCompiler();
|
||||||
|
void remove();
|
||||||
|
void gotFocus();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CodeEditorWidget *m_codeEditor{nullptr};
|
CodeEditorWidget *m_codeEditor{nullptr};
|
||||||
|
std::shared_ptr<SourceSettings> m_sourceSettings;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CompilerWidget : public QWidget
|
class CompilerWidget : public QWidget
|
||||||
@@ -99,11 +149,19 @@ public:
|
|||||||
std::shared_ptr<SourceSettings> m_sourceSettings;
|
std::shared_ptr<SourceSettings> m_sourceSettings;
|
||||||
std::shared_ptr<CompilerSettings> m_compilerSettings;
|
std::shared_ptr<CompilerSettings> m_compilerSettings;
|
||||||
|
|
||||||
|
void focusInEvent(QFocusEvent *) override { emit gotFocus(); }
|
||||||
|
|
||||||
|
TextEditor::TextEditorWidget *textEditor() { return m_asmEditor; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void doCompile();
|
void doCompile();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void remove();
|
||||||
|
void gotFocus();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TextEditor::TextEditorWidget *m_asmEditor{nullptr};
|
AsmEditorWidget *m_asmEditor{nullptr};
|
||||||
Core::SearchableTerminal *m_resultTerminal{nullptr};
|
Core::SearchableTerminal *m_resultTerminal{nullptr};
|
||||||
|
|
||||||
SpinnerSolution::Spinner *m_spinner{nullptr};
|
SpinnerSolution::Spinner *m_spinner{nullptr};
|
||||||
@@ -120,9 +178,14 @@ class EditorWidget : public Utils::FancyMainWindow
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
EditorWidget(const QSharedPointer<JsonSettingsDocument> &document, QWidget *parent = nullptr);
|
EditorWidget(const QSharedPointer<JsonSettingsDocument> &document,
|
||||||
|
QUndoStack *undoStack,
|
||||||
|
TextEditor::TextEditorActionHandler &actionHandler,
|
||||||
|
QWidget *parent = nullptr);
|
||||||
~EditorWidget() override;
|
~EditorWidget() override;
|
||||||
|
|
||||||
|
TextEditor::TextEditorWidget *focusedEditorWidget() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void sourceCodeChanged();
|
void sourceCodeChanged();
|
||||||
|
|
||||||
@@ -144,6 +207,9 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
TextEditor::TextEditorActionHandler m_actionHandler;
|
TextEditor::TextEditorActionHandler m_actionHandler;
|
||||||
|
|
||||||
|
QAction m_undoAction;
|
||||||
|
QAction m_redoAction;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace CompilerExplorer
|
} // namespace CompilerExplorer
|
||||||
|
|||||||
@@ -87,11 +87,12 @@ SourceSettings::SourceSettings(const ApiConfigFunction &apiConfigFunction)
|
|||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const auto &aspect : this->aspects())
|
for (const auto &aspect : this->aspects()) {
|
||||||
connect(aspect,
|
connect(aspect,
|
||||||
&Utils::BaseAspect::volatileValueChanged,
|
&Utils::BaseAspect::volatileValueChanged,
|
||||||
this,
|
this,
|
||||||
&CompilerExplorerSettings::changed);
|
&Utils::AspectContainer::changed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SourceSettings::refresh()
|
void SourceSettings::refresh()
|
||||||
@@ -146,11 +147,12 @@ CompilerSettings::CompilerSettings(const ApiConfigFunction &apiConfigFunction)
|
|||||||
demangleIdentifiers.setLabelText(Tr::tr("Demangle identifiers"));
|
demangleIdentifiers.setLabelText(Tr::tr("Demangle identifiers"));
|
||||||
demangleIdentifiers.setDefaultValue(true);
|
demangleIdentifiers.setDefaultValue(true);
|
||||||
|
|
||||||
for (const auto &aspect : this->aspects())
|
for (const auto &aspect : this->aspects()) {
|
||||||
connect(aspect,
|
connect(aspect,
|
||||||
&Utils::BaseAspect::volatileValueChanged,
|
&Utils::BaseAspect::volatileValueChanged,
|
||||||
this,
|
this,
|
||||||
&CompilerExplorerSettings::changed);
|
&Utils::AspectContainer::changed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerSettings::refresh()
|
void CompilerSettings::refresh()
|
||||||
@@ -325,11 +327,12 @@ CompilerExplorerSettings::CompilerExplorerSettings()
|
|||||||
m_sources.forEachItem<SourceSettings>(&SourceSettings::refresh);
|
m_sources.forEachItem<SourceSettings>(&SourceSettings::refresh);
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const auto &aspect : this->aspects())
|
for (const auto &aspect : this->aspects()) {
|
||||||
connect(aspect,
|
connect(aspect,
|
||||||
&Utils::BaseAspect::volatileValueChanged,
|
&Utils::BaseAspect::volatileValueChanged,
|
||||||
this,
|
this,
|
||||||
&CompilerExplorerSettings::changed);
|
&CompilerExplorerSettings::changed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CompilerExplorerSettings::~CompilerExplorerSettings() = default;
|
CompilerExplorerSettings::~CompilerExplorerSettings() = default;
|
||||||
|
|||||||
@@ -77,7 +77,8 @@ private:
|
|||||||
ApiConfigFunction m_apiConfigFunction;
|
ApiConfigFunction m_apiConfigFunction;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CompilerSettings : public Utils::AspectContainer
|
class CompilerSettings : public Utils::AspectContainer,
|
||||||
|
public std::enable_shared_from_this<CompilerSettings>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CompilerSettings(const ApiConfigFunction &apiConfigFunction);
|
CompilerSettings(const ApiConfigFunction &apiConfigFunction);
|
||||||
|
|||||||
Reference in New Issue
Block a user