Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve entry table display/functionality in GUI #849

Closed
wants to merge 13 commits into from
Closed

Improve entry table display/functionality in GUI #849

wants to merge 13 commits into from

Conversation

fonic
Copy link
Contributor

@fonic fonic commented Aug 5, 2017

Description

This adds to the entry table:

With this, the entry table gets mostly in par with KeePassX 0.4.x.

All changes are currently prefixed with /** @author Fonic [...] */ comments and there are in-code TODOs to be resolved. Those will of course be cleaned/removed once this is ready to be shipped.

Please note that this is work in progress and that I'm still familiarizing myself with the project and its guidelines. Thus, if something is not the way it's supposed to be, please be so kind and point it out.

Motivation

In my opinion, this addresses a major disadvantage of KeePassXC. Not only the additional columns, but more importantly the 'copy-on-doubleclick' really adds to the usability.

I am aware that redesigning the entry table already is a goal within this project (#129). My contribution may either be a step towards this or at least fill the gap until this is done.

DONE

  • Add additional columns to entry table
  • Implement 'copy-on-doubleclick' for certain columns
  • Use date/time format from locale instead of hard-coded format string to display timestamps
  • Add header menu (right click on header):
    • add actions for toggling column visibility
    • add actions for auto-resizing columns (fit to window, fit to contents)
    • add actions to reset header configuration (reset to last session state, reset to defaults)
    • add checkbox actions to toggle hidden/cleartext display of username and password
  • Make settings persistent (save/load to/from configuration):
    • header state (column order/sizes/visibility)
    • hidden/cleartext display of username and password
  • Change EntryModel::columnCount() to comply to Qt documentation advisory

TODO

  • Decide whether overall view state (splitter, entry list header configuration) should be synced across tabs or should be kept separate; separation would reduce complexity and improve usability [discussion]
  • Decide whether view state of entry list should be synced or kept separate when switching between normal mode (i.e. list entries of selected group) and search mode; my opinion: sync state from list to search, but not the other way (i.e. search looks like list, but changes when in search mode are discarded when search mode ends) [discussion]
  • Decide whether to force sort column/order when entering/leaving search mode or to save/restore previous sort column/order; my opinion: backup ordering before entering search mode, force ordering for search mode, restore ordering when leaving search mode [discussion]
  • Add header menu as submenu of menu 'View'
  • Resolve minor in-code TODOs
  • Remove development comments

How has this been tested?

  • locally

Screenshots:

screenshot_20170807_183352

Types of changes

  • ✅ New feature (non-breaking change which adds functionality)

Checklist (in progress):

  • ✅ I have read the CONTRIBUTING document. [REQUIRED]
  • ✅ My code follows the code style of this project. [REQUIRED]
  • ✅ All new and existing tests passed. [REQUIRED]
  • ✅ I have compiled and verified my code with -DWITH_ASAN=ON. [REQUIRED]
  • ❎ My change requires a change to the documentation and I have updated it accordingly.
  • ❎ I have added tests to cover my changes.

fonic added 3 commits August 5, 2017 13:52
Add additional columns 'Password', 'Notes', 'Expires', 'Created', 'Modified', 'Accessed' and 'Attachments' to entry table display. With this, the entry display is in par with KeePassX 0.4.x.
Add 'copy-on-doubleclick' functionality for entry table columns 'Username', 'Password' and 'Notes'.
On Travis CI, entry->attachments()->keys().join() does not exist when it should (http://doc.qt.io/qt-5/qlist.html#more-members). Using for loop construct for now.
* instead this should be global and user-configurable (or derived automatically
* from current regional settings)
*/
QString timeFormat("d MMM yyyy HH:mm:ss");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fonic since this is a constant, this could be declared as such in the EntryModel header file.

static const QString DefaultTimeFormat("d MMM yyyy HH:mm:ss");

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could do that, but I think this should be a global, user-configurable setting as the way timestamps are displayed varies from one country/language to another.

How about putting it in src/core/Config.cpp:

void Config::init(const QString& fileName)
{
    m_defaults.insert("DateTimeFormat", "d MMM yyyy HH:mm:ss");
}

and then fetching it from the config whenever it's needed?

Copy link
Member

@louib louib Aug 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fonic personally, I'd leave it non-configurable, and set the format to ISO 8601. We can always make it configurable if we ever get that request.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should read the locale display preference from the OS and use that.

Copy link
Contributor Author

@fonic fonic Aug 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's do that. Quite easy actually: QDateTime.toString(Qt::DefaultLocaleShortDate). Uses the application's locale and falls back to the system's locale if nothing is set specifically for the application.

To allow for correct sorting, I'd implement Qt::UserRole like done here.

fonic added 7 commits August 6, 2017 05:12
Update entry model test to account for additional columns 'Password', 'Notes', 'Expires', 'Created', 'Modified', 'Accessed' and 'Attachments'.
Instead of using a hard-coded date/time format string to display timestamps, use format defined by current application locale (defaults to system locale if not explicitely set).

Separate display (uses QStrings) and sorting (uses QDateTimes) of timestamps by adding a custom role (Qt::UserRole) to the model.
Add header menu (right click on header):
- actions to toggle columns visibility
- actions to resize all columns
- actions to reset column configuration

Make changes persistent by saving/loading to/from configuration

Change EntryModel::columnCount() to comply to Qt documentation advisory

Lots of code cleanup (comments, TODOs, coding rules)
Use old-style QMenu->addAction(const QString &text, const QObject *receiver, const char *member, const QKeySequence &shortcut = 0) to add actions to header menu to fix compile errors on Travis CI.
Column 'Group' is no longer added/deleted when switching between list and search mode, but shown/hidden instead. Therefore, when in list mode, column 'Group' with index 0 is hidden and cannot be clicked.

Alter test to click column 'Title' with index 1 instead.
@fonic
Copy link
Contributor Author

fonic commented Aug 7, 2017

So, lots of progress here. Please test and let me know what you think. When testing, please focus on the functionality for now. I think I'll restructure this with clean commits once the functionality is defined/decided, as the current approach of keeping track of the view state is inefficient.

Btw:

  • testgui reports lots of leaks which are not related to my changes (I compared with branch 'develop', same thing there). Is that the way it's supposed to be?
  • The build system here seems to use a rather old Qt version. Is there a specific reason for this? I'm using Qt 5.7.1 and the sources build just fine with it

fonic added 3 commits August 7, 2017 10:51
Add functionality for hidden/cleartext display of usernames and passwords:
- modify data providers of entry view model
- add settings to entry view / entry view model
- add corresponding checkbox actions to entry view header menu
- make settings persistent by saving/loading to/from configuration

Again lots of code cleanup (variable names, includes, comments, TODOs, code formatting)
@fonic
Copy link
Contributor Author

fonic commented Aug 8, 2017

I'll stop development at the current state until things listed in the TODO section have been discussed and decided as those greatly affect implementation.

From my point of view, all functionality is there - now it's only a matter of deciding together which pieces to integrate in what way and how (separate pull requests, all in one, ...).

@louib
Copy link
Member

louib commented Aug 10, 2017

@fonic tested that quickly on linux. This is pretty neat, good job!

I'd personally vote for enabling only a subset of the available fields by default (maybe title & username & url & modified date?)

Decide whether overall view state (splitter, entry list header configuration) should be synced across tabs or should be kept separate; separation would reduce complexity and improve usability [discussion]

You mean if the header state should be global or per-database file? I'd go for a global header state. AFAICT it's easier to implement and I feel like the convenience of being able to set it once for all databases wins over being able to customize it for specific databases.

@TheZ3ro
Copy link
Contributor

TheZ3ro commented Aug 12, 2017

Generally I would prefer KISS

Decide whether overall view state (splitter, entry list header configuration) should be synced across tabs or should be kept separate; separation would reduce complexity and improve usability [discussion]

I'd go for a global header state as well. This needs to be saved in the configuration to restore the state when keepassxc is re-opened

Decide whether view state of entry list should be synced or kept separate when switching between normal mode (i.e. list entries of selected group) and search mode; my opinion: sync state from list to search, but not the other way (i.e. search looks like list, but changes when in search mode are discarded when search mode ends) [discussion]

I think it should be separate but if we save the state in the configuration the search state should be saved as well

Decide whether to force sort column/order when entering/leaving search mode or to save/restore previous sort column/order; my opinion: backup ordering before entering search mode, force ordering for search mode, restore ordering when leaving search mode [discussion]

I agree with your opinion

@fonic
Copy link
Contributor Author

fonic commented Aug 28, 2017

Hi there,

sorry that it took me so long to respond, I was on badly needed vacation ;) I'll continue working on this shortly.

I'd personally vote for enabling only a subset of the available fields by default (maybe title & username & url & modified date?)

I would suggest displaying all available fields by default so new users see what is available and can customize to their needs. Just my opinion, of course we can do it your way, too.

Decide whether overall view state (splitter, entry list header configuration) should be synced across tabs or should be kept separate; separation would reduce complexity and improve usability [discussion]

You mean if the header state should be global or per-database file? I'd go for a global header state. AFAICT it's easier to implement and I feel like the convenience of being able to set it once for all databases wins over being able to customize it for specific databases.

Yes, that's exactly what I meant. I already implemented both ways, the complexity of having separate states (i.e. per database) is actually not that bad. Syncing the view, on the other hand, is quite difficult (see below).

I'd go for a global header state as well. This needs to be saved in the configuration to restore the state when keepassxc is re-opened

Good. I agree, I think having separate states is just confusing to users, because every time a tab is selected the view changes. Saving/loading to/from configuration is already implemented, but not yet uploaded.

I think it should be separate but if we save the state in the configuration the search state should be saved as well

Why do you vote for separate? Just asking.

Generally I would prefer KISS

I love KISS, the question in this case is KISS for whom:

  • KISS for the user (same view for each database) means complexity for the code
  • KISS for the code (separate view for each database) might mean complexity for the user

Just so that you understand: syncing the view states is actually quite difficult due to the way the header state is represented in Qt (binary stream).

To make the whole decision process easier, I coded a version that allows toggling of everything we discuss here (e.g. sync splitter yes/no, sync header state yes/no). I think actually testing this is better than words. Will upload that shortly. After that, I'll start submitting the changes cleaned up and piece by piece within a new pull request-

@cjsheets
Copy link

Thank you very much for taking on this feature @fonic , It's the only functionality I find myself missing with keepassxc.

Just thought I'd +1 your thought to retain the option to show all fields. I happen to primarily use the Note field (since, for auto-type, we don't have much say on what goes in Title) but different people will have different styles.

@frostasm
Copy link
Contributor

frostasm commented Nov 2, 2017

There is a chance that these changes will be in version 2.3.0?

@droidmonkey
Copy link
Member

Absolutely

@TheZ3ro
Copy link
Contributor

TheZ3ro commented Nov 27, 2017

@fonic any news on this?

@fonic
Copy link
Contributor Author

fonic commented Dec 17, 2017

Sorry for replying so late. Q3/Q4 is always the busiest time of the year at my workplace, I just couldn't find the time to work on anything else over the last couple of months. Thankfully, that's behind me now :)

I'll check what has changed in the code base since then and continue to work on this.

@fonic
Copy link
Contributor Author

fonic commented Dec 19, 2017

Closing this pull request in favor of new pull request #1305.

@fonic fonic closed this Dec 19, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants