Le Tan 4 роки тому
батько
коміт
877001587b

+ 26 - 0
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;
+}

+ 2 - 0
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:

+ 1 - 0
src/data/extra/web/css/outline.css

@@ -135,6 +135,7 @@
 
 .section-nav a {
     color: inherit !important;
+    white-space: nowrap;
 }
 
 .row {

+ 10 - 10
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 '<a href="#' + item.anchor + '" data="' + item.anchor + '">' + item.title + '</a>';
+    return '<a href="#' + item.anchor + '" title="' + item.title + '" data="' + item.anchor + '">' + item.title + '</a>';
 };
 
 // Turn a perfect toc to a tree using <ul>
@@ -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;
     }
 

+ 2 - 2
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;
     }

+ 2 - 2
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;
     }

+ 14 - 9
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<Node *> 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<QSharedPointer<Node>> &p_nodes) const
@@ -1341,7 +1339,10 @@ void NotebookNodeExplorer::sortNodes(QVector<QSharedPointer<Node>> &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<QSharedPointer<Node>> &p_nodes) con
 
 void NotebookNodeExplorer::sortNodes(QVector<QSharedPointer<Node>> &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: