Răsfoiți Sursa

support locating current note

Support locating the notebook and directory of current note.

Signed-off-by: Le Tan <[email protected]>
Le Tan 9 ani în urmă
părinte
comite
1aa264adc8

+ 16 - 0
src/resources/icons/locate_note.svg

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
+<g id="Icon">
+	<g>
+		<path d="M256,176c-44.004,0-80.001,36-80.001,80c0,44.004,35.997,80,80.001,80c44.005,0,79.999-35.996,79.999-80
+			C335.999,212,300.005,176,256,176z M446.938,234.667c-9.605-88.531-81.074-160-169.605-169.599V32h-42.666v33.067
+			c-88.531,9.599-160,81.068-169.604,169.599H32v42.667h33.062c9.604,88.531,81.072,160,169.604,169.604V480h42.666v-33.062
+			c88.531-9.604,160-81.073,169.605-169.604H480v-42.667H446.938z M256,405.333c-82.137,0-149.334-67.198-149.334-149.333
+			c0-82.136,67.197-149.333,149.334-149.333c82.135,0,149.332,67.198,149.332,149.333C405.332,338.135,338.135,405.333,256,405.333z
+			"/>
+	</g>
+</g>
+</svg>

+ 14 - 2
src/vdirectory.h

@@ -51,10 +51,12 @@ public:
     inline bool isOpened() const;
     inline VDirectory *getParentDirectory();
     inline const VDirectory *getParentDirectory() const;
+    inline VNotebook *getNotebook();
+    inline const VNotebook *getNotebook() const;
     inline const QVector<VFile *> &getFiles() const;
     inline QString retrivePath() const;
     inline QString retriveRelativePath() const;
-    inline QString getNotebook() const;
+    inline QString getNotebookName() const;
     inline bool isExpanded() const;
     void setExpanded(bool p_expanded);
 
@@ -114,11 +116,21 @@ inline const QVector<VFile *> &VDirectory::getFiles() const
     return m_files;
 }
 
-inline QString VDirectory::getNotebook() const
+inline QString VDirectory::getNotebookName() const
 {
     return m_notebook->getName();
 }
 
