open an external file as internal note if it is a note within VNote

This commit is contained in:
Le Tan 2017-08-07 20:04:18 +08:00
parent dfaa7772df
commit c2fe857e3a
10 changed files with 174 additions and 18 deletions

View File

@ -650,3 +650,37 @@ bool VUtils::equalPath(const QString &p_patha, const QString &p_pathb)
return a == b; return a == b;
} }
bool VUtils::splitPathInBasePath(const QString &p_base,
const QString &p_path,
QStringList &p_parts)
{
p_parts.clear();
QString a = QDir::cleanPath(p_base);
QString b = QDir::cleanPath(p_path);
#if defined(Q_OS_WIN)
if (!b.toLower().startsWith(a.toLower())) {
return false;
}
#else
if (!b.startsWith(a)) {
return false;
}
#endif
if (a.size() == b.size()) {
return true;
}
Q_ASSERT(a.size() < b.size());
if (b.at(a.size()) != '/') {
return false;
}
p_parts = b.right(b.size() - a.size() - 1).split("/", QString::SkipEmptyParts);
qDebug() << QString("split path %1 based on %2 to %3 parts").arg(p_path).arg(p_base).arg(p_parts.size());
return true;
}

View File

@ -109,6 +109,15 @@ public:
// Returns true if @p_patha and @p_pathb points to the same file/directory. // Returns true if @p_patha and @p_pathb points to the same file/directory.
static bool equalPath(const QString &p_patha, const QString &p_pathb); static bool equalPath(const QString &p_patha, const QString &p_pathb);
// Try to split @p_path into multiple parts based on @p_base.
// Returns false if @p_path is not under @p_base directory.
// @p_parts will be empty if @p_path is right @p_base.
// Example: "/home/tamlok/study", "/home/tamlok/study/a/b/c/vnote.md"
// returns true and @p_parts is {a, b, c, vnote.md}.
static bool splitPathInBasePath(const QString &p_base,
const QString &p_path,
QStringList &p_parts);
// Regular expression for image link. // Regular expression for image link.
// ![image title]( http://github.com/tamlok/vnote.jpg "alt \" text" ) // ![image title]( http://github.com/tamlok/vnote.jpg "alt \" text" )
// Captured texts (need to be trimmed): // Captured texts (need to be trimmed):

View File

@ -678,3 +678,36 @@ void VDirectory::reorderFiles(int p_first, int p_last, int p_destStart)
m_files = oriFiles; m_files = oriFiles;
} }
} }
VFile *VDirectory::tryLoadFile(QStringList &p_filePath)
{
qDebug() << "directory" << m_name << "tryLoadFile()" << p_filePath.join("/");
if (p_filePath.isEmpty()) {
return NULL;
}
bool opened = isOpened();
if (!open()) {
return NULL;
}
VFile *file = NULL;
if (p_filePath.size() == 1) {
// File.
file = findFile(p_filePath.at(0));
} else {
// Directory.
VDirectory *dir = findSubDirectory(p_filePath.at(0));
if (dir) {
p_filePath.removeFirst();
file = dir->tryLoadFile(p_filePath);
}
}
if (!file && !opened) {
close();
}
return file;
}

View File

@ -60,20 +60,20 @@ public:
static VDirectory *copyDirectory(VDirectory *p_destDir, const QString &p_destName, static VDirectory *copyDirectory(VDirectory *p_destDir, const QString &p_destName,
VDirectory *p_srcDir, bool p_cut); VDirectory *p_srcDir, bool p_cut);
inline const QVector<VDirectory *> &getSubDirs() const; const QVector<VDirectory *> &getSubDirs() const;
inline const QString &getName() const; const QString &getName() const;
inline void setName(const QString &p_name); void setName(const QString &p_name);
inline bool isOpened() const; bool isOpened() const;
inline VDirectory *getParentDirectory(); VDirectory *getParentDirectory();
inline const VDirectory *getParentDirectory() const; const VDirectory *getParentDirectory() const;
inline VNotebook *getNotebook(); VNotebook *getNotebook();
inline const VNotebook *getNotebook() const; const VNotebook *getNotebook() const;
inline const QVector<VFile *> &getFiles() const; const QVector<VFile *> &getFiles() const;
inline QString retrivePath() const; QString retrivePath() const;
QString retriveBasePath() const; QString retriveBasePath() const;
inline QString retriveRelativePath() const; QString retriveRelativePath() const;
inline QString getNotebookName() const; QString getNotebookName() const;
inline bool isExpanded() const; bool isExpanded() const;
void setExpanded(bool p_expanded); void setExpanded(bool p_expanded);
void reorderFiles(int p_first, int p_last, int p_destStart); void reorderFiles(int p_first, int p_last, int p_destStart);
@ -90,6 +90,9 @@ public:
// notebook. // notebook.
bool writeToConfig() const; bool writeToConfig() const;
// Try to load file given relative path @p_filePath.
VFile *tryLoadFile(QStringList &p_filePath);
private: private:
// Get the path of @p_dir recursively // Get the path of @p_dir recursively
QString retrivePath(const VDirectory *p_dir) const; QString retrivePath(const VDirectory *p_dir) const;

