mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-06 06:19:52 +08:00
370 lines
8.8 KiB
C++
370 lines
8.8 KiB
C++
#include "vnotebook.h"
|
|
#include <QDir>
|
|
#include <QDebug>
|
|
#include "vdirectory.h"
|
|
#include "utils/vutils.h"
|
|
#include "vconfigmanager.h"
|
|
#include "vnotefile.h"
|
|
|
|
extern VConfigManager *g_config;
|
|
|
|
VNotebook::VNotebook(const QString &name, const QString &path, QObject *parent)
|
|
: QObject(parent), m_name(name), m_valid(false)
|
|
{
|
|
m_path = QDir::cleanPath(path);
|
|
m_recycleBinFolder = g_config->getRecycleBinFolder();
|
|
m_rootDir = new VDirectory(this,
|
|
NULL,
|
|
VUtils::directoryNameFromPath(path),
|
|
QDateTime::currentDateTimeUtc());
|
|
}
|
|
|
|
VNotebook::~VNotebook()
|
|
{
|
|
delete m_rootDir;
|
|
}
|
|
|
|
bool VNotebook::readConfigNotebook()
|
|
{
|
|
QJsonObject configJson = VConfigManager::readDirectoryConfig(m_path);
|
|
if (configJson.isEmpty()) {
|
|
qWarning() << "fail to read notebook configuration" << m_path;
|
|
m_valid = false;
|
|
return false;
|
|
}
|
|
|
|
// [image_folder] section.
|
|
auto it = configJson.find(DirConfig::c_imageFolder);
|
|
if (it != configJson.end()) {
|
|
m_imageFolder = it.value().toString();
|
|
}
|
|
|
|
// [recycle_bin_folder] section.
|
|
it = configJson.find(DirConfig::c_recycleBinFolder);
|
|
if (it != configJson.end()) {
|
|
m_recycleBinFolder = it.value().toString();
|
|
}
|
|
|
|
// [attachment_folder] section.
|
|
// SHOULD be processed at last.
|
|
it = configJson.find(DirConfig::c_attachmentFolder);
|
|
if (it != configJson.end()) {
|
|
m_attachmentFolder = it.value().toString();
|
|
}
|
|
|
|
// We do not allow empty attachment folder.
|
|
if (m_attachmentFolder.isEmpty()) {
|
|
m_attachmentFolder = g_config->getAttachmentFolder();
|
|
Q_ASSERT(!m_attachmentFolder.isEmpty());
|
|
writeConfigNotebook();
|
|
}
|
|
|
|
m_valid = true;
|
|
return true;
|
|
}
|
|
|
|
QJsonObject VNotebook::toConfigJsonNotebook() const
|
|
{
|
|
QJsonObject json;
|
|
|
|
// [image_folder] section.
|
|
json[DirConfig::c_imageFolder] = m_imageFolder;
|
|
|
|
// [attachment_folder] section.
|
|
json[DirConfig::c_attachmentFolder] = m_attachmentFolder;
|
|
|
|
// [recycle_bin_folder] section.
|
|
json[DirConfig::c_recycleBinFolder] = m_recycleBinFolder;
|
|
|
|
return json;
|
|
}
|
|
|
|
QJsonObject VNotebook::toConfigJson() const
|
|
{
|
|
QJsonObject json = m_rootDir->toConfigJson();
|
|
QJsonObject nbJson = toConfigJsonNotebook();
|
|
|
|
// Merge nbJson to json.
|
|
for (auto it = nbJson.begin(); it != nbJson.end(); ++it) {
|
|
V_ASSERT(!json.contains(it.key()));
|
|
json[it.key()] = it.value();
|
|
}
|
|
|
|
return json;
|
|
}
|
|
|
|
bool VNotebook::writeToConfig() const
|
|
{
|
|
return VConfigManager::writeDirectoryConfig(m_path, toConfigJson());
|
|
}
|
|
|
|
bool VNotebook::writeConfigNotebook() const
|
|
{
|
|
QJsonObject nbJson = toConfigJsonNotebook();
|
|
|
|
QJsonObject configJson = VConfigManager::readDirectoryConfig(m_path);
|
|
if (configJson.isEmpty()) {
|
|
qWarning() << "fail to read notebook configuration" << m_path;
|
|
return false;
|
|
}
|
|
|
|
for (auto it = nbJson.begin(); it != nbJson.end(); ++it) {
|
|
configJson[it.key()] = it.value();
|
|
}
|
|
|
|
return VConfigManager::writeDirectoryConfig(m_path, configJson);
|
|
}
|
|
|
|
const QString &VNotebook::getName() const
|
|
{
|
|
return m_name;
|
|
}
|
|
|
|
const QString &VNotebook::getPath() const
|
|
{
|
|
return m_path;
|
|
}
|
|
|
|
void VNotebook::close()
|
|
{
|
|
m_rootDir->close();
|
|
}
|
|
|
|
bool VNotebook::open()
|
|
{
|
|
QString recycleBinPath = getRecycleBinFolderPath();
|
|
if (!QFileInfo::exists(recycleBinPath)) {
|
|
QDir dir(m_path);
|
|
if (!dir.mkpath(recycleBinPath)) {
|
|
qWarning() << "fail to create recycle bin folder" << recycleBinPath
|
|
<< "for notebook" << m_name;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return m_rootDir->open();
|
|
}
|
|
|
|
VNotebook *VNotebook::createNotebook(const QString &p_name,
|
|
const QString &p_path,
|
|
bool p_import,
|
|
const QString &p_imageFolder,
|
|
const QString &p_attachmentFolder,
|
|
QObject *p_parent)
|
|
{
|
|
VNotebook *nb = new VNotebook(p_name, p_path, p_parent);
|
|
|
|
// If @p_imageFolder is empty, it will report global configured folder as
|
|
// its image folder.
|
|
nb->setImageFolder(p_imageFolder);
|
|
|
|
// If @p_attachmentFolder is empty, use global configured folder.
|
|
QString attachmentFolder = p_attachmentFolder;
|
|
if (attachmentFolder.isEmpty()) {
|
|
attachmentFolder = g_config->getAttachmentFolder();
|
|
}
|
|
|
|
nb->setAttachmentFolder(attachmentFolder);
|
|
|
|
// Check if there alread exists a config file.
|
|
if (p_import && VConfigManager::directoryConfigExist(p_path)) {
|
|
qDebug() << "import existing notebook";
|
|
nb->readConfigNotebook();
|
|
return nb;
|
|
}
|
|
|
|
VUtils::makePath(p_path);
|
|
|
|
if (!nb->writeToConfig()) {
|
|
delete nb;
|
|
return NULL;
|
|
}
|
|
|
|
return nb;
|
|
}
|
|
|
|
bool VNotebook::deleteNotebook(VNotebook *p_notebook, bool p_deleteFiles)
|
|
{
|
|
bool ret = true;
|
|
|
|
if (!p_notebook) {
|
|
return true;
|
|
}
|
|
|
|
if (p_deleteFiles) {
|
|
if (!p_notebook->open()) {
|
|
qWarning() << "fail to open notebook" << p_notebook->getName()
|
|
<< "to delete";
|
|
ret = false;
|
|
goto exit;
|
|
}
|
|
|
|
// Delete sub directories.
|
|
VDirectory *rootDir = p_notebook->getRootDir();
|
|
QVector<VDirectory *> subdirs = rootDir->getSubDirs();
|
|
for (auto dir : subdirs) {
|
|
// Skip recycle bin.
|
|
VDirectory::deleteDirectory(dir, true);
|
|
}
|
|
|
|
// Delete the recycle bin.
|
|
QDir recycleDir(p_notebook->getRecycleBinFolderPath());
|
|
if (!recycleDir.removeRecursively()) {
|
|
qWarning() << "fail to delete notebook recycle bin folder"
|
|
<< p_notebook->getRecycleBinFolderPath();
|
|
ret = false;
|
|
}
|
|
|
|
// Delete the config file.
|
|
if (!VConfigManager::deleteDirectoryConfig(p_notebook->getPath())) {
|
|
ret = false;
|
|
goto exit;
|
|
}
|
|
|
|
// If it is now an empty directory, delete it.
|
|
QDir dir(p_notebook->getPath());
|
|
dir.cdUp();
|
|
if (!dir.rmdir(rootDir->getName())) {
|
|
qWarning() << "fail to delete notebook root folder" << rootDir->getName();
|
|
ret = false;
|
|
}
|
|
}
|
|
|
|
exit:
|
|
p_notebook->close();
|
|
delete p_notebook;
|
|
|
|
return ret;
|
|
}
|
|
|
|
void VNotebook::rename(const QString &p_name)
|
|
{
|
|
if (p_name == m_name || p_name.isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
m_name = p_name;
|
|
}
|
|
|
|
bool VNotebook::containsFile(const VFile *p_file) const
|
|
{
|
|
return m_rootDir->containsFile(p_file);
|
|
}
|
|
|
|
VNoteFile *VNotebook::tryLoadFile(const QString &p_path)
|
|
{
|
|
QFileInfo fi(p_path);
|
|
Q_ASSERT(fi.isAbsolute());
|
|
if (!fi.exists()) {
|
|
return NULL;
|
|
}
|
|
|
|
QStringList filePath;
|
|
if (VUtils::splitPathInBasePath(m_path, p_path, filePath)) {
|
|
if (filePath.isEmpty()) {
|
|
return NULL;
|
|
}
|
|
|
|
bool opened = isOpened();
|
|
if (!open()) {
|
|
return NULL;
|
|
}
|
|
|
|
VNoteFile *file = m_rootDir->tryLoadFile(filePath);
|
|
|
|
if (!file && !opened) {
|
|
close();
|
|
}
|
|
|
|
return file;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
VDirectory *VNotebook::tryLoadDirectory(const QString &p_path)
|
|
{
|
|
QFileInfo fi(p_path);
|
|
Q_ASSERT(fi.isAbsolute());
|
|
if (!fi.exists()) {
|
|
return NULL;
|
|
}
|
|
|
|
QStringList filePath;
|
|
if (VUtils::splitPathInBasePath(m_path, p_path, filePath)) {
|
|
if (filePath.isEmpty()) {
|
|
return NULL;
|
|
}
|
|
|
|
bool opened = isOpened();
|
|
if (!open()) {
|
|
return NULL;
|
|
}
|
|
|
|
VDirectory *dir = m_rootDir->tryLoadDirectory(filePath);
|
|
|
|
if (!dir && !opened) {
|
|
close();
|
|
}
|
|
|
|
return dir;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
const QString &VNotebook::getImageFolder() const
|
|
{
|
|
if (m_imageFolder.isEmpty()) {
|
|
return g_config->getImageFolder();
|
|
} else {
|
|
return m_imageFolder;
|
|
}
|
|
}
|
|
|
|
void VNotebook::setImageFolder(const QString &p_imageFolder)
|
|
{
|
|
m_imageFolder = p_imageFolder;
|
|
}
|
|
|
|
const QString &VNotebook::getImageFolderConfig() const
|
|
{
|
|
return m_imageFolder;
|
|
}
|
|
|
|
const QString &VNotebook::getAttachmentFolder() const
|
|
{
|
|
return m_attachmentFolder;
|
|
}
|
|
|
|
void VNotebook::setAttachmentFolder(const QString &p_attachmentFolder)
|
|
{
|
|
m_attachmentFolder = p_attachmentFolder;
|
|
}
|
|
|
|
bool VNotebook::isOpened() const
|
|
{
|
|
return m_rootDir->isOpened();
|
|
}
|
|
|
|
QDateTime VNotebook::getCreatedTimeUtc()
|
|
{
|
|
if (!isOpened()) {
|
|
if (!open()) {
|
|
return QDateTime();
|
|
}
|
|
}
|
|
|
|
return m_rootDir->getCreatedTimeUtc();
|
|
}
|
|
|
|
QString VNotebook::getRecycleBinFolderPath() const
|
|
{
|
|
QFileInfo fi(m_recycleBinFolder);
|
|
if (fi.isAbsolute()) {
|
|
return m_recycleBinFolder;
|
|
} else {
|
|
return QDir(m_path).filePath(m_recycleBinFolder);
|
|
}
|
|
}
|