+inline VNotebook *VDirectory::getNotebook()
+{
+    return m_notebook;
+}
+
+inline const VNotebook *VDirectory::getNotebook() const
+{
+    return m_notebook;
+}
+
 inline QString VDirectory::retrivePath() const
 {
     return retrivePath(this);

+ 55 - 2
src/vdirectorytree.cpp

@@ -428,7 +428,7 @@ void VDirectoryTree::copySelectedDirectories(bool p_cut)
     for (int i = 0; i < items.size(); ++i) {
         VDirectory *dir = getVDirectory(items[i]);
         QJsonObject dirJson;
-        dirJson["notebook"] = dir->getNotebook();
+        dirJson["notebook"] = dir->getNotebookName();
         dirJson["path"] = dir->retrivePath();
         dirs.append(dirJson);
 
@@ -561,7 +561,7 @@ QTreeWidgetItem *VDirectoryTree::findVDirectory(const VDirectory *p_dir, bool &p
     p_widget = false;
     if (!p_dir) {
         return NULL;
-    } else if (p_dir->getNotebook() != m_notebook->getName()) {
+    } else if (p_dir->getNotebookName() != m_notebook->getName()) {
         return NULL;
     } else if (p_dir == m_notebook->getRootDir()) {
         p_widget = true;
@@ -591,3 +591,56 @@ QTreeWidgetItem *VDirectoryTree::findVDirectory(const VDirectory *p_dir, bool &p
     }
     return NULL;
 }
+
+bool VDirectoryTree::locateDirectory(const VDirectory *p_directory)
+{
+    if (p_directory) {
+        qDebug() << "locate directory" << p_directory->retrivePath()
+                 << "in" << m_notebook->getName();
+        if (p_directory->getNotebook() != m_notebook) {
+            return false;
+        }
+        QTreeWidgetItem *item = expandToVDirectory(p_directory);
+        if (item) {
+            setCurrentItem(item);
+        }
+        return item;
+    }
+    return false;
+}
+
+QTreeWidgetItem *VDirectoryTree::expandToVDirectory(const VDirectory *p_directory)
+{
+    if (!p_directory || p_directory->getNotebook() != m_notebook
+        || p_directory == m_notebook->getRootDir()) {
+        return NULL;
+    }
+
+    if (p_directory->getParentDirectory() == m_notebook->getRootDir()) {
+        // Top-level items.
+        int nrChild = topLevelItemCount();
+        for (int i = 0; i < nrChild; ++i) {
+            QTreeWidgetItem *item = topLevelItem(i);
+            if (getVDirectory(item) == p_directory) {
+                return item;
+            }
+        }
+    } else {
+        QTreeWidgetItem *pItem = expandToVDirectory(p_directory->getParentDirectory());
+        if (!pItem) {
+            return NULL;
+        }
+        int nrChild = pItem->childCount();
+        if (nrChild == 0) {
+            updateDirectoryTreeOne(pItem, 1);
+        }
+        nrChild = pItem->childCount();
+        for (int i = 0; i < nrChild; ++i) {
+            QTreeWidgetItem *item = pItem->child(i);
+            if (getVDirectory(item) == p_directory) {
+                return item;
+            }
+        }
+    }
+    return NULL;
+}

+ 9 - 0
src/vdirectorytree.h

@@ -17,6 +17,8 @@ class VDirectoryTree : public QTreeWidget
 public:
     explicit VDirectoryTree(VNote *vnote, QWidget *parent = 0);
     inline void setEditArea(VEditArea *p_editArea);
+    bool locateDirectory(const VDirectory *p_directory);
+    inline const VNotebook *currentNotebook() const;
 
 signals:
     void currentDirectoryChanged(VDirectory *p_directory);
@@ -59,6 +61,8 @@ private:
     bool copyDirectory(VDirectory *p_destDir, const QString &p_destName,
                        VDirectory *p_srcDir, bool p_cut);
     void updateChildren(QTreeWidgetItem *p_item);
+    // Expand/create the directory tree nodes to @p_directory.
+    QTreeWidgetItem *expandToVDirectory(const VDirectory *p_directory);
 
     VNote *vnote;
     QPointer<VNotebook> m_notebook;
@@ -87,4 +91,9 @@ inline void VDirectoryTree::setEditArea(VEditArea *p_editArea)
     m_editArea = p_editArea;
 }
 
+inline const VNotebook *VDirectoryTree::currentNotebook() const
+{
+    return m_notebook;
+}
+
 #endif // VDIRECTORYTREE_H

+ 42 - 3
src/veditwindow.cpp

@@ -6,19 +6,26 @@
 #include "vconfigmanager.h"
 #include "utils/vutils.h"
 #include "vfile.h"
+#include "vmainwindow.h"
 
 extern VConfigManager vconfig;
 
 VEditWindow::VEditWindow(VNote *vnote, QWidget *parent)
     : QTabWidget(parent), vnote(vnote)
 {
+    initTabActions();
     setupCornerWidget();
 
     setTabsClosable(true);
     setMovable(true);
     setContextMenuPolicy(Qt::CustomContextMenu);
 
-    tabBar()->installEventFilter(this);
+    QTabBar *bar = tabBar();
+    bar->installEventFilter(this);
+    bar->setContextMenuPolicy(Qt::CustomContextMenu);
+    connect(bar, &QTabBar::customContextMenuRequested,
+            this, &VEditWindow::tabbarContextMenuRequested);
+
 
     connect(this, &VEditWindow::tabCloseRequested,
             this, &VEditWindow::handleTabCloseRequest);
@@ -28,18 +35,27 @@ VEditWindow::VEditWindow(VNote *vnote, QWidget *parent)
             this, &VEditWindow::contextMenuRequested);
 }
 
+void VEditWindow::initTabActions()
+{
+    locateAct = new QAction(QIcon(":/resources/icons/locate_note.svg"),
+                            tr("Locate"), this);
+    locateAct->setStatusTip(tr("Locate the directory of current note"));
+    connect(locateAct, &QAction::triggered,
+            this, &VEditWindow::handleLocateAct);
+}
+
 void VEditWindow::setupCornerWidget()
 {
     // Right corner button
     // Actions
     splitAct = new QAction(QIcon(":/resources/icons/split_window.svg"),
-                                    tr("Split"), this);
+                           tr("Split"), this);
     splitAct->setStatusTip(tr("Split current window vertically"));
     connect(splitAct, &QAction::triggered,
             this, &VEditWindow::splitWindow);
 
     removeSplitAct = new QAction(QIcon(":/resources/icons/remove_split.svg"),
-                                          tr("Remove split"), this);
+                                 tr("Remove split"), this);
     removeSplitAct->setStatusTip(tr("Remove current split window"));
     connect(removeSplitAct, &QAction::triggered,
             this, &VEditWindow::removeSplit);
