1. OutlineViewer: support section number;
2. Allow to close the file before opening with external program;
3. Skip end marker within a block marker;
This commit is contained in:
Le Tan 2021-08-17 20:58:55 +08:00
parent 7cc31a5d6e
commit 6109737b9d
19 changed files with 292 additions and 79 deletions

@ -1 +1 @@
Subproject commit 77cf66845ac2dee3e49cee440f5a6b40b777e8bd
Subproject commit f17e9bf898d86c2990b5831dea45673c3269030b

View File

@ -107,6 +107,8 @@ namespace vnotex
void pinToQuickAccessRequested(const QStringList &p_files);
void closeFileRequested(const QString &p_filePath, const QSharedPointer<Event> &p_event);
private:
explicit VNoteX(QObject *p_parent = nullptr);

View File

@ -18,19 +18,29 @@ void WidgetConfig::init(const QJsonObject &p_app,
const auto appObj = p_app.value(m_sessionName).toObject();
const auto userObj = p_user.value(m_sessionName).toObject();
{
m_outlineAutoExpandedLevel = READINT(QStringLiteral("outline_auto_expanded_level"));
if (m_outlineAutoExpandedLevel < 0 || m_outlineAutoExpandedLevel > 6) {
m_outlineAutoExpandedLevel = 6;
}
m_outlineSectionNumberEnabled = READBOOL(QStringLiteral("outline_section_number_enabled"));
}
m_findAndReplaceOptions = static_cast<FindOptions>(READINT(QStringLiteral("find_and_replace_options")));
{
m_nodeExplorerViewOrder = READINT(QStringLiteral("node_explorer_view_order"));
m_nodeExplorerRecycleBinNodeVisible = READBOOL(QStringLiteral("node_explorer_recycle_bin_node_visible"));
m_nodeExplorerExternalFilesVisible = READBOOL(QStringLiteral("node_explorer_external_files_visible"));
m_nodeExplorerAutoImportExternalFilesEnabled = READBOOL(QStringLiteral("node_explorer_auto_import_external_files_enabled"));
m_nodeExplorerCloseBeforeOpenWithEnabled = READBOOL(QStringLiteral("node_explorer_close_before_open_with_enabled"));
}
m_searchPanelAdvancedSettingsVisible = READBOOL(QStringLiteral("search_panel_advanced_settings_visible"));
m_mainWindowKeepDocksExpandingContentArea = READSTRLIST(QStringLiteral("main_window_keep_docks_expanding_content_area"));
m_snippetPanelBuiltInSnippetsVisible = READBOOL(QStringLiteral("snippet_panel_builtin_snippets_visible"));
}
@ -38,11 +48,16 @@ QJsonObject WidgetConfig::toJson() const
{
QJsonObject obj;
obj[QStringLiteral("outline_auto_expanded_level")] = m_outlineAutoExpandedLevel;
obj[QStringLiteral("outline_section_number_enabled")] = m_outlineSectionNumberEnabled;
obj[QStringLiteral("find_and_replace_options")] = static_cast<int>(m_findAndReplaceOptions);
obj[QStringLiteral("node_explorer_view_order")] = m_nodeExplorerViewOrder;
obj[QStringLiteral("node_explorer_recycle_bin_node_visible")] = m_nodeExplorerRecycleBinNodeVisible;
obj[QStringLiteral("node_explorer_external_files_visible")] = m_nodeExplorerExternalFilesVisible;
obj[QStringLiteral("node_explorer_auto_import_external_files_enabled")] = m_nodeExplorerAutoImportExternalFilesEnabled;
obj[QStringLiteral("node_explorer_close_before_open_with_enabled")] = m_nodeExplorerCloseBeforeOpenWithEnabled;
obj[QStringLiteral("search_panel_advanced_settings_visible")] = m_searchPanelAdvancedSettingsVisible;
obj[QStringLiteral("snippet_panel_builtin_snippets_visible")] = m_snippetPanelBuiltInSnippetsVisible;
writeStringList(obj,
@ -61,6 +76,16 @@ void WidgetConfig::setOutlineAutoExpandedLevel(int p_level)
updateConfig(m_outlineAutoExpandedLevel, p_level, this);
}
bool WidgetConfig::getOutlineSectionNumberEnabled() const
{
return m_outlineSectionNumberEnabled;
}
void WidgetConfig::setOutlineSectionNumberEnabled(bool p_enabled)
{
updateConfig(m_outlineSectionNumberEnabled, p_enabled, this);
}
FindOptions WidgetConfig::getFindAndReplaceOptions() const
{
return m_findAndReplaceOptions;
@ -111,6 +136,16 @@ void WidgetConfig::setNodeExplorerAutoImportExternalFilesEnabled(bool p_enabled)
updateConfig(m_nodeExplorerAutoImportExternalFilesEnabled, p_enabled, this);
}
bool WidgetConfig::getNodeExplorerCloseBeforeOpenWithEnabled() const
{
return m_nodeExplorerCloseBeforeOpenWithEnabled;
}
void WidgetConfig::setNodeExplorerCloseBeforeOpenWithEnabled(bool p_enabled)
{
updateConfig(m_nodeExplorerCloseBeforeOpenWithEnabled, p_enabled, this);
}
bool WidgetConfig::isSearchPanelAdvancedSettingsVisible() const
{
return m_searchPanelAdvancedSettingsVisible;
@ -140,3 +175,4 @@ void WidgetConfig::setSnippetPanelBuiltInSnippetsVisible(bool p_visible)
{
updateConfig(m_snippetPanelBuiltInSnippetsVisible, p_visible, this);
}

View File

@ -21,6 +21,9 @@ namespace vnotex
int getOutlineAutoExpandedLevel() const;
void setOutlineAutoExpandedLevel(int p_level);
bool getOutlineSectionNumberEnabled() const;
void setOutlineSectionNumberEnabled(bool p_enabled);
FindOptions getFindAndReplaceOptions() const;
void setFindAndReplaceOptions(FindOptions p_options);
@ -36,6 +39,9 @@ namespace vnotex
bool getNodeExplorerAutoImportExternalFilesEnabled() const;
void setNodeExplorerAutoImportExternalFilesEnabled(bool p_enabled);
bool getNodeExplorerCloseBeforeOpenWithEnabled() const;
void setNodeExplorerCloseBeforeOpenWithEnabled(bool p_enabled);
bool isSearchPanelAdvancedSettingsVisible() const;
void setSearchPanelAdvancedSettingsVisible(bool p_visible);
@ -48,6 +54,8 @@ namespace vnotex
private:
int m_outlineAutoExpandedLevel = 6;
bool m_outlineSectionNumberEnabled = false;
FindOptions m_findAndReplaceOptions = FindOption::FindNone;
int m_nodeExplorerViewOrder = 0;
@ -58,6 +66,8 @@ namespace vnotex
bool m_nodeExplorerAutoImportExternalFilesEnabled = true;
bool m_nodeExplorerCloseBeforeOpenWithEnabled = true;
bool m_searchPanelAdvancedSettingsVisible = true;
// Object name of those docks that should be kept when expanding content area.

View File

@ -358,6 +358,8 @@
"widget" : {
"//comment" : "Level of the heading in outline that should expand to automatically (1-6)",
"outline_auto_expanded_level" : 6,
"//comment" : "Add section number in the outline viewer",
"outline_section_number_enabled" : false,
"//comment" : "Default find options in FindAndReplace",
"find_and_replace_options" : 16,
"//comment" : "View order of the node explorer",
@ -365,6 +367,8 @@
"node_explorer_recycle_bin_node_visible" : false,
"node_explorer_external_files_visible" : true,
"node_explorer_auto_import_external_files_enabled" : true,
"//comment" : "Whether close the file before opening it with external program",
"node_explorer_close_before_open_with_enabled" : true,
"search_panel_advanced_settings_visible" : true,
"//comment" : "Docks to ignore when expanding content area of main window",
"main_window_keep_docks_expanding_content_area": [],

View File

@ -5,7 +5,7 @@
#include <QByteArray>
#include <utils/utils.h>
#include <utils/webutils.h>
#include "githubimagehost.h"
using namespace vnotex;
@ -39,7 +39,8 @@ void GiteeImageHost::setConfig(const QJsonObject &p_jobj)
{
parseConfig(p_jobj, m_personalAccessToken, m_userName, m_repoName);
m_imageUrlPrefix = QString("https://gitee.com/%1/%2/raw/master/").arg(m_userName, m_repoName);
// Do not assume the default branch.
m_imageUrlPrefix = QString("https://gitee.com/%1/%2/raw/").arg(m_userName, m_repoName);
}
bool GiteeImageHost::testConfig(const QJsonObject &p_jobj, QString &p_msg)
@ -165,7 +166,7 @@ bool GiteeImageHost::remove(const QString &p_url, QString &p_msg)
return false;
}
const QString resourcePath = WebUtils::purifyUrl(p_url.mid(m_imageUrlPrefix.size()));
const auto resourcePath = GitHubImageHost::fetchResourcePath(m_imageUrlPrefix, p_url);
auto rawHeader = prepareCommonHeaders();
const auto urlStr = QString("%1/repos/%2/%3/contents/%4").arg(c_apiUrl, m_userName, m_repoName, resourcePath);

View File

@ -39,7 +39,8 @@ void GitHubImageHost::setConfig(const QJsonObject &p_jobj)
{
parseConfig(p_jobj, m_personalAccessToken, m_userName, m_repoName);
m_imageUrlPrefix = QString("https://raw.githubusercontent.com/%1/%2/master/").arg(m_userName, m_repoName);
// Do not assume the default branch.
m_imageUrlPrefix = QString("https://raw.githubusercontent.com/%1/%2/").arg(m_userName, m_repoName);
}
bool GitHubImageHost::testConfig(const QJsonObject &p_jobj, QString &p_msg)
@ -150,6 +151,15 @@ bool GitHubImageHost::ownsUrl(const QString &p_url) const
return p_url.startsWith(m_imageUrlPrefix);
}
QString GitHubImageHost::fetchResourcePath(const QString &p_prefix, const QString &p_url)
{
auto resourcePath = p_url.mid(p_prefix.size());
// Skip the branch name.
resourcePath = resourcePath.mid(resourcePath.indexOf(QLatin1Char('/')) + 1);
resourcePath = WebUtils::purifyUrl(resourcePath);
return resourcePath;
}
bool GitHubImageHost::remove(const QString &p_url, QString &p_msg)
{
Q_ASSERT(ownsUrl(p_url));
@ -159,7 +169,7 @@ bool GitHubImageHost::remove(const QString &p_url, QString &p_msg)
return false;
}
const QString resourcePath = WebUtils::purifyUrl(p_url.mid(m_imageUrlPrefix.size()));
const auto resourcePath = fetchResourcePath(m_imageUrlPrefix, p_url);
auto rawHeader = prepareCommonHeaders(m_personalAccessToken);
const auto urlStr = QString("%1/repos/%2/%3/contents/%4").arg(c_apiUrl, m_userName, m_repoName, resourcePath);

View File

@ -29,6 +29,8 @@ namespace vnotex
bool ownsUrl(const QString &p_url) const Q_DECL_OVERRIDE;
static QString fetchResourcePath(const QString &p_prefix, const QString &p_url);
protected:
QString m_personalAccessToken;

View File

@ -1185,44 +1185,6 @@ void MarkdownEditor::fetchImagesToLocalAndReplace(QString &p_text)
proDlg.setValue(regs.size());
}
static void increaseSectionNumber(QVector<int> &p_sectionNumber, int p_level, int p_baseLevel)
{
Q_ASSERT(p_level >= 1 && p_level < p_sectionNumber.size());
if (p_level < p_baseLevel) {
p_sectionNumber.fill(0);
return;
}
++p_sectionNumber[p_level];
for (int i = p_level + 1; i < p_sectionNumber.size(); ++i) {
p_sectionNumber[i] = 0;
}
}
static QString joinSectionNumberStr(const QVector<int> &p_sectionNumber, bool p_endingDot)
{
QString res;
for (auto sec : p_sectionNumber) {
if (sec != 0) {
if (res.isEmpty()) {
res = QString::number(sec);
} else {
res += '.' + QString::number(sec);
}
} else if (res.isEmpty()) {
continue;
} else {
break;
}
}
if (p_endingDot && !res.isEmpty()) {
return res + '.';
} else {
return res;
}
}
static bool updateHeadingSectionNumber(QTextCursor &p_cursor,
const QTextBlock &p_block,
const QString &p_sectionNumber,
@ -1269,7 +1231,7 @@ static bool updateHeadingSectionNumber(QTextCursor &p_cursor,
bool MarkdownEditor::updateSectionNumber(const QVector<Heading> &p_headings)
{
QVector<int> sectionNumber(7, 0);
SectionNumber sectionNumber(7, 0);
int baseLevel = m_config.getSectionNumberBaseLevel();
if (baseLevel < 1 || baseLevel > 6) {
baseLevel = 1;
@ -1281,8 +1243,8 @@ bool MarkdownEditor::updateSectionNumber(const QVector<Heading> &p_headings)
QTextCursor cursor(doc);
cursor.beginEditBlock();
for (const auto &heading : p_headings) {
increaseSectionNumber(sectionNumber, heading.m_level, baseLevel);
auto sectionStr = m_sectionNumberEnabled ? joinSectionNumberStr(sectionNumber, endingDot) : QString();
OutlineProvider::increaseSectionNumber(sectionNumber, heading.m_level, baseLevel);
auto sectionStr = m_sectionNumberEnabled ? OutlineProvider::joinSectionNumber(sectionNumber, endingDot) : QString();
if (heading.m_blockNumber > -1 && sectionStr != heading.m_sectionNumber) {
if (updateHeadingSectionNumber(cursor,
doc->findBlockByNumber(heading.m_blockNumber),

View File

@ -828,6 +828,14 @@ QSharedPointer<Outline> MarkdownViewWindow::headingsToOutline(const QVector<T> &
}
}
const auto &markdownConfig = ConfigMgr::getInst().getEditorConfig().getMarkdownEditorConfig();
if (markdownConfig.getSectionNumberMode() == MarkdownEditorConfig::SectionNumberMode::Edit) {
outline->m_sectionNumberBaseLevel = -1;
} else {
outline->m_sectionNumberBaseLevel = markdownConfig.getSectionNumberBaseLevel();
outline->m_sectionNumberEndingDot = markdownConfig.getSectionNumberStyle() == MarkdownEditorConfig::SectionNumberStyle::DigDotDigDot;
}
return outline;
}

View File

@ -93,6 +93,8 @@ void NotebookExplorer::setupUI()
&VNoteX::getInst(), &VNoteX::nodeAboutToRemove);
connect(m_nodeExplorer, &NotebookNodeExplorer::nodeAboutToReload,
&VNoteX::getInst(), &VNoteX::nodeAboutToReload);
connect(m_nodeExplorer, &NotebookNodeExplorer::closeFileRequested,
&VNoteX::getInst(), &VNoteX::closeFileRequested);
mainLayout->addWidget(m_nodeExplorer);
setFocusProxy(m_nodeExplorer);
@ -159,13 +161,23 @@ TitleBar *NotebookExplorer::setupTitleBar(QWidget *p_parent)
subMenu,
tr("Import External Files When Activated"),
titleBar,
[this](bool p_checked) {
[](bool p_checked) {
ConfigMgr::getInst().getWidgetConfig().setNodeExplorerAutoImportExternalFilesEnabled(p_checked);
});
importAct->setCheckable(true);
importAct->setChecked(widgetConfig.getNodeExplorerAutoImportExternalFilesEnabled());
}
{
auto act = titleBar->addMenuAction(tr("Close File Before Open With External Program"),
titleBar,
[](bool p_checked) {
ConfigMgr::getInst().getWidgetConfig().setNodeExplorerCloseBeforeOpenWithEnabled(p_checked);
});
act->setCheckable(true);
act->setChecked(widgetConfig.getNodeExplorerCloseBeforeOpenWithEnabled());
}
return titleBar;
}

View File

@ -34,6 +34,7 @@
#include <core/configmgr.h>
#include <core/coreconfig.h>
#include <core/sessionconfig.h>
#include <core/widgetconfig.h>
using namespace vnotex;
@ -2027,23 +2028,42 @@ void NotebookNodeExplorer::setupShortcuts()
void NotebookNodeExplorer::openSelectedNodesWithDefaultProgram()
{
const bool closeBefore = ConfigMgr::getInst().getWidgetConfig().getNodeExplorerCloseBeforeOpenWithEnabled();
const auto files = getSelectedNodesPath();
for (const auto &file : files) {
if (file.isEmpty()) {
continue;
}
if (closeBefore) {
auto event = QSharedPointer<Event>::create();
emit closeFileRequested(file, event);
if (!event->m_response.toBool()) {
continue;
}
}
WidgetUtils::openUrlByDesktop(QUrl::fromLocalFile(file));
}
}
void NotebookNodeExplorer::openSelectedNodesWithExternalProgram(const QString &p_command)
{
const bool closeBefore = ConfigMgr::getInst().getWidgetConfig().getNodeExplorerCloseBeforeOpenWithEnabled();
const auto files = getSelectedNodesPath();
for (const auto &file : files) {
if (file.isEmpty()) {
continue;
}
if (closeBefore) {
auto event = QSharedPointer<Event>::create();
emit closeFileRequested(file, event);
if (!event->m_response.toBool()) {
continue;
}
}
auto command = p_command;
command.replace(QStringLiteral("%1"), QString("\"%1\"").arg(file));
ProcessUtils::startDetached(command);

View File

@ -127,6 +127,9 @@ namespace vnotex
void nodeAboutToReload(Node *p_node, const QSharedPointer<Event> &p_event);
// @p_filePath is either an external file or a node.
void closeFileRequested(const QString &p_filePath, const QSharedPointer<Event> &p_event);
private:
enum Column { Name = 0 };

View File

@ -63,3 +63,41 @@ void OutlineProvider::setCurrentHeadingIndex(int p_idx)
m_currentHeadingIndex = p_idx;
emit currentHeadingChanged();
}
void OutlineProvider::increaseSectionNumber(SectionNumber &p_sectionNumber, int p_level, int p_baseLevel)
{
Q_ASSERT(p_level >= 1 && p_level < p_sectionNumber.size());
if (p_level < p_baseLevel) {
p_sectionNumber.fill(0);
return;
}
++p_sectionNumber[p_level];
for (int i = p_level + 1; i < p_sectionNumber.size(); ++i) {
p_sectionNumber[i] = 0;
}
}
QString OutlineProvider::joinSectionNumber(const SectionNumber &p_sectionNumber, bool p_endingDot)
{
QString res;
for (auto sec : p_sectionNumber) {
if (sec != 0) {
if (res.isEmpty()) {
res = QString::number(sec);
} else {
res += '.' + QString::number(sec);
}
} else if (res.isEmpty()) {
continue;
} else {
break;
}
}
if (p_endingDot && !res.isEmpty()) {
return res + '.';
} else {
return res;
}
}

View File

@ -7,6 +7,8 @@
namespace vnotex
{
typedef QVector<int> SectionNumber;
// Toc content.
struct Outline
{
@ -31,6 +33,12 @@ namespace vnotex
bool isEmpty() const;
QVector<Heading> m_headings;
// 1-based.
// -1 to disable section number by force.
int m_sectionNumberBaseLevel = 1;
bool m_sectionNumberEndingDot = true;
};
// Used to hold toc-related data of one ViewWindow.
@ -53,6 +61,10 @@ namespace vnotex
template <class T>
static void makePerfectHeadings(const QVector<T> &p_headings, QVector<T> &p_perfectHeadings);
static void increaseSectionNumber(SectionNumber &p_sectionNumber, int p_level, int p_baseLevel);
static QString joinSectionNumber(const SectionNumber &p_sectionNumber, bool p_endingDot);
signals:
void outlineChanged();

View File

@ -14,8 +14,8 @@
#include "treewidget.h"
#include "titlebar.h"
#include "configmgr.h"
#include "widgetconfig.h"
#include <core/configmgr.h>
#include <core/widgetconfig.h>
#include "navigationmodemgr.h"
using namespace vnotex;
@ -89,7 +89,7 @@ NavigationModeWrapper<QTreeWidget, QTreeWidgetItem> *OutlineViewer::getNavigatio
TitleBar *OutlineViewer::setupTitleBar(const QString &p_title, QWidget *p_parent)
{
auto titleBar = new TitleBar(p_title, false, TitleBar::Action::None, p_parent);
auto titleBar = new TitleBar(p_title, false, TitleBar::Action::Menu, p_parent);
titleBar->setActionButtonsAlwaysShown(true);
auto decreaseBtn = titleBar->addActionButton(QStringLiteral("decrease_outline_level.svg"), tr("Decrease Expansion Level"));
@ -122,6 +122,17 @@ TitleBar *OutlineViewer::setupTitleBar(const QString &p_title, QWidget *p_parent
showLevel();
});
{
auto act = titleBar->addMenuAction(tr("Section Number"),
titleBar,
[this](bool p_checked) {
ConfigMgr::getInst().getWidgetConfig().setOutlineSectionNumberEnabled(p_checked);
updateTree(true);
});
act->setCheckable(true);
act->setChecked(ConfigMgr::getInst().getWidgetConfig().getOutlineSectionNumberEnabled());
}
return titleBar;
}
@ -148,27 +159,32 @@ void OutlineViewer::setOutlineProvider(const QSharedPointer<OutlineProvider> &p_
this, [this]() {
updateCurrentHeading(m_provider->getCurrentHeadingIndex());
});
if (isVisible()) {
updateOutline(m_provider->getOutline());
updateCurrentHeading(m_provider->getCurrentHeadingIndex());
}
} else {
updateOutline(nullptr);
updateCurrentHeading(-1);
}
if (isVisible()) {
updateTree();
}
}
void OutlineViewer::showEvent(QShowEvent *p_event)
{
QFrame::showEvent(p_event);
// Update the tree.
updateTree();
}
void OutlineViewer::updateTree(bool p_force)
{
if (p_force) {
m_outline.clear();
}
if (m_provider) {
updateOutline(m_provider->getOutline());
updateCurrentHeading(m_provider->getCurrentHeadingIndex());
} else {
updateOutline(nullptr);
updateCurrentHeading(-1);
}
}
@ -219,8 +235,24 @@ void OutlineViewer::updateTreeToOutline(QTreeWidget *p_tree, const Outline &p_ou
return;
}
int sectionNumberBaseLevel = -1;
const auto &widgetConfig = ConfigMgr::getInst().getWidgetConfig();
if (widgetConfig.getOutlineSectionNumberEnabled()) {
sectionNumberBaseLevel = p_outline.m_sectionNumberBaseLevel;
}
SectionNumber sectionNumber(7, 0);
int idx = 0;
renderTreeAtLevel(p_outline.m_headings, idx, 1, p_tree, nullptr, nullptr);
renderTreeAtLevel(p_outline.m_headings,
idx,
1,
p_tree,
nullptr,
nullptr,
sectionNumberBaseLevel,
sectionNumber,
p_outline.m_sectionNumberEndingDot);
}
void OutlineViewer::renderTreeAtLevel(const QVector<Outline::Heading> &p_headings,
@ -228,34 +260,60 @@ void OutlineViewer::renderTreeAtLevel(const QVector<Outline::Heading> &p_heading
int p_level,
QTreeWidget *p_tree,
QTreeWidgetItem *p_parentItem,
QTreeWidgetItem *p_lastItem)
QTreeWidgetItem *p_lastItem,
int p_sectionNumberBaseLevel,
SectionNumber &p_sectionNumber,
bool p_sectionNumberEndingDot)
{
while (p_index < p_headings.size()) {
const auto &heading = p_headings[p_index];
if (heading.m_level < p_level) {
return;
}
QTreeWidgetItem *item = nullptr;
if (heading.m_level == p_level) {
QString sectionStr;
if (p_sectionNumberBaseLevel > 0) {
OutlineProvider::increaseSectionNumber(p_sectionNumber, heading.m_level, p_sectionNumberBaseLevel);
sectionStr = OutlineProvider::joinSectionNumber(p_sectionNumber, p_sectionNumberEndingDot);
}
if (p_parentItem) {
item = new QTreeWidgetItem(p_parentItem);
} else {
item = new QTreeWidgetItem(p_tree);
}
fillTreeItem(item, heading, p_index);
fillTreeItem(item, heading, p_index, sectionStr);
p_lastItem = item;
++p_index;
} else if (heading.m_level < p_level) {
return;
} else {
renderTreeAtLevel(p_headings, p_index, p_level + 1, p_tree, p_lastItem, nullptr);
renderTreeAtLevel(p_headings,
p_index,
p_level + 1,
p_tree,
p_lastItem,
nullptr,
p_sectionNumberBaseLevel,
p_sectionNumber,
p_sectionNumberEndingDot);
}
}
}
void OutlineViewer::fillTreeItem(QTreeWidgetItem *p_item, const Outline::Heading &p_heading, int p_index)
void OutlineViewer::fillTreeItem(QTreeWidgetItem *p_item,
const Outline::Heading &p_heading,
int p_index,
const QString &p_sectionStr)
{
p_item->setData(Column::Name, Qt::UserRole, p_index);
if (p_sectionStr.isEmpty()) {
p_item->setText(Column::Name, p_heading.m_name);
} else {
p_item->setText(Column::Name, tr("%1 %2").arg(p_sectionStr, p_heading.m_name));
}
p_item->setToolTip(Column::Name, p_heading.m_name);
}

View File

@ -28,8 +28,6 @@ namespace vnotex
NavigationModeWrapper<QTreeWidget, QTreeWidgetItem> *getNavigationModeWrapper();
static void updateTreeToOutline(QTreeWidget *p_tree, const Outline &p_outline);
signals:
void focusViewArea();
@ -43,6 +41,8 @@ namespace vnotex
TitleBar *setupTitleBar(const QString &p_title, QWidget *p_parent = nullptr);
void updateTree(bool p_force = false);
void updateOutline(const QSharedPointer<Outline> &p_outline);
void updateCurrentHeading(int p_idx);
@ -61,9 +61,17 @@ namespace vnotex
int p_level,
QTreeWidget *p_tree,
QTreeWidgetItem *p_parentItem,
QTreeWidgetItem *p_lastItem);
QTreeWidgetItem *p_lastItem,
int p_sectionNumberBaseLevel,
SectionNumber &p_sectionNumber,
bool p_sectionNumberEndingDot);
static void fillTreeItem(QTreeWidgetItem *p_item, const Outline::Heading &p_heading, int p_index);
static void fillTreeItem(QTreeWidgetItem *p_item,
const Outline::Heading &p_heading,
int p_index,
const QString &p_sectionStr);
static void updateTreeToOutline(QTreeWidget *p_tree, const Outline &p_outline);
bool m_muted = false;

