mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2024-10-01 01:26:01 -04:00
Code cleanup
Comprehensive code cleanup: - formatting - comments - obsolete code
This commit is contained in:
parent
9ff648177c
commit
8c78aca69e
@ -138,13 +138,8 @@ void Config::init(const QString& fileName)
|
|||||||
m_defaults.insert("GUI/DarkTrayIcon", false);
|
m_defaults.insert("GUI/DarkTrayIcon", false);
|
||||||
m_defaults.insert("GUI/MinimizeToTray", false);
|
m_defaults.insert("GUI/MinimizeToTray", false);
|
||||||
m_defaults.insert("GUI/MinimizeOnClose", false);
|
m_defaults.insert("GUI/MinimizeOnClose", false);
|
||||||
/**
|
m_defaults.insert("GUI/HideUsernames", false);
|
||||||
* @author Fonic <https://github.com/fonic>
|
m_defaults.insert("GUI/HidePasswords", true);
|
||||||
* Set defaults for state of 'Hide Usernames'/'Hide Passwords' settings
|
|
||||||
* of entry view
|
|
||||||
*/
|
|
||||||
m_defaults.insert("GUI/EntryHideUsernames", false);
|
|
||||||
m_defaults.insert("GUI/EntryHidePasswords", true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Config* Config::instance()
|
Config* Config::instance()
|
||||||
|
@ -181,13 +181,7 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
|
|||||||
|
|
||||||
connect(m_mainSplitter, SIGNAL(splitterMoved(int,int)), SIGNAL(mainSplitterSizesChanged()));
|
connect(m_mainSplitter, SIGNAL(splitterMoved(int,int)), SIGNAL(mainSplitterSizesChanged()));
|
||||||
connect(m_detailSplitter, SIGNAL(splitterMoved(int,int)), SIGNAL(detailSplitterSizesChanged()));
|
connect(m_detailSplitter, SIGNAL(splitterMoved(int,int)), SIGNAL(detailSplitterSizesChanged()));
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Connect signal to pass through state changes of entry view view
|
|
||||||
*/
|
|
||||||
connect(m_entryView, SIGNAL(viewStateChanged()), SIGNAL(entryViewStateChanged()));
|
connect(m_entryView, SIGNAL(viewStateChanged()), SIGNAL(entryViewStateChanged()));
|
||||||
|
|
||||||
connect(m_groupView, SIGNAL(groupChanged(Group*)), this, SLOT(onGroupChanged(Group*)));
|
connect(m_groupView, SIGNAL(groupChanged(Group*)), this, SLOT(onGroupChanged(Group*)));
|
||||||
connect(m_groupView, SIGNAL(groupChanged(Group*)), SIGNAL(groupChanged()));
|
connect(m_groupView, SIGNAL(groupChanged(Group*)), SIGNAL(groupChanged()));
|
||||||
connect(m_entryView, SIGNAL(entryActivated(Entry*, EntryModel::ModelColumn)),
|
connect(m_entryView, SIGNAL(entryActivated(Entry*, EntryModel::ModelColumn)),
|
||||||
@ -297,55 +291,49 @@ void DatabaseWidget::setDetailSplitterSizes(const QList<int> &sizes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Get current state of entry view 'Hide Usernames' setting
|
* Get current state of entry view 'Hide Usernames' setting
|
||||||
*/
|
*/
|
||||||
bool DatabaseWidget::entryViewHideUsernames() const
|
bool DatabaseWidget::isUsernamesHidden() const
|
||||||
{
|
{
|
||||||
return m_entryView->hideUsernames();
|
return m_entryView->isUsernamesHidden();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Set state of entry view 'Hide Usernames' setting
|
* Set state of entry view 'Hide Usernames' setting
|
||||||
*/
|
*/
|
||||||
void DatabaseWidget::setEntryViewHideUsernames(const bool hide)
|
void DatabaseWidget::setUsernamesHidden(const bool hide)
|
||||||
{
|
{
|
||||||
m_entryView->setHideUsernames(hide);
|
m_entryView->setUsernamesHidden(hide);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Get current state of entry view 'Hide Passwords' setting
|
* Get current state of entry view 'Hide Passwords' setting
|
||||||
*/
|
*/
|
||||||
bool DatabaseWidget::entryViewHidePasswords() const
|
bool DatabaseWidget::isPasswordsHidden() const
|
||||||
{
|
{
|
||||||
return m_entryView->hidePasswords();
|
return m_entryView->isPasswordsHidden();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Set state of entry view 'Hide Passwords' setting
|
* Set state of entry view 'Hide Passwords' setting
|
||||||
*/
|
*/
|
||||||
void DatabaseWidget::setEntryViewHidePasswords(const bool hide)
|
void DatabaseWidget::setPasswordsHidden(const bool hide)
|
||||||
{
|
{
|
||||||
m_entryView->setHidePasswords(hide);
|
m_entryView->setPasswordsHidden(hide);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
* Get current view state of entry view
|
||||||
* Get current state of entry view view
|
|
||||||
*/
|
*/
|
||||||
QByteArray DatabaseWidget::entryViewViewState() const
|
QByteArray DatabaseWidget::entryViewState() const
|
||||||
{
|
{
|
||||||
return m_entryView->viewState();
|
return m_entryView->viewState();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
* Set view state of entry view
|
||||||
* Set state of entry view view
|
|
||||||
*/
|
*/
|
||||||
bool DatabaseWidget::setEntryViewViewState(const QByteArray& state) const
|
bool DatabaseWidget::setEntryViewState(const QByteArray& state) const
|
||||||
{
|
{
|
||||||
return m_entryView->setViewState(state);
|
return m_entryView->setViewState(state);
|
||||||
}
|
}
|
||||||
@ -696,8 +684,8 @@ void DatabaseWidget::openUrlForEntry(Entry* entry)
|
|||||||
|
|
||||||
void DatabaseWidget::createGroup()
|
void DatabaseWidget::createGroup()
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(m_groupView->currentGroup());
|
||||||
if (!m_groupView->currentGroup()) {
|
if (!m_groupView->currentGroup()) {
|
||||||
Q_ASSERT(false);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -710,8 +698,8 @@ void DatabaseWidget::createGroup()
|
|||||||
void DatabaseWidget::deleteGroup()
|
void DatabaseWidget::deleteGroup()
|
||||||
{
|
{
|
||||||
Group* currentGroup = m_groupView->currentGroup();
|
Group* currentGroup = m_groupView->currentGroup();
|
||||||
|
Q_ASSERT(currentGroup && canDeleteCurrentGroup());
|
||||||
if (!currentGroup || !canDeleteCurrentGroup()) {
|
if (!currentGroup || !canDeleteCurrentGroup()) {
|
||||||
Q_ASSERT(false);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -944,23 +932,14 @@ void DatabaseWidget::unlockDatabase(bool accepted)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Add 'copy-on-doubleclick' functionality for certain columns
|
|
||||||
*
|
|
||||||
* TODO:
|
|
||||||
* If pull request #1298 gets merged, double-clicking column 'Attachments'
|
|
||||||
* could open the new details view (see second screenshot)
|
|
||||||
*/
|
|
||||||
void DatabaseWidget::entryActivationSignalReceived(Entry* entry, EntryModel::ModelColumn column)
|
void DatabaseWidget::entryActivationSignalReceived(Entry* entry, EntryModel::ModelColumn column)
|
||||||
{
|
{
|
||||||
/* Should never happen */
|
Q_ASSERT(entry);
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
Q_ASSERT(false);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Decide what to do based on specified column */
|
// Implement 'copy-on-doubleclick' functionality for certain columns
|
||||||
switch (column) {
|
switch (column) {
|
||||||
case EntryModel::Username:
|
case EntryModel::Username:
|
||||||
setClipboardTextAndMinimize(entry->resolveMultiplePlaceholders(entry->username()));
|
setClipboardTextAndMinimize(entry->resolveMultiplePlaceholders(entry->username()));
|
||||||
@ -973,9 +952,12 @@ void DatabaseWidget::entryActivationSignalReceived(Entry* entry, EntryModel::Mod
|
|||||||
openUrlForEntry(entry);
|
openUrlForEntry(entry);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EntryModel::Notes:
|
// TODO: switch to 'Notes' tab in details view/pane
|
||||||
setClipboardTextAndMinimize(entry->resolveMultiplePlaceholders(entry->notes()));
|
//case EntryModel::Notes:
|
||||||
break;
|
// break;
|
||||||
|
// TODO: switch to 'Attachments' tab in details view/pane
|
||||||
|
//case EntryModel::Attachments:
|
||||||
|
// break;
|
||||||
default:
|
default:
|
||||||
switchToEntryEdit(entry);
|
switchToEntryEdit(entry);
|
||||||
}
|
}
|
||||||
|
@ -92,23 +92,12 @@ public:
|
|||||||
void setMainSplitterSizes(const QList<int>& sizes);
|
void setMainSplitterSizes(const QList<int>& sizes);
|
||||||
QList<int> detailSplitterSizes() const;
|
QList<int> detailSplitterSizes() const;
|
||||||
void setDetailSplitterSizes(const QList<int>& sizes);
|
void setDetailSplitterSizes(const QList<int>& sizes);
|
||||||
|
bool isUsernamesHidden() const;
|
||||||
/**
|
void setUsernamesHidden(const bool hide);
|
||||||
* @author Fonic <https://github.com/fonic>
|
bool isPasswordsHidden() const;
|
||||||
* Methods to get/set state of entry view 'Hide Usernames'/'Hide
|
void setPasswordsHidden(const bool hide);
|
||||||
* Passwords' settings
|
QByteArray entryViewState() const;
|
||||||
*/
|
bool setEntryViewState(const QByteArray& state) const;
|
||||||
bool entryViewHideUsernames() const;
|
|
||||||
void setEntryViewHideUsernames(const bool hide);
|
|
||||||
bool entryViewHidePasswords() const;
|
|
||||||
void setEntryViewHidePasswords(const bool hide);
|
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Methods to get/set state of entry view view state
|
|
||||||
*/
|
|
||||||
QByteArray entryViewViewState() const;
|
|
||||||
bool setEntryViewViewState(const QByteArray& state) const;
|
|
||||||
|
|
||||||
void clearAllWidgets();
|
void clearAllWidgets();
|
||||||
bool currentEntryHasTitle();
|
bool currentEntryHasTitle();
|
||||||
bool currentEntryHasUsername();
|
bool currentEntryHasUsername();
|
||||||
@ -142,13 +131,7 @@ signals:
|
|||||||
void searchModeActivated();
|
void searchModeActivated();
|
||||||
void mainSplitterSizesChanged();
|
void mainSplitterSizesChanged();
|
||||||
void detailSplitterSizesChanged();
|
void detailSplitterSizesChanged();
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Signal to notify about state changes entry view view
|
|
||||||
*/
|
|
||||||
void entryViewStateChanged();
|
void entryViewStateChanged();
|
||||||
|
|
||||||
void updateSearch(QString text);
|
void updateSearch(QString text);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
@ -27,40 +27,20 @@ DatabaseWidgetStateSync::DatabaseWidgetStateSync(QObject* parent)
|
|||||||
{
|
{
|
||||||
m_mainSplitterSizes = variantToIntList(config()->get("GUI/SplitterState"));
|
m_mainSplitterSizes = variantToIntList(config()->get("GUI/SplitterState"));
|
||||||
m_detailSplitterSizes = variantToIntList(config()->get("GUI/DetailSplitterState"));
|
m_detailSplitterSizes = variantToIntList(config()->get("GUI/DetailSplitterState"));
|
||||||
|
m_hideUsernames = config()->get("GUI/HideUsernames").toBool();
|
||||||
/**
|
m_hidePasswords = config()->get("GUI/HidePasswords").toBool();
|
||||||
* @author Fonic <https://github.com/fonic>
|
m_listViewState = config()->get("GUI/ListViewState").toByteArray();
|
||||||
* Load state of entry view 'Hide Usernames'/'Hide Passwords' settings
|
m_searchViewState = config()->get("GUI/SearchViewState").toByteArray();
|
||||||
*/
|
|
||||||
m_entryHideUsernames = config()->get("GUI/EntryHideUsernames").toBool();
|
|
||||||
m_entryHidePasswords = config()->get("GUI/EntryHidePasswords").toBool();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Load states of entry view list/search view
|
|
||||||
*/
|
|
||||||
m_entryListViewState = config()->get("GUI/EntryListViewState").toByteArray();
|
|
||||||
m_entrySearchViewState = config()->get("GUI/EntrySearchViewState").toByteArray();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DatabaseWidgetStateSync::~DatabaseWidgetStateSync()
|
DatabaseWidgetStateSync::~DatabaseWidgetStateSync()
|
||||||
{
|
{
|
||||||
config()->set("GUI/SplitterState", intListToVariant(m_mainSplitterSizes));
|
config()->set("GUI/SplitterState", intListToVariant(m_mainSplitterSizes));
|
||||||
config()->set("GUI/DetailSplitterState", intListToVariant(m_detailSplitterSizes));
|
config()->set("GUI/DetailSplitterState", intListToVariant(m_detailSplitterSizes));
|
||||||
|
config()->set("GUI/HideUsernames", m_hideUsernames);
|
||||||
/**
|
config()->set("GUI/HidePasswords", m_hidePasswords);
|
||||||
* @author Fonic <https://github.com/fonic>
|
config()->set("GUI/ListViewState", m_listViewState);
|
||||||
* Save state of entry view 'Hide Usernames'/'Hide Passwords' settings
|
config()->set("GUI/SearchViewState", m_searchViewState);
|
||||||
*/
|
|
||||||
config()->set("GUI/EntryHideUsernames", m_entryHideUsernames);
|
|
||||||
config()->set("GUI/EntryHidePasswords", m_entryHidePasswords);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Save states of entry view list/search view
|
|
||||||
*/
|
|
||||||
config()->set("GUI/EntryListViewState", m_entryListViewState);
|
|
||||||
config()->set("GUI/EntrySearchViewState", m_entrySearchViewState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseWidgetStateSync::setActive(DatabaseWidget* dbWidget)
|
void DatabaseWidgetStateSync::setActive(DatabaseWidget* dbWidget)
|
||||||
@ -94,14 +74,8 @@ void DatabaseWidgetStateSync::setActive(DatabaseWidget* dbWidget)
|
|||||||
SLOT(updateSplitterSizes()));
|
SLOT(updateSplitterSizes()));
|
||||||
connect(m_activeDbWidget, SIGNAL(detailSplitterSizesChanged()),
|
connect(m_activeDbWidget, SIGNAL(detailSplitterSizesChanged()),
|
||||||
SLOT(updateSplitterSizes()));
|
SLOT(updateSplitterSizes()));
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Connect signal to receive state changes of entry view view
|
|
||||||
*/
|
|
||||||
connect(m_activeDbWidget, SIGNAL(entryViewStateChanged()),
|
connect(m_activeDbWidget, SIGNAL(entryViewStateChanged()),
|
||||||
SLOT(updateViewState()));
|
SLOT(updateViewState()));
|
||||||
|
|
||||||
connect(m_activeDbWidget, SIGNAL(listModeActivated()),
|
connect(m_activeDbWidget, SIGNAL(listModeActivated()),
|
||||||
SLOT(restoreListView()));
|
SLOT(restoreListView()));
|
||||||
connect(m_activeDbWidget, SIGNAL(searchModeActivated()),
|
connect(m_activeDbWidget, SIGNAL(searchModeActivated()),
|
||||||
@ -114,58 +88,54 @@ void DatabaseWidgetStateSync::setActive(DatabaseWidget* dbWidget)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Restore entry view list view state
|
* Restore entry view list view state
|
||||||
*
|
*
|
||||||
* NOTE:
|
* NOTE:
|
||||||
* States of entry view 'Hide Usernames'/'Hide Passwords' settings are considered
|
* States of entry view 'Hide Usernames'/'Hide Passwords' settings are global,
|
||||||
* 'global', i.e. they are the same for both list and search mode
|
* i.e. they are the same for both list and search mode
|
||||||
*
|
*
|
||||||
* NOTE:
|
* NOTE:
|
||||||
* If m_entryListViewState is empty, it is the first time after clean/invalid
|
* If m_listViewState is empty, the list view has been activated for the first
|
||||||
* config that list view is activated. Thus, save its current state. Without
|
* time after starting with a clean (or invalid) config. Thus, save the current
|
||||||
* this, m_entryListViewState would remain empty until there is an actual view
|
* state. Without this, m_listViewState would remain empty until there is an
|
||||||
* state change (e.g. column is resized)
|
* actual view state change (e.g. column is resized)
|
||||||
*/
|
*/
|
||||||
void DatabaseWidgetStateSync::restoreListView()
|
void DatabaseWidgetStateSync::restoreListView()
|
||||||
{
|
{
|
||||||
m_activeDbWidget->setEntryViewHideUsernames(m_entryHideUsernames);
|
m_activeDbWidget->setUsernamesHidden(m_hideUsernames);
|
||||||
m_activeDbWidget->setEntryViewHidePasswords(m_entryHidePasswords);
|
m_activeDbWidget->setPasswordsHidden(m_hidePasswords);
|
||||||
|
|
||||||
if (!m_entryListViewState.isEmpty()) {
|
if (!m_listViewState.isEmpty()) {
|
||||||
m_activeDbWidget->setEntryViewViewState(m_entryListViewState);
|
m_activeDbWidget->setEntryViewState(m_listViewState);
|
||||||
}
|
} else {
|
||||||
else {
|
m_listViewState = m_activeDbWidget->entryViewState();
|
||||||
m_entryListViewState = m_activeDbWidget->entryViewViewState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_blockUpdates = false;
|
m_blockUpdates = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Restore entry view search view state
|
* Restore entry view search view state
|
||||||
*
|
*
|
||||||
* NOTE:
|
* NOTE:
|
||||||
* States of entry view 'Hide Usernames'/'Hide Passwords' settings are considered
|
* States of entry view 'Hide Usernames'/'Hide Passwords' settings are global,
|
||||||
* 'global', i.e. they are the same for both list and search mode
|
* i.e. they are the same for both list and search mode
|
||||||
*
|
*
|
||||||
* NOTE:
|
* NOTE:
|
||||||
* If m_entrySearchViewState is empty, it is the first time after clean/invalid
|
* If m_searchViewState is empty, the search view has been activated for the
|
||||||
* config that search view is activated. Thus, save its current state. Without
|
* first time after starting with a clean (or invalid) config. Thus, save the
|
||||||
* this, m_entrySearchViewState would remain empty until there is an actual view
|
* current state. Without this, m_searchViewState would remain empty until
|
||||||
* state change (e.g. column is resized)
|
* there is an actual view state change (e.g. column is resized)
|
||||||
*/
|
*/
|
||||||
void DatabaseWidgetStateSync::restoreSearchView()
|
void DatabaseWidgetStateSync::restoreSearchView()
|
||||||
{
|
{
|
||||||
m_activeDbWidget->setEntryViewHideUsernames(m_entryHideUsernames);
|
m_activeDbWidget->setUsernamesHidden(m_hideUsernames);
|
||||||
m_activeDbWidget->setEntryViewHidePasswords(m_entryHidePasswords);
|
m_activeDbWidget->setPasswordsHidden(m_hidePasswords);
|
||||||
|
|
||||||
if (!m_entrySearchViewState.isEmpty()) {
|
if (!m_searchViewState.isEmpty()) {
|
||||||
m_activeDbWidget->setEntryViewViewState(m_entrySearchViewState);
|
m_activeDbWidget->setEntryViewState(m_searchViewState);
|
||||||
}
|
} else {
|
||||||
else {
|
m_searchViewState = m_activeDbWidget->entryViewState();
|
||||||
m_entrySearchViewState = m_activeDbWidget->entryViewViewState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_blockUpdates = false;
|
m_blockUpdates = false;
|
||||||
@ -187,10 +157,11 @@ void DatabaseWidgetStateSync::updateSplitterSizes()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
* Update entry view list/search view state
|
||||||
* Update entry view list/search view state (NOTE: states of entry view
|
*
|
||||||
* 'Hide Usernames'/'Hide Passwords' settings are considered 'global',
|
* NOTE:
|
||||||
* i.e. they are the same for both list and search mode)
|
* 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()
|
void DatabaseWidgetStateSync::updateViewState()
|
||||||
{
|
{
|
||||||
@ -198,14 +169,13 @@ void DatabaseWidgetStateSync::updateViewState()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_entryHideUsernames = m_activeDbWidget->entryViewHideUsernames();
|
m_hideUsernames = m_activeDbWidget->isUsernamesHidden();
|
||||||
m_entryHidePasswords = m_activeDbWidget->entryViewHidePasswords();
|
m_hidePasswords = m_activeDbWidget->isPasswordsHidden();
|
||||||
|
|
||||||
if (m_activeDbWidget->isInSearchMode()) {
|
if (m_activeDbWidget->isInSearchMode()) {
|
||||||
m_entrySearchViewState = m_activeDbWidget->entryViewViewState();
|
m_searchViewState = m_activeDbWidget->entryViewState();
|
||||||
}
|
} else {
|
||||||
else {
|
m_listViewState = m_activeDbWidget->entryViewState();
|
||||||
m_entryListViewState = m_activeDbWidget->entryViewViewState();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,8 +189,7 @@ QList<int> DatabaseWidgetStateSync::variantToIntList(const QVariant& variant)
|
|||||||
int size = var.toInt(&ok);
|
int size = var.toInt(&ok);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
result.append(size);
|
result.append(size);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
result.clear();
|
result.clear();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -239,4 +208,3 @@ QVariant DatabaseWidgetStateSync::intListToVariant(const QList<int>& list)
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,11 +37,6 @@ public slots:
|
|||||||
private slots:
|
private slots:
|
||||||
void blockUpdates();
|
void blockUpdates();
|
||||||
void updateSplitterSizes();
|
void updateSplitterSizes();
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Slot to update entry view view state
|
|
||||||
*/
|
|
||||||
void updateViewState();
|
void updateViewState();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -54,21 +49,11 @@ private:
|
|||||||
QList<int> m_mainSplitterSizes;
|
QList<int> m_mainSplitterSizes;
|
||||||
QList<int> m_detailSplitterSizes;
|
QList<int> m_detailSplitterSizes;
|
||||||
|
|
||||||
/**
|
bool m_hideUsernames;
|
||||||
* @author Fonic <https://github.com/fonic>
|
bool m_hidePasswords;
|
||||||
* Properties to store state of entry view 'Hide Usernames'/'Hide
|
|
||||||
* Passwords' settings
|
|
||||||
*/
|
|
||||||
bool m_entryHideUsernames;
|
|
||||||
bool m_entryHidePasswords;
|
|
||||||
|
|
||||||
/**
|
QByteArray m_listViewState;
|
||||||
* @author Fonic <https://github.com/fonic>
|
QByteArray m_searchViewState;
|
||||||
* Properties to store states of entry view list/search view (replaces
|
|
||||||
* m_columnSizesList/m_columnSizesSearch)
|
|
||||||
*/
|
|
||||||
QByteArray m_entryListViewState;
|
|
||||||
QByteArray m_entrySearchViewState;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // KEEPASSX_DATABASEWIDGETSTATESYNC_H
|
#endif // KEEPASSX_DATABASEWIDGETSTATESYNC_H
|
||||||
|
@ -127,7 +127,7 @@ void DetailsWidget::getSelectedEntry(Entry* selectedEntry)
|
|||||||
shortPassword(m_currentEntry->resolveMultiplePlaceholders(m_currentEntry->password())));
|
shortPassword(m_currentEntry->resolveMultiplePlaceholders(m_currentEntry->password())));
|
||||||
m_ui->passwordLabel->setToolTip(m_currentEntry->resolveMultiplePlaceholders(m_currentEntry->password()));
|
m_ui->passwordLabel->setToolTip(m_currentEntry->resolveMultiplePlaceholders(m_currentEntry->password()));
|
||||||
} else {
|
} else {
|
||||||
m_ui->passwordLabel->setText("****");
|
m_ui->passwordLabel->setText(QString("\u25cf").repeated(6));
|
||||||
}
|
}
|
||||||
|
|
||||||
QString url = m_currentEntry->webUrl();
|
QString url = m_currentEntry->webUrl();
|
||||||
|
@ -20,11 +20,6 @@
|
|||||||
#include <QFont>
|
#include <QFont>
|
||||||
#include <QMimeData>
|
#include <QMimeData>
|
||||||
#include <QPalette>
|
#include <QPalette>
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Add include required for additional columns 'Expires', 'Created', 'Modified'
|
|
||||||
* and 'Accessed'
|
|
||||||
*/
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
|
||||||
#include "core/DatabaseIcons.h"
|
#include "core/DatabaseIcons.h"
|
||||||
@ -33,43 +28,15 @@
|
|||||||
#include "core/Group.h"
|
#include "core/Group.h"
|
||||||
#include "core/Metadata.h"
|
#include "core/Metadata.h"
|
||||||
|
|
||||||
/**
|
// String being displayed when hiding content
|
||||||
* @author Fonic <https://github.com/fonic>
|
const QString EntryModel::HiddenContentDisplay(QString("\u25cf").repeated(6));
|
||||||
* Define constant string used to display hidden content in columns 'Username'
|
|
||||||
* and 'Password'
|
|
||||||
*
|
|
||||||
* TODO:
|
|
||||||
* Decide which of the proposed options should be used (stars, bullet, black
|
|
||||||
* circle)
|
|
||||||
*/
|
|
||||||
//const QString EntryModel::HiddenContentDisplay("******");
|
|
||||||
//const QString EntryModel::HiddenContentDisplay(QString(QChar(0x2022)).repeated(6));
|
|
||||||
const QString EntryModel::HiddenContentDisplay(QString(QChar(0x25CF)).repeated(6));
|
|
||||||
|
|
||||||
/**
|
// Format used to display dates
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Define date format used to display dates in columns 'Expires', 'Created',
|
|
||||||
* 'Modified' and 'Accessed'
|
|
||||||
*/
|
|
||||||
const Qt::DateFormat EntryModel::DateFormat = Qt::DefaultLocaleShortDate;
|
const Qt::DateFormat EntryModel::DateFormat = Qt::DefaultLocaleShortDate;
|
||||||
|
|
||||||
/**
|
// Paperclip symbol
|
||||||
* @author Fonic <https://github.com/fonic>
|
const QString EntryModel::PaperClipDisplay("\U0001f4ce");
|
||||||
* Define constant string used to display header and data of column 'Paper-
|
|
||||||
* clip'
|
|
||||||
*
|
|
||||||
* TODO:
|
|
||||||
* When using unicode, ASAN reports memory leaks, but when using a plain
|
|
||||||
* string like 'x', no leaks are reported. Check if this is something to
|
|
||||||
* worry about, might as well be a Qt bug
|
|
||||||
*/
|
|
||||||
const QString EntryModel::PaperClipDisplay(QString("\U0001f4ce"));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Initialize 'Hide Usernames' and 'Hide Passwords' settings using sane
|
|
||||||
* defaults (usernames visible, passwords hidden)
|
|
||||||
*/
|
|
||||||
EntryModel::EntryModel(QObject* parent)
|
EntryModel::EntryModel(QObject* parent)
|
||||||
: QAbstractTableModel(parent)
|
: QAbstractTableModel(parent)
|
||||||
, m_group(nullptr)
|
, m_group(nullptr)
|
||||||
@ -153,27 +120,19 @@ int EntryModel::rowCount(const QModelIndex& parent) const
|
|||||||
{
|
{
|
||||||
if (parent.isValid()) {
|
if (parent.isValid()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return m_entries.size();
|
return m_entries.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int EntryModel::columnCount(const QModelIndex& parent) const
|
int EntryModel::columnCount(const QModelIndex& parent) const
|
||||||
{
|
{
|
||||||
/**
|
// Advised by Qt documentation
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Change column count to include additional columns 'Password', 'Notes',
|
|
||||||
* 'Expires', 'Created', 'Modified', 'Accessed', 'Paperclip' and
|
|
||||||
* 'Attachments'. Also, return 0 when parent is valid as advised by Qt
|
|
||||||
* documentation
|
|
||||||
*/
|
|
||||||
if (parent.isValid()) {
|
if (parent.isValid()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
return 12;
|
return 12;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant EntryModel::data(const QModelIndex& index, int role) const
|
QVariant EntryModel::data(const QModelIndex& index, int role) const
|
||||||
@ -185,26 +144,6 @@ QVariant EntryModel::data(const QModelIndex& index, int role) const
|
|||||||
Entry* entry = entryFromIndex(index);
|
Entry* entry = entryFromIndex(index);
|
||||||
EntryAttributes* attr = entry->attributes();
|
EntryAttributes* attr = entry->attributes();
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
*
|
|
||||||
* Add display data providers for additional columns 'Password', 'Notes',
|
|
||||||
* 'Expires', 'Created', 'Modified', 'Accessed', 'Paperclip' and
|
|
||||||
* 'Attachments'
|
|
||||||
*
|
|
||||||
* Add ability to display usernames and passwords hidden or visible
|
|
||||||
* depending on current state of 'Hide Usernames' and 'Hide Passwords'
|
|
||||||
* settings
|
|
||||||
*
|
|
||||||
* TODO:
|
|
||||||
* Decide which of the additional columns should expand placeholders
|
|
||||||
* -> code added where applicable, but currently commented out
|
|
||||||
*
|
|
||||||
* Check what attr->isReference() does and if it applies to any of the
|
|
||||||
* additional columns
|
|
||||||
* -> code added for columns 'Password' and 'Notes', as EntryAttributes::
|
|
||||||
* PasswordKey and EntryAttributes::NotesKey already existed
|
|
||||||
*/
|
|
||||||
if (role == Qt::DisplayRole) {
|
if (role == Qt::DisplayRole) {
|
||||||
QString result;
|
QString result;
|
||||||
switch (index.column()) {
|
switch (index.column()) {
|
||||||
@ -216,63 +155,44 @@ QVariant EntryModel::data(const QModelIndex& index, int role) const
|
|||||||
case Title:
|
case Title:
|
||||||
result = entry->resolveMultiplePlaceholders(entry->title());
|
result = entry->resolveMultiplePlaceholders(entry->title());
|
||||||
if (attr->isReference(EntryAttributes::TitleKey)) {
|
if (attr->isReference(EntryAttributes::TitleKey)) {
|
||||||
result.prepend(tr("Ref: ","Reference abbreviation"));
|
result.prepend(tr("Ref: ", "Reference abbreviation"));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
case Username:
|
case Username:
|
||||||
/*
|
|
||||||
* Display usernames hidden or visible according to current state
|
|
||||||
* of 'Hide Usernames' setting
|
|
||||||
*/
|
|
||||||
if (m_hideUsernames) {
|
if (m_hideUsernames) {
|
||||||
result = EntryModel::HiddenContentDisplay;
|
result = EntryModel::HiddenContentDisplay;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
//result = entry->username();
|
|
||||||
result = entry->resolveMultiplePlaceholders(entry->username());
|
result = entry->resolveMultiplePlaceholders(entry->username());
|
||||||
}
|
}
|
||||||
if (attr->isReference(EntryAttributes::UserNameKey)) {
|
if (attr->isReference(EntryAttributes::UserNameKey)) {
|
||||||
result.prepend(tr("Ref: ","Reference abbreviation"));
|
result.prepend(tr("Ref: ", "Reference abbreviation"));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
case Password:
|
case Password:
|
||||||
/*
|
|
||||||
* Display passwords hidden or visible according to current state
|
|
||||||
* of 'Hide Passwords' setting
|
|
||||||
*/
|
|
||||||
if (m_hidePasswords) {
|
if (m_hidePasswords) {
|
||||||
result = EntryModel::HiddenContentDisplay;
|
result = EntryModel::HiddenContentDisplay;
|
||||||
}
|
} else {
|
||||||
else {
|
result = entry->resolveMultiplePlaceholders(entry->password());
|
||||||
//result = entry->resolveMultiplePlaceholders(entry->password());
|
|
||||||
result = entry->password();
|
|
||||||
}
|
}
|
||||||
if (attr->isReference(EntryAttributes::PasswordKey)) {
|
if (attr->isReference(EntryAttributes::PasswordKey)) {
|
||||||
result.prepend(tr("Ref: ","Reference abbreviation"));
|
result.prepend(tr("Ref: ", "Reference abbreviation"));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
case Url:
|
case Url:
|
||||||
//result = entry->resolveMultiplePlaceholders(entry->displayUrl());
|
result = entry->resolveMultiplePlaceholders(entry->displayUrl());
|
||||||
result = entry->displayUrl();
|
|
||||||
if (attr->isReference(EntryAttributes::URLKey)) {
|
if (attr->isReference(EntryAttributes::URLKey)) {
|
||||||
result.prepend(tr("Ref: ","Reference abbreviation"));
|
result.prepend(tr("Ref: ", "Reference abbreviation"));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
case Notes:
|
case Notes:
|
||||||
/*
|
// Display only first line of notes in simplified format
|
||||||
* Display only first line of notes in simplified format like
|
result = entry->resolveMultiplePlaceholders(entry->notes().section("\n", 0, 0).simplified());
|
||||||
* KeePassX does
|
|
||||||
*/
|
|
||||||
//result = entry->resolveMultiplePlaceholders(entry->notes().section("\n", 0, 0).simplified());
|
|
||||||
result = entry->notes().section("\n", 0, 0).simplified();
|
|
||||||
if (attr->isReference(EntryAttributes::NotesKey)) {
|
if (attr->isReference(EntryAttributes::NotesKey)) {
|
||||||
result.prepend(tr("Ref: ","Reference abbreviation"));
|
result.prepend(tr("Ref: ", "Reference abbreviation"));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
case Expires:
|
case Expires:
|
||||||
/*
|
// Display either date of expiry or 'Never'
|
||||||
* Display either date of expiry or 'Never' like KeePassX does
|
|
||||||
*/
|
|
||||||
result = entry->timeInfo().expires() ? entry->timeInfo().expiryTime().toLocalTime().toString(EntryModel::DateFormat) : tr("Never");
|
result = entry->timeInfo().expires() ? entry->timeInfo().expiryTime().toLocalTime().toString(EntryModel::DateFormat) : tr("Never");
|
||||||
return result;
|
return result;
|
||||||
case Created:
|
case Created:
|
||||||
@ -288,65 +208,25 @@ QVariant EntryModel::data(const QModelIndex& index, int role) const
|
|||||||
result = entry->attachments()->keys().isEmpty() ? QString() : EntryModel::PaperClipDisplay;
|
result = entry->attachments()->keys().isEmpty() ? QString() : EntryModel::PaperClipDisplay;
|
||||||
return result;
|
return result;
|
||||||
case Attachments:
|
case Attachments:
|
||||||
/*
|
// Display comma-separated list of attachments
|
||||||
* Display comma-separated list of attachments
|
|
||||||
*
|
|
||||||
* TODO:
|
|
||||||
* 'entry->attachments()->keys().join()' works locally, yet it fails
|
|
||||||
* on GitHub/Travis CI, most likely due to an older Qt version, thus
|
|
||||||
* using loop for now (http://doc.qt.io/qt-5/qlist.html#more-members)
|
|
||||||
*/
|
|
||||||
//result = entry->resolveMultiplePlaceholders(entry->attachments()->keys().join(", "));
|
|
||||||
//result = entry->attachments()->keys().join(", ");
|
|
||||||
|
|
||||||
QList<QString> attachments = entry->attachments()->keys();
|
QList<QString> attachments = entry->attachments()->keys();
|
||||||
for (int i=0; i < attachments.size(); i++) {
|
for (int i = 0; i < attachments.size(); ++i) {
|
||||||
if (result.isEmpty()) {
|
if (result.isEmpty()) {
|
||||||
result.append(attachments.at(i));
|
result.append(attachments.at(i));
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else {
|
result.append(QString(", ") + attachments.at(i));
|
||||||
result.append(QString(", ") + attachments.at(i));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//result = entry->resolveMultiplePlaceholders(result);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
} else if (role == Qt::UserRole) { // Qt::UserRole is used as sort role, see EntryView::EntryView()
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
*
|
|
||||||
* Add sort data providers for columns 'Username' and 'Password', required
|
|
||||||
* for correct sorting even if displayed hidden (i.e. settings 'Hide User-
|
|
||||||
* names' and/or 'Hide Passwords' are enabled)
|
|
||||||
*
|
|
||||||
* Add sort data providers for columns 'Expires', 'Created', 'Modified'
|
|
||||||
* and 'Accessed', required for correct sorting of dates (without this,
|
|
||||||
* sorting would be based on string representation of dates, yielding un-
|
|
||||||
* desired results)
|
|
||||||
*
|
|
||||||
* Add sort data provider for column 'Paperclip', required to display
|
|
||||||
* entries with attachments above those without when sorting ascendingly
|
|
||||||
* (and vice versa when sorting descendingly)
|
|
||||||
*
|
|
||||||
* NOTE:
|
|
||||||
* Qt::UserRole is used as sort role, using 'm_sortModel->setSortRole(Qt::
|
|
||||||
* UserRole)' in EntryView.cpp, EntryView::EntryView()
|
|
||||||
*/
|
|
||||||
else if (role == Qt::UserRole) {
|
|
||||||
switch (index.column()) {
|
switch (index.column()) {
|
||||||
case Username:
|
case Username:
|
||||||
//return entry->username();
|
|
||||||
return entry->resolveMultiplePlaceholders(entry->username());
|
return entry->resolveMultiplePlaceholders(entry->username());
|
||||||
case Password:
|
case Password:
|
||||||
//return entry->resolveMultiplePlaceholders(entry->password());
|
return entry->resolveMultiplePlaceholders(entry->password());
|
||||||
return entry->password();
|
|
||||||
case Expires:
|
case Expires:
|
||||||
/*
|
// There seems to be no better way of expressing 'infinity'
|
||||||
* TODO:
|
|
||||||
* Is there any better way to return a QDateTime representing
|
|
||||||
* 'Never' / infinity / end of all time?
|
|
||||||
*/
|
|
||||||
return entry->timeInfo().expires() ? entry->timeInfo().expiryTime() : QDateTime(QDate(9999, 1, 1));
|
return entry->timeInfo().expires() ? entry->timeInfo().expiryTime() : QDateTime(QDate(9999, 1, 1));
|
||||||
case Created:
|
case Created:
|
||||||
return entry->timeInfo().creationTime();
|
return entry->timeInfo().creationTime();
|
||||||
@ -355,16 +235,15 @@ QVariant EntryModel::data(const QModelIndex& index, int role) const
|
|||||||
case Accessed:
|
case Accessed:
|
||||||
return entry->timeInfo().lastAccessTime();
|
return entry->timeInfo().lastAccessTime();
|
||||||
case Paperclip:
|
case Paperclip:
|
||||||
|
// Display entries with attachments above those without when
|
||||||
|
// sorting ascendingly (and vice versa when sorting descendingly)
|
||||||
return entry->attachments()->keys().isEmpty() ? 1 : 0;
|
return entry->attachments()->keys().isEmpty() ? 1 : 0;
|
||||||
default:
|
default:
|
||||||
/*
|
// For all other columns, simply use data provided by Qt::Display-
|
||||||
* For all other columns, simply use data provided by Qt::Display-
|
// Role for sorting
|
||||||
* Role for sorting
|
|
||||||
*/
|
|
||||||
return data(index, Qt::DisplayRole);
|
return data(index, Qt::DisplayRole);
|
||||||
}
|
}
|
||||||
}
|
} else if (role == Qt::DecorationRole) {
|
||||||
else if (role == Qt::DecorationRole) {
|
|
||||||
switch (index.column()) {
|
switch (index.column()) {
|
||||||
case ParentGroup:
|
case ParentGroup:
|
||||||
if (entry->group()) {
|
if (entry->group()) {
|
||||||
@ -374,20 +253,17 @@ QVariant EntryModel::data(const QModelIndex& index, int role) const
|
|||||||
case Title:
|
case Title:
|
||||||
if (entry->isExpired()) {
|
if (entry->isExpired()) {
|
||||||
return databaseIcons()->iconPixmap(DatabaseIcons::ExpiredIconIndex);
|
return databaseIcons()->iconPixmap(DatabaseIcons::ExpiredIconIndex);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return entry->iconScaledPixmap();
|
return entry->iconScaledPixmap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if (role == Qt::FontRole) {
|
||||||
else if (role == Qt::FontRole) {
|
|
||||||
QFont font;
|
QFont font;
|
||||||
if (entry->isExpired()) {
|
if (entry->isExpired()) {
|
||||||
font.setStrikeOut(true);
|
font.setStrikeOut(true);
|
||||||
}
|
}
|
||||||
return font;
|
return font;
|
||||||
}
|
} else if (role == Qt::TextColorRole) {
|
||||||
else if (role == Qt::TextColorRole) {
|
|
||||||
if (entry->hasReferences()) {
|
if (entry->hasReferences()) {
|
||||||
QPalette p;
|
QPalette p;
|
||||||
return QVariant(p.color(QPalette::Active, QPalette::Mid));
|
return QVariant(p.color(QPalette::Active, QPalette::Mid));
|
||||||
@ -399,11 +275,6 @@ QVariant EntryModel::data(const QModelIndex& index, int role) const
|
|||||||
|
|
||||||
QVariant EntryModel::headerData(int section, Qt::Orientation orientation, int role) const
|
QVariant EntryModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Add captions for additional columns 'Password', 'Notes', 'Expires',
|
|
||||||
* 'Created', 'Modified', 'Accessed', 'Paperclip' and 'Attachments'
|
|
||||||
*/
|
|
||||||
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
|
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
|
||||||
switch (section) {
|
switch (section) {
|
||||||
case ParentGroup:
|
case ParentGroup:
|
||||||
@ -450,8 +321,7 @@ Qt::ItemFlags EntryModel::flags(const QModelIndex& modelIndex) const
|
|||||||
{
|
{
|
||||||
if (!modelIndex.isValid()) {
|
if (!modelIndex.isValid()) {
|
||||||
return Qt::NoItemFlags;
|
return Qt::NoItemFlags;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return QAbstractItemModel::flags(modelIndex) | Qt::ItemIsDragEnabled;
|
return QAbstractItemModel::flags(modelIndex) | Qt::ItemIsDragEnabled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -492,8 +362,7 @@ QMimeData* EntryModel::mimeData(const QModelIndexList& indexes) const
|
|||||||
if (seenEntries.isEmpty()) {
|
if (seenEntries.isEmpty()) {
|
||||||
delete data;
|
delete data;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
data->setData(mimeTypes().at(0), encoded);
|
data->setData(mimeTypes().at(0), encoded);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
@ -567,57 +436,51 @@ void EntryModel::makeConnections(const Group* group)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Get current state of 'Hide Usernames' setting
|
* Get current state of 'Hide Usernames' setting
|
||||||
*/
|
*/
|
||||||
bool EntryModel::hideUsernames() const
|
bool EntryModel::isUsernamesHidden() const
|
||||||
{
|
{
|
||||||
return m_hideUsernames;
|
return m_hideUsernames;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Set state of 'Hide Usernames' setting and signal change
|
* Set state of 'Hide Usernames' setting and signal change
|
||||||
*/
|
*/
|
||||||
void EntryModel::setHideUsernames(const bool hide)
|
void EntryModel::setUsernamesHidden(const bool hide)
|
||||||
{
|
{
|
||||||
m_hideUsernames = hide;
|
m_hideUsernames = hide;
|
||||||
emit hideUsernamesChanged();
|
emit usernamesHiddenChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Get current state of 'Hide Passwords' setting
|
* Get current state of 'Hide Passwords' setting
|
||||||
*/
|
*/
|
||||||
bool EntryModel::hidePasswords() const
|
bool EntryModel::isPasswordsHidden() const
|
||||||
{
|
{
|
||||||
return m_hidePasswords;
|
return m_hidePasswords;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Set state of 'Hide Passwords' setting and signal change
|
* Set state of 'Hide Passwords' setting and signal change
|
||||||
*/
|
*/
|
||||||
void EntryModel::setHidePasswords(const bool hide)
|
void EntryModel::setPasswordsHidden(const bool hide)
|
||||||
{
|
{
|
||||||
m_hidePasswords = hide;
|
m_hidePasswords = hide;
|
||||||
emit hidePasswordsChanged();
|
emit passwordsHiddenChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Toggle state of 'Hide Usernames' setting
|
* Toggle state of 'Hide Usernames' setting
|
||||||
*/
|
*/
|
||||||
void EntryModel::toggleHideUsernames(const bool hide)
|
void EntryModel::toggleUsernamesHidden(const bool hide)
|
||||||
{
|
{
|
||||||
setHideUsernames(hide);
|
setUsernamesHidden(hide);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Toggle state of 'Hide Passwords' setting
|
* Toggle state of 'Hide Passwords' setting
|
||||||
*/
|
*/
|
||||||
void EntryModel::toggleHidePasswords(const bool hide)
|
void EntryModel::togglePasswordsHidden(const bool hide)
|
||||||
{
|
{
|
||||||
setHidePasswords(hide);
|
setPasswordsHidden(hide);
|
||||||
}
|
}
|
||||||
|
@ -28,11 +28,6 @@ class EntryModel : public QAbstractTableModel
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Add entries for additional columns 'Password', 'Notes', 'Expires',
|
|
||||||
* 'Created', 'Modified', 'Accessed' and 'Attachments'
|
|
||||||
*/
|
|
||||||
enum ModelColumn
|
enum ModelColumn
|
||||||
{
|
{
|
||||||
ParentGroup = 0,
|
ParentGroup = 0,
|
||||||
@ -65,42 +60,21 @@ public:
|
|||||||
|
|
||||||
void setEntryList(const QList<Entry*>& entries);
|
void setEntryList(const QList<Entry*>& entries);
|
||||||
|
|
||||||
/**
|
bool isUsernamesHidden() const;
|
||||||
* @author Fonic <https://github.com/fonic>
|
void setUsernamesHidden(const bool hide);
|
||||||
* Methods to get/set state of 'Hide Usernames' and 'Hide Passwords'
|
bool isPasswordsHidden() const;
|
||||||
* settings
|
void setPasswordsHidden(const bool hide);
|
||||||
*/
|
|
||||||
bool hideUsernames() const;
|
|
||||||
void setHideUsernames(const bool hide);
|
|
||||||
bool hidePasswords() const;
|
|
||||||
void setHidePasswords(const bool hide);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Signals to notify about list/search mode switches (NOTE: previously
|
|
||||||
* named 'switchedToGroupMode'/'switchedToEntryListMode')
|
|
||||||
*/
|
|
||||||
void switchedToListMode();
|
void switchedToListMode();
|
||||||
void switchedToSearchMode();
|
void switchedToSearchMode();
|
||||||
|
void usernamesHiddenChanged();
|
||||||
/**
|
void passwordsHiddenChanged();
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Signals to notify about state changes of 'Hide Usernames' and 'Hide
|
|
||||||
* Passwords' settings
|
|
||||||
*/
|
|
||||||
void hideUsernamesChanged();
|
|
||||||
void hidePasswordsChanged();
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setGroup(Group* group);
|
void setGroup(Group* group);
|
||||||
|
void toggleUsernamesHidden(const bool hide);
|
||||||
/**
|
void togglePasswordsHidden(const bool hide);
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Slots to toggle state of 'Hide Usernames' and 'Hide Passwords' settings
|
|
||||||
*/
|
|
||||||
void toggleHideUsernames(const bool hide);
|
|
||||||
void toggleHidePasswords(const bool hide);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void entryAboutToAdd(Entry* entry);
|
void entryAboutToAdd(Entry* entry);
|
||||||
@ -118,33 +92,11 @@ private:
|
|||||||
QList<Entry*> m_orgEntries;
|
QList<Entry*> m_orgEntries;
|
||||||
QList<const Group*> m_allGroups;
|
QList<const Group*> m_allGroups;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Properties to store state of 'Hide Usernames' and 'Hide Passwords'
|
|
||||||
* settings
|
|
||||||
*/
|
|
||||||
bool m_hideUsernames;
|
bool m_hideUsernames;
|
||||||
bool m_hidePasswords;
|
bool m_hidePasswords;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Constant string used to display hidden content in columns 'Username'
|
|
||||||
* and 'Password'
|
|
||||||
*/
|
|
||||||
static const QString HiddenContentDisplay;
|
static const QString HiddenContentDisplay;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Date format used to display dates in columns 'Expires', 'Created',
|
|
||||||
* 'Modified' and 'Accessed'
|
|
||||||
*/
|
|
||||||
static const Qt::DateFormat DateFormat;
|
static const Qt::DateFormat DateFormat;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Constant string used to display header and data of column 'Paper-
|
|
||||||
* clip'
|
|
||||||
*/
|
|
||||||
static const QString PaperClipDisplay;
|
static const QString PaperClipDisplay;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -19,26 +19,10 @@
|
|||||||
|
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Add include required for header context menu
|
|
||||||
*/
|
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
|
|
||||||
#include "gui/SortFilterHideProxyModel.h"
|
#include "gui/SortFilterHideProxyModel.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
*
|
|
||||||
* TODO NOTE:
|
|
||||||
* Currently, 'zombie' columns which are not hidden but have width == 0
|
|
||||||
* (rendering them invisible) may appear. This is caused by DatabaseWidget
|
|
||||||
* StateSync. Corresponding checks/workarounds may be removed once sync
|
|
||||||
* code is updated accordingly
|
|
||||||
* -> relevant code pieces: if (header()->sectionSize(...) == 0) { ... }
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
EntryView::EntryView(QWidget* parent)
|
EntryView::EntryView(QWidget* parent)
|
||||||
: QTreeView(parent)
|
: QTreeView(parent)
|
||||||
, m_model(new EntryModel(this))
|
, m_model(new EntryModel(this))
|
||||||
@ -49,12 +33,7 @@ EntryView::EntryView(QWidget* parent)
|
|||||||
m_sortModel->setDynamicSortFilter(true);
|
m_sortModel->setDynamicSortFilter(true);
|
||||||
m_sortModel->setSortLocaleAware(true);
|
m_sortModel->setSortLocaleAware(true);
|
||||||
m_sortModel->setSortCaseSensitivity(Qt::CaseInsensitive);
|
m_sortModel->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||||
/**
|
// Use Qt::UserRole as sort role, see EntryModel::data()
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Set Qt::UserRole as sort role
|
|
||||||
* -> refer to 'if (role == Qt::UserRole)', EntryModel.cpp, EntryModel::
|
|
||||||
* data() for details
|
|
||||||
*/
|
|
||||||
m_sortModel->setSortRole(Qt::UserRole);
|
m_sortModel->setSortRole(Qt::UserRole);
|
||||||
QTreeView::setModel(m_sortModel);
|
QTreeView::setModel(m_sortModel);
|
||||||
|
|
||||||
@ -70,49 +49,31 @@ EntryView::EntryView(QWidget* parent)
|
|||||||
|
|
||||||
connect(this, SIGNAL(doubleClicked(QModelIndex)), SLOT(emitEntryActivated(QModelIndex)));
|
connect(this, SIGNAL(doubleClicked(QModelIndex)), SLOT(emitEntryActivated(QModelIndex)));
|
||||||
connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SIGNAL(entrySelectionChanged()));
|
connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SIGNAL(entrySelectionChanged()));
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Connect signals to get notified about list/search mode switches (NOTE:
|
|
||||||
* previously named 'switch[ed]ToGroupMode'/'switch[ed]ToEntryListMode')
|
|
||||||
*/
|
|
||||||
connect(m_model, SIGNAL(switchedToListMode()), SLOT(switchToListMode()));
|
connect(m_model, SIGNAL(switchedToListMode()), SLOT(switchToListMode()));
|
||||||
connect(m_model, SIGNAL(switchedToSearchMode()), SLOT(switchToSearchMode()));
|
connect(m_model, SIGNAL(switchedToSearchMode()), SLOT(switchToSearchMode()));
|
||||||
/**
|
connect(m_model, SIGNAL(usernamesHiddenChanged()), SIGNAL(viewStateChanged()));
|
||||||
* @author Fonic <https://github.com/fonic>
|
connect(m_model, SIGNAL(passwordsHiddenChanged()), SIGNAL(viewStateChanged()));
|
||||||
* Connect signals to notify about changes of view state when state of
|
|
||||||
* 'Hide Usernames'/'Hide Passwords' settings changes in model
|
|
||||||
*/
|
|
||||||
connect(m_model, SIGNAL(hideUsernamesChanged()), SIGNAL(viewStateChanged()));
|
|
||||||
connect(m_model, SIGNAL(hidePasswordsChanged()), SIGNAL(viewStateChanged()));
|
|
||||||
|
|
||||||
connect(this, SIGNAL(clicked(QModelIndex)), SLOT(emitEntryPressed(QModelIndex)));
|
connect(this, SIGNAL(clicked(QModelIndex)), SLOT(emitEntryPressed(QModelIndex)));
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Create header context menu:
|
|
||||||
* - Actions to toggle state of 'Hide Usernames'/'Hide Passwords' settings
|
|
||||||
* - Actions to toggle column visibility, with each action carrying 'its'
|
|
||||||
* column index as data
|
|
||||||
* - Actions to resize columns
|
|
||||||
* - Action to reset view to defaults
|
|
||||||
*/
|
|
||||||
m_headerMenu = new QMenu(this);
|
m_headerMenu = new QMenu(this);
|
||||||
m_headerMenu->setTitle(tr("Customize View"));
|
m_headerMenu->setTitle(tr("Customize View"));
|
||||||
m_headerMenu->addSection(tr("Customize View"));
|
m_headerMenu->addSection(tr("Customize View"));
|
||||||
|
|
||||||
m_hideUsernamesAction = m_headerMenu->addAction(tr("Hide Usernames"), m_model, SLOT(toggleHideUsernames(bool)));
|
m_hideUsernamesAction = m_headerMenu->addAction(tr("Hide Usernames"), m_model, SLOT(toggleUsernamesHidden(bool)));
|
||||||
m_hideUsernamesAction->setCheckable(true);
|
m_hideUsernamesAction->setCheckable(true);
|
||||||
m_hidePasswordsAction = m_headerMenu->addAction(tr("Hide Passwords"), m_model, SLOT(toggleHidePasswords(bool)));
|
m_hidePasswordsAction = m_headerMenu->addAction(tr("Hide Passwords"), m_model, SLOT(togglePasswordsHidden(bool)));
|
||||||
m_hidePasswordsAction->setCheckable(true);
|
m_hidePasswordsAction->setCheckable(true);
|
||||||
m_headerMenu->addSeparator();
|
m_headerMenu->addSeparator();
|
||||||
|
|
||||||
|
// Actions to toggle column visibility, each carrying the corresponding
|
||||||
|
// colummn index as data
|
||||||
m_columnActions = new QActionGroup(this);
|
m_columnActions = new QActionGroup(this);
|
||||||
m_columnActions->setExclusive(false);
|
m_columnActions->setExclusive(false);
|
||||||
for (int colidx = 1; colidx < header()->count(); colidx++) {
|
for (int columnIndex = 1; columnIndex < header()->count(); ++columnIndex) {
|
||||||
QString caption = m_model->headerData(colidx, Qt::Horizontal, Qt::DisplayRole).toString();
|
QString caption = m_model->headerData(columnIndex, Qt::Horizontal, Qt::DisplayRole).toString();
|
||||||
QAction* action = m_headerMenu->addAction(caption);
|
QAction* action = m_headerMenu->addAction(caption);
|
||||||
action->setCheckable(true);
|
action->setCheckable(true);
|
||||||
action->setData(colidx);
|
action->setData(columnIndex);
|
||||||
m_columnActions->addAction(action);
|
m_columnActions->addAction(action);
|
||||||
}
|
}
|
||||||
connect(m_columnActions, SIGNAL(triggered(QAction*)), this, SLOT(toggleColumnVisibility(QAction*)));
|
connect(m_columnActions, SIGNAL(triggered(QAction*)), this, SLOT(toggleColumnVisibility(QAction*)));
|
||||||
@ -123,17 +84,8 @@ EntryView::EntryView(QWidget* parent)
|
|||||||
m_headerMenu->addSeparator();
|
m_headerMenu->addSeparator();
|
||||||
m_headerMenu->addAction(tr("Reset to defaults"), this, SLOT(resetViewToDefaults()));
|
m_headerMenu->addAction(tr("Reset to defaults"), this, SLOT(resetViewToDefaults()));
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Configure header:
|
|
||||||
* - Set default section size
|
|
||||||
* - Disable stretching of last section (interferes with fitting columns
|
|
||||||
* to window)
|
|
||||||
* - Associate with context menu
|
|
||||||
* - Connect signals to notify about changes of view state when state
|
|
||||||
* of header changes
|
|
||||||
*/
|
|
||||||
header()->setDefaultSectionSize(100);
|
header()->setDefaultSectionSize(100);
|
||||||
|
// Stretching of last section interferes with fitting columns to window
|
||||||
header()->setStretchLastSection(false);
|
header()->setStretchLastSection(false);
|
||||||
header()->setContextMenuPolicy(Qt::CustomContextMenu);
|
header()->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
connect(header(), SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showHeaderMenu(QPoint)));
|
connect(header(), SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showHeaderMenu(QPoint)));
|
||||||
@ -142,35 +94,17 @@ EntryView::EntryView(QWidget* parent)
|
|||||||
connect(header(), SIGNAL(sectionResized(int, int, int)), this, SIGNAL(viewStateChanged()));
|
connect(header(), SIGNAL(sectionResized(int, int, int)), this, SIGNAL(viewStateChanged()));
|
||||||
connect(header(), SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), this, SIGNAL(viewStateChanged()));
|
connect(header(), SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), this, SIGNAL(viewStateChanged()));
|
||||||
|
|
||||||
/**
|
// TODO: not working as expected, columns will end up being very small,
|
||||||
* @author Fonic <https://github.com/fonic>
|
// most likely due to the widget not being sized properly at this time
|
||||||
* Fit columns to window
|
|
||||||
*
|
|
||||||
* TODO:
|
|
||||||
* Not working as expected, columns will end up being very small, most
|
|
||||||
* likely due to EntryView not being sized properly at this time. Find
|
|
||||||
* a way to make this work by analizing when/where EntryView is created
|
|
||||||
*/
|
|
||||||
//fitColumnsToWindow();
|
//fitColumnsToWindow();
|
||||||
|
|
||||||
/**
|
// Configure default search view state and save for later use
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Configure default search view state and save for later use
|
|
||||||
*/
|
|
||||||
header()->showSection(EntryModel::ParentGroup);
|
header()->showSection(EntryModel::ParentGroup);
|
||||||
m_sortModel->sort(EntryModel::ParentGroup, Qt::AscendingOrder);
|
m_sortModel->sort(EntryModel::ParentGroup, Qt::AscendingOrder);
|
||||||
sortByColumn(EntryModel::ParentGroup, Qt::AscendingOrder);
|
sortByColumn(EntryModel::ParentGroup, Qt::AscendingOrder);
|
||||||
m_defaultSearchViewState = header()->saveState();
|
m_defaultSearchViewState = header()->saveState();
|
||||||
|
|
||||||
/**
|
// Configure default list view state and save for later use
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Configure default list view state and save for later use
|
|
||||||
*
|
|
||||||
* NOTE:
|
|
||||||
* Default list view is intentionally configured last since this is the
|
|
||||||
* view that's supposed to be active after initialization as m_inSearchMode
|
|
||||||
* is initialized with 'false'
|
|
||||||
*/
|
|
||||||
header()->hideSection(EntryModel::ParentGroup);
|
header()->hideSection(EntryModel::ParentGroup);
|
||||||
m_sortModel->sort(EntryModel::Title, Qt::AscendingOrder);
|
m_sortModel->sort(EntryModel::Title, Qt::AscendingOrder);
|
||||||
sortByColumn(EntryModel::Title, Qt::AscendingOrder);
|
sortByColumn(EntryModel::Title, Qt::AscendingOrder);
|
||||||
@ -207,8 +141,7 @@ void EntryView::setFirstEntryActive()
|
|||||||
if (m_model->rowCount() > 0) {
|
if (m_model->rowCount() > 0) {
|
||||||
QModelIndex index = m_sortModel->mapToSource(m_sortModel->index(0, 0));
|
QModelIndex index = m_sortModel->mapToSource(m_sortModel->index(0, 0));
|
||||||
setCurrentEntry(m_model->entryFromIndex(index));
|
setCurrentEntry(m_model->entryFromIndex(index));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
emit entrySelectionChanged();
|
emit entrySelectionChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -241,8 +174,7 @@ Entry* EntryView::currentEntry()
|
|||||||
QModelIndexList list = selectionModel()->selectedRows();
|
QModelIndexList list = selectionModel()->selectedRows();
|
||||||
if (list.size() == 1) {
|
if (list.size() == 1) {
|
||||||
return m_model->entryFromIndex(m_sortModel->mapToSource(list.first()));
|
return m_model->entryFromIndex(m_sortModel->mapToSource(list.first()));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -262,58 +194,38 @@ Entry* EntryView::entryFromIndex(const QModelIndex& index)
|
|||||||
{
|
{
|
||||||
if (index.isValid()) {
|
if (index.isValid()) {
|
||||||
return m_model->entryFromIndex(m_sortModel->mapToSource(index));
|
return m_model->entryFromIndex(m_sortModel->mapToSource(index));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
* Switch to list mode, i.e. list entries of group
|
||||||
* Switch to list mode, i.e. list entries of group (NOTE: previously named
|
|
||||||
* 'switchToGroupMode')
|
|
||||||
*/
|
*/
|
||||||
void EntryView::switchToListMode()
|
void EntryView::switchToListMode()
|
||||||
{
|
{
|
||||||
/* Check if already in this mode */
|
|
||||||
if (!m_inSearchMode) {
|
if (!m_inSearchMode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Use header()->hideSection() instead of m_sortModel->hideColumn() as
|
|
||||||
* the latter messes up column indices, interfering with code relying on
|
|
||||||
* proper indices
|
|
||||||
*/
|
|
||||||
header()->hideSection(EntryModel::ParentGroup);
|
header()->hideSection(EntryModel::ParentGroup);
|
||||||
|
|
||||||
m_inSearchMode = false;
|
m_inSearchMode = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
* Switch to search mode, i.e. list search results
|
||||||
* Switch to search mode, i.e. list search results (NOTE: previously named
|
|
||||||
* 'switchToEntryListMode')
|
|
||||||
*/
|
*/
|
||||||
void EntryView::switchToSearchMode()
|
void EntryView::switchToSearchMode()
|
||||||
{
|
{
|
||||||
/* Check if already in this mode */
|
|
||||||
if (m_inSearchMode) {
|
if (m_inSearchMode) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Use header()->showSection() instead of m_sortModel->hideColumn() as
|
|
||||||
* the latter messes up column indices, interfering with code relying on
|
|
||||||
* proper indices
|
|
||||||
*/
|
|
||||||
header()->showSection(EntryModel::ParentGroup);
|
header()->showSection(EntryModel::ParentGroup);
|
||||||
|
|
||||||
/*
|
// Always set sorting to column 'Group', as it does not feel right to
|
||||||
* Always set sorting to column 'Group', as it does not feel right to have
|
// have the last known sort configuration of search view restored by
|
||||||
* the last known sort configuration of search view restored by 'Database
|
// 'DatabaseWidgetStateSync', which is what happens without this
|
||||||
* WidgetStateSync', which is what happens without this
|
|
||||||
*/
|
|
||||||
m_sortModel->sort(EntryModel::ParentGroup, Qt::AscendingOrder);
|
m_sortModel->sort(EntryModel::ParentGroup, Qt::AscendingOrder);
|
||||||
sortByColumn(EntryModel::ParentGroup, Qt::AscendingOrder);
|
sortByColumn(EntryModel::ParentGroup, Qt::AscendingOrder);
|
||||||
|
|
||||||
@ -321,46 +233,41 @@ void EntryView::switchToSearchMode()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Get current state of 'Hide Usernames' setting (NOTE: just pass-through for
|
* Get current state of 'Hide Usernames' setting (NOTE: just pass-through for
|
||||||
* m_model)
|
* m_model)
|
||||||
*/
|
*/
|
||||||
bool EntryView::hideUsernames() const
|
bool EntryView::isUsernamesHidden() const
|
||||||
{
|
{
|
||||||
return m_model->hideUsernames();
|
return m_model->isUsernamesHidden();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Set state of 'Hide Usernames' setting (NOTE: just pass-through for m_model)
|
* Set state of 'Hide Usernames' setting (NOTE: just pass-through for m_model)
|
||||||
*/
|
*/
|
||||||
void EntryView::setHideUsernames(const bool hide)
|
void EntryView::setUsernamesHidden(const bool hide)
|
||||||
{
|
{
|
||||||
m_model->setHideUsernames(hide);
|
m_model->setUsernamesHidden(hide);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Get current state of 'Hide Passwords' setting (NOTE: just pass-through for
|
* Get current state of 'Hide Passwords' setting (NOTE: just pass-through for
|
||||||
* m_model)
|
* m_model)
|
||||||
*/
|
*/
|
||||||
bool EntryView::hidePasswords() const
|
bool EntryView::isPasswordsHidden() const
|
||||||
{
|
{
|
||||||
return m_model->hidePasswords();
|
return m_model->isPasswordsHidden();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Set state of 'Hide Passwords' setting (NOTE: just pass-through for m_model)
|
* Set state of 'Hide Passwords' setting (NOTE: just pass-through for m_model)
|
||||||
*/
|
*/
|
||||||
void EntryView::setHidePasswords(const bool hide)
|
void EntryView::setPasswordsHidden(const bool hide)
|
||||||
{
|
{
|
||||||
m_model->setHidePasswords(hide);
|
m_model->setPasswordsHidden(hide);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
* Get current view state
|
||||||
* Get current state of view
|
|
||||||
*/
|
*/
|
||||||
QByteArray EntryView::viewState() const
|
QByteArray EntryView::viewState() const
|
||||||
{
|
{
|
||||||
@ -368,8 +275,7 @@ QByteArray EntryView::viewState() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
* Set view state
|
||||||
* Set state of entry view view
|
|
||||||
*/
|
*/
|
||||||
bool EntryView::setViewState(const QByteArray& state) const
|
bool EntryView::setViewState(const QByteArray& state) const
|
||||||
{
|
{
|
||||||
@ -377,70 +283,59 @@ bool EntryView::setViewState(const QByteArray& state) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Sync checkable menu actions to current state and display header context
|
* Sync checkable menu actions to current state and display header context
|
||||||
* menu at specified position
|
* menu at specified position
|
||||||
*/
|
*/
|
||||||
void EntryView::showHeaderMenu(const QPoint& position)
|
void EntryView::showHeaderMenu(const QPoint& position)
|
||||||
{
|
{
|
||||||
/* Sync checked state of menu actions to current state of view */
|
m_hideUsernamesAction->setChecked(m_model->isUsernamesHidden());
|
||||||
m_hideUsernamesAction->setChecked(m_model->hideUsernames());
|
m_hidePasswordsAction->setChecked(m_model->isPasswordsHidden());
|
||||||
m_hidePasswordsAction->setChecked(m_model->hidePasswords());
|
const QList<QAction*> actions = m_columnActions->actions();
|
||||||
foreach (QAction *action, m_columnActions->actions()) {
|
for (auto& action : actions) {
|
||||||
|
Q_ASSERT(static_cast<QMetaType::Type>(action->data().type()) == QMetaType::Int);
|
||||||
if (static_cast<QMetaType::Type>(action->data().type()) != QMetaType::Int) {
|
if (static_cast<QMetaType::Type>(action->data().type()) != QMetaType::Int) {
|
||||||
Q_ASSERT(false);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int colidx = action->data().toInt();
|
int columnIndex = action->data().toInt();
|
||||||
bool hidden = header()->isSectionHidden(colidx) || (header()->sectionSize(colidx) == 0);
|
bool hidden = header()->isSectionHidden(columnIndex) || (header()->sectionSize(columnIndex) == 0);
|
||||||
action->setChecked(!hidden);
|
action->setChecked(!hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Display menu */
|
|
||||||
m_headerMenu->popup(mapToGlobal(position));
|
m_headerMenu->popup(mapToGlobal(position));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Toggle visibility of column referenced by triggering action
|
* Toggle visibility of column referenced by triggering action
|
||||||
*/
|
*/
|
||||||
void EntryView::toggleColumnVisibility(QAction *action)
|
void EntryView::toggleColumnVisibility(QAction *action)
|
||||||
{
|
{
|
||||||
/*
|
// Verify action carries a column index as data. Since QVariant.toInt()
|
||||||
* Verify action carries a column index as data. Since QVariant.toInt()
|
// below will accept anything that's interpretable as int, perform a type
|
||||||
* below will accept anything that's interpretable as int, perform a type
|
// check here to make sure data actually IS int
|
||||||
* check here to make sure data actually IS int
|
Q_ASSERT(static_cast<QMetaType::Type>(action->data().type()) == QMetaType::Int);
|
||||||
*/
|
|
||||||
if (static_cast<QMetaType::Type>(action->data().type()) != QMetaType::Int) {
|
if (static_cast<QMetaType::Type>(action->data().type()) != QMetaType::Int) {
|
||||||
Q_ASSERT(false);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Toggle column visibility. Visible columns will only be hidden if at
|
||||||
* Toggle column visibility. Visible columns will only be hidden if at
|
// least one visible column remains, as the table header will disappear
|
||||||
* least one visible column remains, as the table header will disappear
|
// entirely when all columns are hidden
|
||||||
* entirely when all columns are hidden, rendering the context menu in-
|
int columnIndex = action->data().toInt();
|
||||||
* accessible
|
|
||||||
*/
|
|
||||||
int colidx = action->data().toInt();
|
|
||||||
if (action->isChecked()) {
|
if (action->isChecked()) {
|
||||||
header()->showSection(colidx);
|
header()->showSection(columnIndex);
|
||||||
if (header()->sectionSize(colidx) == 0) {
|
if (header()->sectionSize(columnIndex) == 0) {
|
||||||
header()->resizeSection(colidx, header()->defaultSectionSize());
|
header()->resizeSection(columnIndex, header()->defaultSectionSize());
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else {
|
if ((header()->count() - header()->hiddenSectionCount()) > 1) {
|
||||||
if ((header()->count() - header()->hiddenSectionCount()) > 1) {
|
header()->hideSection(columnIndex);
|
||||||
header()->hideSection(colidx);
|
return;
|
||||||
}
|
|
||||||
else {
|
|
||||||
action->setChecked(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
action->setChecked(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Resize columns to fit all visible columns within the available space
|
* Resize columns to fit all visible columns within the available space
|
||||||
*
|
*
|
||||||
* NOTE:
|
* NOTE:
|
||||||
@ -461,69 +356,60 @@ void EntryView::fitColumnsToWindow()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Resize columns to fit current table contents, i.e. make all contents
|
* Resize columns to fit current table contents, i.e. make all contents
|
||||||
* entirely visible
|
* entirely visible
|
||||||
*/
|
*/
|
||||||
void EntryView::fitColumnsToContents()
|
void EntryView::fitColumnsToContents()
|
||||||
{
|
{
|
||||||
/* Resize columns to fit contents */
|
// Resize columns to fit contents
|
||||||
header()->resizeSections(QHeaderView::ResizeToContents);
|
header()->resizeSections(QHeaderView::ResizeToContents);
|
||||||
|
|
||||||
/*
|
// Determine total width of currently visible columns. If there is
|
||||||
* Determine total width of currently visible columns. If there is
|
// still some space available on the header, equally distribute it to
|
||||||
* still some space available on the header, equally distribute it to
|
// visible columns and add remaining fraction to last visible column
|
||||||
* visible columns and add remaining fraction to last visible column
|
|
||||||
*/
|
|
||||||
int width = 0;
|
int width = 0;
|
||||||
for (int colidx = 0; colidx < header()->count(); colidx++) {
|
for (int columnIndex = 0; columnIndex < header()->count(); ++columnIndex) {
|
||||||
if (!header()->isSectionHidden(colidx)) {
|
if (!header()->isSectionHidden(columnIndex)) {
|
||||||
width += header()->sectionSize(colidx);
|
width += header()->sectionSize(columnIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int visible = header()->count() - header()->hiddenSectionCount();
|
int visible = header()->count() - header()->hiddenSectionCount();
|
||||||
int avail = header()->width() - width;
|
int avail = header()->width() - width;
|
||||||
if ((visible > 0) && (avail > 0)) {
|
if ((visible <= 0) || (avail <= 0)) {
|
||||||
int add = avail / visible;
|
return;
|
||||||
width = 0;
|
}
|
||||||
int last = 0;
|
int add = avail / visible;
|
||||||
for (int colidx = 0; colidx < header()->count(); colidx++) {
|
width = 0;
|
||||||
if (!header()->isSectionHidden(colidx)) {
|
int last = 0;
|
||||||
header()->resizeSection(colidx, header()->sectionSize(colidx) + add);
|
for (int columnIndex = 0; columnIndex < header()->count(); ++columnIndex) {
|
||||||
width += header()->sectionSize(colidx);
|
if (!header()->isSectionHidden(columnIndex)) {
|
||||||
if (header()->visualIndex(colidx) > last) {
|
header()->resizeSection(columnIndex, header()->sectionSize(columnIndex) + add);
|
||||||
last = header()->visualIndex(colidx);
|
width += header()->sectionSize(columnIndex);
|
||||||
}
|
if (header()->visualIndex(columnIndex) > last) {
|
||||||
|
last = header()->visualIndex(columnIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
header()->resizeSection(header()->logicalIndex(last), header()->sectionSize(last) + (header()->width() - width));
|
|
||||||
}
|
}
|
||||||
|
header()->resizeSection(header()->logicalIndex(last), header()->sectionSize(last) + (header()->width() - width));
|
||||||
|
|
||||||
/*
|
// Shouldn't be necessary due to use of header()->resizeSection, but
|
||||||
* This should not be necessary due to use of header()->resizeSection,
|
// lets just do it anyway for the sake of completeness
|
||||||
* but lets do it anyway for the sake of completeness
|
|
||||||
*/
|
|
||||||
emit viewStateChanged();
|
emit viewStateChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Reset view to defaults
|
* Reset view to defaults
|
||||||
*/
|
*/
|
||||||
void EntryView::resetViewToDefaults()
|
void EntryView::resetViewToDefaults()
|
||||||
{
|
{
|
||||||
/* Reset state of 'Hide Usernames'/'Hide Passwords' settings */
|
m_model->setUsernamesHidden(false);
|
||||||
m_model->setHideUsernames(false);
|
m_model->setPasswordsHidden(true);
|
||||||
m_model->setHidePasswords(true);
|
|
||||||
|
|
||||||
/* Reset columns (size, order, sorting etc.) */
|
|
||||||
if (m_inSearchMode) {
|
if (m_inSearchMode) {
|
||||||
header()->restoreState(m_defaultSearchViewState);
|
header()->restoreState(m_defaultSearchViewState);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
header()->restoreState(m_defaultListViewState);
|
header()->restoreState(m_defaultListViewState);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Nicely fitting columns to window feels like a sane default */
|
|
||||||
fitColumnsToWindow();
|
fitColumnsToWindow();
|
||||||
}
|
}
|
||||||
|
@ -26,10 +26,6 @@ class Entry;
|
|||||||
class EntryModel;
|
class EntryModel;
|
||||||
class Group;
|
class Group;
|
||||||
class SortFilterHideProxyModel;
|
class SortFilterHideProxyModel;
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Add forward declaration for QActionGroup
|
|
||||||
*/
|
|
||||||
class QActionGroup;
|
class QActionGroup;
|
||||||
|
|
||||||
class EntryView : public QTreeView
|
class EntryView : public QTreeView
|
||||||
@ -46,21 +42,10 @@ public:
|
|||||||
bool inSearchMode();
|
bool inSearchMode();
|
||||||
int numberOfSelectedEntries();
|
int numberOfSelectedEntries();
|
||||||
void setFirstEntryActive();
|
void setFirstEntryActive();
|
||||||
|
bool isUsernamesHidden() const;
|
||||||
/**
|
void setUsernamesHidden(const bool hide);
|
||||||
* @author Fonic <https://github.com/fonic>
|
bool isPasswordsHidden() const;
|
||||||
* Methods to get/set state of 'Hide Usernames'/'Hide Passwords' settings
|
void setPasswordsHidden(const bool hide);
|
||||||
* (NOTE: these are just pass-through methods to avoid exposing entry model)
|
|
||||||
*/
|
|
||||||
bool hideUsernames() const;
|
|
||||||
void setHideUsernames(const bool hide);
|
|
||||||
bool hidePasswords() const;
|
|
||||||
void setHidePasswords(const bool hide);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Methods to get/set state of view
|
|
||||||
*/
|
|
||||||
QByteArray viewState() const;
|
QByteArray viewState() const;
|
||||||
bool setViewState(const QByteArray& state) const;
|
bool setViewState(const QByteArray& state) const;
|
||||||
|
|
||||||
@ -71,10 +56,6 @@ signals:
|
|||||||
void entryActivated(Entry* entry, EntryModel::ModelColumn column);
|
void entryActivated(Entry* entry, EntryModel::ModelColumn column);
|
||||||
void entryPressed(Entry* entry);
|
void entryPressed(Entry* entry);
|
||||||
void entrySelectionChanged();
|
void entrySelectionChanged();
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Signal to notify about changes of view state
|
|
||||||
*/
|
|
||||||
void viewStateChanged();
|
void viewStateChanged();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -83,18 +64,8 @@ protected:
|
|||||||
private slots:
|
private slots:
|
||||||
void emitEntryActivated(const QModelIndex& index);
|
void emitEntryActivated(const QModelIndex& index);
|
||||||
void emitEntryPressed(const QModelIndex& index);
|
void emitEntryPressed(const QModelIndex& index);
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Methods to switch to list/search mode (NOTE: previously named 'switch
|
|
||||||
* ToGroupMode'/'switchToEntryListMode')
|
|
||||||
*/
|
|
||||||
void switchToListMode();
|
void switchToListMode();
|
||||||
void switchToSearchMode();
|
void switchToSearchMode();
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Slots for header context menu and actions
|
|
||||||
*/
|
|
||||||
void showHeaderMenu(const QPoint& position);
|
void showHeaderMenu(const QPoint& position);
|
||||||
void toggleColumnVisibility(QAction *action);
|
void toggleColumnVisibility(QAction *action);
|
||||||
void fitColumnsToWindow();
|
void fitColumnsToWindow();
|
||||||
@ -106,16 +77,9 @@ private:
|
|||||||
SortFilterHideProxyModel* const m_sortModel;
|
SortFilterHideProxyModel* const m_sortModel;
|
||||||
bool m_inSearchMode;
|
bool m_inSearchMode;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Properties to store default view states used by resetViewToDefaults()
|
|
||||||
*/
|
|
||||||
QByteArray m_defaultListViewState;
|
QByteArray m_defaultListViewState;
|
||||||
QByteArray m_defaultSearchViewState;
|
QByteArray m_defaultSearchViewState;
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Properties to store header context menu and actions
|
|
||||||
*/
|
|
||||||
QMenu* m_headerMenu;
|
QMenu* m_headerMenu;
|
||||||
QAction* m_hideUsernamesAction;
|
QAction* m_hideUsernamesAction;
|
||||||
QAction* m_hidePasswordsAction;
|
QAction* m_hidePasswordsAction;
|
||||||
|
@ -686,21 +686,6 @@ void TestGui::testSearch()
|
|||||||
QTRY_COMPARE(m_dbWidget->currentMode(), DatabaseWidget::ViewMode);
|
QTRY_COMPARE(m_dbWidget->currentMode(), DatabaseWidget::ViewMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fonic <https://github.com/fonic>
|
|
||||||
* Update clicks within entry view referencing column indices to account
|
|
||||||
* for changed column indices due to new way of showing/hiding column Entry
|
|
||||||
* Model::ParentGroup. This column now has fixed index 0 wether it's shown
|
|
||||||
* or hidden, thus all indices need to be shifted by +1 when not in search
|
|
||||||
* mode (which is the case within this entire method)
|
|
||||||
*
|
|
||||||
* Old:
|
|
||||||
* clickIndex(entryView->model()->index(row, column), button);
|
|
||||||
*
|
|
||||||
* New:
|
|
||||||
* clickIndex(entryView->model()->index(row, column+1), button);
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void TestGui::testDeleteEntry()
|
void TestGui::testDeleteEntry()
|
||||||
{
|
{
|
||||||
// Add canned entries for consistent testing
|
// Add canned entries for consistent testing
|
||||||
|
Loading…
Reference in New Issue
Block a user