@@ -361,6 +377,20 @@ void VEditWindow::contextMenuRequested(QPoint pos)
     }
 }
 
+void VEditWindow::tabbarContextMenuRequested(QPoint p_pos)
+{
+    QMenu menu(this);
+
+    QTabBar *bar = tabBar();
+    int tab = bar->tabAt(p_pos);
+    if (tab == -1) {
+        return;
+    }
+    locateAct->setData(tab);
+    menu.addAction(locateAct);
+    menu.exec(mapToGlobal(p_pos));
+}
+
 void VEditWindow::tabListJump(QAction *action)
 {
     if (!action) {
@@ -563,3 +593,12 @@ VEditTab *VEditWindow::currentEditTab()
     }
     return getTab(idx);
 }
+
+void VEditWindow::handleLocateAct()
+{
+    int tab = locateAct->data().toInt();
+    qDebug() << "context menu of tab" << tab;
+    VEditTab *editor = getTab(tab);
+    QPointer<VFile> file = editor->getFile();
+    vnote->getMainWindow()->locateFile(file);
+}

+ 7 - 2
src/veditwindow.h

@@ -66,8 +66,11 @@ private slots:
     void handleTabStatusChanged();
     void updateTabListMenu();
     void updateSplitMenu();
+    void tabbarContextMenuRequested(QPoint p_pos);
+    void handleLocateAct();
 
 private:
+    void initTabActions();
     void setupCornerWidget();
     void removeEditTab(int p_index);
     int insertEditTab(int p_index, VFile *p_file, QWidget *p_page);
@@ -79,7 +82,7 @@ private:
     inline QString generateTooltip(const VFile *p_file) const;
     inline QString generateTabText(const QString &p_name, bool p_modified) const;
     bool canRemoveSplit();
-    // If the scroller of the tabBar() is visible.
+    // If the scroller of the tabBar() is visible
     bool scrollerVisible() const;
     void setLeftCornerWidgetVisible(bool p_visible);
 
@@ -93,6 +96,8 @@ private:
     QAction *splitAct;
     QAction *removeSplitAct;
     QActionGroup *tabListAct;
+    // Locate current note in the directory and file list
+    QAction *locateAct;
 };
 
 inline VEditTab* VEditWindow::getTab(int tabIndex) const
@@ -106,7 +111,7 @@ inline QString VEditWindow::generateTooltip(const VFile *p_file) const
         return "";
     }
     // [Notebook]path
-    return QString("[%1] %2").arg(p_file->getNotebook()).arg(p_file->retrivePath());
+    return QString("[%1] %2").arg(p_file->getNotebookName()).arg(p_file->retrivePath());
 }
 
 inline QString VEditWindow::generateTabText(const QString &p_name, bool p_modified) const

