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();