Skip to content

Commit

Permalink
Fix multiple issues with entries and keyboard shortcuts (#2431)
Browse files Browse the repository at this point in the history
* Cleanup entry change notification with entryview focus in/out
* Change Open URL shortcut to CTRL+SHIFT+U to conform with an "action" 
including SHIFT
* Change Copy URL shortcut to CTRL+U to conform with "copy" without SHIFT
* Entry specific toolbar and menu items are disabled unless the entry
row has focus (prevents unintended actions)
* Reword security setting for password visibility in entry edit view
* Add shortcut to hide/unhide usernames (CTRL+SHIFT+B)
* Organize entry menu

* Fix #1588 - show keyboard shortcuts in context menu
* Fix #2403 - Change auto-type shortcut to CTRL + SHIFT + V
* Fix #2096 - Add (CTRL+F) to search bar background
* Fix #2031 & Fix #2266 - add shortcut to hide/unhide passwords (CTRL+SHIFT+C)
* Fix #2166 - Add reveal password button to entry preview
  • Loading branch information
droidmonkey committed Nov 16, 2018
1 parent f06742c commit ee9c71e
Show file tree
Hide file tree
Showing 16 changed files with 365 additions and 225 deletions.
2 changes: 1 addition & 1 deletion src/gui/ApplicationSettingsWidgetSecurity.ui
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@
<item>
<widget class="QCheckBox" name="passwordCleartextCheckBox">
<property name="text">
<string>Show passwords in cleartext by default</string>
<string>Don't hide passwords when editing them</string>
</property>
</widget>
</item>
Expand Down
102 changes: 37 additions & 65 deletions src/gui/DatabaseWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)

m_previewView = new EntryPreviewWidget(this);
m_previewView->hide();
connect(this, SIGNAL(pressedEntry(Entry*)), m_previewView, SLOT(setEntry(Entry*)));
connect(this, SIGNAL(pressedGroup(Group*)), m_previewView, SLOT(setGroup(Group*)));
connect(this, SIGNAL(currentModeChanged(DatabaseWidget::Mode)),
m_previewView, SLOT(setDatabaseMode(DatabaseWidget::Mode)));
Expand Down Expand Up @@ -183,7 +182,7 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
connect(m_entryView,
SIGNAL(entryActivated(Entry*,EntryModel::ModelColumn)),
SLOT(entryActivationSignalReceived(Entry*,EntryModel::ModelColumn)));
connect(m_entryView, SIGNAL(entrySelectionChanged()), SIGNAL(entrySelectionChanged()));
connect(m_entryView, SIGNAL(entrySelectionChanged()), SLOT(emitEntrySelectionChanged()));
connect(m_editEntryWidget, SIGNAL(editFinished(bool)), SLOT(switchToView(bool)));
connect(m_editEntryWidget, SIGNAL(historyEntryActivated(Entry*)), SLOT(switchToHistoryView(Entry*)));
connect(m_historyEditEntryWidget, SIGNAL(editFinished(bool)), SLOT(switchBackToEntryEdit()));
Expand All @@ -202,9 +201,7 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)

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()));
connect(m_editEntryWidget, SIGNAL(editFinished(bool)), SLOT(emitEntrySelectionChanged()));

m_databaseModified = false;