+ 10 - 2
src/vfile.h

@@ -7,6 +7,8 @@
 #include "vdirectory.h"
 #include "vconstants.h"
 
+class VNotebook;
+
 class VFile : public QObject
 {
     Q_OBJECT
@@ -25,7 +27,8 @@ public:
     inline DocType getDocType() const;
     inline QString &getContent();
     inline void setContent(const QString &p_content);
-    inline QString getNotebook() const;
+    inline VNotebook *getNotebook();
+    inline QString getNotebookName() const;
     inline QString retrivePath() const;
     inline QString retriveRelativePath() const;
     inline QString retriveBasePath() const;
@@ -80,7 +83,12 @@ inline QString &VFile::getContent()
     return m_content;
 }
 
-inline QString VFile::getNotebook() const
+inline QString VFile::getNotebookName() const
+{
+    return getDirectory()->getNotebookName();
+}
+
+inline VNotebook *VFile::getNotebook()
 {
     return getDirectory()->getNotebook();
 }

+ 15 - 1
src/vfilelist.cpp

@@ -348,7 +348,7 @@ void VFileList::copySelectedFiles(bool p_isCut)
     for (int i = 0; i < items.size(); ++i) {
         VFile *file = getVFile(items[i]);
         QJsonObject fileJson;
-        fileJson["notebook"] = file->getNotebook();
+        fileJson["notebook"] = file->getNotebookName();
         fileJson["path"] = file->retrivePath();
         files.append(fileJson);
 
@@ -455,3 +455,17 @@ void VFileList::keyPressEvent(QKeyEvent *event)
     }
     QWidget::keyPressEvent(event);
 }
+
+bool VFileList::locateFile(const VFile *p_file)
+{
+    if (p_file) {
+        if (p_file->getDirectory() != m_directory) {
+            return false;
+        }
+        QListWidgetItem *item = findItem(p_file);
+        if (item) {
+            fileList->setCurrentItem(item);
+        }
+    }
+    return false;
+}

+ 7 - 0
src/vfilelist.h

@@ -27,6 +27,8 @@ public:
     inline void setEditArea(VEditArea *editArea);
     void fileInfo(VFile *p_file);
     void deleteFile(VFile *p_file);
+    bool locateFile(const VFile *p_file);
+    inline const VDirectory *currentDirectory() const;
 
 signals:
     void fileClicked(VFile *p_file, OpenFileMode mode = OpenFileMode::Read);
@@ -89,4 +91,9 @@ inline QPointer<VFile> VFileList::getVFile(QListWidgetItem *p_item)
     return p_item->data(Qt::UserRole).value<VFile *>();
 }
 
+inline const VDirectory *VFileList::currentDirectory() const
+{
+    return m_directory;
+}
+
 #endif // VFILELIST_H

+ 23 - 1
src/vmainwindow.cpp

