From 4382e18ae139fb8609ec47d4afc5a83358e4921b Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Mon, 2 Sep 2024 16:30:34 -0400 Subject: [PATCH] Add database icon support --- share/translations/keepassxc_en.ts | 8 ++ src/core/Database.cpp | 18 ++++ src/core/Database.h | 2 + src/gui/DatabaseOpenWidget.cpp | 12 +++ src/gui/DatabaseOpenWidget.ui | 16 ++++ .../DatabaseSettingsWidgetGeneral.cpp | 88 ++++++++++++++++--- .../DatabaseSettingsWidgetGeneral.h | 6 +- .../DatabaseSettingsWidgetGeneral.ui | 54 +++++++++++- 8 files changed, 189 insertions(+), 15 deletions(-) diff --git a/share/translations/keepassxc_en.ts b/share/translations/keepassxc_en.ts index 55e22dbff5..daaa67606e 100644 --- a/share/translations/keepassxc_en.ts +++ b/share/translations/keepassxc_en.ts @@ -2230,6 +2230,14 @@ removed from the database. Clear + + Display icon: + + + + Select Database Icon + + DatabaseSettingsWidgetKeeShare diff --git a/src/core/Database.cpp b/src/core/Database.cpp index 4cccdbf61e..5734f9521d 100644 --- a/src/core/Database.cpp +++ b/src/core/Database.cpp @@ -1081,6 +1081,24 @@ void Database::setPublicColor(const QString& color) markAsModified(); } +int Database::publicIcon() +{ + if (publicCustomData().contains("KPXC_PUBLIC_ICON")) { + return publicCustomData().value("KPXC_PUBLIC_ICON").toInt(); + } + return -1; +} + +void Database::setPublicIcon(int iconIndex) +{ + if (iconIndex < 0) { + publicCustomData().remove("KPXC_PUBLIC_ICON"); + } else { + publicCustomData().insert("KPXC_PUBLIC_ICON", iconIndex); + } + markAsModified(); +} + void Database::markAsTemporaryDatabase() { m_isTemporaryDatabase = true; diff --git a/src/core/Database.h b/src/core/Database.h index 7b4efc003e..29314650e2 100644 --- a/src/core/Database.h +++ b/src/core/Database.h @@ -112,6 +112,8 @@ class Database : public ModifiableObject void setPublicName(const QString& name); QString publicColor(); void setPublicColor(const QString& color); + int publicIcon(); + void setPublicIcon(int iconIndex); Metadata* metadata(); const Metadata* metadata() const; diff --git a/src/gui/DatabaseOpenWidget.cpp b/src/gui/DatabaseOpenWidget.cpp index 72d349a996..14d8f4650e 100644 --- a/src/gui/DatabaseOpenWidget.cpp +++ b/src/gui/DatabaseOpenWidget.cpp @@ -228,12 +228,14 @@ void DatabaseOpenWidget::load(const QString& filename) m_ui->fileNameLabel->setRawText(m_filename); + // Set the public name if defined auto label = tr("Unlock KeePassXC Database"); if (!m_db->publicName().isEmpty()) { label.append(QString(": %1").arg(m_db->publicName())); } m_ui->labelHeadline->setText(label); + // Apply the public color to the central unlock stack if defined auto color = m_db->publicColor(); if (!color.isEmpty()) { m_ui->centralStack->setStyleSheet(QString("QStackedWidget {border: 4px solid %1}").arg(color)); @@ -241,6 +243,16 @@ void DatabaseOpenWidget::load(const QString& filename) m_ui->centralStack->setStyleSheet(""); } + // Show the database icon if defined + auto iconIndex = m_db->publicIcon(); + if (iconIndex >= 0 && iconIndex < databaseIcons()->count()) { + m_ui->dbIconLabel->setPixmap(databaseIcons()->icon(iconIndex, IconSize::Large)); + m_ui->dbIconLabel->setVisible(true); + } else { + m_ui->dbIconLabel->setPixmap({}); + m_ui->dbIconLabel->setVisible(false); + } + if (config()->get(Config::RememberLastKeyFiles).toBool()) { auto lastKeyFiles = config()->get(Config::LastKeyFiles).toHash(); if (lastKeyFiles.contains(m_filename)) { diff --git a/src/gui/DatabaseOpenWidget.ui b/src/gui/DatabaseOpenWidget.ui index f9dc5b7619..1ef04a5287 100644 --- a/src/gui/DatabaseOpenWidget.ui +++ b/src/gui/DatabaseOpenWidget.ui @@ -59,6 +59,22 @@ 9 + + + + + 32 + 32 + + + + + + + true + + + diff --git a/src/gui/dbsettings/DatabaseSettingsWidgetGeneral.cpp b/src/gui/dbsettings/DatabaseSettingsWidgetGeneral.cpp index aa85a859db..c8a9ec8dcd 100644 --- a/src/gui/dbsettings/DatabaseSettingsWidgetGeneral.cpp +++ b/src/gui/dbsettings/DatabaseSettingsWidgetGeneral.cpp @@ -19,10 +19,15 @@ #include "ui_DatabaseSettingsWidgetGeneral.h" #include +#include +#include +#include #include "core/Clock.h" #include "core/Group.h" #include "core/Metadata.h" +#include "gui/DatabaseIcons.h" +#include "gui/IconModels.h" #include "gui/MessageBox.h" DatabaseSettingsWidgetGeneral::DatabaseSettingsWidgetGeneral(QWidget* parent) @@ -31,8 +36,10 @@ DatabaseSettingsWidgetGeneral::DatabaseSettingsWidgetGeneral(QWidget* parent) { m_ui->setupUi(this); - connect(m_ui->dbPublicColorButton, &QPushButton::clicked, this, &DatabaseSettingsWidgetGeneral::pickColor); - connect(m_ui->dbPublicColorClearButton, &QPushButton::clicked, this, [this] { setupColorButton({}); }); + connect(m_ui->dbPublicColorButton, &QPushButton::clicked, this, &DatabaseSettingsWidgetGeneral::pickPublicColor); + connect(m_ui->dbPublicColorClearButton, &QPushButton::clicked, this, [this] { setupPublicColorButton({}); }); + connect(m_ui->dbPublicIconButton, &QPushButton::clicked, this, &DatabaseSettingsWidgetGeneral::pickPublicIcon); + connect(m_ui->dbPublicIconClearButton, &QPushButton::clicked, this, [this] { setupPublicIconButton(-1); }); connect(m_ui->historyMaxItemsCheckBox, SIGNAL(toggled(bool)), m_ui->historyMaxItemsSpinBox, SLOT(setEnabled(bool))); connect(m_ui->historyMaxSizeCheckBox, SIGNAL(toggled(bool)), m_ui->historyMaxSizeSpinBox, SLOT(setEnabled(bool))); @@ -52,7 +59,8 @@ void DatabaseSettingsWidgetGeneral::initialize() m_ui->compressionCheckbox->setChecked(m_db->compressionAlgorithm() != Database::CompressionNone); m_ui->dbPublicName->setText(m_db->publicName()); - setupColorButton(m_db->publicColor()); + setupPublicColorButton(m_db->publicColor()); + setupPublicIconButton(m_db->publicIcon()); if (meta->historyMaxItems() > -1) { m_ui->historyMaxItemsSpinBox->setValue(meta->historyMaxItems()); @@ -126,6 +134,7 @@ bool DatabaseSettingsWidgetGeneral::saveSettings() m_db->setPublicName(m_ui->dbPublicName->text()); m_db->setPublicColor(m_ui->dbPublicColorButton->property("color").toString()); + m_db->setPublicIcon(m_ui->dbPublicIconButton->property("iconIndex").toInt()); bool truncate = false; @@ -167,21 +176,78 @@ bool DatabaseSettingsWidgetGeneral::saveSettings() return true; } -void DatabaseSettingsWidgetGeneral::pickColor() +void DatabaseSettingsWidgetGeneral::pickPublicColor() { auto oldColor = QColor(m_ui->dbPublicColorButton->property("color").toString()); - setupColorButton(QColorDialog::getColor(oldColor)); + auto newColor = QColorDialog::getColor(oldColor); + if (newColor.isValid()) { + setupPublicColorButton(newColor); + } } -void DatabaseSettingsWidgetGeneral::setupColorButton(const QColor& color) +void DatabaseSettingsWidgetGeneral::setupPublicColorButton(const QColor& color) { m_ui->dbPublicColorClearButton->setVisible(color.isValid()); - auto button = m_ui->dbPublicColorButton; if (color.isValid()) { - button->setStyleSheet(QString("background-color:%1").arg(color.name())); - button->setProperty("color", color.name()); + m_ui->dbPublicColorButton->setStyleSheet(QString("background-color:%1").arg(color.name())); + m_ui->dbPublicColorButton->setProperty("color", color.name()); + } else { + m_ui->dbPublicColorButton->setStyleSheet(""); + m_ui->dbPublicColorButton->setProperty("color", {}); + } +} + +void DatabaseSettingsWidgetGeneral::pickPublicIcon() +{ + QDialog dialog(this); + dialog.setSizeGripEnabled(false); + dialog.setWindowTitle(tr("Select Database Icon")); + + auto iconList = new QListView; + iconList->setFlow(QListView::LeftToRight); + iconList->setMovement(QListView::Static); + iconList->setResizeMode(QListView::Adjust); + iconList->setWrapping(true); + iconList->setSpacing(4); + + auto iconModel = new DefaultIconModel; + iconList->setModel(iconModel); + if (m_ui->dbPublicIconButton->property("iconIndex").toInt() >= 0) { + iconList->setCurrentIndex(iconModel->index(m_ui->dbPublicIconButton->property("iconIndex").toInt(), 0)); + } else { + iconList->setCurrentIndex(iconModel->index(0, 0)); + } + + auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + auto layout = new QVBoxLayout(&dialog); + layout->addWidget(iconList); + layout->addWidget(buttonBox); + + // Resize the dialog to fit the default icon list + auto cellSize = iconList->sizeHintForIndex(iconModel->index(0, 0)); + auto spacing = iconList->spacing() * 2; + dialog.resize((cellSize.width() + spacing) * 15, (cellSize.height() + spacing) * 6 + 16); + + connect(iconList, &QListView::doubleClicked, &dialog, &QDialog::accept); + connect(buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); + connect( + &dialog, &QDialog::accepted, this, [this, iconList] { setupPublicIconButton(iconList->currentIndex().row()); }); + + dialog.exec(); +} + +void DatabaseSettingsWidgetGeneral::setupPublicIconButton(int iconIndex) +{ + auto valid = iconIndex >= 0 && iconIndex < databaseIcons()->count(); + m_ui->dbPublicIconClearButton->setVisible(valid); + if (valid) { + m_ui->dbPublicIconButton->setIcon(databaseIcons()->icon(iconIndex)); + m_ui->dbPublicIconButton->setProperty("iconIndex", iconIndex); + m_ui->dbPublicIconClearButton->setVisible(true); } else { - button->setStyleSheet(""); - button->setProperty("color", {}); + m_ui->dbPublicIconButton->setIcon(QIcon()); + m_ui->dbPublicIconButton->setProperty("iconIndex", -1); + m_ui->dbPublicIconClearButton->setVisible(false); } } diff --git a/src/gui/dbsettings/DatabaseSettingsWidgetGeneral.h b/src/gui/dbsettings/DatabaseSettingsWidgetGeneral.h index 2089f9c3a5..7c0c1ebe9a 100644 --- a/src/gui/dbsettings/DatabaseSettingsWidgetGeneral.h +++ b/src/gui/dbsettings/DatabaseSettingsWidgetGeneral.h @@ -46,8 +46,10 @@ public slots: void showEvent(QShowEvent* event) override; private slots: - void pickColor(); - void setupColorButton(const QColor& color); + void pickPublicColor(); + void setupPublicColorButton(const QColor& color); + void pickPublicIcon(); + void setupPublicIconButton(int iconIndex); private: const QScopedPointer m_ui; diff --git a/src/gui/dbsettings/DatabaseSettingsWidgetGeneral.ui b/src/gui/dbsettings/DatabaseSettingsWidgetGeneral.ui index 1c15cb2351..324ae6d3db 100644 --- a/src/gui/dbsettings/DatabaseSettingsWidgetGeneral.ui +++ b/src/gui/dbsettings/DatabaseSettingsWidgetGeneral.ui @@ -145,8 +145,8 @@ - 25 - 25 + 30 + 30 @@ -182,6 +182,56 @@ + + + + Display icon: + + + + + + + + + + 30 + 30 + + + + + + + + 30 + 30 + + + + + + + + Clear + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + +