diff --git a/src/core/EntryAttributes.cpp b/src/core/EntryAttributes.cpp index 1f5b0931..64232d65 100644 --- a/src/core/EntryAttributes.cpp +++ b/src/core/EntryAttributes.cpp @@ -110,11 +110,25 @@ void EntryAttributes::rename(const QString& oldKey, const QString& newKey) return; } + if (m_attributes.contains(newKey)) { + Q_ASSERT(false); + return; + } + QString data = value(oldKey); bool protect = isProtected(oldKey); - remove(oldKey); - set(newKey, data, protect); + Q_EMIT aboutToRename(oldKey, newKey); + + m_attributes.remove(oldKey); + m_attributes.insert(newKey, data); + if (protect) { + m_protectedAttributes.remove(oldKey); + m_protectedAttributes.insert(newKey); + } + + Q_EMIT modified(); + Q_EMIT renamed(oldKey, newKey); } void EntryAttributes::copyCustomKeysFrom(const EntryAttributes* other) diff --git a/src/core/EntryAttributes.h b/src/core/EntryAttributes.h index 2dc63fa8..b328d792 100644 --- a/src/core/EntryAttributes.h +++ b/src/core/EntryAttributes.h @@ -53,6 +53,8 @@ Q_SIGNALS: void added(QString key); void aboutToBeRemoved(QString key); void removed(QString key); + void aboutToRename(QString oldKey, QString newKey); + void renamed(QString oldKey, QString newKey); void aboutToBeReset(); void reset(); diff --git a/src/gui/EditEntryWidget.cpp b/src/gui/EditEntryWidget.cpp index 5964c8ab..6d7070f1 100644 --- a/src/gui/EditEntryWidget.cpp +++ b/src/gui/EditEntryWidget.cpp @@ -61,13 +61,21 @@ EditEntryWidget::EditEntryWidget(QWidget* parent) m_advancedUi->setupUi(m_advancedWidget); m_ui->stackedWidget->addWidget(m_advancedWidget); - m_attachmentsModel = new EntryAttachmentsModel(m_advancedWidget); - m_advancedUi->attachmentsView->setModel(m_attachmentsModel); - m_entryAttributes = new EntryAttributes(this); - - m_attributesModel = new EntryAttributesModel(m_advancedWidget); - m_advancedUi->attributesView->setModel(m_attributesModel); m_entryAttachments = new EntryAttachments(this); + m_attachmentsModel = new EntryAttachmentsModel(m_advancedWidget); + m_attachmentsModel->setEntryAttachments(m_entryAttachments); + m_advancedUi->attachmentsView->setModel(m_attachmentsModel); + + m_entryAttributes = new EntryAttributes(this); + m_attributesModel = new EntryAttributesModel(m_advancedWidget); + m_attributesModel->setEntryAttributes(m_entryAttributes); + m_advancedUi->attributesView->setModel(m_attributesModel); + connect(m_advancedUi->addAttributeButton, SIGNAL(clicked()), SLOT(insertAttribute())); + connect(m_advancedUi->editAttributeButton, SIGNAL(clicked()), SLOT(editCurrentAttribute())); + connect(m_advancedUi->removeAttributeButton, SIGNAL(clicked()), SLOT(removeCurrentAttribute())); + connect(m_advancedUi->attributesView->selectionModel(), + SIGNAL(currentChanged(QModelIndex,QModelIndex)), + SLOT(updateCurrentAttribute())); Q_ASSERT(m_ui->categoryList->model()->rowCount() == m_ui->stackedWidget->count()); @@ -114,12 +122,17 @@ void EditEntryWidget::loadEntry(Entry* entry, bool create, const QString& groupN m_notesUi->notesEdit->setPlainText(entry->notes()); m_entryAttributes->copyCustomKeysFrom(entry->attributes()); - m_attributesModel->setEntryAttributes(m_entryAttributes); *m_entryAttachments = *entry->attachments(); - m_attachmentsModel->setEntryAttachments(m_entryAttachments); m_ui->categoryList->setCurrentRow(0); + if (m_attributesModel->rowCount() != 0) { + m_advancedUi->attributesView->setCurrentIndex(m_attributesModel->index(0, 0)); + } + else { + m_advancedUi->attributesEdit->setEnabled(false); + } + m_mainUi->titleEdit->setFocus(); } @@ -130,6 +143,14 @@ void EditEntryWidget::saveEntry() return; } + if (m_advancedUi->attributesView->currentIndex().isValid()) { + QString key = m_attributesModel->keyByIndex(m_advancedUi->attributesView->currentIndex()); + m_entryAttributes->set(key, m_advancedUi->attributesEdit->toPlainText(), + m_entryAttributes->isProtected(key)); + } + + m_currentAttribute = QPersistentModelIndex(); + m_entry->beginUpdate(); m_entry->setTitle(m_mainUi->titleEdit->text()); @@ -142,19 +163,23 @@ void EditEntryWidget::saveEntry() m_entry->setNotes(m_notesUi->notesEdit->toPlainText()); m_entry->attributes()->copyCustomKeysFrom(m_entryAttributes); - m_entryAttributes->clear(); *m_entry->attachments() = *m_entryAttachments; - m_entryAttachments->clear(); m_entry->endUpdate(); m_entry = 0; + m_entryAttributes->clear(); + m_entryAttachments->clear(); + Q_EMIT editFinished(true); } void EditEntryWidget::cancel() { m_entry = 0; + m_entryAttributes->clear(); + m_entryAttachments->clear(); + Q_EMIT editFinished(false); } @@ -185,3 +210,65 @@ void EditEntryWidget::setPasswordCheckColors() } m_mainUi->passwordRepeatEdit->setPalette(pal); } + +void EditEntryWidget::insertAttribute() +{ + QString name = tr("New attribute"); + int i = 1; + + while (m_entryAttributes->keys().contains(name)) { + name = QString("%1 %2").arg(tr("New attribute")).arg(i); + i++; + } + + m_entryAttributes->set(name, ""); + QModelIndex index = m_attributesModel->indexByKey(name); + + m_advancedUi->attributesView->setCurrentIndex(index); + m_advancedUi->attributesView->edit(index); +} + +void EditEntryWidget::editCurrentAttribute() +{ + QModelIndex index = m_advancedUi->attributesView->currentIndex(); + + if (index.isValid()) { + m_advancedUi->attributesView->edit(index); + } +} + +void EditEntryWidget::removeCurrentAttribute() +{ + QModelIndex index = m_advancedUi->attributesView->currentIndex(); + + if (index.isValid()) { + m_entryAttributes->remove(m_attributesModel->keyByIndex(index)); + } +} + +void EditEntryWidget::updateCurrentAttribute() +{ + QModelIndex newIndex = m_advancedUi->attributesView->currentIndex(); + + if (m_currentAttribute != newIndex) { + if (m_currentAttribute.isValid()) { + QString key = m_attributesModel->keyByIndex(m_currentAttribute); + m_entryAttributes->set(key, m_advancedUi->attributesEdit->toPlainText(), + m_entryAttributes->isProtected(key)); + } + + if (newIndex.isValid()) { + QString key = m_attributesModel->keyByIndex(newIndex); + m_advancedUi->attributesEdit->setPlainText(m_entryAttributes->value(key)); + m_advancedUi->attributesEdit->setEnabled(true); + } + else { + m_advancedUi->attributesEdit->setPlainText(""); + m_advancedUi->attributesEdit->setEnabled(false); + } + + m_advancedUi->editAttributeButton->setEnabled(newIndex.isValid()); + m_advancedUi->removeAttributeButton->setEnabled(newIndex.isValid()); + m_currentAttribute = newIndex; + } +} diff --git a/src/gui/EditEntryWidget.h b/src/gui/EditEntryWidget.h index e0bc6b67..29f10878 100644 --- a/src/gui/EditEntryWidget.h +++ b/src/gui/EditEntryWidget.h @@ -18,6 +18,7 @@ #ifndef KEEPASSX_EDITENTRYWIDGET_H #define KEEPASSX_EDITENTRYWIDGET_H +#include #include #include "gui/DialogyWidget.h" @@ -59,9 +60,13 @@ private Q_SLOTS: void cancel(); void togglePassword(bool checked); void setPasswordCheckColors(); + void insertAttribute(); + void editCurrentAttribute(); + void removeCurrentAttribute(); + void updateCurrentAttribute(); private: - bool passwordsEqual(); + bool passwordsEqual(); Entry* m_entry; @@ -76,6 +81,7 @@ private: EntryAttributesModel* m_attributesModel; EntryAttachments* m_entryAttachments; EntryAttributes* m_entryAttributes; + QPersistentModelIndex m_currentAttribute; Q_DISABLE_COPY(EditEntryWidget) }; diff --git a/src/gui/EditEntryWidgetAdvanced.ui b/src/gui/EditEntryWidgetAdvanced.ui index b881eb57..0036d19c 100644 --- a/src/gui/EditEntryWidgetAdvanced.ui +++ b/src/gui/EditEntryWidgetAdvanced.ui @@ -18,8 +18,11 @@ - - + + + + + false @@ -35,6 +38,9 @@ + + false + Edit @@ -42,6 +48,9 @@ + + false + Remove @@ -121,6 +130,13 @@ + + + AttributesListView + QListView +
gui/EditEntryWidget_p.h
+
+
diff --git a/src/gui/EditEntryWidget_p.h b/src/gui/EditEntryWidget_p.h index b4153a35..9e943eea 100644 --- a/src/gui/EditEntryWidget_p.h +++ b/src/gui/EditEntryWidget_p.h @@ -59,4 +59,27 @@ public: } }; +class AttributesListView : public QListView +{ +public: + explicit AttributesListView(QWidget* parent = 0) : QListView(parent) + { + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); + setItemDelegate(new CategoryListViewDelegate(this)); + } + + virtual QSize sizeHint() const + { + QSize sizeHint = QListView::sizeHint(); + + int width = sizeHintForColumn(0) + frameWidth() * 2 + 5; + if (verticalScrollBar()->isVisible()) { + width += verticalScrollBar()->width(); + } + sizeHint.setWidth(width); + + return sizeHint; + } +}; + #endif // KEEPASSX_EDITENTRYWIDGET_P_H diff --git a/src/gui/EntryAttributesModel.cpp b/src/gui/EntryAttributesModel.cpp index 43c26e17..c38f8fa0 100644 --- a/src/gui/EntryAttributesModel.cpp +++ b/src/gui/EntryAttributesModel.cpp @@ -23,6 +23,7 @@ EntryAttributesModel::EntryAttributesModel(QObject* parent) : QAbstractListModel(parent) , m_entryAttributes(0) + , m_nextRenameDataChange(false) { } @@ -43,6 +44,9 @@ void EntryAttributesModel::setEntryAttributes(EntryAttributes* entryAttributes) connect(m_entryAttributes, SIGNAL(added(QString)), SLOT(attributeAdd())); connect(m_entryAttributes, SIGNAL(aboutToBeRemoved(QString)), SLOT(attributeAboutToRemove(QString))); connect(m_entryAttributes, SIGNAL(removed(QString)), SLOT(attributeRemove())); + connect(m_entryAttributes, SIGNAL(aboutToRename(QString,QString)), + SLOT(attributeAboutToRename(QString,QString))); + connect(m_entryAttributes, SIGNAL(renamed(QString,QString)), SLOT(attributeRename(QString,QString))); connect(m_entryAttributes, SIGNAL(aboutToBeReset()), SLOT(aboutToReset())); connect(m_entryAttributes, SIGNAL(reset()), SLOT(reset())); } @@ -171,6 +175,46 @@ void EntryAttributesModel::attributeRemove() endRemoveRows(); } +void EntryAttributesModel::attributeAboutToRename(QString oldKey, QString newKey) +{ + int oldRow = m_attributes.indexOf(oldKey); + + QList rows = m_attributes; + rows.removeOne(oldKey); + rows.append(newKey); + qSort(rows); + int newRow = rows.indexOf(newKey); + if (newRow > oldRow) { + newRow++; + } + + if (oldRow != newRow) { + bool result = beginMoveRows(QModelIndex(), oldRow, oldRow, QModelIndex(), newRow); + Q_UNUSED(result); + Q_ASSERT(result); + } + else { + m_nextRenameDataChange = true; + } +} + +void EntryAttributesModel::attributeRename(QString oldKey, QString newKey) +{ + Q_UNUSED(oldKey); + + updateAttributes(); + + if (!m_nextRenameDataChange) { + endMoveRows(); + } + else { + m_nextRenameDataChange = false; + + QModelIndex keyIndex = index(m_attributes.indexOf(newKey), 0); + Q_EMIT dataChanged(keyIndex, keyIndex); + } +} + void EntryAttributesModel::aboutToReset() { beginResetModel(); diff --git a/src/gui/EntryAttributesModel.h b/src/gui/EntryAttributesModel.h index 99d9f469..0084644f 100644 --- a/src/gui/EntryAttributesModel.h +++ b/src/gui/EntryAttributesModel.h @@ -44,6 +44,8 @@ private Q_SLOTS: void attributeAdd(); void attributeAboutToRemove(QString key); void attributeRemove(); + void attributeAboutToRename(QString oldKey, QString newKey); + void attributeRename(QString oldKey, QString newKey); void aboutToReset(); void reset(); @@ -52,6 +54,7 @@ private: EntryAttributes* m_entryAttributes; QList m_attributes; + bool m_nextRenameDataChange; }; #endif // KEEPASSX_ENTRYATTRIBUTESMODEL_H