mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 05:49:53 +08:00
MarkdownEditor: support EditPreview mode
This commit is contained in:
parent
86df5c39a2
commit
6b1f00880e
@ -1 +1 @@
|
||||
Subproject commit 00b52913fe8f4ccf5ed5a0cbd3493b94fe354b25
|
||||
Subproject commit 58ad5d96359e2ab3f8f9255bd9194a0ebf1e6798
|
@ -143,7 +143,7 @@ namespace vnotex
|
||||
int m_historyMaxCount = 100;
|
||||
|
||||
// Whether store history in each notebook.
|
||||
bool m_perNotebookHistoryEnabled = true;
|
||||
bool m_perNotebookHistoryEnabled = false;
|
||||
|
||||
static QStringList s_availableLocales;
|
||||
};
|
||||
|
@ -94,8 +94,6 @@ namespace vnotex
|
||||
{
|
||||
Read,
|
||||
Edit,
|
||||
FullPreview,
|
||||
FocusPreview,
|
||||
Invalid
|
||||
};
|
||||
|
||||
|
@ -118,4 +118,5 @@ QString MainConfig::getVersion(const QJsonObject &p_jobj)
|
||||
void MainConfig::doVersionSpecificOverride()
|
||||
{
|
||||
// In a new version, we may want to change one value by force.
|
||||
m_coreConfig->m_perNotebookHistoryEnabled = false;
|
||||
}
|
||||
|
@ -73,6 +73,8 @@ void MarkdownEditorConfig::init(const QJsonObject &p_app, const QJsonObject &p_u
|
||||
m_inplacePreviewSources |= stringToInplacePreviewSource(src);
|
||||
}
|
||||
}
|
||||
|
||||
m_editViewMode = stringToEditViewMode(READSTR(QStringLiteral("edit_view_mode")));
|
||||
}
|
||||
|
||||
QJsonObject MarkdownEditorConfig::toJson() const
|
||||
@ -122,6 +124,8 @@ QJsonObject MarkdownEditorConfig::toJson() const
|
||||
obj[QStringLiteral("inplace_preview_sources")] = srcs.join(QLatin1Char(';'));
|
||||
}
|
||||
|
||||
obj[QStringLiteral("edit_view_mode")] = editViewModeToString(m_editViewMode);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
@ -519,3 +523,34 @@ void MarkdownEditorConfig::setInplacePreviewSources(InplacePreviewSources p_src)
|
||||
{
|
||||
updateConfig(m_inplacePreviewSources, p_src, this);
|
||||
}
|
||||
|
||||
QString MarkdownEditorConfig::editViewModeToString(EditViewMode p_mode) const
|
||||
{
|
||||
switch (p_mode) {
|
||||
case EditViewMode::EditPreview:
|
||||
return QStringLiteral("editpreview");
|
||||
|
||||
default:
|
||||
return QStringLiteral("editonly");
|
||||
}
|
||||
}
|
||||
|
||||
MarkdownEditorConfig::EditViewMode MarkdownEditorConfig::stringToEditViewMode(const QString &p_str) const
|
||||
{
|
||||
auto mode = p_str.toLower();
|
||||
if (mode == QStringLiteral("editpreview")) {
|
||||
return EditViewMode::EditPreview;
|
||||
} else {
|
||||
return EditViewMode::EditOnly;
|
||||
}
|
||||
}
|
||||
|
||||
MarkdownEditorConfig::EditViewMode MarkdownEditorConfig::getEditViewMode() const
|
||||
{
|
||||
return m_editViewMode;
|
||||
}
|
||||
|
||||
void MarkdownEditorConfig::setEditViewMode(EditViewMode p_mode)
|
||||
{
|
||||
updateConfig(m_editViewMode, p_mode, this);
|
||||
}
|
||||
|
@ -39,6 +39,12 @@ namespace vnotex
|
||||
};
|
||||
Q_DECLARE_FLAGS(InplacePreviewSources, InplacePreviewSource);
|
||||
|
||||
enum EditViewMode
|
||||
{
|
||||
EditOnly,
|
||||
EditPreview
|
||||
};
|
||||
|
||||
MarkdownEditorConfig(ConfigMgr *p_mgr,
|
||||
IConfig *p_topConfig,
|
||||
const QSharedPointer<TextEditorConfig> &p_textEditorConfig);
|
||||
@ -130,6 +136,9 @@ namespace vnotex
|
||||
InplacePreviewSources getInplacePreviewSources() const;
|
||||
void setInplacePreviewSources(InplacePreviewSources p_src);
|
||||
|
||||
EditViewMode getEditViewMode() const;
|
||||
void setEditViewMode(EditViewMode p_mode);
|
||||
|
||||
private:
|
||||
friend class MainConfig;
|
||||
|
||||
@ -148,6 +157,9 @@ namespace vnotex
|
||||
QString inplacePreviewSourceToString(InplacePreviewSource p_src) const;
|
||||
InplacePreviewSource stringToInplacePreviewSource(const QString &p_str) const;
|
||||
|
||||
QString editViewModeToString(EditViewMode p_mode) const;
|
||||
EditViewMode stringToEditViewMode(const QString &p_str) const;
|
||||
|
||||
QSharedPointer<TextEditorConfig> m_textEditorConfig;
|
||||
|
||||
WebResource m_viewerResource;
|
||||
@ -227,6 +239,9 @@ namespace vnotex
|
||||
QString m_editorOverriddenFontFamily;
|
||||
|
||||
InplacePreviewSources m_inplacePreviewSources = InplacePreviewSource::NoInplacePreview;
|
||||
|
||||
// View mode in edit mode.
|
||||
EditViewMode m_editViewMode = EditViewMode::EditOnly;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -826,7 +826,9 @@ bool VXNotebookConfigMgr::isBuiltInFolder(const Node *p_node, const QString &p_n
|
||||
if (name == nb->getImageFolder().toLower()
|
||||
|| name == nb->getAttachmentFolder().toLower()
|
||||
|| name == QStringLiteral("_v_images")
|
||||
|| name == QStringLiteral("_v_attachments")) {
|
||||
|| name == QStringLiteral("_v_attachments")
|
||||
|| name == QStringLiteral("vx_images")
|
||||
|| name == QStringLiteral("vx_attachments")) {
|
||||
return true;
|
||||
}
|
||||
return BundleNotebookConfigMgr::isBuiltInFolder(p_node, p_name);
|
||||
|
@ -13,6 +13,7 @@
|
||||
<file>icons/discard_editor.svg</file>
|
||||
<file>icons/edit_editor.svg</file>
|
||||
<file>icons/read_editor.svg</file>
|
||||
<file>icons/view_mode_editor.svg</file>
|
||||
<file>icons/expand.svg</file>
|
||||
<file>icons/fullscreen.svg</file>
|
||||
<file>icons/tag_dock.svg</file>
|
||||
|
1
src/data/core/icons/view_mode_editor.svg
Normal file
1
src/data/core/icons/view_mode_editor.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1636336824519" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2399" width="512" height="512" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M896 809.984l0-553.984-384 0 0 553.984 384 0zM896 169.984q34.005333 0 59.989333 25.984t25.984 59.989333l0 553.984q0 34.005333-25.984 59.989333t-59.989333 25.984l-768 0q-34.005333 0-59.989333-25.984t-25.984-59.989333l0-553.984q0-34.005333 25.984-59.989333t59.989333-25.984l768 0zM553.984 617.984l299.989333 0 0 64-299.989333 0 0-64zM553.984 406.016l299.989333 0 0 64-299.989333 0 0-64zM553.984 512l299.989333 0 0 64-299.989333 0 0-64z" p-id="2400" fill="#000000"></path></svg>
|
After Width: | Height: | Size: 852 B |
@ -4821,7 +4821,7 @@ Description: %3</source>
|
||||
<message>
|
||||
<location filename="../../../widgets/dialogs/settings/texteditorpage.cpp" line="57"/>
|
||||
<source>Normal</source>
|
||||
<translation>正常</translation>
|
||||
<translation>普通</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../../widgets/dialogs/settings/texteditorpage.cpp" line="58"/>
|
||||
|
@ -76,7 +76,7 @@
|
||||
"check_for_updates_on_start" : true,
|
||||
"//comment" : "Max count of the history items for each notebook and session config",
|
||||
"history_max_count" : 100,
|
||||
"per_notebook_history" : true
|
||||
"per_notebook_history" : false
|
||||
},
|
||||
"editor" : {
|
||||
"core": {
|
||||
@ -357,7 +357,9 @@
|
||||
"editor_overridden_font_family" : "",
|
||||
"//comment" : "Sources to enable inplace preview, separated by ;",
|
||||
"//comment" : "imagelink/codeblock/math",
|
||||
"inplace_preview_sources" : "imagelink;codeblock;math"
|
||||
"inplace_preview_sources" : "imagelink;codeblock;math",
|
||||
"//comment" : "view mode of edit mode: editonly/editpreview",
|
||||
"edit_view_mode" : "editonly"
|
||||
},
|
||||
"image_host" : {
|
||||
"hosts" : [
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <QLineEdit>
|
||||
#include <QLayout>
|
||||
#include <QPushButton>
|
||||
#include <QSplitter>
|
||||
|
||||
#include <core/global.h>
|
||||
|
||||
@ -418,3 +419,42 @@ void WidgetUtils::setContentsMargins(QLayout *p_layout)
|
||||
// Use 0 bottom margin to align dock widgets with the content area.
|
||||
p_layout->setContentsMargins(CONTENTS_MARGIN, CONTENTS_MARGIN, CONTENTS_MARGIN, 0);
|
||||
}
|
||||
|
||||
bool WidgetUtils::distributeWidgetsOfSplitter(QSplitter *p_splitter)
|
||||
{
|
||||
if (!p_splitter) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (p_splitter->count() == 0) {
|
||||
return false;
|
||||
} else if (p_splitter->count() == 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto sizes = p_splitter->sizes();
|
||||
int totalWidth = 0;
|
||||
for (auto sz : sizes) {
|
||||
totalWidth += sz;
|
||||
}
|
||||
|
||||
int newWidth = totalWidth / sizes.size();
|
||||
if (newWidth == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool changed = false;
|
||||
for (int i = 0; i < sizes.size(); ++i) {
|
||||
if (sizes[i] != newWidth) {
|
||||
sizes[i] = newWidth;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
p_splitter->setSizes(sizes);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ class QShortcut;
|
||||
class QLineEdit;
|
||||
class QLayout;
|
||||
class QPushButton;
|
||||
class QSplitter;
|
||||
|
||||
namespace vnotex
|
||||
{
|
||||
@ -86,6 +87,8 @@ namespace vnotex
|
||||
|
||||
static void setContentsMargins(QLayout *p_layout);
|
||||
|
||||
static bool distributeWidgetsOfSplitter(QSplitter *p_splitter);
|
||||
|
||||
private:
|
||||
static void resizeToHideScrollBar(QScrollArea *p_scroll, bool p_vertical, bool p_horizontal);
|
||||
};
|
||||
|
@ -251,10 +251,10 @@ bool ManageNotebooksDialog::saveChangesToNotebook()
|
||||
return true;
|
||||
}
|
||||
|
||||
void ManageNotebooksDialog::closeNotebook(const Notebook *p_notebook)
|
||||
bool ManageNotebooksDialog::closeNotebook(const Notebook *p_notebook)
|
||||
{
|
||||
if (!p_notebook) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
int ret = MessageBoxHelper::questionOkCancel(MessageBoxHelper::Question,
|
||||
@ -264,7 +264,7 @@ void ManageNotebooksDialog::closeNotebook(const Notebook *p_notebook)
|
||||
tr("Notebook location: %1").arg(p_notebook->getRootFolderAbsolutePath()),
|
||||
this);
|
||||
if (ret != QMessageBox::Ok) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
@ -274,11 +274,10 @@ void ManageNotebooksDialog::closeNotebook(const Notebook *p_notebook)
|
||||
MessageBoxHelper::notify(MessageBoxHelper::Warning,
|
||||
tr("Failed to close notebook (%1)").arg(p_e.what()),
|
||||
this);
|
||||
loadNotebooks(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
loadNotebooks(nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ManageNotebooksDialog::removeNotebook(const Notebook *p_notebook)
|
||||
@ -298,9 +297,9 @@ void ManageNotebooksDialog::removeNotebook(const Notebook *p_notebook)
|
||||
|
||||
const auto rootFolder = p_notebook->getRootFolderAbsolutePath();
|
||||
|
||||
closeNotebook(p_notebook);
|
||||
|
||||
WidgetUtils::openUrlByDesktop(QUrl::fromLocalFile(rootFolder));
|
||||
if (closeNotebook(p_notebook)) {
|
||||
WidgetUtils::openUrlByDesktop(QUrl::fromLocalFile(rootFolder));
|
||||
}
|
||||
}
|
||||
|
||||
bool ManageNotebooksDialog::checkUnsavedChanges()
|
||||
|
@ -45,7 +45,7 @@ namespace vnotex
|
||||
|
||||
Notebook *getNotebookFromItem(const QListWidgetItem *p_item) const;
|
||||
|
||||
void closeNotebook(const Notebook *p_notebook);
|
||||
bool closeNotebook(const Notebook *p_notebook);
|
||||
|
||||
void removeNotebook(const Notebook *p_notebook);
|
||||
|
||||
|
@ -74,7 +74,7 @@ void MarkdownViewerAdapter::setText(int p_revision,
|
||||
const QString &p_text,
|
||||
int p_lineNumber)
|
||||
{
|
||||
if (p_revision == m_revision) {
|
||||
if (p_revision == m_revision && p_revision != 0) {
|
||||
// Only sync line number position.
|
||||
scrollToPosition(Position(p_lineNumber, ""));
|
||||
return;
|
||||
@ -92,16 +92,9 @@ void MarkdownViewerAdapter::setText(int p_revision,
|
||||
}
|
||||
}
|
||||
|
||||
void MarkdownViewerAdapter::setText(const QString &p_text)
|
||||
void MarkdownViewerAdapter::setText(const QString &p_text, int p_lineNumber)
|
||||
{
|
||||
m_revision = 0;
|
||||
if (m_viewerReady) {
|
||||
emit textUpdated(p_text);
|
||||
} else {
|
||||
m_pendingActions.append([this, p_text]() {
|
||||
emit textUpdated(p_text);
|
||||
});
|
||||
}
|
||||
setText(0, p_text, p_lineNumber);
|
||||
}
|
||||
|
||||
void MarkdownViewerAdapter::setReady(bool p_ready)
|
||||
|
@ -87,7 +87,8 @@ namespace vnotex
|
||||
const QString &p_text,
|
||||
int p_lineNumber);
|
||||
|
||||
void setText(const QString &p_text);
|
||||
// @p_lineNumber: the line number needed to sync, -1 for invalid.
|
||||
void setText(const QString &p_text, int p_lineNumber = -1);
|
||||
|
||||
void scrollToPosition(const Position &p_pos);
|
||||
|
||||
|
@ -525,11 +525,10 @@ void MainWindow::focusViewArea()
|
||||
void MainWindow::setupToolBar()
|
||||
{
|
||||
const int sz = ConfigMgr::getInst().getCoreConfig().getToolBarIconSize();
|
||||
const QSize iconSize(sz, sz);
|
||||
|
||||
if (isFrameless()) {
|
||||
auto toolBar = new TitleToolBar(tr("Global"), this);
|
||||
toolBar->setIconSize(iconSize);
|
||||
toolBar->setIconSize(QSize(sz + 4, sz + 4));
|
||||
ToolBarHelper::setupToolBars(this, toolBar);
|
||||
toolBar->addTitleBarIcons(ToolBarHelper::generateIcon(QStringLiteral("minimize.svg")),
|
||||
ToolBarHelper::generateIcon(QStringLiteral("maximize.svg")),
|
||||
@ -540,7 +539,7 @@ void MainWindow::setupToolBar()
|
||||
toolBar, &TitleToolBar::updateMaximizeAct);
|
||||
} else {
|
||||
auto toolBar = new QToolBar(tr("Global"), this);
|
||||
toolBar->setIconSize(iconSize);
|
||||
toolBar->setIconSize(QSize(sz, sz));
|
||||
ToolBarHelper::setupToolBars(this, toolBar);
|
||||
}
|
||||
|
||||
|
@ -9,15 +9,17 @@
|
||||
#include <QLabel>
|
||||
#include <QApplication>
|
||||
#include <QProgressDialog>
|
||||
#include <QMenu>
|
||||
#include <QActionGroup>
|
||||
|
||||
#include <core/fileopenparameters.h>
|
||||
#include <core/editorconfig.h>
|
||||
#include <core/markdowneditorconfig.h>
|
||||
#include <core/htmltemplatehelper.h>
|
||||
#include <vtextedit/vtextedit.h>
|
||||
#include <vtextedit/pegmarkdownhighlighter.h>
|
||||
#include <vtextedit/markdowneditorconfig.h>
|
||||
#include <utils/pathutils.h>
|
||||
#include <utils/widgetutils.h>
|
||||
#include <buffer/markdownbuffer.h>
|
||||
#include <core/vnotex.h>
|
||||
#include <core/thememgr.h>
|
||||
@ -130,7 +132,6 @@ void MarkdownViewWindow::setModeInternal(ViewWindowMode p_mode, bool p_syncBuffe
|
||||
toggleDebug();
|
||||
}
|
||||
|
||||
bool hideViewer = m_viewerReady;
|
||||
if (!m_editor) {
|
||||
// We need viewer to preview.
|
||||
if (!m_viewer) {
|
||||
@ -139,7 +140,6 @@ void MarkdownViewWindow::setModeInternal(ViewWindowMode p_mode, bool p_syncBuffe
|
||||
// Must show the viewer to let it init with the correct DPI.
|
||||
// Will hide it when viewerReady().
|
||||
m_viewer->show();
|
||||
hideViewer = false;
|
||||
}
|
||||
|
||||
setupTextEditor();
|
||||
@ -153,10 +153,7 @@ void MarkdownViewWindow::setModeInternal(ViewWindowMode p_mode, bool p_syncBuffe
|
||||
m_editor->show();
|
||||
m_editor->setFocus();
|
||||
|
||||
if (hideViewer) {
|
||||
Q_ASSERT(m_viewer);
|
||||
m_viewer->hide();
|
||||
}
|
||||
setEditViewMode(m_editViewMode);
|
||||
|
||||
getMainStatusWidget()->setCurrentWidget(m_textEditorStatusWidget.get());
|
||||
break;
|
||||
@ -167,7 +164,7 @@ void MarkdownViewWindow::setModeInternal(ViewWindowMode p_mode, bool p_syncBuffe
|
||||
break;
|
||||
}
|
||||
|
||||
// Let editor to show or scrollToLine will not work correctly.
|
||||
// Let editor to show, or scrollToLine will not work correctly.
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
if (p_syncBuffer) {
|
||||
@ -267,6 +264,7 @@ void MarkdownViewWindow::setupToolBar()
|
||||
|
||||
addAction(toolBar, ViewWindowToolBarHelper::EditReadDiscard);
|
||||
addAction(toolBar, ViewWindowToolBarHelper::Save);
|
||||
addAction(toolBar, ViewWindowToolBarHelper::ViewMode);
|
||||
|
||||
toolBar->addSeparator();
|
||||
|
||||
@ -336,10 +334,13 @@ void MarkdownViewWindow::setupTextEditor()
|
||||
|
||||
updateConfigRevision();
|
||||
|
||||
m_editViewMode = markdownEditorConfig.getEditViewMode();
|
||||
|
||||
m_editor = new MarkdownEditor(markdownEditorConfig,
|
||||
createMarkdownEditorConfig(editorConfig, markdownEditorConfig),
|
||||
createMarkdownEditorParameters(editorConfig, markdownEditorConfig),
|
||||
this);
|
||||
// Always editor comes first.
|
||||
m_splitter->insertWidget(0, m_editor);
|
||||
|
||||
TextViewWindowHelper::connectEditor(this);
|
||||
@ -486,8 +487,9 @@ void MarkdownViewWindow::setupViewer()
|
||||
connect(adapter, &MarkdownViewerAdapter::viewerReady,
|
||||
this, [this]() {
|
||||
m_viewerReady = true;
|
||||
|
||||
if (m_mode == ViewWindowMode::Edit) {
|
||||
m_viewer->hide();
|
||||
setEditViewMode(m_editViewMode);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -623,7 +625,7 @@ EditorMarkdownViewerAdapter *MarkdownViewWindow::adapter() const
|
||||
|
||||
int MarkdownViewWindow::getEditLineNumber() const
|
||||
{
|
||||
if (m_previousMode == ViewWindowMode::Edit || m_previousMode == ViewWindowMode::FocusPreview) {
|
||||
if (m_previousMode == ViewWindowMode::Edit) {
|
||||
if (m_editor) {
|
||||
return m_editor->getTopLine();
|
||||
}
|
||||
@ -1153,10 +1155,6 @@ QString MarkdownViewWindow::selectedText() const
|
||||
return m_viewer->selectedText();
|
||||
|
||||
case ViewWindowMode::Edit:
|
||||
Q_FALLTHROUGH();
|
||||
case ViewWindowMode::FullPreview:
|
||||
Q_FALLTHROUGH();
|
||||
case ViewWindowMode::FocusPreview:
|
||||
Q_ASSERT(m_editor);
|
||||
return m_editor->getTextEdit()->selectedText();
|
||||
|
||||
@ -1250,3 +1248,111 @@ void MarkdownViewWindow::setupDebugViewer()
|
||||
m_debugViewer->resize(m_splitter->width(), m_splitter->height() / 2);
|
||||
mainSplitter->addWidget(m_debugViewer);
|
||||
}
|
||||
|
||||
void MarkdownViewWindow::updateViewModeMenu(QMenu *p_menu)
|
||||
{
|
||||
p_menu->clear();
|
||||
|
||||
if (isReadMode()) {
|
||||
auto act = p_menu->addAction(tr("View Mode Not Supported In Read Mode"));
|
||||
act->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_viewModeActionGroup) {
|
||||
m_viewModeActionGroup = new QActionGroup(this);
|
||||
connect(m_viewModeActionGroup, &QActionGroup::triggered,
|
||||
this, [this](QAction *act) {
|
||||
auto mode = static_cast<MarkdownEditorConfig::EditViewMode>(act->data().toInt());
|
||||
if (mode != m_editViewMode) {
|
||||
ConfigMgr::getInst().getEditorConfig().getMarkdownEditorConfig().setEditViewMode(mode);
|
||||
setEditViewMode(mode);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
auto act = p_menu->addAction(tr("Edit Only"));
|
||||
act->setCheckable(true);
|
||||
act->setData(static_cast<int>(MarkdownEditorConfig::EditViewMode::EditOnly));
|
||||
m_viewModeActionGroup->addAction(act);
|
||||
|
||||
if (act->data().toInt() == m_editViewMode) {
|
||||
act->setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto act = p_menu->addAction(tr("Edit with Preview"));
|
||||
act->setCheckable(true);
|
||||
act->setData(static_cast<int>(MarkdownEditorConfig::EditViewMode::EditPreview));
|
||||
m_viewModeActionGroup->addAction(act);
|
||||
|
||||
if (act->data().toInt() == m_editViewMode) {
|
||||
act->setChecked(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MarkdownViewWindow::setEditViewMode(MarkdownEditorConfig::EditViewMode p_mode)
|
||||
{
|
||||
Q_ASSERT(m_mode == ViewWindowMode::Edit);
|
||||
|
||||
m_editViewMode = p_mode;
|
||||
|
||||
switch (p_mode) {
|
||||
case MarkdownEditorConfig::EditViewMode::EditOnly:
|
||||
{
|
||||
if (m_viewerReady) {
|
||||
m_viewer->hide();
|
||||
}
|
||||
|
||||
disconnect(m_editor->getTextEdit(), &vte::VTextEdit::contentsChanged,
|
||||
this, &MarkdownViewWindow::syncEditorContentsToPreview);
|
||||
disconnect(m_editor, &MarkdownEditor::topLineChanged,
|
||||
this, &MarkdownViewWindow::syncEditorPositionToPreview);
|
||||
break;
|
||||
}
|
||||
|
||||
case MarkdownEditorConfig::EditViewMode::EditPreview:
|
||||
{
|
||||
m_viewer->show();
|
||||
WidgetUtils::distributeWidgetsOfSplitter(m_splitter);
|
||||
|
||||
if (m_viewerReady) {
|
||||
connect(m_editor->getTextEdit(), &vte::VTextEdit::contentsChanged,
|
||||
this, &MarkdownViewWindow::syncEditorContentsToPreview,
|
||||
Qt::UniqueConnection);
|
||||
connect(m_editor, &MarkdownEditor::topLineChanged,
|
||||
this, &MarkdownViewWindow::syncEditorPositionToPreview,
|
||||
Qt::UniqueConnection);
|
||||
|
||||
syncEditorContentsToPreview();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MarkdownViewWindow::syncEditorContentsToPreview()
|
||||
{
|
||||
if (isReadMode() || m_editViewMode == MarkdownEditorConfig::EditViewMode::EditOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
adapter()->setText(m_editor->getText(), m_editor->getTopLine());
|
||||
}
|
||||
|
||||
void MarkdownViewWindow::syncEditorPositionToPreview()
|
||||
{
|
||||
if (isReadMode() || m_editViewMode == MarkdownEditorConfig::EditViewMode::EditOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
adapter()->scrollToPosition(MarkdownViewerAdapter::Position(m_editor->getTopLine(), QString()));
|
||||
}
|
||||
|
@ -5,9 +5,12 @@
|
||||
|
||||
#include <QScopedPointer>
|
||||
|
||||
#include <core/markdowneditorconfig.h>
|
||||
|
||||
class QSplitter;
|
||||
class QStackedWidget;
|
||||
class QWebEngineView;
|
||||
class QActionGroup;
|
||||
|
||||
namespace vte
|
||||
{
|
||||
@ -22,7 +25,6 @@ namespace vnotex
|
||||
class EditorMarkdownViewerAdapter;
|
||||
class PreviewHelper;
|
||||
struct Outline;
|
||||
class MarkdownEditorConfig;
|
||||
class EditorConfig;
|
||||
class ImageHost;
|
||||
class SearchToken;
|
||||
@ -98,6 +100,8 @@ namespace vnotex
|
||||
|
||||
QString selectedText() const Q_DECL_OVERRIDE;
|
||||
|
||||
void updateViewModeMenu(QMenu *p_menu) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
void setupUI();
|
||||
|
||||
@ -164,6 +168,12 @@ namespace vnotex
|
||||
|
||||
void setupDebugViewer();
|
||||
|
||||
void setEditViewMode(MarkdownEditorConfig::EditViewMode p_mode);
|
||||
|
||||
void syncEditorContentsToPreview();
|
||||
|
||||
void syncEditorPositionToPreview();
|
||||
|
||||
template <class T>
|
||||
static QSharedPointer<Outline> headingsToOutline(const QVector<T> &p_headings);
|
||||
|
||||
@ -210,6 +220,10 @@ namespace vnotex
|
||||
ImageHost *m_imageHost = nullptr;
|
||||
|
||||
bool m_viewerReady = false;
|
||||
|
||||
QActionGroup *m_viewModeActionGroup = nullptr;
|
||||
|
||||
MarkdownEditorConfig::EditViewMode m_editViewMode = MarkdownEditorConfig::EditViewMode::EditOnly;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -596,30 +596,10 @@ QSplitter *ViewArea::tryGetParentSplitter(const QWidget *p_widget) const
|
||||
|
||||
void ViewArea::distributeViewSplitsOfSplitter(QSplitter *p_splitter)
|
||||
{
|
||||
if (!p_splitter || p_splitter->count() <= 1) {
|
||||
if (!WidgetUtils::distributeWidgetsOfSplitter(p_splitter)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Distribute the direct children of splitter.
|
||||
{
|
||||
auto sizes = p_splitter->sizes();
|
||||
int totalWidth = 0;
|
||||
for (auto sz : sizes) {
|
||||
totalWidth += sz;
|
||||
}
|
||||
|
||||
int newWidth = totalWidth / sizes.size();
|
||||
if (newWidth <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < sizes.size(); ++i) {
|
||||
sizes[i] = newWidth;
|
||||
}
|
||||
|
||||
p_splitter->setSizes(sizes);
|
||||
}
|
||||
|
||||
// Distribute child splitter.
|
||||
for (int i = 0; i < p_splitter->count(); ++i) {
|
||||
auto childSplitter = dynamic_cast<QSplitter *>(p_splitter->widget(i));
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "editors/statuswidget.h"
|
||||
#include "propertydefs.h"
|
||||
#include "floatingwidget.h"
|
||||
#include "widgetsfactory.h"
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
@ -341,6 +342,25 @@ QAction *ViewWindow::addAction(QToolBar *p_toolBar, ViewWindowToolBarHelper::Act
|
||||
break;
|
||||
}
|
||||
|
||||
case ViewWindowToolBarHelper::ViewMode:
|
||||
{
|
||||
act = ViewWindowToolBarHelper::addAction(p_toolBar, p_action);
|
||||
connect(this, &ViewWindow::bufferChanged,
|
||||
this, [this, act]() {
|
||||
act->setEnabled(getBuffer());
|
||||
});
|
||||
|
||||
auto toolBtn = dynamic_cast<QToolButton *>(p_toolBar->widgetForAction(act));
|
||||
Q_ASSERT(toolBtn);
|
||||
auto menu = WidgetsFactory::createMenu(p_toolBar);
|
||||
toolBtn->setMenu(menu);
|
||||
connect(menu, &QMenu::aboutToShow,
|
||||
this, [this, menu]() {
|
||||
updateViewModeMenu(menu);
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case ViewWindowToolBarHelper::TypeHeading:
|
||||
{
|
||||
act = ViewWindowToolBarHelper::addAction(p_toolBar, p_action);
|
||||
@ -675,7 +695,7 @@ void ViewWindow::discardChangesAndRead()
|
||||
|
||||
bool ViewWindow::inModeCanInsert() const
|
||||
{
|
||||
return m_mode == ViewWindowMode::Edit || m_mode == ViewWindowMode::FocusPreview || m_mode == ViewWindowMode::FullPreview;
|
||||
return m_mode == ViewWindowMode::Edit;
|
||||
}
|
||||
|
||||
void ViewWindow::handleTypeAction(TypeAction p_action)
|
||||
@ -1300,3 +1320,11 @@ void ViewWindow::toggleDebug()
|
||||
{
|
||||
qDebug() << "debug is not supported";
|
||||
}
|
||||
|
||||
void ViewWindow::updateViewModeMenu(QMenu *p_menu)
|
||||
{
|
||||
p_menu->clear();
|
||||
|
||||
auto act = p_menu->addAction(tr("View Mode Not Supported"));
|
||||
act->setEnabled(false);
|
||||
}
|
||||
|
@ -252,6 +252,8 @@ namespace vnotex
|
||||
|
||||
virtual QPoint getFloatingWidgetPosition();
|
||||
|
||||
virtual void updateViewModeMenu(QMenu *p_menu);
|
||||
|
||||
static QToolBar *createToolBar(QWidget *p_parent = nullptr);
|
||||
|
||||
// The revision of the buffer of the last sync content.
|
||||
|
@ -118,6 +118,18 @@ QAction *ViewWindowToolBarHelper::addAction(QToolBar *p_tb, Action p_action)
|
||||
break;
|
||||
}
|
||||
|
||||
case Action::ViewMode:
|
||||
{
|
||||
act = p_tb->addAction(ToolBarHelper::generateIcon("view_mode_editor.svg"),
|
||||
ViewWindow::tr("View Mode"));
|
||||
|
||||
auto toolBtn = dynamic_cast<QToolButton *>(p_tb->widgetForAction(act));
|
||||
Q_ASSERT(toolBtn);
|
||||
toolBtn->setPopupMode(QToolButton::InstantPopup);
|
||||
toolBtn->setProperty(PropertyDefs::c_toolButtonWithoutMenuIndicator, true);
|
||||
break;
|
||||
}
|
||||
|
||||
case Action::TypeHeading:
|
||||
{
|
||||
act = p_tb->addAction(ToolBarHelper::generateIcon("type_heading_editor.svg"),
|
||||
|
@ -17,6 +17,7 @@ namespace vnotex
|
||||
{
|
||||
Save,
|
||||
EditReadDiscard,
|
||||
ViewMode,
|
||||
|
||||
// Make sure they are put together.
|
||||
// Including Heading1-6 and HeadingNone.
|
||||
|
Loading…
x
Reference in New Issue
Block a user