From 18ed9b761ade46d41985284663e93e0e6cdca2cd Mon Sep 17 00:00:00 2001 From: Le Tan Date: Fri, 29 Sep 2017 19:57:21 +0800 Subject: [PATCH] VAttachmentList: check missing attachments when showing the list --- src/resources/docs/shortcuts_en.md | 2 + src/resources/docs/shortcuts_zh.md | 2 + src/vattachmentlist.cpp | 70 +++++++++++++++++++++++++++++- src/vattachmentlist.h | 3 ++ src/vnotefile.cpp | 32 ++++++++++++-- src/vnotefile.h | 11 ++++- 6 files changed, 112 insertions(+), 8 deletions(-) diff --git a/src/resources/docs/shortcuts_en.md b/src/resources/docs/shortcuts_en.md index 46a0a035..0942ac2f 100644 --- a/src/resources/docs/shortcuts_en.md +++ b/src/resources/docs/shortcuts_en.md @@ -124,6 +124,8 @@ Toggle single panel or two panels mode. Toggle the Tools panel. - `F` Popup the opened notes list of current split window. Within this list, pressing the sequence number in front of each note could jump to that note. +- `A` +Popup the attachments list of current note. - `X` Close current tab. - `J` diff --git a/src/resources/docs/shortcuts_zh.md b/src/resources/docs/shortcuts_zh.md index 4fd11406..926c0aba 100644 --- a/src/resources/docs/shortcuts_zh.md +++ b/src/resources/docs/shortcuts_zh.md @@ -125,6 +125,8 @@ size=8 打开或关闭工具面板。 - `F` 打开当前分割窗口的笔记列表。在该列表中,可以直接按笔记对应的序号实现跳转。 +- `A` +打开当前笔记的附件列表。 - `X` 关闭当前标签页。 - `J` diff --git a/src/vattachmentlist.cpp b/src/vattachmentlist.cpp index f559753b..695df7bc 100644 --- a/src/vattachmentlist.cpp +++ b/src/vattachmentlist.cpp @@ -62,7 +62,8 @@ void VAttachmentList::setupUI() tr("Fail to clear attachments of note %2.") .arg(g_config->c_dataTextStyle) .arg(m_file->getName()), - tr("Please maintain the configureation file manually."), + tr("Please check the attachments folder and " + "maintain the configuration file manually."), QMessageBox::Ok, QMessageBox::Ok, g_vnote->getMainWindow()); @@ -344,7 +345,8 @@ void VAttachmentList::deleteSelectedItems() tr("Fail to delete attachments of note %2.") .arg(g_config->c_dataTextStyle) .arg(m_file->getName()), - tr("Please maintain the configureation file manually."), + tr("Please check the attachments folder and " + "maintain the configuration file manually."), QMessageBox::Ok, QMessageBox::Ok, g_vnote->getMainWindow()); @@ -566,6 +568,8 @@ bool VAttachmentList::handleDropEvent(QDropEvent *p_event) void VAttachmentList::handleAboutToShow() { updateContent(); + + checkAttachments(); } void VAttachmentList::updateButtonState() const @@ -586,3 +590,65 @@ void VAttachmentList::updateButtonState() const btn->setBubbleNumber(numOfAttachments); } + +void VAttachmentList::checkAttachments() +{ + if (!m_file) { + return; + } + + QVector missingAttas = m_file->checkAttachments(); + if (missingAttas.isEmpty()) { + return; + } + + QVector items; + for (auto const & atta : missingAttas) { + items.push_back(ConfirmItemInfo(atta, + atta, + "", + NULL)); + } + + QString text = tr("VNote detects that these attachments of note " + "%2 are missing in disk. " + "Would you like to remove them from the note?") + .arg(g_config->c_dataTextStyle) + .arg(m_file->getName()); + + QString info = tr("Click \"Cancel\" to leave them untouched."); + + VConfirmDeletionDialog dialog(tr("Confirm Deleting Attachments"), + text, + info, + items, + false, + false, + false, + g_vnote->getMainWindow()); + if (dialog.exec()) { + items = dialog.getConfirmedItems(); + + QVector names; + for (auto const & item : items) { + names.push_back(item.m_name); + } + + if (!m_file->deleteAttachments(names, true)) { + VUtils::showMessage(QMessageBox::Warning, + tr("Warning"), + tr("Fail to delete attachments of note %2.") + .arg(g_config->c_dataTextStyle) + .arg(m_file->getName()), + tr("Please check the attachments folder and " + "maintain the configuration file manually."), + QMessageBox::Ok, + QMessageBox::Ok, + g_vnote->getMainWindow()); + } + + updateButtonState(); + + updateContent(); + } +} diff --git a/src/vattachmentlist.h b/src/vattachmentlist.h index 9ed2be3a..52a45964 100644 --- a/src/vattachmentlist.h +++ b/src/vattachmentlist.h @@ -62,6 +62,9 @@ private: // Update the state of VButtonWithWidget. void updateButtonState() const; + // Check if there are attachments that do not exist in disk. + void checkAttachments(); + QPushButton *m_addBtn; QPushButton *m_clearBtn; QPushButton *m_locateBtn; diff --git a/src/vnotefile.cpp b/src/vnotefile.cpp index 743bdbe7..0cbb46f8 100644 --- a/src/vnotefile.cpp +++ b/src/vnotefile.cpp @@ -268,7 +268,7 @@ QString VNoteFile::fetchAttachmentFolderPath() return folderPath; } -bool VNoteFile::deleteAttachments() +bool VNoteFile::deleteAttachments(bool p_omitMissing) { if (m_attachments.isEmpty()) { return true; @@ -279,10 +279,11 @@ bool VNoteFile::deleteAttachments() attas.push_back(m_attachments[i].m_name); } - return deleteAttachments(attas); + return deleteAttachments(attas, p_omitMissing); } -bool VNoteFile::deleteAttachments(const QVector &p_names) +bool VNoteFile::deleteAttachments(const QVector &p_names, + bool p_omitMissing) { if (p_names.isEmpty()) { return true; @@ -298,7 +299,15 @@ bool VNoteFile::deleteAttachments(const QVector &p_names) } m_attachments.remove(idx); - if (!VUtils::deleteFile(getNotebook(), dir.filePath(p_names[i]), false)) { + + QString filePath = dir.filePath(p_names[i]); + if (p_omitMissing + && !QFileInfo::exists(filePath)) { + // The attachment file does not exist. We skip it to avoid error. + continue; + } + + if (!VUtils::deleteFile(getNotebook(), filePath, false)) { ret = false; qWarning() << "fail to delete attachment" << p_names[i] << "for note" << m_name; @@ -386,6 +395,21 @@ bool VNoteFile::renameAttachment(const QString &p_oldName, const QString &p_newN return true; } +QVector VNoteFile::checkAttachments() +{ + QVector missing; + + QDir dir(fetchAttachmentFolderPath()); + for (auto const & atta : m_attachments) { + QString file = dir.filePath(atta.m_name); + if (!QFileInfo::exists(file)) { + missing.push_back(atta.m_name); + } + } + + return missing; +} + bool VNoteFile::deleteFile(VNoteFile *p_file, QString *p_errMsg) { Q_ASSERT(!p_file->isOpened()); diff --git a/src/vnotefile.h b/src/vnotefile.h index 92e444f1..96d3a344 100644 --- a/src/vnotefile.h +++ b/src/vnotefile.h @@ -86,10 +86,13 @@ public: QString fetchAttachmentFolderPath(); // Delete all the attachments. - bool deleteAttachments(); + // @p_omitMissing: omit the error if the attachment file does not exist. + bool deleteAttachments(bool p_omitMissing = false); // Delete attachments specified by @p_names. - bool deleteAttachments(const QVector &p_names); + // @p_omitMissing: omit the error if the attachment file does not exist. + bool deleteAttachments(const QVector &p_names, + bool p_omitMissing = false); // Reorder attachments in m_attachments by index. bool sortAttachments(const QVector &p_sortedIdx); @@ -101,6 +104,10 @@ public: // Rename attachment @p_oldName to @p_newName. bool renameAttachment(const QString &p_oldName, const QString &p_newName); + // Check if all the attachment files still exist. + // Return the missing attachments' names. + QVector checkAttachments(); + // Create a VNoteFile from @p_json Json object. static VNoteFile *fromJson(VDirectory *p_directory, const QJsonObject &p_json,