mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 22:09:52 +08:00
support recycle bin folder for extern files
1. Add external_recycle_bin_folder config; 2. By default, each external file will use _v_recycle_bin in the same directory as its recycle bin folder to hold deleted images;
This commit is contained in:
parent
6f1cab39ba
commit
e5cd014762
@ -113,6 +113,9 @@ markdownit_opt_linkify=true
|
|||||||
; Default name of the recycle bin of notebook
|
; Default name of the recycle bin of notebook
|
||||||
recycle_bin_folder=_v_recycle_bin
|
recycle_bin_folder=_v_recycle_bin
|
||||||
|
|
||||||
|
; Default name of the recycle bin of external files
|
||||||
|
external_recycle_bin_folder=_v_recycle_bin
|
||||||
|
|
||||||
; Confirm before deleting unused images
|
; Confirm before deleting unused images
|
||||||
confirm_images_clean_up=true
|
confirm_images_clean_up=true
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#include <QRegExp>
|
#include <QRegExp>
|
||||||
#include <QKeySequence>
|
#include <QKeySequence>
|
||||||
|
|
||||||
#include "vfile.h"
|
#include "vorphanfile.h"
|
||||||
#include "vnote.h"
|
#include "vnote.h"
|
||||||
#include "vnotebook.h"
|
#include "vnotebook.h"
|
||||||
#include "hgmarkdownhighlighter.h"
|
#include "hgmarkdownhighlighter.h"
|
||||||
@ -740,13 +740,6 @@ QString VUtils::getShortcutText(const QString &p_keySeq)
|
|||||||
return QKeySequence(p_keySeq).toString(QKeySequence::NativeText);
|
return QKeySequence(p_keySeq).toString(QKeySequence::NativeText);
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString getRecycleBinSubFolderToUse(const VNotebook *p_notebook)
|
|
||||||
{
|
|
||||||
QString folderPath = p_notebook->getRecycleBinFolderPath();
|
|
||||||
QDir dir(folderPath);
|
|
||||||
return QDir::cleanPath(dir.absoluteFilePath(QDateTime::currentDateTime().toString("yyyyMMdd")));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VUtils::deleteDirectory(const VNotebook *p_notebook,
|
bool VUtils::deleteDirectory(const VNotebook *p_notebook,
|
||||||
const QString &p_path,
|
const QString &p_path,
|
||||||
bool p_skipRecycleBin)
|
bool p_skipRecycleBin)
|
||||||
@ -756,25 +749,7 @@ bool VUtils::deleteDirectory(const VNotebook *p_notebook,
|
|||||||
return dir.removeRecursively();
|
return dir.removeRecursively();
|
||||||
} else {
|
} else {
|
||||||
// Move it to the recycle bin folder.
|
// Move it to the recycle bin folder.
|
||||||
QString binPath = getRecycleBinSubFolderToUse(p_notebook);
|
return deleteFile(p_notebook->getRecycleBinFolderPath(), p_path);
|
||||||
QDir binDir(binPath);
|
|
||||||
if (!binDir.exists()) {
|
|
||||||
binDir.mkpath(binPath);
|
|
||||||
if (!binDir.exists()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString destName = getFileNameWithSequence(binPath,
|
|
||||||
directoryNameFromPath(p_path));
|
|
||||||
|
|
||||||
qDebug() << "try to move" << p_path << "to" << binPath << "as" << destName;
|
|
||||||
if (!binDir.rename(p_path, binDir.filePath(destName))) {
|
|
||||||
qWarning() << "fail to move directory" << p_path << "to" << binDir.filePath(destName);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -815,41 +790,53 @@ bool VUtils::deleteFile(const VNotebook *p_notebook,
|
|||||||
return file.remove();
|
return file.remove();
|
||||||
} else {
|
} else {
|
||||||
// Move it to the recycle bin folder.
|
// Move it to the recycle bin folder.
|
||||||
QString binPath = getRecycleBinSubFolderToUse(p_notebook);
|
return deleteFile(p_notebook->getRecycleBinFolderPath(), p_path);
|
||||||
QDir binDir(binPath);
|
|
||||||
if (!binDir.exists()) {
|
|
||||||
binDir.mkpath(binPath);
|
|
||||||
if (!binDir.exists()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString destName = getFileNameWithSequence(binPath,
|
|
||||||
fileNameFromPath(p_path));
|
|
||||||
|
|
||||||
qDebug() << "try to move" << p_path << "to" << binPath << "as" << destName;
|
|
||||||
if (!binDir.rename(p_path, binDir.filePath(destName))) {
|
|
||||||
qWarning() << "fail to move file" << p_path << "to" << binDir.filePath(destName);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VUtils::deleteFile(const QString &p_path,
|
bool VUtils::deleteFile(const VOrphanFile *p_file,
|
||||||
|
const QString &p_path,
|
||||||
bool p_skipRecycleBin)
|
bool p_skipRecycleBin)
|
||||||
{
|
{
|
||||||
if (p_skipRecycleBin) {
|
if (p_skipRecycleBin) {
|
||||||
QFile file(p_path);
|
QFile file(p_path);
|
||||||
return file.remove();
|
return file.remove();
|
||||||
} else {
|
} else {
|
||||||
// TODO: Move it to the recycle bin folder.
|
// Move it to the recycle bin folder.
|
||||||
QFile file(p_path);
|
return deleteFile(p_file->fetchRecycleBinFolderPath(), p_path);
|
||||||
return file.remove();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QString getRecycleBinSubFolderToUse(const QString &p_folderPath)
|
||||||
|
{
|
||||||
|
QDir dir(p_folderPath);
|
||||||
|
return QDir::cleanPath(dir.absoluteFilePath(QDateTime::currentDateTime().toString("yyyyMMdd")));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VUtils::deleteFile(const QString &p_recycleBinFolderPath,
|
||||||
|
const QString &p_path)
|
||||||
|
{
|
||||||
|
QString binPath = getRecycleBinSubFolderToUse(p_recycleBinFolderPath);
|
||||||
|
QDir binDir(binPath);
|
||||||
|
if (!binDir.exists()) {
|
||||||
|
binDir.mkpath(binPath);
|
||||||
|
if (!binDir.exists()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString destName = getFileNameWithSequence(binPath,
|
||||||
|
fileNameFromPath(p_path));
|
||||||
|
|
||||||
|
qDebug() << "try to move" << p_path << "to" << binPath << "as" << destName;
|
||||||
|
if (!binDir.rename(p_path, binDir.filePath(destName))) {
|
||||||
|
qWarning() << "fail to move" << p_path << "to" << binDir.filePath(destName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
QVector<VElementRegion> VUtils::fetchImageRegionsUsingParser(const QString &p_content)
|
QVector<VElementRegion> VUtils::fetchImageRegionsUsingParser(const QString &p_content)
|
||||||
{
|
{
|
||||||
Q_ASSERT(!p_content.isEmpty());
|
Q_ASSERT(!p_content.isEmpty());
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
class QKeyEvent;
|
class QKeyEvent;
|
||||||
class VFile;
|
class VFile;
|
||||||
|
class VOrphanFile;
|
||||||
class VNotebook;
|
class VNotebook;
|
||||||
|
|
||||||
#if !defined(V_ASSERT)
|
#if !defined(V_ASSERT)
|
||||||
@ -151,9 +152,10 @@ public:
|
|||||||
bool p_skipRecycleBin = false);
|
bool p_skipRecycleBin = false);
|
||||||
|
|
||||||
// Delete file specified by @p_path.
|
// Delete file specified by @p_path.
|
||||||
// Will just move the file to the recycle bin of VNote if
|
// Will just move the file to the recycle bin of VOrphanFile if
|
||||||
// @p_skipRecycleBin is false.
|
// @p_skipRecycleBin is false.
|
||||||
static bool deleteFile(const QString &p_path,
|
static bool deleteFile(const VOrphanFile *p_file,
|
||||||
|
const QString &p_path,
|
||||||
bool p_skipRecycleBin = false);
|
bool p_skipRecycleBin = false);
|
||||||
|
|
||||||
static QString displayDateTime(const QDateTime &p_dateTime);
|
static QString displayDateTime(const QDateTime &p_dateTime);
|
||||||
@ -203,6 +205,11 @@ private:
|
|||||||
// Use HGMarkdownParser to parse @p_content to get all image link regions.
|
// Use HGMarkdownParser to parse @p_content to get all image link regions.
|
||||||
static QVector<VElementRegion> fetchImageRegionsUsingParser(const QString &p_content);
|
static QVector<VElementRegion> fetchImageRegionsUsingParser(const QString &p_content);
|
||||||
|
|
||||||
|
// Delete file/directory specified by @p_path by moving it to the recycle bin
|
||||||
|
// folder @p_recycleBinFolderPath.
|
||||||
|
static bool deleteFile(const QString &p_recycleBinFolderPath,
|
||||||
|
const QString &p_path);
|
||||||
|
|
||||||
// <value, name>
|
// <value, name>
|
||||||
static QVector<QPair<QString, QString>> s_availableLanguages;
|
static QVector<QPair<QString, QString>> s_availableLanguages;
|
||||||
};
|
};
|
||||||
|
@ -208,6 +208,9 @@ void VConfigManager::initialize()
|
|||||||
m_recycleBinFolder = getConfigFromSettings("global",
|
m_recycleBinFolder = getConfigFromSettings("global",
|
||||||
"recycle_bin_folder").toString();
|
"recycle_bin_folder").toString();
|
||||||
|
|
||||||
|
m_recycleBinFolderExt = getConfigFromSettings("global",
|
||||||
|
"external_recycle_bin_folder").toString();
|
||||||
|
|
||||||
m_confirmImagesCleanUp = getConfigFromSettings("global",
|
m_confirmImagesCleanUp = getConfigFromSettings("global",
|
||||||
"confirm_images_clean_up").toBool();
|
"confirm_images_clean_up").toBool();
|
||||||
|
|
||||||
|
@ -271,6 +271,8 @@ public:
|
|||||||
|
|
||||||
const QString &getRecycleBinFolder() const;
|
const QString &getRecycleBinFolder() const;
|
||||||
|
|
||||||
|
const QString &getRecycleBinFolderExt() const;
|
||||||
|
|
||||||
bool getConfirmImagesCleanUp() const;
|
bool getConfirmImagesCleanUp() const;
|
||||||
void setConfirmImagesCleanUp(bool p_enabled);
|
void setConfirmImagesCleanUp(bool p_enabled);
|
||||||
|
|
||||||
@ -553,6 +555,9 @@ private:
|
|||||||
// Default name of the recycle bin folder of notebook.
|
// Default name of the recycle bin folder of notebook.
|
||||||
QString m_recycleBinFolder;
|
QString m_recycleBinFolder;
|
||||||
|
|
||||||
|
// Default name of the recycle bin folder of external files.
|
||||||
|
QString m_recycleBinFolderExt;
|
||||||
|
|
||||||
// Confirm before deleting unused images.
|
// Confirm before deleting unused images.
|
||||||
bool m_confirmImagesCleanUp;
|
bool m_confirmImagesCleanUp;
|
||||||
|
|
||||||
@ -1439,6 +1444,11 @@ inline const QString &VConfigManager::getRecycleBinFolder() const
|
|||||||
return m_recycleBinFolder;
|
return m_recycleBinFolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const QString &VConfigManager::getRecycleBinFolderExt() const
|
||||||
|
{
|
||||||
|
return m_recycleBinFolderExt;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool VConfigManager::getConfirmImagesCleanUp() const
|
inline bool VConfigManager::getConfirmImagesCleanUp() const
|
||||||
{
|
{
|
||||||
return m_confirmImagesCleanUp;
|
return m_confirmImagesCleanUp;
|
||||||
|
@ -146,6 +146,33 @@ void VEditWindow::initTabActions()
|
|||||||
QUrl url = QUrl::fromLocalFile(file->fetchBasePath());
|
QUrl url = QUrl::fromLocalFile(file->fetchBasePath());
|
||||||
QDesktopServices::openUrl(url);
|
QDesktopServices::openUrl(url);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
m_recycleBinAct = new QAction(QIcon(":/resources/icons/recycle_bin.svg"),
|
||||||
|
tr("&Recycle Bin"), this);
|
||||||
|
m_recycleBinAct->setToolTip(tr("Open the recycle bin of this note"));
|
||||||
|
connect(m_recycleBinAct, &QAction::triggered,
|
||||||
|
this, [this]() {
|
||||||
|
int tab = this->m_closeTabAct->data().toInt();
|
||||||
|
Q_ASSERT(tab != -1);
|
||||||
|
|
||||||
|
VEditTab *editor = getTab(tab);
|
||||||
|
VFile *file = editor->getFile();
|
||||||
|
Q_ASSERT(file);
|
||||||
|
|
||||||
|
QString folderPath;
|
||||||
|
if (file->getType() == FileType::Note) {
|
||||||
|
const VNoteFile *tmpFile = dynamic_cast<const VNoteFile *>((VFile *)file);
|
||||||
|
folderPath = tmpFile->getNotebook()->getRecycleBinFolderPath();
|
||||||
|
} else if (file->getType() == FileType::Orphan) {
|
||||||
|
const VOrphanFile *tmpFile = dynamic_cast<const VOrphanFile *>((VFile *)file);
|
||||||
|
folderPath = tmpFile->fetchRecycleBinFolderPath();
|
||||||
|
} else {
|
||||||
|
Q_ASSERT(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
QUrl url = QUrl::fromLocalFile(folderPath);
|
||||||
|
QDesktopServices::openUrl(url);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void VEditWindow::setupCornerWidget()
|
void VEditWindow::setupCornerWidget()
|
||||||
@ -560,6 +587,11 @@ void VEditWindow::tabbarContextMenuRequested(QPoint p_pos)
|
|||||||
m_locateAct->setData(tab);
|
m_locateAct->setData(tab);
|
||||||
menu.addAction(m_locateAct);
|
menu.addAction(m_locateAct);
|
||||||
|
|
||||||
|
menu.addSeparator();
|
||||||
|
|
||||||
|
m_recycleBinAct->setData(tab);
|
||||||
|
menu.addAction(m_recycleBinAct);
|
||||||
|
|
||||||
m_openLocationAct->setData(tab);
|
m_openLocationAct->setData(tab);
|
||||||
menu.addAction(m_openLocationAct);
|
menu.addAction(m_openLocationAct);
|
||||||
|
|
||||||
@ -567,6 +599,9 @@ void VEditWindow::tabbarContextMenuRequested(QPoint p_pos)
|
|||||||
menu.addAction(m_noteInfoAct);
|
menu.addAction(m_noteInfoAct);
|
||||||
} else if (file->getType() == FileType::Orphan
|
} else if (file->getType() == FileType::Orphan
|
||||||
&& !(dynamic_cast<VOrphanFile *>(file)->isSystemFile())) {
|
&& !(dynamic_cast<VOrphanFile *>(file)->isSystemFile())) {
|
||||||
|
m_recycleBinAct->setData(tab);
|
||||||
|
menu.addAction(m_recycleBinAct);
|
||||||
|
|
||||||
m_openLocationAct->setData(tab);
|
m_openLocationAct->setData(tab);
|
||||||
menu.addAction(m_openLocationAct);
|
menu.addAction(m_openLocationAct);
|
||||||
|
|
||||||
|
@ -177,6 +177,9 @@ private:
|
|||||||
|
|
||||||
// Open the location (the folder containing this file) of this note.
|
// Open the location (the folder containing this file) of this note.
|
||||||
QAction *m_openLocationAct;
|
QAction *m_openLocationAct;
|
||||||
|
|
||||||
|
// Open the recycle bin folder of this note.
|
||||||
|
QAction *m_recycleBinAct;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline QString VEditWindow::generateTooltip(const VFile *p_file) const
|
inline QString VEditWindow::generateTooltip(const VFile *p_file) const
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "dialog/vconfirmdeletiondialog.h"
|
#include "dialog/vconfirmdeletiondialog.h"
|
||||||
#include "vimagepreviewer.h"
|
#include "vimagepreviewer.h"
|
||||||
#include "vtextblockdata.h"
|
#include "vtextblockdata.h"
|
||||||
|
#include "vorphanfile.h"
|
||||||
|
|
||||||
extern VConfigManager *g_config;
|
extern VConfigManager *g_config;
|
||||||
extern VNote *g_vnote;
|
extern VNote *g_vnote;
|
||||||
@ -308,8 +309,11 @@ void VMdEdit::clearUnusedImages()
|
|||||||
if (m_file->getType() == FileType::Note) {
|
if (m_file->getType() == FileType::Note) {
|
||||||
const VNoteFile *tmpFile = dynamic_cast<const VNoteFile *>((VFile *)m_file);
|
const VNoteFile *tmpFile = dynamic_cast<const VNoteFile *>((VFile *)m_file);
|
||||||
ret = VUtils::deleteFile(tmpFile->getNotebook(), unusedImages[i], false);
|
ret = VUtils::deleteFile(tmpFile->getNotebook(), unusedImages[i], false);
|
||||||
|
} else if (m_file->getType() == FileType::Orphan) {
|
||||||
|
const VOrphanFile *tmpFile = dynamic_cast<const VOrphanFile *>((VFile *)m_file);
|
||||||
|
ret = VUtils::deleteFile(tmpFile, unusedImages[i], false);
|
||||||
} else {
|
} else {
|
||||||
ret = VUtils::deleteFile(unusedImages[i], false);
|
Q_ASSERT(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
|
@ -67,3 +67,18 @@ QString VOrphanFile::getImageFolderInLink() const
|
|||||||
|
|
||||||
return folder;
|
return folder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString VOrphanFile::fetchRecycleBinFolderPath() const
|
||||||
|
{
|
||||||
|
QString folder = m_recycleBinFolder;
|
||||||
|
if (m_recycleBinFolder.isEmpty()) {
|
||||||
|
folder = g_config->getRecycleBinFolderExt();
|
||||||
|
}
|
||||||
|
|
||||||
|
QFileInfo fi(folder);
|
||||||
|
if (fi.isAbsolute()) {
|
||||||
|
return folder;
|
||||||
|
} else {
|
||||||
|
return QDir(fetchBasePath()).filePath(folder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -35,6 +35,9 @@ public:
|
|||||||
|
|
||||||
bool isSystemFile() const;
|
bool isSystemFile() const;
|
||||||
|
|
||||||
|
// Get the recycle bin folder for this file.
|
||||||
|
QString fetchRecycleBinFolderPath() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Full path of this file.
|
// Full path of this file.
|
||||||
QString m_path;
|
QString m_path;
|
||||||
@ -45,6 +48,12 @@ private:
|
|||||||
// Valid only within a session.
|
// Valid only within a session.
|
||||||
QString m_imageFolder;
|
QString m_imageFolder;
|
||||||
|
|
||||||
|
// Recycle bin forlder.
|
||||||
|
// May be absolute or relative path.
|
||||||
|
// Empty to use the global default config.
|
||||||
|
// Valid only within a session.
|
||||||
|
QString m_recycleBinFolder;
|
||||||
|
|
||||||
// Whether it is a system internal file.
|
// Whether it is a system internal file.
|
||||||
bool m_systemFile;
|
bool m_systemFile;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user