mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
add recycle bin to each notebook
This commit is contained in:
parent
4626673925
commit
35fa0a46f6
@ -4,11 +4,12 @@
|
|||||||
|
|
||||||
extern VConfigManager *g_config;
|
extern VConfigManager *g_config;
|
||||||
|
|
||||||
VDeleteNotebookDialog::VDeleteNotebookDialog(const QString &p_title, const QString &p_name,
|
VDeleteNotebookDialog::VDeleteNotebookDialog(const QString &p_title,
|
||||||
const QString &p_path, QWidget *p_parent)
|
const VNotebook *p_notebook,
|
||||||
: QDialog(p_parent), m_path(p_path)
|
QWidget *p_parent)
|
||||||
|
: QDialog(p_parent), m_notebook(p_notebook)
|
||||||
{
|
{
|
||||||
setupUI(p_title, p_name);
|
setupUI(p_title, m_notebook->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
void VDeleteNotebookDialog::setupUI(const QString &p_title, const QString &p_name)
|
void VDeleteNotebookDialog::setupUI(const QString &p_title, const QString &p_name)
|
||||||
@ -20,7 +21,7 @@ void VDeleteNotebookDialog::setupUI(const QString &p_title, const QString &p_nam
|
|||||||
|
|
||||||
m_deleteCheck = new QCheckBox(tr("Delete files from disk"), this);
|
m_deleteCheck = new QCheckBox(tr("Delete files from disk"), this);
|
||||||
m_deleteCheck->setChecked(false);
|
m_deleteCheck->setChecked(false);
|
||||||
m_deleteCheck->setToolTip(tr("When checked, VNote will delete all the files within this notebook from disk"));
|
m_deleteCheck->setToolTip(tr("When checked, VNote will delete all files (including Recycle Bin) of this notebook from disk"));
|
||||||
connect(m_deleteCheck, &QCheckBox::stateChanged,
|
connect(m_deleteCheck, &QCheckBox::stateChanged,
|
||||||
this, &VDeleteNotebookDialog::deleteCheckChanged);
|
this, &VDeleteNotebookDialog::deleteCheckChanged);
|
||||||
|
|
||||||
@ -109,12 +110,16 @@ void VDeleteNotebookDialog::deleteCheckChanged(int p_state)
|
|||||||
{
|
{
|
||||||
if (!p_state) {
|
if (!p_state) {
|
||||||
m_warningLabel->setText(tr("VNote won't delete files in directory <span style=\"%1\">%2</span>.")
|
m_warningLabel->setText(tr("VNote won't delete files in directory <span style=\"%1\">%2</span>.")
|
||||||
.arg(g_config->c_dataTextStyle).arg(m_path));
|
.arg(g_config->c_dataTextStyle).arg(m_notebook->getPath()));
|
||||||
} else {
|
} else {
|
||||||
m_warningLabel->setText(tr("<span style=\"%1\">WARNING</span>: "
|
m_warningLabel->setText(tr("<span style=\"%1\">WARNING</span>: "
|
||||||
"VNote may delete <b>ANY</b> files in directory <span style=\"%2\">%3</span>! "
|
"VNote may delete <b>ANY</b> files in directory <span style=\"%2\">%3</span> "
|
||||||
"VNote will try to delete all the root folders within this notebook one by one. "
|
"and directory <span style=\"%2\">%4</span>!<br>"
|
||||||
|
"VNote will try to delete all the root folders within this notebook one by one.<br>"
|
||||||
"It may be UNRECOVERABLE!")
|
"It may be UNRECOVERABLE!")
|
||||||
.arg(g_config->c_warningTextStyle).arg(g_config->c_dataTextStyle).arg(m_path));
|
.arg(g_config->c_warningTextStyle)
|
||||||
|
.arg(g_config->c_dataTextStyle)
|
||||||
|
.arg(m_notebook->getPath())
|
||||||
|
.arg(m_notebook->getRecycleBinFolderPath()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,12 +9,14 @@ class QLineEdit;
|
|||||||
class QString;
|
class QString;
|
||||||
class QCheckBox;
|
class QCheckBox;
|
||||||
class QDialogButtonBox;
|
class QDialogButtonBox;
|
||||||
|
class VNotebook;
|
||||||
|
|
||||||
class VDeleteNotebookDialog : public QDialog
|
class VDeleteNotebookDialog : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
VDeleteNotebookDialog(const QString &p_title, const QString &p_name, const QString &p_path,
|
VDeleteNotebookDialog(const QString &p_title,
|
||||||
|
const VNotebook *p_notebook,
|
||||||
QWidget *p_parent = 0);
|
QWidget *p_parent = 0);
|
||||||
|
|
||||||
// Whether delete files from disk.
|
// Whether delete files from disk.
|
||||||
@ -27,7 +29,7 @@ private:
|
|||||||
void setupUI(const QString &p_title, const QString &p_name);
|
void setupUI(const QString &p_title, const QString &p_name);
|
||||||
QPixmap standardIcon(QMessageBox::Icon p_icon);
|
QPixmap standardIcon(QMessageBox::Icon p_icon);
|
||||||
|
|
||||||
QString m_path;
|
const VNotebook *m_notebook;
|
||||||
QLabel *m_warningLabel;
|
QLabel *m_warningLabel;
|
||||||
QCheckBox *m_deleteCheck;
|
QCheckBox *m_deleteCheck;
|
||||||
QDialogButtonBox *m_btnBox;
|
QDialogButtonBox *m_btnBox;
|
||||||
|
@ -72,7 +72,8 @@ void VDirInfoDialog::handleInputChanged()
|
|||||||
if (nameOk && name != m_directory->getName()) {
|
if (nameOk && name != m_directory->getName()) {
|
||||||
// Check if the name conflicts with existing directory name.
|
// Check if the name conflicts with existing directory name.
|
||||||
// Case-insensitive when creating note.
|
// Case-insensitive when creating note.
|
||||||
if (m_parentDirectory->findSubDirectory(name, false)) {
|
const VDirectory *directory = m_parentDirectory->findSubDirectory(name, false);
|
||||||
|
if (directory && directory != m_directory) {
|
||||||
nameOk = false;
|
nameOk = false;
|
||||||
showWarnLabel = true;
|
showWarnLabel = true;
|
||||||
QString nameConflictText = tr("<span style=\"%1\">WARNING</span>: Name (case-insensitive) already exists. "
|
QString nameConflictText = tr("<span style=\"%1\">WARNING</span>: Name (case-insensitive) already exists. "
|
||||||
|
@ -89,7 +89,8 @@ void VFileInfoDialog::handleInputChanged()
|
|||||||
if (nameOk && name != m_file->getName()) {
|
if (nameOk && name != m_file->getName()) {
|
||||||
// Check if the name conflicts with existing note name.
|
// Check if the name conflicts with existing note name.
|
||||||
// Case-insensitive when creating note.
|
// Case-insensitive when creating note.
|
||||||
if (m_directory->findFile(name, false)) {
|
const VFile *file = m_directory->findFile(name, false);
|
||||||
|
if (file && file != m_file) {
|
||||||
nameOk = false;
|
nameOk = false;
|
||||||
showWarnLabel = true;
|
showWarnLabel = true;
|
||||||
QString nameConflictText = tr("<span style=\"%1\">WARNING</span>: Name (case-insensitive) already exists. "
|
QString nameConflictText = tr("<span style=\"%1\">WARNING</span>: Name (case-insensitive) already exists. "
|
||||||
|
@ -42,9 +42,11 @@ void VNotebookInfoDialog::setupUI(const QString &p_title, const QString &p_info)
|
|||||||
"(empty to use global configuration)"));
|
"(empty to use global configuration)"));
|
||||||
QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), m_imageFolderEdit);
|
QValidator *validator = new QRegExpValidator(QRegExp(VUtils::c_fileNameRegExp), m_imageFolderEdit);
|
||||||
m_imageFolderEdit->setValidator(validator);
|
m_imageFolderEdit->setValidator(validator);
|
||||||
QLabel *imageFolderLabel = new QLabel(tr("&Image folder:"));
|
|
||||||
imageFolderLabel->setBuddy(m_imageFolderEdit);
|
// Recycle bin folder.
|
||||||
imageFolderLabel->setToolTip(m_imageFolderEdit->toolTip());
|
QLineEdit *recycleBinFolderEdit = new QLineEdit(m_notebook->getRecycleBinFolder());
|
||||||
|
recycleBinFolderEdit->setReadOnly(true);
|
||||||
|
recycleBinFolderEdit->setToolTip(tr("The folder to hold deleted files from within VNote"));
|
||||||
|
|
||||||
// Created time.
|
// Created time.
|
||||||
QString createdTimeStr = const_cast<VNotebook *>(m_notebook)->getCreatedTimeUtc().toLocalTime()
|
QString createdTimeStr = const_cast<VNotebook *>(m_notebook)->getCreatedTimeUtc().toLocalTime()
|
||||||
@ -54,7 +56,8 @@ void VNotebookInfoDialog::setupUI(const QString &p_title, const QString &p_info)
|
|||||||
QFormLayout *topLayout = new QFormLayout();
|
QFormLayout *topLayout = new QFormLayout();
|
||||||
topLayout->addRow(tr("Notebook &name:"), m_nameEdit);
|
topLayout->addRow(tr("Notebook &name:"), m_nameEdit);
|
||||||
topLayout->addRow(tr("Notebook &root folder:"), m_pathEdit);
|
topLayout->addRow(tr("Notebook &root folder:"), m_pathEdit);
|
||||||
topLayout->addRow(imageFolderLabel, m_imageFolderEdit);
|
topLayout->addRow(tr("&Image folder:"), m_imageFolderEdit);
|
||||||
|
topLayout->addRow(tr("Recycle bin folder:"), recycleBinFolderEdit);
|
||||||
topLayout->addRow(tr("Created time:"), createdTimeLabel);
|
topLayout->addRow(tr("Created time:"), createdTimeLabel);
|
||||||
|
|
||||||
// Warning label.
|
// Warning label.
|
||||||
@ -100,7 +103,7 @@ void VNotebookInfoDialog::handleInputChanged()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idx < m_notebooks.size()) {
|
if (idx < m_notebooks.size() && m_notebooks[idx] != m_notebook) {
|
||||||
nameOk = false;
|
nameOk = false;
|
||||||
showWarnLabel = true;
|
showWarnLabel = true;
|
||||||
QString nameConflictText = tr("<span style=\"%1\">WARNING</span>: Name (case-insensitive) already exists. "
|
QString nameConflictText = tr("<span style=\"%1\">WARNING</span>: Name (case-insensitive) already exists. "
|
||||||
|
9
src/resources/icons/empty_recycle_bin.svg
Normal file
9
src/resources/icons/empty_recycle_bin.svg
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<g display="inline">
|
||||||
|
<title>Layer 1</title>
|
||||||
|
<path id="svg_6" fill-opacity="0" d="m85.75,73.84658l43.19437,360.59092l241.12296,0l43.05767,-361.68444l-327.375,1.09352z" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="30" fill="#000000" stroke="#000000"/>
|
||||||
|
</g>
|
||||||
|
<g display="inline">
|
||||||
|
<title>Layer 1 copy</title>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 478 B |
10
src/resources/icons/recycle_bin.svg
Normal file
10
src/resources/icons/recycle_bin.svg
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<g display="inline">
|
||||||
|
<title>Layer 1</title>
|
||||||
|
<path stroke="#000000" fill="#000000" stroke-width="30" stroke-dasharray="null" stroke-linejoin="null" stroke-linecap="null" d="m85.750002,73.846584l43.194363,360.590916l241.122963,0l43.057672,-361.684444l-327.374998,1.093528z" fill-opacity="0" id="svg_6"/>
|
||||||
|
</g>
|
||||||
|
<g display="inline">
|
||||||
|
<title>Layer 1 copy</title>
|
||||||
|
<path id="svg_1" d="m278.734806,211.081489l-25.954577,-4.596678l9.562217,-4.993052c5.259196,-2.746226 10.027709,-5.404751 10.596662,-5.907837c1.413302,-1.249639 -16.187262,-28.447523 -18.394639,-28.425008c-0.970333,0.011001 -7.731781,10.542547 -15.025414,23.405944c-7.346415,12.956287 -14.657734,22.823491 -16.392375,22.122467c-20.530561,-8.296065 -37.281946,-16.689857 -37.281946,-18.681204c0,-1.360192 6.441626,-13.493725 14.314808,-26.963432l14.314815,-24.490333l39.029834,0l39.029834,0l10.187868,16.112893l10.187953,16.112893l10.628269,-5.452618c7.367742,-3.779934 10.17318,-4.322708 9.144661,-1.769575c-9.05562,22.481975 -22.568035,48.696355 -24.969931,48.442064c-1.662917,-0.175921 -14.703002,-2.388389 -28.978031,-4.916514l-0.000008,-0.000008zm-121.04853,100.301702c-9.877208,-17.009348 -18.729478,-32.934982 -19.671623,-35.390403c-0.966907,-2.519616 1.850192,-11.523045 6.467384,-20.669546l8.180422,-16.205438l-8.362438,-4.939858c-11.12868,-6.573858 -6.992066,-8.598561 22.529168,-11.027127l23.331407,-1.919317l9.151668,24.180839c5.033491,13.299451 9.795749,25.898384 10.582909,27.997793c0.820922,2.189446 -3.107919,0.732693 -9.21387,-3.416409l-10.645019,-7.233539l-7.43104,14.344659c-4.086999,7.889694 -7.488988,15.223935 -7.559854,16.298312c-0.071034,1.074377 12.472696,2.303847 27.874729,2.732066l28.003626,0.778551l1.827516,20.484288c1.005176,11.266424 1.619826,20.634873 1.366026,20.818805c-0.253785,0.183748 -13.513894,1.179924 -29.466873,2.213472l-29.005467,1.879108l-17.958669,-30.926279l0,0.000023zm110.540841,30.053665c-16.956491,-25.592907 -17.251221,-23.689252 7.951467,-51.353217l16.178415,-17.758401l-1.718289,12.977292l-1.718366,12.9773l18.129745,0c9.97134,0 18.129837,-0.797417 18.129837,-1.771913c0,-0.974657 -5.532483,-11.921252 -12.294352,-24.32608c-6.761869,-12.404828 -12.268679,-23.594376 -12.237409,-24.86568c0.070206,-2.850622 35.51503,-26.389649 37.20008,-24.704623c0.667669,0.667677 7.245506,12.559246 14.617434,26.425987l13.403679,25.21188l-18.035023,29.09066c-9.91941,15.999665 -19.449767,30.651136 -21.178467,32.558624c-1.728899,1.907488 -11.395904,4.238849 -21.482319,5.180634c-19.252488,1.797909 -18.728389,1.364868 -21.551245,17.805095c-0.493994,2.877139 -6.254444,-3.65119 -15.395187,-17.447572l0,0.000015z" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="50" fill="black"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
@ -107,6 +107,9 @@ markdownit_opt_breaks=false
|
|||||||
; Auto-convert URL-like text to links
|
; Auto-convert URL-like text to links
|
||||||
markdownit_opt_linkify=true
|
markdownit_opt_linkify=true
|
||||||
|
|
||||||
|
; Default name of the recycle bin of notebook
|
||||||
|
recycle_bin_folder=_v_recycle_bin
|
||||||
|
|
||||||
[session]
|
[session]
|
||||||
tools_dock_checked=true
|
tools_dock_checked=true
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "vfile.h"
|
#include "vfile.h"
|
||||||
#include "vnote.h"
|
#include "vnote.h"
|
||||||
|
#include "vnotebook.h"
|
||||||
|
|
||||||
extern VConfigManager *g_config;
|
extern VConfigManager *g_config;
|
||||||
|
|
||||||
@ -718,3 +719,100 @@ 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,
|
||||||
|
const QString &p_path,
|
||||||
|
bool p_skipRecycleBin)
|
||||||
|
{
|
||||||
|
if (p_skipRecycleBin) {
|
||||||
|
QDir dir(p_path);
|
||||||
|
return dir.removeRecursively();
|
||||||
|
} else {
|
||||||
|
// Move it to the recycle bin folder.
|
||||||
|
QString binPath = getRecycleBinSubFolderToUse(p_notebook);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VUtils::emptyDirectory(const VNotebook *p_notebook,
|
||||||
|
const QString &p_path,
|
||||||
|
bool p_skipRecycleBin)
|
||||||
|
{
|
||||||
|
QDir dir(p_path);
|
||||||
|
if (!dir.exists()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFileInfoList nodes = dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::Hidden
|
||||||
|
| QDir::NoSymLinks | QDir::NoDotAndDotDot);
|
||||||
|
for (int i = 0; i < nodes.size(); ++i) {
|
||||||
|
const QFileInfo &fileInfo = nodes.at(i);
|
||||||
|
if (fileInfo.isDir()) {
|
||||||
|
if (!deleteDirectory(p_notebook, fileInfo.absoluteFilePath(), p_skipRecycleBin)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Q_ASSERT(fileInfo.isFile());
|
||||||
|
if (!deleteFile(p_notebook, fileInfo.absoluteFilePath(), p_skipRecycleBin)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VUtils::deleteFile(const VNotebook *p_notebook,
|
||||||
|
const QString &p_path,
|
||||||
|
bool p_skipRecycleBin)
|
||||||
|
{
|
||||||
|
if (p_skipRecycleBin) {
|
||||||
|
QFile file(p_path);
|
||||||
|
return file.remove();
|
||||||
|
} else {
|
||||||
|
// Move it to the recycle bin folder.
|
||||||
|
QString binPath = getRecycleBinSubFolderToUse(p_notebook);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
class QKeyEvent;
|
class QKeyEvent;
|
||||||
class VFile;
|
class VFile;
|
||||||
|
class VNotebook;
|
||||||
|
|
||||||
#if !defined(V_ASSERT)
|
#if !defined(V_ASSERT)
|
||||||
#define V_ASSERT(cond) ((!(cond)) ? qt_assert(#cond, __FILE__, __LINE__) : qt_noop())
|
#define V_ASSERT(cond) ((!(cond)) ? qt_assert(#cond, __FILE__, __LINE__) : qt_noop())
|
||||||
@ -124,6 +125,27 @@ public:
|
|||||||
// Returns the shortcut text.
|
// Returns the shortcut text.
|
||||||
static QString getShortcutText(const QString &p_keySeq);
|
static QString getShortcutText(const QString &p_keySeq);
|
||||||
|
|
||||||
|
// Delete directory recursively specified by @p_path.
|
||||||
|
// Will just move the directory to the recycle bin of @p_notebook if
|
||||||
|
// @p_skipRecycleBin is false.
|
||||||
|
static bool deleteDirectory(const VNotebook *p_notebook,
|
||||||
|
const QString &p_path,
|
||||||
|
bool p_skipRecycleBin = false);
|
||||||
|
|
||||||
|
// Empty all files in directory recursively specified by @p_path.
|
||||||
|
// Will just move files to the recycle bin of @p_notebook if
|
||||||
|
// @p_skipRecycleBin is false.
|
||||||
|
static bool emptyDirectory(const VNotebook *p_notebook,
|
||||||
|
const QString &p_path,
|
||||||
|
bool p_skipRecycleBin = false);
|
||||||
|
|
||||||
|
// Delete file specified by @p_path.
|
||||||
|
// Will just move the file to the recycle bin of @p_notebook if
|
||||||
|
// @p_skipRecycleBin is false.
|
||||||
|
static bool deleteFile(const VNotebook *p_notebook,
|
||||||
|
const QString &p_path,
|
||||||
|
bool p_skipRecycleBin = false);
|
||||||
|
|
||||||
// Regular expression for image link.
|
// Regular expression for image link.
|
||||||
// 
|
// 
|
||||||
// Captured texts (need to be trimmed):
|
// Captured texts (need to be trimmed):
|
||||||
|
@ -197,6 +197,9 @@ void VConfigManager::initialize()
|
|||||||
|
|
||||||
m_markdownitOptLinkify = getConfigFromSettings("global",
|
m_markdownitOptLinkify = getConfigFromSettings("global",
|
||||||
"markdownit_opt_linkify").toBool();
|
"markdownit_opt_linkify").toBool();
|
||||||
|
|
||||||
|
m_recycleBinFolder = getConfigFromSettings("global",
|
||||||
|
"recycle_bin_folder").toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VConfigManager::readPredefinedColorsFromSettings()
|
void VConfigManager::readPredefinedColorsFromSettings()
|
||||||
|
@ -264,6 +264,8 @@ public:
|
|||||||
MarkdownitOption getMarkdownitOption() const;
|
MarkdownitOption getMarkdownitOption() const;
|
||||||
void setMarkdownitOption(const MarkdownitOption &p_opt);
|
void setMarkdownitOption(const MarkdownitOption &p_opt);
|
||||||
|
|
||||||
|
const QString &getRecycleBinFolder() const;
|
||||||
|
|
||||||
// Return the configured key sequence of @p_operation.
|
// Return the configured key sequence of @p_operation.
|
||||||
// Return empty if there is no corresponding config.
|
// Return empty if there is no corresponding config.
|
||||||
QString getShortcutKeySequence(const QString &p_operation) const;
|
QString getShortcutKeySequence(const QString &p_operation) const;
|
||||||
@ -531,6 +533,9 @@ private:
|
|||||||
// Auto-convert URL-like text to links.
|
// Auto-convert URL-like text to links.
|
||||||
bool m_markdownitOptLinkify;
|
bool m_markdownitOptLinkify;
|
||||||
|
|
||||||
|
// Default name of the recycle bin folder of notebook.
|
||||||
|
QString m_recycleBinFolder;
|
||||||
|
|
||||||
// The name of the config file in each directory, obsolete.
|
// The name of the config file in each directory, obsolete.
|
||||||
// Use c_dirConfigFile instead.
|
// Use c_dirConfigFile instead.
|
||||||
static const QString c_obsoleteDirConfigFile;
|
static const QString c_obsoleteDirConfigFile;
|
||||||
@ -1377,4 +1382,9 @@ inline void VConfigManager::setMarkdownitOption(const MarkdownitOption &p_opt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const QString &VConfigManager::getRecycleBinFolder() const
|
||||||
|
{
|
||||||
|
return m_recycleBinFolder;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // VCONFIGMANAGER_H
|
#endif // VCONFIGMANAGER_H
|
||||||
|
@ -30,6 +30,7 @@ namespace DirConfig
|
|||||||
static const QString c_subDirectories = "sub_directories";
|
static const QString c_subDirectories = "sub_directories";
|
||||||
static const QString c_files = "files";
|
static const QString c_files = "files";
|
||||||
static const QString c_imageFolder = "image_folder";
|
static const QString c_imageFolder = "image_folder";
|
||||||
|
static const QString c_recycleBinFolder = "recycle_bin_folder";
|
||||||
static const QString c_name = "name";
|
static const QString c_name = "name";
|
||||||
static const QString c_createdTime = "created_time";
|
static const QString c_createdTime = "created_time";
|
||||||
static const QString c_modifiedTime = "modified_time";
|
static const QString c_modifiedTime = "modified_time";
|
||||||
|
@ -412,20 +412,21 @@ VDirectory *VDirectory::addSubDirectory(const QString &p_name, int p_index)
|
|||||||
return dir;
|
return dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VDirectory::deleteSubDirectory(VDirectory *p_subDir)
|
void VDirectory::deleteSubDirectory(VDirectory *p_subDir, bool p_skipRecycleBin)
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(p_subDir->getNotebook() == m_notebook);
|
||||||
|
|
||||||
QString dirPath = p_subDir->fetchPath();
|
QString dirPath = p_subDir->fetchPath();
|
||||||
|
|
||||||
p_subDir->close();
|
p_subDir->close();
|
||||||
|
|
||||||
removeSubDirectory(p_subDir);
|
removeSubDirectory(p_subDir);
|
||||||
|
|
||||||
// Delete the entire directory
|
// Delete the entire directory.
|
||||||
QDir dir(dirPath);
|
if (!VUtils::deleteDirectory(m_notebook, dirPath, p_skipRecycleBin)) {
|
||||||
if (!dir.removeRecursively()) {
|
|
||||||
qWarning() << "fail to remove directory" << dirPath << "recursively";
|
qWarning() << "fail to remove directory" << dirPath << "recursively";
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "deleted" << dirPath << "from disk";
|
qDebug() << "deleted" << dirPath << (p_skipRecycleBin ? "from disk" : "to recycle bin");
|
||||||
}
|
}
|
||||||
|
|
||||||
delete p_subDir;
|
delete p_subDir;
|
||||||
|
@ -35,7 +35,8 @@ public:
|
|||||||
|
|
||||||
VFile *createFile(const QString &p_name);
|
VFile *createFile(const QString &p_name);
|
||||||
|
|
||||||
void deleteSubDirectory(VDirectory *p_subDir);
|
// Remove and delete subdirectory @p_subDir.
|
||||||
|
void deleteSubDirectory(VDirectory *p_subDir, bool p_skipRecycleBin = false);
|
||||||
|
|
||||||
// Remove the file in the config and m_files without deleting it in the disk.
|
// Remove the file in the config and m_files without deleting it in the disk.
|
||||||
// It won't change the parent of @p_file to enable it find its path.
|
// It won't change the parent of @p_file to enable it find its path.
|
||||||
|
@ -447,9 +447,10 @@ void VDirectoryTree::deleteDirectory()
|
|||||||
tr("Are you sure to delete folder <span style=\"%1\">%2</span>?")
|
tr("Are you sure to delete folder <span style=\"%1\">%2</span>?")
|
||||||
.arg(g_config->c_dataTextStyle).arg(curDir->getName()),
|
.arg(g_config->c_dataTextStyle).arg(curDir->getName()),
|
||||||
tr("<span style=\"%1\">WARNING</span>: "
|
tr("<span style=\"%1\">WARNING</span>: "
|
||||||
"VNote will delete the whole directory (<b>ANY</b> files) "
|
"VNote will delete the whole directory "
|
||||||
"<span style=\"%2\">%3</span>."
|
"<span style=\"%2\">%3</span>."
|
||||||
"<br>It may be UNRECOVERABLE!")
|
"You could find deleted files in the recycle bin "
|
||||||
|
"of this notebook.<br>The operation is IRREVERSIBLE!")
|
||||||
.arg(g_config->c_warningTextStyle).arg(g_config->c_dataTextStyle).arg(curDir->fetchPath()),
|
.arg(g_config->c_warningTextStyle).arg(g_config->c_dataTextStyle).arg(curDir->fetchPath()),
|
||||||
QMessageBox::Ok | QMessageBox::Cancel,
|
QMessageBox::Ok | QMessageBox::Cancel,
|
||||||
QMessageBox::Ok, this, MessageBoxType::Danger);
|
QMessageBox::Ok, this, MessageBoxType::Danger);
|
||||||
|
@ -64,8 +64,7 @@ void VFile::deleteDiskFile()
|
|||||||
|
|
||||||
// Delete the file
|
// Delete the file
|
||||||
QString filePath = fetchPath();
|
QString filePath = fetchPath();
|
||||||
QFile file(filePath);
|
if (VUtils::deleteFile(getNotebook(), filePath, false)) {
|
||||||
if (file.remove()) {
|
|
||||||
qDebug() << "deleted" << filePath;
|
qDebug() << "deleted" << filePath;
|
||||||
} else {
|
} else {
|
||||||
qWarning() << "fail to delete" << filePath;
|
qWarning() << "fail to delete" << filePath;
|
||||||
@ -96,8 +95,7 @@ void VFile::deleteLocalImages()
|
|||||||
ImageLink::LocalRelativeInternal);
|
ImageLink::LocalRelativeInternal);
|
||||||
int deleted = 0;
|
int deleted = 0;
|
||||||
for (int i = 0; i < images.size(); ++i) {
|
for (int i = 0; i < images.size(); ++i) {
|
||||||
QFile file(images[i].m_path);
|
if (VUtils::deleteFile(getNotebook(), images[i].m_path, false)) {
|
||||||
if (file.remove()) {
|
|
||||||
++deleted;
|
++deleted;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -394,8 +394,12 @@ void VFileList::deleteFile(VFile *p_file)
|
|||||||
int ret = VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
|
int ret = VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
|
||||||
tr("Are you sure to delete note <span style=\"%1\">%2</span>?")
|
tr("Are you sure to delete note <span style=\"%1\">%2</span>?")
|
||||||
.arg(g_config->c_dataTextStyle).arg(fileName),
|
.arg(g_config->c_dataTextStyle).arg(fileName),
|
||||||
tr("<span style=\"%1\">WARNING</span>: The files (including images) "
|
tr("<span style=\"%1\">WARNING</span>: "
|
||||||
"deleted may be UNRECOVERABLE!")
|
"VNote will delete the note as well as all "
|
||||||
|
"its images and attachments managed by VNote. "
|
||||||
|
"You could find deleted files in the recycle "
|
||||||
|
"bin of this notebook.<br>"
|
||||||
|
"The operation is IRREVERSIBLE!")
|
||||||
.arg(g_config->c_warningTextStyle),
|
.arg(g_config->c_warningTextStyle),
|
||||||
QMessageBox::Ok | QMessageBox::Cancel,
|
QMessageBox::Ok | QMessageBox::Cancel,
|
||||||
QMessageBox::Ok, this, MessageBoxType::Danger);
|
QMessageBox::Ok, this, MessageBoxType::Danger);
|
||||||
|
@ -34,6 +34,7 @@ class VTabIndicator;
|
|||||||
class VSingleInstanceGuard;
|
class VSingleInstanceGuard;
|
||||||
class QTimer;
|
class QTimer;
|
||||||
class QSystemTrayIcon;
|
class QSystemTrayIcon;
|
||||||
|
class QShortcut;
|
||||||
|
|
||||||
class VMainWindow : public QMainWindow
|
class VMainWindow : public QMainWindow
|
||||||
{
|
{
|
||||||
|
@ -255,7 +255,7 @@ void VMdEdit::clearUnusedImages()
|
|||||||
|
|
||||||
// This inserted image is no longer in the file.
|
// This inserted image is no longer in the file.
|
||||||
if (j == images.size()) {
|
if (j == images.size()) {
|
||||||
if (!QFile(link.m_path).remove()) {
|
if (!VUtils::deleteFile(m_file->getNotebook(), link.m_path, false)) {
|
||||||
qWarning() << "fail to delete unused inserted image" << link.m_path;
|
qWarning() << "fail to delete unused inserted image" << link.m_path;
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "delete unused inserted image" << link.m_path;
|
qDebug() << "delete unused inserted image" << link.m_path;
|
||||||
@ -280,7 +280,7 @@ void VMdEdit::clearUnusedImages()
|
|||||||
|
|
||||||
// Original local relative image is no longer in the file.
|
// Original local relative image is no longer in the file.
|
||||||
if (j == images.size()) {
|
if (j == images.size()) {
|
||||||
if (!QFile(link.m_path).remove()) {
|
if (!VUtils::deleteFile(m_file->getNotebook(), link.m_path, false)) {
|
||||||
qWarning() << "fail to delete unused original image" << link.m_path;
|
qWarning() << "fail to delete unused original image" << link.m_path;
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "delete unused original image" << link.m_path;
|
qDebug() << "delete unused original image" << link.m_path;
|
||||||
|
@ -121,5 +121,7 @@
|
|||||||
<file>resources/docs/markdown_guide_en.md</file>
|
<file>resources/docs/markdown_guide_en.md</file>
|
||||||
<file>resources/docs/markdown_guide_zh.md</file>
|
<file>resources/docs/markdown_guide_zh.md</file>
|
||||||
<file>utils/highlightjs/highlightjs-line-numbers.min.js</file>
|
<file>utils/highlightjs/highlightjs-line-numbers.min.js</file>
|
||||||
|
<file>resources/icons/recycle_bin.svg</file>
|
||||||
|
<file>resources/icons/empty_recycle_bin.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
@ -12,6 +12,7 @@ VNotebook::VNotebook(const QString &name, const QString &path, QObject *parent)
|
|||||||
: QObject(parent), m_name(name)
|
: QObject(parent), m_name(name)
|
||||||
{
|
{
|
||||||
m_path = QDir::cleanPath(path);
|
m_path = QDir::cleanPath(path);
|
||||||
|
m_recycleBinFolder = g_config->getRecycleBinFolder();
|
||||||
m_rootDir = new VDirectory(this,
|
m_rootDir = new VDirectory(this,
|
||||||
VUtils::directoryNameFromPath(path),
|
VUtils::directoryNameFromPath(path),
|
||||||
NULL,
|
NULL,
|
||||||
@ -37,6 +38,12 @@ bool VNotebook::readConfig()
|
|||||||
m_imageFolder = it.value().toString();
|
m_imageFolder = it.value().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// [recycle_bin_folder] section.
|
||||||
|
it = configJson.find(DirConfig::c_recycleBinFolder);
|
||||||
|
if (it != configJson.end()) {
|
||||||
|
m_recycleBinFolder = it.value().toString();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,6 +54,9 @@ QJsonObject VNotebook::toConfigJsonNotebook() const
|
|||||||
// [image_folder] section.
|
// [image_folder] section.
|
||||||
json[DirConfig::c_imageFolder] = m_imageFolder;
|
json[DirConfig::c_imageFolder] = m_imageFolder;
|
||||||
|
|
||||||
|
// [recycle_bin_folder] section.
|
||||||
|
json[DirConfig::c_recycleBinFolder] = m_recycleBinFolder;
|
||||||
|
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,9 +79,9 @@ bool VNotebook::writeToConfig() const
|
|||||||
return VConfigManager::writeDirectoryConfig(m_path, toConfigJson());
|
return VConfigManager::writeDirectoryConfig(m_path, toConfigJson());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VNotebook::writeConfig() const
|
bool VNotebook::writeConfigNotebook() const
|
||||||
{
|
{
|
||||||
QJsonObject json = toConfigJson();
|
QJsonObject nbJson = toConfigJsonNotebook();
|
||||||
|
|
||||||
QJsonObject configJson = VConfigManager::readDirectoryConfig(m_path);
|
QJsonObject configJson = VConfigManager::readDirectoryConfig(m_path);
|
||||||
if (configJson.isEmpty()) {
|
if (configJson.isEmpty()) {
|
||||||
@ -79,10 +89,11 @@ bool VNotebook::writeConfig() const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
json[DirConfig::c_subDirectories] = configJson[DirConfig::c_subDirectories];
|
for (auto it = nbJson.begin(); it != nbJson.end(); ++it) {
|
||||||
json[DirConfig::c_files] = configJson[DirConfig::c_files];
|
configJson[it.key()] = it.value();
|
||||||
|
}
|
||||||
|
|
||||||
return VConfigManager::writeDirectoryConfig(m_path, json);
|
return VConfigManager::writeDirectoryConfig(m_path, configJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString &VNotebook::getName() const
|
const QString &VNotebook::getName() const
|
||||||
@ -102,6 +113,16 @@ void VNotebook::close()
|
|||||||
|
|
||||||
bool VNotebook::open()
|
bool VNotebook::open()
|
||||||
{
|
{
|
||||||
|
QString recycleBinPath = getRecycleBinFolderPath();
|
||||||
|
if (!QFileInfo::exists(recycleBinPath)) {
|
||||||
|
QDir dir(m_path);
|
||||||
|
if (!dir.mkpath(recycleBinPath)) {
|
||||||
|
qWarning() << "fail to create recycle bin folder" << recycleBinPath
|
||||||
|
<< "for notebook" << m_name;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return m_rootDir->open();
|
return m_rootDir->open();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,10 +169,20 @@ bool VNotebook::deleteNotebook(VNotebook *p_notebook, bool p_deleteFiles)
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete sub directories.
|
||||||
VDirectory *rootDir = p_notebook->getRootDir();
|
VDirectory *rootDir = p_notebook->getRootDir();
|
||||||
QVector<VDirectory *> subdirs = rootDir->getSubDirs();
|
QVector<VDirectory *> subdirs = rootDir->getSubDirs();
|
||||||
for (auto dir : subdirs) {
|
for (auto dir : subdirs) {
|
||||||
rootDir->deleteSubDirectory(dir);
|
// Skip recycle bin.
|
||||||
|
rootDir->deleteSubDirectory(dir, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the recycle bin.
|
||||||
|
QDir recycleDir(p_notebook->getRecycleBinFolderPath());
|
||||||
|
if (!recycleDir.removeRecursively()) {
|
||||||
|
qWarning() << "fail to delete notebook recycle bin folder"
|
||||||
|
<< p_notebook->getRecycleBinFolderPath();
|
||||||
|
ret = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete the config file.
|
// Delete the config file.
|
||||||
@ -255,3 +286,13 @@ QDateTime VNotebook::getCreatedTimeUtc()
|
|||||||
|
|
||||||
return m_rootDir->getCreatedTimeUtc();
|
return m_rootDir->getCreatedTimeUtc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString VNotebook::getRecycleBinFolderPath() const
|
||||||
|
{
|
||||||
|
QFileInfo fi(m_recycleBinFolder);
|
||||||
|
if (fi.isAbsolute()) {
|
||||||
|
return m_recycleBinFolder;
|
||||||
|
} else {
|
||||||
|
return QDir(m_path).filePath(m_recycleBinFolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -13,6 +13,7 @@ class VNotebook : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
VNotebook(const QString &name, const QString &path, QObject *parent = 0);
|
VNotebook(const QString &name, const QString &path, QObject *parent = 0);
|
||||||
|
|
||||||
~VNotebook();
|
~VNotebook();
|
||||||
|
|
||||||
// Open the root directory to load contents
|
// Open the root directory to load contents
|
||||||
@ -54,15 +55,20 @@ public:
|
|||||||
// Return m_imageFolder.
|
// Return m_imageFolder.
|
||||||
const QString &getImageFolderConfig() const;
|
const QString &getImageFolderConfig() const;
|
||||||
|
|
||||||
|
// Return m_recycleBinFolder.
|
||||||
|
const QString &getRecycleBinFolder() const;
|
||||||
|
|
||||||
|
// Get the recycle folder path for this notebook to use.
|
||||||
|
QString getRecycleBinFolderPath() const;
|
||||||
|
|
||||||
void setImageFolder(const QString &p_imageFolder);
|
void setImageFolder(const QString &p_imageFolder);
|
||||||
|
|
||||||
// Read configurations (excluding "sub_directories" and "files" section)
|
// Read configurations (excluding "sub_directories" and "files" section)
|
||||||
// from root directory config file.
|
// from root directory config file.
|
||||||
bool readConfig();
|
bool readConfig();
|
||||||
|
|
||||||
// Write configurations (excluding "sub_directories" and "files" section)
|
// Write configurations only related to notebook to root directory config file.
|
||||||
// to root directory config file.
|
bool writeConfigNotebook() const;
|
||||||
bool writeConfig() const;
|
|
||||||
|
|
||||||
// Return only the info of notebook part in json.
|
// Return only the info of notebook part in json.
|
||||||
QJsonObject toConfigJsonNotebook() const;
|
QJsonObject toConfigJsonNotebook() const;
|
||||||
@ -88,6 +94,10 @@ private:
|
|||||||
// Otherwise, VNote will use the global configured folder.
|
// Otherwise, VNote will use the global configured folder.
|
||||||
QString m_imageFolder;
|
QString m_imageFolder;
|
||||||
|
|
||||||
|
// Folder name to store deleted files.
|
||||||
|
// Could be relative or absolute.
|
||||||
|
QString m_recycleBinFolder;
|
||||||
|
|
||||||
// Parent is NULL for root directory
|
// Parent is NULL for root directory
|
||||||
VDirectory *m_rootDir;
|
VDirectory *m_rootDir;
|
||||||
};
|
};
|
||||||
@ -97,4 +107,9 @@ inline VDirectory *VNotebook::getRootDir() const
|
|||||||
return m_rootDir;
|
return m_rootDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const QString &VNotebook::getRecycleBinFolder() const
|
||||||
|
{
|
||||||
|
return m_recycleBinFolder;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // VNOTEBOOK_H
|
#endif // VNOTEBOOK_H
|
||||||
|
@ -81,6 +81,78 @@ void VNotebookSelector::initActions()
|
|||||||
QUrl url = QUrl::fromLocalFile(notebook->getPath());
|
QUrl url = QUrl::fromLocalFile(notebook->getPath());
|
||||||
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 notebook"));
|
||||||
|
connect(m_recycleBinAct, &QAction::triggered,
|
||||||
|
this, [this]() {
|
||||||
|
QList<QListWidgetItem *> items = this->m_listWidget->selectedItems();
|
||||||
|
if (items.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT(items.size() == 1);
|
||||||
|
QListWidgetItem *item = items[0];
|
||||||
|
int index = this->indexOfListItem(item);
|
||||||
|
VNotebook *notebook = this->getNotebookFromComboIndex(index);
|
||||||
|
QUrl url = QUrl::fromLocalFile(notebook->getRecycleBinFolderPath());
|
||||||
|
QDesktopServices::openUrl(url);
|
||||||
|
});
|
||||||
|
|
||||||
|
m_emptyRecycleBinAct = new QAction(QIcon(":/resources/icons/empty_recycle_bin.svg"),
|
||||||
|
tr("&Empty Recycle Bin"), this);
|
||||||
|
m_emptyRecycleBinAct->setToolTip(tr("Empty the recycle bin of this notebook"));
|
||||||
|
connect(m_emptyRecycleBinAct, &QAction::triggered,
|
||||||
|
this, [this]() {
|
||||||
|
QList<QListWidgetItem *> items = this->m_listWidget->selectedItems();
|
||||||
|
if (items.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT(items.size() == 1);
|
||||||
|
QListWidgetItem *item = items[0];
|
||||||
|
int index = this->indexOfListItem(item);
|
||||||
|
VNotebook *notebook = this->getNotebookFromComboIndex(index);
|
||||||
|
QString binPath = notebook->getRecycleBinFolderPath();
|
||||||
|
|
||||||
|
int ret = VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
|
||||||
|
tr("Are you sure to empty recycle bin of notebook "
|
||||||
|
"<span style=\"%1\">%2</span>?")
|
||||||
|
.arg(g_config->c_dataTextStyle)
|
||||||
|
.arg(notebook->getName()),
|
||||||
|
tr("<span style=\"%1\">WARNING</span>: "
|
||||||
|
"VNote will delete all the files in directory "
|
||||||
|
"<span style=\"%2\">%3</span>."
|
||||||
|
"<br>It may be UNRECOVERABLE!")
|
||||||
|
.arg(g_config->c_warningTextStyle)
|
||||||
|
.arg(g_config->c_dataTextStyle)
|
||||||
|
.arg(binPath),
|
||||||
|
QMessageBox::Ok | QMessageBox::Cancel,
|
||||||
|
QMessageBox::Ok, this, MessageBoxType::Danger);
|
||||||
|
if (ret == QMessageBox::Ok) {
|
||||||
|
QString info;
|
||||||
|
if (VUtils::emptyDirectory(notebook, binPath, true)) {
|
||||||
|
info = tr("Successfully emptied recycle bin of notebook "
|
||||||
|
"<span style=\"%1\">%2</span>!")
|
||||||
|
.arg(g_config->c_dataTextStyle)
|
||||||
|
.arg(notebook->getName());
|
||||||
|
} else {
|
||||||
|
info = tr("Fail to empty recycle bin of notebook "
|
||||||
|
"<span style=\"%1\">%2</span>!")
|
||||||
|
.arg(g_config->c_dataTextStyle)
|
||||||
|
.arg(notebook->getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
VUtils::showMessage(QMessageBox::Information,
|
||||||
|
tr("Information"),
|
||||||
|
info,
|
||||||
|
"",
|
||||||
|
QMessageBox::Ok,
|
||||||
|
QMessageBox::Ok,
|
||||||
|
this);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void VNotebookSelector::updateComboBox()
|
void VNotebookSelector::updateComboBox()
|
||||||
@ -244,7 +316,7 @@ void VNotebookSelector::deleteNotebook()
|
|||||||
VNotebook *notebook = getNotebookFromComboIndex(index);
|
VNotebook *notebook = getNotebookFromComboIndex(index);
|
||||||
Q_ASSERT(notebook);
|
Q_ASSERT(notebook);
|
||||||
|
|
||||||
VDeleteNotebookDialog dialog(tr("Delete Notebook"), notebook->getName(), notebook->getPath(), this);
|
VDeleteNotebookDialog dialog(tr("Delete Notebook"), notebook, this);
|
||||||
if (dialog.exec() == QDialog::Accepted) {
|
if (dialog.exec() == QDialog::Accepted) {
|
||||||
bool deleteFiles = dialog.getDeleteFiles();
|
bool deleteFiles = dialog.getDeleteFiles();
|
||||||
m_editArea->closeFile(notebook, true);
|
m_editArea->closeFile(notebook, true);
|
||||||
@ -323,7 +395,7 @@ void VNotebookSelector::editNotebookInfo()
|
|||||||
if (imageFolder != notebook->getImageFolderConfig()) {
|
if (imageFolder != notebook->getImageFolderConfig()) {
|
||||||
updated = true;
|
updated = true;
|
||||||
notebook->setImageFolder(imageFolder);
|
notebook->setImageFolder(imageFolder);
|
||||||
notebook->writeConfig();
|
notebook->writeConfigNotebook();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updated) {
|
if (updated) {
|
||||||
@ -369,6 +441,10 @@ void VNotebookSelector::requestPopupListContextMenu(QPoint p_pos)
|
|||||||
QMenu menu(this);
|
QMenu menu(this);
|
||||||
menu.setToolTipsVisible(true);
|
menu.setToolTipsVisible(true);
|
||||||
menu.addAction(m_deleteNotebookAct);
|
menu.addAction(m_deleteNotebookAct);
|
||||||
|
menu.addSeparator();
|
||||||
|
menu.addAction(m_recycleBinAct);
|
||||||
|
menu.addAction(m_emptyRecycleBinAct);
|
||||||
|
menu.addSeparator();
|
||||||
menu.addAction(m_openLocationAct);
|
menu.addAction(m_openLocationAct);
|
||||||
menu.addAction(m_notebookInfoAct);
|
menu.addAction(m_notebookInfoAct);
|
||||||
|
|
||||||
|
@ -90,6 +90,8 @@ private:
|
|||||||
QAction *m_deleteNotebookAct;
|
QAction *m_deleteNotebookAct;
|
||||||
QAction *m_notebookInfoAct;
|
QAction *m_notebookInfoAct;
|
||||||
QAction *m_openLocationAct;
|
QAction *m_openLocationAct;
|
||||||
|
QAction *m_recycleBinAct;
|
||||||
|
QAction *m_emptyRecycleBinAct;
|
||||||
|
|
||||||
// We will add several special action item in the combobox. This is the start index
|
// We will add several special action item in the combobox. This is the start index
|
||||||
// of the real notebook items related to m_notebooks.
|
// of the real notebook items related to m_notebooks.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user