0
0
mirror of https://github.com/keepassxreboot/keepassxc.git synced 2024-09-20 04:12:15 +02:00

add preview panel for entries and groups

This commit is contained in:
thez3ro 2017-08-17 21:02:21 +02:00
parent 03eda06a38
commit 1a87e30b95
No known key found for this signature in database
GPG Key ID: F628F9E41DD7C073
17 changed files with 930 additions and 1 deletions

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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();

View File

@ -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;

213
src/gui/DetailsWidget.cpp Normal file
View File

@ -0,0 +1,213 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* 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 "DetailsWidget.h"
#include "ui_DetailsWidget.h"
#include <QDebug>
#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("<a href=\"%1\">%2</a>").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);
}

60
src/gui/DetailsWidget.h Normal file
View File

@ -0,0 +1,60 @@
/*
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
*
* 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 KEEPASSX_DETAILSWIDGET_H
#define KEEPASSX_DETAILSWIDGET_H
#include <QWidget>
#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<Ui::DetailsWidget> m_ui;
Entry* m_currentEntry;
Group* m_currentGroup;
quint8 m_step;
QTimer* m_timer;
QString shortUrl(QString url);
};
#endif // KEEPASSX_DETAILSWIDGET_H

552
src/gui/DetailsWidget.ui Normal file
View File

@ -0,0 +1,552 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DetailsWidget</class>
<widget class="QWidget" name="DetailsWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>630</width>
<height>207</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>235</height>
</size>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,0,0,0,0">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<item>
<widget class="QLabel" name="entryIcon">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>20</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="titleLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="textFormat">
<enum>Qt::AutoText</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QWidget" name="totpWidget" native="true">
<layout class="QGridLayout" name="gridLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="totpLabel">
<property name="font">
<font>
<pointsize>10</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QToolButton" name="totpButton">
<property name="toolTip">
<string>Generate TOTP Token</string>
</property>
<property name="text">
<string/>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="closeButton">
<property name="toolTip">
<string>Generate TOTP Token</string>
</property>
<property name="text">
<string/>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QStackedWidget" name="stackedWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="entryPage">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="groupLabel_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Group</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="urlLabel_2">
<property name="font">
<font>
<pointsize>9</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>URL</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="passwordLabel_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Password</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="usernameLabel_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Username</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="groupLabel"/>
</item>
<item row="1" column="1">
<widget class="QLabel" name="usernameLabel"/>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="PasswordEdit" name="passwordEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maxLength">
<number>999</number>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="togglePasswordButton">
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="1">
<widget class="QLabel" name="urlLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="2" column="0">
<widget class="QLabel" name="modifyLabel_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Modification</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="accessLabel_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Access</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="accessLabel"/>
</item>
<item row="0" column="1">
<widget class="QLabel" name="creationLabel"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="creationLabel_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Creation</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="expirationLabel_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Expiration</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="modifyLabel"/>
</item>
<item row="3" column="1">
<widget class="QLabel" name="expirationLabel"/>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="groupPage">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="1">
<widget class="QLabel" name="autotypeLabel"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="autotypeLabel_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Autotype</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="searchingLabel"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="searchingLabel_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Searching</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="groupExpirationLabel"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="groupExpirationLabel_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Expiration</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_5">
<item row="2" column="0">
<widget class="QLabel" name="groupModifyLabel_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Modification</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="groupAccessLabel_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Access</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="groupAccessLabel"/>
</item>
<item row="0" column="1">
<widget class="QLabel" name="groupCreationLabel"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="groupCreationLabel_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Creation</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="groupModifyLabel"/>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="1">
<widget class="QTextEdit" name="notesEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>50</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>50</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="notesLabel_2">
<property name="text">
<string>Notes</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
<action name="searchIcon">
<property name="text">
<string>Search</string>
</property>
</action>
<action name="clearIcon">
<property name="text">
<string>Clear</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>PasswordEdit</class>
<extends>QLineEdit</extends>
<header>gui/PasswordEdit.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@ -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

View File

@ -153,6 +153,13 @@
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="detailsHideCheckBox">
<property name="text">
<string>Hide the Details view</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="systrayShowCheckBox">
<property name="text">

View File

@ -136,6 +136,13 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="passwordDetailsCleartextCheckBox">
<property name="text">
<string>Hide passwords in the preview panel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View File

@ -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<EntryModel::ModelColumn>(m_sortModel->mapToSource(index).column()));
}
void EntryView::emitEntryPressed(const QModelIndex& index)
{
emit entryPressed(entryFromIndex(index));
}
void EntryView::setModel(QAbstractItemModel* model)
{
Q_UNUSED(model);

View File

@ -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();

View File

@ -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++) {

View File

@ -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();