From 077cd6562e2b75f32ab4a8df372b605156b2cbf0 Mon Sep 17 00:00:00 2001 From: Le Tan Date: Thu, 4 Nov 2021 20:46:27 +0800 Subject: [PATCH] add debugger to Markdown web viewer by F12 --- src/core/buffer/buffer.cpp | 1 + src/core/configmgr.cpp | 6 +-- src/core/editorconfig.h | 1 + src/data/core/core.qrc | 1 + src/data/core/icons/debug_editor.svg | 1 + src/data/core/vnotex.json | 5 +- src/widgets/markdownviewwindow.cpp | 66 ++++++++++++++++++++++++- src/widgets/markdownviewwindow.h | 8 +++ src/widgets/viewwindow.cpp | 36 +++++++++++--- src/widgets/viewwindow.h | 6 +++ src/widgets/viewwindowtoolbarhelper.cpp | 7 +++ src/widgets/viewwindowtoolbarhelper.h | 3 +- src/widgets/webpage.cpp | 7 ++- src/widgets/webviewer.cpp | 5 ++ src/widgets/webviewer.h | 6 +-- 15 files changed, 141 insertions(+), 18 deletions(-) create mode 100644 src/data/core/icons/debug_editor.svg diff --git a/src/core/buffer/buffer.cpp b/src/core/buffer/buffer.cpp index ce3a02c4..0a9b9513 100644 --- a/src/core/buffer/buffer.cpp +++ b/src/core/buffer/buffer.cpp @@ -61,6 +61,7 @@ void Buffer::attachViewWindow(ViewWindow *p_win) void Buffer::detachViewWindow(ViewWindow *p_win) { + Q_UNUSED(p_win); Q_ASSERT(p_win != m_viewWindowToSync); --m_attachedViewWindowCount; diff --git a/src/core/configmgr.cpp b/src/core/configmgr.cpp index 69a2d9ee..90daa31d 100644 --- a/src/core/configmgr.cpp +++ b/src/core/configmgr.cpp @@ -25,7 +25,7 @@ using namespace vnotex; #ifndef QT_NO_DEBUG - #define VX_DEBUG_WEB + // #define VX_DEBUG_WEB #endif const QString ConfigMgr::c_orgName = "VNote"; @@ -171,7 +171,7 @@ bool ConfigMgr::checkAppConfig() #ifndef VX_DEBUG_WEB if (!needUpdate) { - return; + return false; } #endif @@ -215,7 +215,7 @@ bool ConfigMgr::checkAppConfig() FileUtils::copyFile(getConfigFilePath(Source::Default), mainConfigFilePath); FileUtils::copyDir(extraDataRoot + QStringLiteral("/web"), appConfigDir.filePath(QStringLiteral("web"))); - return needUpdate; + return false; } #else Q_ASSERT(needUpdate); diff --git a/src/core/editorconfig.h b/src/core/editorconfig.h index d15a1e6a..1031c57e 100644 --- a/src/core/editorconfig.h +++ b/src/core/editorconfig.h @@ -59,6 +59,7 @@ namespace vnotex FindPrevious, ApplySnippet, Tag, + Debug, MaxShortcut }; Q_ENUM(Shortcut) diff --git a/src/data/core/core.qrc b/src/data/core/core.qrc index d813cd9a..17dcb9bf 100644 --- a/src/data/core/core.qrc +++ b/src/data/core/core.qrc @@ -77,6 +77,7 @@ icons/maximize_restore.svg icons/close.svg icons/delete.svg + icons/debug_editor.svg icons/stay_on_top.svg icons/outline_editor.svg icons/find_replace_editor.svg diff --git a/src/data/core/icons/debug_editor.svg b/src/data/core/icons/debug_editor.svg new file mode 100644 index 00000000..515d0583 --- /dev/null +++ b/src/data/core/icons/debug_editor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/data/core/vnotex.json b/src/data/core/vnotex.json index 64c75f5a..19d06ce2 100644 --- a/src/data/core/vnotex.json +++ b/src/data/core/vnotex.json @@ -62,7 +62,7 @@ "OpenLastClosedFile" : "Ctrl+Shift+T" }, "toolbar_icon_size" : 16, - "docks_tabbar_icon_size" : 26, + "docks_tabbar_icon_size" : 24, "note_management" : { "external_node" : { "//comment" : "Wildcard patterns of files and folders to exclude as external files", @@ -119,7 +119,8 @@ "FindNext" : "F3", "FindPrevious" : "Shift+F3", "ApplySnippet" : "Ctrl+G, I", - "Tag" : "Ctrl+G, B" + "Tag" : "Ctrl+G, B", + "Debug" : "F12" }, "spell_check_auto_detect_language" : false, "spell_check_default_dictionary" : "en_US", diff --git a/src/widgets/markdownviewwindow.cpp b/src/widgets/markdownviewwindow.cpp index 4bec41c3..1f898699 100644 --- a/src/widgets/markdownviewwindow.cpp +++ b/src/widgets/markdownviewwindow.cpp @@ -126,10 +126,20 @@ void MarkdownViewWindow::setModeInternal(ViewWindowMode p_mode, bool p_syncBuffe case ViewWindowMode::Edit: { + if (m_debugViewer && m_debugViewer->isVisible()) { + toggleDebug(); + } + + bool hideViewer = true; if (!m_editor) { // We need viewer to preview. if (!m_viewer) { setupViewer(); + + // Must show the viewer to let it init with the correct DPI. + // Will hide it when viewerReady(). + m_viewer->show(); + hideViewer = false; } setupTextEditor(); @@ -143,8 +153,10 @@ void MarkdownViewWindow::setModeInternal(ViewWindowMode p_mode, bool p_syncBuffe m_editor->show(); m_editor->setFocus(); - Q_ASSERT(m_viewer); - m_viewer->hide(); + if (hideViewer) { + Q_ASSERT(m_viewer); + m_viewer->hide(); + } getMainStatusWidget()->setCurrentWidget(m_textEditorStatusWidget.get()); break; @@ -274,6 +286,10 @@ void MarkdownViewWindow::setupToolBar() m_editor->setInplacePreviewEnabled(p_checked); } }); + connect(this, &ViewWindow::modeChanged, + this, [this, act]() { + act->setEnabled(inModeCanInsert() && getBuffer()); + }); } addAction(toolBar, ViewWindowToolBarHelper::ImageHost); @@ -301,6 +317,14 @@ void MarkdownViewWindow::setupToolBar() ToolBarHelper::addSpacer(toolBar); addAction(toolBar, ViewWindowToolBarHelper::FindAndReplace); addAction(toolBar, ViewWindowToolBarHelper::Outline); + + { + auto act = addAction(toolBar, ViewWindowToolBarHelper::Debug); + connect(this, &ViewWindow::modeChanged, + this, [this, act]() { + act->setEnabled(m_mode != ViewWindowMode::Edit); + }); + } } void MarkdownViewWindow::setupTextEditor() @@ -459,6 +483,12 @@ void MarkdownViewWindow::setupViewer() this, [this](const QStringList &p_texts, int p_totalMatches, int p_currentMatchIndex) { this->showFindResult(p_texts, p_totalMatches, p_currentMatchIndex); }); + connect(adapter, &MarkdownViewerAdapter::viewerReady, + this, [this]() { + if (m_mode == ViewWindowMode::Edit) { + m_viewer->hide(); + } + }); } void MarkdownViewWindow::syncTextEditorFromBuffer(bool p_syncPositionFromReadMode) @@ -1187,3 +1217,35 @@ bool MarkdownViewWindow::updateConfigRevision() return changed; } + +void MarkdownViewWindow::toggleDebug() +{ + Q_ASSERT(m_viewer); + if (m_debugViewer) { + bool shouldEnable = !m_debugViewer->isVisible(); + m_debugViewer->setVisible(shouldEnable); + m_viewer->page()->setDevToolsPage(shouldEnable ? m_debugViewer->page() : nullptr); + } else { + setupDebugViewer(); + m_viewer->page()->setDevToolsPage(m_debugViewer->page()); + } +} + +void MarkdownViewWindow::setupDebugViewer() +{ + Q_ASSERT(!m_debugViewer); + + // Need a vertical QSplitter to hold the original QSplitter and the debug viewer. + auto mainSplitter = new QSplitter(this); + mainSplitter->setContentsMargins(0, 0, 0, 0); + mainSplitter->setOrientation(Qt::Vertical); + + replaceCentralWidget(mainSplitter); + + mainSplitter->addWidget(m_splitter); + mainSplitter->setFocusProxy(m_splitter); + + m_debugViewer = new WebViewer(VNoteX::getInst().getThemeMgr().getBaseBackground(), this); + m_debugViewer->resize(m_splitter->width(), m_splitter->height() / 2); + mainSplitter->addWidget(m_debugViewer); +} diff --git a/src/widgets/markdownviewwindow.h b/src/widgets/markdownviewwindow.h index df5b9cc7..29815561 100644 --- a/src/widgets/markdownviewwindow.h +++ b/src/widgets/markdownviewwindow.h @@ -7,6 +7,7 @@ class QSplitter; class QStackedWidget; +class QWebEngineView; namespace vte { @@ -76,6 +77,8 @@ namespace vnotex void handleFindAndReplaceWidgetOpened() Q_DECL_OVERRIDE; + void toggleDebug() Q_DECL_OVERRIDE; + protected: void syncEditorFromBuffer() Q_DECL_OVERRIDE; @@ -159,6 +162,8 @@ namespace vnotex bool updateConfigRevision(); + void setupDebugViewer(); + template static QSharedPointer headingsToOutline(const QVector &p_headings); @@ -181,6 +186,9 @@ namespace vnotex QSharedPointer m_mainStatusWidget; + // Used to debug web view. + QWebEngineView *m_debugViewer = nullptr; + // Managed by QObject. PreviewHelper *m_previewHelper = nullptr; diff --git a/src/widgets/viewwindow.cpp b/src/widgets/viewwindow.cpp index 03bef67e..eb79c2f4 100644 --- a/src/widgets/viewwindow.cpp +++ b/src/widgets/viewwindow.cpp @@ -237,7 +237,16 @@ void ViewWindow::setCentralWidget(QWidget *p_widget) m_mainLayout->insertWidget(1, m_centralWidget, 1); setFocusProxy(m_centralWidget); + m_centralWidget->show(); +} +void ViewWindow::replaceCentralWidget(QWidget *p_widget) +{ + Q_ASSERT(m_centralWidget); + m_mainLayout->replaceWidget(m_centralWidget, p_widget); + + m_centralWidget = p_widget; + setFocusProxy(m_centralWidget); m_centralWidget->show(); } @@ -248,14 +257,19 @@ void ViewWindow::addTopWidget(QWidget *p_widget) void ViewWindow::addBottomWidget(QWidget *p_widget) { - m_bottomLayout->addWidget(p_widget); + if (m_statusWidgetInBottomLayout) { + m_bottomLayout->insertWidget(m_bottomLayout->count() - 1, p_widget); + } else { + m_bottomLayout->addWidget(p_widget); + } } void ViewWindow::setStatusWidget(const QSharedPointer &p_widget) { m_statusWidget = p_widget; - m_bottomLayout->insertWidget(0, p_widget.data()); + m_bottomLayout->addWidget(p_widget.data()); p_widget->show(); + m_statusWidgetInBottomLayout = true; } QSharedPointer ViewWindow::statusWidget() @@ -272,6 +286,7 @@ void ViewWindow::setStatusWidgetVisible(bool p_visible) setStatusWidget(m_statusWidget); } else { m_statusWidget->hide(); + m_statusWidgetInBottomLayout = false; } } } @@ -468,10 +483,6 @@ QAction *ViewWindow::addAction(QToolBar *p_toolBar, ViewWindowToolBarHelper::Act case ViewWindowToolBarHelper::InplacePreview: { act = ViewWindowToolBarHelper::addAction(p_toolBar, p_action); - connect(this, &ViewWindow::modeChanged, - this, [this, act]() { - act->setEnabled(inModeCanInsert() && getBuffer()); - }); break; } @@ -497,6 +508,14 @@ QAction *ViewWindow::addAction(QToolBar *p_toolBar, ViewWindowToolBarHelper::Act break; } + case ViewWindowToolBarHelper::Debug: + { + act = ViewWindowToolBarHelper::addAction(p_toolBar, p_action); + connect(act, &QAction::triggered, + this, &ViewWindow::toggleDebug); + break; + } + default: Q_ASSERT(false); break; @@ -1276,3 +1295,8 @@ bool ViewWindow::isSessionEnabled() const { return m_sessionEnabled; } + +void ViewWindow::toggleDebug() +{ + qDebug() << "debug is not supported"; +} diff --git a/src/widgets/viewwindow.h b/src/widgets/viewwindow.h index 7237739d..a391c19b 100644 --- a/src/widgets/viewwindow.h +++ b/src/widgets/viewwindow.h @@ -176,6 +176,8 @@ namespace vnotex virtual void handleFindAndReplaceWidgetOpened(); + virtual void toggleDebug(); + protected: bool eventFilter(QObject *p_obj, QEvent *p_event) Q_DECL_OVERRIDE; @@ -186,6 +188,8 @@ namespace vnotex protected: void setCentralWidget(QWidget *p_widget); + void replaceCentralWidget(QWidget *p_widget); + void addTopWidget(QWidget *p_widget); void addToolBar(QToolBar *p_bar); @@ -367,6 +371,8 @@ namespace vnotex QActionGroup *m_imageHostActionGroup = nullptr; + bool m_statusWidgetInBottomLayout = false; + static QIcon s_savedIcon; static QIcon s_modifiedIcon; }; diff --git a/src/widgets/viewwindowtoolbarhelper.cpp b/src/widgets/viewwindowtoolbarhelper.cpp index 931baa22..6319f957 100644 --- a/src/widgets/viewwindowtoolbarhelper.cpp +++ b/src/widgets/viewwindowtoolbarhelper.cpp @@ -393,6 +393,13 @@ QAction *ViewWindowToolBarHelper::addAction(QToolBar *p_tb, Action p_action) break; } + case Action::Debug: + { + act = p_tb->addAction(ToolBarHelper::generateIcon("debug_editor.svg"), ViewWindow::tr("Debug")); + addActionShortcut(act, editorConfig.getShortcut(Shortcut::Debug), viewWindow); + break; + } + default: Q_ASSERT(false); break; diff --git a/src/widgets/viewwindowtoolbarhelper.h b/src/widgets/viewwindowtoolbarhelper.h index 0e1ebf14..108eefbe 100644 --- a/src/widgets/viewwindowtoolbarhelper.h +++ b/src/widgets/viewwindowtoolbarhelper.h @@ -46,7 +46,8 @@ namespace vnotex FindAndReplace, SectionNumber, InplacePreview, - ImageHost + ImageHost, + Debug }; static QAction *addAction(QToolBar *p_tb, Action p_action); diff --git a/src/widgets/webpage.cpp b/src/widgets/webpage.cpp index 89754164..bfcc5237 100644 --- a/src/widgets/webpage.cpp +++ b/src/widgets/webpage.cpp @@ -23,9 +23,14 @@ bool WebPage::acceptNavigationRequest(const QUrl &p_url, return false; } if (!p_isMainFrame) { return true; - } else if (p_url.scheme() == QStringLiteral("data")) { + } + + const auto scheme = p_url.scheme(); + if (scheme == QStringLiteral("data")) { // Qt 5.12 and above will trigger this when calling QWebEngineView::setHtml(). return true; + } else if (scheme == QStringLiteral("chrome-devtools")) { + return true; } WidgetUtils::openUrlByDesktop(p_url); diff --git a/src/widgets/webviewer.cpp b/src/widgets/webviewer.cpp index e98a215a..4073663b 100644 --- a/src/widgets/webviewer.cpp +++ b/src/widgets/webviewer.cpp @@ -30,6 +30,11 @@ WebViewer::WebViewer(const QColor &p_background, } } +WebViewer::WebViewer(const QColor &p_background, QWidget *p_parent) + : WebViewer(p_background, 1.0, p_parent) +{ +} + WebViewer::~WebViewer() { } diff --git a/src/widgets/webviewer.h b/src/widgets/webviewer.h index e4c7f222..e4441661 100644 --- a/src/widgets/webviewer.h +++ b/src/widgets/webviewer.h @@ -9,9 +9,9 @@ namespace vnotex { Q_OBJECT public: - explicit WebViewer(const QColor &p_background, - qreal p_zoomFactor, - QWidget *p_parent = nullptr); + WebViewer(const QColor &p_background, qreal p_zoomFactor, QWidget *p_parent = nullptr); + + WebViewer(const QColor &p_background, QWidget *p_parent = nullptr); virtual ~WebViewer();