View File

@ -23,6 +23,7 @@
#include <core/events.h>
#include <core/vnotex.h>
#include <core/configmgr.h>
#include <core/notebookmgr.h>
#include <core/coreconfig.h>
#include <core/editorconfig.h>
#include <core/markdowneditorconfig.h>
@ -87,6 +88,9 @@ ViewArea::ViewArea(QWidget *p_parent)
connect(&VNoteX::getInst(), &VNoteX::nodeAboutToReload,
this, &ViewArea::handleNodeChange);
connect(&VNoteX::getInst(), &VNoteX::closeFileRequested,
this, &ViewArea::closeFile);
auto &configMgr = ConfigMgr::getInst();
connect(&configMgr, &ConfigMgr::editorConfigChanged,
this, [this]() {
@ -931,7 +935,7 @@ bool ViewArea::close(Node *p_node, bool p_force)
return closeIf(p_force, [p_node](ViewWindow *p_win) {
auto buffer = p_win->getBuffer();
return buffer->match(p_node) || buffer->isChildOf(p_node);
}, false);
}, true);
}
bool ViewArea::close(const Notebook *p_notebook, bool p_force)
@ -1484,3 +1488,24 @@ void ViewArea::updateHistory(const ViewWindowSession &p_session, Notebook *p_not
p_session.m_readOnly,
p_notebook);
}
void ViewArea::closeFile(const QString &p_filePath, const QSharedPointer<Event> &p_event)
{
if (p_event->m_handled) {
return;
}
auto node = VNoteX::getInst().getNotebookMgr().loadNodeByPath(p_filePath);
bool done = false;
if (node) {
done = close(node.data(), false);
} else {
done = closeIf(false, [p_filePath](ViewWindow *p_win) {
auto buffer = p_win->getBuffer();
return buffer->match(p_filePath);
}, true);
}
p_event->m_response = done;
p_event->m_handled = !done;
}

View File

@ -139,6 +139,8 @@ namespace vnotex
void moveViewWindowOneSplit(ViewSplit *p_split, ViewWindow *p_win, Direction p_direction);
void closeFile(const QString &p_filePath, const QSharedPointer<Event> &p_event);
private:
enum class SplitType
{