diff --git a/src/core/notebook/node.cpp b/src/core/notebook/node.cpp
index 47e4aada..51a19a1a 100644
--- a/src/core/notebook/node.cpp
+++ b/src/core/notebook/node.cpp
@@ -301,3 +301,29 @@ INotebookBackend *Node::getBackend() const
{
return m_notebook->getBackend().data();
}
+
+bool Node::canRename(const QString &p_newName) const
+{
+ if (p_newName == m_name) {
+ return true;
+ }
+
+ if (p_newName.isEmpty()) {
+ return false;
+ }
+
+ Q_ASSERT(m_parent);
+ if (p_newName.toLower() == m_name.toLower()) {
+ if (m_parent->containsChild(p_newName, true)) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ if (m_parent->containsChild(p_newName, false)) {
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/core/notebook/node.h b/src/core/notebook/node.h
index 70fb5283..acd79f8f 100644
--- a/src/core/notebook/node.h
+++ b/src/core/notebook/node.h
@@ -156,6 +156,8 @@ namespace vnotex
INotebookBackend *getBackend() const;
+ bool canRename(const QString &p_newName) const;
+
static bool isAncestor(const Node *p_ancestor, const Node *p_child);
protected:
diff --git a/src/data/extra/web/css/outline.css b/src/data/extra/web/css/outline.css
index b73b2ba1..f632c66e 100644
--- a/src/data/extra/web/css/outline.css
+++ b/src/data/extra/web/css/outline.css
@@ -135,6 +135,7 @@
.section-nav a {
color: inherit !important;
+ white-space: nowrap;
}
.row {
diff --git a/src/data/extra/web/js/outline.js b/src/data/extra/web/js/outline.js
index 748f9f85..88548b47 100644
--- a/src/data/extra/web/js/outline.js
+++ b/src/data/extra/web/js/outline.js
@@ -1,4 +1,4 @@
-var toc = [];
+var vxOutlineToc = [];
var setVisible = function(node, visible) {
var cl = 'hide-none';
@@ -61,32 +61,32 @@ window.addEventListener('load', function() {
// Fetch the outline.
var headers = postContent.querySelectorAll("h1, h2, h3, h4, h5, h6");
- toc = [];
+ vxOutlineToc = [];
for (var i = 0; i < headers.length; ++i) {
var header = headers[i];
- toc.push({
+ vxOutlineToc.push({
level: parseInt(header.tagName.substr(1)),
anchor: header.id,
title: escapeHtml(header.textContent)
});
}
- if (toc.length == 0) {
+ if (vxOutlineToc.length == 0) {
setOutlinePanelVisible(false);
setVisible(floatingContainer, false);
return;
}
- var baseLevel = baseLevelOfToc(toc);
- var tocTree = tocToTree(toPerfectToc(toc, baseLevel), baseLevel);
+ var baseLevel = baseLevelOfToc(vxOutlineToc);
+ var tocTree = tocToTree(toPerfectToc(vxOutlineToc, baseLevel), baseLevel);
outlineContent.innerHTML = tocTree;
setOutlinePanelVisible(true);
setVisible(floatingContainer, true);
});
-// Return the topest level of @toc, starting from 1.
+// Return the topest level of @vxOutlineToc, starting from 1.
var baseLevelOfToc = function(p_toc) {
var level = -1;
for (i in p_toc) {
@@ -130,7 +130,7 @@ var toPerfectToc = function(p_toc, p_baseLevel) {
};
var itemToHtml = function(item) {
- return '' + item.title + '';
+ return '' + item.title + '';
};
// Turn a perfect toc to a tree using
@@ -175,7 +175,7 @@ var tocToTree = function(p_toc, p_baseLevel) {
};
var toggleMore = function() {
- if (toc.length == 0) {
+ if (vxOutlineToc.length == 0) {
return;
}
@@ -190,7 +190,7 @@ var toggleMore = function() {
};
window.addEventListener('scroll', function() {
- if (toc.length == 0 || !isOutlinePanelVisible()) {
+ if (vxOutlineToc.length == 0 || !isOutlinePanelVisible()) {
return;
}
diff --git a/src/widgets/dialogs/folderpropertiesdialog.cpp b/src/widgets/dialogs/folderpropertiesdialog.cpp
index 31d97503..b248c2e7 100644
--- a/src/widgets/dialogs/folderpropertiesdialog.cpp
+++ b/src/widgets/dialogs/folderpropertiesdialog.cpp
@@ -63,8 +63,8 @@ bool FolderPropertiesDialog::validateNameInput(QString &p_msg)
return false;
}
- if (name != m_node->getName()
- && m_infoWidget->getParentNode()->containsChild(name, false)) {
+ Q_ASSERT(m_infoWidget->getParentNode() == m_node->getParent());
+ if (!m_node->canRename(name)) {
p_msg = tr("Name conflicts with existing folder.");
return false;
}
diff --git a/src/widgets/dialogs/notepropertiesdialog.cpp b/src/widgets/dialogs/notepropertiesdialog.cpp
index b25bd2cd..a5857359 100644
--- a/src/widgets/dialogs/notepropertiesdialog.cpp
+++ b/src/widgets/dialogs/notepropertiesdialog.cpp
@@ -65,8 +65,8 @@ bool NotePropertiesDialog::validateNameInput(QString &p_msg)
return false;
}
- if (name != m_node->getName()
- && m_infoWidget->getParentNode()->containsChild(name, false)) {
+ Q_ASSERT(m_infoWidget->getParentNode() == m_node->getParent());
+ if (!m_node->canRename(name)) {
p_msg = tr("Name conflicts with existing note.");
return false;
}
diff --git a/src/widgets/notebooknodeexplorer.cpp b/src/widgets/notebooknodeexplorer.cpp
index a142c696..a0dc3f29 100644
--- a/src/widgets/notebooknodeexplorer.cpp
+++ b/src/widgets/notebooknodeexplorer.cpp
@@ -620,8 +620,9 @@ void NotebookNodeExplorer::setCurrentNode(Node *p_node)
Q_ASSERT(getItemNodeData(item).getNode() == p_node);
- for (auto &it : items) {
- it->setExpanded(true);
+ // Do not expand the last item.
+ for (int i = 0; i < items.size() - 1; ++i) {
+ items[i]->setExpanded(true);
}
m_masterExplorer->setCurrentItem(item);
@@ -1232,7 +1233,7 @@ void NotebookNodeExplorer::removeNodes(QVector p_nodes,
updateNode(node);
}
- if (!p_configOnly && !p_skipRecycleBin) {
+ if (!p_configOnly && !p_skipRecycleBin && m_recycleBinNodeVisible) {
updateNode(m_notebook->getRecycleBinNode().data());
}
@@ -1320,15 +1321,12 @@ void NotebookNodeExplorer::reload()
void NotebookNodeExplorer::focusNormalNode()
{
auto item = m_masterExplorer->currentItem();
- if (item && item != m_masterExplorer->topLevelItem(0)) {
+ if (item && (!m_recycleBinNodeVisible || item != m_masterExplorer->topLevelItem(0))) {
// Not recycle bin.
return;
}
- auto cnt = m_masterExplorer->topLevelItemCount();
- if (cnt > 1) {
- m_masterExplorer->setCurrentItem(m_masterExplorer->topLevelItem(1));
- }
+ m_masterExplorer->setCurrentItem(m_masterExplorer->topLevelItem(m_recycleBinNodeVisible ? 1 : 0));
}
void NotebookNodeExplorer::sortNodes(QVector> &p_nodes) const
@@ -1341,7 +1339,10 @@ void NotebookNodeExplorer::sortNodes(QVector> &p_nodes) con
// Put containers first.
int firstFileIndex = p_nodes.size();
for (int i = 0; i < p_nodes.size(); ++i) {
- if (!p_nodes[i]->isContainer()) {
+ if (p_nodes[i]->isContainer()) {
+ // If it is a container, load it to set its created time and modified time.
+ p_nodes[i]->load();
+ } else {
firstFileIndex = i;
break;
}
@@ -1356,6 +1357,10 @@ void NotebookNodeExplorer::sortNodes(QVector> &p_nodes) con
void NotebookNodeExplorer::sortNodes(QVector> &p_nodes, int p_start, int p_end, int p_viewOrder) const
{
+ if (p_start >= p_end) {
+ return;
+ }
+
bool reversed = false;
switch (p_viewOrder) {
case ViewOrder::OrderedByNameReversed: