forked from qt-creator/qt-creator
BinEditor: Support duplication
Fixes: QTCREATORBUG-13209 Change-Id: I0aafdb2bf87d94f8e86cf392445577dc355e556a Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -126,7 +126,12 @@ public:
|
|||||||
void requestNewWindow(quint64 address) { if (m_newWindowRequestHandler) m_newWindowRequestHandler(address); }
|
void requestNewWindow(quint64 address) { if (m_newWindowRequestHandler) m_newWindowRequestHandler(address); }
|
||||||
void requestWatchPoint(quint64 address, int size) { if (m_watchPointRequestHandler) m_watchPointRequestHandler(address, size); }
|
void requestWatchPoint(quint64 address, int size) { if (m_watchPointRequestHandler) m_watchPointRequestHandler(address, size); }
|
||||||
void requestNewRange(quint64 address) { if (m_newRangeRequestHandler) m_newRangeRequestHandler(address); }
|
void requestNewRange(quint64 address) { if (m_newRangeRequestHandler) m_newRangeRequestHandler(address); }
|
||||||
void announceChangedData(quint64 address, const QByteArray &ba) { if (m_dataChangedHandler) m_dataChangedHandler(address, ba); }
|
|
||||||
|
void announceChangedData(quint64 address, const QByteArray &ba)
|
||||||
|
{
|
||||||
|
if (m_dataChangedHandler)
|
||||||
|
m_dataChangedHandler(address, ba);
|
||||||
|
}
|
||||||
|
|
||||||
void setFinished()
|
void setFinished()
|
||||||
{
|
{
|
||||||
@@ -202,7 +207,7 @@ class BinEditorWidget final : public QAbstractScrollArea
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit BinEditorWidget(BinEditorDocument *doc);
|
explicit BinEditorWidget(const std::shared_ptr<BinEditorDocument> &doc);
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
quint64 baseAddress() const { return m_doc->m_baseAddr; }
|
quint64 baseAddress() const { return m_doc->m_baseAddr; }
|
||||||
@@ -284,7 +289,7 @@ public:
|
|||||||
void asDouble(qint64 offset, double &value, bool old) const;
|
void asDouble(qint64 offset, double &value, bool old) const;
|
||||||
QString toolTip(const QHelpEvent *helpEvent) const;
|
QString toolTip(const QHelpEvent *helpEvent) const;
|
||||||
|
|
||||||
BinEditorDocument *m_doc = nullptr;
|
std::shared_ptr<BinEditorDocument> m_doc;
|
||||||
int m_bytesPerLine = 16;
|
int m_bytesPerLine = 16;
|
||||||
int m_readOnly = false;
|
int m_readOnly = false;
|
||||||
int m_margin = 0;
|
int m_margin = 0;
|
||||||
@@ -356,24 +361,28 @@ static QByteArray calculateHexPattern(const QByteArray &pattern)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
BinEditorWidget::BinEditorWidget(BinEditorDocument *doc)
|
BinEditorWidget::BinEditorWidget(const std::shared_ptr<BinEditorDocument> &doc)
|
||||||
{
|
{
|
||||||
m_doc = doc;
|
m_doc = doc;
|
||||||
setFocusPolicy(Qt::WheelFocus);
|
setFocusPolicy(Qt::WheelFocus);
|
||||||
setFrameStyle(QFrame::Plain);
|
setFrameStyle(QFrame::Plain);
|
||||||
|
|
||||||
connect(doc, &BinEditorDocument::dataAdded,
|
connect(doc.get(), &BinEditorDocument::dataAdded,
|
||||||
this, &BinEditorWidget::onDataAdded);
|
this, &BinEditorWidget::onDataAdded);
|
||||||
connect(doc, &BinEditorDocument::sizesChanged,
|
connect(doc.get(), &BinEditorDocument::sizesChanged,
|
||||||
this, &BinEditorWidget::onSizesChanged);
|
this, &BinEditorWidget::onSizesChanged);
|
||||||
connect(doc, &BinEditorDocument::cursorWanted,
|
connect(doc.get(), &BinEditorDocument::cursorWanted,
|
||||||
this, &BinEditorWidget::onCursorWanted);
|
this, &BinEditorWidget::onCursorWanted);
|
||||||
connect(doc, &BinEditorDocument::cleared,
|
connect(doc.get(), &BinEditorDocument::cleared,
|
||||||
this, &BinEditorWidget::clear);
|
this, &BinEditorWidget::clear);
|
||||||
connect(doc, &BinEditorDocument::aboutToReload,
|
connect(doc.get(), &BinEditorDocument::aboutToReload,
|
||||||
this, &BinEditorWidget::aboutToReload);
|
this, &BinEditorWidget::aboutToReload);
|
||||||
connect(doc, &BinEditorDocument::reloadFinished,
|
connect(doc.get(), &BinEditorDocument::reloadFinished,
|
||||||
this, &BinEditorWidget::reloadFinished);
|
this, &BinEditorWidget::reloadFinished);
|
||||||
|
connect(doc.get(), &BinEditorDocument::contentsChanged, this, [this] {
|
||||||
|
update();
|
||||||
|
viewport()->update();
|
||||||
|
});
|
||||||
|
|
||||||
// Font settings
|
// Font settings
|
||||||
setFontSettings(TextEditorSettings::fontSettings());
|
setFontSettings(TextEditorSettings::fontSettings());
|
||||||
@@ -503,6 +512,7 @@ void BinEditorDocument::changeDataAt(qint64 pos, char c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emit contentsChanged();
|
||||||
announceChangedData(m_baseAddr + pos, QByteArray(1, c));
|
announceChangedData(m_baseAddr + pos, QByteArray(1, c));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2083,7 +2093,6 @@ BinEditorDocument::BinEditorDocument()
|
|||||||
setMimeType(Utils::Constants::OCTET_STREAM_MIMETYPE);
|
setMimeType(Utils::Constants::OCTET_STREAM_MIMETYPE);
|
||||||
m_fetchDataHandler = [this](quint64 address) { provideData(address); };
|
m_fetchDataHandler = [this](quint64 address) { provideData(address); };
|
||||||
m_newRangeRequestHandler = [this](quint64 offset) { provideNewRange(offset); };
|
m_newRangeRequestHandler = [this](quint64 offset) { provideNewRange(offset); };
|
||||||
m_dataChangedHandler = [this](quint64, const QByteArray &) { contentsChanged(); };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BinEditorDocument::setContents(const QByteArray &contents)
|
bool BinEditorDocument::setContents(const QByteArray &contents)
|
||||||
@@ -2184,10 +2193,11 @@ bool BinEditorDocument::saveImpl(QString *errorString, const FilePath &filePath,
|
|||||||
class BinEditorImpl final : public IEditor
|
class BinEditorImpl final : public IEditor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BinEditorImpl(BinEditorWidget *widget, BinEditorDocument *doc)
|
BinEditorImpl(BinEditorWidget *widget, const std::shared_ptr<BinEditorDocument> &doc)
|
||||||
: m_document(doc)
|
: m_document(doc), m_widget(widget)
|
||||||
{
|
{
|
||||||
setWidget(widget);
|
setWidget(widget);
|
||||||
|
setDuplicateSupported(true);
|
||||||
auto codecChooser = new CodecChooser(CodecChooser::Filter::SingleByte);
|
auto codecChooser = new CodecChooser(CodecChooser::Filter::SingleByte);
|
||||||
codecChooser->prependNone();
|
codecChooser->prependNone();
|
||||||
|
|
||||||
@@ -2210,12 +2220,24 @@ public:
|
|||||||
codecChooser->setAssignedCodec(QTextCodec::codecForName(setting.toByteArray()));
|
codecChooser->setAssignedCodec(QTextCodec::codecForName(setting.toByteArray()));
|
||||||
}
|
}
|
||||||
|
|
||||||
~BinEditorImpl() final { delete m_widget; delete m_document; }
|
~BinEditorImpl() final { delete m_widget; }
|
||||||
IDocument *document() const final { return m_document; }
|
|
||||||
|
IDocument *document() const final { return m_document.get(); }
|
||||||
|
|
||||||
QWidget *toolBar() final { return m_toolBar; }
|
QWidget *toolBar() final { return m_toolBar; }
|
||||||
|
|
||||||
|
IEditor *duplicate() final
|
||||||
|
{
|
||||||
|
auto widget = new BinEditorWidget(m_document);
|
||||||
|
widget->setCursorPosition(m_widget->cursorPosition());
|
||||||
|
auto editor = new BinEditorImpl(widget, m_document);
|
||||||
|
emit editorDuplicated(editor);
|
||||||
|
return editor;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BinEditorDocument *m_document;
|
std::shared_ptr<BinEditorDocument> m_document;
|
||||||
|
BinEditorWidget *m_widget = nullptr;
|
||||||
QToolBar *m_toolBar;
|
QToolBar *m_toolBar;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2264,13 +2286,13 @@ class BinEditorFactoryService final : public QObject, public FactoryService
|
|||||||
public:
|
public:
|
||||||
EditorService *createEditorService(const QString &title, bool wantsEditor) final
|
EditorService *createEditorService(const QString &title, bool wantsEditor) final
|
||||||
{
|
{
|
||||||
auto document = new BinEditorDocument;
|
auto document = std::make_shared<BinEditorDocument>();
|
||||||
auto widget = new BinEditorWidget(document);
|
auto widget = new BinEditorWidget(document);
|
||||||
widget->setWindowTitle(title);
|
widget->setWindowTitle(title);
|
||||||
|
|
||||||
auto service = new BinEditorService;
|
auto service = new BinEditorService;
|
||||||
service->m_widget = widget;
|
service->m_widget = widget;
|
||||||
service->m_document = document;
|
service->m_document = document.get();
|
||||||
service->m_editor = new BinEditorImpl(widget, document);
|
service->m_editor = new BinEditorImpl(widget, document);
|
||||||
if (wantsEditor)
|
if (wantsEditor)
|
||||||
EditorManager::activateEditor(service->m_editor);
|
EditorManager::activateEditor(service->m_editor);
|
||||||
@@ -2310,12 +2332,12 @@ public:
|
|||||||
ActionManager::registerAction(m_selectAllAction, Core::Constants::SELECTALL, context);
|
ActionManager::registerAction(m_selectAllAction, Core::Constants::SELECTALL, context);
|
||||||
|
|
||||||
setEditorCreator([this] {
|
setEditorCreator([this] {
|
||||||
auto doc = new BinEditorDocument;
|
auto doc = std::make_shared<BinEditorDocument>();
|
||||||
auto widget = new BinEditorWidget(doc);
|
auto widget = new BinEditorWidget(doc);
|
||||||
auto editor = new BinEditorImpl(widget, doc);
|
auto editor = new BinEditorImpl(widget, doc);
|
||||||
|
|
||||||
connect(m_undoAction, &QAction::triggered, doc, &BinEditorDocument::undo);
|
connect(m_undoAction, &QAction::triggered, doc.get(), &BinEditorDocument::undo);
|
||||||
connect(m_redoAction, &QAction::triggered, doc, &BinEditorDocument::redo);
|
connect(m_redoAction, &QAction::triggered, doc.get(), &BinEditorDocument::redo);
|
||||||
connect(m_copyAction, &QAction::triggered, widget, &BinEditorWidget::copy);
|
connect(m_copyAction, &QAction::triggered, widget, &BinEditorWidget::copy);
|
||||||
connect(m_selectAllAction, &QAction::triggered, widget, &BinEditorWidget::selectAll);
|
connect(m_selectAllAction, &QAction::triggered, widget, &BinEditorWidget::selectAll);
|
||||||
|
|
||||||
@@ -2325,8 +2347,8 @@ public:
|
|||||||
m_redoAction->setEnabled(widget->isRedoAvailable());
|
m_redoAction->setEnabled(widget->isRedoAvailable());
|
||||||
};
|
};
|
||||||
|
|
||||||
connect(doc, &BinEditorDocument::undoAvailable, widget, updateActions);
|
connect(doc.get(), &BinEditorDocument::undoAvailable, widget, updateActions);
|
||||||
connect(doc, &BinEditorDocument::redoAvailable, widget, updateActions);
|
connect(doc.get(), &BinEditorDocument::redoAvailable, widget, updateActions);
|
||||||
|
|
||||||
auto aggregate = new Aggregation::Aggregate;
|
auto aggregate = new Aggregation::Aggregate;
|
||||||
auto binEditorFind = new BinEditorFind(widget);
|
auto binEditorFind = new BinEditorFind(widget);
|
||||||
|
Reference in New Issue
Block a user