View File

@ -1890,11 +1890,19 @@ void VMainWindow::handleVimStatusUpdated(const VVim *p_vim)
} }
} }
void VMainWindow::openExternalFiles(const QStringList &p_files) void VMainWindow::openExternalFiles(const QStringList &p_files, bool p_forceOrphan)
{ {
qDebug() << "open external files" << p_files; qDebug() << "open external files" << p_files;
for (int i = 0; i < p_files.size(); ++i) { for (int i = 0; i < p_files.size(); ++i) {
VFile *file = vnote->getOrphanFile(p_files[i], true); VFile *file = NULL;
if (!p_forceOrphan) {
file = vnote->getInternalFile(p_files[i]);
}
if (!file) {
file = vnote->getOrphanFile(p_files[i], true);
}
editArea->openFile(file, OpenFileMode::Read); editArea->openFile(file, OpenFileMode::Read);
} }
} }

View File

@ -53,7 +53,9 @@ public:
void editOrphanFileInfo(VFile *p_file); void editOrphanFileInfo(VFile *p_file);
// Open external files @p_files as orphan files. // Open external files @p_files as orphan files.
void openExternalFiles(const QStringList &p_files); // If @p_forceOrphan is false, for each file, VNote will try to find out if
// it is a note inside VNote. If yes, VNote will open it as internal file.
void openExternalFiles(const QStringList &p_files, bool p_forceOrphan = false);
private slots: private slots:
void importNoteFromFile(); void importNoteFromFile();

View File

@ -309,3 +309,17 @@ VFile *VNote::getOrphanFile(const QString &p_path, bool p_modifiable, bool p_sys
m_externalFiles.append(file); m_externalFiles.append(file);
return file; return file;
} }
VFile *VNote::getInternalFile(const QString &p_path)
{
VFile *file = NULL;
for (auto & nb : m_notebooks) {
file = nb->tryLoadFile(p_path);
if (file) {
break;
}
}
return file;
}

View File

@ -78,6 +78,11 @@ public:
VFile *getOrphanFile(const QString &p_path, bool p_modifiable, VFile *getOrphanFile(const QString &p_path, bool p_modifiable,
bool p_systemFile = false); bool p_systemFile = false);
// Given the path of a file, try to find it in all notebooks.
// Returns a VFile struct if it is a note in one notebook.
// Otherwise, returns NULL.
VFile *getInternalFile(const QString &p_path);
public slots: public slots:
void updateTemplate(); void updateTemplate();

View File

@ -187,6 +187,37 @@ bool VNotebook::containsFile(const VFile *p_file) const
return m_rootDir->containsFile(p_file); return m_rootDir->containsFile(p_file);
} }
VFile *VNotebook::tryLoadFile(const QString &p_path)
{
QFileInfo fi(p_path);
Q_ASSERT(fi.isAbsolute());
if (!fi.exists()) {
return NULL;
}
QStringList filePath;
if (VUtils::splitPathInBasePath(m_path, p_path, filePath)) {
if (filePath.isEmpty()) {
return NULL;
}
bool opened = isOpened();
if (!open()) {
return NULL;
}
VFile *file = m_rootDir->tryLoadFile(filePath);
if (!file && !opened) {
close();
}
return file;
}
return NULL;
}
const QString &VNotebook::getImageFolder() const const QString &VNotebook::getImageFolder() const
{ {
if (m_imageFolder.isEmpty()) { if (m_imageFolder.isEmpty()) {
@ -205,3 +236,8 @@ const QString &VNotebook::getImageFolderConfig() const
{ {
return m_imageFolder; return m_imageFolder;
} }
bool VNotebook::isOpened() const
{
return m_rootDir->isOpened();
}

View File

@ -17,15 +17,27 @@ public:
// Open the root directory to load contents // Open the root directory to load contents
bool open(); bool open();
// Whether this notebook is opened.
bool isOpened() const;
// Close all the directory and files of this notebook. // Close all the directory and files of this notebook.
// Please make sure all files belonging to this notebook have been closed in the tab. // Please make sure all files belonging to this notebook have been closed in the tab.
void close(); void close();
bool containsFile(const VFile *p_file) const; bool containsFile(const VFile *p_file) const;
// Try to load the file @p_path.
// Returns the corresponding VFile struct if @p_path is a note inside this notebook.
// Otherwise, returns NULL.
// If notebook is not opened currently, it will open itself and close itself
// if @p_path is not inside this notebook.
VFile *tryLoadFile(const QString &p_path);
QString getName() const; QString getName() const;
QString getPath() const; QString getPath() const;
inline VDirectory *getRootDir();
VDirectory *getRootDir() const;
void rename(const QString &p_name); void rename(const QString &p_name);
static VNotebook *createNotebook(const QString &p_name, const QString &p_path, static VNotebook *createNotebook(const QString &p_name, const QString &p_path,
@ -76,7 +88,7 @@ private:
VDirectory *m_rootDir; VDirectory *m_rootDir;
}; };
inline VDirectory *VNotebook::getRootDir() inline VDirectory *VNotebook::getRootDir() const
{ {
return m_rootDir; return m_rootDir;
} }