mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 05:49:53 +08:00
Dev (#1644)
* add file type combobox in NewNoteDialog * add SectionNumberStyle
This commit is contained in:
parent
9dd83a6f2f
commit
6503b433e1
@ -1 +1 @@
|
||||
Subproject commit 5fe5d4be7191de58fd1c2411b1ff97bcbecfaa3d
|
||||
Subproject commit 69bd57656ccac8cf75502506be0c87d80d86e577
|
@ -1,54 +1,123 @@
|
||||
#include "filetypehelper.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QDebug>
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
#include "buffer.h"
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
const FileType FileTypeHelper::s_markdownFileType = "markdown";
|
||||
FileTypeHelper::FileTypeHelper()
|
||||
{
|
||||
setupBuiltInTypes();
|
||||
|
||||
const FileType FileTypeHelper::s_textFileType = "text";
|
||||
// TODO: read configuration file.
|
||||
|
||||
const FileType FileTypeHelper::s_unknownFileType = "unknown";
|
||||
setupSuffixTypeMap();
|
||||
}
|
||||
|
||||
QSharedPointer<QMap<QString, FileType>> FileTypeHelper::s_fileTypeMap;
|
||||
void FileTypeHelper::setupBuiltInTypes()
|
||||
{
|
||||
{
|
||||
FileType type;
|
||||
type.m_type = Type::Markdown;
|
||||
type.m_displayName = Buffer::tr("Markdown");
|
||||
type.m_typeName = QStringLiteral("Markdown");
|
||||
type.m_suffixes << QStringLiteral("md") << QStringLiteral("mkd") << QStringLiteral("markdown");
|
||||
m_fileTypes.push_back(type);
|
||||
}
|
||||
|
||||
FileType FileTypeHelper::fileType(const QString &p_filePath)
|
||||
{
|
||||
FileType type;
|
||||
type.m_type = Type::Text;
|
||||
type.m_typeName = QStringLiteral("Text");
|
||||
type.m_displayName = Buffer::tr("Text");
|
||||
type.m_suffixes << QStringLiteral("txt") << QStringLiteral("text") << QStringLiteral("log");
|
||||
m_fileTypes.push_back(type);
|
||||
}
|
||||
|
||||
{
|
||||
FileType type;
|
||||
type.m_type = Type::Others;
|
||||
type.m_typeName = QStringLiteral("Others");
|
||||
type.m_displayName = Buffer::tr("Others");
|
||||
m_fileTypes.push_back(type);
|
||||
}
|
||||
}
|
||||
|
||||
const FileType &FileTypeHelper::getFileType(const QString &p_filePath) const
|
||||
{
|
||||
Q_ASSERT(!p_filePath.isEmpty());
|
||||
|
||||
if (!s_fileTypeMap) {
|
||||
init();
|
||||
}
|
||||
|
||||
QFileInfo fi(p_filePath);
|
||||
auto suffix = fi.suffix().toLower();
|
||||
auto it = s_fileTypeMap->find(suffix);
|
||||
if (it != s_fileTypeMap->end()) {
|
||||
return it.value();
|
||||
auto it = m_suffixTypeMap.find(suffix);
|
||||
if (it != m_suffixTypeMap.end()) {
|
||||
return m_fileTypes.at(it.value());
|
||||
}
|
||||
|
||||
// Treat all unknown text files as plain text files.
|
||||
if (FileUtils::isText(p_filePath)) {
|
||||
return s_fileTypeMap->value(QStringLiteral("txt"));
|
||||
return m_fileTypes[Type::Text];
|
||||
}
|
||||
|
||||
return s_unknownFileType;
|
||||
return m_fileTypes[Type::Others];
|
||||
}
|
||||
|
||||
#define ADD(x, y) s_fileTypeMap->insert((x), (y))
|
||||
|
||||
void FileTypeHelper::init()
|
||||
const FileType &FileTypeHelper::getFileTypeBySuffix(const QString &p_suffix) const
|
||||
{
|
||||
// TODO: load mapping from configuration file.
|
||||
s_fileTypeMap.reset(new QMap<QString, FileType>());
|
||||
|
||||
ADD(QStringLiteral("md"), s_markdownFileType);
|
||||
ADD(QStringLiteral("markdown"), s_markdownFileType);
|
||||
ADD(QStringLiteral("mkd"), s_markdownFileType);
|
||||
|
||||
ADD(QStringLiteral("txt"), s_textFileType);
|
||||
ADD(QStringLiteral("text"), s_textFileType);
|
||||
ADD(QStringLiteral("log"), s_textFileType);
|
||||
auto it = m_suffixTypeMap.find(p_suffix.toLower());
|
||||
if (it != m_suffixTypeMap.end()) {
|
||||
return m_fileTypes.at(it.value());
|
||||
} else {
|
||||
return m_fileTypes[Type::Others];
|
||||
}
|
||||
}
|
||||
|
||||
#define ADD(x, y) m_suffixTypeMap.insert((x), (y))
|
||||
|
||||
void FileTypeHelper::setupSuffixTypeMap()
|
||||
{
|
||||
for (int i = 0; i < m_fileTypes.size(); ++i) {
|
||||
for (const auto &suffix : m_fileTypes[i].m_suffixes) {
|
||||
if (m_suffixTypeMap.contains(suffix)) {
|
||||
qWarning() << "suffix conflicts detected" << suffix << m_fileTypes[i].m_type;
|
||||
}
|
||||
m_suffixTypeMap.insert(suffix, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const QVector<FileType> &FileTypeHelper::getAllFileTypes() const
|
||||
{
|
||||
return m_fileTypes;
|
||||
}
|
||||
|
||||
const FileType &FileTypeHelper::getFileType(Type p_type) const
|
||||
{
|
||||
return m_fileTypes[p_type];
|
||||
}
|
||||
|
||||
const FileTypeHelper &FileTypeHelper::getInst()
|
||||
{
|
||||
static FileTypeHelper helper;
|
||||
return helper;
|
||||
}
|
||||
|
||||
bool FileTypeHelper::checkFileType(const QString &p_filePath, Type p_type) const
|
||||
{
|
||||
return getFileType(p_filePath).m_type == static_cast<int>(p_type);
|
||||
}
|
||||
|
||||
const FileType &FileTypeHelper::getFileTypeByName(const QString &p_typeName) const
|
||||
{
|
||||
for (const auto &ft : m_fileTypes) {
|
||||
if (ft.m_typeName == p_typeName) {
|
||||
return ft;
|
||||
}
|
||||
}
|
||||
|
||||
Q_ASSERT(false);
|
||||
return m_fileTypes[Type::Others];
|
||||
}
|
||||
|
@ -3,30 +3,65 @@
|
||||
|
||||
#include <QString>
|
||||
#include <QMap>
|
||||
#include <QSharedPointer>
|
||||
#include <QVector>
|
||||
|
||||
namespace vnotex
|
||||
{
|
||||
typedef QString FileType;
|
||||
class FileType
|
||||
{
|
||||
public:
|
||||
// FileTypeHelper::Type.
|
||||
int m_type = -1;
|
||||
|
||||
QString m_typeName;
|
||||
|
||||
QString m_displayName;
|
||||
|
||||
QStringList m_suffixes;
|
||||
|
||||
QString preferredSuffix() const
|
||||
{
|
||||
return m_suffixes.isEmpty() ? QString() : m_suffixes.first();
|
||||
}
|
||||
};
|
||||
|
||||
// Map file suffix to file type.
|
||||
class FileTypeHelper
|
||||
{
|
||||
public:
|
||||
FileTypeHelper() = delete;
|
||||
enum Type
|
||||
{
|
||||
Markdown = 0,
|
||||
Text,
|
||||
Others
|
||||
};
|
||||
|
||||
static FileType fileType(const QString &p_filePath);
|
||||
const FileType &getFileType(const QString &p_filePath) const;
|
||||
|
||||
static const FileType s_markdownFileType;
|
||||
const FileType &getFileType(Type p_type) const;
|
||||
|
||||
static const FileType s_textFileType;
|
||||
const FileType &getFileTypeByName(const QString &p_typeName) const;
|
||||
|
||||
static const FileType s_unknownFileType;
|
||||
const FileType &getFileTypeBySuffix(const QString &p_suffix) const;
|
||||
|
||||
const QVector<FileType> &getAllFileTypes() const;
|
||||
|
||||
bool checkFileType(const QString &p_filePath, Type p_type) const;
|
||||
|
||||
static const FileTypeHelper &getInst();
|
||||
|
||||
private:
|
||||
static void init();
|
||||
FileTypeHelper();
|
||||
|
||||
static QSharedPointer<QMap<QString, FileType>> s_fileTypeMap;
|
||||
void setupBuiltInTypes();
|
||||
|
||||
void setupSuffixTypeMap();
|
||||
|
||||
// Built-in Type could be accessed via enum Type.
|
||||
QVector<FileType> m_fileTypes;
|
||||
|
||||
// suffix -> index of m_fileTypes.
|
||||
// TODO: handle suffix conflicts.
|
||||
QMap<QString, int> m_suffixTypeMap;
|
||||
};
|
||||
} // ns vnotex
|
||||
|
||||
|
@ -37,13 +37,15 @@ void BufferMgr::initBufferServer()
|
||||
{
|
||||
m_bufferServer.reset(new NameBasedServer<IBufferFactory>);
|
||||
|
||||
const auto &helper = FileTypeHelper::getInst();
|
||||
|
||||
// Markdown.
|
||||
auto markdownFactory = QSharedPointer<MarkdownBufferFactory>::create();
|
||||
m_bufferServer->registerItem(FileTypeHelper::s_markdownFileType, markdownFactory);
|
||||
m_bufferServer->registerItem(helper.getFileType(FileTypeHelper::Markdown).m_typeName, markdownFactory);
|
||||
|
||||
// Text.
|
||||
auto textFactory = QSharedPointer<TextBufferFactory>::create();
|
||||
m_bufferServer->registerItem(FileTypeHelper::s_textFileType, textFactory);
|
||||
m_bufferServer->registerItem(helper.getFileType(FileTypeHelper::Text).m_typeName, textFactory);
|
||||
}
|
||||
|
||||
void BufferMgr::open(Node *p_node, const QSharedPointer<FileOpenParameters> &p_paras)
|
||||
@ -59,11 +61,11 @@ void BufferMgr::open(Node *p_node, const QSharedPointer<FileOpenParameters> &p_p
|
||||
auto buffer = findBuffer(p_node);
|
||||
if (!buffer) {
|
||||
auto nodePath = p_node->fetchAbsolutePath();
|
||||
auto fileType = FileTypeHelper::fileType(nodePath);
|
||||
auto fileType = FileTypeHelper::getInst().getFileType(nodePath).m_typeName;
|
||||
auto factory = m_bufferServer->getItem(fileType);
|
||||
if (!factory) {
|
||||
// No factory to open this file type.
|
||||
qInfo() << "File will be opened by system:" << nodePath;
|
||||
qInfo() << "file will be opened by default program" << nodePath;
|
||||
WidgetUtils::openUrlByDesktop(QUrl::fromLocalFile(nodePath));
|
||||
return;
|
||||
}
|
||||
@ -102,11 +104,11 @@ void BufferMgr::open(const QString &p_filePath, const QSharedPointer<FileOpenPar
|
||||
auto buffer = findBuffer(p_filePath);
|
||||
if (!buffer) {
|
||||
// Open it as external file.
|
||||
auto fileType = FileTypeHelper::fileType(p_filePath);
|
||||
auto fileType = FileTypeHelper::getInst().getFileType(p_filePath).m_typeName;
|
||||
auto factory = m_bufferServer->getItem(fileType);
|
||||
if (!factory) {
|
||||
// No factory to open this file type.
|
||||
qInfo() << "File will be opened by system:" << p_filePath;
|
||||
qInfo() << "file will be opened by default program" << p_filePath;
|
||||
WidgetUtils::openUrlByDesktop(QUrl::fromLocalFile(p_filePath));
|
||||
return;
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ void MarkdownEditorConfig::init(const QJsonObject &p_app, const QJsonObject &p_u
|
||||
|
||||
m_sectionNumberMode = stringToSectionNumberMode(READSTR(QStringLiteral("section_number")));
|
||||
m_sectionNumberBaseLevel = READINT(QStringLiteral("section_number_base_level"));
|
||||
m_sectionNumberStyle = stringToSectionNumberStyle(READSTR(QStringLiteral("section_number_style")));
|
||||
|
||||
m_constrainImageWidthEnabled = READBOOL(QStringLiteral("constrain_image_width"));
|
||||
m_constrainInPlacePreviewWidthEnabled = READBOOL(QStringLiteral("constrain_inplace_preview_width"));
|
||||
@ -61,6 +62,7 @@ QJsonObject MarkdownEditorConfig::toJson() const
|
||||
|
||||
obj[QStringLiteral("section_number")] = sectionNumberModeToString(m_sectionNumberMode);
|
||||
obj[QStringLiteral("section_number_base_level")] = m_sectionNumberBaseLevel;
|
||||
obj[QStringLiteral("section_number_style")] = sectionNumberStyleToString(m_sectionNumberStyle);
|
||||
|
||||
obj[QStringLiteral("constrain_image_width")] = m_constrainImageWidthEnabled;
|
||||
obj[QStringLiteral("constrain_inplace_preview_width")] = m_constrainInPlacePreviewWidthEnabled;
|
||||
@ -267,6 +269,27 @@ MarkdownEditorConfig::SectionNumberMode MarkdownEditorConfig::stringToSectionNum
|
||||
}
|
||||
}
|
||||
|
||||
QString MarkdownEditorConfig::sectionNumberStyleToString(SectionNumberStyle p_style) const
|
||||
{
|
||||
switch (p_style) {
|
||||
case SectionNumberStyle::DigDotDig:
|
||||
return QStringLiteral("digdotdig");
|
||||
|
||||
default:
|
||||
return QStringLiteral("digdotdigdot");
|
||||
}
|
||||
}
|
||||
|
||||
MarkdownEditorConfig::SectionNumberStyle MarkdownEditorConfig::stringToSectionNumberStyle(const QString &p_str) const
|
||||
{
|
||||
auto style = p_str.toLower();
|
||||
if (style == QStringLiteral("digdotdig")) {
|
||||
return SectionNumberStyle::DigDotDig;
|
||||
} else {
|
||||
return SectionNumberStyle::DigDotDigDot;
|
||||
}
|
||||
}
|
||||
|
||||
MarkdownEditorConfig::SectionNumberMode MarkdownEditorConfig::getSectionNumberMode() const
|
||||
{
|
||||
return m_sectionNumberMode;
|
||||
@ -286,3 +309,13 @@ void MarkdownEditorConfig::setSectionNumberBaseLevel(int p_level)
|
||||
{
|
||||
updateConfig(m_sectionNumberBaseLevel, p_level, this);
|
||||
}
|
||||
|
||||
MarkdownEditorConfig::SectionNumberStyle MarkdownEditorConfig::getSectionNumberStyle() const
|
||||
{
|
||||
return m_sectionNumberStyle;
|
||||
}
|
||||
|
||||
void MarkdownEditorConfig::setSectionNumberStyle(SectionNumberStyle p_style)
|
||||
{
|
||||
updateConfig(m_sectionNumberStyle, p_style, this);
|
||||
}
|
||||
|
@ -22,6 +22,14 @@ namespace vnotex
|
||||
Edit
|
||||
};
|
||||
|
||||
enum SectionNumberStyle
|
||||
{
|
||||
// 1.1.
|
||||
DigDotDigDot,
|
||||
// 1.1
|
||||
DigDotDig
|
||||
};
|
||||
|
||||
MarkdownEditorConfig(ConfigMgr *p_mgr,
|
||||
IConfig *p_topConfig,
|
||||
const QSharedPointer<TextEditorConfig> &p_textEditorConfig);
|
||||
@ -58,6 +66,9 @@ namespace vnotex
|
||||
int getSectionNumberBaseLevel() const;
|
||||
void setSectionNumberBaseLevel(int p_level);
|
||||
|
||||
SectionNumberStyle getSectionNumberStyle() const;
|
||||
void setSectionNumberStyle(SectionNumberStyle p_style);
|
||||
|
||||
bool getConstrainImageWidthEnabled() const;
|
||||
void setConstrainImageWidthEnabled(bool p_enabled);
|
||||
|
||||
@ -88,6 +99,9 @@ namespace vnotex
|
||||
QString sectionNumberModeToString(SectionNumberMode p_mode) const;
|
||||
SectionNumberMode stringToSectionNumberMode(const QString &p_str) const;
|
||||
|
||||
QString sectionNumberStyleToString(SectionNumberStyle p_style) const;
|
||||
SectionNumberStyle stringToSectionNumberStyle(const QString &p_str) const;
|
||||
|
||||
QSharedPointer<TextEditorConfig> m_textEditorConfig;
|
||||
|
||||
ViewerResource m_viewerResource;
|
||||
@ -112,6 +126,9 @@ namespace vnotex
|
||||
// 1 based.
|
||||
int m_sectionNumberBaseLevel = 2;
|
||||
|
||||
// Section number style.
|
||||
SectionNumberStyle m_sectionNumberStyle = SectionNumberStyle::DigDotDigDot;
|
||||
|
||||
// Whether enable image width constraint.
|
||||
bool m_constrainImageWidthEnabled = true;
|
||||
|
||||
|
@ -23,8 +23,8 @@ void NodeContentMediaUtils::copyMediaFiles(const Node *p_node,
|
||||
const QString &p_destFilePath)
|
||||
{
|
||||
Q_ASSERT(p_node->getType() == Node::Type::File);
|
||||
auto fileType = FileTypeHelper::fileType(p_node->fetchAbsolutePath());
|
||||
if (fileType == QStringLiteral("markdown")) {
|
||||
const auto &fileType = FileTypeHelper::getInst().getFileType(p_node->fetchAbsolutePath());
|
||||
if (fileType.m_type == FileTypeHelper::Markdown) {
|
||||
copyMarkdownMediaFiles(p_node->read(),
|
||||
PathUtils::parentDirPath(p_node->fetchContentPath()),
|
||||
p_backend,
|
||||
@ -36,8 +36,8 @@ void NodeContentMediaUtils::copyMediaFiles(const QString &p_filePath,
|
||||
INotebookBackend *p_backend,
|
||||
const QString &p_destFilePath)
|
||||
{
|
||||
auto fileType = FileTypeHelper::fileType(p_filePath);
|
||||
if (fileType == QStringLiteral("markdown")) {
|
||||
const auto &fileType = FileTypeHelper::getInst().getFileType(p_filePath);
|
||||
if (fileType.m_type == FileTypeHelper::Markdown) {
|
||||
copyMarkdownMediaFiles(FileUtils::readTextFile(p_filePath),
|
||||
PathUtils::parentDirPath(p_filePath),
|
||||
p_backend,
|
||||
@ -112,8 +112,8 @@ void NodeContentMediaUtils::copyMarkdownMediaFiles(const QString &p_content,
|
||||
void NodeContentMediaUtils::removeMediaFiles(const Node *p_node)
|
||||
{
|
||||
Q_ASSERT(p_node->getType() == Node::Type::File);
|
||||
auto fileType = FileTypeHelper::fileType(p_node->fetchAbsolutePath());
|
||||
if (fileType == QStringLiteral("markdown")) {
|
||||
const auto &fileType = FileTypeHelper::getInst().getFileType(p_node->fetchAbsolutePath());
|
||||
if (fileType.m_type == FileTypeHelper::Markdown) {
|
||||
removeMarkdownMediaFiles(p_node);
|
||||
}
|
||||
}
|
||||
@ -162,8 +162,8 @@ void NodeContentMediaUtils::copyAttachment(Node *p_node,
|
||||
return;
|
||||
}
|
||||
|
||||
auto fileType = FileTypeHelper::fileType(p_node->fetchAbsolutePath());
|
||||
if (fileType == QStringLiteral("markdown")) {
|
||||
const auto &fileType = FileTypeHelper::getInst().getFileType(p_node->fetchAbsolutePath());
|
||||
if (fileType.m_type == FileTypeHelper::Markdown) {
|
||||
fixMarkdownLinks(srcAttachmentFolderPath, p_backend, p_destFilePath, p_destAttachmentFolderPath);
|
||||
}
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
<svg t="1600000206395" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9662" width="512" height="512"><path d="M0 616.192l321.344 206.624 0-149.152L130.016 555.52l191.328-118.144L321.344 287.2 0 494.88 0 616.192zM389.312 896l110.592 0 162.048-768-111.328 0L389.312 896zM702.688 287.2l0 150.176 191.264 118.144-191.264 118.112 0 149.152L1024 616.192l0-121.312L702.688 287.2z" p-id="9663" fill="#000000"></path></svg>
|
||||
<?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="1609914714422" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7578" width="512" height="512" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M516.551 695.182c0 5.006 3.869 9.102 8.533 9.102h210.49c4.664 0 8.533-4.096 8.533-9.102V640.57c0-5.006-3.869-9.102-8.534-9.102H525.084c-4.664 0-8.533 4.096-8.533 9.102v54.613z m-221.753 6.94L513.252 518.94c4.323-3.64 4.323-10.353 0-13.994L294.798 321.877c-5.916-5.006-14.905-0.796-14.905 6.94v71.34c0 2.73 1.138 5.233 3.3 6.94L408.12 512 283.193 616.903c-2.048 1.707-3.3 4.324-3.3 6.94v71.34c0 7.736 8.989 11.946 14.905 6.94z" p-id="7579" fill="#000000"></path><path d="M930.702 56.889H93.298c-20.139 0-36.41 16.27-36.41 36.409v837.404c0 20.139 16.271 36.41 36.41 36.41h837.404c20.139 0 36.41-16.271 36.41-36.41V93.298c0-20.139-16.271-36.41-36.41-36.41z m-45.51 828.302H138.808V138.81H885.19V885.19z" p-id="7580" fill="#000000"></path></svg>
|
Before Width: | Height: | Size: 460 B After Width: | Height: | Size: 1.1 KiB |
@ -228,8 +228,11 @@
|
||||
"insert_file_name_as_title" : true,
|
||||
"//comment" : "none/read/edit",
|
||||
"section_number" : "read",
|
||||
"//comment" : "base level to start section numbering, valid only in edit mode",
|
||||
"//comment" : "Base level to start section numbering, valid only in edit mode",
|
||||
"section_number_base_level" : 2,
|
||||
"//comment" : "Style of the section number in edit mode",
|
||||
"//comment" : "digdotdigdot/digdotdig",
|
||||
"section_number_style" : "digdotdigdot",
|
||||
"//comment" : "Whether enable image width constraint",
|
||||
"constrain_image_width" : true,
|
||||
"//comment" : "Whether enable in-place preview width constraint",
|
||||
|
@ -1079,3 +1079,18 @@ QSizeGrip {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
/* ViewWindow */
|
||||
vnotex--ViewWindow QToolBar[ViewWindowToolBar="true"] {
|
||||
background-color: @widgets#viewwindow#toolbar#bg;
|
||||
}
|
||||
|
||||
/* ViewSplit */
|
||||
vnotex--ViewSplit QTabBar::tab:selected {
|
||||
color: @widgets#viewsplit#tabbar#tab#selected#fg;
|
||||
background-color: @widgets#viewsplit#tabbar#tab#selected#bg;
|
||||
}
|
||||
|
||||
vte--VTextEdit {
|
||||
border: none;
|
||||
}
|
||||
|
@ -233,6 +233,14 @@
|
||||
"active" : {
|
||||
"fg" : "@base#icon#fg"
|
||||
}
|
||||
},
|
||||
"tabbar" : {
|
||||
"tab" : {
|
||||
"selected" : {
|
||||
"fg" : "@base#content#fg",
|
||||
"bg" : "@base#content#bg"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"qmainwindow" : {
|
||||
@ -403,8 +411,8 @@
|
||||
"bg" : "@base#hover#bg"
|
||||
},
|
||||
"selected" : {
|
||||
"fg" : "@base#selected#fg",
|
||||
"bg" : "@base#selected#bg",
|
||||
"fg" : "@base#content#fg",
|
||||
"bg" : "@base#content#bg",
|
||||
"border" : "@base#master#bg"
|
||||
}
|
||||
}
|
||||
@ -584,6 +592,11 @@
|
||||
"border" : "@widgets#qslider#handle#border",
|
||||
"bg" : "@base#master#alt"
|
||||
}
|
||||
},
|
||||
"viewwindow" : {
|
||||
"toolbar" : {
|
||||
"bg" : "@base#content#bg"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -108,7 +108,7 @@
|
||||
},
|
||||
"HRULE" : {
|
||||
"text-color" : "#abb2bf",
|
||||
"background-color" : "#493134"
|
||||
"background-color" : "#864046"
|
||||
},
|
||||
"LIST_BULLET" : {
|
||||
"text-color" : "#e06c75",
|
||||
|
@ -22,27 +22,27 @@
|
||||
|
||||
#vx-content.vx-section-number h2::before {
|
||||
counter-increment: section1;
|
||||
content: counter(section1) " ";
|
||||
content: counter(section1) ". ";
|
||||
}
|
||||
|
||||
#vx-content.vx-section-number h3::before {
|
||||
counter-increment: section2;
|
||||
content: counter(section1) "." counter(section2) " ";
|
||||
content: counter(section1) "." counter(section2) ". ";
|
||||
}
|
||||
|
||||
#vx-content.vx-section-number h4::before {
|
||||
counter-increment: section3;
|
||||
content: counter(section1) "." counter(section2) "." counter(section3) " ";
|
||||
content: counter(section1) "." counter(section2) "." counter(section3) ". ";
|
||||
}
|
||||
|
||||
#vx-content.vx-section-number h5::before {
|
||||
counter-increment: section4;
|
||||
content: counter(section1) "." counter(section2) "." counter(section3) "." counter(section4) " ";
|
||||
content: counter(section1) "." counter(section2) "." counter(section3) "." counter(section4) ". ";
|
||||
}
|
||||
|
||||
#vx-content.vx-section-number h6::before {
|
||||
counter-increment: section5;
|
||||
content: counter(section1) "." counter(section2) "." counter(section3) "." counter(section4) "." counter(section5) " ";
|
||||
content: counter(section1) "." counter(section2) "." counter(section3) "." counter(section4) "." counter(section5) ". ";
|
||||
}
|
||||
|
||||
#vx-content.vx-constrain-image-width img {
|
||||
|
@ -61,7 +61,9 @@ class MarkJs {
|
||||
'className': this.className,
|
||||
'caseSensitive': p_options.caseSensitive,
|
||||
'accuracy': p_options.wholeWordOnly ? 'exactly' : 'partially',
|
||||
'done': callbackFunc(this, p_text, p_options)
|
||||
'done': callbackFunc(this, p_text, p_options),
|
||||
// Ignore SVG, or SVG will be corrupted.
|
||||
'exclude': ['svg *']
|
||||
}
|
||||
|
||||
if (p_options.regularExpression) {
|
||||
|
@ -111,6 +111,6 @@ class Utils {
|
||||
}
|
||||
|
||||
static headingSequenceRegExp() {
|
||||
return /^\d{1,3}(?:\.\d+)*\.? /;
|
||||
return /^\d{1,3}(?:\.\d+)*\. /;
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <QMenu>
|
||||
#include <QDebug>
|
||||
#include <QFormLayout>
|
||||
#include <QLineEdit>
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
@ -366,3 +367,10 @@ QFormLayout *WidgetUtils::createFormLayout(QWidget *p_parent)
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
void WidgetUtils::selectBaseName(QLineEdit *p_lineEdit)
|
||||
{
|
||||
auto text = p_lineEdit->text();
|
||||
int dotIndex = text.lastIndexOf(QLatin1Char('.'));
|
||||
p_lineEdit->setSelection(0, (dotIndex == -1) ? text.size() : dotIndex);
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ class QListView;
|
||||
class QMenu;
|
||||
class QShortcut;
|
||||
class QFormLayout;
|
||||
class QLineEdit;
|
||||
|
||||
namespace vnotex
|
||||
{
|
||||
@ -80,6 +81,9 @@ namespace vnotex
|
||||
|
||||
static QFormLayout *createFormLayout(QWidget *p_parent = nullptr);
|
||||
|
||||
// Select the base name part of the line edit content.
|
||||
static void selectBaseName(QLineEdit *p_lineEdit);
|
||||
|
||||
private:
|
||||
static void resizeToHideScrollBar(QScrollArea *p_scroll, bool p_vertical, bool p_horizontal);
|
||||
};
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <utils/pathutils.h>
|
||||
#include "exception.h"
|
||||
#include "nodeinfowidget.h"
|
||||
#include <utils/widgetutils.h>
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
@ -110,8 +111,7 @@ void NewNoteDialog::initDefaultValues()
|
||||
{
|
||||
auto lineEdit = m_infoWidget->getNameLineEdit();
|
||||
lineEdit->setText(c_defaultNoteName);
|
||||
int dotIndex = c_defaultNoteName.lastIndexOf('.');
|
||||
lineEdit->setSelection(0, (dotIndex == -1) ? c_defaultNoteName.size() : dotIndex);
|
||||
WidgetUtils::selectBaseName(lineEdit);
|
||||
|
||||
validateInputs();
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "exception.h"
|
||||
#include "nodelabelwithupbutton.h"
|
||||
#include <utils/widgetutils.h>
|
||||
#include <buffer/filetypehelper.h>
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
@ -16,11 +17,9 @@ NodeInfoWidget::NodeInfoWidget(const Node *p_node, QWidget *p_parent)
|
||||
: QWidget(p_parent),
|
||||
m_mode(Mode::Edit)
|
||||
{
|
||||
setupUI(p_node->getParent());
|
||||
setupUI(p_node->getParent(), p_node->getType());
|
||||
|
||||
setNode(p_node);
|
||||
|
||||
setStateAccordingToModeAndNodeType(p_node->getType());
|
||||
}
|
||||
|
||||
NodeInfoWidget::NodeInfoWidget(const Node *p_parentNode,
|
||||
@ -29,31 +28,42 @@ NodeInfoWidget::NodeInfoWidget(const Node *p_parentNode,
|
||||
: QWidget(p_parent),
|
||||
m_mode(Mode::Create)
|
||||
{
|
||||
setupUI(p_parentNode);
|
||||
|
||||
setStateAccordingToModeAndNodeType(p_typeToCreate);
|
||||
setupUI(p_parentNode, p_typeToCreate);
|
||||
}
|
||||
|
||||
void NodeInfoWidget::setupUI(const Node *p_parentNode)
|
||||
void NodeInfoWidget::setupUI(const Node *p_parentNode, Node::Type p_newNodeType)
|
||||
{
|
||||
const bool createMode = m_mode == Mode::Create;
|
||||
const bool isNote = p_newNodeType == Node::Type::File;
|
||||
|
||||
m_mainLayout = WidgetUtils::createFormLayout(this);
|
||||
|
||||
m_mainLayout->addRow(tr("Notebook:"),
|
||||
new QLabel(p_parentNode->getNotebook()->getName(), this));
|
||||
|
||||
m_parentNodeLabel = new NodeLabelWithUpButton(p_parentNode, this);
|
||||
m_parentNodeLabel->setReadOnly(!createMode);
|
||||
connect(m_parentNodeLabel, &NodeLabelWithUpButton::nodeChanged,
|
||||
this, &NodeInfoWidget::inputEdited);
|
||||
m_mainLayout->addRow(tr("Location:"), m_parentNodeLabel);
|
||||
|
||||
if (createMode && isNote) {
|
||||
setupFileTypeComboBox(this);
|
||||
m_mainLayout->addRow(tr("File type:"), m_fileTypeComboBox);
|
||||
}
|
||||
|
||||
setupNameLineEdit(this);
|
||||
m_mainLayout->addRow(tr("Name:"), m_nameLineEdit);
|
||||
|
||||
m_createdDateTimeLabel = new QLabel(this);
|
||||
m_mainLayout->addRow(tr("Created time:"), m_createdDateTimeLabel);
|
||||
if (!createMode) {
|
||||
m_createdDateTimeLabel = new QLabel(this);
|
||||
m_mainLayout->addRow(tr("Created time:"), m_createdDateTimeLabel);
|
||||
}
|
||||
|
||||
m_modifiedDateTimeLabel = new QLabel(this);
|
||||
m_mainLayout->addRow(tr("Modified time:"), m_modifiedDateTimeLabel);
|
||||
if (!createMode && isNote) {
|
||||
m_modifiedDateTimeLabel = new QLabel(this);
|
||||
m_mainLayout->addRow(tr("Modified time:"), m_modifiedDateTimeLabel);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeInfoWidget::setupNameLineEdit(QWidget *p_parent)
|
||||
@ -63,23 +73,30 @@ void NodeInfoWidget::setupNameLineEdit(QWidget *p_parent)
|
||||
m_nameLineEdit);
|
||||
m_nameLineEdit->setValidator(validator);
|
||||
connect(m_nameLineEdit, &QLineEdit::textEdited,
|
||||
this, &NodeInfoWidget::inputEdited);
|
||||
}
|
||||
this, [this]() {
|
||||
// Choose the correct file type.
|
||||
if (m_fileTypeComboBox) {
|
||||
auto inputName = m_nameLineEdit->text();
|
||||
QString typeName;
|
||||
int dotIdx = inputName.lastIndexOf(QLatin1Char('.'));
|
||||
if (dotIdx != -1) {
|
||||
auto suffix = inputName.mid(dotIdx + 1);
|
||||
const auto &fileType = FileTypeHelper::getInst().getFileTypeBySuffix(suffix);
|
||||
typeName = fileType.m_typeName;
|
||||
} else {
|
||||
typeName = FileTypeHelper::getInst().getFileType(FileTypeHelper::Others).m_typeName;
|
||||
}
|
||||
|
||||
void NodeInfoWidget::setStateAccordingToModeAndNodeType(Node::Type p_type)
|
||||
{
|
||||
bool createMode = m_mode == Mode::Create;
|
||||
bool isNote = p_type == Node::Type::File;
|
||||
int idx = m_fileTypeComboBox->findData(typeName);
|
||||
if (idx != -1) {
|
||||
m_fileTypeComboBoxMuted = true;
|
||||
m_fileTypeComboBox->setCurrentIndex(idx);
|
||||
m_fileTypeComboBoxMuted = false;
|
||||
}
|
||||
}
|
||||
|
||||
m_parentNodeLabel->setReadOnly(!createMode);
|
||||
|
||||
bool visible = !createMode;
|
||||
m_createdDateTimeLabel->setVisible(visible);
|
||||
m_mainLayout->labelForField(m_createdDateTimeLabel)->setVisible(visible);
|
||||
|
||||
visible = !createMode && isNote;
|
||||
m_modifiedDateTimeLabel->setVisible(visible);
|
||||
m_mainLayout->labelForField(m_modifiedDateTimeLabel)->setVisible(visible);
|
||||
emit inputEdited();
|
||||
});
|
||||
}
|
||||
|
||||
QLineEdit *NodeInfoWidget::getNameLineEdit() const
|
||||
@ -108,6 +125,7 @@ void NodeInfoWidget::setNode(const Node *p_node)
|
||||
return;
|
||||
}
|
||||
|
||||
Q_ASSERT(m_mode != Mode::Create);
|
||||
m_node = p_node;
|
||||
if (m_node) {
|
||||
Q_ASSERT(getNotebook() == m_node->getNotebook());
|
||||
@ -120,3 +138,39 @@ void NodeInfoWidget::setNode(const Node *p_node)
|
||||
m_modifiedDateTimeLabel->setText(modifiedTime);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeInfoWidget::setupFileTypeComboBox(QWidget *p_parent)
|
||||
{
|
||||
m_fileTypeComboBox = WidgetsFactory::createComboBox(p_parent);
|
||||
const auto &fileTypes = FileTypeHelper::getInst().getAllFileTypes();
|
||||
for (const auto &ft : fileTypes) {
|
||||
m_fileTypeComboBox->addItem(ft.m_displayName, ft.m_typeName);
|
||||
}
|
||||
connect(m_fileTypeComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, [this]() {
|
||||
if (m_fileTypeComboBoxMuted) {
|
||||
return;
|
||||
}
|
||||
auto name = m_fileTypeComboBox->currentData().toString();
|
||||
const auto &fileType = FileTypeHelper::getInst().getFileTypeByName(name);
|
||||
const auto suffix = fileType.preferredSuffix();
|
||||
if (!suffix.isEmpty()) {
|
||||
// Change the suffix.
|
||||
auto inputName = m_nameLineEdit->text();
|
||||
QString newName;
|
||||
int dotIdx = inputName.lastIndexOf(QLatin1Char('.'));
|
||||
if (dotIdx == -1) {
|
||||
newName = inputName + QLatin1Char('.') + suffix;
|
||||
} else if (inputName.mid(dotIdx + 1) != suffix) {
|
||||
newName = inputName.left(dotIdx + 1) + suffix;
|
||||
}
|
||||
|
||||
if (!newName.isEmpty()) {
|
||||
m_nameLineEdit->setText(newName);
|
||||
}
|
||||
}
|
||||
|
||||
WidgetUtils::selectBaseName(m_nameLineEdit);
|
||||
m_nameLineEdit->setFocus();
|
||||
});
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
class QLineEdit;
|
||||
class QLabel;
|
||||
class QFormLayout;
|
||||
class QComboBox;
|
||||
|
||||
namespace vnotex
|
||||
{
|
||||
@ -38,18 +39,20 @@ namespace vnotex
|
||||
void inputEdited();
|
||||
|
||||
private:
|
||||
void setupUI(const Node *p_parentNode);
|
||||
void setupUI(const Node *p_parentNode, Node::Type p_newNodeType);
|
||||
|
||||
void setupFileTypeComboBox(QWidget *p_parent);
|
||||
|
||||
void setupNameLineEdit(QWidget *p_parent);
|
||||
|
||||
void setStateAccordingToModeAndNodeType(Node::Type p_type);
|
||||
|
||||
void setNode(const Node *p_node);
|
||||
|
||||
Mode m_mode;
|
||||
|
||||
QFormLayout *m_mainLayout = nullptr;
|
||||
|
||||
QComboBox *m_fileTypeComboBox = nullptr;
|
||||
|
||||
QLineEdit *m_nameLineEdit = nullptr;
|
||||
|
||||
NodeLabelWithUpButton *m_parentNodeLabel = nullptr;
|
||||
@ -59,6 +62,8 @@ namespace vnotex
|
||||
QLabel *m_modifiedDateTimeLabel = nullptr;
|
||||
|
||||
const Node *m_node = nullptr;
|
||||
|
||||
bool m_fileTypeComboBoxMuted = false;
|
||||
};
|
||||
} // ns vnotex
|
||||
|
||||
|
@ -27,9 +27,9 @@ void NodeLabelWithUpButton::setupUI()
|
||||
|
||||
auto iconFile = VNoteX::getInst().getThemeMgr().getIconFile("up_parent_node.svg");
|
||||
m_upButton = new QPushButton(IconUtils::fetchIconWithDisabledState(iconFile),
|
||||
"",
|
||||
tr("Up"),
|
||||
this);
|
||||
m_upButton->setToolTip(tr("Up"));
|
||||
m_upButton->setToolTip(tr("Create note under an upper level node"));
|
||||
connect(m_upButton, &QPushButton::clicked,
|
||||
this, [this]() {
|
||||
if (!m_node->isRoot()) {
|
||||
|
@ -51,6 +51,10 @@ void MarkdownEditorPage::loadInternal()
|
||||
m_sectionNumberComboBox->setCurrentIndex(idx);
|
||||
|
||||
m_sectionNumberBaseLevelSpinBox->setValue(markdownConfig.getSectionNumberBaseLevel());
|
||||
|
||||
idx = m_sectionNumberStyleComboBox->findData(static_cast<int>(markdownConfig.getSectionNumberStyle()));
|
||||
Q_ASSERT(idx != -1);
|
||||
m_sectionNumberStyleComboBox->setCurrentIndex(idx);
|
||||
}
|
||||
|
||||
m_constrainImageWidthCheckBox->setChecked(markdownConfig.getConstrainImageWidthEnabled());
|
||||
@ -83,6 +87,11 @@ void MarkdownEditorPage::saveInternal()
|
||||
if (m_sectionNumberBaseLevelSpinBox->isEnabled()) {
|
||||
markdownConfig.setSectionNumberBaseLevel(m_sectionNumberBaseLevelSpinBox->value());
|
||||
}
|
||||
|
||||
if (m_sectionNumberStyleComboBox->isEnabled()) {
|
||||
auto style = m_sectionNumberStyleComboBox->currentData().toInt();
|
||||
markdownConfig.setSectionNumberStyle(static_cast<MarkdownEditorConfig::SectionNumberStyle>(style));
|
||||
}
|
||||
}
|
||||
|
||||
markdownConfig.setConstrainImageWidthEnabled(m_constrainImageWidthCheckBox->isChecked());
|
||||
@ -229,11 +238,9 @@ QGroupBox *MarkdownEditorPage::setupGeneralGroup()
|
||||
|
||||
m_sectionNumberComboBox = WidgetsFactory::createComboBox(this);
|
||||
m_sectionNumberComboBox->setToolTip(tr("Section number mode"));
|
||||
|
||||
m_sectionNumberComboBox->addItem(tr("None"), (int)MarkdownEditorConfig::SectionNumberMode::None);
|
||||
m_sectionNumberComboBox->addItem(tr("Read"), (int)MarkdownEditorConfig::SectionNumberMode::Read);
|
||||
m_sectionNumberComboBox->addItem(tr("Edit"), (int)MarkdownEditorConfig::SectionNumberMode::Edit);
|
||||
|
||||
sectionLayout->addWidget(m_sectionNumberComboBox);
|
||||
connect(m_sectionNumberComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &MarkdownEditorPage::pageIsChanged);
|
||||
@ -242,13 +249,22 @@ QGroupBox *MarkdownEditorPage::setupGeneralGroup()
|
||||
m_sectionNumberBaseLevelSpinBox->setToolTip(tr("Base level to start section numbering in edit mode"));
|
||||
m_sectionNumberBaseLevelSpinBox->setRange(1, 6);
|
||||
m_sectionNumberBaseLevelSpinBox->setSingleStep(1);
|
||||
|
||||
sectionLayout->addWidget(m_sectionNumberBaseLevelSpinBox);
|
||||
connect(m_sectionNumberBaseLevelSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
|
||||
this, &MarkdownEditorPage::pageIsChanged);
|
||||
|
||||
m_sectionNumberStyleComboBox = WidgetsFactory::createComboBox(this);
|
||||
m_sectionNumberStyleComboBox->setToolTip(tr("Section number style"));
|
||||
m_sectionNumberStyleComboBox->addItem(tr("1.1."), (int)MarkdownEditorConfig::SectionNumberStyle::DigDotDigDot);
|
||||
m_sectionNumberStyleComboBox->addItem(tr("1.1"), (int)MarkdownEditorConfig::SectionNumberStyle::DigDotDig);
|
||||
sectionLayout->addWidget(m_sectionNumberStyleComboBox);
|
||||
connect(m_sectionNumberStyleComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &MarkdownEditorPage::pageIsChanged);
|
||||
|
||||
connect(m_sectionNumberComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, [this](int p_index) {
|
||||
m_sectionNumberBaseLevelSpinBox->setEnabled(p_index == MarkdownEditorConfig::SectionNumberMode::Edit);
|
||||
m_sectionNumberStyleComboBox->setEnabled(p_index == MarkdownEditorConfig::SectionNumberMode::Edit);
|
||||
});
|
||||
|
||||
const QString label(tr("Section number:"));
|
||||
|
@ -54,6 +54,8 @@ namespace vnotex
|
||||
QComboBox *m_sectionNumberComboBox = nullptr;
|
||||
|
||||
QSpinBox *m_sectionNumberBaseLevelSpinBox = nullptr;
|
||||
|
||||
QComboBox *m_sectionNumberStyleComboBox = nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -755,7 +755,6 @@ void MarkdownEditor::updateHeadings(const QVector<vte::peg::ElementRegion> &p_he
|
||||
// Assume that each block contains only one line.
|
||||
// Only support # syntax for now.
|
||||
auto doc = document();
|
||||
QRegExp headerReg(vte::MarkdownUtils::c_headerRegExp);
|
||||
for (auto const ® : p_headerRegions) {
|
||||
auto block = doc->findBlock(reg.m_startPos);
|
||||
if (!block.isValid()) {
|
||||
@ -766,11 +765,11 @@ void MarkdownEditor::updateHeadings(const QVector<vte::peg::ElementRegion> &p_he
|
||||
qWarning() << "header accross multiple blocks, starting from block" << block.blockNumber() << block.text();
|
||||
}
|
||||
|
||||
if (headerReg.exactMatch(block.text())) {
|
||||
const int level = headerReg.cap(1).length();
|
||||
Heading heading(headerReg.cap(2).trimmed(),
|
||||
level,
|
||||
headerReg.cap(3),
|
||||
auto match = vte::MarkdownUtils::matchHeader(block.text());
|
||||
if (match.m_matched) {
|
||||
Heading heading(match.m_header,
|
||||
match.m_level,
|
||||
match.m_sequence,
|
||||
block.blockNumber());
|
||||
headings.append(heading);
|
||||
}
|
||||
@ -1097,10 +1096,9 @@ static void increaseSectionNumber(QVector<int> &p_sectionNumber, int p_level, in
|
||||
}
|
||||
}
|
||||
|
||||
static QString joinSectionNumberStr(const QVector<int> &p_sectionNumber)
|
||||
static QString joinSectionNumberStr(const QVector<int> &p_sectionNumber, bool p_endingDot)
|
||||
{
|
||||
QString res;
|
||||
// TODO: make it configurable? 1.1 or 1.1.?
|
||||
for (auto sec : p_sectionNumber) {
|
||||
if (sec != 0) {
|
||||
if (res.isEmpty()) {
|
||||
@ -1115,28 +1113,41 @@ static QString joinSectionNumberStr(const QVector<int> &p_sectionNumber)
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
if (p_endingDot && !res.isEmpty()) {
|
||||
return res + '.';
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
static bool updateHeadingSectionNumber(QTextCursor &p_cursor,
|
||||
const QTextBlock &p_block,
|
||||
QRegExp &p_headingReg,
|
||||
QRegExp &p_prefixReg,
|
||||
const QString &p_sectionNumber)
|
||||
const QString &p_sectionNumber,
|
||||
bool p_endingDot)
|
||||
{
|
||||
if (!p_block.isValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QString text = p_block.text();
|
||||
bool matched = p_headingReg.exactMatch(text);
|
||||
Q_ASSERT(matched);
|
||||
auto match = vte::MarkdownUtils::matchHeader(text);
|
||||
Q_ASSERT(match.m_matched);
|
||||
|
||||
matched = p_prefixReg.exactMatch(text);
|
||||
Q_ASSERT(matched);
|
||||
bool isSequence = false;
|
||||
if (!match.m_sequence.isEmpty()) {
|
||||
// Check if this sequence is the real sequence matching current style.
|
||||
if (match.m_sequence.endsWith('.')) {
|
||||
isSequence = p_endingDot;
|
||||
} else {
|
||||
isSequence = !p_endingDot;
|
||||
}
|
||||
}
|
||||
|
||||
int start = p_headingReg.cap(1).length() + 1;
|
||||
int end = p_prefixReg.cap(1).length();
|
||||
int start = match.m_level + 1;
|
||||
int end = match.m_level + match.m_spacesAfterMarker;
|
||||
if (isSequence) {
|
||||
end += match.m_sequence.size() + match.m_spacesAfterSequence;
|
||||
}
|
||||
|
||||
Q_ASSERT(start <= end);
|
||||
|
||||
@ -1162,20 +1173,18 @@ bool MarkdownEditor::updateSectionNumber(const QVector<Heading> &p_headings)
|
||||
}
|
||||
|
||||
bool changed = false;
|
||||
bool endingDot = m_config.getSectionNumberStyle() == MarkdownEditorConfig::SectionNumberStyle::DigDotDigDot;
|
||||
auto doc = document();
|
||||
QRegExp headerReg(vte::MarkdownUtils::c_headerRegExp);
|
||||
QRegExp prefixReg(vte::MarkdownUtils::c_headerPrefixRegExp);
|
||||
QTextCursor cursor(doc);
|
||||
cursor.beginEditBlock();
|
||||
for (const auto &heading : p_headings) {
|
||||
increaseSectionNumber(sectionNumber, heading.m_level, baseLevel);
|
||||
auto sectionStr = m_sectionNumberEnabled ? joinSectionNumberStr(sectionNumber) : QString();
|
||||
auto sectionStr = m_sectionNumberEnabled ? joinSectionNumberStr(sectionNumber, endingDot) : QString();
|
||||
if (heading.m_blockNumber > -1 && sectionStr != heading.m_sectionNumber) {
|
||||
if (updateHeadingSectionNumber(cursor,
|
||||
doc->findBlockByNumber(heading.m_blockNumber),
|
||||
headerReg,
|
||||
prefixReg,
|
||||
sectionStr)) {
|
||||
sectionStr,
|
||||
endingDot)) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
@ -251,7 +251,8 @@ void MarkdownViewWindow::handleBufferChangedInternal()
|
||||
|
||||
void MarkdownViewWindow::setupToolBar()
|
||||
{
|
||||
auto toolBar = new QToolBar(this);
|
||||
auto toolBar = createToolBar(this);
|
||||
|
||||
const auto &editorConfig = ConfigMgr::getInst().getEditorConfig();
|
||||
const int iconSize = editorConfig.getToolBarIconSize();
|
||||
toolBar->setIconSize(QSize(iconSize, iconSize));
|
||||
|
@ -51,6 +51,7 @@ void OutlineViewer::setupUI(const QString &p_title)
|
||||
{
|
||||
auto mainLayout = new QVBoxLayout(this);
|
||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||
mainLayout->setSpacing(0);
|
||||
|
||||
{
|
||||
auto titleBar = setupTitleBar(p_title, this);
|
||||
|
@ -13,3 +13,5 @@ const char *PropertyDefs::s_dialogCentralWidget = "DialogCentralWidget";
|
||||
const char *PropertyDefs::s_viewSplitCornerWidget = "ViewSplitCornerWidget";
|
||||
|
||||
const char *PropertyDefs::s_state = "State";
|
||||
|
||||
const char *PropertyDefs::s_viewWindowToolBar = "ViewWindowToolBar";
|
||||
|
@ -19,6 +19,8 @@ namespace vnotex
|
||||
|
||||
static const char *s_viewSplitCornerWidget;
|
||||
|
||||
static const char *s_viewWindowToolBar;
|
||||
|
||||
// Values: info/warning/error.
|
||||
static const char *s_state;
|
||||
};
|
||||
|
@ -55,7 +55,7 @@ void TextViewWindow::setupUI()
|
||||
|
||||
void TextViewWindow::setupToolBar()
|
||||
{
|
||||
auto toolBar = new QToolBar(this);
|
||||
auto toolBar = createToolBar(this);
|
||||
const auto &editorConfig = ConfigMgr::getInst().getEditorConfig();
|
||||
const int iconSize = editorConfig.getToolBarIconSize();
|
||||
toolBar->setIconSize(QSize(iconSize, iconSize));
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "exception.h"
|
||||
#include "findandreplacewidget.h"
|
||||
#include "editors/statuswidget.h"
|
||||
#include "propertydefs.h"
|
||||
|
||||
using namespace vnotex;
|
||||
|
||||
@ -106,14 +107,17 @@ ViewWindow::~ViewWindow()
|
||||
void ViewWindow::setupUI()
|
||||
{
|
||||
m_mainLayout = new QVBoxLayout(this);
|
||||
m_mainLayout->setSpacing(0);
|
||||
m_mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
m_topLayout = new QVBoxLayout();
|
||||
m_topLayout->setContentsMargins(0, 0, 0, 0);
|
||||
m_topLayout->setSpacing(0);
|
||||
m_mainLayout->addLayout(m_topLayout, 0);
|
||||
|
||||
m_bottomLayout = new QVBoxLayout();
|
||||
m_bottomLayout->setContentsMargins(0, 0, 0, 0);
|
||||
m_bottomLayout->setSpacing(0);
|
||||
m_mainLayout->addLayout(m_bottomLayout, 0);
|
||||
}
|
||||
|
||||
@ -1073,3 +1077,10 @@ void ViewWindow::read(bool p_save)
|
||||
}
|
||||
setFocus();
|
||||
}
|
||||
|
||||
QToolBar *ViewWindow::createToolBar(QWidget *p_parent)
|
||||
{
|
||||
auto toolBar = new QToolBar(p_parent);
|
||||
toolBar->setProperty(PropertyDefs::s_viewWindowToolBar, true);
|
||||
return toolBar;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
class QVBoxLayout;
|
||||
class QTimer;
|
||||
class QToolBar;
|
||||
|
||||
namespace vnotex
|
||||
{
|
||||
@ -218,6 +219,8 @@ namespace vnotex
|
||||
|
||||
static ViewWindow::Mode modeFromOpenParameters(const FileOpenParameters &p_paras);
|
||||
|
||||
static QToolBar *createToolBar(QWidget *p_parent = nullptr);
|
||||
|
||||
// The revision of the buffer of the last sync content.
|
||||
int m_bufferRevision = 0;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user