mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
remove recycle bin node
This commit is contained in:
parent
c362facdd7
commit
964dfbb085
@ -23,6 +23,8 @@ namespace vnotex
|
|||||||
FailToRemoveDir,
|
FailToRemoveDir,
|
||||||
FileMissingOnDisk,
|
FileMissingOnDisk,
|
||||||
EssentialFileMissing,
|
EssentialFileMissing,
|
||||||
|
FileExistsOnCreate,
|
||||||
|
DirExistsOnCreate,
|
||||||
InvalidArgument
|
InvalidArgument
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -254,3 +254,8 @@ TagI *BundleNotebook::tag()
|
|||||||
{
|
{
|
||||||
return getTagMgr();
|
return getTagMgr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int BundleNotebook::getConfigVersion() const
|
||||||
|
{
|
||||||
|
return m_configVersion;
|
||||||
|
}
|
||||||
|
@ -41,6 +41,8 @@ namespace vnotex
|
|||||||
|
|
||||||
TagI *tag() Q_DECL_OVERRIDE;
|
TagI *tag() Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
int getConfigVersion() const;
|
||||||
|
|
||||||
// HistoryI.
|
// HistoryI.
|
||||||
public:
|
public:
|
||||||
HistoryI *history() Q_DECL_OVERRIDE;
|
HistoryI *history() Q_DECL_OVERRIDE;
|
||||||
|
@ -109,6 +109,24 @@ bool Node::containsChild(const QSharedPointer<Node> &p_node) const
|
|||||||
return m_children.indexOf(p_node) != -1;
|
return m_children.indexOf(p_node) != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Node::isLegalNameForNewChild(const QString &p_name) const
|
||||||
|
{
|
||||||
|
if (p_name.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto mgr = getConfigMgr();
|
||||||
|
if (mgr->isBuiltInFile(this, p_name) || mgr->isBuiltInFolder(this, p_name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (containsChild(p_name, false)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
QSharedPointer<Node> Node::findChild(const QString &p_name, bool p_caseSensitive) const
|
QSharedPointer<Node> Node::findChild(const QString &p_name, bool p_caseSensitive) const
|
||||||
{
|
{
|
||||||
auto targetName = p_caseSensitive ? p_name : p_name.toLower();
|
auto targetName = p_caseSensitive ? p_name : p_name.toLower();
|
||||||
@ -356,7 +374,7 @@ bool Node::canRename(const QString &p_newName) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_parent->containsChild(p_newName, false)) {
|
if (!m_parent->isLegalNameForNewChild(p_newName)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,6 @@ namespace vnotex
|
|||||||
|
|
||||||
enum Use {
|
enum Use {
|
||||||
Normal,
|
Normal,
|
||||||
RecycleBin,
|
|
||||||
Root
|
Root
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -115,6 +114,8 @@ namespace vnotex
|
|||||||
// Case sensitive.
|
// Case sensitive.
|
||||||
bool containsContentChild(const QString &p_name) const;
|
bool containsContentChild(const QString &p_name) const;
|
||||||
|
|
||||||
|
bool isLegalNameForNewChild(const QString &p_name) const;
|
||||||
|
|
||||||
void addChild(const QSharedPointer<Node> &p_node);
|
void addChild(const QSharedPointer<Node> &p_node);
|
||||||
|
|
||||||
void insertChild(int p_idx, const QSharedPointer<Node> &p_node);
|
void insertChild(int p_idx, const QSharedPointer<Node> &p_node);
|
||||||
|
@ -16,6 +16,8 @@ const QString Notebook::c_defaultAttachmentFolder = QStringLiteral("vx_attachmen
|
|||||||
|
|
||||||
const QString Notebook::c_defaultImageFolder = QStringLiteral("vx_images");
|
const QString Notebook::c_defaultImageFolder = QStringLiteral("vx_images");
|
||||||
|
|
||||||
|
const QString Notebook::c_defaultRecycleBinFolder = QStringLiteral("vx_recycle_bin");
|
||||||
|
|
||||||
static vnotex::ID generateNotebookID()
|
static vnotex::ID generateNotebookID()
|
||||||
{
|
{
|
||||||
static vnotex::ID id = Notebook::InvalidId;
|
static vnotex::ID id = Notebook::InvalidId;
|
||||||
@ -44,6 +46,9 @@ Notebook::Notebook(const NotebookParameters &p_paras,
|
|||||||
if (m_attachmentFolder.isEmpty()) {
|
if (m_attachmentFolder.isEmpty()) {
|
||||||
m_attachmentFolder = c_defaultAttachmentFolder;
|
m_attachmentFolder = c_defaultAttachmentFolder;
|
||||||
}
|
}
|
||||||
|
if (m_recycleBinFolder.isEmpty()) {
|
||||||
|
m_recycleBinFolder = c_defaultRecycleBinFolder;
|
||||||
|
}
|
||||||
|
|
||||||
m_configMgr->setNotebook(this);
|
m_configMgr->setNotebook(this);
|
||||||
}
|
}
|
||||||
@ -151,6 +156,28 @@ const QString &Notebook::getAttachmentFolder() const
|
|||||||
return m_attachmentFolder;
|
return m_attachmentFolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QString &Notebook::getRecycleBinFolder() const
|
||||||
|
{
|
||||||
|
return m_recycleBinFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Notebook::getRecycleBinFolderAbsolutePath() const
|
||||||
|
{
|
||||||
|
if (QDir::isAbsolutePath(m_recycleBinFolder)) {
|
||||||
|
if (!QFileInfo::exists(m_recycleBinFolder)) {
|
||||||
|
QDir dir(m_recycleBinFolder);
|
||||||
|
dir.mkpath(m_recycleBinFolder);
|
||||||
|
}
|
||||||
|
return m_recycleBinFolder;
|
||||||
|
} else {
|
||||||
|
auto folderPath = getBackend()->getFullPath(m_recycleBinFolder);
|
||||||
|
if (!getBackend()->exists(m_recycleBinFolder)) {
|
||||||
|
getBackend()->makePath(m_recycleBinFolder);
|
||||||
|
}
|
||||||
|
return folderPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const QSharedPointer<INotebookBackend> &Notebook::getBackend() const
|
const QSharedPointer<INotebookBackend> &Notebook::getBackend() const
|
||||||
{
|
{
|
||||||
return m_backend;
|
return m_backend;
|
||||||
@ -176,23 +203,6 @@ const QSharedPointer<Node> &Notebook::getRootNode() const
|
|||||||
return m_root;
|
return m_root;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSharedPointer<Node> Notebook::getRecycleBinNode() const
|
|
||||||
{
|
|
||||||
auto root = getRootNode();
|
|
||||||
const auto &children = root->getChildrenRef();
|
|
||||||
auto it = std::find_if(children.begin(),
|
|
||||||
children.end(),
|
|
||||||
[this](const QSharedPointer<Node> &p_node) {
|
|
||||||
return isRecycleBinNode(p_node.data());
|
|
||||||
});
|
|
||||||
|
|
||||||
if (it != children.end()) {
|
|
||||||
return *it;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
QSharedPointer<Node> Notebook::newNode(Node *p_parent,
|
QSharedPointer<Node> Notebook::newNode(Node *p_parent,
|
||||||
Node::Flags p_flags,
|
Node::Flags p_flags,
|
||||||
const QString &p_name,
|
const QString &p_name,
|
||||||
@ -259,27 +269,6 @@ void Notebook::removeNode(Node *p_node, bool p_force, bool p_configOnly)
|
|||||||
removeNode(p_node->sharedFromThis(), p_force, p_configOnly);
|
removeNode(p_node->sharedFromThis(), p_force, p_configOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Notebook::isRecycleBinNode(const Node *p_node) const
|
|
||||||
{
|
|
||||||
return p_node && p_node->getUse() == Node::Use::RecycleBin;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Notebook::isNodeInRecycleBin(const Node *p_node) const
|
|
||||||
{
|
|
||||||
if (p_node) {
|
|
||||||
p_node = p_node->getParent();
|
|
||||||
while (p_node) {
|
|
||||||
if (isRecycleBinNode(p_node)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
p_node = p_node->getParent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Notebook::moveNodeToRecycleBin(Node *p_node)
|
void Notebook::moveNodeToRecycleBin(Node *p_node)
|
||||||
{
|
{
|
||||||
moveNodeToRecycleBin(p_node->sharedFromThis());
|
moveNodeToRecycleBin(p_node->sharedFromThis());
|
||||||
@ -288,59 +277,41 @@ void Notebook::moveNodeToRecycleBin(Node *p_node)
|
|||||||
void Notebook::moveNodeToRecycleBin(const QSharedPointer<Node> &p_node)
|
void Notebook::moveNodeToRecycleBin(const QSharedPointer<Node> &p_node)
|
||||||
{
|
{
|
||||||
Q_ASSERT(p_node && !p_node->isRoot());
|
Q_ASSERT(p_node && !p_node->isRoot());
|
||||||
auto destNode = getOrCreateRecycleBinDateNode();
|
m_configMgr->removeNodeToFolder(p_node, getOrCreateRecycleBinDateFolder());
|
||||||
copyNodeAsChildOf(p_node, destNode.data(), true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QSharedPointer<Node> Notebook::getOrCreateRecycleBinDateNode()
|
QString Notebook::getOrCreateRecycleBinDateFolder()
|
||||||
{
|
{
|
||||||
// Name after date.
|
// Name after date.
|
||||||
auto dateNodeName = QDate::currentDate().toString(QStringLiteral("yyyyMMdd"));
|
auto dateFolderName = QDate::currentDate().toString(QStringLiteral("yyyyMMdd"));
|
||||||
|
auto folderPath = PathUtils::concatenateFilePath(getRecycleBinFolder(), dateFolderName);
|
||||||
auto recycleBinNode = getRecycleBinNode();
|
if (QDir::isAbsolutePath(folderPath)) {
|
||||||
auto dateNode = recycleBinNode->findChild(dateNodeName,
|
qDebug() << "using absolute recycle bin folder" << folderPath;
|
||||||
FileUtils::isPlatformNameCaseSensitive());
|
QDir dir(folderPath);
|
||||||
if (!dateNode) {
|
if (dir.exists()) {
|
||||||
// Create a date node.
|
dir.mkpath(folderPath);
|
||||||
dateNode = newNode(recycleBinNode.data(), Node::Flag::Container, dateNodeName);
|
}
|
||||||
|
} else {
|
||||||
|
if (!getBackend()->exists(folderPath)) {
|
||||||
|
getBackend()->makePath(folderPath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return dateNode;
|
return folderPath;
|
||||||
}
|
|
||||||
|
|
||||||
void Notebook::emptyNode(const Node *p_node, bool p_force)
|
|
||||||
{
|
|
||||||
// Empty the children.
|
|
||||||
auto children = p_node->getChildren();
|
|
||||||
for (const auto &child : children) {
|
|
||||||
removeNode(child, p_force);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Notebook::moveFileToRecycleBin(const QString &p_filePath)
|
void Notebook::moveFileToRecycleBin(const QString &p_filePath)
|
||||||
{
|
{
|
||||||
auto node = getOrCreateRecycleBinDateNode();
|
auto destFilePath = PathUtils::concatenateFilePath(getOrCreateRecycleBinDateFolder(), PathUtils::fileName(p_filePath));
|
||||||
auto destFilePath = PathUtils::concatenateFilePath(node->fetchPath(),
|
|
||||||
PathUtils::fileName(p_filePath));
|
|
||||||
destFilePath = getBackend()->renameIfExistsCaseInsensitive(destFilePath);
|
destFilePath = getBackend()->renameIfExistsCaseInsensitive(destFilePath);
|
||||||
m_backend->copyFile(p_filePath, destFilePath);
|
m_backend->copyFile(p_filePath, destFilePath, true);
|
||||||
|
|
||||||
getBackend()->removeFile(p_filePath);
|
|
||||||
|
|
||||||
emit nodeUpdated(node.data());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Notebook::moveDirToRecycleBin(const QString &p_dirPath)
|
void Notebook::moveDirToRecycleBin(const QString &p_dirPath)
|
||||||
{
|
{
|
||||||
auto node = getOrCreateRecycleBinDateNode();
|
auto destDirPath = PathUtils::concatenateFilePath(getOrCreateRecycleBinDateFolder(), PathUtils::fileName(p_dirPath));
|
||||||
auto destDirPath = PathUtils::concatenateFilePath(node->fetchPath(),
|
|
||||||
PathUtils::fileName(p_dirPath));
|
|
||||||
destDirPath = getBackend()->renameIfExistsCaseInsensitive(destDirPath);
|
destDirPath = getBackend()->renameIfExistsCaseInsensitive(destDirPath);
|
||||||
m_backend->copyDir(p_dirPath, destDirPath);
|
m_backend->copyDir(p_dirPath, destDirPath, true);
|
||||||
|
|
||||||
getBackend()->removeDir(p_dirPath);
|
|
||||||
|
|
||||||
emit nodeUpdated(node.data());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QSharedPointer<Node> Notebook::addAsNode(Node *p_parent,
|
QSharedPointer<Node> Notebook::addAsNode(Node *p_parent,
|
||||||
@ -416,3 +387,12 @@ TagI *Notebook::tag()
|
|||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Notebook::emptyRecycleBin()
|
||||||
|
{
|
||||||
|
QDir dir(getRecycleBinFolderAbsolutePath());
|
||||||
|
auto children = dir.entryList(QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot);
|
||||||
|
for (const auto &child : children) {
|
||||||
|
FileUtils::removeDir(dir.filePath(child));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -61,6 +61,10 @@ namespace vnotex
|
|||||||
|
|
||||||
const QString &getAttachmentFolder() const;
|
const QString &getAttachmentFolder() const;
|
||||||
|
|
||||||
|
const QString &getRecycleBinFolder() const;
|
||||||
|
|
||||||
|
QString getRecycleBinFolderAbsolutePath() const;
|
||||||
|
|
||||||
const QDateTime &getCreatedTimeUtc() const;
|
const QDateTime &getCreatedTimeUtc() const;
|
||||||
|
|
||||||
const QSharedPointer<INotebookBackend> &getBackend() const;
|
const QSharedPointer<INotebookBackend> &getBackend() const;
|
||||||
@ -71,8 +75,6 @@ namespace vnotex
|
|||||||
|
|
||||||
const QSharedPointer<Node> &getRootNode() const;
|
const QSharedPointer<Node> &getRootNode() const;
|
||||||
|
|
||||||
QSharedPointer<Node> getRecycleBinNode() const;
|
|
||||||
|
|
||||||
QSharedPointer<Node> newNode(Node *p_parent,
|
QSharedPointer<Node> newNode(Node *p_parent,
|
||||||
Node::Flags p_flags,
|
Node::Flags p_flags,
|
||||||
const QString &p_name,
|
const QString &p_name,
|
||||||
@ -116,17 +118,11 @@ namespace vnotex
|
|||||||
// Move @p_dirPath to the recycle bin, without adding it as a child node.
|
// Move @p_dirPath to the recycle bin, without adding it as a child node.
|
||||||
void moveDirToRecycleBin(const QString &p_dirPath);
|
void moveDirToRecycleBin(const QString &p_dirPath);
|
||||||
|
|
||||||
|
virtual void emptyRecycleBin();
|
||||||
|
|
||||||
// Remove all files of this notebook from disk.
|
// Remove all files of this notebook from disk.
|
||||||
virtual void remove() = 0;
|
virtual void remove() = 0;
|
||||||
|
|
||||||
bool isRecycleBinNode(const Node *p_node) const;
|
|
||||||
|
|
||||||
bool isNodeInRecycleBin(const Node *p_node) const;
|
|
||||||
|
|
||||||
// Remove all children node of @p_node.
|
|
||||||
// @p_force: if true, just delete all folders and files under @p_node.
|
|
||||||
void emptyNode(const Node *p_node, bool p_force = false);
|
|
||||||
|
|
||||||
// Whether @p_name is a built-in file under @p_node.
|
// Whether @p_name is a built-in file under @p_node.
|
||||||
bool isBuiltInFile(const Node *p_node, const QString &p_name) const;
|
bool isBuiltInFile(const Node *p_node, const QString &p_name) const;
|
||||||
|
|
||||||
@ -150,6 +146,8 @@ namespace vnotex
|
|||||||
|
|
||||||
static const QString c_defaultImageFolder;
|
static const QString c_defaultImageFolder;
|
||||||
|
|
||||||
|
static const QString c_defaultRecycleBinFolder;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Return null if history is not suported.
|
// Return null if history is not suported.
|
||||||
virtual HistoryI *history();
|
virtual HistoryI *history();
|
||||||
@ -168,7 +166,7 @@ namespace vnotex
|
|||||||
virtual void initializeInternal() = 0;
|
virtual void initializeInternal() = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSharedPointer<Node> getOrCreateRecycleBinDateNode();
|
QString getOrCreateRecycleBinDateFolder();
|
||||||
|
|
||||||
bool m_initialized = false;
|
bool m_initialized = false;
|
||||||
|
|
||||||
@ -196,6 +194,9 @@ namespace vnotex
|
|||||||
// Name of the folder to hold attachments.
|
// Name of the folder to hold attachments.
|
||||||
QString m_attachmentFolder;
|
QString m_attachmentFolder;
|
||||||
|
|
||||||
|
// Name or path of the folder to hold deleted files.
|
||||||
|
QString m_recycleBinFolder;
|
||||||
|
|
||||||
QDateTime m_createdTimeUtc;
|
QDateTime m_createdTimeUtc;
|
||||||
|
|
||||||
// Backend for file access and synchronization.
|
// Backend for file access and synchronization.
|
||||||
|
@ -83,13 +83,13 @@ namespace vnotex
|
|||||||
|
|
||||||
// Copy @p_filePath to @p_destPath.
|
// Copy @p_filePath to @p_destPath.
|
||||||
// @p_filePath could be outside notebook.
|
// @p_filePath could be outside notebook.
|
||||||
virtual void copyFile(const QString &p_filePath, const QString &p_destPath) = 0;
|
virtual void copyFile(const QString &p_filePath, const QString &p_destPath, bool p_move = false) = 0;
|
||||||
|
|
||||||
// Delete @p_filePath from disk.
|
// Delete @p_filePath from disk.
|
||||||
virtual void removeFile(const QString &p_filePath) = 0;
|
virtual void removeFile(const QString &p_filePath) = 0;
|
||||||
|
|
||||||
// Copy @p_dirPath to as @p_destPath.
|
// Copy @p_dirPath to as @p_destPath.
|
||||||
virtual void copyDir(const QString &p_dirPath, const QString &p_destPath) = 0;
|
virtual void copyDir(const QString &p_dirPath, const QString &p_destPath, bool p_move = false) = 0;
|
||||||
|
|
||||||
// Delete @p_dirPath from disk if it is empty.
|
// Delete @p_dirPath from disk if it is empty.
|
||||||
// Return false if it is not deleted due to non-empty.
|
// Return false if it is not deleted due to non-empty.
|
||||||
|
@ -123,7 +123,7 @@ void LocalNotebookBackend::renameDir(const QString &p_dirPath, const QString &p_
|
|||||||
FileUtils::renameFile(dirPath, p_name);
|
FileUtils::renameFile(dirPath, p_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalNotebookBackend::copyFile(const QString &p_filePath, const QString &p_destPath)
|
void LocalNotebookBackend::copyFile(const QString &p_filePath, const QString &p_destPath, bool p_move)
|
||||||
{
|
{
|
||||||
auto filePath = p_filePath;
|
auto filePath = p_filePath;
|
||||||
if (QFileInfo(filePath).isRelative()) {
|
if (QFileInfo(filePath).isRelative()) {
|
||||||
@ -132,10 +132,10 @@ void LocalNotebookBackend::copyFile(const QString &p_filePath, const QString &p_
|
|||||||
|
|
||||||
Q_ASSERT(QFileInfo(filePath).isFile());
|
Q_ASSERT(QFileInfo(filePath).isFile());
|
||||||
|
|
||||||
FileUtils::copyFile(filePath, getFullPath(p_destPath));
|
FileUtils::copyFile(filePath, getFullPath(p_destPath), p_move);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalNotebookBackend::copyDir(const QString &p_dirPath, const QString &p_destPath)
|
void LocalNotebookBackend::copyDir(const QString &p_dirPath, const QString &p_destPath, bool p_move)
|
||||||
{
|
{
|
||||||
auto dirPath = p_dirPath;
|
auto dirPath = p_dirPath;
|
||||||
if (QFileInfo(dirPath).isRelative()) {
|
if (QFileInfo(dirPath).isRelative()) {
|
||||||
@ -144,7 +144,7 @@ void LocalNotebookBackend::copyDir(const QString &p_dirPath, const QString &p_de
|
|||||||
|
|
||||||
Q_ASSERT(QFileInfo(dirPath).isDir());
|
Q_ASSERT(QFileInfo(dirPath).isDir());
|
||||||
|
|
||||||
FileUtils::copyDir(dirPath, getFullPath(p_destPath));
|
FileUtils::copyDir(dirPath, getFullPath(p_destPath), p_move);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalNotebookBackend::removeFile(const QString &p_filePath)
|
void LocalNotebookBackend::removeFile(const QString &p_filePath)
|
||||||
|
@ -69,10 +69,10 @@ namespace vnotex
|
|||||||
|
|
||||||
// Copy @p_filePath to @p_destPath.
|
// Copy @p_filePath to @p_destPath.
|
||||||
// @p_filePath may beyond this notebook backend.
|
// @p_filePath may beyond this notebook backend.
|
||||||
void copyFile(const QString &p_filePath, const QString &p_destPath) Q_DECL_OVERRIDE;
|
void copyFile(const QString &p_filePath, const QString &p_destPath, bool p_move = false) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
// Copy @p_dirPath to as @p_destPath.
|
// Copy @p_dirPath to as @p_destPath.
|
||||||
void copyDir(const QString &p_dirPath, const QString &p_destPath) Q_DECL_OVERRIDE;
|
void copyDir(const QString &p_dirPath, const QString &p_destPath, bool p_move = false) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
QString renameIfExistsCaseInsensitive(const QString &p_path) const Q_DECL_OVERRIDE;
|
QString renameIfExistsCaseInsensitive(const QString &p_path) const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
@ -95,12 +95,14 @@ bool BundleNotebookConfigMgr::isBuiltInFile(const Node *p_node, const QString &p
|
|||||||
bool BundleNotebookConfigMgr::isBuiltInFolder(const Node *p_node, const QString &p_name) const
|
bool BundleNotebookConfigMgr::isBuiltInFolder(const Node *p_node, const QString &p_name) const
|
||||||
{
|
{
|
||||||
if (p_node->isRoot()) {
|
if (p_node->isRoot()) {
|
||||||
return p_name.toLower() == c_configFolderName;
|
const auto name = p_name.toLower();
|
||||||
|
return (name == c_configFolderName
|
||||||
|
|| name == getNotebook()->getRecycleBinFolder().toLower());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BundleNotebookConfigMgr::getCodeVersion() const
|
int BundleNotebookConfigMgr::getCodeVersion() const
|
||||||
{
|
{
|
||||||
return 2;
|
return 3;
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,8 @@ namespace vnotex
|
|||||||
|
|
||||||
virtual void removeNode(const QSharedPointer<Node> &p_node, bool p_force, bool p_configOnly) = 0;
|
virtual void removeNode(const QSharedPointer<Node> &p_node, bool p_force, bool p_configOnly) = 0;
|
||||||
|
|
||||||
|
virtual void removeNodeToFolder(const QSharedPointer<Node> &p_node, const QString &p_destFolder) = 0;
|
||||||
|
|
||||||
// Whether @p_name is a built-in file under @p_node.
|
// 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 isBuiltInFile(const Node *p_node, const QString &p_name) const = 0;
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <utils/contentmediautils.h>
|
#include <utils/contentmediautils.h>
|
||||||
|
|
||||||
#include "vxnodeconfig.h"
|
#include "vxnodeconfig.h"
|
||||||
|
#include "vxnotebookconfigmgrfactory.h"
|
||||||
|
|
||||||
using namespace vnotex;
|
using namespace vnotex;
|
||||||
|
|
||||||
@ -29,19 +30,12 @@ using namespace vnotex::vx_node_config;
|
|||||||
|
|
||||||
const QString VXNotebookConfigMgr::c_nodeConfigName = "vx.json";
|
const QString VXNotebookConfigMgr::c_nodeConfigName = "vx.json";
|
||||||
|
|
||||||
const QString VXNotebookConfigMgr::c_recycleBinFolderName = "vx_recycle_bin";
|
|
||||||
|
|
||||||
bool VXNotebookConfigMgr::s_initialized = false;
|
bool VXNotebookConfigMgr::s_initialized = false;
|
||||||
|
|
||||||
QVector<QRegExp> VXNotebookConfigMgr::s_externalNodeExcludePatterns;
|
QVector<QRegExp> VXNotebookConfigMgr::s_externalNodeExcludePatterns;
|
||||||
|
|
||||||
VXNotebookConfigMgr::VXNotebookConfigMgr(const QString &p_name,
|
VXNotebookConfigMgr::VXNotebookConfigMgr(const QSharedPointer<INotebookBackend> &p_backend, QObject *p_parent)
|
||||||
const QString &p_displayName,
|
: BundleNotebookConfigMgr(p_backend, p_parent)
|
||||||
const QString &p_description,
|
|
||||||
const QSharedPointer<INotebookBackend> &p_backend,
|
|
||||||
QObject *p_parent)
|
|
||||||
: BundleNotebookConfigMgr(p_backend, p_parent),
|
|
||||||
m_info(p_name, p_displayName, p_description)
|
|
||||||
{
|
{
|
||||||
if (!s_initialized) {
|
if (!s_initialized) {
|
||||||
s_initialized = true;
|
s_initialized = true;
|
||||||
@ -58,17 +52,17 @@ VXNotebookConfigMgr::VXNotebookConfigMgr(const QString &p_name,
|
|||||||
|
|
||||||
QString VXNotebookConfigMgr::getName() const
|
QString VXNotebookConfigMgr::getName() const
|
||||||
{
|
{
|
||||||
return m_info.m_name;
|
return VXNotebookConfigMgrFactory::c_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString VXNotebookConfigMgr::getDisplayName() const
|
QString VXNotebookConfigMgr::getDisplayName() const
|
||||||
{
|
{
|
||||||
return m_info.m_displayName;
|
return VXNotebookConfigMgrFactory::c_displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString VXNotebookConfigMgr::getDescription() const
|
QString VXNotebookConfigMgr::getDescription() const
|
||||||
{
|
{
|
||||||
return m_info.m_description;
|
return VXNotebookConfigMgrFactory::c_description;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VXNotebookConfigMgr::createEmptySkeleton(const NotebookParameters &p_paras)
|
void VXNotebookConfigMgr::createEmptySkeleton(const NotebookParameters &p_paras)
|
||||||
@ -97,29 +91,21 @@ QSharedPointer<Node> VXNotebookConfigMgr::loadRootNode()
|
|||||||
root->setExists(true);
|
root->setExists(true);
|
||||||
Q_ASSERT(root->isLoaded());
|
Q_ASSERT(root->isLoaded());
|
||||||
|
|
||||||
if (!markRecycleBinNode(root)) {
|
if (static_cast<BundleNotebook *>(getNotebook())->getConfigVersion() < 3) {
|
||||||
const_cast<VXNotebookConfigMgr *>(this)->createRecycleBinNode(root);
|
removeLegacyRecycleBinNode(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VXNotebookConfigMgr::markRecycleBinNode(const QSharedPointer<Node> &p_root)
|
void VXNotebookConfigMgr::removeLegacyRecycleBinNode(const QSharedPointer<Node> &p_root)
|
||||||
{
|
{
|
||||||
auto node = p_root->findChild(c_recycleBinFolderName,
|
// Do not support recycle bin node as it complicates everything.
|
||||||
|
auto node = p_root->findChild(QStringLiteral("vx_recycle_bin"),
|
||||||
FileUtils::isPlatformNameCaseSensitive());
|
FileUtils::isPlatformNameCaseSensitive());
|
||||||
if (node) {
|
if (node) {
|
||||||
if (!node->exists()) {
|
|
||||||
removeNode(node, true, true);
|
removeNode(node, true, true);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
node->setUse(Node::Use::RecycleBin);
|
|
||||||
markNodeReadOnly(node.data());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VXNotebookConfigMgr::markNodeReadOnly(Node *p_node) const
|
void VXNotebookConfigMgr::markNodeReadOnly(Node *p_node) const
|
||||||
@ -134,15 +120,6 @@ void VXNotebookConfigMgr::markNodeReadOnly(Node *p_node) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VXNotebookConfigMgr::createRecycleBinNode(const QSharedPointer<Node> &p_root)
|
|
||||||
{
|
|
||||||
Q_ASSERT(p_root->isRoot());
|
|
||||||
|
|
||||||
auto node = newNode(p_root.data(), Node::Flag::Container, c_recycleBinFolderName, "");
|
|
||||||
node->setUse(Node::Use::RecycleBin);
|
|
||||||
markNodeReadOnly(node.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
QSharedPointer<NodeConfig> VXNotebookConfigMgr::readNodeConfig(const QString &p_path) const
|
QSharedPointer<NodeConfig> VXNotebookConfigMgr::readNodeConfig(const QString &p_path) const
|
||||||
{
|
{
|
||||||
auto backend = getBackend();
|
auto backend = getBackend();
|
||||||
@ -314,6 +291,13 @@ QSharedPointer<Node> VXNotebookConfigMgr::newFileNode(Node *p_parent,
|
|||||||
|
|
||||||
// Write empty file.
|
// Write empty file.
|
||||||
if (p_create) {
|
if (p_create) {
|
||||||
|
if (getBackend()->childExistsCaseInsensitive(p_parent->fetchPath(), p_name)) {
|
||||||
|
// File already exists. Exception.
|
||||||
|
Exception::throwOne(Exception::Type::FileExistsOnCreate,
|
||||||
|
QString("file (%1) already exists when creating new node").arg(node->fetchPath()));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
getBackend()->writeFile(node->fetchPath(), p_content);
|
getBackend()->writeFile(node->fetchPath(), p_content);
|
||||||
node->setExists(true);
|
node->setExists(true);
|
||||||
} else {
|
} else {
|
||||||
@ -343,6 +327,13 @@ QSharedPointer<Node> VXNotebookConfigMgr::newFolderNode(Node *p_parent,
|
|||||||
|
|
||||||
// Make folder.
|
// Make folder.
|
||||||
if (p_create) {
|
if (p_create) {
|
||||||
|
if (getBackend()->childExistsCaseInsensitive(p_parent->fetchPath(), p_name)) {
|
||||||
|
// Dir already exists. Exception.
|
||||||
|
Exception::throwOne(Exception::Type::DirExistsOnCreate,
|
||||||
|
QString("dir (%1) already exists when creating new node").arg(node->fetchPath()));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
getBackend()->makePath(node->fetchPath());
|
getBackend()->makePath(node->fetchPath());
|
||||||
node->setExists(true);
|
node->setExists(true);
|
||||||
} else {
|
} else {
|
||||||
@ -513,22 +504,9 @@ QSharedPointer<Node> VXNotebookConfigMgr::copyFileNodeAsChildOf(const QSharedPoi
|
|||||||
bool p_move,
|
bool p_move,
|
||||||
bool p_updateDatabase)
|
bool p_updateDatabase)
|
||||||
{
|
{
|
||||||
// Copy source file itself.
|
QString destFilePath;
|
||||||
auto srcFilePath = p_src->fetchAbsolutePath();
|
QString attachmentFolder;
|
||||||
auto destFilePath = PathUtils::concatenateFilePath(p_dest->fetchPath(),
|
copyFilesOfFileNode(p_src, p_dest->fetchPath(), destFilePath, attachmentFolder);
|
||||||
PathUtils::fileName(srcFilePath));
|
|
||||||
destFilePath = getBackend()->renameIfExistsCaseInsensitive(destFilePath);
|
|
||||||
getBackend()->copyFile(srcFilePath, destFilePath);
|
|
||||||
|
|
||||||
// Copy media files fetched from content.
|
|
||||||
ContentMediaUtils::copyMediaFiles(p_src.data(), getBackend().data(), destFilePath);
|
|
||||||
|
|
||||||
// Copy attachment folder. Rename attachment folder if conflicts.
|
|
||||||
QString attachmentFolder = p_src->getAttachmentFolder();
|
|
||||||
if (!attachmentFolder.isEmpty()) {
|
|
||||||
auto destAttachmentFolderPath = fetchNodeAttachmentFolder(destFilePath, attachmentFolder);
|
|
||||||
ContentMediaUtils::copyAttachment(p_src.data(), getBackend().data(), destFilePath, destAttachmentFolderPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a file node.
|
// Create a file node.
|
||||||
auto notebook = getNotebook();
|
auto notebook = getNotebook();
|
||||||
@ -571,7 +549,7 @@ QSharedPointer<Node> VXNotebookConfigMgr::copyFileNodeAsChildOf(const QSharedPoi
|
|||||||
|
|
||||||
if (p_move) {
|
if (p_move) {
|
||||||
if (sameNotebook) {
|
if (sameNotebook) {
|
||||||
// The same notebook. Do not directly call removeNode() since we need to update the record
|
// The same notebook. Do not directly call removeNode() since we already update the record
|
||||||
// in database directly.
|
// in database directly.
|
||||||
removeNode(p_src, false, false, false);
|
removeNode(p_src, false, false, false);
|
||||||
} else {
|
} else {
|
||||||
@ -587,9 +565,7 @@ QSharedPointer<Node> VXNotebookConfigMgr::copyFolderNodeAsChildOf(const QSharedP
|
|||||||
bool p_move,
|
bool p_move,
|
||||||
bool p_updateDatabase)
|
bool p_updateDatabase)
|
||||||
{
|
{
|
||||||
auto srcFolderPath = p_src->fetchAbsolutePath();
|
auto destFolderPath = PathUtils::concatenateFilePath(p_dest->fetchPath(), p_src->getName());
|
||||||
auto destFolderPath = PathUtils::concatenateFilePath(p_dest->fetchPath(),
|
|
||||||
PathUtils::fileName(srcFolderPath));
|
|
||||||
destFolderPath = getBackend()->renameIfExistsCaseInsensitive(destFolderPath);
|
destFolderPath = getBackend()->renameIfExistsCaseInsensitive(destFolderPath);
|
||||||
|
|
||||||
// Make folder.
|
// Make folder.
|
||||||
@ -662,7 +638,6 @@ void VXNotebookConfigMgr::removeNode(const QSharedPointer<Node> &p_node,
|
|||||||
bool p_configOnly,
|
bool p_configOnly,
|
||||||
bool p_updateDatabase)
|
bool p_updateDatabase)
|
||||||
{
|
{
|
||||||
auto parentNode = p_node->getParent();
|
|
||||||
if (!p_configOnly && p_node->exists()) {
|
if (!p_configOnly && p_node->exists()) {
|
||||||
// Remove all children.
|
// Remove all children.
|
||||||
auto children = p_node->getChildren();
|
auto children = p_node->getChildren();
|
||||||
@ -683,7 +658,7 @@ void VXNotebookConfigMgr::removeNode(const QSharedPointer<Node> &p_node,
|
|||||||
removeNodeFromDatabase(p_node.data());
|
removeNodeFromDatabase(p_node.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parentNode) {
|
if (auto parentNode = p_node->getParent()) {
|
||||||
parentNode->removeChild(p_node);
|
parentNode->removeChild(p_node);
|
||||||
writeNodeConfig(parentNode);
|
writeNodeConfig(parentNode);
|
||||||
}
|
}
|
||||||
@ -722,6 +697,70 @@ void VXNotebookConfigMgr::removeFilesOfNode(Node *p_node, bool p_force)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VXNotebookConfigMgr::removeNodeToFolder(const QSharedPointer<Node> &p_node, const QString &p_destFolder)
|
||||||
|
{
|
||||||
|
if (p_node->isContainer()) {
|
||||||
|
removeFolderNodeToFolder(p_node, p_destFolder);
|
||||||
|
} else {
|
||||||
|
removeFileNodeToFolder(p_node, p_destFolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VXNotebookConfigMgr::removeFolderNodeToFolder(const QSharedPointer<Node> &p_node, const QString &p_destFolder)
|
||||||
|
{
|
||||||
|
auto destFolderPath = PathUtils::concatenateFilePath(p_destFolder, p_node->getName());
|
||||||
|
destFolderPath = getBackend()->renameIfExistsCaseInsensitive(destFolderPath);
|
||||||
|
|
||||||
|
// Make folder.
|
||||||
|
getBackend()->makePath(destFolderPath);
|
||||||
|
|
||||||
|
// Children.
|
||||||
|
auto children = p_node->getChildren();
|
||||||
|
for (const auto &child : children) {
|
||||||
|
removeNodeToFolder(child, destFolderPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeNode(p_node, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VXNotebookConfigMgr::removeFileNodeToFolder(const QSharedPointer<Node> &p_node, const QString &p_destFolder)
|
||||||
|
{
|
||||||
|
// Use a wrapper folder.
|
||||||
|
auto destFolderPath = PathUtils::concatenateFilePath(p_destFolder, p_node->getName());
|
||||||
|
destFolderPath = getBackend()->renameIfExistsCaseInsensitive(destFolderPath);
|
||||||
|
|
||||||
|
// Make folder.
|
||||||
|
getBackend()->makePath(destFolderPath);
|
||||||
|
|
||||||
|
QString destFilePath;
|
||||||
|
QString attachmentFolder;
|
||||||
|
copyFilesOfFileNode(p_node, destFolderPath, destFilePath, attachmentFolder);
|
||||||
|
|
||||||
|
removeNode(p_node, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VXNotebookConfigMgr::copyFilesOfFileNode(const QSharedPointer<Node> &p_node,
|
||||||
|
const QString &p_destFolder,
|
||||||
|
QString &p_destFilePath,
|
||||||
|
QString &p_attachmentFolder)
|
||||||
|
{
|
||||||
|
// Copy source file itself.
|
||||||
|
auto nodeFilePath = p_node->fetchAbsolutePath();
|
||||||
|
p_destFilePath = PathUtils::concatenateFilePath(p_destFolder, PathUtils::fileName(nodeFilePath));
|
||||||
|
p_destFilePath = getBackend()->renameIfExistsCaseInsensitive(p_destFilePath);
|
||||||
|
getBackend()->copyFile(nodeFilePath, p_destFilePath);
|
||||||
|
|
||||||
|
// Copy media files fetched from content.
|
||||||
|
ContentMediaUtils::copyMediaFiles(p_node.data(), getBackend().data(), p_destFilePath);
|
||||||
|
|
||||||
|
// Copy attachment folder. Rename attachment folder if conflicts.
|
||||||
|
p_attachmentFolder = p_node->getAttachmentFolder();
|
||||||
|
if (!p_attachmentFolder.isEmpty()) {
|
||||||
|
auto destAttachmentFolderPath = fetchNodeAttachmentFolder(p_destFilePath, p_attachmentFolder);
|
||||||
|
ContentMediaUtils::copyAttachment(p_node.data(), getBackend().data(), p_destFilePath, destAttachmentFolderPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QString VXNotebookConfigMgr::fetchNodeImageFolderPath(Node *p_node)
|
QString VXNotebookConfigMgr::fetchNodeImageFolderPath(Node *p_node)
|
||||||
{
|
{
|
||||||
auto pa = PathUtils::concatenateFilePath(PathUtils::parentDirPath(p_node->fetchAbsolutePath()),
|
auto pa = PathUtils::concatenateFilePath(PathUtils::parentDirPath(p_node->fetchAbsolutePath()),
|
||||||
@ -783,9 +822,9 @@ bool VXNotebookConfigMgr::isBuiltInFile(const Node *p_node, const QString &p_nam
|
|||||||
bool VXNotebookConfigMgr::isBuiltInFolder(const Node *p_node, const QString &p_name) const
|
bool VXNotebookConfigMgr::isBuiltInFolder(const Node *p_node, const QString &p_name) const
|
||||||
{
|
{
|
||||||
const auto name = p_name.toLower();
|
const auto name = p_name.toLower();
|
||||||
if (name == c_recycleBinFolderName
|
const auto &nb = getNotebook();
|
||||||
|| name == getNotebook()->getImageFolder().toLower()
|
if (name == nb->getImageFolder().toLower()
|
||||||
|| name == getNotebook()->getAttachmentFolder().toLower()
|
|| name == nb->getAttachmentFolder().toLower()
|
||||||
|| name == QStringLiteral("_v_images")
|
|| name == QStringLiteral("_v_images")
|
||||||
|| name == QStringLiteral("_v_attachments")) {
|
|| name == QStringLiteral("_v_attachments")) {
|
||||||
return true;
|
return true;
|
||||||
@ -946,7 +985,7 @@ bool VXNotebookConfigMgr::checkNodeExists(Node *p_node)
|
|||||||
QStringList VXNotebookConfigMgr::scanAndImportExternalFiles(Node *p_node)
|
QStringList VXNotebookConfigMgr::scanAndImportExternalFiles(Node *p_node)
|
||||||
{
|
{
|
||||||
QStringList files;
|
QStringList files;
|
||||||
if (!p_node->isContainer() || p_node->getUse() == Node::Use::RecycleBin) {
|
if (!p_node->isContainer()) {
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,11 +27,7 @@ namespace vnotex
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit VXNotebookConfigMgr(const QString &p_name,
|
VXNotebookConfigMgr(const QSharedPointer<INotebookBackend> &p_backend, QObject *p_parent = nullptr);
|
||||||
const QString &p_displayName,
|
|
||||||
const QString &p_description,
|
|
||||||
const QSharedPointer<INotebookBackend> &p_backend,
|
|
||||||
QObject *p_parent = nullptr);
|
|
||||||
|
|
||||||
QString getName() const Q_DECL_OVERRIDE;
|
QString getName() const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
@ -71,6 +67,8 @@ namespace vnotex
|
|||||||
|
|
||||||
void removeNode(const QSharedPointer<Node> &p_node, bool p_force = false, bool p_configOnly = false) Q_DECL_OVERRIDE;
|
void removeNode(const QSharedPointer<Node> &p_node, bool p_force = false, bool p_configOnly = false) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
void removeNodeToFolder(const QSharedPointer<Node> &p_node, const QString &p_destFolder) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
bool isBuiltInFile(const Node *p_node, const QString &p_name) const Q_DECL_OVERRIDE;
|
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;
|
bool isBuiltInFolder(const Node *p_node, const QString &p_name) const Q_DECL_OVERRIDE;
|
||||||
@ -137,11 +135,9 @@ namespace vnotex
|
|||||||
|
|
||||||
void removeFilesOfNode(Node *p_node, bool p_force);
|
void removeFilesOfNode(Node *p_node, bool p_force);
|
||||||
|
|
||||||
bool markRecycleBinNode(const QSharedPointer<Node> &p_root);
|
|
||||||
|
|
||||||
void markNodeReadOnly(Node *p_node) const;
|
void markNodeReadOnly(Node *p_node) const;
|
||||||
|
|
||||||
void createRecycleBinNode(const QSharedPointer<Node> &p_root);
|
void removeLegacyRecycleBinNode(const QSharedPointer<Node> &p_root);
|
||||||
|
|
||||||
// Generate node attachment folder.
|
// Generate node attachment folder.
|
||||||
// @p_folderName: suggested folder name if not empty, may be renamed due to conflicts.
|
// @p_folderName: suggested folder name if not empty, may be renamed due to conflicts.
|
||||||
@ -171,9 +167,16 @@ namespace vnotex
|
|||||||
|
|
||||||
bool sameNotebook(const Node *p_node) const;
|
bool sameNotebook(const Node *p_node) const;
|
||||||
|
|
||||||
static bool isLikelyImageFolder(const QString &p_dirPath);
|
void removeFolderNodeToFolder(const QSharedPointer<Node> &p_node, const QString &p_destFolder);
|
||||||
|
|
||||||
Info m_info;
|
void removeFileNodeToFolder(const QSharedPointer<Node> &p_node, const QString &p_destFolder);
|
||||||
|
|
||||||
|
void copyFilesOfFileNode(const QSharedPointer<Node> &p_node,
|
||||||
|
const QString &p_destFolder,
|
||||||
|
QString &p_destFilePath,
|
||||||
|
QString &p_attachmentFolder);
|
||||||
|
|
||||||
|
static bool isLikelyImageFolder(const QString &p_dirPath);
|
||||||
|
|
||||||
static bool s_initialized;
|
static bool s_initialized;
|
||||||
|
|
||||||
@ -181,9 +184,6 @@ namespace vnotex
|
|||||||
|
|
||||||
// Name of the node's config file.
|
// Name of the node's config file.
|
||||||
static const QString c_nodeConfigName;
|
static const QString c_nodeConfigName;
|
||||||
|
|
||||||
// Name of the recycle bin folder which should be a child of the root node.
|
|
||||||
static const QString c_recycleBinFolderName;
|
|
||||||
};
|
};
|
||||||
} // ns vnotex
|
} // ns vnotex
|
||||||
|
|
||||||
|
@ -7,29 +7,32 @@
|
|||||||
|
|
||||||
using namespace vnotex;
|
using namespace vnotex;
|
||||||
|
|
||||||
|
const QString VXNotebookConfigMgrFactory::c_name = QStringLiteral("vx.vnotex");
|
||||||
|
|
||||||
|
const QString VXNotebookConfigMgrFactory::c_displayName = QObject::tr("VNoteX Notebook Configuration");
|
||||||
|
|
||||||
|
const QString VXNotebookConfigMgrFactory::c_description = QObject::tr("Built-in VNoteX notebook configuration");
|
||||||
|
|
||||||
VXNotebookConfigMgrFactory::VXNotebookConfigMgrFactory()
|
VXNotebookConfigMgrFactory::VXNotebookConfigMgrFactory()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QString VXNotebookConfigMgrFactory::getName() const
|
QString VXNotebookConfigMgrFactory::getName() const
|
||||||
{
|
{
|
||||||
return QStringLiteral("vx.vnotex");
|
return c_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString VXNotebookConfigMgrFactory::getDisplayName() const
|
QString VXNotebookConfigMgrFactory::getDisplayName() const
|
||||||
{
|
{
|
||||||
return QObject::tr("VNoteX Notebook Configuration");
|
return c_displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString VXNotebookConfigMgrFactory::getDescription() const
|
QString VXNotebookConfigMgrFactory::getDescription() const
|
||||||
{
|
{
|
||||||
return QObject::tr("Built-in VNoteX notebook configuration");
|
return c_description;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSharedPointer<INotebookConfigMgr> VXNotebookConfigMgrFactory::createNotebookConfigMgr(const QSharedPointer<INotebookBackend> &p_backend)
|
QSharedPointer<INotebookConfigMgr> VXNotebookConfigMgrFactory::createNotebookConfigMgr(const QSharedPointer<INotebookBackend> &p_backend)
|
||||||
{
|
{
|
||||||
return QSharedPointer<VXNotebookConfigMgr>::create(getName(),
|
return QSharedPointer<VXNotebookConfigMgr>::create(p_backend);
|
||||||
getDisplayName(),
|
|
||||||
getDescription(),
|
|
||||||
p_backend);
|
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,12 @@ namespace vnotex
|
|||||||
QString getDescription()const Q_DECL_OVERRIDE;
|
QString getDescription()const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
QSharedPointer<INotebookConfigMgr> createNotebookConfigMgr(const QSharedPointer<INotebookBackend> &p_backend) Q_DECL_OVERRIDE;
|
QSharedPointer<INotebookConfigMgr> createNotebookConfigMgr(const QSharedPointer<INotebookBackend> &p_backend) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
static const QString c_name;
|
||||||
|
|
||||||
|
static const QString c_displayName;
|
||||||
|
|
||||||
|
static const QString c_description;
|
||||||
};
|
};
|
||||||
} // ns vnotex
|
} // ns vnotex
|
||||||
|
|
||||||
|
@ -114,11 +114,7 @@ void SessionConfig::loadCore(const QJsonObject &p_session)
|
|||||||
if (!isUndefinedKey(coreObj, QStringLiteral("system_title_bar"))) {
|
if (!isUndefinedKey(coreObj, QStringLiteral("system_title_bar"))) {
|
||||||
m_systemTitleBarEnabled = readBool(coreObj, QStringLiteral("system_title_bar"));
|
m_systemTitleBarEnabled = readBool(coreObj, QStringLiteral("system_title_bar"));
|
||||||
} else {
|
} else {
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
m_systemTitleBarEnabled = false;
|
|
||||||
#else
|
|
||||||
m_systemTitleBarEnabled = true;
|
m_systemTitleBarEnabled = true;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isUndefinedKey(coreObj, QStringLiteral("minimize_to_system_tray"))) {
|
if (!isUndefinedKey(coreObj, QStringLiteral("minimize_to_system_tray"))) {
|
||||||
@ -318,9 +314,6 @@ void SessionConfig::doVersionSpecificOverride()
|
|||||||
{
|
{
|
||||||
// In a new version, we may want to change one value by force.
|
// In a new version, we may want to change one value by force.
|
||||||
// SHOULD set the in memory variable only, or will override the notebook list.
|
// SHOULD set the in memory variable only, or will override the notebook list.
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
m_systemTitleBarEnabled = false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const ExportOption &SessionConfig::getExportOption() const
|
const ExportOption &SessionConfig::getExportOption() const
|
||||||
|
@ -31,7 +31,6 @@ void WidgetConfig::init(const QJsonObject &p_app,
|
|||||||
|
|
||||||
{
|
{
|
||||||
m_nodeExplorerViewOrder = READINT(QStringLiteral("node_explorer_view_order"));
|
m_nodeExplorerViewOrder = READINT(QStringLiteral("node_explorer_view_order"));
|
||||||
m_nodeExplorerRecycleBinNodeVisible = READBOOL(QStringLiteral("node_explorer_recycle_bin_node_visible"));
|
|
||||||
m_nodeExplorerExternalFilesVisible = READBOOL(QStringLiteral("node_explorer_external_files_visible"));
|
m_nodeExplorerExternalFilesVisible = READBOOL(QStringLiteral("node_explorer_external_files_visible"));
|
||||||
m_nodeExplorerAutoImportExternalFilesEnabled = READBOOL(QStringLiteral("node_explorer_auto_import_external_files_enabled"));
|
m_nodeExplorerAutoImportExternalFilesEnabled = READBOOL(QStringLiteral("node_explorer_auto_import_external_files_enabled"));
|
||||||
m_nodeExplorerCloseBeforeOpenWithEnabled = READBOOL(QStringLiteral("node_explorer_close_before_open_with_enabled"));
|
m_nodeExplorerCloseBeforeOpenWithEnabled = READBOOL(QStringLiteral("node_explorer_close_before_open_with_enabled"));
|
||||||
@ -55,7 +54,6 @@ QJsonObject WidgetConfig::toJson() const
|
|||||||
obj[QStringLiteral("find_and_replace_options")] = static_cast<int>(m_findAndReplaceOptions);
|
obj[QStringLiteral("find_and_replace_options")] = static_cast<int>(m_findAndReplaceOptions);
|
||||||
|
|
||||||
obj[QStringLiteral("node_explorer_view_order")] = m_nodeExplorerViewOrder;
|
obj[QStringLiteral("node_explorer_view_order")] = m_nodeExplorerViewOrder;
|
||||||
obj[QStringLiteral("node_explorer_recycle_bin_node_visible")] = m_nodeExplorerRecycleBinNodeVisible;
|
|
||||||
obj[QStringLiteral("node_explorer_external_files_visible")] = m_nodeExplorerExternalFilesVisible;
|
obj[QStringLiteral("node_explorer_external_files_visible")] = m_nodeExplorerExternalFilesVisible;
|
||||||
obj[QStringLiteral("node_explorer_auto_import_external_files_enabled")] = m_nodeExplorerAutoImportExternalFilesEnabled;
|
obj[QStringLiteral("node_explorer_auto_import_external_files_enabled")] = m_nodeExplorerAutoImportExternalFilesEnabled;
|
||||||
obj[QStringLiteral("node_explorer_close_before_open_with_enabled")] = m_nodeExplorerCloseBeforeOpenWithEnabled;
|
obj[QStringLiteral("node_explorer_close_before_open_with_enabled")] = m_nodeExplorerCloseBeforeOpenWithEnabled;
|
||||||
@ -108,16 +106,6 @@ void WidgetConfig::setNodeExplorerViewOrder(int p_viewOrder)
|
|||||||
updateConfig(m_nodeExplorerViewOrder, p_viewOrder, this);
|
updateConfig(m_nodeExplorerViewOrder, p_viewOrder, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WidgetConfig::isNodeExplorerRecycleBinNodeVisible() const
|
|
||||||
{
|
|
||||||
return m_nodeExplorerRecycleBinNodeVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WidgetConfig::setNodeExplorerRecycleBinNodeVisible(bool p_visible)
|
|
||||||
{
|
|
||||||
updateConfig(m_nodeExplorerRecycleBinNodeVisible, p_visible, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WidgetConfig::isNodeExplorerExternalFilesVisible() const
|
bool WidgetConfig::isNodeExplorerExternalFilesVisible() const
|
||||||
{
|
{
|
||||||
return m_nodeExplorerExternalFilesVisible;
|
return m_nodeExplorerExternalFilesVisible;
|
||||||
|
@ -30,9 +30,6 @@ namespace vnotex
|
|||||||
int getNodeExplorerViewOrder() const;
|
int getNodeExplorerViewOrder() const;
|
||||||
void setNodeExplorerViewOrder(int p_viewOrder);
|
void setNodeExplorerViewOrder(int p_viewOrder);
|
||||||
|
|
||||||
bool isNodeExplorerRecycleBinNodeVisible() const;
|
|
||||||
void setNodeExplorerRecycleBinNodeVisible(bool p_visible);
|
|
||||||
|
|
||||||
bool isNodeExplorerExternalFilesVisible() const;
|
bool isNodeExplorerExternalFilesVisible() const;
|
||||||
void setNodeExplorerExternalFilesVisible(bool p_visible);
|
void setNodeExplorerExternalFilesVisible(bool p_visible);
|
||||||
|
|
||||||
@ -63,8 +60,6 @@ namespace vnotex
|
|||||||
|
|
||||||
int m_nodeExplorerViewOrder = 0;
|
int m_nodeExplorerViewOrder = 0;
|
||||||
|
|
||||||
bool m_nodeExplorerRecycleBinNodeVisible = false;
|
|
||||||
|
|
||||||
bool m_nodeExplorerExternalFilesVisible = true;
|
bool m_nodeExplorerExternalFilesVisible = true;
|
||||||
|
|
||||||
bool m_nodeExplorerAutoImportExternalFilesEnabled = true;
|
bool m_nodeExplorerAutoImportExternalFilesEnabled = true;
|
||||||
|
@ -373,7 +373,6 @@
|
|||||||
"find_and_replace_options" : 16,
|
"find_and_replace_options" : 16,
|
||||||
"//comment" : "View order of the node explorer",
|
"//comment" : "View order of the node explorer",
|
||||||
"node_explorer_view_order" : 0,
|
"node_explorer_view_order" : 0,
|
||||||
"node_explorer_recycle_bin_node_visible" : false,
|
|
||||||
"node_explorer_external_files_visible" : true,
|
"node_explorer_external_files_visible" : true,
|
||||||
"node_explorer_auto_import_external_files_enabled" : true,
|
"node_explorer_auto_import_external_files_enabled" : true,
|
||||||
"//comment" : "Whether close the file before opening it with external program",
|
"//comment" : "Whether close the file before opening it with external program",
|
||||||
|
@ -470,11 +470,6 @@ bool Searcher::firstPhaseSearch(Notebook *p_notebook, QVector<SearchSecondPhaseI
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_notebook->isRecycleBinNode(child.data())) {
|
|
||||||
qDebug() << "skipped searching recycle bin";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (child->hasContent() && testTarget(SearchTarget::SearchFile)) {
|
if (child->hasContent() && testTarget(SearchTarget::SearchFile)) {
|
||||||
if (!firstPhaseSearch(child.data(), p_secondPhaseItems)) {
|
if (!firstPhaseSearch(child.data(), p_secondPhaseItems)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -260,7 +260,7 @@ void ManageNotebooksDialog::closeNotebook(const Notebook *p_notebook)
|
|||||||
int ret = MessageBoxHelper::questionOkCancel(MessageBoxHelper::Question,
|
int ret = MessageBoxHelper::questionOkCancel(MessageBoxHelper::Question,
|
||||||
tr("Close notebook (%1)?")
|
tr("Close notebook (%1)?")
|
||||||
.arg(p_notebook->getName()),
|
.arg(p_notebook->getName()),
|
||||||
tr("The notebook could be imported again later."),
|
tr("The notebook could be opened by VNote again."),
|
||||||
tr("Notebook location: %1").arg(p_notebook->getRootFolderAbsolutePath()),
|
tr("Notebook location: %1").arg(p_notebook->getRootFolderAbsolutePath()),
|
||||||
this);
|
this);
|
||||||
if (ret != QMessageBox::Ok) {
|
if (ret != QMessageBox::Ok) {
|
||||||
@ -289,14 +289,18 @@ void ManageNotebooksDialog::removeNotebook(const Notebook *p_notebook)
|
|||||||
|
|
||||||
int ret = MessageBoxHelper::questionOkCancel(MessageBoxHelper::Warning,
|
int ret = MessageBoxHelper::questionOkCancel(MessageBoxHelper::Warning,
|
||||||
tr("Please close the notebook in VNote first and delete the notebook root folder files manually."),
|
tr("Please close the notebook in VNote first and delete the notebook root folder files manually."),
|
||||||
tr("Press \"Ok\" to open the location of the notebook root folder."),
|
tr("Press \"Ok\" to close the notebook and open the location of the notebook root folder."),
|
||||||
tr("Notebook location: %1").arg(p_notebook->getRootFolderAbsolutePath()),
|
tr("Notebook location: %1").arg(p_notebook->getRootFolderAbsolutePath()),
|
||||||
this);
|
this);
|
||||||
if (ret != QMessageBox::Ok) {
|
if (ret != QMessageBox::Ok) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WidgetUtils::openUrlByDesktop(QUrl::fromLocalFile(p_notebook->getRootFolderAbsolutePath()));
|
const auto rootFolder = p_notebook->getRootFolderAbsolutePath();
|
||||||
|
|
||||||
|
closeNotebook(p_notebook);
|
||||||
|
|
||||||
|
WidgetUtils::openUrlByDesktop(QUrl::fromLocalFile(rootFolder));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ManageNotebooksDialog::checkUnsavedChanges()
|
bool ManageNotebooksDialog::checkUnsavedChanges()
|
||||||
|
@ -57,8 +57,8 @@ bool NewFolderDialog::validateNameInput(QString &p_msg)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_infoWidget->getParentNode()->containsChild(name, false)) {
|
if (!m_infoWidget->getParentNode()->isLegalNameForNewChild(name)) {
|
||||||
p_msg = tr("Name conflicts with existing folder.");
|
p_msg = tr("Name conflicts with existing or built-in folder.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,8 +93,8 @@ bool NewNoteDialog::validateNameInput(QString &p_msg)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_infoWidget->getParentNode()->containsChild(name, false)) {
|
if (!m_infoWidget->getParentNode()->isLegalNameForNewChild(name)) {
|
||||||
p_msg = tr("Name conflicts with existing note.");
|
p_msg = tr("Name conflicts with existing or built-in note.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -629,7 +629,7 @@ void MainWindow::exportNotes()
|
|||||||
auto currentNotebook = m_notebookExplorer->currentNotebook().data();
|
auto currentNotebook = m_notebookExplorer->currentNotebook().data();
|
||||||
auto viewWindow = m_viewArea->getCurrentViewWindow();
|
auto viewWindow = m_viewArea->getCurrentViewWindow();
|
||||||
auto folderNode = m_notebookExplorer->currentExploredFolderNode();
|
auto folderNode = m_notebookExplorer->currentExploredFolderNode();
|
||||||
if (folderNode && (folderNode->isRoot() || currentNotebook->isRecycleBinNode(folderNode))) {
|
if (folderNode && (folderNode->isRoot())) {
|
||||||
folderNode = nullptr;
|
folderNode = nullptr;
|
||||||
}
|
}
|
||||||
auto noteNode = m_notebookExplorer->currentExploredNode();
|
auto noteNode = m_notebookExplorer->currentExploredNode();
|
||||||
|
@ -81,7 +81,6 @@ void NotebookExplorer::setupUI()
|
|||||||
|
|
||||||
const auto &widgetConfig = ConfigMgr::getInst().getWidgetConfig();
|
const auto &widgetConfig = ConfigMgr::getInst().getWidgetConfig();
|
||||||
m_nodeExplorer = new NotebookNodeExplorer(this);
|
m_nodeExplorer = new NotebookNodeExplorer(this);
|
||||||
m_nodeExplorer->setRecycleBinNodeVisible(widgetConfig.isNodeExplorerRecycleBinNodeVisible());
|
|
||||||
m_nodeExplorer->setViewOrder(widgetConfig.getNodeExplorerViewOrder());
|
m_nodeExplorer->setViewOrder(widgetConfig.getNodeExplorerViewOrder());
|
||||||
m_nodeExplorer->setExternalFilesVisible(widgetConfig.isNodeExplorerExternalFilesVisible());
|
m_nodeExplorer->setExternalFilesVisible(widgetConfig.isNodeExplorerExternalFilesVisible());
|
||||||
connect(m_nodeExplorer, &NotebookNodeExplorer::nodeActivated,
|
connect(m_nodeExplorer, &NotebookNodeExplorer::nodeActivated,
|
||||||
@ -122,15 +121,9 @@ TitleBar *NotebookExplorer::setupTitleBar(QWidget *p_parent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto btn = titleBar->addActionButton(QStringLiteral("recycle_bin.svg"), tr("Toggle Recycle Bin Node"));
|
auto recycleBinMenu = WidgetsFactory::createMenu(titleBar);
|
||||||
btn->defaultAction()->setCheckable(true);
|
setupRecycleBinMenu(recycleBinMenu);
|
||||||
btn->defaultAction()->setChecked(widgetConfig.isNodeExplorerRecycleBinNodeVisible());
|
titleBar->addActionButton(QStringLiteral("recycle_bin.svg"), tr("Recycle Bin"), recycleBinMenu);
|
||||||
connect(btn, &QToolButton::triggered,
|
|
||||||
this, [this](QAction *p_act) {
|
|
||||||
const bool checked = p_act->isChecked();
|
|
||||||
ConfigMgr::getInst().getWidgetConfig().setNodeExplorerRecycleBinNodeVisible(checked);
|
|
||||||
m_nodeExplorer->setRecycleBinNodeVisible(checked);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -260,15 +253,6 @@ void NotebookExplorer::newFolder()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_currentNotebook->isRecycleBinNode(node)) {
|
|
||||||
node = m_currentNotebook->getRootNode().data();
|
|
||||||
} else if (m_currentNotebook->isNodeInRecycleBin(node)) {
|
|
||||||
MessageBoxHelper::notify(MessageBoxHelper::Information,
|
|
||||||
tr("Could not create folder within Recycle Bin."),
|
|
||||||
VNoteX::getInst().getMainWindow());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
NewFolderDialog dialog(node, VNoteX::getInst().getMainWindow());
|
NewFolderDialog dialog(node, VNoteX::getInst().getMainWindow());
|
||||||
if (dialog.exec() == QDialog::Accepted) {
|
if (dialog.exec() == QDialog::Accepted) {
|
||||||
m_nodeExplorer->setCurrentNode(dialog.getNewNode().data());
|
m_nodeExplorer->setCurrentNode(dialog.getNewNode().data());
|
||||||
@ -282,15 +266,6 @@ void NotebookExplorer::newNote()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_currentNotebook->isRecycleBinNode(node)) {
|
|
||||||
node = m_currentNotebook->getRootNode().data();
|
|
||||||
} else if (m_currentNotebook->isNodeInRecycleBin(node)) {
|
|
||||||
MessageBoxHelper::notify(MessageBoxHelper::Information,
|
|
||||||
tr("Could not create note within Recycle Bin."),
|
|
||||||
VNoteX::getInst().getMainWindow());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
NewNoteDialog dialog(node, VNoteX::getInst().getMainWindow());
|
NewNoteDialog dialog(node, VNoteX::getInst().getMainWindow());
|
||||||
if (dialog.exec() == QDialog::Accepted) {
|
if (dialog.exec() == QDialog::Accepted) {
|
||||||
m_nodeExplorer->setCurrentNode(dialog.getNewNode().data());
|
m_nodeExplorer->setCurrentNode(dialog.getNewNode().data());
|
||||||
@ -340,15 +315,6 @@ void NotebookExplorer::importFile()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_currentNotebook->isRecycleBinNode(node)) {
|
|
||||||
node = m_currentNotebook->getRootNode().data();
|
|
||||||
} else if (m_currentNotebook->isNodeInRecycleBin(node)) {
|
|
||||||
MessageBoxHelper::notify(MessageBoxHelper::Information,
|
|
||||||
tr("Could not create note within Recycle Bin."),
|
|
||||||
VNoteX::getInst().getMainWindow());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QString lastFolderPath = QDir::homePath();
|
static QString lastFolderPath = QDir::homePath();
|
||||||
QStringList files = QFileDialog::getOpenFileNames(VNoteX::getInst().getMainWindow(),
|
QStringList files = QFileDialog::getOpenFileNames(VNoteX::getInst().getMainWindow(),
|
||||||
tr("Select Files To Import"),
|
tr("Select Files To Import"),
|
||||||
@ -381,15 +347,6 @@ void NotebookExplorer::importFolder()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_currentNotebook->isRecycleBinNode(node)) {
|
|
||||||
node = m_currentNotebook->getRootNode().data();
|
|
||||||
} else if (m_currentNotebook->isNodeInRecycleBin(node)) {
|
|
||||||
MessageBoxHelper::notify(MessageBoxHelper::Information,
|
|
||||||
tr("Could not create folder within Recycle Bin."),
|
|
||||||
VNoteX::getInst().getMainWindow());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImportFolderDialog dialog(node, VNoteX::getInst().getMainWindow());
|
ImportFolderDialog dialog(node, VNoteX::getInst().getMainWindow());
|
||||||
if (dialog.exec() == QDialog::Accepted) {
|
if (dialog.exec() == QDialog::Accepted) {
|
||||||
m_nodeExplorer->setCurrentNode(dialog.getNewNode().data());
|
m_nodeExplorer->setCurrentNode(dialog.getNewNode().data());
|
||||||
@ -483,6 +440,33 @@ void NotebookExplorer::setupViewMenu(QMenu *p_menu)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NotebookExplorer::setupRecycleBinMenu(QMenu *p_menu)
|
||||||
|
{
|
||||||
|
p_menu->addAction(tr("Open Recycle Bin"),
|
||||||
|
this,
|
||||||
|
[this]() {
|
||||||
|
if (m_currentNotebook) {
|
||||||
|
WidgetUtils::openUrlByDesktop(QUrl::fromLocalFile(m_currentNotebook->getRecycleBinFolderAbsolutePath()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
p_menu->addAction(tr("Empty Recycle Bin"),
|
||||||
|
this,
|
||||||
|
[this]() {
|
||||||
|
if (!m_currentNotebook) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int okRet = MessageBoxHelper::questionOkCancel(MessageBoxHelper::Warning,
|
||||||
|
tr("Empty the recycle bin of notebook (%1)?").arg(m_currentNotebook->getName()),
|
||||||
|
tr("CAUTION! All the files under the recycle bin folder will be deleted and unrecoverable!"),
|
||||||
|
tr("Recycle bin folder: %1").arg(m_currentNotebook->getRecycleBinFolderAbsolutePath()),
|
||||||
|
VNoteX::getInst().getMainWindow());
|
||||||
|
if (okRet == QMessageBox::Ok) {
|
||||||
|
m_currentNotebook->emptyRecycleBin();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void NotebookExplorer::saveSession()
|
void NotebookExplorer::saveSession()
|
||||||
{
|
{
|
||||||
updateSession();
|
updateSession();
|
||||||
|
@ -69,6 +69,8 @@ namespace vnotex
|
|||||||
|
|
||||||
void setupViewMenu(QMenu *p_menu);
|
void setupViewMenu(QMenu *p_menu);
|
||||||
|
|
||||||
|
void setupRecycleBinMenu(QMenu *p_menu);
|
||||||
|
|
||||||
void saveSession();
|
void saveSession();
|
||||||
|
|
||||||
void loadSession();
|
void loadSession();
|
||||||
|
@ -192,13 +192,11 @@ void NotebookNodeExplorer::initNodeIcons() const
|
|||||||
|
|
||||||
const QString folderIconName("folder_node.svg");
|
const QString folderIconName("folder_node.svg");
|
||||||
const QString fileIconName("file_node.svg");
|
const QString fileIconName("file_node.svg");
|
||||||
const QString recycleBinIconName("recycle_bin.svg");
|
|
||||||
|
|
||||||
s_nodeIcons[NodeIcon::FolderNode] = IconUtils::fetchIcon(themeMgr.getIconFile(folderIconName), fg);
|
s_nodeIcons[NodeIcon::FolderNode] = IconUtils::fetchIcon(themeMgr.getIconFile(folderIconName), fg);
|
||||||
s_nodeIcons[NodeIcon::FileNode] = IconUtils::fetchIcon(themeMgr.getIconFile(fileIconName), fg);
|
s_nodeIcons[NodeIcon::FileNode] = IconUtils::fetchIcon(themeMgr.getIconFile(fileIconName), fg);
|
||||||
s_nodeIcons[NodeIcon::InvalidFolderNode] = IconUtils::fetchIcon(themeMgr.getIconFile(folderIconName), invalidFg);
|
s_nodeIcons[NodeIcon::InvalidFolderNode] = IconUtils::fetchIcon(themeMgr.getIconFile(folderIconName), invalidFg);
|
||||||
s_nodeIcons[NodeIcon::InvalidFileNode] = IconUtils::fetchIcon(themeMgr.getIconFile(fileIconName), invalidFg);
|
s_nodeIcons[NodeIcon::InvalidFileNode] = IconUtils::fetchIcon(themeMgr.getIconFile(fileIconName), invalidFg);
|
||||||
s_nodeIcons[NodeIcon::RecycleBinNode] = IconUtils::fetchIcon(themeMgr.getIconFile(recycleBinIconName), fg);
|
|
||||||
s_nodeIcons[NodeIcon::ExternalFolderNode] = IconUtils::fetchIcon(themeMgr.getIconFile(folderIconName), externalFg);
|
s_nodeIcons[NodeIcon::ExternalFolderNode] = IconUtils::fetchIcon(themeMgr.getIconFile(folderIconName), externalFg);
|
||||||
s_nodeIcons[NodeIcon::ExternalFileNode] = IconUtils::fetchIcon(themeMgr.getIconFile(fileIconName), externalFg);
|
s_nodeIcons[NodeIcon::ExternalFileNode] = IconUtils::fetchIcon(themeMgr.getIconFile(fileIconName), externalFg);
|
||||||
}
|
}
|
||||||
@ -341,7 +339,6 @@ void NotebookNodeExplorer::generateNodeTree()
|
|||||||
if (currentNode) {
|
if (currentNode) {
|
||||||
setCurrentNode(currentNode);
|
setCurrentNode(currentNode);
|
||||||
} else {
|
} else {
|
||||||
// Do not focus the recycle bin.
|
|
||||||
focusNormalNode();
|
focusNormalNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,12 +349,6 @@ void NotebookNodeExplorer::loadRootNode(const Node *p_node) const
|
|||||||
{
|
{
|
||||||
Q_ASSERT(p_node->isLoaded() && p_node->isContainer());
|
Q_ASSERT(p_node->isLoaded() && p_node->isContainer());
|
||||||
|
|
||||||
// Render recycle bin node first.
|
|
||||||
auto recycleBinNode = m_notebook->getRecycleBinNode();
|
|
||||||
if (recycleBinNode) {
|
|
||||||
loadRecycleBinNode(recycleBinNode.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
// External children.
|
// External children.
|
||||||
if (m_externalFilesVisible) {
|
if (m_externalFilesVisible) {
|
||||||
auto externalChildren = p_node->fetchExternalChildren();
|
auto externalChildren = p_node->fetchExternalChildren();
|
||||||
@ -372,10 +363,6 @@ void NotebookNodeExplorer::loadRootNode(const Node *p_node) const
|
|||||||
auto children = p_node->getChildren();
|
auto children = p_node->getChildren();
|
||||||
sortNodes(children);
|
sortNodes(children);
|
||||||
for (const auto &child : children) {
|
for (const auto &child : children) {
|
||||||
if (recycleBinNode == child) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto item = new QTreeWidgetItem(m_masterExplorer);
|
auto item = new QTreeWidgetItem(m_masterExplorer);
|
||||||
loadNode(item, child.data(), 1);
|
loadNode(item, child.data(), 1);
|
||||||
}
|
}
|
||||||
@ -444,43 +431,6 @@ void NotebookNodeExplorer::loadChildren(QTreeWidgetItem *p_item, Node *p_node, i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotebookNodeExplorer::loadRecycleBinNode(Node *p_node) const
|
|
||||||
{
|
|
||||||
if (!m_recycleBinNodeVisible) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto item = new QTreeWidgetItem();
|
|
||||||
item->setWhatsThis(Column::Name,
|
|
||||||
tr("Recycle bin of this notebook. Deleted files could be found here. "
|
|
||||||
"It is organized in folders named by date. Nodes could be moved to "
|
|
||||||
"other folders by Cut and Paste."));
|
|
||||||
m_masterExplorer->insertTopLevelItem(0, item);
|
|
||||||
|
|
||||||
loadRecycleBinNode(item, p_node, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotebookNodeExplorer::loadRecycleBinNode(QTreeWidgetItem *p_item, Node *p_node, int p_level) const
|
|
||||||
{
|
|
||||||
if (!m_recycleBinNodeVisible) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!p_node->isLoaded()) {
|
|
||||||
p_node->load();
|
|
||||||
}
|
|
||||||
|
|
||||||
clearTreeWigetItemChildren(p_item);
|
|
||||||
|
|
||||||
setItemNodeData(p_item, NodeData(p_node, true));
|
|
||||||
p_item->setText(Column::Name, tr("Recycle Bin"));
|
|
||||||
p_item->setIcon(Column::Name, getNodeItemIcon(p_node));
|
|
||||||
|
|
||||||
loadChildren(p_item, p_node, p_level - 1);
|
|
||||||
|
|
||||||
// No need to restore state.
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotebookNodeExplorer::fillTreeItem(QTreeWidgetItem *p_item, Node *p_node, bool p_loaded) const
|
void NotebookNodeExplorer::fillTreeItem(QTreeWidgetItem *p_item, Node *p_node, bool p_loaded) const
|
||||||
{
|
{
|
||||||
setItemNodeData(p_item, NodeData(p_node, p_loaded));
|
setItemNodeData(p_item, NodeData(p_node, p_loaded));
|
||||||
@ -502,10 +452,6 @@ const QIcon &NotebookNodeExplorer::getNodeItemIcon(const Node *p_node) const
|
|||||||
if (p_node->hasContent()) {
|
if (p_node->hasContent()) {
|
||||||
return p_node->exists() ? s_nodeIcons[NodeIcon::FileNode] : s_nodeIcons[NodeIcon::InvalidFileNode];
|
return p_node->exists() ? s_nodeIcons[NodeIcon::FileNode] : s_nodeIcons[NodeIcon::InvalidFileNode];
|
||||||
} else {
|
} else {
|
||||||
if (p_node->getUse() == Node::Use::RecycleBin) {
|
|
||||||
return s_nodeIcons[NodeIcon::RecycleBinNode];
|
|
||||||
}
|
|
||||||
|
|
||||||
return p_node->exists() ? s_nodeIcons[NodeIcon::FolderNode] : s_nodeIcons[NodeIcon::InvalidFolderNode];
|
return p_node->exists() ? s_nodeIcons[NodeIcon::FolderNode] : s_nodeIcons[NodeIcon::InvalidFolderNode];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -561,20 +507,9 @@ void NotebookNodeExplorer::updateNode(Node *p_node)
|
|||||||
if (item) {
|
if (item) {
|
||||||
bool expanded = item->isExpanded();
|
bool expanded = item->isExpanded();
|
||||||
item->setExpanded(false);
|
item->setExpanded(false);
|
||||||
|
|
||||||
if (m_notebook->isRecycleBinNode(p_node)) {
|
|
||||||
loadRecycleBinNode(item, p_node, 1);
|
|
||||||
} else {
|
|
||||||
loadNode(item, p_node, 1);
|
loadNode(item, p_node, 1);
|
||||||
}
|
|
||||||
|
|
||||||
item->setExpanded(expanded);
|
item->setExpanded(expanded);
|
||||||
} else {
|
} else {
|
||||||
if (m_notebook->isRecycleBinNode(p_node) && !m_recycleBinNodeVisible) {
|
|
||||||
// No need to update.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
saveNotebookTreeState(false);
|
saveNotebookTreeState(false);
|
||||||
|
|
||||||
generateNodeTree();
|
generateNodeTree();
|
||||||
@ -762,49 +697,7 @@ void NotebookNodeExplorer::createContextMenuOnRoot(QMenu *p_menu)
|
|||||||
void NotebookNodeExplorer::createContextMenuOnNode(QMenu *p_menu, const Node *p_node)
|
void NotebookNodeExplorer::createContextMenuOnNode(QMenu *p_menu, const Node *p_node)
|
||||||
{
|
{
|
||||||
const int selectedSize = m_masterExplorer->selectedItems().size();
|
const int selectedSize = m_masterExplorer->selectedItems().size();
|
||||||
if (m_notebook->isRecycleBinNode(p_node)) {
|
|
||||||
// Recycle bin node.
|
|
||||||
createAndAddAction(Action::Reload, p_menu);
|
|
||||||
|
|
||||||
createAndAddAction(Action::ReloadIndex, p_menu);
|
|
||||||
|
|
||||||
if (selectedSize == 1) {
|
|
||||||
createAndAddAction(Action::EmptyRecycleBin, p_menu);
|
|
||||||
|
|
||||||
createAndAddAction(Action::OpenLocation, p_menu);
|
|
||||||
}
|
|
||||||
} else if (m_notebook->isNodeInRecycleBin(p_node)) {
|
|
||||||
// Node in recycle bin.
|
|
||||||
createAndAddAction(Action::Open, p_menu);
|
|
||||||
|
|
||||||
addOpenWithMenu(p_menu);
|
|
||||||
|
|
||||||
p_menu->addSeparator();
|
|
||||||
|
|
||||||
if (selectedSize == 1 && p_node->isContainer()) {
|
|
||||||
createAndAddAction(Action::ExpandAll, p_menu);
|
|
||||||
}
|
|
||||||
|
|
||||||
p_menu->addSeparator();
|
|
||||||
|
|
||||||
createAndAddAction(Action::Cut, p_menu);
|
|
||||||
|
|
||||||
createAndAddAction(Action::DeleteFromRecycleBin, p_menu);
|
|
||||||
|
|
||||||
p_menu->addSeparator();
|
|
||||||
|
|
||||||
createAndAddAction(Action::Reload, p_menu);
|
|
||||||
|
|
||||||
createAndAddAction(Action::ReloadIndex, p_menu);
|
|
||||||
|
|
||||||
if (selectedSize == 1) {
|
|
||||||
p_menu->addSeparator();
|
|
||||||
|
|
||||||
createAndAddAction(Action::CopyPath, p_menu);
|
|
||||||
|
|
||||||
createAndAddAction(Action::OpenLocation, p_menu);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
createAndAddAction(Action::Open, p_menu);
|
createAndAddAction(Action::Open, p_menu);
|
||||||
|
|
||||||
addOpenWithMenu(p_menu);
|
addOpenWithMenu(p_menu);
|
||||||
@ -862,7 +755,6 @@ void NotebookNodeExplorer::createContextMenuOnNode(QMenu *p_menu, const Node *p_
|
|||||||
|
|
||||||
createAndAddAction(Action::Properties, p_menu);
|
createAndAddAction(Action::Properties, p_menu);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotebookNodeExplorer::createContextMenuOnExternalNode(QMenu *p_menu, const ExternalNode *p_node)
|
void NotebookNodeExplorer::createContextMenuOnExternalNode(QMenu *p_menu, const ExternalNode *p_node)
|
||||||
@ -901,7 +793,7 @@ QAction *NotebookNodeExplorer::createAction(Action p_act, QObject *p_parent)
|
|||||||
switch (p_act) {
|
switch (p_act) {
|
||||||
case Action::NewNote:
|
case Action::NewNote:
|
||||||
act = new QAction(generateMenuActionIcon("new_note.svg"),
|
act = new QAction(generateMenuActionIcon("new_note.svg"),
|
||||||
tr("New N&ote"),
|
tr("New &Note"),
|
||||||
p_parent);
|
p_parent);
|
||||||
connect(act, &QAction::triggered,
|
connect(act, &QAction::triggered,
|
||||||
this, []() {
|
this, []() {
|
||||||
@ -1033,47 +925,10 @@ QAction *NotebookNodeExplorer::createAction(Action p_act, QObject *p_parent)
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Action::EmptyRecycleBin:
|
|
||||||
act = new QAction(tr("&Empty"), p_parent);
|
|
||||||
connect(act, &QAction::triggered,
|
|
||||||
this, [this]() {
|
|
||||||
auto rbNode = m_notebook->getRecycleBinNode().data();
|
|
||||||
auto rbNodePath = rbNode->fetchAbsolutePath();
|
|
||||||
int ret = MessageBoxHelper::questionOkCancel(MessageBoxHelper::Warning,
|
|
||||||
tr("Empty the recycle bin of this notebook?"),
|
|
||||||
tr("All files in recycle bin will be deleted permanently."),
|
|
||||||
tr("Location of recycle bin: %1").arg(rbNodePath));
|
|
||||||
if (ret != QMessageBox::Ok) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
m_notebook->emptyNode(rbNode, true);
|
|
||||||
} catch (Exception &p_e) {
|
|
||||||
MessageBoxHelper::notify(MessageBoxHelper::Critical,
|
|
||||||
tr("Failed to empty recycle bin (%1) (%2).").arg(rbNodePath, p_e.what()),
|
|
||||||
VNoteX::getInst().getMainWindow());
|
|
||||||
}
|
|
||||||
|
|
||||||
updateNode(rbNode);
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Action::Delete:
|
case Action::Delete:
|
||||||
act = new QAction(tr("&Delete"), p_parent);
|
act = new QAction(tr("&Delete"), p_parent);
|
||||||
connect(act, &QAction::triggered,
|
connect(act, &QAction::triggered,
|
||||||
this, [this]() {
|
this, &NotebookNodeExplorer::removeSelectedNodes);
|
||||||
removeSelectedNodes(false);
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Action::DeleteFromRecycleBin:
|
|
||||||
// It is fine to have &D with Action::Delete since they won't be at the same context.
|
|
||||||
act = new QAction(tr("&Delete From Recycle Bin"), p_parent);
|
|
||||||
connect(act, &QAction::triggered,
|
|
||||||
this, [this]() {
|
|
||||||
removeSelectedNodes(true);
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Action::RemoveFromConfig:
|
case Action::RemoveFromConfig:
|
||||||
@ -1417,21 +1272,12 @@ void NotebookNodeExplorer::selectNodes(const QVector<const Node *> &p_nodes)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotebookNodeExplorer::removeSelectedNodes(bool p_skipRecycleBin)
|
void NotebookNodeExplorer::removeSelectedNodes()
|
||||||
{
|
{
|
||||||
QString text;
|
const QString text = tr("Delete these folders and notes?");
|
||||||
QString info;
|
const QString info = tr("Deleted files could be found in the recycle bin of notebook.");
|
||||||
if (p_skipRecycleBin) {
|
|
||||||
text = tr("Delete these folders and notes permanently?");
|
|
||||||
info = tr("Files will be deleted permanently and could not be found even "
|
|
||||||
"in operating system's recycle bin.");
|
|
||||||
} else {
|
|
||||||
text = tr("Delete these folders and notes?");
|
|
||||||
info = tr("Deleted files could be found in the recycle bin of notebook.");
|
|
||||||
}
|
|
||||||
|
|
||||||
auto nodes = confirmSelectedNodes(tr("Confirm Deletion"), text, info);
|
auto nodes = confirmSelectedNodes(tr("Confirm Deletion"), text, info);
|
||||||
removeNodes(nodes, p_skipRecycleBin, false);
|
removeNodes(nodes, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<Node *> NotebookNodeExplorer::confirmSelectedNodes(const QString &p_title,
|
QVector<Node *> NotebookNodeExplorer::confirmSelectedNodes(const QString &p_title,
|
||||||
@ -1471,9 +1317,7 @@ QVector<Node *> NotebookNodeExplorer::confirmSelectedNodes(const QString &p_titl
|
|||||||
return nodesToDelete;
|
return nodesToDelete;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotebookNodeExplorer::removeNodes(QVector<Node *> p_nodes,
|
void NotebookNodeExplorer::removeNodes(QVector<Node *> p_nodes, bool p_configOnly)
|
||||||
bool p_skipRecycleBin,
|
|
||||||
bool p_configOnly)
|
|
||||||
{
|
{
|
||||||
if (p_nodes.isEmpty()) {
|
if (p_nodes.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
@ -1494,8 +1338,8 @@ void NotebookNodeExplorer::removeNodes(QVector<Node *> p_nodes,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_configOnly || p_skipRecycleBin) {
|
if (p_configOnly) {
|
||||||
m_notebook->removeNode(node, false, p_configOnly);
|
m_notebook->removeNode(node, false, true);
|
||||||
} else {
|
} else {
|
||||||
m_notebook->moveNodeToRecycleBin(node);
|
m_notebook->moveNodeToRecycleBin(node);
|
||||||
}
|
}
|
||||||
@ -1515,10 +1359,6 @@ void NotebookNodeExplorer::removeNodes(QVector<Node *> p_nodes,
|
|||||||
updateNode(node);
|
updateNode(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!p_configOnly && !p_skipRecycleBin && m_recycleBinNodeVisible) {
|
|
||||||
updateNode(m_notebook->getRecycleBinNode().data());
|
|
||||||
}
|
|
||||||
|
|
||||||
VNoteX::getInst().showStatusMessageShort(tr("Deleted/Removed %n item(s)", "", nrDeleted));
|
VNoteX::getInst().showStatusMessageShort(tr("Deleted/Removed %n item(s)", "", nrDeleted));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1527,7 +1367,7 @@ void NotebookNodeExplorer::removeSelectedNodesFromConfig()
|
|||||||
auto nodes = confirmSelectedNodes(tr("Confirm Removal"),
|
auto nodes = confirmSelectedNodes(tr("Confirm Removal"),
|
||||||
tr("Remove these folders and notes from index?"),
|
tr("Remove these folders and notes from index?"),
|
||||||
tr("Files are not touched but just removed from notebook index."));
|
tr("Files are not touched but just removed from notebook index."));
|
||||||
removeNodes(nodes, false, true);
|
removeNodes(nodes, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotebookNodeExplorer::filterAwayChildrenNodes(QVector<Node *> &p_nodes)
|
void NotebookNodeExplorer::filterAwayChildrenNodes(QVector<Node *> &p_nodes)
|
||||||
@ -1569,29 +1409,6 @@ bool NotebookNodeExplorer::allSelectedItemsSameType() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == NodeData::NodeType::Node) {
|
|
||||||
bool hasNormalNode = false;
|
|
||||||
bool hasNodeInRecycleBin = false;
|
|
||||||
for (auto &item : items) {
|
|
||||||
auto node = getItemNodeData(item).getNode();
|
|
||||||
if (m_notebook->isRecycleBinNode(node)) {
|
|
||||||
return false;
|
|
||||||
} else if (m_notebook->isNodeInRecycleBin(node)) {
|
|
||||||
if (hasNormalNode) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
hasNodeInRecycleBin = true;
|
|
||||||
} else {
|
|
||||||
if (hasNodeInRecycleBin) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
hasNormalNode = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1603,12 +1420,11 @@ void NotebookNodeExplorer::reload()
|
|||||||
void NotebookNodeExplorer::focusNormalNode()
|
void NotebookNodeExplorer::focusNormalNode()
|
||||||
{
|
{
|
||||||
auto item = m_masterExplorer->currentItem();
|
auto item = m_masterExplorer->currentItem();
|
||||||
if (item && (!m_recycleBinNodeVisible || item != m_masterExplorer->topLevelItem(0))) {
|
if (item) {
|
||||||
// Not recycle bin.
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_masterExplorer->setCurrentItem(m_masterExplorer->topLevelItem(m_recycleBinNodeVisible ? 1 : 0));
|
m_masterExplorer->setCurrentItem(m_masterExplorer->topLevelItem(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotebookNodeExplorer::sortNodes(QVector<QSharedPointer<Node>> &p_nodes) const
|
void NotebookNodeExplorer::sortNodes(QVector<QSharedPointer<Node>> &p_nodes) const
|
||||||
@ -1688,16 +1504,6 @@ void NotebookNodeExplorer::sortNodes(QVector<QSharedPointer<Node>> &p_nodes, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotebookNodeExplorer::setRecycleBinNodeVisible(bool p_visible)
|
|
||||||
{
|
|
||||||
if (m_recycleBinNodeVisible == p_visible) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_recycleBinNodeVisible = p_visible;
|
|
||||||
reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotebookNodeExplorer::setExternalFilesVisible(bool p_visible)
|
void NotebookNodeExplorer::setExternalFilesVisible(bool p_visible)
|
||||||
{
|
{
|
||||||
if (m_externalFilesVisible == p_visible) {
|
if (m_externalFilesVisible == p_visible) {
|
||||||
@ -1748,11 +1554,7 @@ void NotebookNodeExplorer::manualSort()
|
|||||||
const auto &children = parentNode->getChildrenRef();
|
const auto &children = parentNode->getChildrenRef();
|
||||||
for (int i = 0; i < children.size(); ++i) {
|
for (int i = 0; i < children.size(); ++i) {
|
||||||
const auto &child = children[i];
|
const auto &child = children[i];
|
||||||
if (m_notebook->isRecycleBinNode(child.data())) {
|
const bool selected = sortFolders ? child->isContainer() : !child->isContainer();
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool selected = sortFolders ? child->isContainer() : !child->isContainer();
|
|
||||||
if (selected) {
|
if (selected) {
|
||||||
selectedIdx.push_back(i);
|
selectedIdx.push_back(i);
|
||||||
|
|
||||||
|
@ -103,8 +103,6 @@ namespace vnotex
|
|||||||
|
|
||||||
void reload();
|
void reload();
|
||||||
|
|
||||||
void setRecycleBinNodeVisible(bool p_visible);
|
|
||||||
|
|
||||||
void setViewOrder(int p_order);
|
void setViewOrder(int p_order);
|
||||||
|
|
||||||
void setExternalFilesVisible(bool p_visible);
|
void setExternalFilesVisible(bool p_visible);
|
||||||
@ -146,9 +144,7 @@ namespace vnotex
|
|||||||
Copy,
|
Copy,
|
||||||
Cut,
|
Cut,
|
||||||
Paste,
|
Paste,
|
||||||
EmptyRecycleBin,
|
|
||||||
Delete,
|
Delete,
|
||||||
DeleteFromRecycleBin,
|
|
||||||
RemoveFromConfig,
|
RemoveFromConfig,
|
||||||
Sort,
|
Sort,
|
||||||
Reload,
|
Reload,
|
||||||
@ -180,10 +176,6 @@ namespace vnotex
|
|||||||
|
|
||||||
void loadNode(QTreeWidgetItem *p_item, const QSharedPointer<ExternalNode> &p_node) const;
|
void loadNode(QTreeWidgetItem *p_item, const QSharedPointer<ExternalNode> &p_node) const;
|
||||||
|
|
||||||
void loadRecycleBinNode(Node *p_node) const;
|
|
||||||
|
|
||||||
void loadRecycleBinNode(QTreeWidgetItem *p_item, Node *p_node, int p_level) const;
|
|
||||||
|
|
||||||
void fillTreeItem(QTreeWidgetItem *p_item, Node *p_node, bool p_loaded) const;
|
void fillTreeItem(QTreeWidgetItem *p_item, Node *p_node, bool p_loaded) const;
|
||||||
|
|
||||||
void fillTreeItem(QTreeWidgetItem *p_item, const QSharedPointer<ExternalNode> &p_node) const;
|
void fillTreeItem(QTreeWidgetItem *p_item, const QSharedPointer<ExternalNode> &p_node) const;
|
||||||
@ -225,7 +217,7 @@ namespace vnotex
|
|||||||
|
|
||||||
QPair<QVector<Node *>, QVector<QSharedPointer<ExternalNode>>> getSelectedNodes() const;
|
QPair<QVector<Node *>, QVector<QSharedPointer<ExternalNode>>> getSelectedNodes() const;
|
||||||
|
|
||||||
void removeSelectedNodes(bool p_skipRecycleBin);
|
void removeSelectedNodes();
|
||||||
|
|
||||||
void removeSelectedNodesFromConfig();
|
void removeSelectedNodesFromConfig();
|
||||||
|
|
||||||
@ -241,8 +233,7 @@ namespace vnotex
|
|||||||
|
|
||||||
void selectNodes(const QVector<const Node *> &p_nodes);
|
void selectNodes(const QVector<const Node *> &p_nodes);
|
||||||
|
|
||||||
// @p_skipRecycleBin is irrelevant if @p_configOnly is true.
|
void removeNodes(QVector<Node *> p_nodes, bool p_configOnly);
|
||||||
void removeNodes(QVector<Node *> p_nodes, bool p_skipRecycleBin, bool p_configOnly);
|
|
||||||
|
|
||||||
void filterAwayChildrenNodes(QVector<Node *> &p_nodes);
|
void filterAwayChildrenNodes(QVector<Node *> &p_nodes);
|
||||||
|
|
||||||
@ -251,7 +242,6 @@ namespace vnotex
|
|||||||
// Check if all selected items are the same type for operations.
|
// Check if all selected items are the same type for operations.
|
||||||
bool allSelectedItemsSameType() const;
|
bool allSelectedItemsSameType() const;
|
||||||
|
|
||||||
// Skip the recycle bin node if possible.
|
|
||||||
void focusNormalNode();
|
void focusNormalNode();
|
||||||
|
|
||||||
void sortNodes(QVector<QSharedPointer<Node>> &p_nodes) const;
|
void sortNodes(QVector<QSharedPointer<Node>> &p_nodes) const;
|
||||||
@ -298,8 +288,6 @@ namespace vnotex
|
|||||||
|
|
||||||
QScopedPointer<NavigationModeWrapper<QTreeWidget, QTreeWidgetItem>> m_navigationWrapper;
|
QScopedPointer<NavigationModeWrapper<QTreeWidget, QTreeWidgetItem>> m_navigationWrapper;
|
||||||
|
|
||||||
bool m_recycleBinNodeVisible = false;
|
|
||||||
|
|
||||||
int m_viewOrder = ViewOrder::OrderedByConfiguration;
|
int m_viewOrder = ViewOrder::OrderedByConfiguration;
|
||||||
|
|
||||||
bool m_externalFilesVisible = true;
|
bool m_externalFilesVisible = true;
|
||||||
@ -312,7 +300,6 @@ namespace vnotex
|
|||||||
FileNode,
|
FileNode,
|
||||||
InvalidFolderNode,
|
InvalidFolderNode,
|
||||||
InvalidFileNode,
|
InvalidFileNode,
|
||||||
RecycleBinNode,
|
|
||||||
ExternalFolderNode,
|
ExternalFolderNode,
|
||||||
ExternalFileNode,
|
ExternalFileNode,
|
||||||
MaxIcons
|
MaxIcons
|
||||||
|
@ -448,7 +448,7 @@ SearchState SearchPanel::search(const QSharedPointer<SearchOption> &p_option)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
auto folder = m_provider->getCurrentFolder();
|
auto folder = m_provider->getCurrentFolder();
|
||||||
if (folder && (folder->isRoot() || notebook->isRecycleBinNode(folder))) {
|
if (folder && (folder->isRoot())) {
|
||||||
folder = nullptr;
|
folder = nullptr;
|
||||||
}
|
}
|
||||||
if (!folder) {
|
if (!folder) {
|
||||||
|
@ -239,11 +239,6 @@ void TagExplorer::updateNodeList(const QString &p_tag)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_notebook->isNodeInRecycleBin(node.data())) {
|
|
||||||
qDebug() << "skipped node in recycle bin" << p_tag << pa;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto item = new QListWidgetItem(m_nodeList);
|
auto item = new QListWidgetItem(m_nodeList);
|
||||||
item->setText(node->getName());
|
item->setText(node->getName());
|
||||||
item->setToolTip(NotebookNodeExplorer::generateToolTip(node.data()));
|
item->setToolTip(NotebookNodeExplorer::generateToolTip(node.data()));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user