mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 05:49:53 +08:00
add MindMap editor
This commit is contained in:
parent
e76c6829f7
commit
5229be4687
@ -5,12 +5,13 @@ SOURCES += \
|
||||
$$PWD/markdownbuffer.cpp \
|
||||
$$PWD/markdownbufferfactory.cpp \
|
||||
$$PWD/filetypehelper.cpp \
|
||||
$$PWD/mindmapbuffer.cpp \
|
||||
$$PWD/mindmapbufferfactory.cpp \
|
||||
$$PWD/nodebufferprovider.cpp \
|
||||
$$PWD/pdfbuffer.cpp \
|
||||
$$PWD/pdfbufferfactory.cpp \
|
||||
$$PWD/textbuffer.cpp \
|
||||
$$PWD/textbufferfactory.cpp \
|
||||
$$PWD/urlbasedbufferprovider.cpp
|
||||
$$PWD/textbufferfactory.cpp
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/bufferprovider.h \
|
||||
@ -20,6 +21,8 @@ HEADERS += \
|
||||
$$PWD/markdownbuffer.h \
|
||||
$$PWD/markdownbufferfactory.h \
|
||||
$$PWD/filetypehelper.h \
|
||||
$$PWD/mindmapbuffer.h \
|
||||
$$PWD/mindmapbufferfactory.h \
|
||||
$$PWD/nodebufferprovider.h \
|
||||
$$PWD/pdfbuffer.h \
|
||||
$$PWD/pdfbufferfactory.h \
|
||||
|
@ -91,6 +91,22 @@ void FileTypeHelper::setupBuiltInTypes()
|
||||
m_fileTypes.push_back(type);
|
||||
}
|
||||
|
||||
{
|
||||
FileType type;
|
||||
type.m_type = FileType::MindMap;
|
||||
type.m_typeName = QStringLiteral("MindMap");
|
||||
type.m_displayName = Buffer::tr("Mind Map");
|
||||
|
||||
auto suffixes = coreConfig.findFileTypeSuffix(type.m_typeName);
|
||||
if (suffixes && !suffixes->isEmpty()) {
|
||||
type.m_suffixes = *suffixes;
|
||||
} else {
|
||||
type.m_suffixes << QStringLiteral("emind");
|
||||
}
|
||||
|
||||
m_fileTypes.push_back(type);
|
||||
}
|
||||
|
||||
{
|
||||
FileType type;
|
||||
type.m_type = FileType::Others;
|
||||
|
@ -16,6 +16,7 @@ namespace vnotex
|
||||
Markdown = 0,
|
||||
Text,
|
||||
Pdf,
|
||||
MindMap,
|
||||
Others
|
||||
};
|
||||
|
||||
|
17
src/core/buffer/mindmapbuffer.cpp
Normal file
17
src/core/buffer/mindmapbuffer.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
#include "mindmapbuffer.h"
|
||||
|
||||
#include <widgets/mindmapviewwindow.h>
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
MindMapBuffer::MindMapBuffer(const BufferParameters &p_parameters,
|
||||
QObject *p_parent)
|
||||
: Buffer(p_parameters, p_parent)
|
||||
{
|
||||
}
|
||||
|
||||
ViewWindow *MindMapBuffer::createViewWindowInternal(const QSharedPointer<FileOpenParameters> &p_paras, QWidget *p_parent)
|
||||
{
|
||||
Q_UNUSED(p_paras);
|
||||
return new MindMapViewWindow(p_parent);
|
||||
}
|
21
src/core/buffer/mindmapbuffer.h
Normal file
21
src/core/buffer/mindmapbuffer.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef MINDMAPBUFFER_H
|
||||
#define MINDMAPBUFFER_H
|
||||
|
||||
#include "buffer.h"
|
||||
|
||||
namespace vnotex
|
||||
{
|
||||
class MindMapBuffer : public Buffer
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MindMapBuffer(const BufferParameters &p_parameters,
|
||||
QObject *p_parent = nullptr);
|
||||
|
||||
protected:
|
||||
ViewWindow *createViewWindowInternal(const QSharedPointer<FileOpenParameters> &p_paras,
|
||||
QWidget *p_parent) Q_DECL_OVERRIDE;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MINDMAPBUFFER_H
|
16
src/core/buffer/mindmapbufferfactory.cpp
Normal file
16
src/core/buffer/mindmapbufferfactory.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
#include "mindmapbufferfactory.h"
|
||||
|
||||
#include "mindmapbuffer.h"
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
Buffer *MindMapBufferFactory::createBuffer(const BufferParameters &p_parameters,
|
||||
QObject *p_parent)
|
||||
{
|
||||
return new MindMapBuffer(p_parameters, p_parent);
|
||||
}
|
||||
|
||||
bool MindMapBufferFactory::isBufferCreatedByFactory(const Buffer *p_buffer) const
|
||||
{
|
||||
return dynamic_cast<const MindMapBuffer *>(p_buffer) != nullptr;
|
||||
}
|
19
src/core/buffer/mindmapbufferfactory.h
Normal file
19
src/core/buffer/mindmapbufferfactory.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef MINDMAPBUFFERFACTORY_H
|
||||
#define MINDMAPBUFFERFACTORY_H
|
||||
|
||||
#include "ibufferfactory.h"
|
||||
|
||||
namespace vnotex
|
||||
{
|
||||
// Buffer factory for MindMap file.
|
||||
class MindMapBufferFactory : public IBufferFactory
|
||||
{
|
||||
public:
|
||||
Buffer *createBuffer(const BufferParameters &p_parameters,
|
||||
QObject *p_parent) Q_DECL_OVERRIDE;
|
||||
|
||||
bool isBufferCreatedByFactory(const Buffer *p_buffer) const Q_DECL_OVERRIDE;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MINDMAPBUFFERFACTORY_H
|
@ -15,7 +15,6 @@ namespace vnotex
|
||||
protected:
|
||||
ViewWindow *createViewWindowInternal(const QSharedPointer<FileOpenParameters> &p_paras,
|
||||
QWidget *p_parent) Q_DECL_OVERRIDE;
|
||||
|
||||
};
|
||||
} // ns vnotex
|
||||
|
||||
|
@ -1,3 +0,0 @@
|
||||
#include "urlbasedbufferprovider.h"
|
||||
|
||||
using namespace vnotex;
|
@ -8,6 +8,7 @@
|
||||
#include <buffer/markdownbufferfactory.h>
|
||||
#include <buffer/textbufferfactory.h>
|
||||
#include <buffer/pdfbufferfactory.h>
|
||||
#include <buffer/mindmapbufferfactory.h>
|
||||
#include <buffer/buffer.h>
|
||||
#include <buffer/nodebufferprovider.h>
|
||||
#include <buffer/filebufferprovider.h>
|
||||
@ -57,6 +58,10 @@ void BufferMgr::initBufferServer()
|
||||
// Pdf.
|
||||
auto pdfFactory = QSharedPointer<PdfBufferFactory>::create();
|
||||
m_bufferServer->registerItem(helper.getFileType(FileType::Pdf).m_typeName, pdfFactory);
|
||||
|
||||
// MindMap.
|
||||
auto mindMapFactory = QSharedPointer<MindMapBufferFactory>::create();
|
||||
m_bufferServer->registerItem(helper.getFileType(FileType::MindMap).m_typeName, mindMapFactory);
|
||||
}
|
||||
|
||||
void BufferMgr::open(Node *p_node, const QSharedPointer<FileOpenParameters> &p_paras)
|
||||
|
@ -24,6 +24,7 @@ SOURCES += \
|
||||
$$PWD/logger.cpp \
|
||||
$$PWD/mainconfig.cpp \
|
||||
$$PWD/markdowneditorconfig.cpp \
|
||||
$$PWD/mindmapeditorconfig.cpp \
|
||||
$$PWD/pdfviewerconfig.cpp \
|
||||
$$PWD/quickaccesshelper.cpp \
|
||||
$$PWD/singleinstanceguard.cpp \
|
||||
@ -54,6 +55,7 @@ HEADERS += \
|
||||
$$PWD/logger.h \
|
||||
$$PWD/mainconfig.h \
|
||||
$$PWD/markdowneditorconfig.h \
|
||||
$$PWD/mindmapeditorconfig.h \
|
||||
$$PWD/noncopyable.h \
|
||||
$$PWD/pdfviewerconfig.h \
|
||||
$$PWD/quickaccesshelper.h \
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "texteditorconfig.h"
|
||||
#include "markdowneditorconfig.h"
|
||||
#include "pdfviewerconfig.h"
|
||||
#include "mindmapeditorconfig.h"
|
||||
|
||||
#include <vtextedit/viconfig.h>
|
||||
|
||||
@ -43,7 +44,8 @@ EditorConfig::EditorConfig(ConfigMgr *p_mgr, IConfig *p_topConfig)
|
||||
: IConfig(p_mgr, p_topConfig),
|
||||
m_textEditorConfig(new TextEditorConfig(p_mgr, p_topConfig)),
|
||||
m_markdownEditorConfig(new MarkdownEditorConfig(p_mgr, p_topConfig, m_textEditorConfig)),
|
||||
m_pdfViewerConfig(new PdfViewerConfig(p_mgr, p_topConfig))
|
||||
m_pdfViewerConfig(new PdfViewerConfig(p_mgr, p_topConfig)),
|
||||
m_mindMapEditorConfig(new MindMapEditorConfig(p_mgr, p_topConfig))
|
||||
{
|
||||
m_sessionName = QStringLiteral("editor");
|
||||
}
|
||||
@ -68,6 +70,7 @@ void EditorConfig::init(const QJsonObject &p_app,
|
||||
m_textEditorConfig->init(appObj, userObj);
|
||||
m_markdownEditorConfig->init(appObj, userObj);
|
||||
m_pdfViewerConfig->init(appObj, userObj);
|
||||
m_mindMapEditorConfig->init(appObj, userObj);
|
||||
}
|
||||
|
||||
void EditorConfig::loadCore(const QJsonObject &p_app, const QJsonObject &p_user)
|
||||
@ -152,6 +155,7 @@ QJsonObject EditorConfig::toJson() const
|
||||
obj[m_textEditorConfig->getSessionName()] = m_textEditorConfig->toJson();
|
||||
obj[m_markdownEditorConfig->getSessionName()] = m_markdownEditorConfig->toJson();
|
||||
obj[m_pdfViewerConfig->getSessionName()] = m_pdfViewerConfig->toJson();
|
||||
obj[m_mindMapEditorConfig->getSessionName()] = m_mindMapEditorConfig->toJson();
|
||||
obj[QStringLiteral("core")] = saveCore();
|
||||
obj[QStringLiteral("image_host")] = saveImageHost();
|
||||
|
||||
@ -192,6 +196,16 @@ const PdfViewerConfig &EditorConfig::getPdfViewerConfig() const
|
||||
return *m_pdfViewerConfig;
|
||||
}
|
||||
|
||||
MindMapEditorConfig &EditorConfig::getMindMapEditorConfig()
|
||||
{
|
||||
return *m_mindMapEditorConfig;
|
||||
}
|
||||
|
||||
const MindMapEditorConfig &EditorConfig::getMindMapEditorConfig() const
|
||||
{
|
||||
return *m_mindMapEditorConfig;
|
||||
}
|
||||
|
||||
int EditorConfig::getToolBarIconSize() const
|
||||
{
|
||||
return m_toolBarIconSize;
|
||||
|
@ -20,6 +20,7 @@ namespace vnotex
|
||||
class TextEditorConfig;
|
||||
class MarkdownEditorConfig;
|
||||
class PdfViewerConfig;
|
||||
class MindMapEditorConfig;
|
||||
|
||||
class EditorConfig : public IConfig
|
||||
{
|
||||
@ -109,6 +110,9 @@ namespace vnotex
|
||||
PdfViewerConfig &getPdfViewerConfig();
|
||||
const PdfViewerConfig &getPdfViewerConfig() const;
|
||||
|
||||
MindMapEditorConfig &getMindMapEditorConfig();
|
||||
const MindMapEditorConfig &getMindMapEditorConfig() const;
|
||||
|
||||
void init(const QJsonObject &p_app, const QJsonObject &p_user) Q_DECL_OVERRIDE;
|
||||
|
||||
QJsonObject toJson() const Q_DECL_OVERRIDE;
|
||||
@ -182,6 +186,8 @@ namespace vnotex
|
||||
|
||||
QScopedPointer<PdfViewerConfig> m_pdfViewerConfig;
|
||||
|
||||
QScopedPointer<MindMapEditorConfig> m_mindMapEditorConfig;
|
||||
|
||||
bool m_spellCheckAutoDetectLanguageEnabled = false;
|
||||
|
||||
QString m_spellCheckDefaultDictionary;
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include <core/markdowneditorconfig.h>
|
||||
#include <core/pdfviewerconfig.h>
|
||||
#include <core/mindmapeditorconfig.h>
|
||||
#include <core/configmgr.h>
|
||||
#include <utils/utils.h>
|
||||
#include <utils/fileutils.h>
|
||||
@ -19,6 +20,8 @@ HtmlTemplateHelper::Template HtmlTemplateHelper::s_markdownViewerTemplate;
|
||||
|
||||
HtmlTemplateHelper::Template HtmlTemplateHelper::s_pdfViewerTemplate;
|
||||
|
||||
HtmlTemplateHelper::Template HtmlTemplateHelper::s_mindMapEditorTemplate;
|
||||
|
||||
QString MarkdownWebGlobalOptions::toJavascriptObject() const
|
||||
{
|
||||
return QStringLiteral("window.vxOptions = {\n")
|
||||
@ -339,7 +342,7 @@ const QString &HtmlTemplateHelper::getPdfViewerTemplatePath()
|
||||
|
||||
void HtmlTemplateHelper::updatePdfViewerTemplate(const PdfViewerConfig &p_config, bool p_force)
|
||||
{
|
||||
if (!p_force && p_config.revision() == s_markdownViewerTemplate.m_revision) {
|
||||
if (!p_force && p_config.revision() == s_pdfViewerTemplate.m_revision) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -361,3 +364,41 @@ void HtmlTemplateHelper::generatePdfViewerTemplate(const PdfViewerConfig &p_conf
|
||||
|
||||
fillResources(p_template.m_template, viewerResource);
|
||||
}
|
||||
|
||||
const QString &HtmlTemplateHelper::getMindMapEditorTemplate()
|
||||
{
|
||||
return s_mindMapEditorTemplate.m_template;
|
||||
}
|
||||
|
||||
void HtmlTemplateHelper::updateMindMapEditorTemplate(const MindMapEditorConfig &p_config, bool p_force)
|
||||
{
|
||||
if (!p_force && p_config.revision() == s_mindMapEditorTemplate.m_revision) {
|
||||
return;
|
||||
}
|
||||
|
||||
s_mindMapEditorTemplate.m_revision = p_config.revision();
|
||||
|
||||
const auto &themeMgr = VNoteX::getInst().getThemeMgr();
|
||||
generateMindMapEditorTemplate(p_config,
|
||||
themeMgr.getFile(Theme::File::WebStyleSheet),
|
||||
s_mindMapEditorTemplate);
|
||||
}
|
||||
|
||||
void HtmlTemplateHelper::generateMindMapEditorTemplate(const MindMapEditorConfig &p_config,
|
||||
const QString &p_webStyleSheetFile,
|
||||
Template& p_template)
|
||||
{
|
||||
const auto &editorResource = p_config.getEditorResource();
|
||||
p_template.m_templatePath = ConfigMgr::getInst().getUserOrAppFile(editorResource.m_template);
|
||||
try {
|
||||
p_template.m_template = FileUtils::readTextFile(p_template.m_templatePath);
|
||||
} catch (Exception &p_e) {
|
||||
qWarning() << "failed to read HTML template" << p_template.m_templatePath << p_e.what();
|
||||
p_template.m_template = errorPage();
|
||||
return;
|
||||
}
|
||||
|
||||
fillThemeStyles(p_template.m_template, p_webStyleSheetFile, QString());
|
||||
|
||||
fillResources(p_template.m_template, editorResource);
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ namespace vnotex
|
||||
{
|
||||
class MarkdownEditorConfig;
|
||||
class PdfViewerConfig;
|
||||
class MindMapEditorConfig;
|
||||
struct WebResource;
|
||||
|
||||
// Global options to be passed to Web side at the very beginning for Markdown.
|
||||
@ -91,7 +92,7 @@ namespace vnotex
|
||||
|
||||
HtmlTemplateHelper() = delete;
|
||||
|
||||
// For Markdown.
|
||||
// For MarkdownViewer.
|
||||
static const QString &getMarkdownViewerTemplate();
|
||||
static void updateMarkdownViewerTemplate(const MarkdownEditorConfig &p_config, bool p_force = false);
|
||||
|
||||
@ -119,6 +120,10 @@ namespace vnotex
|
||||
|
||||
static const QString &getPdfViewerTemplatePath();
|
||||
|
||||
// For MindMapEditor.
|
||||
static const QString &getMindMapEditorTemplate();
|
||||
static void updateMindMapEditorTemplate(const MindMapEditorConfig &p_config, bool p_force = false);
|
||||
|
||||
private:
|
||||
struct Template
|
||||
{
|
||||
@ -131,9 +136,15 @@ namespace vnotex
|
||||
|
||||
static void generatePdfViewerTemplate(const PdfViewerConfig &p_config, Template& p_template);
|
||||
|
||||
static void generateMindMapEditorTemplate(const MindMapEditorConfig &p_config,
|
||||
const QString &p_webStyleSheetFile,
|
||||
Template& p_template);
|
||||
|
||||
static Template s_markdownViewerTemplate;
|
||||
|
||||
static Template s_pdfViewerTemplate;
|
||||
|
||||
static Template s_mindMapEditorTemplate;
|
||||
};
|
||||
}
|
||||
|
||||
|
61
src/core/mindmapeditorconfig.cpp
Normal file
61
src/core/mindmapeditorconfig.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
#include "mindmapeditorconfig.h"
|
||||
|
||||
#include "mainconfig.h"
|
||||
|
||||
#define READSTR(key) readString(appObj, userObj, (key))
|
||||
#define READBOOL(key) readBool(appObj, userObj, (key))
|
||||
#define READINT(key) readInt(appObj, userObj, (key))
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
MindMapEditorConfig::MindMapEditorConfig(ConfigMgr *p_mgr, IConfig *p_topConfig)
|
||||
: IConfig(p_mgr, p_topConfig)
|
||||
{
|
||||
m_sessionName = QStringLiteral("mindmap_editor");
|
||||
}
|
||||
|
||||
void MindMapEditorConfig::init(const QJsonObject &p_app,
|
||||
const QJsonObject &p_user)
|
||||
{
|
||||
const auto appObj = p_app.value(m_sessionName).toObject();
|
||||
const auto userObj = p_user.value(m_sessionName).toObject();
|
||||
|
||||
loadEditorResource(appObj, userObj);
|
||||
}
|
||||
|
||||
QJsonObject MindMapEditorConfig::toJson() const
|
||||
{
|
||||
QJsonObject obj;
|
||||
obj[QStringLiteral("editor_resource")] = saveEditorResource();
|
||||
return obj;
|
||||
}
|
||||
|
||||
void MindMapEditorConfig::loadEditorResource(const QJsonObject &p_app, const QJsonObject &p_user)
|
||||
{
|
||||
const QString name(QStringLiteral("editor_resource"));
|
||||
|
||||
if (MainConfig::isVersionChanged()) {
|
||||
bool needOverride = p_app[QStringLiteral("override_editor_resource")].toBool();
|
||||
if (needOverride) {
|
||||
qInfo() << "override \"editor_resource\" in user configuration due to version change";
|
||||
m_editorResource.init(p_app[name].toObject());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (p_user.contains(name)) {
|
||||
m_editorResource.init(p_user[name].toObject());
|
||||
} else {
|
||||
m_editorResource.init(p_app[name].toObject());
|
||||
}
|
||||
}
|
||||
|
||||
QJsonObject MindMapEditorConfig::saveEditorResource() const
|
||||
{
|
||||
return m_editorResource.toJson();
|
||||
}
|
||||
|
||||
const WebResource &MindMapEditorConfig::getEditorResource() const
|
||||
{
|
||||
return m_editorResource;
|
||||
}
|
31
src/core/mindmapeditorconfig.h
Normal file
31
src/core/mindmapeditorconfig.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef MINDMAPEDITORCONFIG_H
|
||||
#define MINDMAPEDITORCONFIG_H
|
||||
|
||||
#include "iconfig.h"
|
||||
|
||||
#include "webresource.h"
|
||||
|
||||
namespace vnotex
|
||||
{
|
||||
class MindMapEditorConfig : public IConfig
|
||||
{
|
||||
public:
|
||||
MindMapEditorConfig(ConfigMgr *p_mgr, IConfig *p_topConfig);
|
||||
|
||||
void init(const QJsonObject &p_app, const QJsonObject &p_user) Q_DECL_OVERRIDE;
|
||||
|
||||
QJsonObject toJson() const Q_DECL_OVERRIDE;
|
||||
|
||||
const WebResource &getEditorResource() const;
|
||||
|
||||
private:
|
||||
friend class MainConfig;
|
||||
|
||||
void loadEditorResource(const QJsonObject &p_app, const QJsonObject &p_user);
|
||||
QJsonObject saveEditorResource() const;
|
||||
|
||||
WebResource m_editorResource;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MINDMAPEDITORCONFIG_H
|
@ -94,6 +94,12 @@
|
||||
"suffixes" : [
|
||||
"pdf"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "MindMap",
|
||||
"suffixes" : [
|
||||
"emind"
|
||||
]
|
||||
}
|
||||
],
|
||||
"shortcut_leader_key" : "Ctrl+G",
|
||||
@ -519,6 +525,39 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"mindmap_editor" : {
|
||||
"override_editor_resource" : true,
|
||||
"editor_resource" : {
|
||||
"template" : "web/mindmap-editor-template.html",
|
||||
"resources" : [
|
||||
{
|
||||
"name" : "built_in",
|
||||
"enabled" : true,
|
||||
"scripts" : [
|
||||
"web/js/qwebchannel.js",
|
||||
"web/js/eventemitter.js",
|
||||
"web/js/utils.js",
|
||||
"web/js/vxcore.js",
|
||||
"web/js/mindmapeditorcore.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "mind_elixir",
|
||||
"enabled" : true,
|
||||
"scripts" : [
|
||||
"web/js/mind-elixir/MindElixir.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name" : "mindmap_editor",
|
||||
"enabled" : true,
|
||||
"scripts" : [
|
||||
"web/js/mindmapeditor.js"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"image_host" : {
|
||||
"hosts" : [
|
||||
],
|
||||
|
@ -79,8 +79,6 @@
|
||||
<file>web/js/turndown.js</file>
|
||||
<file>web/js/mark.js/mark.min.js</file>
|
||||
<file>web/js/markjs.js</file>
|
||||
<file>web/js/mind-elixir/MindElixir.min.js</file>
|
||||
<file>web/js/mind-elixir/painter.js</file>
|
||||
|
||||
<file>web/pdf.js/pdfviewer.js</file>
|
||||
<file>web/pdf.js/pdfviewer.css</file>
|
||||
@ -327,6 +325,11 @@
|
||||
<file>web/pdf.js/web/cmaps/V.bcmap</file>
|
||||
<file>web/pdf.js/web/cmaps/WP-Symbol.bcmap</file>
|
||||
|
||||
<file>web/js/mind-elixir/MindElixir.js</file>
|
||||
<file>web/mindmap-editor-template.html</file>
|
||||
<file>web/js/mindmapeditorcore.js</file>
|
||||
<file>web/js/mindmapeditor.js</file>
|
||||
|
||||
<file>dicts/en_US.aff</file>
|
||||
<file>dicts/en_US.dic</file>
|
||||
<file>themes/native/text-editor.theme</file>
|
||||
|
@ -12,6 +12,10 @@ class MarkJs {
|
||||
this.adapter.on('basicMarkdownRendered', () => {
|
||||
this.clearCache();
|
||||
});
|
||||
|
||||
this.adapter.on('rendered', () => {
|
||||
this.clearCache();
|
||||
});
|
||||
}
|
||||
|
||||
// @p_options: {
|
||||
|
1
src/data/extra/web/js/mind-elixir/MindElixir.js
Normal file
1
src/data/extra/web/js/mind-elixir/MindElixir.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,2 +1,2 @@
|
||||
# [mind-elixir](https://github.com/ssshooter/mind-elixir-core)
|
||||
v0.19.3
|
||||
v1.1.3
|
||||
|
File diff suppressed because one or more lines are too long
33
src/data/extra/web/js/mindmapeditor.js
Normal file
33
src/data/extra/web/js/mindmapeditor.js
Normal file
@ -0,0 +1,33 @@
|
||||
/* Main script file for MindMapEditor. */
|
||||
|
||||
new QWebChannel(qt.webChannelTransport,
|
||||
function(p_channel) {
|
||||
let adapter = p_channel.objects.vxAdapter;
|
||||
// Export the adapter globally.
|
||||
window.vxAdapter = adapter;
|
||||
|
||||
// Connect signals from CPP side.
|
||||
adapter.saveDataRequested.connect(function(p_id) {
|
||||
window.vxcore.saveData(p_id);
|
||||
});
|
||||
|
||||
adapter.dataUpdated.connect(function(p_data) {
|
||||
window.vxcore.setData(p_data);
|
||||
});
|
||||
|
||||
adapter.findTextRequested.connect(function(p_texts, p_options, p_currentMatchLine) {
|
||||
window.vxcore.findText(p_texts, p_options, p_currentMatchLine);
|
||||
});
|
||||
|
||||
console.log('QWebChannel has been set up');
|
||||
|
||||
if (window.vxcore.initialized) {
|
||||
window.vxAdapter.setReady(true);
|
||||
}
|
||||
});
|
||||
|
||||
window.vxcore.on('ready', function() {
|
||||
if (window.vxAdapter) {
|
||||
window.vxAdapter.setReady(true);
|
||||
}
|
||||
});
|
38
src/data/extra/web/js/mindmapeditorcore.js
Normal file
38
src/data/extra/web/js/mindmapeditorcore.js
Normal file
@ -0,0 +1,38 @@
|
||||
class MindMapEditorCore extends VXCore {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
initOnLoad() {
|
||||
let options = {
|
||||
el: '#vx-mindmap',
|
||||
direction: MindElixir.LEFT,
|
||||
}
|
||||
|
||||
this.mind = new MindElixir(options);
|
||||
|
||||
this.mind.bus.addListener('operation', operation => {
|
||||
if (operation === 'beginEdit') {
|
||||
return;
|
||||
}
|
||||
window.vxAdapter.notifyContentsChanged();
|
||||
});
|
||||
}
|
||||
|
||||
saveData(p_id) {
|
||||
let data = this.mind.getAllDataString();
|
||||
window.vxAdapter.setSavedData(p_id, data);
|
||||
}
|
||||
|
||||
setData(p_data) {
|
||||
if (p_data && p_data !== "") {
|
||||
this.mind.init(JSON.parse(p_data));
|
||||
} else {
|
||||
const data = MindElixir.new('New Topic')
|
||||
this.mind.init(data)
|
||||
}
|
||||
this.emit('rendered');
|
||||
}
|
||||
}
|
||||
|
||||
window.vxcore = new MindMapEditorCore();
|
33
src/data/extra/web/mindmap-editor-template.html
Normal file
33
src/data/extra/web/mindmap-editor-template.html
Normal file
@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>VNoteX MindMap Viewer</title>
|
||||
|
||||
<style type="text/css">
|
||||
/* VX_GLOBAL_STYLES_PLACEHOLDER */
|
||||
#vx-mindmap {
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0px !important;
|
||||
padding: 0px !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- VX_THEME_STYLES_PLACEHOLDER -->
|
||||
|
||||
<!-- VX_STYLES_PLACEHOLDER -->
|
||||
|
||||
<script type="text/javascript">
|
||||
/* VX_GLOBAL_OPTIONS_PLACEHOLDER */
|
||||
</script>
|
||||
|
||||
<!-- VX_SCRIPTS_PLACEHOLDER -->
|
||||
</head>
|
||||
<body>
|
||||
<div id="vx-mindmap"></div>
|
||||
</body>
|
||||
</html>
|
@ -84,7 +84,7 @@ void MarkdownViewer::setPreviewHelper(PreviewHelper *p_previewHelper)
|
||||
TimeStamp p_timeStamp,
|
||||
const QString &p_lang,
|
||||
const QString &p_text) {
|
||||
if (m_adapter->isViewerReady()) {
|
||||
if (m_adapter->isReady()) {
|
||||
m_adapter->graphPreviewRequested(p_id, p_timeStamp, p_lang, p_text);
|
||||
} else {
|
||||
p_previewHelper->handleGraphPreviewData(MarkdownViewerAdapter::PreviewData());
|
||||
@ -94,7 +94,7 @@ void MarkdownViewer::setPreviewHelper(PreviewHelper *p_previewHelper)
|
||||
this, [this, p_previewHelper](quint64 p_id,
|
||||
TimeStamp p_timeStamp,
|
||||
const QString &p_text) {
|
||||
if (m_adapter->isViewerReady()) {
|
||||
if (m_adapter->isReady()) {
|
||||
m_adapter->mathPreviewRequested(p_id, p_timeStamp, p_text);
|
||||
} else {
|
||||
p_previewHelper->handleMathPreviewData(MarkdownViewerAdapter::PreviewData());
|
||||
|
@ -50,16 +50,6 @@ MarkdownViewerAdapter::Heading MarkdownViewerAdapter::Heading::fromJson(const QJ
|
||||
p_obj.value(QStringLiteral("anchor")).toString());
|
||||
}
|
||||
|
||||
QJsonObject MarkdownViewerAdapter::FindOption::toJson() const
|
||||
{
|
||||
QJsonObject obj;
|
||||
obj["findBackward"] = m_findBackward;
|
||||
obj["caseSensitive"] = m_caseSensitive;
|
||||
obj["wholeWordOnly"] = m_wholeWordOnly;
|
||||
obj["regularExpression"] = m_regularExpression;
|
||||
return obj;
|
||||
}
|
||||
|
||||
MarkdownViewerAdapter::CssRuleStyle MarkdownViewerAdapter::CssRuleStyle::fromJson(const QJsonObject &p_obj)
|
||||
{
|
||||
CssRuleStyle style;
|
||||
@ -90,7 +80,7 @@ QTextCharFormat MarkdownViewerAdapter::CssRuleStyle::toTextCharFormat() const
|
||||
}
|
||||
|
||||
MarkdownViewerAdapter::MarkdownViewerAdapter(QObject *p_parent)
|
||||
: QObject(p_parent)
|
||||
: WebViewAdapter(p_parent)
|
||||
{
|
||||
}
|
||||
|
||||
@ -108,15 +98,16 @@ void MarkdownViewerAdapter::setText(int p_revision,
|
||||
return;
|
||||
}
|
||||
|
||||
m_revision = p_revision;
|
||||
if (m_viewerReady) {
|
||||
if (isReady()) {
|
||||
m_revision = p_revision;
|
||||
emit textUpdated(p_text);
|
||||
scrollToPosition(Position(p_lineNumber, ""));
|
||||
} else {
|
||||
m_pendingActions.append([this, p_text, p_lineNumber]() {
|
||||
emit textUpdated(p_text);
|
||||
scrollToPosition(Position(p_lineNumber, ""));
|
||||
});
|
||||
pendAction(std::bind(QOverload<int, const QString &, int>::of(&MarkdownViewerAdapter::setText),
|
||||
this,
|
||||
p_revision,
|
||||
p_text,
|
||||
p_lineNumber));
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,37 +116,18 @@ void MarkdownViewerAdapter::setText(const QString &p_text, int p_lineNumber)
|
||||
setText(0, p_text, p_lineNumber);
|
||||
}
|
||||
|
||||
void MarkdownViewerAdapter::setReady(bool p_ready)
|
||||
{
|
||||
if (m_viewerReady == p_ready) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_viewerReady = p_ready;
|
||||
if (m_viewerReady) {
|
||||
for (auto &act : m_pendingActions) {
|
||||
act();
|
||||
}
|
||||
m_pendingActions.clear();
|
||||
emit viewerReady();
|
||||
}
|
||||
}
|
||||
|
||||
void MarkdownViewerAdapter::scrollToLine(int p_lineNumber)
|
||||
{
|
||||
if (p_lineNumber == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_viewerReady) {
|
||||
m_pendingActions.append([this, p_lineNumber]() {
|
||||
scrollToPosition(Position(p_lineNumber, ""));
|
||||
});
|
||||
return;
|
||||
if (isReady()) {
|
||||
m_topLineNumber = p_lineNumber;
|
||||
emit editLineNumberUpdated(p_lineNumber);
|
||||
} else {
|
||||
pendAction(std::bind(&MarkdownViewerAdapter::scrollToLine, this, p_lineNumber));
|
||||
}
|
||||
|
||||
m_topLineNumber = p_lineNumber;
|
||||
emit editLineNumberUpdated(p_lineNumber);
|
||||
}
|
||||
|
||||
void MarkdownViewerAdapter::setTopLineNumber(int p_lineNumber)
|
||||
@ -196,11 +168,6 @@ void MarkdownViewerAdapter::setGraphPreviewData(quint64 p_id,
|
||||
emit graphPreviewDataReady(PreviewData(p_id, p_timeStamp, p_format, ba, p_needScale));
|
||||
}
|
||||
|
||||
bool MarkdownViewerAdapter::isViewerReady() const
|
||||
{
|
||||
return m_viewerReady;
|
||||
}
|
||||
|
||||
void MarkdownViewerAdapter::setMathPreviewData(quint64 p_id,
|
||||
quint64 p_timeStamp,
|
||||
const QString &p_format,
|
||||
@ -272,7 +239,7 @@ void MarkdownViewerAdapter::scrollToAnchor(const QString &p_anchor)
|
||||
if (p_anchor.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Q_ASSERT(m_viewerReady);
|
||||
Q_ASSERT(isReady());
|
||||
m_currentHeadingIndex = -1;
|
||||
emit anchorScrollRequested(p_anchor);
|
||||
}
|
||||
@ -340,38 +307,6 @@ void MarkdownViewerAdapter::setCrossCopyResult(quint64 p_id, quint64 p_timeStamp
|
||||
emit crossCopyReady(p_id, p_timeStamp, p_html);
|
||||
}
|
||||
|
||||
void MarkdownViewerAdapter::findText(const QStringList &p_texts, FindOptions p_options, int p_currentMatchLine)
|
||||
{
|
||||
FindOption opts;
|
||||
if (p_options & vnotex::FindOption::FindBackward) {
|
||||
opts.m_findBackward = true;
|
||||
}
|
||||
if (p_options & vnotex::FindOption::CaseSensitive) {
|
||||
opts.m_caseSensitive = true;
|
||||
}
|
||||
if (p_options & vnotex::FindOption::WholeWordOnly) {
|
||||
opts.m_wholeWordOnly = true;
|
||||
}
|
||||
if (p_options & vnotex::FindOption::RegularExpression) {
|
||||
opts.m_regularExpression = true;
|
||||
}
|
||||
|
||||
if (m_viewerReady) {
|
||||
emit findTextRequested(p_texts, opts.toJson(), p_currentMatchLine);
|
||||
} else {
|
||||
m_pendingActions.append([this, p_texts, opts, p_currentMatchLine]() {
|
||||
// FIXME: highlights will be clear once the page is ready. Add a delay here.
|
||||
Utils::sleepWait(1000);
|
||||
emit findTextRequested(p_texts, opts.toJson(), p_currentMatchLine);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void MarkdownViewerAdapter::setFindText(const QStringList &p_texts, int p_totalMatches, int p_currentMatchIndex)
|
||||
{
|
||||
emit findTextReady(p_texts, p_totalMatches, p_currentMatchIndex);
|
||||
}
|
||||
|
||||
void MarkdownViewerAdapter::setWorkFinished()
|
||||
{
|
||||
emit workFinished();
|
||||
@ -393,8 +328,7 @@ void MarkdownViewerAdapter::setSavedContent(const QString &p_headContent,
|
||||
void MarkdownViewerAdapter::reset()
|
||||
{
|
||||
m_revision = 0;
|
||||
m_viewerReady = false;
|
||||
m_pendingActions.clear();
|
||||
setReady(false);
|
||||
m_topLineNumber = -1;
|
||||
m_headings.clear();
|
||||
m_currentHeadingIndex = -1;
|
||||
@ -437,12 +371,10 @@ void MarkdownViewerAdapter::renderGraph(quint64 p_id,
|
||||
|
||||
void MarkdownViewerAdapter::highlightCodeBlock(int p_idx, quint64 p_timeStamp, const QString &p_text)
|
||||
{
|
||||
if (m_viewerReady) {
|
||||
if (isReady()) {
|
||||
emit highlightCodeBlockRequested(p_idx, p_timeStamp, p_text);
|
||||
} else {
|
||||
m_pendingActions.append([this, p_idx, p_timeStamp, p_text]() {
|
||||
emit highlightCodeBlockRequested(p_idx, p_timeStamp, p_text);
|
||||
});
|
||||
pendAction(std::bind(&MarkdownViewerAdapter::highlightCodeBlock, this, p_idx, p_timeStamp, p_text));
|
||||
}
|
||||
}
|
||||
|
||||
@ -454,24 +386,23 @@ void MarkdownViewerAdapter::setStyleSheetStyles(quint64 p_id, const QJsonArray &
|
||||
ruleStyles.push_back(CssRuleStyle::fromJson(p_styles[i].toObject()));
|
||||
}
|
||||
|
||||
m_callbackPool.call(p_id, &ruleStyles);
|
||||
invokeCallback(p_id, &ruleStyles);
|
||||
}
|
||||
|
||||
void MarkdownViewerAdapter::fetchStylesFromStyleSheet(const QString &p_styleSheet,
|
||||
const std::function<void(const QVector<CssRuleStyle> *)> &p_callback)
|
||||
{
|
||||
if (p_styleSheet.isEmpty()) {
|
||||
p_callback(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
const quint64 id = m_callbackPool.add([p_callback](void *data) {
|
||||
p_callback(reinterpret_cast<const QVector<CssRuleStyle> *>(data));
|
||||
});
|
||||
if (m_viewerReady) {
|
||||
if (isReady()) {
|
||||
const quint64 id = addCallback([p_callback](void *data) {
|
||||
p_callback(reinterpret_cast<const QVector<CssRuleStyle> *>(data));
|
||||
});
|
||||
emit parseStyleSheetRequested(id, p_styleSheet);
|
||||
} else {
|
||||
m_pendingActions.append([this, p_styleSheet, id]() {
|
||||
emit parseStyleSheetRequested(id, p_styleSheet);
|
||||
});
|
||||
pendAction(std::bind(&MarkdownViewerAdapter::fetchStylesFromStyleSheet, this, p_styleSheet, p_callback));
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
#ifndef MARKDOWNVIEWERADAPTER_H
|
||||
#define MARKDOWNVIEWERADAPTER_H
|
||||
|
||||
#include <QObject>
|
||||
#include "webviewadapter.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QJsonObject>
|
||||
#include <QScopedPointer>
|
||||
@ -9,12 +10,11 @@
|
||||
#include <QTextCharFormat>
|
||||
|
||||
#include <core/global.h>
|
||||
#include <utils/callbackpool.h>
|
||||
|
||||
namespace vnotex
|
||||
{
|
||||
// Adapter and interface between CPP and JS.
|
||||
class MarkdownViewerAdapter : public QObject
|
||||
class MarkdownViewerAdapter : public WebViewAdapter
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@ -67,19 +67,6 @@ namespace vnotex
|
||||
QString m_anchor;
|
||||
};
|
||||
|
||||
struct FindOption
|
||||
{
|
||||
QJsonObject toJson() const;
|
||||
|
||||
bool m_findBackward = false;
|
||||
|
||||
bool m_caseSensitive = false;
|
||||
|
||||
bool m_wholeWordOnly = false;
|
||||
|
||||
bool m_regularExpression = false;
|
||||
};
|
||||
|
||||
struct CssRuleStyle
|
||||
{
|
||||
QTextCharFormat toTextCharFormat() const;
|
||||
@ -113,8 +100,6 @@ namespace vnotex
|
||||
|
||||
int getTopLineNumber() const;
|
||||
|
||||
bool isViewerReady() const;
|
||||
|
||||
const QVector<MarkdownViewerAdapter::Heading> &getHeadings() const;
|
||||
int getCurrentHeadingIndex() const;
|
||||
|
||||
@ -126,8 +111,6 @@ namespace vnotex
|
||||
|
||||
QString getCrossCopyTargetDisplayName(const QString &p_target) const;
|
||||
|
||||
void findText(const QStringList &p_texts, FindOptions p_options, int p_currentMatchLine = -1);
|
||||
|
||||
void saveContent();
|
||||
|
||||
// Should be called before WebViewer.setHtml().
|
||||
@ -141,8 +124,6 @@ namespace vnotex
|
||||
|
||||
// Functions to be called from web side.
|
||||
public slots:
|
||||
void setReady(bool p_ready);
|
||||
|
||||
void setWorkFinished();
|
||||
|
||||
// The line number at the top.
|
||||
@ -183,8 +164,6 @@ namespace vnotex
|
||||
|
||||
void setCrossCopyResult(quint64 p_id, quint64 p_timeStamp, const QString &p_html);
|
||||
|
||||
void setFindText(const QStringList &p_texts, int p_totalMatches, int p_currentMatchIndex);
|
||||
|
||||
void setSavedContent(const QString &p_headContent, const QString &p_styleContent, const QString &p_content, const QString &p_bodyClassList);
|
||||
|
||||
// Call local CPP code to render graph.
|
||||
@ -227,8 +206,6 @@ namespace vnotex
|
||||
const QString &p_baseUrl,
|
||||
const QString &p_html);
|
||||
|
||||
void findTextRequested(const QStringList &p_texts, const QJsonObject &p_options, int p_currentMatchLine);
|
||||
|
||||
// Request to get the whole HTML content.
|
||||
void contentRequested();
|
||||
|
||||
@ -247,8 +224,6 @@ namespace vnotex
|
||||
|
||||
void mathPreviewDataReady(const PreviewData &p_data);
|
||||
|
||||
void viewerReady();
|
||||
|
||||
// All rendering work has finished.
|
||||
void workFinished();
|
||||
|
||||
@ -264,8 +239,6 @@ namespace vnotex
|
||||
|
||||
void crossCopyReady(quint64 p_id, quint64 p_timeStamp, const QString &p_html);
|
||||
|
||||
void findTextReady(const QStringList &p_texts, int p_totalMatches, int p_currentMatchIndex);
|
||||
|
||||
void contentReady(const QString &p_headContent,
|
||||
const QString &p_styleContent,
|
||||
const QString &p_content,
|
||||
@ -280,12 +253,6 @@ namespace vnotex
|
||||
|
||||
int m_revision = 0;
|
||||
|
||||
// Whether web side viewer is ready to handle text update.
|
||||
bool m_viewerReady = false;
|
||||
|
||||
// Pending actions for the viewer once it is ready.
|
||||
QVector<std::function<void()>> m_pendingActions;
|
||||
|
||||
// Source line number of the top element node at web side.
|
||||
int m_topLineNumber = -1;
|
||||
|
||||
@ -296,8 +263,6 @@ namespace vnotex
|
||||
|
||||
// Targets supported by cross copy. Set by web.
|
||||
QStringList m_crossCopyTargets;
|
||||
|
||||
CallbackPool m_callbackPool;
|
||||
};
|
||||
}
|
||||
|
||||
|
44
src/widgets/editors/mindmapeditor.cpp
Normal file
44
src/widgets/editors/mindmapeditor.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
#include "mindmapeditor.h"
|
||||
|
||||
#include <QWebChannel>
|
||||
|
||||
#include "mindmapeditoradapter.h"
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
MindMapEditor::MindMapEditor(MindMapEditorAdapter *p_adapter,
|
||||
const QColor &p_background,
|
||||
qreal p_zoomFactor,
|
||||
QWidget *p_parent)
|
||||
: WebViewer(p_background, p_zoomFactor, p_parent),
|
||||
m_adapter(p_adapter)
|
||||
{
|
||||
setAcceptDrops(true);
|
||||
|
||||
m_adapter->setParent(this);
|
||||
connect(m_adapter, &MindMapEditorAdapter::contentsChanged,
|
||||
this, [this]() {
|
||||
m_modified = true;
|
||||
emit contentsChanged();
|
||||
});
|
||||
|
||||
auto channel = new QWebChannel(this);
|
||||
channel->registerObject(QStringLiteral("vxAdapter"), m_adapter);
|
||||
|
||||
page()->setWebChannel(channel);
|
||||
}
|
||||
|
||||
MindMapEditorAdapter *MindMapEditor::adapter() const
|
||||
{
|
||||
return m_adapter;
|
||||
}
|
||||
|
||||
void MindMapEditor::setModified(bool p_modified)
|
||||
{
|
||||
m_modified = p_modified;
|
||||
}
|
||||
|
||||
bool MindMapEditor::isModified() const
|
||||
{
|
||||
return m_modified;
|
||||
}
|
35
src/widgets/editors/mindmapeditor.h
Normal file
35
src/widgets/editors/mindmapeditor.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef MINDMAPEDITOR_H
|
||||
#define MINDMAPEDITOR_H
|
||||
|
||||
#include "../webviewer.h"
|
||||
|
||||
namespace vnotex
|
||||
{
|
||||
class MindMapEditorAdapter;
|
||||
|
||||
class MindMapEditor : public WebViewer
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MindMapEditor(MindMapEditorAdapter *p_adapter,
|
||||
const QColor &p_background,
|
||||
qreal p_zoomFactor,
|
||||
QWidget *p_parent = nullptr);
|
||||
|
||||
MindMapEditorAdapter *adapter() const;
|
||||
|
||||
void setModified(bool p_modified);
|
||||
bool isModified() const;
|
||||
|
||||
signals:
|
||||
void contentsChanged();
|
||||
|
||||
private:
|
||||
// Managed by QObject.
|
||||
MindMapEditorAdapter *m_adapter = nullptr;
|
||||
|
||||
bool m_modified = false;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MINDMAPEDITOR_H
|
39
src/widgets/editors/mindmapeditoradapter.cpp
Normal file
39
src/widgets/editors/mindmapeditoradapter.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
#include "mindmapeditoradapter.h"
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
MindMapEditorAdapter::MindMapEditorAdapter(QObject *p_parent)
|
||||
: WebViewAdapter(p_parent)
|
||||
{
|
||||
}
|
||||
|
||||
void MindMapEditorAdapter::setData(const QString &p_data)
|
||||
{
|
||||
if (isReady()) {
|
||||
emit dataUpdated(p_data);
|
||||
} else {
|
||||
pendAction(std::bind(&MindMapEditorAdapter::setData, this, p_data));
|
||||
}
|
||||
}
|
||||
|
||||
void MindMapEditorAdapter::saveData(const std::function<void(const QString &)> &p_callback)
|
||||
{
|
||||
if (isReady()) {
|
||||
const quint64 id = addCallback([p_callback](void *data) {
|
||||
p_callback(*reinterpret_cast<const QString *>(data));
|
||||
});
|
||||
emit saveDataRequested(id);
|
||||
} else {
|
||||
pendAction(std::bind(&MindMapEditorAdapter::saveData, this, p_callback));
|
||||
}
|
||||
}
|
||||
|
||||
void MindMapEditorAdapter::setSavedData(quint64 p_id, const QString &p_data)
|
||||
{
|
||||
invokeCallback(p_id, (void *)&p_data);
|
||||
}
|
||||
|
||||
void MindMapEditorAdapter::notifyContentsChanged()
|
||||
{
|
||||
emit contentsChanged();
|
||||
}
|
45
src/widgets/editors/mindmapeditoradapter.h
Normal file
45
src/widgets/editors/mindmapeditoradapter.h
Normal file
@ -0,0 +1,45 @@
|
||||
#ifndef MINDMAPEDITORADAPTER_H
|
||||
#define MINDMAPEDITORADAPTER_H
|
||||
|
||||
#include "webviewadapter.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include <core/global.h>
|
||||
|
||||
namespace vnotex
|
||||
{
|
||||
// Adapter and interface between CPP and JS for MindMap.
|
||||
class MindMapEditorAdapter : public WebViewAdapter
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MindMapEditorAdapter(QObject *p_parent = nullptr);
|
||||
|
||||
~MindMapEditorAdapter() = default;
|
||||
|
||||
void setData(const QString &p_data);
|
||||
|
||||
void saveData(const std::function<void(const QString &)> &p_callback);
|
||||
|
||||
// Functions to be called from web side.
|
||||
public slots:
|
||||
void setSavedData(quint64 p_id, const QString &p_data);
|
||||
|
||||
void notifyContentsChanged();
|
||||
|
||||
// Signals to be connected at web side.
|
||||
signals:
|
||||
void dataUpdated(const QString& p_data);
|
||||
|
||||
void saveDataRequested(quint64 p_id);
|
||||
|
||||
signals:
|
||||
void contentsChanged();
|
||||
|
||||
private:
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MINDMAPEDITORADAPTER_H
|
@ -3,7 +3,6 @@
|
||||
#include <QWebChannel>
|
||||
|
||||
#include "pdfvieweradapter.h"
|
||||
#include "previewhelper.h"
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
using namespace vnotex;
|
||||
|
||||
PdfViewerAdapter::PdfViewerAdapter(QObject *p_parent)
|
||||
: QObject(p_parent)
|
||||
: WebViewAdapter(p_parent)
|
||||
{
|
||||
}
|
||||
|
||||
@ -11,26 +11,9 @@ void PdfViewerAdapter::setUrl(const QString &p_url)
|
||||
{
|
||||
// TODO: Not supported yet.
|
||||
Q_ASSERT(false);
|
||||
if (m_viewerReady) {
|
||||
if (isReady()) {
|
||||
emit urlUpdated(p_url);
|
||||
} else {
|
||||
m_pendingActions.append([this, p_url]() {
|
||||
emit urlUpdated(p_url);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void PdfViewerAdapter::setReady(bool p_ready)
|
||||
{
|
||||
if (m_viewerReady == p_ready) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_viewerReady = p_ready;
|
||||
if (m_viewerReady) {
|
||||
for (auto &act : m_pendingActions) {
|
||||
act();
|
||||
}
|
||||
m_pendingActions.clear();
|
||||
pendAction(std::bind(&PdfViewerAdapter::setUrl, this, p_url));
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,12 @@
|
||||
#ifndef PDFVIEWERADAPTER_H
|
||||
#define PDFVIEWERADAPTER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include <core/global.h>
|
||||
#include "webviewadapter.h"
|
||||
|
||||
namespace vnotex
|
||||
{
|
||||
// Adapter and interface between CPP and JS for PDF.
|
||||
class PdfViewerAdapter : public QObject
|
||||
class PdfViewerAdapter : public WebViewAdapter
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@ -22,18 +18,10 @@ namespace vnotex
|
||||
|
||||
// Functions to be called from web side.
|
||||
public slots:
|
||||
void setReady(bool p_ready);
|
||||
|
||||
// Signals to be connected at web side.
|
||||
signals:
|
||||
void urlUpdated(const QString &p_url);
|
||||
|
||||
private:
|
||||
// Whether web side viewer is ready to handle url update.
|
||||
bool m_viewerReady = false;
|
||||
|
||||
// Pending actions for the viewer once it is ready.
|
||||
QVector<std::function<void()>> m_pendingActions;
|
||||
};
|
||||
}
|
||||
|
||||
|
92
src/widgets/editors/webviewadapter.cpp
Normal file
92
src/widgets/editors/webviewadapter.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
#include "webviewadapter.h"
|
||||
|
||||
#include <utils/utils.h>
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
QJsonObject WebViewAdapter::FindOption::toJson() const
|
||||
{
|
||||
QJsonObject obj;
|
||||
obj["findBackward"] = m_findBackward;
|
||||
obj["caseSensitive"] = m_caseSensitive;
|
||||
obj["wholeWordOnly"] = m_wholeWordOnly;
|
||||
obj["regularExpression"] = m_regularExpression;
|
||||
return obj;
|
||||
}
|
||||
|
||||
WebViewAdapter::WebViewAdapter(QObject *p_parent)
|
||||
: QObject(p_parent)
|
||||
{
|
||||
}
|
||||
|
||||
void WebViewAdapter::setReady(bool p_ready)
|
||||
{
|
||||
if (m_ready == p_ready) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_ready = p_ready;
|
||||
if (m_ready) {
|
||||
for (auto &act : m_pendingActions) {
|
||||
act();
|
||||
}
|
||||
m_pendingActions.clear();
|
||||
emit ready();
|
||||
} else {
|
||||
m_pendingActions.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void WebViewAdapter::pendAction(const std::function<void()> &p_func)
|
||||
{
|
||||
Q_ASSERT(!m_ready);
|
||||
m_pendingActions.append(p_func);
|
||||
}
|
||||
|
||||
bool WebViewAdapter::isReady() const
|
||||
{
|
||||
return m_ready;
|
||||
}
|
||||
|
||||
void WebViewAdapter::invokeCallback(quint64 p_id, void *p_data)
|
||||
{
|
||||
m_callbackPool.call(p_id, p_data);
|
||||
}
|
||||
|
||||
quint64 WebViewAdapter::addCallback(const CallbackPool::Callback &p_callback)
|
||||
{
|
||||
return m_callbackPool.add(p_callback);
|
||||
}
|
||||
|
||||
void WebViewAdapter::findText(const QStringList &p_texts, FindOptions p_options, int p_currentMatchLine)
|
||||
{
|
||||
FindOption opts;
|
||||
if (p_options & vnotex::FindOption::FindBackward) {
|
||||
opts.m_findBackward = true;
|
||||
}
|
||||
if (p_options & vnotex::FindOption::CaseSensitive) {
|
||||
opts.m_caseSensitive = true;
|
||||
}
|
||||
if (p_options & vnotex::FindOption::WholeWordOnly) {
|
||||
opts.m_wholeWordOnly = true;
|
||||
}
|
||||
if (p_options & vnotex::FindOption::RegularExpression) {
|
||||
opts.m_regularExpression = true;
|
||||
}
|
||||
|
||||
if (isReady()) {
|
||||
emit findTextRequested(p_texts, opts.toJson(), p_currentMatchLine);
|
||||
} else {
|
||||
pendAction([this, p_texts, opts, p_currentMatchLine]() {
|
||||
// FIXME: highlights will be clear once the page is ready. Add a delay here.
|
||||
Utils::sleepWait(1000);
|
||||
emit findTextRequested(p_texts, opts.toJson(), p_currentMatchLine);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void WebViewAdapter::setFindText(const QStringList &p_texts, int p_totalMatches, int p_currentMatchIndex)
|
||||
{
|
||||
emit findTextReady(p_texts, p_totalMatches, p_currentMatchIndex);
|
||||
}
|
||||
|
71
src/widgets/editors/webviewadapter.h
Normal file
71
src/widgets/editors/webviewadapter.h
Normal file
@ -0,0 +1,71 @@
|
||||
#ifndef WEBVIEWADAPTER_H
|
||||
#define WEBVIEWADAPTER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <QVector>
|
||||
|
||||
#include <utils/callbackpool.h>
|
||||
#include <core/global.h>
|
||||
|
||||
namespace vnotex
|
||||
{
|
||||
// Base class of adapter and interface between CPP and JS for WebView.
|
||||
class WebViewAdapter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit WebViewAdapter(QObject *p_parent = nullptr);
|
||||
|
||||
bool isReady() const;
|
||||
|
||||
void findText(const QStringList &p_texts, FindOptions p_options, int p_currentMatchLine = -1);
|
||||
|
||||
// Functions to be called from web side.
|
||||
public slots:
|
||||
void setReady(bool p_ready);
|
||||
|
||||
void setFindText(const QStringList &p_texts, int p_totalMatches, int p_currentMatchIndex);
|
||||
|
||||
// Signals to be connected at cpp side.
|
||||
signals:
|
||||
void ready();
|
||||
|
||||
void findTextReady(const QStringList &p_texts, int p_totalMatches, int p_currentMatchIndex);
|
||||
|
||||
// Signals to be connected at web side.
|
||||
signals:
|
||||
void findTextRequested(const QStringList &p_texts, const QJsonObject &p_options, int p_currentMatchLine);
|
||||
|
||||
protected:
|
||||
void pendAction(const std::function<void()> &p_func);
|
||||
|
||||
void invokeCallback(quint64 p_id, void *p_data);
|
||||
|
||||
quint64 addCallback(const CallbackPool::Callback &p_callback);
|
||||
|
||||
private:
|
||||
struct FindOption
|
||||
{
|
||||
QJsonObject toJson() const;
|
||||
|
||||
bool m_findBackward = false;
|
||||
|
||||
bool m_caseSensitive = false;
|
||||
|
||||
bool m_wholeWordOnly = false;
|
||||
|
||||
bool m_regularExpression = false;
|
||||
};
|
||||
|
||||
// Whether web side is ready.
|
||||
bool m_ready = false;
|
||||
|
||||
// Pending actions for the editor once it is ready.
|
||||
QVector<std::function<void()>> m_pendingActions;
|
||||
|
||||
CallbackPool m_callbackPool;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // WEBVIEWADAPTER_H
|
@ -325,3 +325,19 @@ FindOptions FindAndReplaceWidget::getOptions() const
|
||||
{
|
||||
return m_options;
|
||||
}
|
||||
|
||||
void FindAndReplaceWidget::setOptionsEnabled(FindOptions p_options, bool p_enabled)
|
||||
{
|
||||
if (p_options & FindOption::CaseSensitive) {
|
||||
m_caseSensitiveCheckBox->setEnabled(p_enabled);
|
||||
}
|
||||
if (p_options & FindOption::WholeWordOnly) {
|
||||
m_wholeWordOnlyCheckBox->setEnabled(p_enabled);
|
||||
}
|
||||
if (p_options & FindOption::RegularExpression) {
|
||||
m_regularExpressionCheckBox->setEnabled(p_enabled);
|
||||
}
|
||||
if (p_options & FindOption::IncrementalSearch) {
|
||||
m_incrementalSearchCheckBox->setEnabled(p_enabled);
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ namespace vnotex
|
||||
|
||||
FindOptions getOptions() const;
|
||||
|
||||
void setOptionsEnabled(FindOptions p_options, bool p_enabled);
|
||||
|
||||
signals:
|
||||
void findTextChanged(const QString &p_text, FindOptions p_options);
|
||||
|
||||
|
@ -140,7 +140,7 @@ void MarkdownViewWindow::setModeInternal(ViewWindowMode p_mode, bool p_syncBuffe
|
||||
setupViewer();
|
||||
|
||||
// Must show the viewer to let it init with the correct DPI.
|
||||
// Will hide it when viewerReady().
|
||||
// Will hide it when ready().
|
||||
m_viewer->show();
|
||||
}
|
||||
|
||||
@ -361,7 +361,7 @@ void MarkdownViewWindow::setupTextEditor()
|
||||
updateEditorFromConfig();
|
||||
|
||||
// Connect viewer and editor.
|
||||
connect(adapter(), &MarkdownViewerAdapter::viewerReady,
|
||||
connect(adapter(), &MarkdownViewerAdapter::ready,
|
||||
m_editor->getHighlighter(), &vte::PegMarkdownHighlighter::updateHighlight);
|
||||
connect(m_editor, &MarkdownEditor::htmlToMarkdownRequested,
|
||||
adapter(), &MarkdownViewerAdapter::htmlToMarkdownRequested);
|
||||
@ -494,7 +494,7 @@ 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,
|
||||
connect(adapter, &MarkdownViewerAdapter::ready,
|
||||
this, [this]() {
|
||||
m_viewerReady = true;
|
||||
|
||||
|
292
src/widgets/mindmapviewwindow.cpp
Normal file
292
src/widgets/mindmapviewwindow.cpp
Normal file
@ -0,0 +1,292 @@
|
||||
#include "mindmapviewwindow.h"
|
||||
|
||||
#include <QToolBar>
|
||||
#include <QSplitter>
|
||||
|
||||
#include <core/vnotex.h>
|
||||
#include <core/thememgr.h>
|
||||
#include <core/htmltemplatehelper.h>
|
||||
#include <core/configmgr.h>
|
||||
#include <core/editorconfig.h>
|
||||
#include <core/mindmapeditorconfig.h>
|
||||
#include <utils/utils.h>
|
||||
#include <utils/pathutils.h>
|
||||
|
||||
#include "toolbarhelper.h"
|
||||
#include "findandreplacewidget.h"
|
||||
#include "editors/mindmapeditor.h"
|
||||
#include "editors/mindmapeditoradapter.h"
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
MindMapViewWindow::MindMapViewWindow(QWidget *p_parent)
|
||||
: ViewWindow(p_parent)
|
||||
{
|
||||
m_mode = ViewWindowMode::Edit;
|
||||
setupUI();
|
||||
}
|
||||
|
||||
void MindMapViewWindow::setupUI()
|
||||
{
|
||||
setupEditor();
|
||||
setCentralWidget(m_editor);
|
||||
|
||||
setupToolBar();
|
||||
}
|
||||
|
||||
void MindMapViewWindow::setupEditor()
|
||||
{
|
||||
Q_ASSERT(!m_editor);
|
||||
|
||||
const auto &editorConfig = ConfigMgr::getInst().getEditorConfig();
|
||||
const auto &mindMapEditorConfig = editorConfig.getMindMapEditorConfig();
|
||||
|
||||
updateConfigRevision();
|
||||
|
||||
HtmlTemplateHelper::updateMindMapEditorTemplate(mindMapEditorConfig);
|
||||
|
||||
auto adapter = new MindMapEditorAdapter(nullptr);
|
||||
m_editor = new MindMapEditor(adapter,
|
||||
VNoteX::getInst().getThemeMgr().getBaseBackground(),
|
||||
1.0,
|
||||
this);
|
||||
connect(m_editor, &MindMapEditor::contentsChanged,
|
||||
this, [this]() {
|
||||
getBuffer()->setModified(m_editor->isModified());
|
||||
getBuffer()->invalidateContent(
|
||||
this, [this](int p_revision) {
|
||||
this->setBufferRevisionAfterInvalidation(p_revision);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
QString MindMapViewWindow::getLatestContent() const
|
||||
{
|
||||
QString content;
|
||||
adapter()->saveData([&content](const QString &p_data) {
|
||||
content = p_data;
|
||||
});
|
||||
|
||||
while (content.isNull()) {
|
||||
Utils::sleepWait(50);
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
QString MindMapViewWindow::selectedText() const
|
||||
{
|
||||
return m_editor->selectedText();
|
||||
}
|
||||
|
||||
void MindMapViewWindow::setMode(ViewWindowMode p_mode)
|
||||
{
|
||||
Q_UNUSED(p_mode);
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
|
||||
void MindMapViewWindow::openTwice(const QSharedPointer<FileOpenParameters> &p_paras)
|
||||
{
|
||||
Q_UNUSED(p_paras);
|
||||
}
|
||||
|
||||
ViewWindowSession MindMapViewWindow::saveSession() const
|
||||
{
|
||||
auto session = ViewWindow::saveSession();
|
||||
return session;
|
||||
}
|
||||
|
||||
void MindMapViewWindow::applySnippet(const QString &p_name)
|
||||
{
|
||||
Q_UNUSED(p_name);
|
||||
}
|
||||
|
||||
void MindMapViewWindow::applySnippet()
|
||||
{
|
||||
}
|
||||
|
||||
void MindMapViewWindow::fetchWordCountInfo(const std::function<void(const WordCountInfo &)> &p_callback) const
|
||||
{
|
||||
Q_UNUSED(p_callback);
|
||||
}
|
||||
|
||||
void MindMapViewWindow::handleEditorConfigChange()
|
||||
{
|
||||
if (updateConfigRevision()) {
|
||||
const auto &editorConfig = ConfigMgr::getInst().getEditorConfig();
|
||||
const auto &mindMapEditorConfig = editorConfig.getMindMapEditorConfig();
|
||||
|
||||
HtmlTemplateHelper::updateMindMapEditorTemplate(mindMapEditorConfig);
|
||||
}
|
||||
}
|
||||
|
||||
void MindMapViewWindow::setModified(bool p_modified)
|
||||
{
|
||||
m_editor->setModified(p_modified);
|
||||
}
|
||||
|
||||
void MindMapViewWindow::print()
|
||||
{
|
||||
}
|
||||
|
||||
void MindMapViewWindow::syncEditorFromBuffer()
|
||||
{
|
||||
auto buffer = getBuffer();
|
||||
if (buffer) {
|
||||
m_editor->setHtml(HtmlTemplateHelper::getMindMapEditorTemplate(),
|
||||
PathUtils::pathToUrl(buffer->getContentPath()));
|
||||
adapter()->setData(buffer->getContent());
|
||||
m_editor->setModified(buffer->isModified());
|
||||
} else {
|
||||
m_editor->setHtml("");
|
||||
adapter()->setData("");
|
||||
m_editor->setModified(false);
|
||||
}
|
||||
|
||||
m_bufferRevision = buffer ? buffer->getRevision() : 0;
|
||||
}
|
||||
|
||||
void MindMapViewWindow::syncEditorFromBufferContent()
|
||||
{
|
||||
auto buffer = getBuffer();
|
||||
Q_ASSERT(buffer);
|
||||
adapter()->setData(buffer->getContent());
|
||||
m_editor->setModified(buffer->isModified());
|
||||
m_bufferRevision = buffer->getRevision();
|
||||
}
|
||||
|
||||
void MindMapViewWindow::scrollUp()
|
||||
{
|
||||
}
|
||||
|
||||
void MindMapViewWindow::scrollDown()
|
||||
{
|
||||
}
|
||||
|
||||
void MindMapViewWindow::zoom(bool p_zoomIn)
|
||||
{
|
||||
Q_UNUSED(p_zoomIn);
|
||||
}
|
||||
|
||||
MindMapEditorAdapter *MindMapViewWindow::adapter() const
|
||||
{
|
||||
if (m_editor) {
|
||||
return dynamic_cast<MindMapEditorAdapter *>(m_editor->adapter());
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool MindMapViewWindow::updateConfigRevision()
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
const auto &editorConfig = ConfigMgr::getInst().getEditorConfig();
|
||||
|
||||
if (m_editorConfigRevision != editorConfig.revision()) {
|
||||
changed = true;
|
||||
m_editorConfigRevision = editorConfig.revision();
|
||||
}
|
||||
|
||||
if (m_editorConfigRevision != editorConfig.getMindMapEditorConfig().revision()) {
|
||||
changed = true;
|
||||
m_editorConfigRevision = editorConfig.getMindMapEditorConfig().revision();
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
void MindMapViewWindow::setupToolBar()
|
||||
{
|
||||
auto toolBar = createToolBar(this);
|
||||
addToolBar(toolBar);
|
||||
|
||||
addAction(toolBar, ViewWindowToolBarHelper::Save);
|
||||
|
||||
toolBar->addSeparator();
|
||||
|
||||
addAction(toolBar, ViewWindowToolBarHelper::Attachment);
|
||||
|
||||
addAction(toolBar, ViewWindowToolBarHelper::Tag);
|
||||
|
||||
ToolBarHelper::addSpacer(toolBar);
|
||||
|
||||
addAction(toolBar, ViewWindowToolBarHelper::FindAndReplace);
|
||||
|
||||
addAction(toolBar, ViewWindowToolBarHelper::Debug);
|
||||
}
|
||||
|
||||
void MindMapViewWindow::toggleDebug()
|
||||
{
|
||||
if (m_debugViewer) {
|
||||
bool shouldEnable = !m_debugViewer->isVisible();
|
||||
m_debugViewer->setVisible(shouldEnable);
|
||||
m_editor->page()->setDevToolsPage(shouldEnable ? m_debugViewer->page() : nullptr);
|
||||
} else {
|
||||
setupDebugViewer();
|
||||
m_editor->page()->setDevToolsPage(m_debugViewer->page());
|
||||
}
|
||||
}
|
||||
|
||||
void MindMapViewWindow::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_editor);
|
||||
mainSplitter->setFocusProxy(m_editor);
|
||||
|
||||
m_debugViewer = new WebViewer(VNoteX::getInst().getThemeMgr().getBaseBackground(), this);
|
||||
m_debugViewer->resize(m_editor->width(), m_editor->height() / 2);
|
||||
mainSplitter->addWidget(m_debugViewer);
|
||||
}
|
||||
|
||||
void MindMapViewWindow::handleFindTextChanged(const QString &p_text, FindOptions p_options)
|
||||
{
|
||||
if (p_options & FindOption::IncrementalSearch) {
|
||||
m_editor->findText(p_text, p_options);
|
||||
}
|
||||
}
|
||||
|
||||
void MindMapViewWindow::handleFindNext(const QStringList &p_texts, FindOptions p_options)
|
||||
{
|
||||
// We do not use mark.js for searching as the contents are mainly SVG.
|
||||
m_editor->findText(p_texts.empty() ? QString() : p_texts[0], p_options);
|
||||
}
|
||||
|
||||
void MindMapViewWindow::handleReplace(const QString &p_text, FindOptions p_options, const QString &p_replaceText)
|
||||
{
|
||||
Q_UNUSED(p_text);
|
||||
Q_UNUSED(p_options);
|
||||
Q_UNUSED(p_replaceText);
|
||||
showMessage(tr("Replace is not supported yet"));
|
||||
}
|
||||
|
||||
void MindMapViewWindow::handleReplaceAll(const QString &p_text, FindOptions p_options, const QString &p_replaceText)
|
||||
{
|
||||
Q_UNUSED(p_text);
|
||||
Q_UNUSED(p_options);
|
||||
Q_UNUSED(p_replaceText);
|
||||
showMessage(tr("Replace is not supported yet"));
|
||||
}
|
||||
|
||||
void MindMapViewWindow::handleFindAndReplaceWidgetClosed()
|
||||
{
|
||||
m_editor->findText(QString(), FindOption::FindNone);
|
||||
}
|
||||
|
||||
void MindMapViewWindow::showFindAndReplaceWidget()
|
||||
{
|
||||
bool isFirstTime = !m_findAndReplace;
|
||||
ViewWindow::showFindAndReplaceWidget();
|
||||
if (isFirstTime) {
|
||||
m_findAndReplace->setReplaceEnabled(false);
|
||||
m_findAndReplace->setOptionsEnabled(FindOption::WholeWordOnly | FindOption::RegularExpression, false);
|
||||
}
|
||||
}
|
93
src/widgets/mindmapviewwindow.h
Normal file
93
src/widgets/mindmapviewwindow.h
Normal file
@ -0,0 +1,93 @@
|
||||
#ifndef MINDMAPVIEWWINDOW_H
|
||||
#define MINDMAPVIEWWINDOW_H
|
||||
|
||||
#include "viewwindow.h"
|
||||
|
||||
#include <QScopedPointer>
|
||||
|
||||
class QWebEngineView;
|
||||
|
||||
namespace vnotex
|
||||
{
|
||||
class MindMapEditor;
|
||||
class MindMapEditorAdapter;
|
||||
|
||||
class MindMapViewWindow : public ViewWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MindMapViewWindow(QWidget *p_parent = nullptr);
|
||||
|
||||
QString getLatestContent() const Q_DECL_OVERRIDE;
|
||||
|
||||
QString selectedText() const Q_DECL_OVERRIDE;
|
||||
|
||||
void setMode(ViewWindowMode p_mode) Q_DECL_OVERRIDE;
|
||||
|
||||
void openTwice(const QSharedPointer<FileOpenParameters> &p_paras) Q_DECL_OVERRIDE;
|
||||
|
||||
ViewWindowSession saveSession() const Q_DECL_OVERRIDE;
|
||||
|
||||
void applySnippet(const QString &p_name) Q_DECL_OVERRIDE;
|
||||
|
||||
void applySnippet() Q_DECL_OVERRIDE;
|
||||
|
||||
void fetchWordCountInfo(const std::function<void(const WordCountInfo &)> &p_callback) const Q_DECL_OVERRIDE;
|
||||
|
||||
public slots:
|
||||
void handleEditorConfigChange() Q_DECL_OVERRIDE;
|
||||
|
||||
protected slots:
|
||||
void setModified(bool p_modified) Q_DECL_OVERRIDE;
|
||||
|
||||
void print() Q_DECL_OVERRIDE;
|
||||
|
||||
void toggleDebug() Q_DECL_OVERRIDE;
|
||||
|
||||
void handleFindTextChanged(const QString &p_text, FindOptions p_options) Q_DECL_OVERRIDE;
|
||||
|
||||
void handleFindNext(const QStringList &p_texts, FindOptions p_options) Q_DECL_OVERRIDE;
|
||||
|
||||
void handleReplace(const QString &p_text, FindOptions p_options, const QString &p_replaceText) Q_DECL_OVERRIDE;
|
||||
|
||||
void handleReplaceAll(const QString &p_text, FindOptions p_options, const QString &p_replaceText) Q_DECL_OVERRIDE;
|
||||
|
||||
void handleFindAndReplaceWidgetClosed() Q_DECL_OVERRIDE;
|
||||
|
||||
void showFindAndReplaceWidget() Q_DECL_OVERRIDE;
|
||||
|
||||
protected:
|
||||
void syncEditorFromBuffer() Q_DECL_OVERRIDE;
|
||||
|
||||
void syncEditorFromBufferContent() Q_DECL_OVERRIDE;
|
||||
|
||||
void scrollUp() Q_DECL_OVERRIDE;
|
||||
|
||||
void scrollDown() Q_DECL_OVERRIDE;
|
||||
|
||||
void zoom(bool p_zoomIn) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
void setupUI();
|
||||
|
||||
void setupToolBar();
|
||||
|
||||
void setupEditor();
|
||||
|
||||
MindMapEditorAdapter *adapter() const;
|
||||
|
||||
bool updateConfigRevision();
|
||||
|
||||
void setupDebugViewer();
|
||||
|
||||
// Managed by QObject.
|
||||
MindMapEditor *m_editor = nullptr;
|
||||
|
||||
// Used to debug web view.
|
||||
QWebEngineView *m_debugViewer = nullptr;
|
||||
|
||||
int m_editorConfigRevision = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MINDMAPVIEWWINDOW_H
|
@ -24,6 +24,16 @@ void PdfViewWindow::setupUI()
|
||||
{
|
||||
setupViewer();
|
||||
setCentralWidget(m_viewer);
|
||||
|
||||
setupToolBar();
|
||||
}
|
||||
|
||||
void PdfViewWindow::setupToolBar()
|
||||
{
|
||||
auto toolBar = createToolBar(this);
|
||||
addToolBar(toolBar);
|
||||
|
||||
addAction(toolBar, ViewWindowToolBarHelper::Tag);
|
||||
}
|
||||
|
||||
void PdfViewWindow::setupViewer()
|
||||
@ -68,7 +78,6 @@ void PdfViewWindow::openTwice(const QSharedPointer<FileOpenParameters> &p_paras)
|
||||
ViewWindowSession PdfViewWindow::saveSession() const
|
||||
{
|
||||
auto session = ViewWindow::saveSession();
|
||||
session.m_lineNumber = 1;
|
||||
return session;
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,6 @@ namespace vnotex
|
||||
{
|
||||
class PdfViewer;
|
||||
class PdfViewerAdapter;
|
||||
class EditorConfig;
|
||||
|
||||
class PdfViewWindow : public ViewWindow
|
||||
{
|
||||
@ -57,6 +56,8 @@ namespace vnotex
|
||||
private:
|
||||
void setupUI();
|
||||
|
||||
void setupToolBar();
|
||||
|
||||
void setupViewer();
|
||||
|
||||
PdfViewerAdapter *adapter() const;
|
||||
|
@ -165,11 +165,6 @@ bool TextViewWindow::updateConfigRevision()
|
||||
return changed;
|
||||
}
|
||||
|
||||
void TextViewWindow::setBufferRevisionAfterInvalidation(int p_bufferRevision)
|
||||
{
|
||||
m_bufferRevision = p_bufferRevision;
|
||||
}
|
||||
|
||||
void TextViewWindow::setMode(ViewWindowMode p_mode)
|
||||
{
|
||||
Q_UNUSED(p_mode);
|
||||
|
@ -79,11 +79,6 @@ namespace vnotex
|
||||
|
||||
void setupToolBar();
|
||||
|
||||
// When we have new changes to the buffer content from our ViewWindow,
|
||||
// we will invalidate the contents of the buffer and the buffer will
|
||||
// call this function to tell us now the latest buffer revision.
|
||||
void setBufferRevisionAfterInvalidation(int p_bufferRevision);
|
||||
|
||||
void updateEditorFromConfig();
|
||||
|
||||
void handleFileOpenParameters(const QSharedPointer<FileOpenParameters> &p_paras);
|
||||
|
@ -1402,3 +1402,8 @@ void ViewWindow::print()
|
||||
void ViewWindow::clearHighlights()
|
||||
{
|
||||
}
|
||||
|
||||
void ViewWindow::setBufferRevisionAfterInvalidation(int p_bufferRevision)
|
||||
{
|
||||
m_bufferRevision = p_bufferRevision;
|
||||
}
|
||||
|
@ -227,6 +227,11 @@ namespace vnotex
|
||||
// Sync buffer content changes to editor.
|
||||
virtual void syncEditorFromBufferContent() = 0;
|
||||
|
||||
// When we have new changes to the buffer content from our ViewWindow,
|
||||
// we will invalidate the contents of the buffer and the buffer will
|
||||
// call this function to tell us now the latest buffer revision.
|
||||
void setBufferRevisionAfterInvalidation(int p_bufferRevision);
|
||||
|
||||
// Whether we are in a mode that enable us to insert text.
|
||||
bool inModeCanInsert() const;
|
||||
|
||||
@ -242,7 +247,7 @@ namespace vnotex
|
||||
|
||||
void showZoomDelta(int p_delta);
|
||||
|
||||
void showFindAndReplaceWidget();
|
||||
virtual void showFindAndReplaceWidget();
|
||||
|
||||
void hideFindAndReplaceWidget();
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
#include "webpage.h"
|
||||
|
||||
#include <QWebEnginePage>
|
||||
|
||||
#include <utils/utils.h>
|
||||
|
||||
using namespace vnotex;
|
||||
@ -38,3 +40,20 @@ WebViewer::WebViewer(const QColor &p_background, QWidget *p_parent)
|
||||
WebViewer::~WebViewer()
|
||||
{
|
||||
}
|
||||
|
||||
void WebViewer::findText(const QString &p_text, FindOptions p_options)
|
||||
{
|
||||
if (p_options & FindOption::RegularExpression) {
|
||||
return;
|
||||
}
|
||||
|
||||
QWebEnginePage::FindFlags flags;
|
||||
if (p_options & FindOption::FindBackward) {
|
||||
flags |= QWebEnginePage::FindFlag::FindBackward;
|
||||
}
|
||||
if (p_options & FindOption::CaseSensitive) {
|
||||
flags |= QWebEnginePage::FindFlag::FindCaseSensitively;
|
||||
}
|
||||
|
||||
QWebEngineView::findText(p_text, flags);
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
#include <QWebEngineView>
|
||||
|
||||
#include <core/global.h>
|
||||
|
||||
namespace vnotex
|
||||
{
|
||||
class WebViewer : public QWebEngineView
|
||||
@ -15,6 +17,8 @@ namespace vnotex
|
||||
|
||||
virtual ~WebViewer();
|
||||
|
||||
void findText(const QString &p_text, FindOptions p_options);
|
||||
|
||||
signals:
|
||||
void linkHovered(const QString &p_url);
|
||||
};
|
||||
|
@ -51,12 +51,15 @@ SOURCES += \
|
||||
$$PWD/editors/markdowntablehelper.cpp \
|
||||
$$PWD/editors/markdownviewer.cpp \
|
||||
$$PWD/editors/markdownvieweradapter.cpp \
|
||||
$$PWD/editors/mindmapeditor.cpp \
|
||||
$$PWD/editors/mindmapeditoradapter.cpp \
|
||||
$$PWD/editors/pdfviewer.cpp \
|
||||
$$PWD/editors/pdfvieweradapter.cpp \
|
||||
$$PWD/editors/plantumlhelper.cpp \
|
||||
$$PWD/editors/previewhelper.cpp \
|
||||
$$PWD/editors/statuswidget.cpp \
|
||||
$$PWD/editors/texteditor.cpp \
|
||||
$$PWD/editors/webviewadapter.cpp \
|
||||
$$PWD/editreaddiscardaction.cpp \
|
||||
$$PWD/filesystemviewer.cpp \
|
||||
$$PWD/dialogs/folderfilesfilterwidget.cpp \
|
||||
@ -77,6 +80,7 @@ SOURCES += \
|
||||
$$PWD/locationlist.cpp \
|
||||
$$PWD/mainwindow.cpp \
|
||||
$$PWD/markdownviewwindow.cpp \
|
||||
$$PWD/mindmapviewwindow.cpp \
|
||||
$$PWD/navigationmodemgr.cpp \
|
||||
$$PWD/notebookexplorersession.cpp \
|
||||
$$PWD/outlinepopup.cpp \
|
||||
@ -186,12 +190,15 @@ HEADERS += \
|
||||
$$PWD/editors/markdowntablehelper.h \
|
||||
$$PWD/editors/markdownviewer.h \
|
||||
$$PWD/editors/markdownvieweradapter.h \
|
||||
$$PWD/editors/mindmapeditor.h \
|
||||
$$PWD/editors/mindmapeditoradapter.h \
|
||||
$$PWD/editors/pdfviewer.h \
|
||||
$$PWD/editors/pdfvieweradapter.h \
|
||||
$$PWD/editors/plantumlhelper.h \
|
||||
$$PWD/editors/previewhelper.h \
|
||||
$$PWD/editors/statuswidget.h \
|
||||
$$PWD/editors/texteditor.h \
|
||||
$$PWD/editors/webviewadapter.h \
|
||||
$$PWD/editreaddiscardaction.h \
|
||||
$$PWD/filesystemviewer.h \
|
||||
$$PWD/dialogs/folderfilesfilterwidget.h \
|
||||
@ -213,6 +220,7 @@ HEADERS += \
|
||||
$$PWD/locationlist.h \
|
||||
$$PWD/mainwindow.h \
|
||||
$$PWD/markdownviewwindow.h \
|
||||
$$PWD/mindmapviewwindow.h \
|
||||
$$PWD/navigationmodemgr.h \
|
||||
$$PWD/navigationmodewrapper.h \
|
||||
$$PWD/notebookexplorersession.h \
|
||||
|
Loading…
x
Reference in New Issue
Block a user