Skip to content

Commit

Permalink
Add New Entry Attachments dialog and functionality
Browse files Browse the repository at this point in the history
Fixes #11506
  • Loading branch information
w15dev committed Jan 7, 2025
1 parent 17dc022 commit eae01f6
Show file tree
Hide file tree
Showing 8 changed files with 252 additions and 0 deletions.
31 changes: 31 additions & 0 deletions share/translations/keepassxc_en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3980,6 +3980,10 @@ Error: %1</source>
Would you like to overwrite the existing attachment?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>New</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>EntryAttributesModel</name>
Expand Down Expand Up @@ -6349,6 +6353,33 @@ Expect some bugs and minor issues, this version is meant for testing purposes.</
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>NewEntryAttachmentsDialog</name>
<message>
<source>New entry attachments</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>File name</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>File contents...</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Attachment name cannot be empty</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Attachment with the same name already exists</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Save attachment</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>NixUtils</name>
<message>
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ set(gui_SOURCES
gui/entry/EntryAttachmentsModel.cpp
gui/entry/EntryAttachmentsWidget.cpp
gui/entry/EntryAttributesModel.cpp
gui/entry/NewEntryAttachmentsDialog.cpp
gui/entry/EntryHistoryModel.cpp
gui/entry/EntryModel.cpp
gui/entry/EntryView.cpp
Expand Down
18 changes: 18 additions & 0 deletions src/gui/entry/EntryAttachmentsWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@
*/

#include "EntryAttachmentsWidget.h"
#include "NewEntryAttachmentsDialog.h"
#include "ui_EntryAttachmentsWidget.h"

#include <QDialog>
#include <QDir>
#include <QDropEvent>
#include <QMimeData>
Expand Down Expand Up @@ -68,6 +70,7 @@ EntryAttachmentsWidget::EntryAttachmentsWidget(QWidget* parent)
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->newAttachmentButton, SIGNAL(clicked()), SLOT(newAttachments()));
connect(m_ui->removeAttachmentButton, SIGNAL(clicked()), SLOT(removeSelectedAttachments()));
connect(m_ui->renameAttachmentButton, SIGNAL(clicked()), SLOT(renameSelectedAttachments()));

Expand Down Expand Up @@ -163,6 +166,20 @@ void EntryAttachmentsWidget::insertAttachments()
emit widgetUpdated();
}

void EntryAttachmentsWidget::newAttachments()
{
Q_ASSERT(m_entryAttachments);
Q_ASSERT(!isReadOnly());
if (isReadOnly()) {
return;
}

auto newWidnow = new NewEntryAttachmentsDialog(m_entryAttachments, this);
if (newWidnow->exec() == QDialog::Accepted) {
emit widgetUpdated();
}
}

