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);