Refactor Database and Database widgets (#2491)

The Database, DatabaseWidget, and DatabaseTabWidget classes share many responsibilities in inconsistent ways resulting in impenetrable and unmaintainable code and a diverse set of bugs and architecture restrictions. This patch reworks the architecture, responsibilities of, and dependencies between these classes.

The core changes are:

* Move loading and saving logic from widgets into the Database class
* Get rid of the DatabaseManagerStruct and move all the information contained in it into the Database
* Let database objects keep track of modifications and dirty/clean state instead of handing this to external widgets
* Move GUI interactions for loading and saving from the DatabaseTabWidget into the DatabaseWidget (resolves #2494 as a side-effect)
* Heavily clean up DatabaseTabWidget and degrade it to a slightly glorified QTabWidget
* Use QSharedPointers for all Database objects
* Remove the modifiedImmediate signal and replace it with a markAsModified() method
* Implement proper tabName() method instead of reading back titles from GUI widgets (resolves #1389 and its duplicates #2146 #855)
* Fix unwanted AES-KDF downgrade if database uses Argon2 and has CustomData
* Improve code

This patch is also the first major step towards solving issues #476 and #2322.
This commit is contained in:
Janek Bevendorff 2018-11-22 11:47:31 +01:00 committed by GitHub
parent 917c4cc18b
commit d612cad09a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
115 changed files with 2116 additions and 2165 deletions

View file

@ -61,7 +61,7 @@ void UrlFetchProgressDialog::networkReplyProgress(qint64 bytesRead, qint64 total
EditWidgetIcons::EditWidgetIcons(QWidget* parent)
: QWidget(parent)
, m_ui(new Ui::EditWidgetIcons())
, m_database(nullptr)
, m_db(nullptr)
#ifdef WITH_XC_NETWORKING
, m_reply(nullptr)
#endif
@ -102,7 +102,7 @@ EditWidgetIcons::~EditWidgetIcons()
IconStruct EditWidgetIcons::state()
{
Q_ASSERT(m_database);
Q_ASSERT(m_db);
Q_ASSERT(!m_currentUuid.isNull());
IconStruct iconStruct;
@ -127,16 +127,19 @@ IconStruct EditWidgetIcons::state()
void EditWidgetIcons::reset()
{
m_database = nullptr;
m_db.reset();
m_currentUuid = QUuid();
}
void EditWidgetIcons::load(const QUuid& currentUuid, Database* database, const IconStruct& iconStruct, const QString& url)
void EditWidgetIcons::load(const QUuid& currentUuid,
QSharedPointer<Database> database,
const IconStruct& iconStruct,
const QString& url)
{
Q_ASSERT(database);
Q_ASSERT(!currentUuid.isNull());
m_database = database;
m_db = database;
m_currentUuid = currentUuid;
setUrl(url);
@ -329,7 +332,7 @@ void EditWidgetIcons::startFetchFavicon(const QUrl& url)
void EditWidgetIcons::addCustomIconFromFile()
{
if (m_database) {
if (m_db) {
QString filter = QString("%1 (%2);;%3 (*)").arg(tr("Images"), Tools::imageReaderFilter(), tr("All files"));
auto filenames = QFileDialog::getOpenFileNames(this, tr("Select Image(s)"), "", filter);
@ -378,19 +381,19 @@ void EditWidgetIcons::addCustomIconFromFile()
bool EditWidgetIcons::addCustomIcon(const QImage& icon)
{
bool added = false;
if (m_database) {
if (m_db) {
// Don't add an icon larger than 128x128, but retain original size if smaller
auto scaledicon = icon;
if (icon.width() > 128 || icon.height() > 128) {
scaledicon = icon.scaled(128, 128);
}
QUuid uuid = m_database->metadata()->findCustomIcon(scaledicon);
QUuid uuid = m_db->metadata()->findCustomIcon(scaledicon);
if (uuid.isNull()) {
uuid = QUuid::createUuid();
m_database->metadata()->addCustomIcon(uuid, scaledicon);
m_customIconModel->setIcons(m_database->metadata()->customIconsScaledPixmaps(),
m_database->metadata()->customIconsOrder());
m_db->metadata()->addCustomIcon(uuid, scaledicon);
m_customIconModel->setIcons(m_db->metadata()->customIconsScaledPixmaps(),
m_db->metadata()->customIconsOrder());
added = true;
}
@ -407,12 +410,12 @@ bool EditWidgetIcons::addCustomIcon(const QImage& icon)
void EditWidgetIcons::removeCustomIcon()
{
if (m_database) {
if (m_db) {
QModelIndex index = m_ui->customIconsView->currentIndex();
if (index.isValid()) {
QUuid iconUuid = m_customIconModel->uuidFromIndex(index);
const QList<Entry*> allEntries = m_database->rootGroup()->entriesRecursive(true);
const QList<Entry*> allEntries = m_db->rootGroup()->entriesRecursive(true);
QList<Entry*> entriesWithSameIcon;
QList<Entry*> historyEntriesWithSameIcon;
@ -427,7 +430,7 @@ void EditWidgetIcons::removeCustomIcon()
}
}
const QList<Group*> allGroups = m_database->rootGroup()->groupsRecursive(true);
const QList<Group*> allGroups = m_db->rootGroup()->groupsRecursive(true);
QList<Group*> groupsWithSameIcon;
for (Group* group : allGroups) {
@ -471,14 +474,14 @@ void EditWidgetIcons::removeCustomIcon()
}
// Remove the icon from the database
m_database->metadata()->removeCustomIcon(iconUuid);
m_customIconModel->setIcons(m_database->metadata()->customIconsScaledPixmaps(),
m_database->metadata()->customIconsOrder());
m_db->metadata()->removeCustomIcon(iconUuid);
m_customIconModel->setIcons(m_db->metadata()->customIconsScaledPixmaps(),
m_db->metadata()->customIconsOrder());
// Reset the current icon view
updateRadioButtonDefaultIcons();
if (m_database->resolveEntry(m_currentUuid) != nullptr) {
if (m_db->rootGroup()->findEntryByUuid(m_currentUuid) != nullptr) {
m_ui->defaultIconsView->setCurrentIndex(m_defaultIconModel->index(Entry::DefaultIconNumber));
} else {
m_ui->defaultIconsView->setCurrentIndex(m_defaultIconModel->index(Group::DefaultIconNumber));