diff --git a/src/utils/vutils.cpp b/src/utils/vutils.cpp index be701227..a7fb3888 100644 --- a/src/utils/vutils.cpp +++ b/src/utils/vutils.cpp @@ -1581,6 +1581,42 @@ QString VUtils::promptForFileName(const QString &p_title, return name; } +QString VUtils::promptForFileName(const QString &p_title, + const QString &p_label, + const QString &p_default, + std::function p_checkExistsFunc, + QWidget *p_parent) +{ + QString name = p_default; + QString text = p_label; + while (true) { + bool ok; + name = QInputDialog::getText(p_parent, + p_title, + text, + QLineEdit::Normal, + name, + &ok); + if (!ok || name.isEmpty()) { + return ""; + } + + if (!VUtils::checkFileNameLegal(name)) { + text = QObject::tr("Illegal name. Please try again:"); + continue; + } + + if (p_checkExistsFunc(name)) { + text = QObject::tr("Name already exists. Please try again:"); + continue; + } + + break; + } + + return name; +} + bool VUtils::onlyHasImgInHtml(const QString &p_html) { // Tricky. diff --git a/src/utils/vutils.h b/src/utils/vutils.h index ce150ee1..8c47657b 100644 --- a/src/utils/vutils.h +++ b/src/utils/vutils.h @@ -8,6 +8,8 @@ #include #include #include +#include + #include "vconfigmanager.h" #include "vconstants.h" @@ -339,6 +341,12 @@ public: const QString &p_dir, QWidget *p_parent = nullptr); + static QString promptForFileName(const QString &p_title, + const QString &p_label, + const QString &p_default, + std::function p_checkExistsFunc, + QWidget *p_parent = nullptr); + // Whether @p_html has only content. static bool onlyHasImgInHtml(const QString &p_html); diff --git a/src/vattachmentlist.cpp b/src/vattachmentlist.cpp index df9502ff..b455361e 100644 --- a/src/vattachmentlist.cpp +++ b/src/vattachmentlist.cpp @@ -13,8 +13,11 @@ #include "vlineedit.h" extern VConfigManager *g_config; + extern VMainWindow *g_mainWin; +const QString VAttachmentList::c_infoShortcutSequence = "F2"; + VAttachmentList::VAttachmentList(QWidget *p_parent) : QWidget(p_parent), VButtonPopupWidget(this), @@ -239,12 +242,13 @@ void VAttachmentList::handleContextMenuRequested(QPoint p_pos) return; } + int selectedSize = m_attachmentList->selectedItems().size(); if (item) { if (!item->isSelected()) { m_attachmentList->setCurrentItem(item, QItemSelectionModel::ClearAndSelect); } - if (m_attachmentList->selectedItems().size() == 1) { + if (selectedSize == 1) { QAction *openAct = new QAction(tr("&Open"), &menu); openAct->setToolTip(tr("Open current attachment file")); connect(openAct, &QAction::triggered, @@ -280,6 +284,18 @@ void VAttachmentList::handleContextMenuRequested(QPoint p_pos) menu.addAction(sortAct); } + if (selectedSize == 1) { + menu.addSeparator(); + + QAction *fileInfoAct = new QAction(VIconUtils::menuIcon(":/resources/icons/note_info.svg"), + tr("&Info\t%1").arg(VUtils::getShortcutText(c_infoShortcutSequence)), + &menu); + fileInfoAct->setToolTip(tr("View and edit current folder's information")); + connect(fileInfoAct, &QAction::triggered, + this, &VAttachmentList::attachmentInfo); + menu.addAction(fileInfoAct); + } + if (!menu.actions().isEmpty()) { menu.exec(mapToGlobal(p_pos)); } @@ -439,7 +455,7 @@ void VAttachmentList::handleListItemCommitData(QWidget *p_itemEdit) item->setText(oldText); } else { if (!m_file->renameAttachment(oldText, text)) { - VUtils::showMessage(QMessageBox::Information, + VUtils::showMessage(QMessageBox::Warning, tr("Rename Attachment"), tr("Fail to rename attachment %2.") .arg(g_config->c_dataTextStyle) @@ -447,7 +463,7 @@ void VAttachmentList::handleListItemCommitData(QWidget *p_itemEdit) "", QMessageBox::Ok, QMessageBox::Ok, - this); + g_mainWin); // Recover to old name. item->setText(oldText); } else { @@ -634,5 +650,51 @@ void VAttachmentList::init() setupUI(); + QShortcut *infoShortcut = new QShortcut(QKeySequence(c_infoShortcutSequence), this); + infoShortcut->setContext(Qt::WidgetWithChildrenShortcut); + connect(infoShortcut, &QShortcut::activated, + this, &VAttachmentList::attachmentInfo); + updateContent(); } + +void VAttachmentList::attachmentInfo() +{ + QListWidgetItem *item = m_attachmentList->currentItem(); + if (!item) { + return; + } + + QString oldName = item->data(Qt::UserRole).toString(); + QString name = VUtils::promptForFileName(tr("Attachment Information"), + tr("Rename attachment (%1):").arg(oldName), + oldName, + [this](const QString &p_name) { + if (m_file->findAttachment(p_name, false) > -1) { + return true; + } + + return false; + }, + g_mainWin); + + if (name.isEmpty()) { + return; + } + + if (!m_file->renameAttachment(oldName, name)) { + VUtils::showMessage(QMessageBox::Warning, + tr("Attachment Information"), + tr("Fail to rename attachment %2.") + .arg(g_config->c_dataTextStyle) + .arg(oldName), + "", + QMessageBox::Ok, + QMessageBox::Ok, + g_mainWin); + } else { + // Change the data. + item->setData(Qt::UserRole, name); + item->setText(name); + } +} diff --git a/src/vattachmentlist.h b/src/vattachmentlist.h index 811c6a96..647f14d1 100644 --- a/src/vattachmentlist.h +++ b/src/vattachmentlist.h @@ -50,6 +50,8 @@ private slots: void handleListItemCommitData(QWidget *p_itemEdit); + void attachmentInfo(); + private: void setupUI(); @@ -79,6 +81,8 @@ private: QListWidget *m_attachmentList; VNoteFile *m_file; + + static const QString c_infoShortcutSequence; }; #endif // VATTACHMENTLIST_H diff --git a/src/vexplorer.cpp b/src/vexplorer.cpp index 3f7cea96..f4174129 100644 --- a/src/vexplorer.cpp +++ b/src/vexplorer.cpp @@ -236,6 +236,12 @@ void VExplorer::init() infoShortcut->setContext(Qt::WidgetWithChildrenShortcut); connect(infoShortcut, &QShortcut::activated, this, [this]() { + QModelIndexList selectedIdx = m_tree->selectionModel()->selectedRows(); + if (selectedIdx.size() == 1) { + QFileSystemModel *model = static_cast(m_tree->model()); + QString filePath = model->filePath(selectedIdx[0]); + renameFile(filePath); + } }); g_config->getExplorerEntries(m_entries);