diff --git a/src/dialog/vnewnotebookdialog.cpp b/src/dialog/vnewnotebookdialog.cpp
index b5cba5b3..3047200c 100644
--- a/src/dialog/vnewnotebookdialog.cpp
+++ b/src/dialog/vnewnotebookdialog.cpp
@@ -198,13 +198,6 @@ void VNewNotebookDialog::showEvent(QShowEvent *event)
void VNewNotebookDialog::handleInputChanged()
{
- QString warnText = tr("WARNING: The folder chosen is NOT empty! "
- "It is highly recommended to use an EMPTY and EXCLUSIVE folder for a new notebook.")
- .arg(g_config->c_warningTextStyle);
- QString infoText = tr("INFO: The folder chosen seems to be a root "
- "folder of a notebook created by VNote before. "
- "VNote will try to import it by reading the configuration file.")
- .arg("font-weight:bold;");
bool pathOk = false;
bool configExist = false;
bool showWarnLabel = false;
@@ -236,20 +229,25 @@ void VNewNotebookDialog::handleInputChanged()
// Folder is not empty.
configExist = VConfigManager::directoryConfigExist(path);
if (configExist) {
+ QString infoText = tr("INFO: The folder chosen seems to be a root "
+ "folder of a notebook created by VNote before. "
+ "VNote will try to import it by reading the configuration file.")
+ .arg("font-weight:bold;");
m_warnLabel->setText(infoText);
} else {
QString warnText = tr("WARNING: The folder chosen is NOT empty! "
- "VNote will try to create a new notebook and import existing files.")
+ "It is highly recommended to use an EMPTY and EXCLUSIVE folder for a new notebook. "
+ "If continue, VNote will try to create a notebook based on existing "
+ "folders and files recursively.")
.arg(g_config->c_warningTextStyle);
m_warnLabel->setText(warnText);
m_importExternalProject = true;
- // If ok button is clicked, automatically create a configuration file
- configExist = true;
}
showWarnLabel = true;
}
+
pathOk = true;
} else {
pathOk = true;
diff --git a/src/vdirectory.cpp b/src/vdirectory.cpp
index 17cb1f1c..82f3321c 100644
--- a/src/vdirectory.cpp
+++ b/src/vdirectory.cpp
@@ -740,3 +740,65 @@ QList VDirectory::collectFiles()
return files;
}
+
+VDirectory *VDirectory::buildDirectory(const QString &p_path,
+ VDirectory *p_parent,
+ QString *p_errMsg)
+{
+ VDirectory *ret = new VDirectory(p_parent->getNotebook(),
+ p_parent,
+ VUtils::directoryNameFromPath(p_path),
+ QDateTime::currentDateTimeUtc());
+
+ QDir rootDir(p_path);
+
+ // Process all the folders.
+ QVector &subdirs = ret->getSubDirs();
+ QFileInfoList dirList = rootDir.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot);
+ for (auto const & sub : dirList) {
+ VDirectory *dir = VDirectory::buildDirectory(sub.absoluteFilePath(),
+ ret,
+ p_errMsg);
+ if (dir) {
+ subdirs.append(dir);
+ }
+ }
+
+ // Process all the files.
+ QVector &files = ret->getFiles();
+ QDateTime dateTime = QDateTime::currentDateTimeUtc();
+ QList suffixes = g_config->getDocSuffixes()[(int)DocType::Markdown];
+ QStringList filters;
+ for (auto const & suf : suffixes) {
+ filters << ("*." + suf);
+ }
+
+ QStringList fileList = rootDir.entryList(filters, QDir::Files);
+ for (auto const & fileName : fileList) {
+ VNoteFile *file = new VNoteFile(ret,
+ fileName,
+ FileType::Note,
+ true,
+ dateTime,
+ dateTime);
+ if (!file) {
+ VUtils::addErrMsg(p_errMsg, tr("Skip file %1.").arg(rootDir.absoluteFilePath(fileName)));
+ } else {
+ files.append(file);
+ }
+ }
+
+ if (subdirs.isEmpty() && files.isEmpty()) {
+ delete ret;
+ VUtils::addErrMsg(p_errMsg, tr("Skip folder %1.").arg(p_path));
+ return NULL;
+ }
+
+ if (!ret->writeToConfig()) {
+ delete ret;
+ VUtils::addErrMsg(p_errMsg, tr("Fail to write configuration of folder %1.").arg(p_path));
+ return NULL;
+ }
+
+ return ret;
+}
diff --git a/src/vdirectory.h b/src/vdirectory.h
index 5c431540..52a9700f 100644
--- a/src/vdirectory.h
+++ b/src/vdirectory.h
@@ -68,6 +68,7 @@ public:
QString *p_errMsg = NULL);
const QVector &getSubDirs() const;
+ QVector &getSubDirs();
const QString &getName() const;
void setName(const QString &p_name);
@@ -76,7 +77,11 @@ public:
const VDirectory *getParentDirectory() const;
VNotebook *getNotebook();
const VNotebook *getNotebook() const;
+
const QVector &getFiles() const;
+
+ QVector &getFiles();
+
QString fetchPath() const;
QString fetchBasePath() const;
QString fetchRelativePath() const;
@@ -122,6 +127,10 @@ public:
bool p_skipRecycleBin = false,
QString *p_errMsg = NULL);
+ static VDirectory *buildDirectory(const QString &p_path,
+ VDirectory *p_parent,
+ QString *p_errMsg);
+
private:
// Get the path of @p_dir recursively
QString fetchPath(const VDirectory *p_dir) const;
@@ -173,6 +182,11 @@ inline const QVector &VDirectory::getSubDirs() const
return m_subDirs;
}
+inline QVector &VDirectory::getSubDirs()
+{
+ return m_subDirs;
+}
+
inline const QString &VDirectory::getName() const
{
return m_name;
@@ -203,6 +217,11 @@ inline const QVector &VDirectory::getFiles() const
return m_files;
}
+inline QVector &VDirectory::getFiles()
+{
+ return m_files;
+}
+
inline QString VDirectory::getNotebookName() const
{
return m_notebook->getName();
diff --git a/src/vnotebook.cpp b/src/vnotebook.cpp
index 227defcc..11b5736e 100644
--- a/src/vnotebook.cpp
+++ b/src/vnotebook.cpp
@@ -457,3 +457,43 @@ void VNotebook::removeTag(const QString &p_tag)
}
}
}
+
+bool VNotebook::buildNotebook(const QString &p_name,
+ const QString &p_path,
+ const QString &p_imgFolder,
+ const QString &p_attachmentFolder,
+ QString *p_errMsg)
+{
+ VNotebook *nb = new VNotebook(p_name, p_path);
+ nb->setImageFolder(p_imgFolder);
+
+ QString attachmentFolder = p_attachmentFolder;
+ if (p_attachmentFolder.isEmpty()) {
+ nb->setAttachmentFolder(g_config->getAttachmentFolder());
+ } else {
+ nb->setAttachmentFolder(p_attachmentFolder);
+ }
+
+ // Process all the folders.
+ QVector &subdirs = nb->getRootDir()->getSubDirs();
+ QDir rootDir(p_path);
+ QFileInfoList dirList = rootDir.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot);
+ for (auto const & sub : dirList) {
+ VDirectory *dir = VDirectory::buildDirectory(sub.absoluteFilePath(),
+ nb->getRootDir(),
+ p_errMsg);
+ if (dir) {
+ subdirs.append(dir);
+ }
+ }
+
+ if (!nb->writeToConfig()) {
+ delete nb;
+ VUtils::addErrMsg(p_errMsg,
+ tr("Fail to write notebook configuration file."));
+ return false;
+ }
+
+ delete nb;
+ return true;
+}
diff --git a/src/vnotebook.h b/src/vnotebook.h
index 5d94d13e..891367bf 100644
--- a/src/vnotebook.h
+++ b/src/vnotebook.h
@@ -111,6 +111,14 @@ public:
QList collectFiles();
+ // Create configuration files recursively to build a notebook based on
+ // a external directory.
+ static bool buildNotebook(const QString &p_name,
+ const QString &p_path,
+ const QString &p_imgFolder,
+ const QString &p_attachmentFolder,
+ QString *p_errMsg = NULL);
+
private:
// Serialize current instance to json.
QJsonObject toConfigJson() const;
diff --git a/src/vnotebookselector.cpp b/src/vnotebookselector.cpp
index 24d6bcd8..c1f50d42 100644
--- a/src/vnotebookselector.cpp
+++ b/src/vnotebookselector.cpp
@@ -1,7 +1,6 @@
#include "vnotebookselector.h"
#include
#include
-#include
#include
#include
#include
@@ -10,6 +9,7 @@
#include
#include
#include
+
#include "vnotebook.h"
#include "vconfigmanager.h"
#include "dialog/vnewnotebookdialog.h"
@@ -119,46 +119,6 @@ int VNotebookSelector::itemIndexOfNotebook(const VNotebook *p_notebook) const
return -1;
}
-void VNotebookSelector::createConfigFiles(const QString &p_path)
-{
- QDir root(p_path);
- QStringList filters;
- filters << "*.md" << "*.markdown";
-
- QJsonObject dirJson;
- dirJson[DirConfig::c_version] = "1";
- dirJson[DirConfig::c_createdTime] = QDateTime::currentDateTime().toString(Qt::ISODate);
-
- QJsonArray subDirs;
- QJsonArray files;
-
- QFileInfoList dirInfoList = root.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
- QFileInfoList fileInfoList = root.entryInfoList(filters,QDir::Files);
-
- for(const QFileInfo &dirInfo : dirInfoList) {
- const QString dirname = dirInfo.fileName();
- if (dirname != "_v_recycle_bin") {
- QJsonObject item;
- item[DirConfig::c_name] = dirname;
- subDirs.append(item);
-
- createConfigFiles(dirInfo.absoluteFilePath());
- }
- }
-
- for(const QFileInfo &fileInfo : fileInfoList) {
- QJsonObject item;
- item[DirConfig::c_createdTime] = fileInfo.created().toString(Qt::ISODate);
- item[DirConfig::c_name] = fileInfo.fileName();
- files.append(item);
- }
-
- dirJson[DirConfig::c_subDirectories] = subDirs;
- dirJson[DirConfig::c_files] = files;
-
- g_config->writeDirectoryConfig(p_path,dirJson);
-}
-
void VNotebookSelector::insertAddNotebookItem()
{
QListWidgetItem *item = new QListWidgetItem();
@@ -230,6 +190,9 @@ bool VNotebookSelector::newNotebook()
info += "\n";
info += tr("* A previously created notebook could be imported into VNote "
"by choosing its root folder.");
+ info += "\n";
+ info += tr("* When a non-empty folder is chosen, VNote will create a notebook "
+ "based on the folders and files in it recursively.");
// Use empty default name and path to let the dialog to auto generate a name
// under the default VNote notebook folder.
@@ -240,18 +203,51 @@ bool VNotebookSelector::newNotebook()
m_notebooks,
this);
if (dialog.exec() == QDialog::Accepted) {
-
+ bool isImport = dialog.isImportExistingNotebook();
if(dialog.isImportExternalProject()) {
- createConfigFiles(dialog.getPathInput());
+ QString msg;
+ bool ret = VNotebook::buildNotebook(dialog.getNameInput(),
+ dialog.getPathInput(),
+ dialog.getImageFolder(),
+ dialog.getAttachmentFolder(),
+ &msg);
+
+ QList suffixes = g_config->getDocSuffixes()[(int)DocType::Markdown];
+ QString sufs;
+ for (auto const & suf : suffixes) {
+ if (sufs.isEmpty()) {
+ sufs = "*." + suf;
+ } else {
+ sufs += ",*." + suf;
+ }
+ }
+
+ QString info = ret ? tr("Successfully build notebook recursively (%1).").arg(sufs)
+ : tr("Fail to build notebook recursively.");
+ if (!ret || !msg.isEmpty()) {
+ VUtils::showMessage(ret ? QMessageBox::Information : QMessageBox::Warning,
+ ret ? tr("Information") : tr("Warning"),
+ info,
+ msg,
+ QMessageBox::Ok,
+ QMessageBox::Ok,
+ this);
+ }
+
+ if (!ret) {
+ return false;
+ }
+
+ isImport = true;
}
createNotebook(dialog.getNameInput(),
dialog.getPathInput(),
- dialog.isImportExistingNotebook(),
+ isImport,
dialog.getImageFolder(),
dialog.getAttachmentFolder());
- emit notebookCreated(dialog.getNameInput(), dialog.isImportExistingNotebook());
+ emit notebookCreated(dialog.getNameInput(), isImport);
return true;
}
diff --git a/src/vnotebookselector.h b/src/vnotebookselector.h
index 35605078..43985a2c 100644
--- a/src/vnotebookselector.h
+++ b/src/vnotebookselector.h
@@ -71,9 +71,6 @@ private:
// Return the item index of @p_notebook.
int itemIndexOfNotebook(const VNotebook *p_notebook) const;
- // Recursively create config files
- void createConfigFiles(const QString &p_path);
-
// If @p_import is true, we will use the existing config file.
// If @p_imageFolder is empty, we will use the global one.
// If @p_attachmentFolder is empty, we will use the global one.