diff options
author | hjk <hjk@theqtcompany.com> | 2016-07-14 10:00:15 +0200 |
---|---|---|
committer | hjk <hjk@qt.io> | 2016-07-21 06:20:52 +0000 |
commit | 6e925910b460a8accec07de8d37f4610678a41b5 (patch) | |
tree | c71aa3d260a8d259d588814232d23ab324079ade /src/plugins/bineditor | |
parent | 66142d94d2a7dad970c4dcc37e5bd37f62e4d933 (diff) | |
download | qt-creator-6e925910b460a8accec07de8d37f4610678a41b5.tar.gz |
Debugger/BinEditor: Standardize interface
Change-Id: I4acf6bc7648e57c564e86023176ae3905a293a99
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Diffstat (limited to 'src/plugins/bineditor')
-rw-r--r-- | src/plugins/bineditor/bineditor.pro | 1 | ||||
-rw-r--r-- | src/plugins/bineditor/bineditor.qbs | 9 | ||||
-rw-r--r-- | src/plugins/bineditor/bineditorplugin.cpp | 63 | ||||
-rw-r--r-- | src/plugins/bineditor/bineditorplugin.h | 23 | ||||
-rw-r--r-- | src/plugins/bineditor/bineditorservice.h | 85 | ||||
-rw-r--r-- | src/plugins/bineditor/bineditorwidget.cpp | 106 | ||||
-rw-r--r-- | src/plugins/bineditor/bineditorwidget.h | 31 |
7 files changed, 239 insertions, 79 deletions
diff --git a/src/plugins/bineditor/bineditor.pro b/src/plugins/bineditor/bineditor.pro index 3dde3eaf67..1603f77e08 100644 --- a/src/plugins/bineditor/bineditor.pro +++ b/src/plugins/bineditor/bineditor.pro @@ -3,6 +3,7 @@ include(../../qtcreatorplugin.pri) DEFINES += BINEDITOR_LIBRARY HEADERS += bineditorplugin.h \ + bineditorservice.h \ bineditorwidget.h \ bineditorconstants.h \ bineditor_global.h \ diff --git a/src/plugins/bineditor/bineditor.qbs b/src/plugins/bineditor/bineditor.qbs index 8d2138598d..6a94295cef 100644 --- a/src/plugins/bineditor/bineditor.qbs +++ b/src/plugins/bineditor/bineditor.qbs @@ -11,12 +11,11 @@ QtcPlugin { Depends { name: "TextEditor" } files: [ - "bineditorwidget.cpp", - "bineditorwidget.h", - "bineditorconstants.h", "bineditor_global.h", - "bineditorplugin.cpp", - "bineditorplugin.h", + "bineditorconstants.h", + "bineditorwidget.cpp", "bineditorwidget.h", + "bineditorplugin.cpp", "bineditorplugin.h", + "bineditorservice.h", "markup.cpp", "markup.h", ] diff --git a/src/plugins/bineditor/bineditorplugin.cpp b/src/plugins/bineditor/bineditorplugin.cpp index 6f5f75dfc2..c1f9906a58 100644 --- a/src/plugins/bineditor/bineditorplugin.cpp +++ b/src/plugins/bineditor/bineditorplugin.cpp @@ -26,6 +26,7 @@ #include "bineditorplugin.h" #include "bineditorwidget.h" #include "bineditorconstants.h" +#include "bineditorservice.h" #include <coreplugin/icore.h> @@ -59,30 +60,6 @@ using namespace Utils; using namespace Core; namespace BinEditor { - -///////////////////////////////// BinEditorWidgetFactory ////////////////////////////////// - -/*! - \class BinEditor::BinEditorWidgetFactory - \brief The BinEditorWidgetFactory class offers a service registered with - PluginManager to create bin editor widgets for plugins - without direct linkage. - - \sa ExtensionSystem::PluginManager::getObjectByClassName, ExtensionSystem::invoke -*/ - -class BinEditorWidgetFactory : public QObject -{ - Q_OBJECT -public: - BinEditorWidgetFactory() {} - - Q_INVOKABLE QWidget *createWidget(QWidget *parent) - { - return new BinEditorWidget(parent); - } -}; - namespace Internal { class BinEditorFind : public IFindSupport @@ -230,12 +207,10 @@ public: setId(Core::Constants::K_DEFAULT_BINARY_EDITOR_ID); setMimeType(QLatin1String(BinEditor::Constants::C_BINEDITOR_MIMETYPE)); m_widget = parent; - connect(m_widget, &BinEditorWidget::dataRequested, - this, &BinEditorDocument::provideData); - connect(m_widget, &BinEditorWidget::newRangeRequested, - this, &BinEditorDocument::provideNewRange); - connect(m_widget, &BinEditorWidget::dataChanged, - this, &IDocument::contentsChanged); + EditorService *es = m_widget->editorService(); + es->setFetchDataHandler([this](quint64 address) { provideData(address); }); + es->setNewRangeRequestHandler([this](quint64 offset) { provideNewRange(offset); }); + es->setDataChangedHandler([this](quint64, const QByteArray &) { contentsChanged(); }); } QByteArray contents() const override @@ -316,7 +291,7 @@ public: return OpenResult::ReadError; } - void provideData(quint64 block) + void provideData(quint64 address) { const FileName fn = filePath(); if (fn.isEmpty()) @@ -324,13 +299,13 @@ public: QFile file(fn.toString()); if (file.open(QIODevice::ReadOnly)) { int blockSize = m_widget->dataBlockSize(); - file.seek(block * blockSize); + file.seek(address); QByteArray data = file.read(blockSize); file.close(); const int dataSize = data.size(); if (dataSize != blockSize) data += QByteArray(blockSize - dataSize, 0); - m_widget->addData(block, data); + m_widget->addData(address, data); } else { QMessageBox::critical(ICore::mainWindow(), tr("File Error"), tr("Cannot open %1: %2").arg( @@ -470,12 +445,30 @@ IEditor *BinEditorFactory::createEditor() return editor; } +///////////////////////////////// BinEditor Services ////////////////////////////////// + +EditorService *FactoryServiceImpl::createEditorService(const QString &title0, bool wantsEditor) +{ + BinEditorWidget *widget = nullptr; + if (wantsEditor) { + QString title = title0; + IEditor *editor = EditorManager::openEditorWithContents( + Core::Constants::K_DEFAULT_BINARY_EDITOR_ID, &title); + if (!editor) + return 0; + widget = qobject_cast<BinEditorWidget *>(editor->widget()); + widget->setEditor(editor); + } else { + widget = new BinEditorWidget; + widget->setWindowTitle(title0); + } + return widget->editorService(); +} ///////////////////////////////// BinEditorPlugin ////////////////////////////////// BinEditorPlugin::BinEditorPlugin() { - m_undoAction = m_redoAction = m_copyAction = m_selectAllAction = 0; } BinEditorPlugin::~BinEditorPlugin() @@ -522,8 +515,8 @@ bool BinEditorPlugin::initialize(const QStringList &arguments, QString *errorMes connect(Core::EditorManager::instance(), &EditorManager::currentEditorChanged, this, &BinEditorPlugin::updateCurrentEditor); + addAutoReleasedObject(new FactoryServiceImpl); addAutoReleasedObject(new BinEditorFactory(this)); - addAutoReleasedObject(new BinEditorWidgetFactory); return true; } diff --git a/src/plugins/bineditor/bineditorplugin.h b/src/plugins/bineditor/bineditorplugin.h index 4fd3c743f8..f22c6701a7 100644 --- a/src/plugins/bineditor/bineditorplugin.h +++ b/src/plugins/bineditor/bineditorplugin.h @@ -25,6 +25,8 @@ #pragma once +#include "bineditorservice.h" + #include <extensionsystem/iplugin.h> #include <coreplugin/editormanager/ieditorfactory.h> #include <coreplugin/icontext.h> @@ -34,9 +36,9 @@ #include <QAction> namespace BinEditor { -class BinEditorWidget; - namespace Internal { + +class BinEditorWidget; class BinEditorFactory; class BinEditorPlugin : public ExtensionSystem::IPlugin @@ -65,10 +67,10 @@ private: Core::Context m_context; QAction *registerNewAction(Core::Id id, const QString &title = QString()); - QAction *m_undoAction; - QAction *m_redoAction; - QAction *m_copyAction; - QAction *m_selectAllAction; + QAction *m_undoAction = nullptr; + QAction *m_redoAction = nullptr; + QAction *m_copyAction = nullptr; + QAction *m_selectAllAction = nullptr; QPointer<BinEditorWidget> m_currentEditor; }; @@ -86,5 +88,14 @@ private: BinEditorPlugin *m_owner; }; +class FactoryServiceImpl : public QObject, public FactoryService +{ + Q_OBJECT + Q_INTERFACES(BinEditor::FactoryService) + +public: + EditorService *createEditorService(const QString &title0, bool wantsEditor) override; +}; + } // namespace Internal } // namespace BinEditor diff --git a/src/plugins/bineditor/bineditorservice.h b/src/plugins/bineditor/bineditorservice.h new file mode 100644 index 0000000000..5a68907e03 --- /dev/null +++ b/src/plugins/bineditor/bineditorservice.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include "bineditor_global.h" + +#include <QColor> +#include <QObject> +#include <QString> + +#include <functional> + +namespace Core { class IEditor; } + +namespace BinEditor { + +class EditorService +{ +public: + virtual ~EditorService() {} + + virtual QWidget *widget() = 0; + virtual Core::IEditor *editor() = 0; + + // "Slots" + virtual void setSizes(quint64 address, qint64 range, int blockSize) = 0; + virtual void setReadOnly(bool on) = 0; + virtual void setFinished() = 0; + virtual void setNewWindowRequestAllowed(bool on) = 0; + virtual void setCursorPosition(qint64 pos) = 0; + virtual void updateContents() = 0; + virtual void addData(quint64 address, const QByteArray &data) = 0; + + virtual void clearMarkup() = 0; + virtual void addMarkup(quint64 address, quint64 len, const QColor &color, const QString &toolTip) = 0; + virtual void commitMarkup() = 0; + + // "Signals" + virtual void setFetchDataHandler(const std::function<void(quint64 block)> &) = 0; + virtual void setNewWindowRequestHandler(const std::function<void(quint64 address)> &) = 0; + virtual void setNewRangeRequestHandler(const std::function<void(quint64 address)> &) = 0; + virtual void setDataChangedHandler(const std::function<void(quint64 address, const QByteArray &)> &) = 0; + virtual void setWatchPointRequestHandler(const std::function<void(quint64 address, uint size)> &) = 0; + virtual void setAboutToBeDestroyedHandler(const std::function<void()> &) = 0; +}; + +class FactoryService +{ +public: + virtual ~FactoryService() {} + + // Create a BinEditor widget. Embed into a Core::IEditor iff wantsEditor == true. + virtual EditorService *createEditorService(const QString &title, bool wantsEditor) = 0; +}; + +} // namespace BinEditor + +#define BinEditor_FactoryService_iid "org.qt-project.Qt.Creator.BinEditor.EditorService" + +QT_BEGIN_NAMESPACE +Q_DECLARE_INTERFACE(BinEditor::FactoryService, BinEditor_FactoryService_iid) +QT_END_NAMESPACE diff --git a/src/plugins/bineditor/bineditorwidget.cpp b/src/plugins/bineditor/bineditorwidget.cpp index 44e9ccb694..c6269a6bc0 100644 --- a/src/plugins/bineditor/bineditorwidget.cpp +++ b/src/plugins/bineditor/bineditorwidget.cpp @@ -24,11 +24,17 @@ ****************************************************************************/ #include "bineditorwidget.h" +#include "bineditorservice.h" +#include "markup.h" + +#include <coreplugin/coreconstants.h> +#include <coreplugin/editormanager/editormanager.h> +#include <coreplugin/editormanager/ieditor.h> #include <texteditor/fontsettings.h> #include <texteditor/texteditorconstants.h> #include <texteditor/texteditorsettings.h> -#include <coreplugin/editormanager/ieditor.h> + #include <utils/fileutils.h> #include <utils/qtcassert.h> @@ -51,6 +57,8 @@ #include <QToolTip> #include <QWheelEvent> +using namespace Core; + static QByteArray calculateHexPattern(const QByteArray &pattern) { QByteArray result; @@ -69,9 +77,65 @@ static QByteArray calculateHexPattern(const QByteArray &pattern) } namespace BinEditor { +namespace Internal { + +class BinEditorWidgetPrivate : public EditorService +{ +public: + BinEditorWidgetPrivate(BinEditorWidget *widget) : q(widget) {} + ~BinEditorWidgetPrivate() override { if (m_aboutToBeDestroyedHandler) m_aboutToBeDestroyedHandler(); } + + QWidget *widget() override { return q; } + IEditor *editor() override { return q->editor(); } + + void setReadOnly(bool on) override { q->setReadOnly(on); } + void setNewWindowRequestAllowed(bool on) override { q->setNewWindowRequestAllowed(on); } + + void setFinished() override + { + q->setReadOnly(true); + m_fetchDataHandler = {}; + m_newWindowRequestHandler = {}; + m_newRangeRequestHandler = {}; + m_dataChangedHandler = {}; + m_watchPointRequestHandler = {}; + } + + void setSizes(quint64 address, qint64 range, int blockSize) override { q->setSizes(address, range, blockSize); } + void setCursorPosition(qint64 pos) override { q->setCursorPosition(pos); } + void updateContents() override { q->updateContents(); } + void addData(quint64 address, const QByteArray &data) override { q->addData(address, data); } + + void clearMarkup() override { m_markup.clear(); } + void addMarkup(quint64 a, quint64 l, const QColor &c, const QString &t) override { m_markup.append(Markup(a, l, c, t)); } + void commitMarkup() override { q->setMarkup(m_markup); } + + void setFetchDataHandler(const std::function<void(quint64)> &cb) override { m_fetchDataHandler = cb; } + void setNewWindowRequestHandler(const std::function<void(quint64)> &cb) { m_newWindowRequestHandler = cb; } + void setNewRangeRequestHandler(const std::function<void(quint64)> &cb) { m_newRangeRequestHandler = cb; } + void setDataChangedHandler(const std::function<void(quint64, const QByteArray &)> &cb) { m_dataChangedHandler = cb; } + void setWatchPointRequestHandler(const std::function<void(quint64, uint)> &cb) { m_watchPointRequestHandler = cb; } + void setAboutToBeDestroyedHandler(const std::function<void()> & cb) { m_aboutToBeDestroyedHandler = cb; } + + void fetchData(quint64 address) { if (m_fetchDataHandler) m_fetchDataHandler(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 requestNewRange(quint64 address) { if (m_newRangeRequestHandler) m_newRangeRequestHandler(address); } + void announceChangedData(quint64 address, const QByteArray &ba) { if (m_dataChangedHandler) m_dataChangedHandler(address, ba); } + +private: + BinEditorWidget *q; + std::function<void(quint64)> m_fetchDataHandler; + std::function<void(quint64)> m_newWindowRequestHandler; + std::function<void(quint64)> m_newRangeRequestHandler; + std::function<void(quint64, const QByteArray &)> m_dataChangedHandler; + std::function<void(quint64, uint)> m_watchPointRequestHandler; + std::function<void()> m_aboutToBeDestroyedHandler; + QList<Markup> m_markup; +}; BinEditorWidget::BinEditorWidget(QWidget *parent) - : QAbstractScrollArea(parent) + : QAbstractScrollArea(parent), d(new BinEditorWidgetPrivate(this)) { m_bytesPerLine = 16; m_ieditor = 0; @@ -102,6 +166,12 @@ BinEditorWidget::BinEditorWidget(QWidget *parent) BinEditorWidget::~BinEditorWidget() { + delete d; +} + +EditorService *BinEditorWidget::editorService() const +{ + return d; } void BinEditorWidget::init() @@ -153,10 +223,9 @@ void BinEditorWidget::init() } -void BinEditorWidget::addData(quint64 block, const QByteArray &data) +void BinEditorWidget::addData(quint64 addr, const QByteArray &data) { QTC_ASSERT(data.size() == m_blockSize, return); - const quint64 addr = block * m_blockSize; if (addr >= m_baseAddr && addr <= m_baseAddr + m_size - 1) { if (m_data.size() * m_blockSize >= 64 * 1024 * 1024) m_data.clear(); @@ -176,13 +245,11 @@ bool BinEditorWidget::requestDataAt(qint64 pos) const it = m_data.find(block); if (it != m_data.end()) return true; - if (!m_requests.contains(block)) { - m_requests.insert(block); - emit const_cast<BinEditorWidget*>(this)-> - dataRequested(m_baseAddr / m_blockSize + block); - return true; - } - return false; + if (m_requests.contains(block)) + return false; + m_requests.insert(block); + d->fetchData((m_baseAddr / m_blockSize + block) * m_blockSize); + return true; } bool BinEditorWidget::requestOldDataAt(qint64 pos) const @@ -215,7 +282,7 @@ void BinEditorWidget::changeDataAt(qint64 pos, char c) } } - emit dataChanged(m_baseAddr + pos, QByteArray(1, c)); + d->announceChangedData(m_baseAddr + pos, QByteArray(1, c)); } QByteArray BinEditorWidget::dataMid(qint64 from, int length, bool old) const @@ -429,9 +496,9 @@ void BinEditorWidget::scrollContentsBy(int dx, int dy) const QScrollBar * const scrollBar = verticalScrollBar(); const int scrollPos = scrollBar->value(); if (dy <= 0 && scrollPos == scrollBar->maximum()) - emit newRangeRequested(baseAddress() + m_size); + d->requestNewRange(baseAddress() + m_size); else if (dy >= 0 && scrollPos == scrollBar->minimum()) - emit newRangeRequested(baseAddress()); + d->requestNewRange(baseAddress()); } void BinEditorWidget::changeEvent(QEvent *e) @@ -1044,7 +1111,7 @@ bool BinEditorWidget::event(QEvent *e) const QScrollBar * const scrollBar = verticalScrollBar(); const int maximum = scrollBar->maximum(); if (maximum && scrollBar->value() >= maximum - 1) { - emit newRangeRequested(baseAddress() + m_size); + d->requestNewRange(baseAddress() + m_size); return true; } break; @@ -1531,11 +1598,11 @@ void BinEditorWidget::contextMenuEvent(QContextMenuEvent *event) else if (action == jumpToLeAddressHereAction) jumpToAddress(leAddress); else if (action == jumpToBeAddressNewWindowAction) - emit newWindowRequested(beAddress); + d->requestNewWindow(beAddress); else if (action == jumpToLeAddressNewWindowAction) - emit newWindowRequested(leAddress); + d->requestNewWindow(leAddress); else if (action == addWatchpointAction) - emit addWatchpointRequested(m_baseAddr + selStart, byteCount); + d->requestWatchPoint(m_baseAddr + selStart, byteCount); delete contextMenu; } @@ -1557,7 +1624,7 @@ void BinEditorWidget::jumpToAddress(quint64 address) if (address >= m_baseAddr && address < m_baseAddr + m_size) setCursorPosition(address - m_baseAddr); else - emit newRangeRequested(address); + d->requestNewRange(address); } void BinEditorWidget::setNewWindowRequestAllowed(bool c) @@ -1614,4 +1681,5 @@ void BinEditorWidget::setMarkup(const QList<Markup> &markup) viewport()->update(); } +} // namespace Internal } // namespace BinEditor diff --git a/src/plugins/bineditor/bineditorwidget.h b/src/plugins/bineditor/bineditorwidget.h index dd54b53c7f..de8d78462c 100644 --- a/src/plugins/bineditor/bineditorwidget.h +++ b/src/plugins/bineditor/bineditorwidget.h @@ -27,6 +27,7 @@ #include "bineditor_global.h" #include "markup.h" +#include "bineditorservice.h" #include <QBasicTimer> #include <QMap> @@ -46,8 +47,11 @@ namespace Core { class IEditor; } namespace TextEditor { class FontSettings; } namespace BinEditor { +namespace Internal { -class BINEDITOR_EXPORT BinEditorWidget : public QAbstractScrollArea +class BinEditorWidgetPrivate; + +class BinEditorWidget : public QAbstractScrollArea { Q_OBJECT Q_PROPERTY(bool modified READ isModified WRITE setModified DESIGNABLE false) @@ -59,17 +63,19 @@ public: BinEditorWidget(QWidget *parent = 0); ~BinEditorWidget(); + EditorService *editorService() const; + quint64 baseAddress() const { return m_baseAddr; } - Q_INVOKABLE void setSizes(quint64 startAddr, qint64 range, int blockSize = 4096); + void setSizes(quint64 startAddr, qint64 range, int blockSize = 4096); int dataBlockSize() const { return m_blockSize; } QByteArray contents() const { return dataMid(0, m_size); } - Q_INVOKABLE void addData(quint64 block, const QByteArray &data); + void addData(quint64 addr, const QByteArray &data); bool newWindowRequestAllowed() const { return m_canRequestNewWindow; } - Q_INVOKABLE void updateContents(); + void updateContents(); bool save(QString *errorString, const QString &oldFileName, const QString &newFileName); void zoomIn(int range = 1); @@ -81,7 +87,7 @@ public: }; qint64 cursorPosition() const; - Q_INVOKABLE void setCursorPosition(qint64 pos, MoveMode moveMode = MoveAnchor); + void setCursorPosition(qint64 pos, MoveMode moveMode = MoveAnchor); void jumpToAddress(quint64 address); void setModified(bool); @@ -123,19 +129,13 @@ public: void setMarkup(const QList<Markup> &markup); void setNewWindowRequestAllowed(bool c); -Q_SIGNALS: +signals: void modificationChanged(bool modified); void undoAvailable(bool); void redoAvailable(bool); void cursorPositionChanged(int position); - void dataRequested(quint64 block); - void newWindowRequested(quint64 address); - void newRangeRequested(quint64 address); - void addWatchpointRequested(quint64 address, uint size); - void dataChanged(quint64 address, const QByteArray &data); - -protected: +private: void scrollContentsBy(int dx, int dy); void paintEvent(QPaintEvent *e); void resizeEvent(QResizeEvent *); @@ -150,7 +150,9 @@ protected: void timerEvent(QTimerEvent *); void contextMenuEvent(QContextMenuEvent *event); -private: + friend class BinEditorWidgetPrivate; + BinEditorWidgetPrivate *d; + typedef QMap<qint64, QByteArray> BlockMap; BlockMap m_data; BlockMap m_oldData; @@ -242,4 +244,5 @@ private: QList<Markup> m_markup; }; +} // namespace Internal } // namespace BinEditor |