From 7595b036394e7f3940340a16933de2b5540259da Mon Sep 17 00:00:00 2001 From: Le Tan Date: Mon, 1 Feb 2021 20:42:39 +0800 Subject: [PATCH] refactor Node interface (#1681) --- src/core/buffer/buffer.cpp | 8 +- src/core/buffer/buffer.h | 2 +- src/core/buffer/bufferprovider.h | 2 + src/core/buffer/filebufferprovider.cpp | 57 +-- src/core/buffer/filebufferprovider.h | 8 +- src/core/buffer/markdownbuffer.cpp | 4 +- src/core/buffer/nodebufferprovider.cpp | 53 ++- src/core/buffer/nodebufferprovider.h | 17 +- src/core/buffermgr.cpp | 9 +- src/core/core.pri | 4 + src/core/externalfile.cpp | 79 ++++ src/core/externalfile.h | 48 +++ src/core/file.cpp | 13 + src/core/file.h | 70 ++++ src/core/notebook/filenode.cpp | 135 ------- src/core/notebook/filenode.h | 60 --- src/core/notebook/foldernode.cpp | 65 ---- src/core/notebook/foldernode.h | 40 -- src/core/notebook/node.cpp | 346 ++++++++---------- src/core/notebook/node.h | 143 ++++---- src/core/notebook/notebook.cpp | 47 +-- src/core/notebook/notebook.h | 13 +- src/core/notebook/notebook.pri | 8 +- src/core/notebook/vxnode.cpp | 117 ++++++ src/core/notebook/vxnode.h | 45 +++ src/core/notebook/vxnodefile.cpp | 92 +++++ src/core/notebook/vxnodefile.h | 52 +++ .../notebookconfigmgr/inotebookconfigmgr.h | 17 +- .../nodecontentmediautils.cpp | 14 +- .../notebookconfigmgr/vxnotebookconfigmgr.cpp | 304 +++++++-------- .../notebookconfigmgr/vxnotebookconfigmgr.h | 26 +- src/utils/fileutils.cpp | 24 +- .../dialogs/folderpropertiesdialog.cpp | 2 +- src/widgets/dialogs/importfolderdialog.cpp | 2 +- src/widgets/dialogs/importfolderutils.cpp | 8 +- src/widgets/dialogs/newfolderdialog.cpp | 6 +- src/widgets/dialogs/newnotedialog.cpp | 6 +- src/widgets/dialogs/nodeinfowidget.cpp | 10 +- src/widgets/dialogs/nodeinfowidget.h | 4 +- src/widgets/dialogs/nodelabelwithupbutton.cpp | 2 +- src/widgets/dialogs/notepropertiesdialog.cpp | 2 +- src/widgets/markdownviewwindow.cpp | 2 +- src/widgets/notebookexplorer.cpp | 6 +- src/widgets/notebooknodeexplorer.cpp | 28 +- 44 files changed, 1073 insertions(+), 927 deletions(-) create mode 100644 src/core/externalfile.cpp create mode 100644 src/core/externalfile.h create mode 100644 src/core/file.cpp create mode 100644 src/core/file.h delete mode 100644 src/core/notebook/filenode.cpp delete mode 100644 src/core/notebook/filenode.h delete mode 100644 src/core/notebook/foldernode.cpp delete mode 100644 src/core/notebook/foldernode.h create mode 100644 src/core/notebook/vxnode.cpp create mode 100644 src/core/notebook/vxnode.h create mode 100644 src/core/notebook/vxnodefile.cpp create mode 100644 src/core/notebook/vxnodefile.h diff --git a/src/core/buffer/buffer.cpp b/src/core/buffer/buffer.cpp index ba4fe47a..819ec0b2 100644 --- a/src/core/buffer/buffer.cpp +++ b/src/core/buffer/buffer.cpp @@ -105,9 +105,9 @@ QString Buffer::getContentPath() const return m_provider->getContentPath(); } -QString Buffer::getContentBasePath() const +QString Buffer::getResourcePath() const { - return PathUtils::parentDirPath(getContentPath()); + return m_provider->getResourcePath(); } ID Buffer::getID() const @@ -337,7 +337,7 @@ void Buffer::writeBackupFile() { if (m_backupFilePath.isEmpty()) { const auto &config = ConfigMgr::getInst().getEditorConfig(); - QString backupDirPath(QDir(getContentBasePath()).filePath(config.getBackupFileDirectory())); + QString backupDirPath(QDir(getResourcePath()).filePath(config.getBackupFileDirectory())); backupDirPath = QDir::cleanPath(backupDirPath); auto backupFileName = FileUtils::generateFileNameWithSequence(backupDirPath, getName(), @@ -365,7 +365,7 @@ void Buffer::checkBackupFileOfPreviousSession() return; } - QString backupDirPath(QDir(getContentBasePath()).filePath(config.getBackupFileDirectory())); + QString backupDirPath(QDir(getResourcePath()).filePath(config.getBackupFileDirectory())); backupDirPath = QDir::cleanPath(backupDirPath); QDir backupDir(backupDirPath); QStringList backupFiles; diff --git a/src/core/buffer/buffer.h b/src/core/buffer/buffer.h index 3ef1a81a..a907e7b0 100644 --- a/src/core/buffer/buffer.h +++ b/src/core/buffer/buffer.h @@ -81,7 +81,7 @@ namespace vnotex QString getContentPath() const; // Get the base path to resolve resources. - QString getContentBasePath() const; + QString getResourcePath() const; ID getID() const; diff --git a/src/core/buffer/bufferprovider.h b/src/core/buffer/bufferprovider.h index b698b5a2..aec87060 100644 --- a/src/core/buffer/bufferprovider.h +++ b/src/core/buffer/bufferprovider.h @@ -34,6 +34,8 @@ namespace vnotex virtual QString getContentPath() const = 0; + virtual QString getResourcePath() const = 0; + virtual void write(const QString &p_content) = 0; virtual QString read() const = 0; diff --git a/src/core/buffer/filebufferprovider.cpp b/src/core/buffer/filebufferprovider.cpp index fda059a9..4be3e53f 100644 --- a/src/core/buffer/filebufferprovider.cpp +++ b/src/core/buffer/filebufferprovider.cpp @@ -5,15 +5,16 @@ #include #include #include +#include using namespace vnotex; -FileBufferProvider::FileBufferProvider(const QString &p_filePath, +FileBufferProvider::FileBufferProvider(const QSharedPointer &p_file, Node *p_nodeAttachedTo, bool p_readOnly, QObject *p_parent) : BufferProvider(p_parent), - c_filePath(p_filePath), + m_file(p_file), c_nodeAttachedTo(p_nodeAttachedTo), m_readOnly(p_readOnly) { @@ -32,42 +33,49 @@ bool FileBufferProvider::match(const Node *p_node) const bool FileBufferProvider::match(const QString &p_filePath) const { - return PathUtils::areSamePaths(c_filePath, p_filePath); + return PathUtils::areSamePaths(m_file->getFilePath(), p_filePath); } QString FileBufferProvider::getName() const { - return PathUtils::fileName(c_filePath); + return m_file->getName(); } QString FileBufferProvider::getPath() const { - return c_filePath; + return m_file->getFilePath(); } QString FileBufferProvider::getContentPath() const { - // TODO. - return getPath(); + return m_file->getContentPath(); +} + +QString FileBufferProvider::getResourcePath() const +{ + return m_file->getResourcePath(); } void FileBufferProvider::write(const QString &p_content) { - FileUtils::writeFile(getContentPath(), p_content); + m_file->write(p_content); m_lastModified = getLastModifiedFromFile(); } QString FileBufferProvider::read() const { const_cast(this)->m_lastModified = getLastModifiedFromFile(); - return FileUtils::readTextFile(getContentPath()); + return m_file->read(); } QString FileBufferProvider::fetchImageFolderPath() { - auto pa = PathUtils::concatenateFilePath(PathUtils::parentDirPath(getContentPath()), QStringLiteral("vx_images")); - QDir().mkpath(pa); - return pa; + auto file = m_file->getImageInterface(); + if (file) { + return file->fetchImageFolderPath(); + } else { + return QString(); + } } bool FileBufferProvider::isChildOf(const Node *p_node) const @@ -130,23 +138,30 @@ void FileBufferProvider::removeAttachment(const QStringList &p_paths) QString FileBufferProvider::insertImage(const QString &p_srcImagePath, const QString &p_imageFileName) { - const auto imageFolderPath = fetchImageFolderPath(); - auto destFilePath = FileUtils::renameIfExistsCaseInsensitive(PathUtils::concatenateFilePath(imageFolderPath, p_imageFileName)); - FileUtils::copyFile(p_srcImagePath, destFilePath); - return destFilePath; + auto file = m_file->getImageInterface(); + if (file) { + return file->insertImage(p_srcImagePath, p_imageFileName); + } else { + return QString(); + } } QString FileBufferProvider::insertImage(const QImage &p_image, const QString &p_imageFileName) { - const auto imageFolderPath = fetchImageFolderPath(); - auto destFilePath = FileUtils::renameIfExistsCaseInsensitive(PathUtils::concatenateFilePath(imageFolderPath, p_imageFileName)); - p_image.save(destFilePath); - return destFilePath; + auto file = m_file->getImageInterface(); + if (file) { + return file->insertImage(p_image, p_imageFileName); + } else { + return QString(); + } } void FileBufferProvider::removeImage(const QString &p_imagePath) { - FileUtils::removeFile(p_imagePath); + auto file = m_file->getImageInterface(); + if (file) { + file->removeImage(p_imagePath); + } } bool FileBufferProvider::isAttachmentSupported() const diff --git a/src/core/buffer/filebufferprovider.h b/src/core/buffer/filebufferprovider.h index 57a849cd..93dab3ef 100644 --- a/src/core/buffer/filebufferprovider.h +++ b/src/core/buffer/filebufferprovider.h @@ -5,12 +5,14 @@ namespace vnotex { + class File; + // Buffer provider based on external file. class FileBufferProvider : public BufferProvider { Q_OBJECT public: - FileBufferProvider(const QString &p_filePath, + FileBufferProvider(const QSharedPointer &m_file, Node *p_nodeAttachedTo, bool p_readOnly, QObject *p_parent = nullptr); @@ -27,6 +29,8 @@ namespace vnotex QString getContentPath() const Q_DECL_OVERRIDE; + QString getResourcePath() const Q_DECL_OVERRIDE; + void write(const QString &p_content) Q_DECL_OVERRIDE; QString read() const Q_DECL_OVERRIDE; @@ -62,7 +66,7 @@ namespace vnotex bool isReadOnly() const Q_DECL_OVERRIDE; private: - const QString c_filePath; + QSharedPointer m_file; Node *c_nodeAttachedTo = nullptr; diff --git a/src/core/buffer/markdownbuffer.cpp b/src/core/buffer/markdownbuffer.cpp index d029633e..409cd846 100644 --- a/src/core/buffer/markdownbuffer.cpp +++ b/src/core/buffer/markdownbuffer.cpp @@ -35,7 +35,7 @@ void MarkdownBuffer::fetchInitialImages() { Q_ASSERT(m_initialImages.isEmpty()); m_initialImages = vte::MarkdownUtils::fetchImagesFromMarkdownText(getContent(), - getContentBasePath(), + getResourcePath(), vte::MarkdownLink::TypeFlag::LocalRelativeInternal); } @@ -56,7 +56,7 @@ QSet MarkdownBuffer::clearObsoleteImages() const bool discarded = state() & StateFlag::Discarded; const auto latestImages = vte::MarkdownUtils::fetchImagesFromMarkdownText(!discarded ? getContent() : m_provider->read(), - getContentBasePath(), + getResourcePath(), vte::MarkdownLink::TypeFlag::LocalRelativeInternal); QSet latestImagesPath; for (const auto &link : latestImages) { diff --git a/src/core/buffer/nodebufferprovider.cpp b/src/core/buffer/nodebufferprovider.cpp index e83905df..b8614dd4 100644 --- a/src/core/buffer/nodebufferprovider.cpp +++ b/src/core/buffer/nodebufferprovider.cpp @@ -4,15 +4,16 @@ #include #include +#include using namespace vnotex; -NodeBufferProvider::NodeBufferProvider(Node *p_node, QObject *p_parent) +NodeBufferProvider::NodeBufferProvider(const QSharedPointer &p_node, QObject *p_parent) : BufferProvider(p_parent), m_node(p_node), - m_path(m_node->fetchAbsolutePath()), - m_contentPath(m_node->fetchContentPath()) + m_nodeFile(p_node->getContentFile()) { + Q_ASSERT(m_nodeFile); } Buffer::ProviderType NodeBufferProvider::getType() const @@ -22,7 +23,7 @@ Buffer::ProviderType NodeBufferProvider::getType() const bool NodeBufferProvider::match(const Node *p_node) const { - return m_node == p_node; + return m_node.data() == p_node; } bool NodeBufferProvider::match(const QString &p_filePath) const @@ -37,34 +38,45 @@ QString NodeBufferProvider::getName() const QString NodeBufferProvider::getPath() const { - return m_path; + return m_nodeFile->getFilePath(); } QString NodeBufferProvider::getContentPath() const { - return m_contentPath; + return m_nodeFile->getContentPath(); +} + +QString NodeBufferProvider::getResourcePath() const +{ + return m_nodeFile->getResourcePath(); } void NodeBufferProvider::write(const QString &p_content) { - m_node->write(p_content); + m_nodeFile->write(p_content); m_lastModified = getLastModifiedFromFile(); } QString NodeBufferProvider::read() const { const_cast(this)->m_lastModified = getLastModifiedFromFile(); - return m_node->read(); + return m_nodeFile->read(); } QString NodeBufferProvider::fetchImageFolderPath() { - return m_node->fetchImageFolderPath(); + auto file = m_nodeFile->getImageInterface(); + if (file) { + return file->fetchImageFolderPath(); + } else { + Q_ASSERT(false); + return getContentPath(); + } } bool NodeBufferProvider::isChildOf(const Node *p_node) const { - return Node::isAncestor(p_node, m_node); + return Node::isAncestor(p_node, m_node.data()); } QString NodeBufferProvider::getAttachmentFolder() const @@ -104,17 +116,30 @@ void NodeBufferProvider::removeAttachment(const QStringList &p_paths) QString NodeBufferProvider::insertImage(const QString &p_srcImagePath, const QString &p_imageFileName) { - return m_node->insertImage(p_srcImagePath, p_imageFileName); + auto file = m_nodeFile->getImageInterface(); + if (file) { + return file->insertImage(p_srcImagePath, p_imageFileName); + } else { + return QString(); + } } QString NodeBufferProvider::insertImage(const QImage &p_image, const QString &p_imageFileName) { - return m_node->insertImage(p_image, p_imageFileName); + auto file = m_nodeFile->getImageInterface(); + if (file) { + return file->insertImage(p_image, p_imageFileName); + } else { + return QString(); + } } void NodeBufferProvider::removeImage(const QString &p_imagePath) { - m_node->removeImage(p_imagePath); + auto file = m_nodeFile->getImageInterface(); + if (file) { + file->removeImage(p_imagePath); + } } bool NodeBufferProvider::isAttachmentSupported() const @@ -124,7 +149,7 @@ bool NodeBufferProvider::isAttachmentSupported() const Node *NodeBufferProvider::getNode() const { - return m_node; + return m_node.data(); } bool NodeBufferProvider::isReadOnly() const diff --git a/src/core/buffer/nodebufferprovider.h b/src/core/buffer/nodebufferprovider.h index ba420661..69c95e75 100644 --- a/src/core/buffer/nodebufferprovider.h +++ b/src/core/buffer/nodebufferprovider.h @@ -1,16 +1,21 @@ #ifndef NODEBUFFERPROVIDER_H #define NODEBUFFERPROVIDER_H +#include + #include "bufferprovider.h" namespace vnotex { + class File; + class IFileWithImage; + // Buffer provider based on an internal node. class NodeBufferProvider : public BufferProvider { Q_OBJECT public: - NodeBufferProvider(Node *p_node, QObject *p_parent = nullptr); + NodeBufferProvider(const QSharedPointer &p_node, QObject *p_parent = nullptr); Buffer::ProviderType getType() const Q_DECL_OVERRIDE; @@ -24,6 +29,8 @@ namespace vnotex QString getContentPath() const Q_DECL_OVERRIDE; + QString getResourcePath() const Q_DECL_OVERRIDE; + void write(const QString &p_content) Q_DECL_OVERRIDE; QString read() const Q_DECL_OVERRIDE; @@ -59,13 +66,9 @@ namespace vnotex bool isReadOnly() const Q_DECL_OVERRIDE; private: - Node *m_node = nullptr; + QSharedPointer m_node; - // Used as cache. - QString m_path; - - // Used as cache. - QString m_contentPath; + QSharedPointer m_nodeFile; }; } diff --git a/src/core/buffermgr.cpp b/src/core/buffermgr.cpp index 48ac861a..6e33b6d5 100644 --- a/src/core/buffermgr.cpp +++ b/src/core/buffermgr.cpp @@ -13,6 +13,7 @@ #include #include "notebookmgr.h" #include "vnotex.h" +#include "externalfile.h" #include "fileopenparameters.h" @@ -54,7 +55,7 @@ void BufferMgr::open(Node *p_node, const QSharedPointer &p_p return; } - if (p_node->getType() == Node::Type::Folder) { + if (p_node->isContainer()) { return; } @@ -71,7 +72,7 @@ void BufferMgr::open(Node *p_node, const QSharedPointer &p_p } BufferParameters paras; - paras.m_provider.reset(new NodeBufferProvider(p_node)); + paras.m_provider.reset(new NodeBufferProvider(p_node->sharedFromThis())); buffer = factory->createBuffer(paras, this); addBuffer(buffer); } @@ -95,7 +96,7 @@ void BufferMgr::open(const QString &p_filePath, const QSharedPointergetType() == Node::File) { + if (node->hasContent()) { open(node.data(), p_paras); return; } else { @@ -123,7 +124,7 @@ void BufferMgr::open(const QString &p_filePath, const QSharedPointer::create(p_filePath), p_paras->m_nodeAttachedTo, p_paras->m_readOnly)); buffer = factory->createBuffer(paras, this); diff --git a/src/core/core.pri b/src/core/core.pri index eeb2256d..d5a9ef69 100644 --- a/src/core/core.pri +++ b/src/core/core.pri @@ -15,6 +15,8 @@ SOURCES += \ $$PWD/configmgr.cpp \ $$PWD/coreconfig.cpp \ $$PWD/editorconfig.cpp \ + $$PWD/externalfile.cpp \ + $$PWD/file.cpp \ $$PWD/htmltemplatehelper.cpp \ $$PWD/logger.cpp \ $$PWD/mainconfig.cpp \ @@ -36,6 +38,8 @@ HEADERS += \ $$PWD/coreconfig.h \ $$PWD/editorconfig.h \ $$PWD/events.h \ + $$PWD/externalfile.h \ + $$PWD/file.h \ $$PWD/filelocator.h \ $$PWD/fileopenparameters.h \ $$PWD/htmltemplatehelper.h \ diff --git a/src/core/externalfile.cpp b/src/core/externalfile.cpp new file mode 100644 index 00000000..17f395be --- /dev/null +++ b/src/core/externalfile.cpp @@ -0,0 +1,79 @@ +#include "externalfile.h" + +#include +#include + +using namespace vnotex; + +ExternalFile::ExternalFile(const QString &p_filePath) + : c_filePath(p_filePath) +{ +} + +QString ExternalFile::read() const +{ + return FileUtils::readTextFile(getContentPath()); +} + +void ExternalFile::write(const QString &p_content) +{ + FileUtils::writeFile(getContentPath(), p_content); +} + +QString ExternalFile::getName() const +{ + return PathUtils::fileName(c_filePath); +} + +QString ExternalFile::getFilePath() const +{ + return c_filePath; +} + +QString ExternalFile::getContentPath() const +{ + return c_filePath; +} + +QString ExternalFile::getResourcePath() const +{ + return PathUtils::parentDirPath(getContentPath()); +} + +IFileWithImage *ExternalFile::getImageInterface() +{ + return this; +} + +Node *ExternalFile::getNode() const +{ + return nullptr; +} + +QString ExternalFile::fetchImageFolderPath() +{ + auto pa = PathUtils::concatenateFilePath(getResourcePath(), QStringLiteral("vx_images")); + QDir().mkpath(pa); + return pa; +} + +QString ExternalFile::insertImage(const QString &p_srcImagePath, const QString &p_imageFileName) +{ + const auto imageFolderPath = fetchImageFolderPath(); + auto destFilePath = FileUtils::renameIfExistsCaseInsensitive(PathUtils::concatenateFilePath(imageFolderPath, p_imageFileName)); + FileUtils::copyFile(p_srcImagePath, destFilePath); + return destFilePath; +} + +QString ExternalFile::insertImage(const QImage &p_image, const QString &p_imageFileName) +{ + const auto imageFolderPath = fetchImageFolderPath(); + auto destFilePath = FileUtils::renameIfExistsCaseInsensitive(PathUtils::concatenateFilePath(imageFolderPath, p_imageFileName)); + p_image.save(destFilePath); + return destFilePath; +} + +void ExternalFile::removeImage(const QString &p_imagePath) +{ + FileUtils::removeFile(p_imagePath); +} diff --git a/src/core/externalfile.h b/src/core/externalfile.h new file mode 100644 index 00000000..ddafc955 --- /dev/null +++ b/src/core/externalfile.h @@ -0,0 +1,48 @@ +#ifndef EXTERNALFILE_H +#define EXTERNALFILE_H + +#include "file.h" + +namespace vnotex +{ + class ExternalFile : public File, public IFileWithImage + { + public: + explicit ExternalFile(const QString &p_filePath); + + QString read() const Q_DECL_OVERRIDE; + + void write(const QString &p_content) Q_DECL_OVERRIDE; + + QString getName() const Q_DECL_OVERRIDE; + + QString getFilePath() const Q_DECL_OVERRIDE; + + QString getContentPath() const Q_DECL_OVERRIDE; + + // Path to resolve resources. + QString getResourcePath() const Q_DECL_OVERRIDE; + + IFileWithImage *getImageInterface() Q_DECL_OVERRIDE; + + // Get the corresponding node if available. + Node *getNode() const Q_DECL_OVERRIDE; + + // IFileWithImage interfaces. + public: + QString fetchImageFolderPath() Q_DECL_OVERRIDE; + + // Insert image from @p_srcImagePath. + // Return inserted image file path. + QString insertImage(const QString &p_srcImagePath, const QString &p_imageFileName) Q_DECL_OVERRIDE; + + QString insertImage(const QImage &p_image, const QString &p_imageFileName) Q_DECL_OVERRIDE; + + void removeImage(const QString &p_imagePath) Q_DECL_OVERRIDE; + + private: + QString c_filePath; + }; +} + +#endif // EXTERNALFILE_H diff --git a/src/core/file.cpp b/src/core/file.cpp new file mode 100644 index 00000000..9127d942 --- /dev/null +++ b/src/core/file.cpp @@ -0,0 +1,13 @@ +#include "file.h" + +using namespace vnotex; + +const FileType &File::getContentType() const +{ + return FileTypeHelper::getInst().getFileType(m_contentType); +} + +void File::setContentType(FileTypeHelper::Type p_type) +{ + m_contentType = p_type; +} diff --git a/src/core/file.h b/src/core/file.h new file mode 100644 index 00000000..6498a899 --- /dev/null +++ b/src/core/file.h @@ -0,0 +1,70 @@ +#ifndef FILE_H +#define FILE_H + +#include + +#include + +class QImage; + +namespace vnotex +{ + class Node; + + class IFileWithImage + { + public: + IFileWithImage() = default; + + virtual ~IFileWithImage() = default; + + virtual QString fetchImageFolderPath() = 0; + + // Insert image from @p_srcImagePath. + // Return inserted image file path. + virtual QString insertImage(const QString &p_srcImagePath, const QString &p_imageFileName) = 0; + + virtual QString insertImage(const QImage &p_image, const QString &p_imageFileName) = 0; + + virtual void removeImage(const QString &p_imagePath) = 0; + }; + + // Abstract file interface. + class File + { + public: + File() = default; + + virtual ~File() = default; + + virtual QString read() const = 0; + + virtual void write(const QString &p_content) = 0; + + virtual QString getName() const = 0; + + virtual QString getFilePath() const = 0; + + // The main content file of File. + // In bundle case, getFilePath() may point to a folder, getContentPath() points to the real content file. + virtual QString getContentPath() const = 0; + + // Path to resolve resources. + virtual QString getResourcePath() const = 0; + + virtual IFileWithImage *getImageInterface() = 0; + + // Get the corresponding node if available. + virtual Node *getNode() const = 0; + + const FileType &getContentType() const; + + protected: + void setContentType(FileTypeHelper::Type p_type); + + private: + FileTypeHelper::Type m_contentType = FileTypeHelper::Others; + }; +} + +#endif // FILE_H diff --git a/src/core/notebook/filenode.cpp b/src/core/notebook/filenode.cpp deleted file mode 100644 index d4644c0b..00000000 --- a/src/core/notebook/filenode.cpp +++ /dev/null @@ -1,135 +0,0 @@ -#include "filenode.h" - -#include -#include -#include -#include -#include "notebook.h" - -using namespace vnotex; - -FileNode::FileNode(ID p_id, - const QString &p_name, - const QDateTime &p_createdTimeUtc, - const QDateTime &p_modifiedTimeUtc, - const QString &p_attachmentFolder, - const QStringList &p_tags, - Notebook *p_notebook, - Node *p_parent) - : Node(Node::Type::File, - p_id, - p_name, - p_createdTimeUtc, - p_notebook, - p_parent), - m_modifiedTimeUtc(p_modifiedTimeUtc), - m_attachmentFolder(p_attachmentFolder), - m_tags(p_tags) -{ -} - -QVector> FileNode::getChildren() const -{ - return QVector>(); -} - -int FileNode::getChildrenCount() const -{ - return 0; -} - -void FileNode::addChild(const QSharedPointer &p_node) -{ - Q_ASSERT(false); - Q_UNUSED(p_node); -} - -void FileNode::insertChild(int p_idx, const QSharedPointer &p_node) -{ - Q_ASSERT(false); - Q_UNUSED(p_idx); - Q_UNUSED(p_node); -} - -void FileNode::removeChild(const QSharedPointer &p_child) -{ - Q_ASSERT(false); - Q_UNUSED(p_child); -} - -QDateTime FileNode::getModifiedTimeUtc() const -{ - return m_modifiedTimeUtc; -} - -void FileNode::setModifiedTimeUtc() -{ - m_modifiedTimeUtc = QDateTime::currentDateTimeUtc(); -} - -QString FileNode::getAttachmentFolder() const -{ - return m_attachmentFolder; -} - -void FileNode::setAttachmentFolder(const QString &p_folder) -{ - m_attachmentFolder = p_folder; -} - -QStringList FileNode::addAttachment(const QString &p_destFolderPath, const QStringList &p_files) -{ - QStringList addedFiles; - for (const auto &file : p_files) { - if (PathUtils::isDir(file)) { - qWarning() << "skip adding folder as attachment" << file; - continue; - } - - auto destFilePath = m_backend->renameIfExistsCaseInsensitive( - PathUtils::concatenateFilePath(p_destFolderPath, PathUtils::fileName(file))); - m_backend->copyFile(file, destFilePath); - addedFiles << destFilePath; - } - - return addedFiles; -} - -QString FileNode::newAttachmentFile(const QString &p_destFolderPath, const QString &p_name) -{ - auto destFilePath = m_backend->renameIfExistsCaseInsensitive( - PathUtils::concatenateFilePath(p_destFolderPath, p_name)); - m_backend->writeFile(destFilePath, QByteArray()); - return destFilePath; -} - -QString FileNode::newAttachmentFolder(const QString &p_destFolderPath, const QString &p_name) -{ - auto destFilePath = m_backend->renameIfExistsCaseInsensitive( - PathUtils::concatenateFilePath(p_destFolderPath, p_name)); - m_backend->makePath(destFilePath); - return destFilePath; -} - -QString FileNode::renameAttachment(const QString &p_path, const QString &p_name) -{ - m_backend->renameFile(p_path, p_name); - return p_name; -} - -void FileNode::removeAttachment(const QStringList &p_paths) -{ - // Just move it to recycle bin but not added as a child node of recycle bin. - for (const auto &pa : p_paths) { - if (QFileInfo(pa).isDir()) { - m_notebook->moveDirToRecycleBin(pa); - } else { - m_notebook->moveFileToRecycleBin(pa); - } - } -} - -QStringList FileNode::getTags() const -{ - return m_tags; -} diff --git a/src/core/notebook/filenode.h b/src/core/notebook/filenode.h deleted file mode 100644 index 2bce7bc2..00000000 --- a/src/core/notebook/filenode.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef FILENODE_H -#define FILENODE_H - -#include "node.h" - -namespace vnotex -{ - // File node of notebook. - class FileNode : public Node - { - public: - FileNode(ID p_id, - const QString &p_name, - const QDateTime &p_createdTimeUtc, - const QDateTime &p_modifiedTimeUtc, - const QString &p_attachmentFolder, - const QStringList &p_tags, - Notebook *p_notebook, - Node *p_parent = nullptr); - - QVector> getChildren() const Q_DECL_OVERRIDE; - - int getChildrenCount() const Q_DECL_OVERRIDE; - - void addChild(const QSharedPointer &p_node) Q_DECL_OVERRIDE; - - void insertChild(int p_idx, const QSharedPointer &p_node) Q_DECL_OVERRIDE; - - void removeChild(const QSharedPointer &p_child) Q_DECL_OVERRIDE; - - QDateTime getModifiedTimeUtc() const Q_DECL_OVERRIDE; - - void setModifiedTimeUtc() Q_DECL_OVERRIDE; - - QString getAttachmentFolder() const Q_DECL_OVERRIDE; - - void setAttachmentFolder(const QString &p_folder) Q_DECL_OVERRIDE; - - QStringList addAttachment(const QString &p_destFolderPath, const QStringList &p_files) Q_DECL_OVERRIDE; - - QString newAttachmentFile(const QString &p_destFolderPath, const QString &p_name) Q_DECL_OVERRIDE; - - QString newAttachmentFolder(const QString &p_destFolderPath, const QString &p_name) Q_DECL_OVERRIDE; - - QString renameAttachment(const QString &p_path, const QString &p_name) Q_DECL_OVERRIDE; - - void removeAttachment(const QStringList &p_paths) Q_DECL_OVERRIDE; - - QStringList getTags() const Q_DECL_OVERRIDE; - - private: - QDateTime m_modifiedTimeUtc; - - QString m_attachmentFolder; - - QStringList m_tags; - }; -} - -#endif // FILENODE_H diff --git a/src/core/notebook/foldernode.cpp b/src/core/notebook/foldernode.cpp deleted file mode 100644 index f20f5c2c..00000000 --- a/src/core/notebook/foldernode.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "foldernode.h" - -using namespace vnotex; - -FolderNode::FolderNode(const QString &p_name, - Notebook *p_notebook, - Node *p_parent) - : Node(Node::Type::Folder, - p_name, - p_notebook, - p_parent) -{ -} - -void FolderNode::loadFolder(ID p_id, - const QDateTime &p_createdTimeUtc, - const QVector> &p_children) -{ - Node::loadInfo(p_id, p_createdTimeUtc); - m_children = p_children; -} - -QVector> FolderNode::getChildren() const -{ - return m_children; -} - -int FolderNode::getChildrenCount() const -{ - return m_children.size(); -} - -void FolderNode::addChild(const QSharedPointer &p_node) -{ - insertChild(m_children.size(), p_node); -} - -void FolderNode::insertChild(int p_idx, const QSharedPointer &p_node) -{ - p_node->setParent(this); - - m_children.insert(p_idx, p_node); -} - -void FolderNode::removeChild(const QSharedPointer &p_child) -{ - if (m_children.removeOne(p_child)) { - p_child->setParent(nullptr); - } -} - -QDateTime FolderNode::getModifiedTimeUtc() const -{ - return getCreatedTimeUtc(); -} - -void FolderNode::setModifiedTimeUtc() -{ - Q_ASSERT(false); -} - -QDir FolderNode::toDir() const -{ - return QDir(fetchAbsolutePath()); -} diff --git a/src/core/notebook/foldernode.h b/src/core/notebook/foldernode.h deleted file mode 100644 index 5a0c5e7e..00000000 --- a/src/core/notebook/foldernode.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef FOLDERNODE_H -#define FOLDERNODE_H - -#include "node.h" - -namespace vnotex -{ - class FolderNode : public Node - { - public: - FolderNode(const QString &p_name, - Notebook *p_notebook, - Node *p_parent = nullptr); - - void loadFolder(ID p_id, - const QDateTime &p_createdTimeUtc, - const QVector> &p_children); - - QVector> getChildren() const Q_DECL_OVERRIDE; - - int getChildrenCount() const Q_DECL_OVERRIDE; - - void addChild(const QSharedPointer &p_node) Q_DECL_OVERRIDE; - - void insertChild(int p_idx, const QSharedPointer &p_node) Q_DECL_OVERRIDE; - - void removeChild(const QSharedPointer &p_child) Q_DECL_OVERRIDE; - - QDateTime getModifiedTimeUtc() const Q_DECL_OVERRIDE; - - void setModifiedTimeUtc() Q_DECL_OVERRIDE; - - QDir toDir() const Q_DECL_OVERRIDE; - - private: - QVector> m_children; - }; -} // ns vnotex - -#endif // FOLDERNODE_H diff --git a/src/core/notebook/node.cpp b/src/core/notebook/node.cpp index 97f5a2ad..610ca2f2 100644 --- a/src/core/notebook/node.cpp +++ b/src/core/notebook/node.cpp @@ -10,39 +10,39 @@ using namespace vnotex; -Node::Node(Type p_type, +Node::Node(Flags p_flags, ID p_id, const QString &p_name, const QDateTime &p_createdTimeUtc, + const QDateTime &p_modifiedTimeUtc, + const QStringList &p_tags, + const QString &p_attachmentFolder, Notebook *p_notebook, Node *p_parent) : m_notebook(p_notebook), - m_type(p_type), + m_loaded(true), + m_flags(p_flags), m_id(p_id), m_name(p_name), m_createdTimeUtc(p_createdTimeUtc), - m_loaded(true), + m_modifiedTimeUtc(p_modifiedTimeUtc), + m_tags(p_tags), + m_attachmentFolder(p_attachmentFolder), m_parent(p_parent) { - if (m_notebook) { - m_configMgr = m_notebook->getConfigMgr(); - m_backend = m_notebook->getBackend(); - } + Q_ASSERT(m_notebook); } -Node::Node(Type p_type, +Node::Node(Flags p_flags, const QString &p_name, Notebook *p_notebook, Node *p_parent) : m_notebook(p_notebook), - m_type(p_type), + m_flags(p_flags), m_name(p_name), m_parent(p_parent) { - if (m_notebook) { - m_configMgr = m_notebook->getConfigMgr(); - m_backend = m_notebook->getBackend(); - } + Q_ASSERT(m_notebook); } Node::~Node() @@ -54,23 +54,24 @@ bool Node::isLoaded() const return m_loaded; } -void Node::setLoaded(bool p_loaded) -{ - m_loaded = p_loaded; -} - -void Node::loadInfo(ID p_id, const QDateTime &p_createdTimeUtc) +void Node::loadCompleteInfo(ID p_id, + const QDateTime &p_createdTimeUtc, + const QDateTime &p_modifiedTimeUtc, + const QStringList &p_tags, + const QVector> &p_children) { Q_ASSERT(!m_loaded); - m_id = p_id; m_createdTimeUtc = p_createdTimeUtc; + m_modifiedTimeUtc = p_modifiedTimeUtc; + m_tags = p_tags; + m_children = p_children; m_loaded = true; } bool Node::isRoot() const { - return !m_parent; + return !m_parent && m_use == Use::Root; } const QString &Node::getName() const @@ -78,12 +79,29 @@ const QString &Node::getName() const return m_name; } -bool Node::hasChild(const QString &p_name, bool p_caseSensitive) const +void Node::setName(const QString &p_name) +{ + m_name = p_name; +} + +void Node::updateName(const QString &p_name) +{ + if (m_name == p_name) { + return; + } + + getConfigMgr()->renameNode(this, p_name); + Q_ASSERT(m_name == p_name); + + emit m_notebook->nodeUpdated(this); +} + +bool Node::containsChild(const QString &p_name, bool p_caseSensitive) const { return findChild(p_name, p_caseSensitive) != nullptr; } -bool Node::hasChild(const QSharedPointer &p_node) const +bool Node::containsChild(const QSharedPointer &p_node) const { return getChildren().indexOf(p_node) != -1; } @@ -111,21 +129,11 @@ Node *Node::getParent() const return m_parent; } -Node::Type Node::getType() const -{ - return m_type; -} - Node::Flags Node::getFlags() const { return m_flags; } -void Node::setFlags(Node::Flags p_flags) -{ - m_flags = p_flags; -} - Node::Use Node::getUse() const { return m_use; @@ -146,58 +154,52 @@ const QDateTime &Node::getCreatedTimeUtc() const return m_createdTimeUtc; } +const QDateTime &Node::getModifiedTimeUtc() const +{ + return m_modifiedTimeUtc; +} + +void Node::setModifiedTimeUtc() +{ + m_modifiedTimeUtc = QDateTime::currentDateTimeUtc(); +} + +const QVector> &Node::getChildren() const +{ + return m_children; +} + +int Node::getChildrenCount() const +{ + return m_children.size(); +} + +void Node::addChild(const QSharedPointer &p_node) +{ + insertChild(m_children.size(), p_node); +} + +void Node::insertChild(int p_idx, const QSharedPointer &p_node) +{ + Q_ASSERT(isContainer()); + + p_node->setParent(this); + + m_children.insert(p_idx, p_node); +} + +void Node::removeChild(const QSharedPointer &p_child) +{ + if (m_children.removeOne(p_child)) { + p_child->setParent(nullptr); + } +} + Notebook *Node::getNotebook() const { return m_notebook; } -QString Node::fetchRelativePath() const -{ - if (!m_parent) { - return QString(); - } else { - return PathUtils::concatenateFilePath(m_parent->fetchRelativePath(), m_name); - } -} - -QString Node::fetchAbsolutePath() const -{ - return PathUtils::concatenateFilePath(m_notebook->getRootFolderAbsolutePath(), - fetchRelativePath()); -} - -QString Node::fetchContentPath() const -{ - return fetchAbsolutePath(); -} - -void Node::load() -{ - Q_ASSERT(m_notebook); - m_notebook->load(this); -} - -void Node::save() -{ - Q_ASSERT(m_notebook); - m_notebook->save(this); -} - -void Node::setName(const QString &p_name) -{ - m_name = p_name; -} - -void Node::updateName(const QString &p_name) -{ - if (m_name == p_name) { - return; - } - - m_notebook->rename(this, p_name); - Q_ASSERT(m_name == p_name); -} - bool Node::isAncestor(const Node *p_ancestor, const Node *p_child) { if (!p_ancestor || !p_child) { @@ -214,122 +216,82 @@ bool Node::isAncestor(const Node *p_ancestor, const Node *p_child) return false; } -bool Node::existsOnDisk() const +const QStringList &Node::getTags() const { - return m_configMgr->nodeExistsOnDisk(this); -} - -QString Node::read() const -{ - return m_configMgr->readNode(this); -} - -void Node::write(const QString &p_content) -{ - m_configMgr->writeNode(this, p_content); -} - -QString Node::fetchImageFolderPath() -{ - return m_configMgr->fetchNodeImageFolderPath(this); -} - -QString Node::insertImage(const QString &p_srcImagePath, const QString &p_imageFileName) -{ - const auto imageFolderPath = fetchImageFolderPath(); - auto destFilePath = m_backend->renameIfExistsCaseInsensitive(PathUtils::concatenateFilePath(imageFolderPath, p_imageFileName)); - m_backend->copyFile(p_srcImagePath, destFilePath); - return destFilePath; -} - -QString Node::insertImage(const QImage &p_image, const QString &p_imageFileName) -{ - const auto imageFolderPath = fetchImageFolderPath(); - auto destFilePath = m_backend->renameIfExistsCaseInsensitive(PathUtils::concatenateFilePath(imageFolderPath, p_imageFileName)); - p_image.save(destFilePath); - m_backend->addFile(destFilePath); - return destFilePath; -} - -void Node::removeImage(const QString &p_imagePath) -{ - // Just move it to recycle bin but not added as a child node of recycle bin. - m_notebook->moveFileToRecycleBin(p_imagePath); -} - -QString Node::getAttachmentFolder() const -{ - Q_ASSERT(false); - return QString(); -} - -void Node::setAttachmentFolder(const QString &p_folder) -{ - Q_UNUSED(p_folder); - Q_ASSERT(false); -} - -QString Node::fetchAttachmentFolderPath() -{ - return m_configMgr->fetchNodeAttachmentFolderPath(this); -} - -QStringList Node::addAttachment(const QString &p_destFolderPath, const QStringList &p_files) -{ - Q_UNUSED(p_destFolderPath); - Q_UNUSED(p_files); - Q_ASSERT(false); - return QStringList(); -} - -QString Node::newAttachmentFile(const QString &p_destFolderPath, const QString &p_name) -{ - Q_UNUSED(p_destFolderPath); - Q_UNUSED(p_name); - Q_ASSERT(false); - return QString(); -} - -QString Node::newAttachmentFolder(const QString &p_destFolderPath, const QString &p_name) -{ - Q_UNUSED(p_destFolderPath); - Q_UNUSED(p_name); - Q_ASSERT(false); - return QString(); -} - -QString Node::renameAttachment(const QString &p_path, const QString &p_name) -{ - Q_UNUSED(p_path); - Q_UNUSED(p_name); - Q_ASSERT(false); - return QString(); -} - -void Node::removeAttachment(const QStringList &p_paths) -{ - Q_UNUSED(p_paths); - Q_ASSERT(false); -} - -QStringList Node::getTags() const -{ - Q_ASSERT(false); - return QStringList(); -} - -QDir Node::toDir() const -{ - Q_ASSERT(false); - return QDir(); -} - -INotebookBackend *Node::getBackend() const -{ - return m_backend.data(); + return m_tags; } bool Node::isReadOnly() const { return m_flags & Flag::ReadOnly; } + +void Node::setReadOnly(bool p_readOnly) +{ + if (p_readOnly) { + m_flags |= Flag::ReadOnly; + } else { + m_flags &= ~Flag::ReadOnly; + } +} + +QString Node::fetchPath() const +{ + if (!m_parent) { + return QString(); + } else { + return PathUtils::concatenateFilePath(m_parent->fetchPath(), m_name); + } +} + +bool Node::isContainer() const +{ + return m_flags & Flag::Container; +} + +bool Node::hasContent() const +{ + return m_flags & Flag::Content; +} + +QDir Node::toDir() const +{ + if (isContainer()) { + return QDir(fetchAbsolutePath()); + } +} + +void Node::load() +{ + getConfigMgr()->loadNode(this); +} + +void Node::save() +{ + getConfigMgr()->saveNode(this); +} + +INotebookConfigMgr *Node::getConfigMgr() const +{ + return m_notebook->getConfigMgr().data(); +} + +const QString &Node::getAttachmentFolder() const +{ + return m_attachmentFolder; +} + +void Node::setAttachmentFolder(const QString &p_attachmentFolder) +{ + m_attachmentFolder = p_attachmentFolder; +} + +QString Node::fetchAttachmentFolderPath() +{ + return getConfigMgr()->fetchNodeAttachmentFolderPath(this); +} + +INotebookBackend *Node::getBackend() const +{ + return m_notebook->getBackend().data(); +} diff --git a/src/core/notebook/node.h b/src/core/notebook/node.h index f6cf2395..70fb5283 100644 --- a/src/core/notebook/node.h +++ b/src/core/notebook/node.h @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -13,6 +14,7 @@ namespace vnotex class Notebook; class INotebookConfigMgr; class INotebookBackend; + class File; // Used when add/new a node. struct NodeParameters @@ -24,43 +26,46 @@ namespace vnotex }; // Node of notebook. - class Node + class Node : public QEnableSharedFromThis { public: - enum Type { - Folder, - File - }; - enum Flag { None = 0, - ReadOnly = 0x1 + // A node with content. + Content = 0x1, + // A node with children. + Container = 0x2, + ReadOnly = 0x4 }; Q_DECLARE_FLAGS(Flags, Flag) enum Use { Normal, - RecycleBin + RecycleBin, + Root }; + enum { InvalidId = 0 }; + // Constructor with all information loaded. - Node(Type p_type, + Node(Flags p_flags, ID p_id, const QString &p_name, const QDateTime &p_createdTimeUtc, + const QDateTime &p_modifiedTimeUtc, + const QStringList &p_tags, + const QString &p_attachmentFolder, Notebook *p_notebook, - Node *p_parent = nullptr); + Node *p_parent); // Constructor not loaded. - Node(Type p_type, + Node(Flags p_flags, const QString &p_name, Notebook *p_notebook, - Node *p_parent = nullptr); + Node *p_parent); virtual ~Node(); - enum { InvalidId = 0 }; - bool isLoaded() const; bool isRoot() const; @@ -68,13 +73,20 @@ namespace vnotex const QString &getName() const; void setName(const QString &p_name); - // Change the config and backend file as well. void updateName(const QString &p_name); - Node::Type getType() const; + // Fetch path of this node within notebook. + // This may not be the same as the actual file path. It depends on the config mgr. + virtual QString fetchPath() const; + + // Fetch absolute file path if available. + virtual QString fetchAbsolutePath() const = 0; + + bool isContainer() const; + + bool hasContent() const; Node::Flags getFlags() const; - void setFlags(Node::Flags p_flags); Node::Use getUse() const; void setUse(Node::Use p_use); @@ -83,97 +95,74 @@ namespace vnotex const QDateTime &getCreatedTimeUtc() const; - virtual QDateTime getModifiedTimeUtc() const = 0; - virtual void setModifiedTimeUtc() = 0; + const QDateTime &getModifiedTimeUtc() const; + void setModifiedTimeUtc(); - virtual QString getAttachmentFolder() const; - virtual void setAttachmentFolder(const QString &p_folder); - - virtual QVector> getChildren() const = 0; - - virtual int getChildrenCount() const = 0; + const QVector> &getChildren() const; + int getChildrenCount() const; QSharedPointer findChild(const QString &p_name, bool p_caseSensitive = true) const; - bool hasChild(const QString &p_name, bool p_caseSensitive = true) const; + bool containsChild(const QString &p_name, bool p_caseSensitive = true) const; - bool hasChild(const QSharedPointer &p_node) const; + bool containsChild(const QSharedPointer &p_node) const; - virtual void addChild(const QSharedPointer &p_node) = 0; + void addChild(const QSharedPointer &p_node); - virtual void insertChild(int p_idx, const QSharedPointer &p_node) = 0; + void insertChild(int p_idx, const QSharedPointer &p_node); - virtual void removeChild(const QSharedPointer &p_node) = 0; + void removeChild(const QSharedPointer &p_node); void setParent(Node *p_parent); Node *getParent() const; Notebook *getNotebook() const; - // Path to the node. - QString fetchRelativePath() const; + void load(); + void save(); - QString fetchAbsolutePath() const; + const QStringList &getTags() const; - // A node may be a container of all the stuffs, so the node's path may not be identical with - // the content file path, like TextBundle. - virtual QString fetchContentPath() const; + const QString &getAttachmentFolder() const; + void setAttachmentFolder(const QString &p_attachmentFolder); - // Get image folder path. - virtual QString fetchImageFolderPath(); + QString fetchAttachmentFolderPath(); - virtual void load(); - virtual void save(); + virtual QStringList addAttachment(const QString &p_destFolderPath, const QStringList &p_files) = 0; - static bool isAncestor(const Node *p_ancestor, const Node *p_child); + virtual QString newAttachmentFile(const QString &p_destFolderPath, const QString &p_name) = 0; - bool existsOnDisk() const; + virtual QString newAttachmentFolder(const QString &p_destFolderPath, const QString &p_name) = 0; - QString read() const; - void write(const QString &p_content); + virtual QString renameAttachment(const QString &p_path, const QString &p_name) = 0; - // Insert image from @p_srcImagePath. - // Return inserted image file path. - virtual QString insertImage(const QString &p_srcImagePath, const QString &p_imageFileName); + virtual void removeAttachment(const QStringList &p_paths) = 0; - virtual QString insertImage(const QImage &p_image, const QString &p_imageFileName); + QDir toDir() const; - virtual void removeImage(const QString &p_imagePath); + bool isReadOnly() const; + void setReadOnly(bool p_readOnly); - // Get attachment folder path. - virtual QString fetchAttachmentFolderPath(); + // Get File if this node has content. + virtual QSharedPointer getContentFile() = 0; - virtual QStringList addAttachment(const QString &p_destFolderPath, const QStringList &p_files); + void loadCompleteInfo(ID p_id, + const QDateTime &p_createdTimeUtc, + const QDateTime &p_modifiedTimeUtc, + const QStringList &p_tags, + const QVector> &p_children); - virtual QString newAttachmentFile(const QString &p_destFolderPath, const QString &p_name); - - virtual QString newAttachmentFolder(const QString &p_destFolderPath, const QString &p_name); - - virtual QString renameAttachment(const QString &p_path, const QString &p_name); - - virtual void removeAttachment(const QStringList &p_paths); - - virtual QStringList getTags() const; - - virtual QDir toDir() const; + INotebookConfigMgr *getConfigMgr() const; INotebookBackend *getBackend() const; - bool isReadOnly() const; + static bool isAncestor(const Node *p_ancestor, const Node *p_child); protected: - void loadInfo(ID p_id, const QDateTime &p_createdTimeUtc); - - void setLoaded(bool p_loaded); - Notebook *m_notebook = nullptr; - QSharedPointer m_configMgr; - - QSharedPointer m_backend; - private: - Type m_type = Type::Folder; + bool m_loaded = false; Flags m_flags = Flag::None; @@ -185,9 +174,15 @@ namespace vnotex QDateTime m_createdTimeUtc; - bool m_loaded = false; + QDateTime m_modifiedTimeUtc; + + QStringList m_tags; + + QString m_attachmentFolder; Node *m_parent = nullptr; + + QVector> m_children; }; Q_DECLARE_OPERATORS_FOR_FLAGS(Node::Flags) diff --git a/src/core/notebook/notebook.cpp b/src/core/notebook/notebook.cpp index 05011ee6..a0625564 100644 --- a/src/core/notebook/notebook.cpp +++ b/src/core/notebook/notebook.cpp @@ -152,6 +152,7 @@ const QSharedPointer &Notebook::getRootNode() const { if (!m_root) { const_cast(this)->m_root = m_configMgr->loadRootNode(); + Q_ASSERT(m_root->isRoot()); } return m_root; @@ -174,9 +175,9 @@ QSharedPointer Notebook::getRecycleBinNode() const return nullptr; } -QSharedPointer Notebook::newNode(Node *p_parent, Node::Type p_type, const QString &p_name) +QSharedPointer Notebook::newNode(Node *p_parent, Node::Flags p_flags, const QString &p_name) { - return m_configMgr->newNode(p_parent, p_type, p_name); + return m_configMgr->newNode(p_parent, p_flags, p_name); } const QDateTime &Notebook::getCreatedTimeUtc() const @@ -184,30 +185,6 @@ const QDateTime &Notebook::getCreatedTimeUtc() const return m_createdTimeUtc; } -void Notebook::load(Node *p_node) -{ - Q_ASSERT(p_node->getNotebook() == this); - if (p_node->isLoaded()) { - return; - } - - m_configMgr->loadNode(p_node); -} - -void Notebook::save(const Node *p_node) -{ - Q_ASSERT(p_node->getNotebook() == this); - m_configMgr->saveNode(p_node); -} - -void Notebook::rename(Node *p_node, const QString &p_name) -{ - Q_ASSERT(p_node->getNotebook() == this); - m_configMgr->renameNode(p_node, p_name); - - emit nodeUpdated(p_node); -} - QSharedPointer Notebook::loadNodeByPath(const QString &p_path) { if (!PathUtils::pathContains(m_rootFolderPath, p_path)) { @@ -237,7 +214,7 @@ QSharedPointer Notebook::copyNodeAsChildOf(const QSharedPointer &p_s if (Node::isAncestor(p_src.data(), p_dest)) { Exception::throwOne(Exception::Type::InvalidArgument, QString("source (%1) is the ancestor of destination (%2)") - .arg(p_src->fetchRelativePath(), p_dest->fetchRelativePath())); + .arg(p_src->fetchPath(), p_dest->fetchPath())); return nullptr; } @@ -314,7 +291,7 @@ QSharedPointer Notebook::getOrCreateRecycleBinDateNode() FileUtils::isPlatformNameCaseSensitive()); if (!dateNode) { // Create a date node. - dateNode = newNode(recycleBinNode.data(), Node::Type::Folder, dateNodeName); + dateNode = newNode(recycleBinNode.data(), Node::Flag::Container, dateNodeName); } return dateNode; @@ -331,7 +308,7 @@ void Notebook::emptyNode(const Node *p_node, bool p_force) void Notebook::moveFileToRecycleBin(const QString &p_filePath) { auto node = getOrCreateRecycleBinDateNode(); - auto destFilePath = PathUtils::concatenateFilePath(node->fetchRelativePath(), + auto destFilePath = PathUtils::concatenateFilePath(node->fetchPath(), PathUtils::fileName(p_filePath)); destFilePath = getBackend()->renameIfExistsCaseInsensitive(destFilePath); m_backend->copyFile(p_filePath, destFilePath); @@ -344,8 +321,8 @@ void Notebook::moveFileToRecycleBin(const QString &p_filePath) void Notebook::moveDirToRecycleBin(const QString &p_dirPath) { auto node = getOrCreateRecycleBinDateNode(); - auto destDirPath = PathUtils::concatenateFilePath(node->fetchRelativePath(), - PathUtils::fileName(p_dirPath)); + auto destDirPath = PathUtils::concatenateFilePath(node->fetchPath(), + PathUtils::fileName(p_dirPath)); destDirPath = getBackend()->renameIfExistsCaseInsensitive(destDirPath); m_backend->copyDir(p_dirPath, destDirPath); @@ -355,11 +332,11 @@ void Notebook::moveDirToRecycleBin(const QString &p_dirPath) } QSharedPointer Notebook::addAsNode(Node *p_parent, - Node::Type p_type, + Node::Flags p_flags, const QString &p_name, const NodeParameters &p_paras) { - return m_configMgr->addAsNode(p_parent, p_type, p_name, p_paras); + return m_configMgr->addAsNode(p_parent, p_flags, p_name, p_paras); } bool Notebook::isBuiltInFile(const Node *p_node, const QString &p_name) const @@ -373,8 +350,8 @@ bool Notebook::isBuiltInFolder(const Node *p_node, const QString &p_name) const } QSharedPointer Notebook::copyAsNode(Node *p_parent, - Node::Type p_type, + Node::Flags p_flags, const QString &p_path) { - return m_configMgr->copyAsNode(p_parent, p_type, p_path); + return m_configMgr->copyAsNode(p_parent, p_flags, p_path); } diff --git a/src/core/notebook/notebook.h b/src/core/notebook/notebook.h index 0f913abb..2288fcdd 100644 --- a/src/core/notebook/notebook.h +++ b/src/core/notebook/notebook.h @@ -65,28 +65,25 @@ namespace vnotex QSharedPointer getRecycleBinNode() const; - QSharedPointer newNode(Node *p_parent, Node::Type p_type, const QString &p_name); + QSharedPointer newNode(Node *p_parent, + Node::Flags p_flags, + const QString &p_name); // Add @p_name under @p_parent to add as a new node @p_type. QSharedPointer addAsNode(Node *p_parent, - Node::Type p_type, + Node::Flags p_flags, const QString &p_name, const NodeParameters &p_paras); // Copy @p_path to @p_parent and add as a new node @p_type. QSharedPointer copyAsNode(Node *p_parent, - Node::Type p_type, + Node::Flags p_flags, const QString &p_path); virtual ID getNextNodeId() const = 0; virtual ID getAndUpdateNextNodeId() = 0; - virtual void load(Node *p_node); - virtual void save(const Node *p_node); - - virtual void rename(Node *p_node, const QString &p_name); - virtual void updateNotebookConfig() = 0; virtual void removeNotebookConfig() = 0; diff --git a/src/core/notebook/notebook.pri b/src/core/notebook/notebook.pri index 96a8ad80..68ef64bf 100644 --- a/src/core/notebook/notebook.pri +++ b/src/core/notebook/notebook.pri @@ -4,8 +4,8 @@ SOURCES += \ $$PWD/notebookparameters.cpp \ $$PWD/bundlenotebook.cpp \ $$PWD/node.cpp \ - $$PWD/filenode.cpp \ - $$PWD/foldernode.cpp + $$PWD/vxnode.cpp \ + $$PWD/vxnodefile.cpp HEADERS += \ $$PWD/notebook.h \ @@ -14,5 +14,5 @@ HEADERS += \ $$PWD/notebookparameters.h \ $$PWD/bundlenotebook.h \ $$PWD/node.h \ - $$PWD/filenode.h \ - $$PWD/foldernode.h + $$PWD/vxnode.h \ + $$PWD/vxnodefile.h diff --git a/src/core/notebook/vxnode.cpp b/src/core/notebook/vxnode.cpp new file mode 100644 index 00000000..b731cff5 --- /dev/null +++ b/src/core/notebook/vxnode.cpp @@ -0,0 +1,117 @@ +#include "vxnode.h" + +#include + +#include +#include +#include +#include "notebook.h" +#include "vxnodefile.h" + +using namespace vnotex; + +VXNode::VXNode(ID p_id, + const QString &p_name, + const QDateTime &p_createdTimeUtc, + const QDateTime &p_modifiedTimeUtc, + const QStringList &p_tags, + const QString &p_attachmentFolder, + Notebook *p_notebook, + Node *p_parent) + : Node(Node::Flag::Content, + p_id, + p_name, + p_createdTimeUtc, + p_modifiedTimeUtc, + p_tags, + p_attachmentFolder, + p_notebook, + p_parent) +{ +} + +VXNode::VXNode(const QString &p_name, + Notebook *p_notebook, + Node *p_parent) + : Node(Node::Flag::Container, + p_name, + p_notebook, + p_parent) +{ +} + +QString VXNode::fetchAbsolutePath() const +{ + return PathUtils::concatenateFilePath(m_notebook->getRootFolderAbsolutePath(), + fetchPath()); +} + +QSharedPointer VXNode::getContentFile() +{ + // We should not keep the shared ptr of VXNodeFile, or there is a cyclic ref. + return QSharedPointer::create(sharedFromThis().dynamicCast()); +} + +QStringList VXNode::addAttachment(const QString &p_destFolderPath, const QStringList &p_files) +{ + Q_ASSERT(PathUtils::pathContains(fetchAttachmentFolderPath(), p_destFolderPath)); + + auto backend = getBackend(); + QStringList addedFiles; + for (const auto &file : p_files) { + if (PathUtils::isDir(file)) { + qWarning() << "skip adding folder as attachment" << file; + continue; + } + + auto destFilePath = backend->renameIfExistsCaseInsensitive( + PathUtils::concatenateFilePath(p_destFolderPath, PathUtils::fileName(file))); + backend->copyFile(file, destFilePath); + addedFiles << destFilePath; + } + + return addedFiles; +} + +QString VXNode::newAttachmentFile(const QString &p_destFolderPath, const QString &p_name) +{ + Q_ASSERT(PathUtils::pathContains(fetchAttachmentFolderPath(), p_destFolderPath)); + + auto backend = getBackend(); + auto destFilePath = backend->renameIfExistsCaseInsensitive( + PathUtils::concatenateFilePath(p_destFolderPath, p_name)); + backend->writeFile(destFilePath, QByteArray()); + return destFilePath; +} + +QString VXNode::newAttachmentFolder(const QString &p_destFolderPath, const QString &p_name) +{ + Q_ASSERT(PathUtils::pathContains(fetchAttachmentFolderPath(), p_destFolderPath)); + + auto backend = getBackend(); + auto destFilePath = backend->renameIfExistsCaseInsensitive( + PathUtils::concatenateFilePath(p_destFolderPath, p_name)); + backend->makePath(destFilePath); + return destFilePath; +} + +QString VXNode::renameAttachment(const QString &p_path, const QString &p_name) +{ + Q_ASSERT(PathUtils::pathContains(fetchAttachmentFolderPath(), p_path)); + getBackend()->renameFile(p_path, p_name); + return p_name; +} + +void VXNode::removeAttachment(const QStringList &p_paths) +{ + auto attaFolderPath = fetchAttachmentFolderPath(); + // Just move it to recycle bin but not added as a child node of recycle bin. + for (const auto &pa : p_paths) { + Q_ASSERT(PathUtils::pathContains(attaFolderPath, pa)); + if (QFileInfo(pa).isDir()) { + m_notebook->moveDirToRecycleBin(pa); + } else { + m_notebook->moveFileToRecycleBin(pa); + } + } +} diff --git a/src/core/notebook/vxnode.h b/src/core/notebook/vxnode.h new file mode 100644 index 00000000..ddbcccb8 --- /dev/null +++ b/src/core/notebook/vxnode.h @@ -0,0 +1,45 @@ +#ifndef VXNODE_H +#define VXNODE_H + +#include "node.h" + +namespace vnotex +{ + // Node of VXNotebookConfigMgr. + class VXNode : public Node + { + public: + // For content node. + VXNode(ID p_id, + const QString &p_name, + const QDateTime &p_createdTimeUtc, + const QDateTime &p_modifiedTimeUtc, + const QStringList &p_tags, + const QString &p_attachmentFolder, + Notebook *p_notebook, + Node *p_parent); + + // For container node. + VXNode(const QString &p_name, + Notebook *p_notebook, + Node *p_parent); + + QString fetchAbsolutePath() const Q_DECL_OVERRIDE; + + QSharedPointer getContentFile() Q_DECL_OVERRIDE; + + QStringList addAttachment(const QString &p_destFolderPath, const QStringList &p_files) Q_DECL_OVERRIDE; + + QString newAttachmentFile(const QString &p_destFolderPath, const QString &p_name) Q_DECL_OVERRIDE; + + QString newAttachmentFolder(const QString &p_destFolderPath, const QString &p_name) Q_DECL_OVERRIDE; + + QString renameAttachment(const QString &p_path, const QString &p_name) Q_DECL_OVERRIDE; + + void removeAttachment(const QStringList &p_paths) Q_DECL_OVERRIDE; + + private: + }; +} + +#endif // VXNODE_H diff --git a/src/core/notebook/vxnodefile.cpp b/src/core/notebook/vxnodefile.cpp new file mode 100644 index 00000000..a904013b --- /dev/null +++ b/src/core/notebook/vxnodefile.cpp @@ -0,0 +1,92 @@ +#include "vxnodefile.h" + +#include + +#include +#include +#include +#include +#include "vxnode.h" +#include "notebook.h" + +using namespace vnotex; + +VXNodeFile::VXNodeFile(const QSharedPointer &p_node) + : m_node(p_node) +{ + Q_ASSERT(m_node && m_node->hasContent()); +} + +QString VXNodeFile::read() const +{ + return m_node->getBackend()->readTextFile(m_node->fetchPath()); +} + +void VXNodeFile::write(const QString &p_content) +{ + m_node->getBackend()->writeFile(m_node->fetchPath(), p_content); + + m_node->setModifiedTimeUtc(); + m_node->save(); +} + +QString VXNodeFile::getName() const +{ + return m_node->getName(); +} + +QString VXNodeFile::getFilePath() const +{ + return m_node->fetchAbsolutePath(); +} + +QString VXNodeFile::getContentPath() const +{ + return m_node->fetchAbsolutePath(); +} + +QString VXNodeFile::getResourcePath() const +{ + return PathUtils::parentDirPath(getContentPath()); +} + +IFileWithImage *VXNodeFile::getImageInterface() +{ + return this; +} + +Node *VXNodeFile::getNode() const +{ + return m_node.data(); +} + +QString VXNodeFile::fetchImageFolderPath() +{ + auto configMgr = dynamic_cast(m_node->getConfigMgr()); + return configMgr->fetchNodeImageFolderPath(m_node.data()); +} + +QString VXNodeFile::insertImage(const QString &p_srcImagePath, const QString &p_imageFileName) +{ + auto backend = m_node->getBackend(); + const auto imageFolderPath = fetchImageFolderPath(); + auto destFilePath = backend->renameIfExistsCaseInsensitive(PathUtils::concatenateFilePath(imageFolderPath, p_imageFileName)); + backend->copyFile(p_srcImagePath, destFilePath); + return destFilePath; +} + +QString VXNodeFile::insertImage(const QImage &p_image, const QString &p_imageFileName) +{ + auto backend = m_node->getBackend(); + const auto imageFolderPath = fetchImageFolderPath(); + auto destFilePath = backend->renameIfExistsCaseInsensitive(PathUtils::concatenateFilePath(imageFolderPath, p_imageFileName)); + p_image.save(destFilePath); + backend->addFile(destFilePath); + return destFilePath; +} + +void VXNodeFile::removeImage(const QString &p_imagePath) +{ + // Just move it to recycle bin but not added as a child node of recycle bin. + m_node->getNotebook()->moveFileToRecycleBin(p_imagePath); +} diff --git a/src/core/notebook/vxnodefile.h b/src/core/notebook/vxnodefile.h new file mode 100644 index 00000000..77a87ae9 --- /dev/null +++ b/src/core/notebook/vxnodefile.h @@ -0,0 +1,52 @@ +#ifndef VXNODEFILE_H +#define VXNODEFILE_H + +#include + +#include + +namespace vnotex +{ + class VXNode; + + // File from VXNode. + class VXNodeFile : public File, public IFileWithImage + { + public: + explicit VXNodeFile(const QSharedPointer &p_node); + + QString read() const Q_DECL_OVERRIDE; + + void write(const QString &p_content) Q_DECL_OVERRIDE; + + QString getName() const Q_DECL_OVERRIDE; + + QString getFilePath() const Q_DECL_OVERRIDE; + + QString getContentPath() const Q_DECL_OVERRIDE; + + QString getResourcePath() const Q_DECL_OVERRIDE; + + IFileWithImage *getImageInterface() Q_DECL_OVERRIDE; + + // Get the corresponding node if available. + Node *getNode() const Q_DECL_OVERRIDE; + + // IFileWithImage interfaces. + public: + QString fetchImageFolderPath() Q_DECL_OVERRIDE; + + // Insert image from @p_srcImagePath. + // Return inserted image file path. + QString insertImage(const QString &p_srcImagePath, const QString &p_imageFileName) Q_DECL_OVERRIDE; + + QString insertImage(const QImage &p_image, const QString &p_imageFileName) Q_DECL_OVERRIDE; + + void removeImage(const QString &p_imagePath) Q_DECL_OVERRIDE; + + private: + QSharedPointer m_node; + }; +} + +#endif // VXNODEFILE_H diff --git a/src/core/notebookconfigmgr/inotebookconfigmgr.h b/src/core/notebookconfigmgr/inotebookconfigmgr.h index d9a49ad3..7070d647 100644 --- a/src/core/notebookconfigmgr/inotebookconfigmgr.h +++ b/src/core/notebookconfigmgr/inotebookconfigmgr.h @@ -44,16 +44,16 @@ namespace vnotex virtual void renameNode(Node *p_node, const QString &p_name) = 0; virtual QSharedPointer newNode(Node *p_parent, - Node::Type p_type, + Node::Flags p_flags, const QString &p_name) = 0; virtual QSharedPointer addAsNode(Node *p_parent, - Node::Type p_type, + Node::Flags p_flags, const QString &p_name, const NodeParameters &p_paras) = 0; virtual QSharedPointer copyAsNode(Node *p_parent, - Node::Type p_type, + Node::Flags p_flags, const QString &p_path) = 0; Notebook *getNotebook() const; @@ -68,20 +68,13 @@ namespace vnotex virtual void removeNode(const QSharedPointer &p_node, bool p_force, bool p_configOnly) = 0; - virtual bool nodeExistsOnDisk(const Node *p_node) const = 0; - - virtual QString readNode(const Node *p_node) const = 0; - virtual void writeNode(Node *p_node, const QString &p_content) = 0; - - virtual QString fetchNodeImageFolderPath(Node *p_node) = 0; - - virtual QString fetchNodeAttachmentFolderPath(Node *p_node) = 0; - // Whether @p_name is a built-in file under @p_node. virtual bool isBuiltInFile(const Node *p_node, const QString &p_name) const = 0; virtual bool isBuiltInFolder(const Node *p_node, const QString &p_name) const = 0; + virtual QString fetchNodeAttachmentFolderPath(Node *p_node) = 0; + protected: // Version of the config processing code. virtual QString getCodeVersion() const; diff --git a/src/core/notebookconfigmgr/nodecontentmediautils.cpp b/src/core/notebookconfigmgr/nodecontentmediautils.cpp index b81b1b41..b149f721 100644 --- a/src/core/notebookconfigmgr/nodecontentmediautils.cpp +++ b/src/core/notebookconfigmgr/nodecontentmediautils.cpp @@ -22,7 +22,8 @@ void NodeContentMediaUtils::copyMediaFiles(const Node *p_node, INotebookBackend *p_backend, const QString &p_destFilePath) { - Q_ASSERT(p_node->getType() == Node::Type::File); + Q_ASSERT(p_node->hasContent()); + /* const auto &fileType = FileTypeHelper::getInst().getFileType(p_node->fetchAbsolutePath()); if (fileType.m_type == FileTypeHelper::Markdown) { copyMarkdownMediaFiles(p_node->read(), @@ -30,12 +31,14 @@ void NodeContentMediaUtils::copyMediaFiles(const Node *p_node, p_backend, p_destFilePath); } + */ } void NodeContentMediaUtils::copyMediaFiles(const QString &p_filePath, INotebookBackend *p_backend, const QString &p_destFilePath) { + /* const auto &fileType = FileTypeHelper::getInst().getFileType(p_filePath); if (fileType.m_type == FileTypeHelper::Markdown) { copyMarkdownMediaFiles(FileUtils::readTextFile(p_filePath), @@ -43,6 +46,7 @@ void NodeContentMediaUtils::copyMediaFiles(const QString &p_filePath, p_backend, p_destFilePath); } + */ } void NodeContentMediaUtils::copyMarkdownMediaFiles(const QString &p_content, @@ -50,6 +54,7 @@ void NodeContentMediaUtils::copyMarkdownMediaFiles(const QString &p_content, INotebookBackend *p_backend, const QString &p_destFilePath) { + /* auto content = p_content; // Images. @@ -107,19 +112,23 @@ void NodeContentMediaUtils::copyMarkdownMediaFiles(const QString &p_content, if (!renamedImages.isEmpty()) { p_backend->writeFile(p_destFilePath, content); } + */ } void NodeContentMediaUtils::removeMediaFiles(const Node *p_node) { + /* Q_ASSERT(p_node->getType() == Node::Type::File); const auto &fileType = FileTypeHelper::getInst().getFileType(p_node->fetchAbsolutePath()); if (fileType.m_type == FileTypeHelper::Markdown) { removeMarkdownMediaFiles(p_node); } + */ } void NodeContentMediaUtils::removeMarkdownMediaFiles(const Node *p_node) { + /* auto content = p_node->read(); // Images. @@ -143,6 +152,7 @@ void NodeContentMediaUtils::removeMarkdownMediaFiles(const Node *p_node) } backend->removeFile(link.m_path); } + */ } void NodeContentMediaUtils::copyAttachment(Node *p_node, @@ -150,6 +160,7 @@ void NodeContentMediaUtils::copyAttachment(Node *p_node, const QString &p_destFilePath, const QString &p_destAttachmentFolderPath) { + /* Q_ASSERT(p_node->getType() == Node::Type::File); Q_ASSERT(!p_node->getAttachmentFolder().isEmpty()); @@ -166,6 +177,7 @@ void NodeContentMediaUtils::copyAttachment(Node *p_node, if (fileType.m_type == FileTypeHelper::Markdown) { fixMarkdownLinks(srcAttachmentFolderPath, p_backend, p_destFilePath, p_destAttachmentFolderPath); } + */ } void NodeContentMediaUtils::fixMarkdownLinks(const QString &p_srcFolderPath, diff --git a/src/core/notebookconfigmgr/vxnotebookconfigmgr.cpp b/src/core/notebookconfigmgr/vxnotebookconfigmgr.cpp index 66be042e..1b8f85e5 100644 --- a/src/core/notebookconfigmgr/vxnotebookconfigmgr.cpp +++ b/src/core/notebookconfigmgr/vxnotebookconfigmgr.cpp @@ -7,8 +7,7 @@ #include #include -#include -#include +#include #include #include #include @@ -97,10 +96,12 @@ VXNotebookConfigMgr::NodeConfig::NodeConfig() VXNotebookConfigMgr::NodeConfig::NodeConfig(const QString &p_version, ID p_id, - const QDateTime &p_createdTimeUtc) + const QDateTime &p_createdTimeUtc, + const QDateTime &p_modifiedTimeUtc) : m_version(p_version), m_id(p_id), - m_createdTimeUtc(p_createdTimeUtc) + m_createdTimeUtc(p_createdTimeUtc), + m_modifiedTimeUtc(p_modifiedTimeUtc) { } @@ -111,6 +112,7 @@ QJsonObject VXNotebookConfigMgr::NodeConfig::toJson() const jobj[NodeConfig::c_version] = m_version; jobj[NodeConfig::c_id] = QString::number(m_id); jobj[NodeConfig::c_createdTimeUtc] = Utils::dateTimeStringUniform(m_createdTimeUtc); + jobj[NodeConfig::c_modifiedTimeUtc] = Utils::dateTimeStringUniform(m_modifiedTimeUtc); QJsonArray files; for (const auto &file : m_files) { @@ -141,6 +143,7 @@ void VXNotebookConfigMgr::NodeConfig::fromJson(const QJsonObject &p_jobj) } m_createdTimeUtc = Utils::dateTimeFromStringUniform(p_jobj[NodeConfig::c_createdTimeUtc].toString()); + m_modifiedTimeUtc = Utils::dateTimeFromStringUniform(p_jobj[NodeConfig::c_modifiedTimeUtc].toString()); auto filesJson = p_jobj[NodeConfig::c_files].toArray(); m_files.resize(filesJson.size()); @@ -194,9 +197,11 @@ void VXNotebookConfigMgr::createEmptySkeleton(const NotebookParameters &p_paras) void VXNotebookConfigMgr::createEmptyRootNode() { + auto currentTime = QDateTime::currentDateTimeUtc(); NodeConfig node(getCodeVersion(), BundleNotebookConfigMgr::RootNodeId, - QDateTime::currentDateTimeUtc()); + currentTime, + currentTime); writeNodeConfig(c_nodeConfigName, node); } @@ -204,6 +209,7 @@ QSharedPointer VXNotebookConfigMgr::loadRootNode() const { auto nodeConfig = readNodeConfig(""); QSharedPointer root = nodeConfigToNode(*nodeConfig, "", nullptr); + root->setUse(Node::Use::Root); Q_ASSERT(root->isLoaded()); if (!markRecycleBinNode(root)) { @@ -228,12 +234,11 @@ bool VXNotebookConfigMgr::markRecycleBinNode(const QSharedPointer &p_root) void VXNotebookConfigMgr::markNodeReadOnly(Node *p_node) const { - auto flags = p_node->getFlags(); - if (flags & Node::Flag::ReadOnly) { + if (p_node->isReadOnly()) { return; } - p_node->setFlags(flags | Node::Flag::ReadOnly); + p_node->setReadOnly(true); for (auto &child : p_node->getChildren()) { markNodeReadOnly(child.data()); } @@ -243,7 +248,7 @@ void VXNotebookConfigMgr::createRecycleBinNode(const QSharedPointer &p_roo { Q_ASSERT(p_root->isRoot()); - auto node = newNode(p_root.data(), Node::Type::Folder, c_recycleBinFolderName); + auto node = newNode(p_root.data(), Node::Flag::Container, c_recycleBinFolderName); node->setUse(Node::Use::RecycleBin); markNodeReadOnly(node.data()); } @@ -272,8 +277,8 @@ QSharedPointer VXNotebookConfigMgr::readNodeCon QString VXNotebookConfigMgr::getNodeConfigFilePath(const Node *p_node) const { - Q_ASSERT(p_node->getType() == Node::Type::Folder); - return PathUtils::concatenateFilePath(p_node->fetchRelativePath(), c_nodeConfigName); + Q_ASSERT(p_node->isContainer()); + return PathUtils::concatenateFilePath(p_node->fetchPath(), c_nodeConfigName); } void VXNotebookConfigMgr::writeNodeConfig(const QString &p_path, const NodeConfig &p_config) const @@ -291,97 +296,92 @@ QSharedPointer VXNotebookConfigMgr::nodeConfigToNode(const NodeConfig &p_c const QString &p_name, Node *p_parent) const { - auto node = QSharedPointer::create(p_name, getNotebook(), p_parent); + auto node = QSharedPointer::create(p_name, getNotebook(), p_parent); loadFolderNode(node.data(), p_config); return node; } -void VXNotebookConfigMgr::loadFolderNode(FolderNode *p_node, const NodeConfig &p_config) const +void VXNotebookConfigMgr::loadFolderNode(Node *p_node, const NodeConfig &p_config) const { QVector> children; children.reserve(p_config.m_files.size() + p_config.m_folders.size()); for (const auto &folder : p_config.m_folders) { - auto folderNode = QSharedPointer::create(folder.m_name, - getNotebook(), - p_node); + auto folderNode = QSharedPointer::create(folder.m_name, + getNotebook(), + p_node); inheritNodeFlags(p_node, folderNode.data()); children.push_back(folderNode); } for (const auto &file : p_config.m_files) { - auto fileNode = QSharedPointer::create(file.m_id, - file.m_name, - file.m_createdTimeUtc, - file.m_modifiedTimeUtc, - file.m_attachmentFolder, - file.m_tags, - getNotebook(), - p_node); + auto fileNode = QSharedPointer::create(file.m_id, + file.m_name, + file.m_createdTimeUtc, + file.m_modifiedTimeUtc, + file.m_tags, + file.m_attachmentFolder, + getNotebook(), + p_node); inheritNodeFlags(p_node, fileNode.data()); children.push_back(fileNode); } - p_node->loadFolder(p_config.m_id, p_config.m_createdTimeUtc, children); + p_node->loadCompleteInfo(p_config.m_id, + p_config.m_createdTimeUtc, + p_config.m_modifiedTimeUtc, + QStringList(), + children); } QSharedPointer VXNotebookConfigMgr::newNode(Node *p_parent, - Node::Type p_type, + Node::Flags p_flags, const QString &p_name) { - Q_ASSERT(p_parent && p_parent->getType() == Node::Type::Folder); + Q_ASSERT(p_parent && p_parent->isContainer()); QSharedPointer node; - switch (p_type) { - case Node::Type::File: + if (p_flags & Node::Flag::Content) { + Q_ASSERT(!(p_flags & Node::Flag::Container)); node = newFileNode(p_parent, p_name, true, NodeParameters()); - break; - - case Node::Type::Folder: + } else { node = newFolderNode(p_parent, p_name, true, NodeParameters()); - break; } return node; } QSharedPointer VXNotebookConfigMgr::addAsNode(Node *p_parent, - Node::Type p_type, + Node::Flags p_flags, const QString &p_name, const NodeParameters &p_paras) { - Q_ASSERT(p_parent && p_parent->getType() == Node::Type::Folder); + Q_ASSERT(p_parent && p_parent->isContainer()); QSharedPointer node; - switch (p_type) { - case Node::Type::File: + if (p_flags & Node::Flag::Content) { + Q_ASSERT(!(p_flags & Node::Flag::Container)); node = newFileNode(p_parent, p_name, false, p_paras); - break; - - case Node::Type::Folder: + } else { node = newFolderNode(p_parent, p_name, false, p_paras); - break; } return node; } QSharedPointer VXNotebookConfigMgr::copyAsNode(Node *p_parent, - Node::Type p_type, + Node::Flags p_flags, const QString &p_path) { - Q_ASSERT(p_parent && p_parent->getType() == Node::Type::Folder); + Q_ASSERT(p_parent && p_parent->isContainer()); QSharedPointer node; - switch (p_type) { - case Node::Type::File: + if (p_flags & Node::Flag::Content) { + Q_ASSERT(!(p_flags & Node::Flag::Container)); node = copyFileAsChildOf(p_path, p_parent); - break; - - case Node::Type::Folder: + } else { node = copyFolderAsChildOf(p_path, p_parent); - break; } return node; @@ -395,18 +395,18 @@ QSharedPointer VXNotebookConfigMgr::newFileNode(Node *p_parent, auto notebook = getNotebook(); // Create file node. - auto node = QSharedPointer::create(Node::InvalidId, - p_name, - p_paras.m_createdTimeUtc, - p_paras.m_modifiedTimeUtc, - p_paras.m_attachmentFolder, - p_paras.m_tags, - notebook, - p_parent); + auto node = QSharedPointer::create(Node::InvalidId, + p_name, + p_paras.m_createdTimeUtc, + p_paras.m_modifiedTimeUtc, + p_paras.m_tags, + p_paras.m_attachmentFolder, + notebook, + p_parent); // Write empty file. if (p_create) { - getBackend()->writeFile(node->fetchRelativePath(), QString()); + getBackend()->writeFile(node->fetchPath(), QString()); } addChildNode(p_parent, node); @@ -423,14 +423,16 @@ QSharedPointer VXNotebookConfigMgr::newFolderNode(Node *p_parent, auto notebook = getNotebook(); // Create folder node. - auto node = QSharedPointer::create(p_name, notebook, p_parent); - node->loadFolder(Node::InvalidId, - p_paras.m_createdTimeUtc, - QVector>()); + auto node = QSharedPointer::create(p_name, notebook, p_parent); + node->loadCompleteInfo(Node::InvalidId, + p_paras.m_createdTimeUtc, + p_paras.m_modifiedTimeUtc, + QStringList(), + QVector>()); // Make folder. if (p_create) { - getBackend()->makePath(node->fetchRelativePath()); + getBackend()->makePath(node->fetchPath()); } writeNodeConfig(node.data()); @@ -443,16 +445,15 @@ QSharedPointer VXNotebookConfigMgr::newFolderNode(Node *p_parent, QSharedPointer VXNotebookConfigMgr::nodeToNodeConfig(const Node *p_node) const { - Q_ASSERT(p_node->getType() == Node::Type::Folder); + Q_ASSERT(p_node->isContainer()); auto config = QSharedPointer::create(getCodeVersion(), p_node->getId(), - p_node->getCreatedTimeUtc()); + p_node->getCreatedTimeUtc(), + p_node->getModifiedTimeUtc()); for (const auto &child : p_node->getChildren()) { - switch (child->getType()) { - case Node::Type::File: - { + if (child->hasContent()) { NodeFileConfig fileConfig; fileConfig.m_name = child->getName(); fileConfig.m_id = child->getId(); @@ -462,17 +463,12 @@ QSharedPointer VXNotebookConfigMgr::nodeToNodeC fileConfig.m_tags = child->getTags(); config->m_files.push_back(fileConfig); - break; - } - - case Node::Type::Folder: - { + } else { + Q_ASSERT(child->isContainer()); NodeFolderConfig folderConfig; folderConfig.m_name = child->getName(); config->m_folders.push_back(folderConfig); - break; - } } } @@ -485,16 +481,16 @@ void VXNotebookConfigMgr::loadNode(Node *p_node) const return; } - auto config = readNodeConfig(p_node->fetchRelativePath()); - auto folderNode = dynamic_cast(p_node); - loadFolderNode(folderNode, *config); + auto config = readNodeConfig(p_node->fetchPath()); + Q_ASSERT(p_node->isContainer()); + loadFolderNode(p_node, *config); } void VXNotebookConfigMgr::saveNode(const Node *p_node) { Q_ASSERT(!p_node->isRoot()); - if (p_node->getType() == Node::Type::Folder) { + if (p_node->isContainer()) { writeNodeConfig(p_node); } else { writeNodeConfig(p_node->getParent()); @@ -504,14 +500,10 @@ void VXNotebookConfigMgr::saveNode(const Node *p_node) void VXNotebookConfigMgr::renameNode(Node *p_node, const QString &p_name) { Q_ASSERT(!p_node->isRoot()); - switch (p_node->getType()) { - case Node::Type::Folder: - getBackend()->renameDir(p_node->fetchRelativePath(), p_name); - break; - - case Node::Type::File: - getBackend()->renameFile(p_node->fetchRelativePath(), p_name); - break; + if (p_node->isContainer()) { + getBackend()->renameDir(p_node->fetchPath(), p_name); + } else { + getBackend()->renameFile(p_node->fetchPath(), p_name); } p_node->setName(p_name); @@ -520,26 +512,18 @@ void VXNotebookConfigMgr::renameNode(Node *p_node, const QString &p_name) void VXNotebookConfigMgr::addChildNode(Node *p_parent, const QSharedPointer &p_child) const { - // Add @p_child after the last node of same type. - const auto type = p_child->getType(); - switch (type) { - case Node::Type::Folder: - { + if (p_child->isContainer()) { int idx = 0; auto children = p_parent->getChildren(); for (; idx < children.size(); ++idx) { - if (children[idx]->getType() != type) { + if (!children[idx]->isContainer()) { break; } } p_parent->insertChild(idx, p_child); - break; - } - - case Node::Type::File: + } else { p_parent->addChild(p_child); - break; } inheritNodeFlags(p_parent, p_child.data()); @@ -573,22 +557,13 @@ QSharedPointer VXNotebookConfigMgr::copyNodeAsChildOf(const QSharedPointer Node *p_dest, bool p_move) { - Q_ASSERT(p_dest->getType() == Node::Type::Folder); - if (!p_src->existsOnDisk()) { - Exception::throwOne(Exception::Type::FileMissingOnDisk, - QString("source node missing on disk (%1)").arg(p_src->fetchAbsolutePath())); - return nullptr; - } + Q_ASSERT(p_dest->isContainer()); QSharedPointer node; - switch (p_src->getType()) { - case Node::Type::File: - node = copyFileNodeAsChildOf(p_src, p_dest, p_move); - break; - - case Node::Type::Folder: + if (p_src->isContainer()) { node = copyFolderNodeAsChildOf(p_src, p_dest, p_move); - break; + } else { + node = copyFileNodeAsChildOf(p_src, p_dest, p_move); } return node; @@ -600,7 +575,7 @@ QSharedPointer VXNotebookConfigMgr::copyFileNodeAsChildOf(const QSharedPoi { // Copy source file itself. auto srcFilePath = p_src->fetchAbsolutePath(); - auto destFilePath = PathUtils::concatenateFilePath(p_dest->fetchRelativePath(), + auto destFilePath = PathUtils::concatenateFilePath(p_dest->fetchPath(), PathUtils::fileName(srcFilePath)); destFilePath = getBackend()->renameIfExistsCaseInsensitive(destFilePath); getBackend()->copyFile(srcFilePath, destFilePath); @@ -623,14 +598,14 @@ QSharedPointer VXNotebookConfigMgr::copyFileNodeAsChildOf(const QSharedPoi id = notebook->getAndUpdateNextNodeId(); } - auto destNode = QSharedPointer::create(id, - PathUtils::fileName(destFilePath), - p_src->getCreatedTimeUtc(), - p_src->getModifiedTimeUtc(), - attachmentFolder, - p_src->getTags(), - notebook, - p_dest); + auto destNode = QSharedPointer::create(id, + PathUtils::fileName(destFilePath), + p_src->getCreatedTimeUtc(), + p_src->getModifiedTimeUtc(), + p_src->getTags(), + attachmentFolder, + notebook, + p_dest); addChildNode(p_dest, destNode); writeNodeConfig(p_dest); @@ -647,7 +622,7 @@ QSharedPointer VXNotebookConfigMgr::copyFolderNodeAsChildOf(const QSharedP bool p_move) { auto srcFolderPath = p_src->fetchAbsolutePath(); - auto destFolderPath = PathUtils::concatenateFilePath(p_dest->fetchRelativePath(), + auto destFolderPath = PathUtils::concatenateFilePath(p_dest->fetchPath(), PathUtils::fileName(srcFolderPath)); destFolderPath = getBackend()->renameIfExistsCaseInsensitive(destFolderPath); @@ -661,10 +636,14 @@ QSharedPointer VXNotebookConfigMgr::copyFolderNodeAsChildOf(const QSharedP // Use a new id. id = notebook->getAndUpdateNextNodeId(); } - auto destNode = QSharedPointer::create(PathUtils::fileName(destFolderPath), - notebook, - p_dest); - destNode->loadFolder(id, p_src->getCreatedTimeUtc(), QVector>()); + auto destNode = QSharedPointer::create(PathUtils::fileName(destFolderPath), + notebook, + p_dest); + destNode->loadCompleteInfo(id, + p_src->getCreatedTimeUtc(), + p_src->getModifiedTimeUtc(), + QStringList(), + QVector>()); writeNodeConfig(destNode.data()); @@ -704,9 +683,7 @@ void VXNotebookConfigMgr::removeNode(const QSharedPointer &p_node, bool p_ void VXNotebookConfigMgr::removeFilesOfNode(Node *p_node, bool p_force) { Q_ASSERT(p_node->getNotebook() == getNotebook()); - switch (p_node->getType()) { - case Node::Type::File: - { + if (!p_node->isContainer()) { // Delete attachment. if (!p_node->getAttachmentFolder().isEmpty()) { getBackend()->removeDir(p_node->fetchAttachmentFolderPath()); @@ -716,18 +693,14 @@ void VXNotebookConfigMgr::removeFilesOfNode(Node *p_node, bool p_force) NodeContentMediaUtils::removeMediaFiles(p_node); // Delete node file itself. - auto filePath = p_node->fetchRelativePath(); + auto filePath = p_node->fetchPath(); getBackend()->removeFile(filePath); - break; - } - - case Node::Type::Folder: - { + } else { Q_ASSERT(p_node->getChildrenCount() == 0); // Delete node config file and the dir if it is empty. auto configFilePath = getNodeConfigFilePath(p_node); getBackend()->removeFile(configFilePath); - auto folderPath = p_node->fetchRelativePath(); + auto folderPath = p_node->fetchPath(); if (p_force) { getBackend()->removeDir(folderPath); } else { @@ -737,29 +710,7 @@ void VXNotebookConfigMgr::removeFilesOfNode(Node *p_node, bool p_force) qWarning() << "folder is not deleted since it is not empty" << folderPath; } } - break; } - } -} - -bool VXNotebookConfigMgr::nodeExistsOnDisk(const Node *p_node) const -{ - return getBackend()->exists(p_node->fetchRelativePath()); -} - -QString VXNotebookConfigMgr::readNode(const Node *p_node) const -{ - Q_ASSERT(p_node->getType() == Node::Type::File); - return getBackend()->readTextFile(p_node->fetchRelativePath()); -} - -void VXNotebookConfigMgr::writeNode(Node *p_node, const QString &p_content) -{ - Q_ASSERT(p_node->getType() == Node::Type::File); - getBackend()->writeFile(p_node->fetchRelativePath(), p_content); - - p_node->setModifiedTimeUtc(); - writeNodeConfig(p_node->getParent()); } QString VXNotebookConfigMgr::fetchNodeImageFolderPath(Node *p_node) @@ -767,7 +718,7 @@ QString VXNotebookConfigMgr::fetchNodeImageFolderPath(Node *p_node) auto pa = PathUtils::concatenateFilePath(PathUtils::parentDirPath(p_node->fetchAbsolutePath()), getNotebook()->getImageFolder()); // Do not make the folder when it is a folder node request. - if (p_node->getType() == Node::Type::File) { + if (p_node->hasContent()) { getBackend()->makePath(pa); } return pa; @@ -777,7 +728,7 @@ QString VXNotebookConfigMgr::fetchNodeAttachmentFolderPath(Node *p_node) { auto notebookFolder = PathUtils::concatenateFilePath(PathUtils::parentDirPath(p_node->fetchAbsolutePath()), getNotebook()->getAttachmentFolder()); - if (p_node->getType() == Node::Type::File) { + if (p_node->hasContent()) { auto nodeFolder = p_node->getAttachmentFolder(); if (nodeFolder.isEmpty()) { auto folderPath = fetchNodeAttachmentFolder(p_node->fetchAbsolutePath(), nodeFolder); @@ -830,7 +781,7 @@ bool VXNotebookConfigMgr::isBuiltInFolder(const Node *p_node, const QString &p_n QSharedPointer VXNotebookConfigMgr::copyFileAsChildOf(const QString &p_srcPath, Node *p_dest) { // Copy source file itself. - auto destFilePath = PathUtils::concatenateFilePath(p_dest->fetchRelativePath(), + auto destFilePath = PathUtils::concatenateFilePath(p_dest->fetchPath(), PathUtils::fileName(p_srcPath)); destFilePath = getBackend()->renameIfExistsCaseInsensitive(destFilePath); getBackend()->copyFile(p_srcPath, destFilePath); @@ -840,14 +791,14 @@ QSharedPointer VXNotebookConfigMgr::copyFileAsChildOf(const QString &p_src // Create a file node. auto currentTime = QDateTime::currentDateTimeUtc(); - auto destNode = QSharedPointer::create(getNotebook()->getAndUpdateNextNodeId(), - PathUtils::fileName(destFilePath), - currentTime, - currentTime, - QString(), - QStringList(), - getNotebook(), - p_dest); + auto destNode = QSharedPointer::create(getNotebook()->getAndUpdateNextNodeId(), + PathUtils::fileName(destFilePath), + currentTime, + currentTime, + QStringList(), + QString(), + getNotebook(), + p_dest); addChildNode(p_dest, destNode); writeNodeConfig(p_dest); @@ -856,7 +807,7 @@ QSharedPointer VXNotebookConfigMgr::copyFileAsChildOf(const QString &p_src QSharedPointer VXNotebookConfigMgr::copyFolderAsChildOf(const QString &p_srcPath, Node *p_dest) { - auto destFolderPath = PathUtils::concatenateFilePath(p_dest->fetchRelativePath(), + auto destFolderPath = PathUtils::concatenateFilePath(p_dest->fetchPath(), PathUtils::fileName(p_srcPath)); destFolderPath = getBackend()->renameIfExistsCaseInsensitive(destFolderPath); @@ -865,10 +816,15 @@ QSharedPointer VXNotebookConfigMgr::copyFolderAsChildOf(const QString &p_s // Create a folder node. auto notebook = getNotebook(); - auto destNode = QSharedPointer::create(PathUtils::fileName(destFolderPath), - notebook, - p_dest); - destNode->loadFolder(notebook->getAndUpdateNextNodeId(), QDateTime::currentDateTimeUtc(), QVector>()); + auto destNode = QSharedPointer::create(PathUtils::fileName(destFolderPath), + notebook, + p_dest); + auto currentTime = QDateTime::currentDateTimeUtc(); + destNode->loadCompleteInfo(notebook->getAndUpdateNextNodeId(), + currentTime, + currentTime, + QStringList(), + QVector>()); writeNodeConfig(destNode.data()); @@ -880,7 +836,7 @@ QSharedPointer VXNotebookConfigMgr::copyFolderAsChildOf(const QString &p_s void VXNotebookConfigMgr::inheritNodeFlags(const Node *p_node, Node *p_child) const { - if (p_node->getFlags() & Node::Flag::ReadOnly) { + if (p_node->isReadOnly()) { markNodeReadOnly(p_child); } } diff --git a/src/core/notebookconfigmgr/vxnotebookconfigmgr.h b/src/core/notebookconfigmgr/vxnotebookconfigmgr.h index 1885987e..db387335 100644 --- a/src/core/notebookconfigmgr/vxnotebookconfigmgr.h +++ b/src/core/notebookconfigmgr/vxnotebookconfigmgr.h @@ -12,8 +12,6 @@ class QJsonObject; namespace vnotex { - class FolderNode; - // Config manager for VNoteX's bundle notebook. class VXNotebookConfigMgr : public BundleNotebookConfigMgr { @@ -41,16 +39,16 @@ namespace vnotex void renameNode(Node *p_node, const QString &p_name) Q_DECL_OVERRIDE; QSharedPointer newNode(Node *p_parent, - Node::Type p_type, + Node::Flags p_flags, const QString &p_name) Q_DECL_OVERRIDE; QSharedPointer addAsNode(Node *p_parent, - Node::Type p_type, + Node::Flags p_flags, const QString &p_name, const NodeParameters &p_paras) Q_DECL_OVERRIDE; QSharedPointer copyAsNode(Node *p_parent, - Node::Type p_type, + Node::Flags p_flags, const QString &p_path) Q_DECL_OVERRIDE; QSharedPointer loadNodeByPath(const QSharedPointer &p_root, @@ -62,13 +60,11 @@ namespace vnotex void removeNode(const QSharedPointer &p_node, bool p_force = false, bool p_configOnly = false) Q_DECL_OVERRIDE; - bool nodeExistsOnDisk(const Node *p_node) const Q_DECL_OVERRIDE; + bool isBuiltInFile(const Node *p_node, const QString &p_name) const Q_DECL_OVERRIDE; - QString readNode(const Node *p_node) const Q_DECL_OVERRIDE; + bool isBuiltInFolder(const Node *p_node, const QString &p_name) const Q_DECL_OVERRIDE; - void writeNode(Node *p_node, const QString &p_content) Q_DECL_OVERRIDE; - - QString fetchNodeImageFolderPath(Node *p_node) Q_DECL_OVERRIDE; + QString fetchNodeImageFolderPath(Node *p_node); QString fetchNodeAttachmentFolderPath(Node *p_node) Q_DECL_OVERRIDE; @@ -105,7 +101,8 @@ namespace vnotex NodeConfig(const QString &p_version, ID p_id, - const QDateTime &p_createdTimeUtc); + const QDateTime &p_createdTimeUtc, + const QDateTime &p_modifiedTimeUtc); QJsonObject toJson() const; @@ -114,6 +111,7 @@ namespace vnotex QString m_version; ID m_id = Node::InvalidId; QDateTime m_createdTimeUtc; + QDateTime m_modifiedTimeUtc; QVector m_files; QVector m_folders; @@ -147,7 +145,7 @@ namespace vnotex const QString &p_name, Node *p_parent = nullptr) const; - void loadFolderNode(FolderNode *p_node, const NodeConfig &p_config) const; + void loadFolderNode(Node *p_node, const NodeConfig &p_config) const; QSharedPointer nodeToNodeConfig(const Node *p_node) const; @@ -186,10 +184,6 @@ namespace vnotex // Return the attachment folder path. QString fetchNodeAttachmentFolder(const QString &p_nodePath, QString &p_folderName); - bool isBuiltInFile(const Node *p_node, const QString &p_name) const Q_DECL_OVERRIDE; - - bool isBuiltInFolder(const Node *p_node, const QString &p_name) const Q_DECL_OVERRIDE; - void inheritNodeFlags(const Node *p_node, Node *p_child) const; Info m_info; diff --git a/src/utils/fileutils.cpp b/src/utils/fileutils.cpp index 61020e9d..99b0a18d 100644 --- a/src/utils/fileutils.cpp +++ b/src/utils/fileutils.cpp @@ -15,7 +15,7 @@ QByteArray FileUtils::readFile(const QString &p_filePath) QFile file(p_filePath); if (!file.open(QIODevice::ReadOnly)) { Exception::throwOne(Exception::Type::FailToReadFile, - QString("fail to read file: %1").arg(p_filePath)); + QString("failed to read file: %1").arg(p_filePath)); } return file.readAll(); @@ -26,7 +26,7 @@ QString FileUtils::readTextFile(const QString &p_filePath) QFile file(p_filePath); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { Exception::throwOne(Exception::Type::FailToReadFile, - QString("fail to read file: %1").arg(p_filePath)); + QString("failed to read file: %1").arg(p_filePath)); } QString text(file.readAll()); @@ -39,7 +39,7 @@ void FileUtils::writeFile(const QString &p_filePath, const QByteArray &p_data) QFile file(p_filePath); if (!file.open(QIODevice::WriteOnly)) { Exception::throwOne(Exception::Type::FailToWriteFile, - QString("fail to write to file: %1").arg(p_filePath)); + QString("failed to write to file: %1").arg(p_filePath)); } file.write(p_data); @@ -51,7 +51,7 @@ void FileUtils::writeFile(const QString &p_filePath, const QString &p_text) QFile file(p_filePath); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { Exception::throwOne(Exception::Type::FailToWriteFile, - QString("fail to write to file: %1").arg(p_filePath)); + QString("failed to write to file: %1").arg(p_filePath)); } QTextStream stream(&file); @@ -66,7 +66,7 @@ void FileUtils::renameFile(const QString &p_path, const QString &p_name) QFile file(p_path); if (!file.exists() || !file.rename(newFilePath)) { Exception::throwOne(Exception::Type::FailToRenameFile, - QString("fail to rename file: %1").arg(p_path)); + QString("failed to rename file: %1").arg(p_path)); } } @@ -104,7 +104,7 @@ void FileUtils::copyFile(const QString &p_filePath, QDir dir; if (!dir.mkpath(PathUtils::parentDirPath(p_destPath))) { Exception::throwOne(Exception::Type::FailToCreateDir, - QString("fail to create directory: %1").arg(PathUtils::parentDirPath(p_destPath))); + QString("failed to create directory: %1").arg(PathUtils::parentDirPath(p_destPath))); } bool failed = false; @@ -121,7 +121,7 @@ void FileUtils::copyFile(const QString &p_filePath, if (failed) { Exception::throwOne(Exception::Type::FailToCopyFile, - QString("fail to copy file: %1 %2").arg(p_filePath, p_destPath)); + QString("failed to copy file: %1 %2").arg(p_filePath, p_destPath)); } } @@ -144,7 +144,7 @@ void FileUtils::copyDir(const QString &p_dirPath, QDir destDir(p_destPath); if (!destDir.mkpath(p_destPath)) { Exception::throwOne(Exception::Type::FailToCreateDir, - QString("fail to create directory: %1").arg(p_destPath)); + QString("failed to create directory: %1").arg(p_destPath)); } // Copy directory contents recursively. @@ -167,7 +167,7 @@ void FileUtils::copyDir(const QString &p_dirPath, if (p_move) { if (!destDir.rmdir(p_dirPath)) { Exception::throwOne(Exception::Type::FailToRemoveDir, - QString("fail to remove source directory after move: %1").arg(p_dirPath)); + QString("failed to remove source directory after move: %1").arg(p_dirPath)); } } } @@ -198,7 +198,7 @@ void FileUtils::removeFile(const QString &p_filePath) QFile file(p_filePath); if (!file.remove()) { Exception::throwOne(Exception::Type::FailToRemoveFile, - QString("fail to remove file: %1").arg(p_filePath)); + QString("failed to remove file: %1").arg(p_filePath)); } } @@ -211,7 +211,7 @@ bool FileUtils::removeDirIfEmpty(const QString &p_dirPath) if (!dir.rmdir(p_dirPath)) { Exception::throwOne(Exception::Type::FailToRemoveFile, - QString("fail to remove directory: %1").arg(p_dirPath)); + QString("failed to remove directory: %1").arg(p_dirPath)); return false; } @@ -223,7 +223,7 @@ void FileUtils::removeDir(const QString &p_dirPath) QDir dir(p_dirPath); if (!dir.removeRecursively()) { Exception::throwOne(Exception::Type::FailToRemoveFile, - QString("fail to remove directory recursively: %1").arg(p_dirPath)); + QString("failed to remove directory recursively: %1").arg(p_dirPath)); } } diff --git a/src/widgets/dialogs/folderpropertiesdialog.cpp b/src/widgets/dialogs/folderpropertiesdialog.cpp index d1d936b8..31d97503 100644 --- a/src/widgets/dialogs/folderpropertiesdialog.cpp +++ b/src/widgets/dialogs/folderpropertiesdialog.cpp @@ -64,7 +64,7 @@ bool FolderPropertiesDialog::validateNameInput(QString &p_msg) } if (name != m_node->getName() - && m_infoWidget->getParentNode()->hasChild(name, false)) { + && m_infoWidget->getParentNode()->containsChild(name, false)) { p_msg = tr("Name conflicts with existing folder."); return false; } diff --git a/src/widgets/dialogs/importfolderdialog.cpp b/src/widgets/dialogs/importfolderdialog.cpp index 016a73e7..f9c9ff09 100644 --- a/src/widgets/dialogs/importfolderdialog.cpp +++ b/src/widgets/dialogs/importfolderdialog.cpp @@ -86,7 +86,7 @@ bool ImportFolderDialog::importFolder() auto nb = m_parentNode->getNotebook(); m_newNode = nullptr; try { - m_newNode = nb->copyAsNode(m_parentNode, Node::Type::Folder, folder); + m_newNode = nb->copyAsNode(m_parentNode, Node::Flag::Container, folder); } catch (Exception &p_e) { auto msg = tr("Failed to add folder (%1) as node (%2).").arg(folder, p_e.what()); qCritical() << msg; diff --git a/src/widgets/dialogs/importfolderutils.cpp b/src/widgets/dialogs/importfolderutils.cpp index 30b43d7f..d5b766ed 100644 --- a/src/widgets/dialogs/importfolderutils.cpp +++ b/src/widgets/dialogs/importfolderutils.cpp @@ -23,7 +23,7 @@ void ImportFolderUtils::importFolderContents(Notebook *p_notebook, QSharedPointer node; try { - node = p_notebook->addAsNode(p_node, Node::Type::Folder, child.fileName(), NodeParameters()); + node = p_notebook->addAsNode(p_node, Node::Flag::Container, child.fileName(), NodeParameters()); } catch (Exception &p_e) { Utils::appendMsg(p_errMsg, ImportFolderUtilsTranslate::tr("Failed to add folder (%1) as node (%2).").arg(child.fileName(), p_e.what())); continue; @@ -33,7 +33,7 @@ void ImportFolderUtils::importFolderContents(Notebook *p_notebook, } else if (!p_notebook->isBuiltInFile(p_node, child.fileName())) { if (p_suffixes.contains(child.suffix())) { try { - p_notebook->addAsNode(p_node, Node::Type::File, child.fileName(), NodeParameters()); + p_notebook->addAsNode(p_node, Node::Flag::Content, child.fileName(), NodeParameters()); } catch (Exception &p_e) { Utils::appendMsg(p_errMsg, ImportFolderUtilsTranslate::tr("Failed to add file (%1) as node (%2).").arg(child.filePath(), p_e.what())); } @@ -69,7 +69,7 @@ void ImportFolderUtils::importFolderContentsByLegacyConfig(Notebook *p_notebook, try { NodeParameters paras; paras.m_createdTimeUtc = LegacyNotebookUtils::getCreatedTimeUtcOfFolder(rootDir.filePath(name)); - node = p_notebook->addAsNode(p_node, Node::Type::Folder, name, paras); + node = p_notebook->addAsNode(p_node, Node::Flag::Container, name, paras); } catch (Exception &p_e) { Utils::appendMsg(p_errMsg, ImportFolderUtilsTranslate::tr("Failed to add folder (%1) as node (%2).").arg(name, p_e.what())); return; @@ -97,7 +97,7 @@ void ImportFolderUtils::importFolderContentsByLegacyConfig(Notebook *p_notebook, paras.m_modifiedTimeUtc = info.m_modifiedTimeUtc; paras.m_attachmentFolder = info.m_attachmentFolder; paras.m_tags = info.m_tags; - node = p_notebook->addAsNode(p_node, Node::Type::File, info.m_name, paras); + node = p_notebook->addAsNode(p_node, Node::Flag::Content, info.m_name, paras); } catch (Exception &p_e) { Utils::appendMsg(p_errMsg, ImportFolderUtilsTranslate::tr("Failed to add file (%1) as node (%2).").arg(info.m_name, p_e.what())); return; diff --git a/src/widgets/dialogs/newfolderdialog.cpp b/src/widgets/dialogs/newfolderdialog.cpp index 610345b8..430e7fee 100644 --- a/src/widgets/dialogs/newfolderdialog.cpp +++ b/src/widgets/dialogs/newfolderdialog.cpp @@ -33,7 +33,7 @@ void NewFolderDialog::setupUI(const Node *p_node) void NewFolderDialog::setupNodeInfoWidget(const Node *p_node, QWidget *p_parent) { - m_infoWidget = new NodeInfoWidget(p_node, Node::Type::Folder, p_parent); + m_infoWidget = new NodeInfoWidget(p_node, Node::Flag::Container, p_parent); connect(m_infoWidget, &NodeInfoWidget::inputEdited, this, &NewFolderDialog::validateInputs); } @@ -59,7 +59,7 @@ bool NewFolderDialog::validateNameInput(QString &p_msg) return false; } - if (m_infoWidget->getParentNode()->hasChild(name, false)) { + if (m_infoWidget->getParentNode()->containsChild(name, false)) { p_msg = tr("Name conflicts with existing folder."); return false; } @@ -81,7 +81,7 @@ bool NewFolderDialog::newFolder() Notebook *notebook = const_cast(m_infoWidget->getNotebook()); Node *parentNode = const_cast(m_infoWidget->getParentNode()); try { - m_newNode = notebook->newNode(parentNode, Node::Type::Folder, m_infoWidget->getName()); + m_newNode = notebook->newNode(parentNode, Node::Flag::Container, m_infoWidget->getName()); } catch (Exception &p_e) { QString msg = tr("Failed to create folder under (%1) in (%2) (%3).").arg(parentNode->getName(), notebook->getName(), diff --git a/src/widgets/dialogs/newnotedialog.cpp b/src/widgets/dialogs/newnotedialog.cpp index 768fd9fc..8eecbd29 100644 --- a/src/widgets/dialogs/newnotedialog.cpp +++ b/src/widgets/dialogs/newnotedialog.cpp @@ -37,7 +37,7 @@ void NewNoteDialog::setupUI(const Node *p_node) void NewNoteDialog::setupNodeInfoWidget(const Node *p_node, QWidget *p_parent) { - m_infoWidget = new NodeInfoWidget(p_node, Node::Type::File, p_parent); + m_infoWidget = new NodeInfoWidget(p_node, Node::Flag::Content, p_parent); connect(m_infoWidget, &NodeInfoWidget::inputEdited, this, &NewNoteDialog::validateInputs); } @@ -63,7 +63,7 @@ bool NewNoteDialog::validateNameInput(QString &p_msg) return false; } - if (m_infoWidget->getParentNode()->hasChild(name, false)) { + if (m_infoWidget->getParentNode()->containsChild(name, false)) { p_msg = tr("Name conflicts with existing note."); return false; } @@ -85,7 +85,7 @@ bool NewNoteDialog::newNote() Notebook *notebook = const_cast(m_infoWidget->getNotebook()); Node *parentNode = const_cast(m_infoWidget->getParentNode()); try { - m_newNode = notebook->newNode(parentNode, Node::Type::File, m_infoWidget->getName()); + m_newNode = notebook->newNode(parentNode, Node::Flag::Content, m_infoWidget->getName()); } catch (Exception &p_e) { QString msg = tr("Failed to create note under (%1) in (%2) (%3).").arg(parentNode->getName(), notebook->getName(), diff --git a/src/widgets/dialogs/nodeinfowidget.cpp b/src/widgets/dialogs/nodeinfowidget.cpp index bfe888e5..9a8404cc 100644 --- a/src/widgets/dialogs/nodeinfowidget.cpp +++ b/src/widgets/dialogs/nodeinfowidget.cpp @@ -17,24 +17,24 @@ NodeInfoWidget::NodeInfoWidget(const Node *p_node, QWidget *p_parent) : QWidget(p_parent), m_mode(Mode::Edit) { - setupUI(p_node->getParent(), p_node->getType()); + setupUI(p_node->getParent(), p_node->getFlags()); setNode(p_node); } NodeInfoWidget::NodeInfoWidget(const Node *p_parentNode, - Node::Type p_typeToCreate, + Node::Flags p_flags, QWidget *p_parent) : QWidget(p_parent), m_mode(Mode::Create) { - setupUI(p_parentNode, p_typeToCreate); + setupUI(p_parentNode, p_flags); } -void NodeInfoWidget::setupUI(const Node *p_parentNode, Node::Type p_newNodeType) +void NodeInfoWidget::setupUI(const Node *p_parentNode, Node::Flags p_newNodeFlags) { const bool createMode = m_mode == Mode::Create; - const bool isNote = p_newNodeType == Node::Type::File; + const bool isNote = p_newNodeFlags & Node::Flag::Content; m_mainLayout = WidgetUtils::createFormLayout(this); diff --git a/src/widgets/dialogs/nodeinfowidget.h b/src/widgets/dialogs/nodeinfowidget.h index a9343b8c..89f8d38e 100644 --- a/src/widgets/dialogs/nodeinfowidget.h +++ b/src/widgets/dialogs/nodeinfowidget.h @@ -24,7 +24,7 @@ namespace vnotex NodeInfoWidget(const Node *p_node, QWidget *p_parent = nullptr); NodeInfoWidget(const Node *p_parentNode, - Node::Type p_typeToCreate, + Node::Flags p_flags, QWidget *p_parent = nullptr); QLineEdit *getNameLineEdit() const; @@ -39,7 +39,7 @@ namespace vnotex void inputEdited(); private: - void setupUI(const Node *p_parentNode, Node::Type p_newNodeType); + void setupUI(const Node *p_parentNode, Node::Flags p_newNodeFlags); void setupFileTypeComboBox(QWidget *p_parent); diff --git a/src/widgets/dialogs/nodelabelwithupbutton.cpp b/src/widgets/dialogs/nodelabelwithupbutton.cpp index c6f73368..35bf0f62 100644 --- a/src/widgets/dialogs/nodelabelwithupbutton.cpp +++ b/src/widgets/dialogs/nodelabelwithupbutton.cpp @@ -45,7 +45,7 @@ void NodeLabelWithUpButton::setupUI() void NodeLabelWithUpButton::updateLabelAndButton() { - m_label->setText(m_node->fetchRelativePath()); + m_label->setText(m_node->fetchPath()); m_upButton->setVisible(!m_readOnly && !m_node->isRoot()); } diff --git a/src/widgets/dialogs/notepropertiesdialog.cpp b/src/widgets/dialogs/notepropertiesdialog.cpp index 42c00786..b25bd2cd 100644 --- a/src/widgets/dialogs/notepropertiesdialog.cpp +++ b/src/widgets/dialogs/notepropertiesdialog.cpp @@ -66,7 +66,7 @@ bool NotePropertiesDialog::validateNameInput(QString &p_msg) } if (name != m_node->getName() - && m_infoWidget->getParentNode()->hasChild(name, false)) { + && m_infoWidget->getParentNode()->containsChild(name, false)) { p_msg = tr("Name conflicts with existing note."); return false; } diff --git a/src/widgets/markdownviewwindow.cpp b/src/widgets/markdownviewwindow.cpp index c1b4e532..b2266360 100644 --- a/src/widgets/markdownviewwindow.cpp +++ b/src/widgets/markdownviewwindow.cpp @@ -460,7 +460,7 @@ void MarkdownViewWindow::syncTextEditorFromBuffer(bool p_syncPositionFromReadMod m_editor->setBuffer(buffer); if (buffer) { m_editor->setReadOnly(buffer->isReadOnly()); - m_editor->setBasePath(buffer->getContentBasePath()); + m_editor->setBasePath(buffer->getResourcePath()); m_editor->setText(buffer->getContent()); m_editor->setModified(buffer->isModified()); diff --git a/src/widgets/notebookexplorer.cpp b/src/widgets/notebookexplorer.cpp index 6d154a2d..f8f84270 100644 --- a/src/widgets/notebookexplorer.cpp +++ b/src/widgets/notebookexplorer.cpp @@ -183,10 +183,10 @@ Node *NotebookExplorer::currentExploredFolderNode() const auto node = m_nodeExplorer->getCurrentNode(); if (node) { - if (node->getType() == Node::Type::File) { + if (!node->isContainer()) { node = node->getParent(); } - Q_ASSERT(node && node->getType() == Node::Type::Folder); + Q_ASSERT(node && node->isContainer()); } else { node = m_currentNotebook->getRootNode().data(); } @@ -241,7 +241,7 @@ void NotebookExplorer::importFile() QString errMsg; for (const auto &file : files) { try { - m_currentNotebook->copyAsNode(node, Node::Type::File, file); + m_currentNotebook->copyAsNode(node, Node::Flag::Content, file); } catch (Exception &p_e) { errMsg += tr("Failed to add file (%1) as node (%2).\n").arg(file, p_e.what()); } diff --git a/src/widgets/notebooknodeexplorer.cpp b/src/widgets/notebooknodeexplorer.cpp index f8b53d92..0410a128 100644 --- a/src/widgets/notebooknodeexplorer.cpp +++ b/src/widgets/notebooknodeexplorer.cpp @@ -419,19 +419,15 @@ void NotebookNodeExplorer::fillTreeItem(QTreeWidgetItem *p_item, Node *p_node, b QIcon NotebookNodeExplorer::getNodeItemIcon(const Node *p_node) const { - switch (p_node->getType()) { - case Node::Type::File: + if (p_node->hasContent()) { return s_fileNodeIcon; - - case Node::Type::Folder: - { + } else { if (p_node->getUse() == Node::Use::RecycleBin) { return s_recycleBinNodeIcon; } return s_folderNodeIcon; } - } return QIcon(); } @@ -794,18 +790,12 @@ QAction *NotebookNodeExplorer::createAction(Action p_act, QObject *p_parent) } int ret = QDialog::Rejected; - switch (node->getType()) { - case Node::Type::File: - { + if (node->hasContent()) { NotePropertiesDialog dialog(node, VNoteX::getInst().getMainWindow()); ret = dialog.exec(); - break; - } - - case Node::Type::Folder: + } else { FolderPropertiesDialog dialog(node, VNoteX::getInst().getMainWindow()); ret = dialog.exec(); - break; } if (ret == QDialog::Accepted) { @@ -822,7 +812,7 @@ QAction *NotebookNodeExplorer::createAction(Action p_act, QObject *p_parent) auto node = getCurrentNode(); if (node) { locationPath = node->fetchAbsolutePath(); - if (node->getType() == Node::Type::File) { + if (!node->isContainer()) { locationPath = PathUtils::parentDirPath(locationPath); } } else if (m_notebook) { @@ -940,7 +930,7 @@ void NotebookNodeExplorer::copySelectedNodes(bool p_move) p_move ? ClipboardData::MoveNode : ClipboardData::CopyNode); for (auto node : nodes) { auto item = QSharedPointer::create(node->getNotebook()->getId(), - node->fetchRelativePath()); + node->fetchPath()); cdata.addItem(item); } @@ -1012,7 +1002,7 @@ static QSharedPointer getNodeFromClipboardDataItem(const NodeClipboardData } auto node = notebook->loadNodeByPath(p_item->m_nodeRelativePath); - Q_ASSERT(!node || node->fetchRelativePath() == p_item->m_nodeRelativePath); + Q_ASSERT(!node || node->fetchPath() == p_item->m_nodeRelativePath); return node; } @@ -1024,12 +1014,12 @@ void NotebookNodeExplorer::pasteNodesFromClipboard() destNode = m_notebook->getRootNode().data(); } else { // Current node may be a file node. - if (destNode->getType() == Node::Type::File) { + if (!destNode->isContainer()) { destNode = destNode->getParent(); } } - Q_ASSERT(destNode && destNode->getType() == Node::Type::Folder); + Q_ASSERT(destNode && destNode->isContainer()); // Fetch source nodes from clipboard. auto cdata = tryFetchClipboardData();