diff --git a/src/core/EntryAttachments.cpp b/src/core/EntryAttachments.cpp index 49f5198d2f..23aef01f94 100644 --- a/src/core/EntryAttachments.cpp +++ b/src/core/EntryAttachments.cpp @@ -112,6 +112,13 @@ void EntryAttachments::remove(const QStringList& keys) } } +void EntryAttachments::rename(const QString& key, const QString& newKey) +{ + const QByteArray val = value(key); + remove(key); + set(newKey, val); +} + bool EntryAttachments::isEmpty() const { return m_attachments.isEmpty(); diff --git a/src/core/EntryAttachments.h b/src/core/EntryAttachments.h index 2cb884e778..923376f3b6 100644 --- a/src/core/EntryAttachments.h +++ b/src/core/EntryAttachments.h @@ -36,6 +36,7 @@ class EntryAttachments : public QObject void set(const QString& key, const QByteArray& value); void remove(const QString& key); void remove(const QStringList& keys); + void rename(const QString& key, const QString& newKey); bool isEmpty() const; void clear(); void copyDataFrom(const EntryAttachments* other); diff --git a/src/gui/entry/EntryAttachmentsModel.cpp b/src/gui/entry/EntryAttachmentsModel.cpp index 8f04a2629a..c27b7fd449 100644 --- a/src/gui/entry/EntryAttachmentsModel.cpp +++ b/src/gui/entry/EntryAttachmentsModel.cpp @@ -101,6 +101,28 @@ QVariant EntryAttachmentsModel::data(const QModelIndex& index, int role) const return QVariant(); } +bool EntryAttachmentsModel::setData(const QModelIndex& index, const QVariant& value, int role) +{ + if (!m_readOnly && index.column() == Columns::NameColumn) { + const QString key = value.toString().trimmed(); + if (key.isEmpty() || m_entryAttachments->hasKey(key)) { + return false; + } + m_entryAttachments->rename(keyByIndex(index), key); + return true; + } + return QAbstractListModel::setData(index, value, role); +} + +Qt::ItemFlags EntryAttachmentsModel::flags(const QModelIndex& index) const +{ + Qt::ItemFlags flags = QAbstractListModel::flags(index); + if (!m_readOnly && index.column() == Columns::NameColumn) { + flags = flags | Qt::ItemIsEditable; + } + return flags; +} + QString EntryAttachmentsModel::keyByIndex(const QModelIndex& index) const { if (!index.isValid()) { @@ -150,3 +172,8 @@ void EntryAttachmentsModel::reset() { endResetModel(); } + +void EntryAttachmentsModel::setReadOnly(bool readOnly) +{ + m_readOnly = readOnly; +} diff --git a/src/gui/entry/EntryAttachmentsModel.h b/src/gui/entry/EntryAttachmentsModel.h index 18a02c7c6d..486ee059ff 100644 --- a/src/gui/entry/EntryAttachmentsModel.h +++ b/src/gui/entry/EntryAttachmentsModel.h @@ -40,6 +40,8 @@ class EntryAttachmentsModel : public QAbstractListModel int columnCount(const QModelIndex& parent = QModelIndex()) const override; QVariant headerData(int section, Qt::Orientation orientation, int role) const override; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override; + Qt::ItemFlags flags(const QModelIndex& index) const override; QString keyByIndex(const QModelIndex& index) const; private slots: @@ -50,10 +52,12 @@ private slots: void attachmentRemove(); void aboutToReset(); void reset(); + void setReadOnly(bool readOnly); private: EntryAttachments* m_entryAttachments; QStringList m_headers; + bool m_readOnly = false; }; #endif // KEEPASSX_ENTRYATTACHMENTSMODEL_H diff --git a/src/gui/entry/EntryAttachmentsWidget.cpp b/src/gui/entry/EntryAttachmentsWidget.cpp index 836c8ef277..7bea0fdb51 100644 --- a/src/gui/entry/EntryAttachmentsWidget.cpp +++ b/src/gui/entry/EntryAttachmentsWidget.cpp @@ -49,12 +49,14 @@ EntryAttachmentsWidget::EntryAttachmentsWidget(QWidget* parent) SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(updateButtonsEnabled())); // clang-format on + connect(this, SIGNAL(readOnlyChanged(bool)), m_attachmentsModel, SLOT(setReadOnly(bool))); connect(m_ui->attachmentsView, SIGNAL(doubleClicked(QModelIndex)), SLOT(openAttachment(QModelIndex))); connect(m_ui->saveAttachmentButton, SIGNAL(clicked()), SLOT(saveSelectedAttachments())); connect(m_ui->openAttachmentButton, SIGNAL(clicked()), SLOT(openSelectedAttachments())); connect(m_ui->addAttachmentButton, SIGNAL(clicked()), SLOT(insertAttachments())); connect(m_ui->removeAttachmentButton, SIGNAL(clicked()), SLOT(removeSelectedAttachments())); + connect(m_ui->renameAttachmentButton, SIGNAL(clicked()), SLOT(renameSelectedAttachments())); updateButtonsVisible(); updateButtonsEnabled(); @@ -184,6 +186,11 @@ void EntryAttachmentsWidget::removeSelectedAttachments() } } +void EntryAttachmentsWidget::renameSelectedAttachments() +{ + m_ui->attachmentsView->edit(m_ui->attachmentsView->selectionModel()->selectedIndexes().first()); +} + void EntryAttachmentsWidget::saveSelectedAttachments() { const QModelIndexList indexes = m_ui->attachmentsView->selectionModel()->selectedRows(0); @@ -289,6 +296,7 @@ void EntryAttachmentsWidget::updateButtonsEnabled() m_ui->addAttachmentButton->setEnabled(!m_readOnly); m_ui->removeAttachmentButton->setEnabled(hasSelection && !m_readOnly); + m_ui->renameAttachmentButton->setEnabled(hasSelection && !m_readOnly); m_ui->saveAttachmentButton->setEnabled(hasSelection); m_ui->openAttachmentButton->setEnabled(hasSelection); diff --git a/src/gui/entry/EntryAttachmentsWidget.h b/src/gui/entry/EntryAttachmentsWidget.h index 19e82eb5dd..b959d7c710 100644 --- a/src/gui/entry/EntryAttachmentsWidget.h +++ b/src/gui/entry/EntryAttachmentsWidget.h @@ -45,6 +45,7 @@ public slots: private slots: void insertAttachments(); void removeSelectedAttachments(); + void renameSelectedAttachments(); void saveSelectedAttachments(); void openAttachment(const QModelIndex& index); void openSelectedAttachments(); diff --git a/src/gui/entry/EntryAttachmentsWidget.ui b/src/gui/entry/EntryAttachmentsWidget.ui index bd6e155386..e685813b3d 100644 --- a/src/gui/entry/EntryAttachmentsWidget.ui +++ b/src/gui/entry/EntryAttachmentsWidget.ui @@ -31,6 +31,9 @@ Attachments + + QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked + @@ -74,6 +77,19 @@ + + + + false + + + Rename selected attachment + + + Rename + + +