From 1a87e30b95f0cda7b31e641a79ffc5bb46fb7521 Mon Sep 17 00:00:00 2001 From: thez3ro Date: Thu, 17 Aug 2017 21:02:21 +0200 Subject: [PATCH] add preview panel for entries and groups --- COPYING | 1 + .../application/22x22/actions/chronometer.png | Bin 0 -> 1675 bytes src/CMakeLists.txt | 1 + src/core/Group.cpp | 12 + src/core/Group.h | 1 + src/gui/DatabaseWidget.cpp | 46 +- src/gui/DatabaseWidget.h | 9 + src/gui/DetailsWidget.cpp | 213 +++++++ src/gui/DetailsWidget.h | 60 ++ src/gui/DetailsWidget.ui | 552 ++++++++++++++++++ src/gui/SettingsWidget.cpp | 4 + src/gui/SettingsWidgetGeneral.ui | 7 + src/gui/SettingsWidgetSecurity.ui | 7 + src/gui/entry/EntryView.cpp | 7 + src/gui/entry/EntryView.h | 2 + src/gui/group/GroupView.cpp | 7 + src/gui/group/GroupView.h | 2 + 17 files changed, 930 insertions(+), 1 deletion(-) create mode 100644 share/icons/application/22x22/actions/chronometer.png create mode 100644 src/gui/DetailsWidget.cpp create mode 100644 src/gui/DetailsWidget.h create mode 100644 src/gui/DetailsWidget.ui diff --git a/COPYING b/COPYING index 403e4564b..e12f4534c 100644 --- a/COPYING +++ b/COPYING @@ -156,6 +156,7 @@ License: LGPL-2.1 Comment: based on Nuvola icon theme Files: share/icons/application/*/actions/application-exit.png + share/icons/application/*/actions/chronometer.png share/icons/application/*/actions/configure.png share/icons/application/*/actions/dialog-close.png share/icons/application/*/actions/dialog-ok.png diff --git a/share/icons/application/22x22/actions/chronometer.png b/share/icons/application/22x22/actions/chronometer.png new file mode 100644 index 0000000000000000000000000000000000000000..71d6eabe5f7447958918c8c5d73ab060ada1d78c GIT binary patch literal 1675 zcmV;626Xv}P)izt!0M$-mqryuIZXgCJUomu zXU+fsMn*=qWipvpqmk$@HBI}jBuTJs8=U))BpI?Sqf{!bRjQRs%Z23+BC+U?+IH@| zOuqlmpc?%7KPEo@P9~Fa=){Q=IDh^;0N~uYbKTE(KR>j6`}Q~LjXLJ%=doHW@}}d! z_gpZ>5DrJs)wQ2mTU%im#)BvNleulN=#fw;99~??U!IwpU2z=e>i?oRd-iPip}s?x z6N$vZnb{dU-q=7(D#c}4rbHqE-}h0iR{7%6B0YJc^JqLy2M>M^j4>>HHE*O^w0qfX zwz#~qd~;-EMlc=+lVxIzk)kM2Rh3-VMIfM(CJ0+OucRCwK1Lv5voc9LzLL zwQXnHdzNKEmPB-ScT+GJguocobQ=2H9KrKIw3!+sf@RyVZ5zG4z0{iCfl_G$?d|Qa zA2@KJ2LN3hy$EKSW`9ddOEQ7K_FDi3qOi!frOH-e{0x7_be4+-4Ik zFTYHWu3sl55TN^0Q}8^GlF1}gRV7A5oOAe|M?`?E$bH9ta%^)lNs=;+Mg#F!44S6# zfU0si97Zr2<-|E+ZEgHNw{G#@zw-`{gu~diYZqsXfrvO01fEPLvAd&#bI(UC7W>wP zKmK93tE+2*d9J5gjRqKFV1huRD3YYA5EO-ES%x48^l)*JjPY^O(rM79o~=Yg2&gI% zW2l+6z*0WnpUdUqVx?MHw`?1p=YRkZ08tPCL4YJlxP9{`Ub}Ds=0_hPBFg|{ApU<< z0n4%wjzqCiTv?l(oP3FhG;w`>eNxx;pP8nCjZz6gRpo(T5a1lH=iyLa9{`|!>J;2& z69H8P-@Gw6=iD?+lq(fPqA^q|m8l~~j>rHCtXwYtYiVf-qA1e(`Z|wq+XmNhU|SX^ z0GxAfSr+$2k$bWX5OLr4Vb*F~k|fBojCefGv)L?aX6^d)^t1&4Y)5*>SGmR9gyXpQ z^!9D4R4QZ`26V$9P6T3%h%s_>og`6&@B8F)j&iw7^?IGMxg0#tr))O+=+XM4e-{b` z2LOa>rAmsdEHK87sllLJE|>YPjt->LX)r<9{1}`=4hBJj09oE_xJWpRnVA_lu1C7A zV_{)ocgp=Wl?wTuhgz+MjZz8OY?g|}BCLi*Yinzmnwq+D@BY1CUA=O34FEJv z!~Fa_XzR0SZ*P}0O*^b<+HX2KI(ql+-3v|A5DJALZsrTivQVv5kG878+CzHuHT3cIRNF)+1vLvJFG|f_}G`+gI`boW3|9ifW zU$t$!{3z{x5B` V=tXj1`11e&002ovPDHLkV1fyI8=(LI literal 0 HcmV?d00001 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3f0ba7823..97ff5edf2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -98,6 +98,7 @@ set(keepassx_SOURCES gui/DatabaseTabWidget.cpp gui/DatabaseWidget.cpp gui/DatabaseWidgetStateSync.cpp + gui/DetailsWidget.cpp gui/DialogyWidget.cpp gui/DragTabBar.cpp gui/EditWidget.cpp diff --git a/src/core/Group.cpp b/src/core/Group.cpp index 644d2ff67..fa48d8cec 100644 --- a/src/core/Group.cpp +++ b/src/core/Group.cpp @@ -435,6 +435,18 @@ void Group::setParent(Database* db) QObject::setParent(db); } +QStringList Group::hierarchy() +{ + QStringList hierarchy; + Group* group = this; + while (group->parentGroup()) { + hierarchy << group->name(); + + group = group->parentGroup(); + } + return hierarchy; +} + Database* Group::database() { return m_db; diff --git a/src/core/Group.h b/src/core/Group.h index 27400703e..2a9d2b18c 100644 --- a/src/core/Group.h +++ b/src/core/Group.h @@ -106,6 +106,7 @@ public: Group* parentGroup(); const Group* parentGroup() const; void setParent(Group* parent, int index = -1); + QStringList hierarchy(); Database* database(); const Database* database() const; diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index 6a425b5d7..0b83002e8 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -47,6 +47,7 @@ #include "gui/TotpDialog.h" #include "gui/DatabaseOpenWidget.h" #include "gui/DatabaseSettingsWidget.h" +#include "gui/DetailsWidget.h" #include "gui/KeePass1OpenWidget.h" #include "gui/MessageBox.h" #include "gui/UnlockDatabaseWidget.h" @@ -74,6 +75,9 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent) mainLayout->addLayout(layout); m_splitter = new QSplitter(m_mainWidget); m_splitter->setChildrenCollapsible(false); + m_detailSplitter = new QSplitter(m_mainWidget); + m_detailSplitter->setOrientation(Qt::Vertical); + m_detailSplitter->setChildrenCollapsible(true); QWidget* rightHandSideWidget = new QWidget(m_splitter); @@ -99,10 +103,18 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent) "border: 2px solid rgb(190, 190, 190);" "border-radius: 5px;"); + m_detailsView = new DetailsWidget(this); + QVBoxLayout* vLayout = new QVBoxLayout(rightHandSideWidget); vLayout->setMargin(0); vLayout->addWidget(m_searchingLabel); - vLayout->addWidget(m_entryView); + vLayout->addWidget(m_detailSplitter); + + m_detailSplitter->addWidget(m_entryView); + m_detailSplitter->addWidget(m_detailsView); + + m_detailSplitter->setStretchFactor(0, 80); + m_detailSplitter->setStretchFactor(1, 20); m_searchingLabel->setVisible(false); @@ -180,6 +192,12 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent) connect(&m_fileWatchUnblockTimer, SIGNAL(timeout()), this, SLOT(unblockAutoReload())); connect(this, SIGNAL(currentChanged(int)), this, SLOT(emitCurrentModeChanged())); + connect(m_groupView, SIGNAL(groupPressed(Group*)), SLOT(emitPressedGroup(Group*))); + //connect(m_groupView, SIGNAL(groupChanged(Group*)), SLOT(emitPressedGroup(Group*))); + connect(m_entryView, SIGNAL(entryPressed(Entry*)), SLOT(emitPressedEntry(Entry*))); + //connect(m_entryView, SIGNAL(entrySelectionChanged()), SLOT(emitPressedEntry())); + connect(m_editEntryWidget, SIGNAL(editFinished(bool)), SLOT(emitPressedEntry())); + m_databaseModified = false; m_fileWatchTimer.setSingleShot(true); @@ -1041,6 +1059,32 @@ void DatabaseWidget::emitEntryContextMenuRequested(const QPoint& pos) emit entryContextMenuRequested(m_entryView->viewport()->mapToGlobal(pos)); } +void DatabaseWidget::emitPressedEntry() +{ + Entry* currentEntry = m_entryView->currentEntry(); + emitPressedEntry(currentEntry); +} + +void DatabaseWidget::emitPressedEntry(Entry* currentEntry) +{ + if (!currentEntry) { + // if no entry is pressed, leave in details the last entry + return; + } + + emit pressedEntry(currentEntry); +} + +void DatabaseWidget::emitPressedGroup(Group* currentGroup) +{ + if (!currentGroup) { + // if no group is pressed, leave in details the last group + return; + } + + emit pressedGroup(currentGroup); +} + bool DatabaseWidget::dbHasKey() const { return m_db->hasKey(); diff --git a/src/gui/DatabaseWidget.h b/src/gui/DatabaseWidget.h index 934820009..141248bd4 100644 --- a/src/gui/DatabaseWidget.h +++ b/src/gui/DatabaseWidget.h @@ -27,6 +27,7 @@ #include "core/Uuid.h" #include "gui/entry/EntryModel.h" +#include "gui/DetailsWidget.h" #include "gui/MessageWidget.h" #include "gui/csvImport/CsvImportWizard.h" @@ -47,6 +48,7 @@ class QSplitter; class QLabel; class UnlockDatabaseWidget; class MessageWidget; +class DetailsWidget; class UnlockDatabaseDialog; class QFileSystemWatcher; @@ -115,6 +117,8 @@ signals: void databaseMerged(Database* mergedDb); void groupContextMenuRequested(const QPoint& globalPos); void entryContextMenuRequested(const QPoint& globalPos); + void pressedEntry(Entry* selectedEntry); + void pressedGroup(Group* selectedGroup); void unlockedDatabase(); void listModeAboutToActivate(); void listModeActivated(); @@ -179,6 +183,9 @@ private slots: void switchToGroupEdit(Group* entry, bool create); void emitGroupContextMenuRequested(const QPoint& pos); void emitEntryContextMenuRequested(const QPoint& pos); + void emitPressedEntry(); + void emitPressedEntry(Entry* currentEntry); + void emitPressedGroup(Group* currentGroup); void updateMasterKey(bool accepted); void openDatabase(bool accepted); void mergeDatabase(bool accepted); @@ -209,6 +216,7 @@ private: UnlockDatabaseWidget* m_unlockDatabaseWidget; UnlockDatabaseDialog* m_unlockDatabaseDialog; QSplitter* m_splitter; + QSplitter* m_detailSplitter; GroupView* m_groupView; EntryView* m_entryView; QLabel* m_searchingLabel; @@ -219,6 +227,7 @@ private: Uuid m_groupBeforeLock; Uuid m_entryBeforeLock; MessageWidget* m_messageWidget; + DetailsWidget* m_detailsView; // Search state QString m_lastSearchText; diff --git a/src/gui/DetailsWidget.cpp b/src/gui/DetailsWidget.cpp new file mode 100644 index 000000000..d506d551e --- /dev/null +++ b/src/gui/DetailsWidget.cpp @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2012 Felix Geyer + * Copyright (C) 2017 KeePassXC Team + * + * 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 . + */ + +#include "DetailsWidget.h" +#include "ui_DetailsWidget.h" + +#include + +#include "core/Config.h" +#include "core/FilePath.h" +#include "core/TimeInfo.h" + +DetailsWidget::DetailsWidget(QWidget* parent) + : QWidget(parent) + , m_ui(new Ui::DetailsWidget()) + , m_currentEntry(nullptr) + , m_currentGroup(nullptr) +{ + m_ui->setupUi(this); + + connect(parent, SIGNAL(pressedEntry(Entry*)), SLOT(getSelectedEntry(Entry*))); + connect(parent, SIGNAL(pressedGroup(Group*)), SLOT(getSelectedGroup(Group*))); + + m_ui->totpButton->setIcon(filePath()->icon("actions", "chronometer")); + m_ui->closeButton->setIcon(filePath()->icon("actions", "dialog-close")); + m_ui->togglePasswordButton->setIcon(filePath()->onOffIcon("actions", "password-show")); + + connect(m_ui->totpButton, SIGNAL(toggled(bool)), SLOT(showTotp(bool))); + connect(m_ui->closeButton, SIGNAL(toggled(bool)), SLOT(hideDetails())); + connect(m_ui->togglePasswordButton, SIGNAL(toggled(bool)), SLOT(togglePasswordShown(bool))); + + this->hide(); +} + +DetailsWidget::~DetailsWidget() +{ +} + +void DetailsWidget::getSelectedEntry(Entry* selectedEntry) +{ + m_currentEntry = selectedEntry; + + if (!config()->get("GUI/HideDetailsView").toBool()) { + this->show(); + } + + m_ui->stackedWidget->setCurrentIndex(EntryPreview); + + m_ui->totpButton->hide(); + m_ui->totpWidget->hide(); + m_ui->totpButton->setChecked(false); + + m_ui->entryIcon->setPixmap(m_currentEntry->iconPixmap()); + + QStringList hierarchy = m_currentEntry->group()->hierarchy(); + QString title = " / "; + for (QString parent : hierarchy) { + title.append(parent); + title.append(" / "); + } + title.append(m_currentEntry->title()); + m_ui->titleLabel->setText(title); + + m_ui->usernameLabel->setText(m_currentEntry->username()); + m_ui->groupLabel->setText(m_currentEntry->group()->name()); + m_ui->notesEdit->setText(m_currentEntry->notes()); + + if (!config()->get("security/hidepassworddetails").toBool()) { + m_ui->passwordEdit->setText(m_currentEntry->password()); + m_ui->togglePasswordButton->show(); + } else { + m_ui->passwordEdit->setText("****"); + m_ui->togglePasswordButton->hide(); + } + + QString url = m_currentEntry->webUrl(); + if (url != "") { + url = QString("%2").arg(url).arg(shortUrl(url)); + m_ui->urlLabel->setOpenExternalLinks(true); + } else { + url = shortUrl(m_currentEntry->resolveMultiplePlaceholders(m_currentEntry->url())); + m_ui->urlLabel->setOpenExternalLinks(false); + } + m_ui->urlLabel->setText(url); + + TimeInfo entryTime = m_currentEntry->timeInfo(); + if (entryTime.expires()) { + m_ui->expirationLabel->setText(entryTime.expiryTime().toString(Qt::DefaultLocaleShortDate)); + } else { + m_ui->expirationLabel->setText(tr("Never")); + } + + m_ui->creationLabel->setText(entryTime.creationTime().toString(Qt::DefaultLocaleShortDate)); + m_ui->modifyLabel->setText(entryTime.lastModificationTime().toString(Qt::DefaultLocaleShortDate)); + m_ui->accessLabel->setText(entryTime.lastAccessTime().toString(Qt::DefaultLocaleShortDate)); + + if (m_currentEntry->hasTotp()) { + m_ui->totpButton->show(); + updateTotp(); + + m_step = m_currentEntry->totpStep(); + + m_timer = new QTimer(this); + connect(m_timer, SIGNAL(timeout()), this, SLOT(updateTotp())); + m_timer->start(m_step * 10); + } +} + +void DetailsWidget::getSelectedGroup(Group* selectedGroup) +{ + m_currentGroup = selectedGroup; + + if (!config()->get("GUI/HideDetailsView").toBool()) { + this->show(); + } + + m_ui->stackedWidget->setCurrentIndex(GroupPreview); + + m_ui->totpButton->hide(); + m_ui->totpWidget->hide(); + + m_ui->entryIcon->setPixmap(m_currentGroup->iconPixmap()); + + QStringList hierarchy = m_currentGroup->hierarchy(); + QString title = " / "; + for (QString parent : hierarchy) { + title.append(parent); + title.append(" / "); + } + m_ui->titleLabel->setText(title); + + m_ui->notesEdit->setText(m_currentGroup->notes()); + + QString searching = tr("Disabled"); + if (m_currentGroup->resolveSearchingEnabled()) { + searching = tr("Enabled"); + } + m_ui->searchingLabel->setText(searching); + + QString autotype = tr("Disabled"); + if (m_currentGroup->resolveAutoTypeEnabled()) { + autotype = tr("Enabled"); + } + m_ui->autotypeLabel->setText(autotype); + + TimeInfo groupTime = m_currentGroup->timeInfo(); + if (groupTime.expires()) { + m_ui->groupExpirationLabel->setText(groupTime.expiryTime().toString(Qt::DefaultLocaleShortDate)); + } else { + m_ui->groupExpirationLabel->setText(tr("Never")); + } + + m_ui->groupCreationLabel->setText(groupTime.creationTime().toString(Qt::DefaultLocaleShortDate)); + m_ui->groupModifyLabel->setText(groupTime.lastModificationTime().toString(Qt::DefaultLocaleShortDate)); + m_ui->groupAccessLabel->setText(groupTime.lastAccessTime().toString(Qt::DefaultLocaleShortDate)); +} + +void DetailsWidget::updateTotp() +{ + QString totpCode = m_currentEntry->totp(); + QString firstHalf = totpCode.left(totpCode.size()/2); + QString secondHalf = totpCode.right(totpCode.size()/2); + m_ui->totpLabel->setText(firstHalf + " " + secondHalf); +} + +void DetailsWidget::showTotp(bool visible) +{ + if (visible){ + m_ui->totpWidget->show(); + } else { + m_ui->totpWidget->hide(); + } +} + +QString DetailsWidget::shortUrl(QString url) +{ + QString newurl = ""; + if (url.length() > 60) { + newurl.append(url.left(20)); + newurl.append("..."); + newurl.append(url.right(20)); + return newurl; + } + return url; +} + +void DetailsWidget::hideDetails() +{ + this->hide(); +} + +void DetailsWidget::togglePasswordShown(bool showing) +{ + m_ui->passwordEdit->setShowPassword(showing); + bool blockSignals = m_ui->togglePasswordButton->blockSignals(true); + m_ui->togglePasswordButton->setChecked(showing); + m_ui->togglePasswordButton->blockSignals(blockSignals); +} \ No newline at end of file diff --git a/src/gui/DetailsWidget.h b/src/gui/DetailsWidget.h new file mode 100644 index 000000000..89e6cf62b --- /dev/null +++ b/src/gui/DetailsWidget.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2017 KeePassXC Team + * + * 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 . + */ + +#ifndef KEEPASSX_DETAILSWIDGET_H +#define KEEPASSX_DETAILSWIDGET_H + +#include + +#include "gui/DatabaseWidget.h" + +namespace Ui { + class DetailsWidget; +} + +class DetailsWidget : public QWidget +{ + Q_OBJECT + +public: + explicit DetailsWidget(QWidget* parent = nullptr); + ~DetailsWidget(); + + enum StackedWidgetIndex + { + EntryPreview = 0, + GroupPreview = 1, + }; + +private slots: + void getSelectedEntry(Entry* selectedEntry); + void getSelectedGroup(Group* selectedGroup); + void showTotp(bool visible); + void updateTotp(); + void hideDetails(); + void togglePasswordShown(bool showing); + +private: + const QScopedPointer m_ui; + Entry* m_currentEntry; + Group* m_currentGroup; + quint8 m_step; + QTimer* m_timer; + QString shortUrl(QString url); +}; + +#endif // KEEPASSX_DETAILSWIDGET_H diff --git a/src/gui/DetailsWidget.ui b/src/gui/DetailsWidget.ui new file mode 100644 index 000000000..fb6b7fb24 --- /dev/null +++ b/src/gui/DetailsWidget.ui @@ -0,0 +1,552 @@ + + + DetailsWidget + + + + 0 + 0 + 630 + 207 + + + + + 0 + 0 + + + + + 16777215 + 235 + + + + + + + QLayout::SetDefaultConstraint + + + + + + 0 + 0 + + + + + 20 + 16777215 + + + + + + + + + + + + 0 + 0 + + + + + 12 + + + + Qt::AutoText + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + + + 0 + + + 0 + + + + + + 10 + 75 + true + + + + + + + + + + + + + + Generate TOTP Token + + + + + + true + + + + + + + Generate TOTP Token + + + + + + true + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + + 0 + 0 + + + + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + 75 + true + + + + Group + + + + + + + + 9 + 75 + true + + + + URL + + + + + + + + 75 + true + + + + Password + + + + + + + + 75 + true + + + + Username + + + + + + + + + + + + + + + + 0 + 0 + + + + 999 + + + true + + + + + + + true + + + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + + + + 75 + true + + + + Modification + + + + + + + + 75 + true + + + + Access + + + + + + + + + + + + + + 75 + true + + + + Creation + + + + + + + + 75 + true + + + + Expiration + + + + + + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + + + + 75 + true + + + + Autotype + + + + + + + + + + + 75 + true + + + + Searching + + + + + + + + + + + 75 + true + + + + Expiration + + + + + + + + + + + + + + 75 + true + + + + Modification + + + + + + + + 75 + true + + + + Access + + + + + + + + + + + + + + 75 + true + + + + Creation + + + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + 0 + 50 + + + + + 16777215 + 50 + + + + Qt::ClickFocus + + + true + + + + + + + Notes + + + + + + + + + Qt::Horizontal + + + + + + + Search + + + + + Clear + + + + + + PasswordEdit + QLineEdit +
gui/PasswordEdit.h
+ 1 +
+
+ + +
diff --git a/src/gui/SettingsWidget.cpp b/src/gui/SettingsWidget.cpp index 8385bf262..aa0e56648 100644 --- a/src/gui/SettingsWidget.cpp +++ b/src/gui/SettingsWidget.cpp @@ -134,6 +134,7 @@ void SettingsWidget::loadSettings() m_generalUi->languageComboBox->setCurrentIndex(defaultIndex); } + m_generalUi->detailsHideCheckBox->setChecked(config()->get("GUI/HideDetailsView").toBool()); m_generalUi->systrayShowCheckBox->setChecked(config()->get("GUI/ShowTrayIcon").toBool()); m_generalUi->systrayMinimizeToTrayCheckBox->setChecked(config()->get("GUI/MinimizeToTray").toBool()); m_generalUi->systrayMinimizeOnCloseCheckBox->setChecked(config()->get("GUI/MinimizeOnClose").toBool()); @@ -160,6 +161,7 @@ void SettingsWidget::loadSettings() m_secUi->fallbackToGoogle->setChecked(config()->get("security/IconDownloadFallbackToGoogle").toBool()); m_secUi->passwordCleartextCheckBox->setChecked(config()->get("security/passwordscleartext").toBool()); + m_secUi->passwordDetailsCleartextCheckBox->setChecked(config()->get("security/hidepassworddetails").toBool()); m_secUi->passwordRepeatCheckBox->setChecked(config()->get("security/passwordsrepeat").toBool()); @@ -203,6 +205,7 @@ void SettingsWidget::saveSettings() config()->set("GUI/Language", m_generalUi->languageComboBox->itemData(currentLangIndex).toString()); + config()->set("GUI/HideDetailsView", m_generalUi->detailsHideCheckBox->isChecked()); config()->set("GUI/ShowTrayIcon", m_generalUi->systrayShowCheckBox->isChecked()); config()->set("GUI/MinimizeToTray", m_generalUi->systrayMinimizeToTrayCheckBox->isChecked()); config()->set("GUI/MinimizeOnClose", m_generalUi->systrayMinimizeOnCloseCheckBox->isChecked()); @@ -226,6 +229,7 @@ void SettingsWidget::saveSettings() config()->set("security/IconDownloadFallbackToGoogle", m_secUi->fallbackToGoogle->isChecked()); config()->set("security/passwordscleartext", m_secUi->passwordCleartextCheckBox->isChecked()); + config()->set("security/hidepassworddetails", m_secUi->passwordDetailsCleartextCheckBox->isChecked()); config()->set("security/passwordsrepeat", m_secUi->passwordRepeatCheckBox->isChecked()); // Security: clear storage if related settings are disabled diff --git a/src/gui/SettingsWidgetGeneral.ui b/src/gui/SettingsWidgetGeneral.ui index 1e62104cc..7dc4487cf 100644 --- a/src/gui/SettingsWidgetGeneral.ui +++ b/src/gui/SettingsWidgetGeneral.ui @@ -153,6 +153,13 @@ + + + + Hide the Details view + + + diff --git a/src/gui/SettingsWidgetSecurity.ui b/src/gui/SettingsWidgetSecurity.ui index 4233fdbd1..53c69db6d 100644 --- a/src/gui/SettingsWidgetSecurity.ui +++ b/src/gui/SettingsWidgetSecurity.ui @@ -136,6 +136,13 @@ + + + + Hide passwords in the preview panel + + + diff --git a/src/gui/entry/EntryView.cpp b/src/gui/entry/EntryView.cpp index 1bdd4fbcf..ac8e66782 100644 --- a/src/gui/entry/EntryView.cpp +++ b/src/gui/entry/EntryView.cpp @@ -49,6 +49,8 @@ EntryView::EntryView(QWidget* parent) connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SIGNAL(entrySelectionChanged())); connect(m_model, SIGNAL(switchedToEntryListMode()), SLOT(switchToEntryListMode())); connect(m_model, SIGNAL(switchedToGroupMode()), SLOT(switchToGroupMode())); + + connect(this, SIGNAL(clicked(QModelIndex)), SLOT(emitEntryPressed(QModelIndex))); } void EntryView::keyPressEvent(QKeyEvent* event) @@ -99,6 +101,11 @@ void EntryView::emitEntryActivated(const QModelIndex& index) emit entryActivated(entry, static_cast(m_sortModel->mapToSource(index).column())); } +void EntryView::emitEntryPressed(const QModelIndex& index) +{ + emit entryPressed(entryFromIndex(index)); +} + void EntryView::setModel(QAbstractItemModel* model) { Q_UNUSED(model); diff --git a/src/gui/entry/EntryView.h b/src/gui/entry/EntryView.h index 6a545f62a..14c6b7ccc 100644 --- a/src/gui/entry/EntryView.h +++ b/src/gui/entry/EntryView.h @@ -47,6 +47,7 @@ public slots: signals: void entryActivated(Entry* entry, EntryModel::ModelColumn column); + void entryPressed(Entry* entry); void entrySelectionChanged(); protected: @@ -54,6 +55,7 @@ protected: private slots: void emitEntryActivated(const QModelIndex& index); + void emitEntryPressed(const QModelIndex& index); void switchToEntryListMode(); void switchToGroupMode(); diff --git a/src/gui/group/GroupView.cpp b/src/gui/group/GroupView.cpp index e9649e441..82d01e31c 100644 --- a/src/gui/group/GroupView.cpp +++ b/src/gui/group/GroupView.cpp @@ -41,6 +41,8 @@ GroupView::GroupView(Database* db, QWidget* parent) connect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), SLOT(emitGroupChanged())); + connect(this, SIGNAL(clicked(QModelIndex)), SLOT(emitGroupPressed(QModelIndex))); + modelReset(); setDragEnabled(true); @@ -126,6 +128,11 @@ void GroupView::emitGroupChanged() emit groupChanged(currentGroup()); } +void GroupView::emitGroupPressed(const QModelIndex& index) +{ + emit groupPressed(m_model->groupFromIndex(index)); +} + void GroupView::syncExpandedState(const QModelIndex& parent, int start, int end) { for (int row = start; row <= end; row++) { diff --git a/src/gui/group/GroupView.h b/src/gui/group/GroupView.h index eaa290725..0a084425d 100644 --- a/src/gui/group/GroupView.h +++ b/src/gui/group/GroupView.h @@ -38,11 +38,13 @@ public: signals: void groupChanged(Group* group); + void groupPressed(Group* group); private slots: void expandedChanged(const QModelIndex& index); void emitGroupChanged(const QModelIndex& index); void emitGroupChanged(); + void emitGroupPressed(const QModelIndex& index); void syncExpandedState(const QModelIndex& parent, int start, int end); void modelReset();