void EntryAttachmentsWidget::removeSelectedAttachments()
{
Q_ASSERT(m_entryAttachments);
Expand Down Expand Up @@ -300,6 +317,7 @@ void EntryAttachmentsWidget::updateButtonsEnabled()
const bool hasSelection = m_ui->attachmentsView->selectionModel()->hasSelection();

m_ui->addAttachmentButton->setEnabled(!m_readOnly);
m_ui->newAttachmentButton->setEnabled(!m_readOnly);
m_ui->removeAttachmentButton->setEnabled(hasSelection && !m_readOnly);
m_ui->renameAttachmentButton->setEnabled(hasSelection && !m_readOnly);

Expand Down
1 change: 1 addition & 0 deletions src/gui/entry/EntryAttachmentsWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public slots:

private slots:
void insertAttachments();
void newAttachments();
void removeSelectedAttachments();
void renameSelectedAttachments();
void saveSelectedAttachments();
Expand Down
10 changes: 10 additions & 0 deletions src/gui/entry/EntryAttachmentsWidget.ui
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="newAttachmentButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>New</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="addAttachmentButton">
<property name="enabled">
Expand Down
81 changes: 81 additions & 0 deletions src/gui/entry/NewEntryAttachmentsDialog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright (C) 2021 KeePassXC Team <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "NewEntryAttachmentsDialog.h"
#include "core/EntryAttachments.h"
#include "ui_NewEntryAttachmentsDialog.h"

#include <QMessageBox>
#include <QPushButton>

#include <optional>

NewEntryAttachmentsDialog::NewEntryAttachmentsDialog(QPointer<EntryAttachments> attachments, QWidget* parent)
: QDialog(parent)
, m_attachments(std::move(attachments))
, m_ui(new Ui::NewEntryAttachmentsDialog)
{
m_ui->setupUi(this);

connect(m_ui->dialogButtons, SIGNAL(accepted()), this, SLOT(saveAttachment()));
connect(m_ui->dialogButtons, SIGNAL(rejected()), this, SLOT(reject()));
connect(m_ui->titleEdit, SIGNAL(textChanged(const QString&)), this, SLOT(fileNameTextChanged(const QString&)));

fileNameTextChanged(m_ui->titleEdit->text());
}

NewEntryAttachmentsDialog::~NewEntryAttachmentsDialog() = default;

std::optional<QString> NewEntryAttachmentsDialog::ValidateFileName(const QString& fileName) const
{
if (fileName.isEmpty()) {
return tr("Attachment name cannot be empty");
}

if (m_attachments->hasKey(fileName)) {
return tr("Attachment with the same name already exists");
}

return std::nullopt;
}

void NewEntryAttachmentsDialog::saveAttachment()
{
auto fileName = m_ui->titleEdit->text();
auto text = m_ui->attachmentTextEdit->toPlainText().toUtf8();

if (auto error = ValidateFileName(fileName); error) {
QMessageBox::warning(this, tr("Save attachment"), error.value());
return;
}

m_attachments->set(fileName, text);

accept();
}

void NewEntryAttachmentsDialog::fileNameTextChanged(const QString& fileName)
{
const auto error = ValidateFileName(fileName);

m_ui->errorLabel->setText(error.value_or(QString{}));
m_ui->errorLabel->setVisible(error.has_value());

if (auto okButton = m_ui->dialogButtons->button(QDialogButtonBox::Ok); okButton) {
okButton->setDisabled(error.has_value());
}
}
55 changes: 55 additions & 0 deletions src/gui/entry/NewEntryAttachmentsDialog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (C) 2021 KeePassXC Team <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef NEWENTRYATTACHMENTSWIDGET_H
#define NEWENTRYATTACHMENTSWIDGET_H

#include <QDialog>
#include <QPointer>

#include <optional>
#include <qwidget.h>

namespace Ui
{
class NewEntryAttachmentsDialog;
}

class QByteArray;
class EntryAttachments;

class NewEntryAttachmentsDialog : public QDialog
{
Q_OBJECT
public:
explicit NewEntryAttachmentsDialog(QPointer<EntryAttachments> attachments, QWidget* parent = nullptr);
~NewEntryAttachmentsDialog() override;

private slots:
void saveAttachment();
void fileNameTextChanged(const QString& fileName);

private:
std::optional<QString> ValidateFileName(const QString& fileName) const;

private:
QPointer<EntryAttachments> m_attachments;

QScopedPointer<Ui::NewEntryAttachmentsDialog> m_ui;
};

#endif // NEWENTRYATTACHMENTSWIDGET_H
55 changes: 55 additions & 0 deletions src/gui/entry/NewEntryAttachmentsDialog.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>NewEntryAttachmentsDialog</class>
<widget class="QDialog" name="NewEntryAttachmentsDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>402</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>New entry attachments</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLineEdit" name="titleEdit">
<property name="placeholderText">
<string>File name</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="errorLabel">
<property name="enabled">
<bool>true</bool>
</property>
<property name="styleSheet">
<string notr="true">color: #FF9696</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="attachmentTextEdit">
<property name="placeholderText">
<string>File contents...</string>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="dialogButtons">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

0 comments on commit eae01f6

Please sign in to comment.