From 1aa264adc80dd740a02bbda803951fb630d43ad6 Mon Sep 17 00:00:00 2001 From: Le Tan Date: Sat, 24 Dec 2016 13:09:19 +0800 Subject: [PATCH] support locating current note Support locating the notebook and directory of current note. Signed-off-by: Le Tan --- src/resources/icons/locate_note.svg | 16 ++++++++ src/vdirectory.h | 16 +++++++- src/vdirectorytree.cpp | 57 ++++++++++++++++++++++++++++- src/vdirectorytree.h | 9 +++++ src/veditwindow.cpp | 45 +++++++++++++++++++++-- src/veditwindow.h | 9 ++++- src/vfile.h | 12 +++++- src/vfilelist.cpp | 16 +++++++- src/vfilelist.h | 7 ++++ src/vmainwindow.cpp | 24 +++++++++++- src/vmainwindow.h | 1 + src/vnote.cpp | 3 +- src/vnote.h | 9 +++++ src/vnote.qrc | 1 + src/vnotebookselector.cpp | 13 +++++++ src/vnotebookselector.h | 2 + 16 files changed, 226 insertions(+), 14 deletions(-) create mode 100644 src/resources/icons/locate_note.svg diff --git a/src/resources/icons/locate_note.svg b/src/resources/icons/locate_note.svg new file mode 100644 index 00000000..e2dd098c --- /dev/null +++ b/src/resources/icons/locate_note.svg @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/src/vdirectory.h b/src/vdirectory.h index a943ade7..cd65599f 100644 --- a/src/vdirectory.h +++ b/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 &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 &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); diff --git a/src/vdirectorytree.cpp b/src/vdirectorytree.cpp index 2fe386a7..a4987750 100644 --- a/src/vdirectorytree.cpp +++ b/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; +} diff --git a/src/vdirectorytree.h b/src/vdirectorytree.h index 1cb211bb..1dfd4b51 100644 --- a/src/vdirectorytree.h +++ b/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 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 diff --git a/src/veditwindow.cpp b/src/veditwindow.cpp index c186e471..20c86809 100644 --- a/src/veditwindow.cpp +++ b/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 file = editor->getFile(); + vnote->getMainWindow()->locateFile(file); +} diff --git a/src/veditwindow.h b/src/veditwindow.h index a9a375f8..2ce7d2b5 100644 --- a/src/veditwindow.h +++ b/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 diff --git a/src/vfile.h b/src/vfile.h index e4758ce3..252f6226 100644 --- a/src/vfile.h +++ b/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(); } diff --git a/src/vfilelist.cpp b/src/vfilelist.cpp index 49c7816e..d451b554 100644 --- a/src/vfilelist.cpp +++ b/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; +} diff --git a/src/vfilelist.h b/src/vfilelist.h index 0417e822..30309345 100644 --- a/src/vfilelist.h +++ b/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 VFileList::getVFile(QListWidgetItem *p_item) return p_item->data(Qt::UserRole).value(); } +inline const VDirectory *VFileList::currentDirectory() const +{ + return m_directory; +} + #endif // VFILELIST_H diff --git a/src/vmainwindow.cpp b/src/vmainwindow.cpp index 5d42b3e6..256de2ab 100644 --- a/src/vmainwindow.cpp +++ b/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); + } + } +} + diff --git a/src/vmainwindow.h b/src/vmainwindow.h index 0d23ad48..628c6fbc 100644 --- a/src/vmainwindow.h +++ b/src/vmainwindow.h @@ -35,6 +35,7 @@ class VMainWindow : public QMainWindow public: VMainWindow(QWidget *parent = 0); const QVector > &getPalette() const; + void locateFile(VFile *p_file) const; private slots: void importNoteFromFile(); diff --git a/src/vnote.cpp b/src/vnote.cpp index a843ab37..42664396 100644 --- a/src/vnote.cpp +++ b/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(parent)) { vconfig.initialize(); initTemplate(); diff --git a/src/vnote.h b/src/vnote.h index a9e9fbdc..fd710b61 100644 --- a/src/vnote.h +++ b/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 > &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 m_notebooks; QVector > m_palette; + VMainWindow *m_mainWindow; }; inline const QVector >& VNote::getPalette() const @@ -48,4 +52,9 @@ inline const QVector >& VNote::getPalette() const return m_palette; } +inline VMainWindow *VNote::getMainWindow() const +{ + return m_mainWindow; +} + #endif // VNOTE_H diff --git a/src/vnote.qrc b/src/vnote.qrc index dcc0c085..95b294e1 100644 --- a/src/vnote.qrc +++ b/src/vnote.qrc @@ -76,5 +76,6 @@ resources/icons/import_note.svg resources/icons/editing.svg resources/icons/reading.svg + resources/icons/locate_note.svg diff --git a/src/vnotebookselector.cpp b/src/vnotebookselector.cpp index e5f9d88d..c851288b 100644 --- a/src/vnotebookselector.cpp +++ b/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; +} diff --git a/src/vnotebookselector.h b/src/vnotebookselector.h index 6e2a1d9b..3f820648 100644 --- a/src/vnotebookselector.h +++ b/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);