Browse Source

support Ctrl+Shift+T to recover last closed files

Add config LastClosedFile in [shortcuts] of vnote.ini.
Le Tan 8 years ago
parent
commit
ae19191917

+ 2 - 0
src/resources/docs/shortcuts_en.md

@@ -15,6 +15,8 @@ Quit VNote.
 VNote supports `Ctrl+J` and `Ctrl+K` for navigation in the notebooks list, directories list, notes list, opened notes list, and outline list.
 - `Ctrl+Left Mouse`  
 Scroll in all directions.
+- `Ctrl+Shift+T`  
+Recover last closed file.
 
 ### Read Mode
 - `Ctrl+W`  

+ 2 - 0
src/resources/docs/shortcuts_zh.md

@@ -15,6 +15,8 @@
 在笔记本列表、文件夹列表、笔记列表、已打开笔记列表和大纲目录中,均支持`Ctrl+J`和`Ctrl+K`导航。
 - `Ctrl+Left Mouse`  
 任意滚动。
+- `Ctrl+Shift+T`  
+恢复上一个关闭的文件。
 
 ### 阅读模式
 - `Ctrl+W`  

+ 2 - 0
src/resources/vnote.ini

@@ -191,6 +191,8 @@ Find=Ctrl+F
 FindNext=F3
 ; Find previous occurence
 FindPrevious=Shift+F3
+; Recover last closed file
+LastClosedFile=Ctrl+Shift+T
 
 [captain_mode_shortcuts]
 ; Define shortcuts in Captain mode here.

+ 29 - 0
src/veditarea.cpp

@@ -70,6 +70,22 @@ void VEditArea::setupUI()
     connect(m_findReplace, &VFindReplaceDialog::dialogClosed,
             this, &VEditArea::handleFindDialogClosed);
     m_findReplace->hide();
+
+    // Shortcut Ctrl+Shift+T to open last closed file.
+    QString keySeq = g_config->getShortcutKeySequence("LastClosedFile");
+    qDebug() << "set LastClosedFile shortcut to" << keySeq;
+    QShortcut *lastClosedFileShortcut = new QShortcut(QKeySequence(keySeq), this);
+    lastClosedFileShortcut->setContext(Qt::ApplicationShortcut);
+    connect(lastClosedFileShortcut, &QShortcut::activated,
+            this, [this]() {
+                if (!m_lastClosedFiles.isEmpty()) {
+                    const VFileSessionInfo &file = m_lastClosedFiles.top();
+                    QVector<VFileSessionInfo> files(1, file);
+                    m_lastClosedFiles.pop();
+
+                    openFiles(files);
+                }
+            });
 }
 
 void VEditArea::insertSplitWindow(int idx)
@@ -947,3 +963,16 @@ void VEditArea::evaluateMagicWordsByCaptain(void *p_target, void *p_data)
     }
 }
 
+void VEditArea::recordClosedFile(const VFileSessionInfo &p_file)
+{
+    for (auto it = m_lastClosedFiles.begin(); it != m_lastClosedFiles.end(); ++it) {
+        if (it->m_file == p_file.m_file) {
+            // Remove it.
+            m_lastClosedFiles.erase(it);
+            break;
+        }
+    }
+
+    m_lastClosedFiles.push(p_file);
+    qDebug() << "pushed closed file" << p_file.m_file;
+}

+ 8 - 1
src/veditarea.h

@@ -8,11 +8,12 @@
 #include <QDir>
 #include <QVector>
 #include <QPair>
-#include <QtDebug>
 #include <QSplitter>
+#include <QStack>
 #include "vnotebook.h"
 #include "veditwindow.h"
 #include "vnavigationmode.h"
+#include "vfilesessioninfo.h"
 
 class VFile;
 class VDirectory;
@@ -76,6 +77,9 @@ public:
     // Open files @p_files.
     int openFiles(const QVector<VFileSessionInfo> &p_files);
 
+    // Record a closed file in the stack.
+    void recordClosedFile(const VFileSessionInfo &p_file);
+
 signals:
     // Emit when current window's tab status updated.
     void tabStatusUpdated(const VEditTabInfo &p_info);
@@ -199,6 +203,9 @@ private:
     QSplitter *splitter;
     VFindReplaceDialog *m_findReplace;
 
+    // Last closed files stack.
+    QStack<VFileSessionInfo> m_lastClosedFiles;
+
     // Navigation Mode.
     // Map second key to VEditWindow.
     QMap<QChar, VEditWindow *> m_keyMap;

+ 20 - 0
src/veditwindow.cpp

@@ -302,18 +302,25 @@ bool VEditWindow::closeFile(const VFile *p_file, bool p_forced)
 
     VEditTab *editor = getTab(idx);
     Q_ASSERT(editor);
+    VEditTabInfo tabInfo = editor->fetchTabInfo();
+    VFileSessionInfo info = VFileSessionInfo::fromEditTabInfo(&tabInfo);
     if (!p_forced) {
         setCurrentIndex(idx);
         updateTabStatus(idx);
     }
+
     // Even p_forced is true we need to delete unused images.
     bool ok = editor->closeFile(p_forced);
     if (ok) {
         removeEditTab(idx);
+
+        m_editArea->recordClosedFile(info);
     }
+
     if (count() == 0) {
         emit requestRemoveSplit(this);
     }
+
     return ok;
 }
 
@@ -362,22 +369,30 @@ bool VEditWindow::closeAllFiles(bool p_forced)
     for (int i = 0; i < nrTab; ++i) {
         VEditTab *editor = getTab(0);
 
+        VEditTabInfo tabInfo = editor->fetchTabInfo();
+        VFileSessionInfo info = VFileSessionInfo::fromEditTabInfo(&tabInfo);
+
         if (!p_forced) {
             setCurrentIndex(0);
             updateTabStatus(0);
         }
+
         // Even p_forced is true we need to delete unused images.
         bool ok = editor->closeFile(p_forced);
         if (ok) {
             removeEditTab(0);
+
+            m_editArea->recordClosedFile(info);
         } else {
             ret = false;
             break;
         }
     }
+
     if (count() == 0) {
         emit requestRemoveSplit(this);
     }
+
     return ret;
 }
 
@@ -420,9 +435,13 @@ bool VEditWindow::closeTab(int p_index)
 {
     VEditTab *editor = getTab(p_index);
     Q_ASSERT(editor);
+    VEditTabInfo tabInfo = editor->fetchTabInfo();
+    VFileSessionInfo info = VFileSessionInfo::fromEditTabInfo(&tabInfo);
     bool ok = editor->closeFile(false);
     if (ok) {
         removeEditTab(p_index);
+
+        m_editArea->recordClosedFile(info);
     }
 
     // User clicks the close button. We should make this window
@@ -431,6 +450,7 @@ bool VEditWindow::closeTab(int p_index)
     if (count() == 0) {
         emit requestRemoveSplit(this);
     }
+
     return ok;
 }
 

+ 7 - 1
src/vnote.cpp

@@ -343,7 +343,13 @@ VFile *VNote::getFile(const QString &p_path)
 {
     VFile *file = getInternalFile(p_path);
     if (!file) {
-        file = getOrphanFile(p_path, true, false);
+        QFileInfo fi(p_path);
+        if (fi.isNativePath()) {
+            file = getOrphanFile(p_path, true, false);
+        } else {
+            // File in Qt resource system.
+            file = getOrphanFile(p_path, false, true);
+        }
     }
 
     return file;