Skip to content

Commit

Permalink
Merge pull request #1305 from fonic/improved_entry_view
Browse files Browse the repository at this point in the history
Improve and extend entry view table
  • Loading branch information
phoerious authored Jan 21, 2018
2 parents 5e30214 + 8c78aca commit 0a876c8
Show file tree
Hide file tree
Showing 12 changed files with 665 additions and 111 deletions.
2 changes: 2 additions & 0 deletions src/core/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ void Config::init(const QString& fileName)
m_defaults.insert("GUI/DarkTrayIcon", false);
m_defaults.insert("GUI/MinimizeToTray", false);
m_defaults.insert("GUI/MinimizeOnClose", false);
m_defaults.insert("GUI/HideUsernames", false);
m_defaults.insert("GUI/HidePasswords", true);
}

Config* Config::instance()
Expand Down
89 changes: 67 additions & 22 deletions src/gui/DatabaseWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)

connect(m_mainSplitter, SIGNAL(splitterMoved(int,int)), SIGNAL(mainSplitterSizesChanged()));
connect(m_detailSplitter, SIGNAL(splitterMoved(int,int)), SIGNAL(detailSplitterSizesChanged()));
connect(m_entryView->header(), SIGNAL(sectionResized(int,int,int)), SIGNAL(entryColumnSizesChanged()));
connect(m_entryView, SIGNAL(viewStateChanged()), SIGNAL(entryViewStateChanged()));
connect(m_groupView, SIGNAL(groupChanged(Group*)), this, SLOT(onGroupChanged(Group*)));
connect(m_groupView, SIGNAL(groupChanged(Group*)), SIGNAL(groupChanged()));
connect(m_entryView, SIGNAL(entryActivated(Entry*, EntryModel::ModelColumn)),
Expand Down Expand Up @@ -290,28 +290,52 @@ void DatabaseWidget::setDetailSplitterSizes(const QList<int> &sizes)
m_detailSplitter->setSizes(sizes);
}

QList<int> DatabaseWidget::entryHeaderViewSizes() const
/**
* Get current state of entry view 'Hide Usernames' setting
*/
bool DatabaseWidget::isUsernamesHidden() const
{
QList<int> sizes;
return m_entryView->isUsernamesHidden();
}

for (int i = 0; i < m_entryView->header()->count(); i++) {
sizes.append(m_entryView->header()->sectionSize(i));
}
/**
* Set state of entry view 'Hide Usernames' setting
*/
void DatabaseWidget::setUsernamesHidden(const bool hide)
{
m_entryView->setUsernamesHidden(hide);
}

return sizes;
/**
* Get current state of entry view 'Hide Passwords' setting
*/
bool DatabaseWidget::isPasswordsHidden() const
{
return m_entryView->isPasswordsHidden();
}

void DatabaseWidget::setEntryViewHeaderSizes(const QList<int>& sizes)
/**
* Set state of entry view 'Hide Passwords' setting
*/
void DatabaseWidget::setPasswordsHidden(const bool hide)
{
const bool enoughSizes = sizes.size() == m_entryView->header()->count();
Q_ASSERT(enoughSizes);
if (!enoughSizes) {
return;
}
m_entryView->setPasswordsHidden(hide);
}

for (int i = 0; i < sizes.size(); i++) {
m_entryView->header()->resizeSection(i, sizes[i]);
}
/**
* Get current view state of entry view
*/
QByteArray DatabaseWidget::entryViewState() const
{
return m_entryView->viewState();
}

/**
* Set view state of entry view
*/
bool DatabaseWidget::setEntryViewState(const QByteArray& state) const
{
return m_entryView->setViewState(state);
}

void DatabaseWidget::clearAllWidgets()
Expand Down Expand Up @@ -660,8 +684,8 @@ void DatabaseWidget::openUrlForEntry(Entry* entry)