Expand Down Expand Up @@ -506,80 +503,60 @@ void DatabaseWidget::setFocus()
void DatabaseWidget::copyTitle()
{
Entry* currentEntry = m_entryView->currentEntry();
Q_ASSERT(currentEntry);
if (!currentEntry) {
return;
if (currentEntry) {
setClipboardTextAndMinimize(currentEntry->resolveMultiplePlaceholders(currentEntry->title()));
}

setClipboardTextAndMinimize(currentEntry->resolveMultiplePlaceholders(currentEntry->title()));
}

void DatabaseWidget::copyUsername()
{
Entry* currentEntry = m_entryView->currentEntry();
Q_ASSERT(currentEntry);
if (!currentEntry) {
return;
if (currentEntry) {
setClipboardTextAndMinimize(currentEntry->resolveMultiplePlaceholders(currentEntry->username()));
}

setClipboardTextAndMinimize(currentEntry->resolveMultiplePlaceholders(currentEntry->username()));
}

void DatabaseWidget::copyPassword()
{
Entry* currentEntry = m_entryView->currentEntry();
Q_ASSERT(currentEntry);
if (!currentEntry) {
return;
if (currentEntry) {
setClipboardTextAndMinimize(currentEntry->resolveMultiplePlaceholders(currentEntry->password()));
}

setClipboardTextAndMinimize(currentEntry->resolveMultiplePlaceholders(currentEntry->password()));
}

void DatabaseWidget::copyURL()
{
Entry* currentEntry = m_entryView->currentEntry();
Q_ASSERT(currentEntry);
if (!currentEntry) {
return;
if (currentEntry) {
setClipboardTextAndMinimize(currentEntry->resolveMultiplePlaceholders(currentEntry->url()));
}

setClipboardTextAndMinimize(currentEntry->resolveMultiplePlaceholders(currentEntry->url()));
}

void DatabaseWidget::copyNotes()
{
Entry* currentEntry = m_entryView->currentEntry();
Q_ASSERT(currentEntry);
if (!currentEntry) {
return;
if (currentEntry) {
setClipboardTextAndMinimize(currentEntry->resolveMultiplePlaceholders(currentEntry->notes()));
}

setClipboardTextAndMinimize(currentEntry->resolveMultiplePlaceholders(currentEntry->notes()));
}

void DatabaseWidget::copyAttribute(QAction* action)
{
Entry* currentEntry = m_entryView->currentEntry();
Q_ASSERT(currentEntry);
if (!currentEntry) {
return;
if (currentEntry) {
setClipboardTextAndMinimize(
currentEntry->resolveMultiplePlaceholders(
currentEntry->attributes()->value(action->data().toString())));
}

setClipboardTextAndMinimize(
currentEntry->resolveMultiplePlaceholders(currentEntry->attributes()->value(action->data().toString())));
}

void DatabaseWidget::showTotpKeyQrCode()
{
Entry* currentEntry = m_entryView->currentEntry();
Q_ASSERT(currentEntry);
if (!currentEntry) {
return;
if (currentEntry) {
auto totpDisplayDialog = new TotpExportSettingsDialog(this, currentEntry);
totpDisplayDialog->open();
}

auto totpDisplayDialog = new TotpExportSettingsDialog(this, currentEntry);
totpDisplayDialog->open();
}

void DatabaseWidget::setClipboardTextAndMinimize(const QString& text)
Expand All @@ -593,27 +570,22 @@ void DatabaseWidget::setClipboardTextAndMinimize(const QString& text)
void DatabaseWidget::performAutoType()
{
Entry* currentEntry = m_entryView->currentEntry();
Q_ASSERT(currentEntry);
if (!currentEntry) {
return;
if (currentEntry) {
autoType()->performAutoType(currentEntry, window());
}

autoType()->performAutoType(currentEntry, window());
}

void DatabaseWidget::openUrl()
{
Entry* currentEntry = m_entryView->currentEntry();
Q_ASSERT(currentEntry);
if (!currentEntry) {
return;
if (currentEntry) {
openUrlForEntry(currentEntry);
}

openUrlForEntry(currentEntry);
}

void DatabaseWidget::openUrlForEntry(Entry* entry)
{
Q_ASSERT(entry);
QString cmdString = entry->resolveMultiplePlaceholders(entry->url());
if (cmdString.startsWith("cmd://")) {
// check if decision to execute command was stored
Expand Down Expand Up @@ -1076,10 +1048,11 @@ void DatabaseWidget::setSearchLimitGroup(bool state)
void DatabaseWidget::onGroupChanged(Group* group)
{
// Intercept group changes if in search mode
if (isInSearchMode())
if (isInSearchMode()) {
search(m_lastSearchText);
else
} else {
m_entryView->setGroup(group);
}
}

QString DatabaseWidget::getCurrentSearch()
Expand Down Expand Up @@ -1114,20 +1087,14 @@ void DatabaseWidget::emitEntryContextMenuRequested(const QPoint& pos)
emit entryContextMenuRequested(m_entryView->viewport()->mapToGlobal(pos));
}

void DatabaseWidget::emitPressedEntry()
void DatabaseWidget::emitEntrySelectionChanged()
{
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;
if (currentEntry) {
m_previewView->setEntry(currentEntry);
}

emit pressedEntry(currentEntry);
emit entrySelectionChanged();
}

void DatabaseWidget::emitPressedGroup(Group* currentGroup)
Expand Down Expand Up @@ -1354,7 +1321,12 @@ void DatabaseWidget::restoreGroupEntryFocus(const QUuid& groupUuid, const QUuid&

bool DatabaseWidget::isGroupSelected() const
{
return m_groupView->currentGroup() != nullptr;
return m_groupView->currentGroup();
}

bool DatabaseWidget::currentEntryHasFocus()
{
return m_entryView->numberOfSelectedEntries() > 0 && m_entryView->hasFocus();
}

bool DatabaseWidget::currentEntryHasTitle()
Expand Down
4 changes: 2 additions & 2 deletions src/gui/DatabaseWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class DatabaseWidget : public QStackedWidget
QByteArray entryViewState() const;
bool setEntryViewState(const QByteArray& state) const;
void clearAllWidgets();
bool currentEntryHasFocus();
bool currentEntryHasTitle();
bool currentEntryHasUsername();
bool currentEntryHasPassword();
Expand Down Expand Up @@ -198,9 +199,8 @@ 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 emitEntrySelectionChanged();
void openDatabase(bool accepted);
void mergeDatabase(bool accepted);
void unlockDatabase(bool accepted);
Expand Down
36 changes: 30 additions & 6 deletions src/gui/EntryPreviewWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,14 @@ EntryPreviewWidget::EntryPreviewWidget(QWidget* parent)
// Entry
m_ui->entryTotpButton->setIcon(filePath()->icon("actions", "chronometer"));
m_ui->entryCloseButton->setIcon(filePath()->icon("actions", "dialog-close"));
m_ui->togglePasswordButton->setIcon(filePath()->onOffIcon("actions", "password-show"));

m_ui->entryAttachmentsWidget->setReadOnly(true);
m_ui->entryAttachmentsWidget->setButtonsVisible(false);

connect(m_ui->entryTotpButton, SIGNAL(toggled(bool)), m_ui->entryTotpWidget, SLOT(setVisible(bool)));
connect(m_ui->entryCloseButton, SIGNAL(clicked()), SLOT(hide()));
connect(m_ui->togglePasswordButton, SIGNAL(clicked(bool)), SLOT(setPasswordVisible(bool)));
connect(m_ui->entryTabWidget, SIGNAL(tabBarClicked(int)), SLOT(updateTabIndexes()), Qt::QueuedConnection);
connect(&m_totpTimer, SIGNAL(timeout()), this, SLOT(updateTotpLabel()));

Expand Down Expand Up @@ -152,18 +154,40 @@ void EntryPreviewWidget::updateEntryTotp()
}
}

void EntryPreviewWidget::setPasswordVisible(bool state)
{
const QString password = m_currentEntry->resolveMultiplePlaceholders(m_currentEntry->password());
auto flags = m_ui->entryPasswordLabel->textInteractionFlags();
if (state) {
m_ui->entryPasswordLabel->setRawText(password);
m_ui->entryPasswordLabel->setToolTip(password);
m_ui->entryPasswordLabel->setTextInteractionFlags(flags | Qt::TextSelectableByMouse);
} else {
m_ui->entryPasswordLabel->setTextInteractionFlags(flags & ~Qt::TextSelectableByMouse);
m_ui->entryPasswordLabel->setToolTip({});
if (password.isEmpty() && config()->get("security/passwordemptynodots").toBool()) {
m_ui->entryPasswordLabel->setRawText("");
} else {
m_ui->entryPasswordLabel->setRawText(QString("\u25cf").repeated(6));
}
}
}

void EntryPreviewWidget::updateEntryGeneralTab()
{
Q_ASSERT(m_currentEntry);
m_ui->entryUsernameLabel->setText(m_currentEntry->resolveMultiplePlaceholders(m_currentEntry->username()));

if (!config()->get("security/HidePasswordPreviewPanel").toBool()) {
const QString password = m_currentEntry->resolveMultiplePlaceholders(m_currentEntry->password());
m_ui->entryPasswordLabel->setRawText(password);
m_ui->entryPasswordLabel->setToolTip(password);
if (config()->get("security/HidePasswordPreviewPanel").toBool()) {
// Hide password
setPasswordVisible(false);
// Show the password toggle button if there are dots in the label
m_ui->togglePasswordButton->setVisible(!m_ui->entryPasswordLabel->rawText().isEmpty());
m_ui->togglePasswordButton->setChecked(false);
} else {
m_ui->entryPasswordLabel->setRawText(QString("\u25cf").repeated(6));
m_ui->entryPasswordLabel->setToolTip({});
// Show password
setPasswordVisible(true);
m_ui->togglePasswordButton->setVisible(false);
}

m_ui->entryUrlLabel->setRawText(m_currentEntry->displayUrl());
Expand Down
1 change: 1 addition & 0 deletions src/gui/EntryPreviewWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ private slots:
void updateEntryAttributesTab();
void updateEntryAttachmentsTab();
void updateEntryAutotypeTab();
void setPasswordVisible(bool state);

void updateGroupHeaderLine();
void updateGroupGeneralTab();
Expand Down
Loading

0 comments on commit ee9c71e

Please sign in to comment.