@@ -575,7 +575,7 @@ void VMainWindow::handleCurTabStatusChanged(const VFile *p_file, const VEditTab
 
     QString title;
     if (p_file) {
-        title = QString("[%1] %2").arg(p_file->getNotebook()).arg(p_file->retrivePath());
+        title = QString("[%1] %2").arg(p_file->getNotebookName()).arg(p_file->retrivePath());
         if (p_file->isModified()) {
             title.append('*');
         }
@@ -726,3 +726,25 @@ void VMainWindow::insertImage()
     Q_ASSERT(m_curTab == editArea->currentEditTab());
     m_curTab->insertImage();
 }
+
+void VMainWindow::locateFile(VFile *p_file) const
+{
+    if (!p_file) {
+        return;
+    }
+    qDebug() << "locate file" << p_file->retrivePath();
+    VNotebook *notebook = p_file->getNotebook();
+    if (notebookSelector->locateNotebook(notebook)) {
+        while (directoryTree->currentNotebook() != notebook) {
+            QCoreApplication::sendPostedEvents();
+        }
+        VDirectory *dir = p_file->getDirectory();
+        if (directoryTree->locateDirectory(dir)) {
+            while (fileList->currentDirectory() != dir) {
+                QCoreApplication::sendPostedEvents();
+            }
+            fileList->locateFile(p_file);
+        }
+    }
+}
+

+ 1 - 0
src/vmainwindow.h

@@ -35,6 +35,7 @@ class VMainWindow : public QMainWindow
 public:
     VMainWindow(QWidget *parent = 0);
     const QVector<QPair<QString, QString> > &getPalette() const;
+    void locateFile(VFile *p_file) const;
 
 private slots:
     void importNoteFromFile();

+ 2 - 1
src/vnote.cpp

@@ -6,6 +6,7 @@
 #include "vnote.h"
 #include "utils/vutils.h"
 #include "vconfigmanager.h"
+#include "vmainwindow.h"
 
 VConfigManager vconfig;
 
@@ -14,7 +15,7 @@ QString VNote::preTemplateHtml;
 QString VNote::postTemplateHtml;
 
 VNote::VNote(QObject *parent)
-    : QObject(parent)
+    : QObject(parent), m_mainWindow(dynamic_cast<VMainWindow *>(parent))
 {
     vconfig.initialize();
     initTemplate();

+ 9 - 0
src/vnote.h

@@ -12,6 +12,8 @@
 #include "vnotebook.h"
 #include "vconstants.h"
 
+class VMainWindow;
+
 class VNote : public QObject
 {
     Q_OBJECT
@@ -33,6 +35,7 @@ public:
     inline const QVector<QPair<QString, QString> > &getPalette() const;
     void initPalette(QPalette palette);
     QString getColorFromPalette(const QString &p_name) const;
+    inline VMainWindow *getMainWindow() const;
 
 public slots:
     void updateTemplate();
@@ -41,6 +44,7 @@ private:
     // Maintain all the notebooks. Other holder should use QPointer.
     QVector<VNotebook *> m_notebooks;
     QVector<QPair<QString, QString> > m_palette;
+    VMainWindow *m_mainWindow;
 };
 
 inline const QVector<QPair<QString, QString> >& VNote::getPalette() const
@@ -48,4 +52,9 @@ inline const QVector<QPair<QString, QString> >& VNote::getPalette() const
     return m_palette;
 }
 
+inline VMainWindow *VNote::getMainWindow() const
+{
+    return m_mainWindow;
+}
+
 #endif // VNOTE_H

+ 1 - 0
src/vnote.qrc

@@ -76,5 +76,6 @@
         <file>resources/icons/import_note.svg</file>
         <file>resources/icons/editing.svg</file>
         <file>resources/icons/reading.svg</file>
+        <file>resources/icons/locate_note.svg</file>
     </qresource>
 </RCC>

+ 13 - 0
src/vnotebookselector.cpp

@@ -343,3 +343,16 @@ int VNotebookSelector::indexOfListItem(const QListWidgetItem *p_item)
     }
     return -1;
 }
+
+bool VNotebookSelector::locateNotebook(const VNotebook *p_notebook)
+{
+    if (p_notebook) {
+        for (int i = 0; i < m_notebooks.size(); ++i) {
+            if (m_notebooks[i] == p_notebook) {
+                setCurrentIndexNotebook(i);
+                return true;
+            }
+        }
+    }
+    return false;
+}

+ 2 - 0
src/vnotebookselector.h

@@ -19,6 +19,8 @@ public:
     explicit VNotebookSelector(VNote *vnote, QWidget *p_parent = 0);
     void update();
     inline void setEditArea(VEditArea *p_editArea);
+    // Select notebook @p_notebook.
+    bool locateNotebook(const VNotebook *p_notebook);
 
 signals:
     void curNotebookChanged(VNotebook *p_notebook);