Improve UI of the search edit (resurrecting 5c7c7f54)

- The copy action (Control+C) when no text is selected copies the
  password of the current entry.  This should be reasonable when
  Control+B copies the username.

- Down at EOL moves the focus to the entry view.  Enter and Tab should
  do that, but it would be handy for user to be able to get to the third
  entry by hitting Down three times.
This commit is contained in:
Akinori MUSHA 2016-12-22 16:21:52 +09:00
parent 63a1b49745
commit d0a3c08840
5 changed files with 61 additions and 14 deletions

View File

@ -385,6 +385,11 @@ void DatabaseWidget::deleteEntries()
} }
} }
void DatabaseWidget::setFocus()
{
m_entryView->setFocus();
}
void DatabaseWidget::copyTitle() void DatabaseWidget::copyTitle()
{ {
Entry* currentEntry = m_entryView->currentEntry(); Entry* currentEntry = m_entryView->currentEntry();

View File

@ -116,6 +116,7 @@ public Q_SLOTS:
void createEntry(); void createEntry();
void cloneEntry(); void cloneEntry();
void deleteEntries(); void deleteEntries();
void setFocus();
void copyTitle(); void copyTitle();
void copyUsername(); void copyUsername();
void copyPassword(); void copyPassword();

View File

@ -24,7 +24,7 @@
#include "core/FilePath.h" #include "core/FilePath.h"
bool SearchEventFilter::eventFilter(QObject *obj, QEvent *event) bool SearchWidget::eventFilter(QObject *obj, QEvent *event)
{ {
if (event->type() == QEvent::KeyPress) { if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event); QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
@ -32,6 +32,25 @@ bool SearchEventFilter::eventFilter(QObject *obj, QEvent *event)
emit escapePressed(); emit escapePressed();
return true; return true;
} }
else if (keyEvent->matches(QKeySequence::Copy)) {
// If Control+C is pressed in the search edit when no
// text is selected, copy the password of the current
// entry.
if (!m_ui->searchEdit->hasSelectedText()) {
emit copyPressed();
return true;
}
}
else if (keyEvent->matches(QKeySequence::MoveToNextLine)) {
// If Down is pressed at EOL in the search edit, move
// the focus to the entry view.
QLineEdit* searchEdit = m_ui->searchEdit;
if (!searchEdit->hasSelectedText() &&
searchEdit->cursorPosition() == searchEdit->text().length()) {
emit downPressed();
return true;
}
}
} }
return QObject::eventFilter(obj, event); return QObject::eventFilter(obj, event);
@ -51,11 +70,13 @@ SearchWidget::SearchWidget(QWidget *parent)
connect(m_ui->searchEdit, SIGNAL(returnPressed()), SLOT(startSearch())); connect(m_ui->searchEdit, SIGNAL(returnPressed()), SLOT(startSearch()));
connect(m_ui->searchIcon, SIGNAL(triggered(QAction*)), m_ui->searchEdit, SLOT(setFocus())); connect(m_ui->searchIcon, SIGNAL(triggered(QAction*)), m_ui->searchEdit, SLOT(setFocus()));
connect(m_searchTimer, SIGNAL(timeout()), this, SLOT(startSearch())); connect(m_searchTimer, SIGNAL(timeout()), this, SLOT(startSearch()));
connect(&m_searchEventFilter, SIGNAL(escapePressed()), m_ui->searchEdit, SLOT(clear())); connect(this, SIGNAL(escapePressed()), m_ui->searchEdit, SLOT(clear()));
connect(this, SIGNAL(copyPressed()), SLOT(copyPassword()));
connect(this, SIGNAL(downPressed()), SLOT(setFocusToEntry()));
new QShortcut(Qt::CTRL + Qt::Key_F, m_ui->searchEdit, SLOT(setFocus()), nullptr, Qt::ApplicationShortcut); new QShortcut(Qt::CTRL + Qt::Key_F, m_ui->searchEdit, SLOT(setFocus()), nullptr, Qt::ApplicationShortcut);
m_ui->searchEdit->installEventFilter(&m_searchEventFilter); m_ui->searchEdit->installEventFilter(this);
QMenu *searchMenu = new QMenu(); QMenu *searchMenu = new QMenu();
m_actionCaseSensitive = searchMenu->addAction(tr("Case Sensitive"), this, SLOT(updateCaseSensitive())); m_actionCaseSensitive = searchMenu->addAction(tr("Case Sensitive"), this, SLOT(updateCaseSensitive()));
@ -80,6 +101,8 @@ void SearchWidget::connectSignals(SignalMultiplexer& mx)
void SearchWidget::databaseChanged(DatabaseWidget *dbWidget) void SearchWidget::databaseChanged(DatabaseWidget *dbWidget)
{ {
m_dbWidget = dbWidget;
if (dbWidget != nullptr) { if (dbWidget != nullptr) {
// Set current search text from this database // Set current search text from this database
m_ui->searchEdit->setText(dbWidget->getCurrentSearch()); m_ui->searchEdit->setText(dbWidget->getCurrentSearch());
@ -118,3 +141,15 @@ void SearchWidget::setCaseSensitive(bool state)
m_actionCaseSensitive->setChecked(state); m_actionCaseSensitive->setChecked(state);
updateCaseSensitive(); updateCaseSensitive();
} }
void SearchWidget::copyPassword()
{
if (m_dbWidget)
m_dbWidget->copyPassword();
}
void SearchWidget::setFocusToEntry()
{
if (m_dbWidget)
m_dbWidget->setFocus();
}

View File

@ -28,16 +28,6 @@ namespace Ui {
class SearchWidget; class SearchWidget;
} }
class SearchEventFilter : public QObject
{
Q_OBJECT
signals:
void escapePressed();
protected:
virtual bool eventFilter(QObject *obj, QEvent *event) override;
};
class SearchWidget : public QWidget class SearchWidget : public QWidget
{ {
@ -53,6 +43,9 @@ public:
signals: signals:
void search(const QString &text); void search(const QString &text);
void caseSensitiveChanged(bool state); void caseSensitiveChanged(bool state);
void escapePressed();
void copyPressed();
void downPressed();
public slots: public slots:
void databaseChanged(DatabaseWidget* dbWidget); void databaseChanged(DatabaseWidget* dbWidget);
@ -61,15 +54,21 @@ private slots:
void startSearchTimer(); void startSearchTimer();
void startSearch(); void startSearch();
void updateCaseSensitive(); void updateCaseSensitive();
void copyPassword();
void setFocusToEntry();
private: private:
const QScopedPointer<Ui::SearchWidget> m_ui; const QScopedPointer<Ui::SearchWidget> m_ui;
QTimer* m_searchTimer; QTimer* m_searchTimer;
SearchEventFilter m_searchEventFilter; DatabaseWidget *m_dbWidget;
QAction *m_actionCaseSensitive; QAction *m_actionCaseSensitive;
Q_DISABLE_COPY(SearchWidget) Q_DISABLE_COPY(SearchWidget)
protected:
bool eventFilter(QObject *obj, QEvent *event);
}; };
#endif // SEARCHWIDGET_H #endif // SEARCHWIDGET_H

View File

@ -406,6 +406,13 @@ void TestGui::testSearch()
// Search for "someTHING" // Search for "someTHING"
QTest::keyClicks(searchTextEdit, "THING"); QTest::keyClicks(searchTextEdit, "THING");
QTRY_COMPARE(entryView->model()->rowCount(), 2); QTRY_COMPARE(entryView->model()->rowCount(), 2);
// Press Down to focus on the entry view if at EOL
QTest::keyClick(searchTextEdit, Qt::Key_Left);
QTest::keyClick(searchTextEdit, Qt::Key_Down);
QTRY_VERIFY(searchTextEdit->hasFocus());
QTest::keyClick(searchTextEdit, Qt::Key_Down);
QTRY_VERIFY(entryView->hasFocus());
QTest::mouseClick(searchTextEdit, Qt::LeftButton);
// Test case sensitive search // Test case sensitive search
searchWidget->setCaseSensitive(true); searchWidget->setCaseSensitive(true);