VAttachmentList: check missing attachments when showing the list

This commit is contained in:
Le Tan 2017-09-29 19:57:21 +08:00
parent 58e7cdca4b
commit 18ed9b761a
6 changed files with 112 additions and 8 deletions

View File

@ -124,6 +124,8 @@ Toggle single panel or two panels mode.
Toggle the Tools panel. Toggle the Tools panel.
- `F` - `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. 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` - `X`
Close current tab. Close current tab.
- `J` - `J`

View File

@ -125,6 +125,8 @@ size=8
打开或关闭工具面板。 打开或关闭工具面板。
- `F` - `F`
打开当前分割窗口的笔记列表。在该列表中,可以直接按笔记对应的序号实现跳转。 打开当前分割窗口的笔记列表。在该列表中,可以直接按笔记对应的序号实现跳转。
- `A`
打开当前笔记的附件列表。
- `X` - `X`
关闭当前标签页。 关闭当前标签页。
- `J` - `J`

View File

@ -62,7 +62,8 @@ void VAttachmentList::setupUI()
tr("Fail to clear attachments of note <span style=\"%1\">%2</span>.") tr("Fail to clear attachments of note <span style=\"%1\">%2</span>.")
.arg(g_config->c_dataTextStyle) .arg(g_config->c_dataTextStyle)
.arg(m_file->getName()), .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,
QMessageBox::Ok, QMessageBox::Ok,
g_vnote->getMainWindow()); g_vnote->getMainWindow());
@ -344,7 +345,8 @@ void VAttachmentList::deleteSelectedItems()
tr("Fail to delete attachments of note <span style=\"%1\">%2</span>.") tr("Fail to delete attachments of note <span style=\"%1\">%2</span>.")
.arg(g_config->c_dataTextStyle) .arg(g_config->c_dataTextStyle)
.arg(m_file->getName()), .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,
QMessageBox::Ok, QMessageBox::Ok,
g_vnote->getMainWindow()); g_vnote->getMainWindow());
@ -566,6 +568,8 @@ bool VAttachmentList::handleDropEvent(QDropEvent *p_event)
void VAttachmentList::handleAboutToShow() void VAttachmentList::handleAboutToShow()
{ {
updateContent(); updateContent();
checkAttachments();
} }
void VAttachmentList::updateButtonState() const void VAttachmentList::updateButtonState() const
@ -586,3 +590,65 @@ void VAttachmentList::updateButtonState() const
btn->setBubbleNumber(numOfAttachments); btn->setBubbleNumber(numOfAttachments);
} }
void VAttachmentList::checkAttachments()
{
if (!m_file) {
return;
}
QVector<QString> missingAttas = m_file->checkAttachments();
if (missingAttas.isEmpty()) {
return;
}
QVector<ConfirmItemInfo> items;
for (auto const & atta : missingAttas) {
items.push_back(ConfirmItemInfo(atta,
atta,
"",
NULL));
}
QString text = tr("VNote detects that these attachments of note "
"<span style=\"%1\">%2</span> 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<QString> 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 <span style=\"%1\">%2</span>.")
.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();
}
}

View File

@ -62,6 +62,9 @@ private:
// Update the state of VButtonWithWidget. // Update the state of VButtonWithWidget.
void updateButtonState() const; void updateButtonState() const;
// Check if there are attachments that do not exist in disk.
void checkAttachments();
QPushButton *m_addBtn; QPushButton *m_addBtn;
QPushButton *m_clearBtn; QPushButton *m_clearBtn;
QPushButton *m_locateBtn; QPushButton *m_locateBtn;

View File

@ -268,7 +268,7 @@ QString VNoteFile::fetchAttachmentFolderPath()
return folderPath; return folderPath;
} }
bool VNoteFile::deleteAttachments() bool VNoteFile::deleteAttachments(bool p_omitMissing)
{ {
if (m_attachments.isEmpty()) { if (m_attachments.isEmpty()) {
return true; return true;
@ -279,10 +279,11 @@ bool VNoteFile::deleteAttachments()
attas.push_back(m_attachments[i].m_name); attas.push_back(m_attachments[i].m_name);
} }
return deleteAttachments(attas); return deleteAttachments(attas, p_omitMissing);
} }
bool VNoteFile::deleteAttachments(const QVector<QString> &p_names) bool VNoteFile::deleteAttachments(const QVector<QString> &p_names,
bool p_omitMissing)
{ {
if (p_names.isEmpty()) { if (p_names.isEmpty()) {
return true; return true;
@ -298,7 +299,15 @@ bool VNoteFile::deleteAttachments(const QVector<QString> &p_names)
} }
m_attachments.remove(idx); 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; ret = false;
qWarning() << "fail to delete attachment" << p_names[i] qWarning() << "fail to delete attachment" << p_names[i]
<< "for note" << m_name; << "for note" << m_name;
@ -386,6 +395,21 @@ bool VNoteFile::renameAttachment(const QString &p_oldName, const QString &p_newN
return true; return true;
} }
QVector<QString> VNoteFile::checkAttachments()
{
QVector<QString> 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) bool VNoteFile::deleteFile(VNoteFile *p_file, QString *p_errMsg)
{ {
Q_ASSERT(!p_file->isOpened()); Q_ASSERT(!p_file->isOpened());

View File

@ -86,10 +86,13 @@ public:
QString fetchAttachmentFolderPath(); QString fetchAttachmentFolderPath();
// Delete all the attachments. // 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. // Delete attachments specified by @p_names.
bool deleteAttachments(const QVector<QString> &p_names); // @p_omitMissing: omit the error if the attachment file does not exist.
bool deleteAttachments(const QVector<QString> &p_names,
bool p_omitMissing = false);
// Reorder attachments in m_attachments by index. // Reorder attachments in m_attachments by index.
bool sortAttachments(const QVector<int> &p_sortedIdx); bool sortAttachments(const QVector<int> &p_sortedIdx);
@ -101,6 +104,10 @@ public:
// Rename attachment @p_oldName to @p_newName. // Rename attachment @p_oldName to @p_newName.
bool renameAttachment(const QString &p_oldName, const QString &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<QString> checkAttachments();
// Create a VNoteFile from @p_json Json object. // Create a VNoteFile from @p_json Json object.
static VNoteFile *fromJson(VDirectory *p_directory, static VNoteFile *fromJson(VDirectory *p_directory,
const QJsonObject &p_json, const QJsonObject &p_json,