void DatabaseWidget::createGroup()
{
Q_ASSERT(m_groupView->currentGroup());
if (!m_groupView->currentGroup()) {
Q_ASSERT(false);
return;
}

Expand All @@ -674,8 +698,8 @@ void DatabaseWidget::createGroup()
void DatabaseWidget::deleteGroup()
{
Group* currentGroup = m_groupView->currentGroup();
Q_ASSERT(currentGroup && canDeleteCurrentGroup());
if (!currentGroup || !canDeleteCurrentGroup()) {
Q_ASSERT(false);
return;
}

Expand Down Expand Up @@ -910,10 +934,31 @@ void DatabaseWidget::unlockDatabase(bool accepted)

void DatabaseWidget::entryActivationSignalReceived(Entry* entry, EntryModel::ModelColumn column)
{
if (column == EntryModel::Url && !entry->url().isEmpty()) {
openUrlForEntry(entry);
Q_ASSERT(entry);
if (!entry) {
return;
}
else {

// Implement 'copy-on-doubleclick' functionality for certain columns
switch (column) {
case EntryModel::Username:
setClipboardTextAndMinimize(entry->resolveMultiplePlaceholders(entry->username()));
break;
case EntryModel::Password:
setClipboardTextAndMinimize(entry->resolveMultiplePlaceholders(entry->password()));
break;
case EntryModel::Url:
if (!entry->url().isEmpty()) {
openUrlForEntry(entry);
}
break;
// TODO: switch to 'Notes' tab in details view/pane
//case EntryModel::Notes:
// break;
// TODO: switch to 'Attachments' tab in details view/pane
//case EntryModel::Attachments:
// break;
default:
switchToEntryEdit(entry);
}
}
Expand Down Expand Up @@ -1151,7 +1196,7 @@ bool DatabaseWidget::canDeleteCurrentGroup() const

bool DatabaseWidget::isInSearchMode() const
{
return m_entryView->inEntryListMode();
return m_entryView->inSearchMode();
}

Group* DatabaseWidget::currentGroup() const
Expand Down
10 changes: 7 additions & 3 deletions src/gui/DatabaseWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,12 @@ class DatabaseWidget : public QStackedWidget
void setMainSplitterSizes(const QList<int>& sizes);
QList<int> detailSplitterSizes() const;
void setDetailSplitterSizes(const QList<int>& sizes);
QList<int> entryHeaderViewSizes() const;
void setEntryViewHeaderSizes(const QList<int>& sizes);
bool isUsernamesHidden() const;
void setUsernamesHidden(const bool hide);
bool isPasswordsHidden() const;
void setPasswordsHidden(const bool hide);
QByteArray entryViewState() const;
bool setEntryViewState(const QByteArray& state) const;
void clearAllWidgets();
bool currentEntryHasTitle();
bool currentEntryHasUsername();
Expand Down Expand Up @@ -127,7 +131,7 @@ class DatabaseWidget : public QStackedWidget
void searchModeActivated();
void mainSplitterSizesChanged();
void detailSplitterSizesChanged();
void entryColumnSizesChanged();
void entryViewStateChanged();
void updateSearch(QString text);

public slots:
Expand Down
85 changes: 66 additions & 19 deletions src/gui/DatabaseWidgetStateSync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,20 @@ DatabaseWidgetStateSync::DatabaseWidgetStateSync(QObject* parent)
{
m_mainSplitterSizes = variantToIntList(config()->get("GUI/SplitterState"));
m_detailSplitterSizes = variantToIntList(config()->get("GUI/DetailSplitterState"));
m_columnSizesList = variantToIntList(config()->get("GUI/EntryListColumnSizes"));
m_columnSizesSearch = variantToIntList(config()->get("GUI/EntrySearchColumnSizes"));
m_hideUsernames = config()->get("GUI/HideUsernames").toBool();
m_hidePasswords = config()->get("GUI/HidePasswords").toBool();
m_listViewState = config()->get("GUI/ListViewState").toByteArray();
m_searchViewState = config()->get("GUI/SearchViewState").toByteArray();
}

DatabaseWidgetStateSync::~DatabaseWidgetStateSync()
{
config()->set("GUI/SplitterState", intListToVariant(m_mainSplitterSizes));
config()->set("GUI/DetailSplitterState", intListToVariant(m_detailSplitterSizes));
config()->set("GUI/EntryListColumnSizes", intListToVariant(m_columnSizesList));
config()->set("GUI/EntrySearchColumnSizes", intListToVariant(m_columnSizesSearch));
config()->set("GUI/HideUsernames", m_hideUsernames);
config()->set("GUI/HidePasswords", m_hidePasswords);
config()->set("GUI/ListViewState", m_listViewState);
config()->set("GUI/SearchViewState", m_searchViewState);
}

void DatabaseWidgetStateSync::setActive(DatabaseWidget* dbWidget)
Expand Down Expand Up @@ -70,8 +74,8 @@ void DatabaseWidgetStateSync::setActive(DatabaseWidget* dbWidget)
SLOT(updateSplitterSizes()));
connect(m_activeDbWidget, SIGNAL(detailSplitterSizesChanged()),
SLOT(updateSplitterSizes()));
connect(m_activeDbWidget, SIGNAL(entryColumnSizesChanged()),
SLOT(updateColumnSizes()));
connect(m_activeDbWidget, SIGNAL(entryViewStateChanged()),
SLOT(updateViewState()));
connect(m_activeDbWidget, SIGNAL(listModeActivated()),
SLOT(restoreListView()));
connect(m_activeDbWidget, SIGNAL(searchModeActivated()),
Expand All @@ -83,19 +87,55 @@ void DatabaseWidgetStateSync::setActive(DatabaseWidget* dbWidget)
}
}

/**
* Restore entry view list view state
*
* NOTE:
* States of entry view 'Hide Usernames'/'Hide Passwords' settings are global,
* i.e. they are the same for both list and search mode
*
* NOTE:
* If m_listViewState is empty, the list view has been activated for the first
* time after starting with a clean (or invalid) config. Thus, save the current
* state. Without this, m_listViewState would remain empty until there is an
* actual view state change (e.g. column is resized)
*/
void DatabaseWidgetStateSync::restoreListView()
{
if (!m_columnSizesList.isEmpty()) {
m_activeDbWidget->setEntryViewHeaderSizes(m_columnSizesList);
m_activeDbWidget->setUsernamesHidden(m_hideUsernames);
m_activeDbWidget->setPasswordsHidden(m_hidePasswords);

if (!m_listViewState.isEmpty()) {
m_activeDbWidget->setEntryViewState(m_listViewState);
} else {
m_listViewState = m_activeDbWidget->entryViewState();
}

m_blockUpdates = false;
}

/**
* Restore entry view search view state
*
* NOTE:
* States of entry view 'Hide Usernames'/'Hide Passwords' settings are global,
* i.e. they are the same for both list and search mode
*
* NOTE:
* If m_searchViewState is empty, the search view has been activated for the
* first time after starting with a clean (or invalid) config. Thus, save the
* current state. Without this, m_searchViewState would remain empty until
* there is an actual view state change (e.g. column is resized)
*/
void DatabaseWidgetStateSync::restoreSearchView()
{
if (!m_columnSizesSearch.isEmpty()) {
m_activeDbWidget->setEntryViewHeaderSizes(m_columnSizesSearch);
m_activeDbWidget->setUsernamesHidden(m_hideUsernames);
m_activeDbWidget->setPasswordsHidden(m_hidePasswords);

if (!m_searchViewState.isEmpty()) {
m_activeDbWidget->setEntryViewState(m_searchViewState);
} else {
m_searchViewState = m_activeDbWidget->entryViewState();
}

m_blockUpdates = false;
Expand All @@ -116,17 +156,26 @@ void DatabaseWidgetStateSync::updateSplitterSizes()
m_detailSplitterSizes = m_activeDbWidget->detailSplitterSizes();
}

void DatabaseWidgetStateSync::updateColumnSizes()
/**
* Update entry view list/search view state
*
* NOTE:
* States of entry view 'Hide Usernames'/'Hide Passwords' settings are global,
* i.e. they are the same for both list and search mode
*/
void DatabaseWidgetStateSync::updateViewState()
{
if (m_blockUpdates) {
return;
}

if (m_activeDbWidget->isGroupSelected()) {
m_columnSizesList = m_activeDbWidget->entryHeaderViewSizes();
}
else {
m_columnSizesSearch = m_activeDbWidget->entryHeaderViewSizes();
m_hideUsernames = m_activeDbWidget->isUsernamesHidden();
m_hidePasswords = m_activeDbWidget->isPasswordsHidden();

if (m_activeDbWidget->isInSearchMode()) {
m_searchViewState = m_activeDbWidget->entryViewState();
} else {
m_listViewState = m_activeDbWidget->entryViewState();
}
}

Expand All @@ -140,8 +189,7 @@ QList<int> DatabaseWidgetStateSync::variantToIntList(const QVariant& variant)
int size = var.toInt(&ok);
if (ok) {
result.append(size);
}
else {
} else {
result.clear();
break;
}
Expand All @@ -160,4 +208,3 @@ QVariant DatabaseWidgetStateSync::intListToVariant(const QList<int>& list)

return result;
}

10 changes: 7 additions & 3 deletions src/gui/DatabaseWidgetStateSync.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public slots:
private slots:
void blockUpdates();
void updateSplitterSizes();
void updateColumnSizes();
void updateViewState();

private:
static QList<int> variantToIntList(const QVariant& variant);
Expand All @@ -48,8 +48,12 @@ private slots:
bool m_blockUpdates;
QList<int> m_mainSplitterSizes;
QList<int> m_detailSplitterSizes;
QList<int> m_columnSizesList;
QList<int> m_columnSizesSearch;

bool m_hideUsernames;
bool m_hidePasswords;

QByteArray m_listViewState;
QByteArray m_searchViewState;
};

#endif // KEEPASSX_DATABASEWIDGETSTATESYNC_H
2 changes: 1 addition & 1 deletion src/gui/DetailsWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ void DetailsWidget::getSelectedEntry(Entry* selectedEntry)
shortPassword(m_currentEntry->resolveMultiplePlaceholders(m_currentEntry->password())));
m_ui->passwordLabel->setToolTip(m_currentEntry->resolveMultiplePlaceholders(m_currentEntry->password()));
} else {
m_ui->passwordLabel->setText("****");
m_ui->passwordLabel->setText(QString("\u25cf").repeated(6));
}

QString url = m_currentEntry->webUrl();
Expand Down
Loading

0 comments on commit 0a876c8

Please sign in to comment.