From 6d569a86f9f7d86bc8672a7f9364cc4c525c26c0 Mon Sep 17 00:00:00 2001 From: Bernhard Rieder Date: Mon, 9 Oct 2017 13:26:24 +0200 Subject: [PATCH 01/79] added autoopen functionality (#477) --- src/gui/DatabaseTabWidget.cpp | 41 ++++++++++++++++++++++++++++++++++- src/gui/DatabaseWidget.cpp | 15 ++++++++++--- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/gui/DatabaseTabWidget.cpp b/src/gui/DatabaseTabWidget.cpp index df0e1a1da..b443aba10 100644 --- a/src/gui/DatabaseTabWidget.cpp +++ b/src/gui/DatabaseTabWidget.cpp @@ -129,7 +129,13 @@ void DatabaseTabWidget::openDatabase(const QString& fileName, const QString& pw, while (i.hasNext()) { i.next(); if (i.value().canonicalFilePath == canonicalFilePath) { - setCurrentIndex(databaseIndex(i.key())); + if (pw.isEmpty() && keyFile.isEmpty()) { + setCurrentIndex(databaseIndex(i.key())); + } else { + if (!i.key()->hasKey()) { + i.value().dbWidget->switchToOpenDatabase(canonicalFilePath, pw, keyFile); + } + } return; } } @@ -607,6 +613,39 @@ void DatabaseTabWidget::updateTabNameFromDbWidgetSender() DatabaseWidget* dbWidget = static_cast(sender()); updateTabName(databaseFromDatabaseWidget(dbWidget)); + + Database* db = dbWidget->database(); + Group *autoload = db->rootGroup()->findChildByName("AutoOpen"); + if (autoload) + { + const DatabaseManagerStruct& dbStruct = m_dbList.value(db); + QFileInfo dbpath(dbStruct.canonicalFilePath); + QDir dbFolder(dbpath.canonicalPath()); + + for (auto entry : autoload->entries()) { + + if (entry->url().isEmpty() || entry->password().isEmpty()) + continue; + + QFileInfo filepath; + if (entry->url().startsWith("file:/")) { + QUrl url(entry->url()); + filepath.setFile(url.toLocalFile()); + } + else { + filepath.setFile(entry->url()); + if (filepath.isRelative()) { + filepath.setFile(dbFolder, entry->url()); + } + } + + if (!filepath.isFile()) + continue; + + openDatabase(filepath.canonicalFilePath(), entry->password(), ""); + + } + } } int DatabaseTabWidget::databaseIndex(Database* db) diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index 3a39bddcf..e5693e4f9 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -897,8 +897,13 @@ void DatabaseWidget::switchToDatabaseSettings() void DatabaseWidget::switchToOpenDatabase(const QString& fileName) { updateFilename(fileName); - m_databaseOpenWidget->load(fileName); - setCurrentWidget(m_databaseOpenWidget); + if (m_databaseOpenWidget) { + m_databaseOpenWidget->load(fileName); + setCurrentWidget(m_databaseOpenWidget); + } else if (m_unlockDatabaseWidget) { + m_unlockDatabaseWidget->load(fileName); + setCurrentWidget(m_unlockDatabaseWidget); + } } void DatabaseWidget::switchToOpenDatabase(const QString& fileName, const QString& password, @@ -906,7 +911,11 @@ void DatabaseWidget::switchToOpenDatabase(const QString& fileName, const QString { updateFilename(fileName); switchToOpenDatabase(fileName); - m_databaseOpenWidget->enterKey(password, keyFile); + if (m_databaseOpenWidget) { + m_databaseOpenWidget->enterKey(password, keyFile); + } else if (m_unlockDatabaseWidget) { + m_unlockDatabaseWidget->enterKey(password, keyFile); + } } void DatabaseWidget::switchToImportCsv(const QString& fileName) From 0fc8c37f23d0fa1ee64f718c92afc20c9ff037c9 Mon Sep 17 00:00:00 2001 From: Bernhard Rieder Date: Thu, 12 Oct 2017 23:30:51 +0200 Subject: [PATCH 02/79] changed file:/ to file:// --- src/gui/DatabaseTabWidget.cpp | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/gui/DatabaseTabWidget.cpp b/src/gui/DatabaseTabWidget.cpp index b443aba10..67edd130a 100644 --- a/src/gui/DatabaseTabWidget.cpp +++ b/src/gui/DatabaseTabWidget.cpp @@ -90,12 +90,12 @@ void DatabaseTabWidget::newDatabase() Database* db = new Database(); db->rootGroup()->setName(tr("Root")); dbStruct.dbWidget = new DatabaseWidget(db, this); - + CompositeKey emptyKey; db->setKey(emptyKey); insertDatabase(db, dbStruct); - + if (!saveDatabaseAs(db)) { closeDatabase(db); return; @@ -616,19 +616,16 @@ void DatabaseTabWidget::updateTabNameFromDbWidgetSender() Database* db = dbWidget->database(); Group *autoload = db->rootGroup()->findChildByName("AutoOpen"); - if (autoload) - { + if (autoload) { const DatabaseManagerStruct& dbStruct = m_dbList.value(db); QFileInfo dbpath(dbStruct.canonicalFilePath); QDir dbFolder(dbpath.canonicalPath()); - for (auto entry : autoload->entries()) { - - if (entry->url().isEmpty() || entry->password().isEmpty()) + if (entry->url().isEmpty() || entry->password().isEmpty()) { continue; - + } QFileInfo filepath; - if (entry->url().startsWith("file:/")) { + if (entry->url().startsWith("file://")) { QUrl url(entry->url()); filepath.setFile(url.toLocalFile()); } @@ -639,11 +636,11 @@ void DatabaseTabWidget::updateTabNameFromDbWidgetSender() } } - if (!filepath.isFile()) + if (!filepath.isFile()) { continue; + } openDatabase(filepath.canonicalFilePath(), entry->password(), ""); - } } } From 4e7f2c6a4fe920ec4301b110258f894fc9ea87bf Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Sat, 28 Oct 2017 09:23:45 -0400 Subject: [PATCH 03/79] Fix apply button not saving new entries --- src/gui/entry/EditEntryWidget.cpp | 4 ++- src/gui/entry/EditEntryWidget.h | 1 + tests/gui/TestGui.cpp | 58 ++++++++++++++++++++++++++++--- tests/gui/TestGui.h | 1 + 4 files changed, 58 insertions(+), 6 deletions(-) diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index 809ac95eb..5a058bda4 100644 --- a/src/gui/entry/EditEntryWidget.cpp +++ b/src/gui/entry/EditEntryWidget.cpp @@ -278,6 +278,7 @@ void EditEntryWidget::loadEntry(Entry* entry, bool create, bool history, const Q m_database = database; m_create = create; m_history = history; + m_saved = false; if (history) { setHeadline(QString("%1 > %2").arg(parentName, tr("Entry history"))); @@ -438,6 +439,7 @@ void EditEntryWidget::saveEntry() } updateEntryData(m_entry); + m_saved = true; if (!m_create) { m_entry->endUpdate(); @@ -510,7 +512,7 @@ void EditEntryWidget::cancel() clear(); - emit editFinished(false); + emit editFinished(m_saved); } void EditEntryWidget::clear() diff --git a/src/gui/entry/EditEntryWidget.h b/src/gui/entry/EditEntryWidget.h index 2888d43a8..628f8f8ed 100644 --- a/src/gui/entry/EditEntryWidget.h +++ b/src/gui/entry/EditEntryWidget.h @@ -121,6 +121,7 @@ private: bool m_create; bool m_history; + bool m_saved; const QScopedPointer m_mainUi; const QScopedPointer m_advancedUi; const QScopedPointer m_autoTypeUi; diff --git a/tests/gui/TestGui.cpp b/tests/gui/TestGui.cpp index 75ce3cc59..6805e1053 100644 --- a/tests/gui/TestGui.cpp +++ b/tests/gui/TestGui.cpp @@ -332,15 +332,27 @@ void TestGui::testAddEntry() QTest::keyClicks(passwordRepeatEdit, "something 2"); QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton); - // Add entry "something 3" + // Add entry "something 3" using the apply button then click ok QTest::mouseClick(entryNewWidget, Qt::LeftButton); QTest::keyClicks(titleEdit, "something 3"); + QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Apply), Qt::LeftButton); QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton); + // Add entry "something 4" using the apply button then click cancel + QTest::mouseClick(entryNewWidget, Qt::LeftButton); + QTest::keyClicks(titleEdit, "something 4"); + QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Apply), Qt::LeftButton); + QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Cancel), Qt::LeftButton); + + // Add entry "something 5" but click cancel button (does NOT add entry) + QTest::mouseClick(entryNewWidget, Qt::LeftButton); + QTest::keyClicks(titleEdit, "something 5"); + QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Cancel), Qt::LeftButton); + QApplication::processEvents(); - // Confirm that 4 entries now exist - QTRY_COMPARE(entryView->model()->rowCount(), 4); + // Confirm that 5 entries now exist + QTRY_COMPARE(entryView->model()->rowCount(), 5); } void TestGui::testPasswordEntryEntropy() @@ -513,7 +525,7 @@ void TestGui::testTotp() void TestGui::testSearch() { // Add canned entries for consistent testing - testAddEntry(); + Q_UNUSED(addCannedEntries()); QToolBar* toolBar = m_mainWindow->findChild("toolBar"); @@ -629,7 +641,7 @@ void TestGui::testSearch() void TestGui::testDeleteEntry() { // Add canned entries for consistent testing - testAddEntry(); + Q_UNUSED(addCannedEntries()); GroupView* groupView = m_dbWidget->findChild("groupView"); EntryView* entryView = m_dbWidget->findChild("entryView"); @@ -905,6 +917,42 @@ void TestGui::cleanupTestCase() delete m_mainWindow; } +int TestGui::addCannedEntries() +{ + int entries_added = 0; + + // Find buttons + QToolBar* toolBar = m_mainWindow->findChild("toolBar"); + QWidget* entryNewWidget = toolBar->widgetForAction(m_mainWindow->findChild("actionEntryNew")); + EditEntryWidget* editEntryWidget = m_dbWidget->findChild("editEntryWidget"); + QLineEdit* titleEdit = editEntryWidget->findChild("titleEdit"); + QLineEdit* passwordEdit = editEntryWidget->findChild("passwordEdit"); + QLineEdit* passwordRepeatEdit = editEntryWidget->findChild("passwordRepeatEdit"); + + // Add entry "test" and confirm added + QTest::mouseClick(entryNewWidget, Qt::LeftButton); + QTest::keyClicks(titleEdit, "test"); + QDialogButtonBox* editEntryWidgetButtonBox = editEntryWidget->findChild("buttonBox"); + QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton); + ++entries_added; + + // Add entry "something 2" + QTest::mouseClick(entryNewWidget, Qt::LeftButton); + QTest::keyClicks(titleEdit, "something 2"); + QTest::keyClicks(passwordEdit, "something 2"); + QTest::keyClicks(passwordRepeatEdit, "something 2"); + QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton); + ++entries_added; + + // Add entry "something 3" + QTest::mouseClick(entryNewWidget, Qt::LeftButton); + QTest::keyClicks(titleEdit, "something 3"); + QTest::mouseClick(editEntryWidgetButtonBox->button(QDialogButtonBox::Ok), Qt::LeftButton); + ++entries_added; + + return entries_added; +} + void TestGui::checkDatabase(QString dbFileName) { if (dbFileName.isEmpty()) diff --git a/tests/gui/TestGui.h b/tests/gui/TestGui.h index 904e5f21e..352dbf213 100644 --- a/tests/gui/TestGui.h +++ b/tests/gui/TestGui.h @@ -61,6 +61,7 @@ private slots: void testDatabaseLocking(); private: + int addCannedEntries(); void checkDatabase(QString dbFileName = ""); void triggerAction(const QString& name); void dragAndDropGroup(const QModelIndex& sourceIndex, const QModelIndex& targetIndex, int row, From ffe344ce901b37c0b118398be1a1db0862f3357d Mon Sep 17 00:00:00 2001 From: frostasm Date: Sun, 29 Oct 2017 11:18:48 +0200 Subject: [PATCH 04/79] Save the geometry of main window only if the window is visible --- src/gui/MainWindow.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index c82ea1751..ccc5fb11f 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -727,7 +727,9 @@ void MainWindow::changeEvent(QEvent* event) void MainWindow::saveWindowInformation() { - config()->set("GUI/MainWindowGeometry", saveGeometry()); + if (isVisible()) { + config()->set("GUI/MainWindowGeometry", saveGeometry()); + } } bool MainWindow::saveLastDatabases() @@ -858,6 +860,7 @@ void MainWindow::trayIconTriggered(QSystemTrayIcon::ActivationReason reason) void MainWindow::hideWindow() { + saveWindowInformation(); #ifndef Q_OS_MAC setWindowState(windowState() | Qt::WindowMinimized); #endif From 6bbd42bfd194c93639ba246b92ae08dbee277e79 Mon Sep 17 00:00:00 2001 From: frostasm Date: Sat, 28 Oct 2017 18:37:05 +0300 Subject: [PATCH 05/79] Allow to change the height of the preview panel (#1135) --- src/gui/DetailsWidget.ui | 322 ++++++++++++++++++--------------------- 1 file changed, 147 insertions(+), 175 deletions(-) diff --git a/src/gui/DetailsWidget.ui b/src/gui/DetailsWidget.ui index fb31409f8..8fbafe349 100644 --- a/src/gui/DetailsWidget.ui +++ b/src/gui/DetailsWidget.ui @@ -6,22 +6,10 @@ 0 0 - 630 + 600 200 - - - 0 - 0 - - - - - 16777215 - 200 - - @@ -36,12 +24,6 @@ 0 - - - 20 - 16777215 - - @@ -166,85 +148,19 @@ - - - 0 - 0 - - 0 - + + + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + - - - - - - - 0 - 0 - - - - PointingHandCursor - - - - - - - - - - - 0 - 0 - - - - - 75 - true - - - - Expiration - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - - 9 - 75 - true - - - - URL - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - @@ -267,6 +183,102 @@ + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + + 0 + 0 + + + + + 9 + 75 + true + + + + URL + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + PointingHandCursor + + + + + + + + + + + 0 + 0 + + + + + 75 + true + + + + Expiration + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + @@ -291,41 +303,11 @@ - - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - 0 - 0 - - - - - + + @@ -347,7 +329,30 @@ - + + + + + 0 + 0 + + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + @@ -357,7 +362,7 @@ - + @@ -379,7 +384,7 @@ - + @@ -389,7 +394,7 @@ - + @@ -411,15 +416,18 @@ - - + + - Qt::Vertical + Qt::Horizontal + + + QSizePolicy::Fixed 20 - 40 + 20 @@ -434,27 +442,9 @@ Attributes - - + + - - - 0 - 1 - - - - - 0 - 80 - - - - - 16777215 - 80 - - Qt::ClickFocus @@ -469,27 +459,9 @@ Notes - - + + - - - 0 - 1 - - - - - 0 - 80 - - - - - 16777215 - 80 - - Qt::ClickFocus @@ -504,8 +476,8 @@ Autotype - - + + QFrame::Sunken From 8b00d0580bd4028a20124113d2bc2be3f3153f1e Mon Sep 17 00:00:00 2001 From: frostasm Date: Sat, 28 Oct 2017 21:14:45 +0300 Subject: [PATCH 06/79] Synchronize the height of the preview panel for all open databases --- src/gui/DatabaseWidget.cpp | 39 ++++++++++++++++++----------- src/gui/DatabaseWidget.h | 11 +++++--- src/gui/DatabaseWidgetStateSync.cpp | 20 ++++++++++----- src/gui/DatabaseWidgetStateSync.h | 3 ++- 4 files changed, 48 insertions(+), 25 deletions(-) diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index 6571668c8..ec51312c1 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -73,15 +73,15 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent) QLayout* layout = new QHBoxLayout(); mainLayout->addWidget(m_messageWidget); mainLayout->addLayout(layout); - m_splitter = new QSplitter(m_mainWidget); - m_splitter->setChildrenCollapsible(false); + m_mainSplitter = new QSplitter(m_mainWidget); + m_mainSplitter->setChildrenCollapsible(false); m_detailSplitter = new QSplitter(m_mainWidget); m_detailSplitter->setOrientation(Qt::Vertical); m_detailSplitter->setChildrenCollapsible(true); - QWidget* rightHandSideWidget = new QWidget(m_splitter); + QWidget* rightHandSideWidget = new QWidget(m_mainSplitter); - m_groupView = new GroupView(db, m_splitter); + m_groupView = new GroupView(db, m_mainSplitter); m_groupView->setObjectName("groupView"); m_groupView->setContextMenuPolicy(Qt::CustomContextMenu); connect(m_groupView, SIGNAL(customContextMenuRequested(QPoint)), @@ -122,13 +122,13 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent) setTabOrder(m_entryView, m_groupView); - m_splitter->addWidget(m_groupView); - m_splitter->addWidget(rightHandSideWidget); + m_mainSplitter->addWidget(m_groupView); + m_mainSplitter->addWidget(rightHandSideWidget); - m_splitter->setStretchFactor(0, 30); - m_splitter->setStretchFactor(1, 70); + m_mainSplitter->setStretchFactor(0, 30); + m_mainSplitter->setStretchFactor(1, 70); - layout->addWidget(m_splitter); + layout->addWidget(m_mainSplitter); m_mainWidget->setLayout(mainLayout); m_editEntryWidget = new EditEntryWidget(); @@ -168,7 +168,8 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent) addWidget(m_keepass1OpenWidget); addWidget(m_unlockDatabaseWidget); - connect(m_splitter, SIGNAL(splitterMoved(int,int)), SIGNAL(splitterSizesChanged())); + connect(m_mainSplitter, SIGNAL(splitterMoved(int,int)), SIGNAL(mainSplitterSizesChanged())); + connect(m_detailSplitter, SIGNAL(splitterMoved(int,int)), SIGNAL(detailSplitterSizesChanged())); connect(m_entryView->header(), SIGNAL(sectionResized(int,int,int)), SIGNAL(entryColumnSizesChanged())); connect(m_groupView, SIGNAL(groupChanged(Group*)), this, SLOT(onGroupChanged(Group*))); connect(m_groupView, SIGNAL(groupChanged(Group*)), SIGNAL(groupChanged())); @@ -251,14 +252,24 @@ bool DatabaseWidget::isEditWidgetModified() const } } -QList DatabaseWidget::splitterSizes() const +QList DatabaseWidget::mainSplitterSizes() const { - return m_splitter->sizes(); + return m_mainSplitter->sizes(); } -void DatabaseWidget::setSplitterSizes(const QList& sizes) +void DatabaseWidget::setMainSplitterSizes(const QList& sizes) { - m_splitter->setSizes(sizes); + m_mainSplitter->setSizes(sizes); +} + +QList DatabaseWidget::detailSplitterSizes() const +{ + return m_detailSplitter->sizes(); +} + +void DatabaseWidget::setDetailSplitterSizes(const QList &sizes) +{ + m_detailSplitter->setSizes(sizes); } QList DatabaseWidget::entryHeaderViewSizes() const diff --git a/src/gui/DatabaseWidget.h b/src/gui/DatabaseWidget.h index 404adb528..215077594 100644 --- a/src/gui/DatabaseWidget.h +++ b/src/gui/DatabaseWidget.h @@ -88,8 +88,10 @@ public: bool isGroupSelected() const; bool isInEditMode() const; bool isEditWidgetModified() const; - QList splitterSizes() const; - void setSplitterSizes(const QList& sizes); + QList mainSplitterSizes() const; + void setMainSplitterSizes(const QList& sizes); + QList detailSplitterSizes() const; + void setDetailSplitterSizes(const QList& sizes); QList entryHeaderViewSizes() const; void setEntryViewHeaderSizes(const QList& sizes); void clearAllWidgets(); @@ -123,7 +125,8 @@ signals: void listModeActivated(); void searchModeAboutToActivate(); void searchModeActivated(); - void splitterSizesChanged(); + void mainSplitterSizesChanged(); + void detailSplitterSizesChanged(); void entryColumnSizesChanged(); void updateSearch(QString text); @@ -214,7 +217,7 @@ private: KeePass1OpenWidget* m_keepass1OpenWidget; UnlockDatabaseWidget* m_unlockDatabaseWidget; UnlockDatabaseDialog* m_unlockDatabaseDialog; - QSplitter* m_splitter; + QSplitter* m_mainSplitter; QSplitter* m_detailSplitter; GroupView* m_groupView; EntryView* m_entryView; diff --git a/src/gui/DatabaseWidgetStateSync.cpp b/src/gui/DatabaseWidgetStateSync.cpp index 1510d8440..9b5492b0d 100644 --- a/src/gui/DatabaseWidgetStateSync.cpp +++ b/src/gui/DatabaseWidgetStateSync.cpp @@ -25,14 +25,16 @@ DatabaseWidgetStateSync::DatabaseWidgetStateSync(QObject* parent) , m_activeDbWidget(nullptr) , m_blockUpdates(false) { - m_splitterSizes = variantToIntList(config()->get("GUI/SplitterState")); + m_mainSplitterSizes = variantToIntList(config()->get("GUI/SplitterState")); + m_detailSplitterSizes = variantToIntList(config()->get("GUI/DetailSplitterState")); m_columnSizesList = variantToIntList(config()->get("GUI/EntryListColumnSizes")); m_columnSizesSearch = variantToIntList(config()->get("GUI/EntrySearchColumnSizes")); } DatabaseWidgetStateSync::~DatabaseWidgetStateSync() { - config()->set("GUI/SplitterState", intListToVariant(m_splitterSizes)); + config()->set("GUI/SplitterState", intListToVariant(m_mainSplitterSizes)); + config()->set("GUI/DetailSplitterState", intListToVariant(m_detailSplitterSizes)); config()->set("GUI/EntryListColumnSizes", intListToVariant(m_columnSizesList)); config()->set("GUI/EntrySearchColumnSizes", intListToVariant(m_columnSizesSearch)); } @@ -48,8 +50,11 @@ void DatabaseWidgetStateSync::setActive(DatabaseWidget* dbWidget) if (m_activeDbWidget) { m_blockUpdates = true; - if (!m_splitterSizes.isEmpty()) - m_activeDbWidget->setSplitterSizes(m_splitterSizes); + if (!m_mainSplitterSizes.isEmpty()) + m_activeDbWidget->setMainSplitterSizes(m_mainSplitterSizes); + + if (!m_detailSplitterSizes.isEmpty()) + m_activeDbWidget->setDetailSplitterSizes(m_detailSplitterSizes); if (m_activeDbWidget->isInSearchMode()) restoreSearchView(); @@ -58,7 +63,9 @@ void DatabaseWidgetStateSync::setActive(DatabaseWidget* dbWidget) m_blockUpdates = false; - connect(m_activeDbWidget, SIGNAL(splitterSizesChanged()), + connect(m_activeDbWidget, SIGNAL(mainSplitterSizesChanged()), + SLOT(updateSplitterSizes())); + connect(m_activeDbWidget, SIGNAL(detailSplitterSizesChanged()), SLOT(updateSplitterSizes())); connect(m_activeDbWidget, SIGNAL(entryColumnSizesChanged()), SLOT(updateColumnSizes())); @@ -102,7 +109,8 @@ void DatabaseWidgetStateSync::updateSplitterSizes() return; } - m_splitterSizes = m_activeDbWidget->splitterSizes(); + m_mainSplitterSizes = m_activeDbWidget->mainSplitterSizes(); + m_detailSplitterSizes = m_activeDbWidget->detailSplitterSizes(); } void DatabaseWidgetStateSync::updateColumnSizes() diff --git a/src/gui/DatabaseWidgetStateSync.h b/src/gui/DatabaseWidgetStateSync.h index 96ecd104a..79a8ded38 100644 --- a/src/gui/DatabaseWidgetStateSync.h +++ b/src/gui/DatabaseWidgetStateSync.h @@ -46,7 +46,8 @@ private: DatabaseWidget* m_activeDbWidget; bool m_blockUpdates; - QList m_splitterSizes; + QList m_mainSplitterSizes; + QList m_detailSplitterSizes; QList m_columnSizesList; QList m_columnSizesSearch; }; From afaa0a3493c78d47fd4aad14c4c3fff5292b5afe Mon Sep 17 00:00:00 2001 From: frostasm Date: Thu, 2 Nov 2017 20:47:54 +0200 Subject: [PATCH 07/79] Fix formatting brackets in DatabaseWidgetStateSync::setActive function --- src/gui/DatabaseWidgetStateSync.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/gui/DatabaseWidgetStateSync.cpp b/src/gui/DatabaseWidgetStateSync.cpp index 9b5492b0d..57a3dcf86 100644 --- a/src/gui/DatabaseWidgetStateSync.cpp +++ b/src/gui/DatabaseWidgetStateSync.cpp @@ -50,16 +50,19 @@ void DatabaseWidgetStateSync::setActive(DatabaseWidget* dbWidget) if (m_activeDbWidget) { m_blockUpdates = true; - if (!m_mainSplitterSizes.isEmpty()) + if (!m_mainSplitterSizes.isEmpty()) { m_activeDbWidget->setMainSplitterSizes(m_mainSplitterSizes); + } - if (!m_detailSplitterSizes.isEmpty()) + if (!m_detailSplitterSizes.isEmpty()) { m_activeDbWidget->setDetailSplitterSizes(m_detailSplitterSizes); + } - if (m_activeDbWidget->isInSearchMode()) + if (m_activeDbWidget->isInSearchMode()) { restoreSearchView(); - else + } else { restoreListView(); + } m_blockUpdates = false; From c3c67f18b8752b3304bcd057efac43ade31c89fb Mon Sep 17 00:00:00 2001 From: thez3ro Date: Sun, 29 Oct 2017 15:04:46 +0100 Subject: [PATCH 08/79] add test for DB creation --- src/gui/DatabaseWidget.cpp | 19 +++++++++++--- src/gui/DatabaseWidget.h | 3 +++ src/gui/csvImport/CsvImportWizard.cpp | 23 ++++------------ src/gui/csvImport/CsvImportWizard.h | 6 ++--- tests/gui/TestGui.cpp | 38 +++++++++++++++++++++++++++ tests/gui/TestGui.h | 1 + 6 files changed, 64 insertions(+), 26 deletions(-) diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index ec51312c1..63420158b 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -63,6 +63,7 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent) , m_newGroup(nullptr) , m_newEntry(nullptr) , m_newParent(nullptr) + , m_importingCsv(false) { m_mainWidget = new QWidget(this); @@ -137,13 +138,14 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent) m_editGroupWidget = new EditGroupWidget(); m_editGroupWidget->setObjectName("editGroupWidget"); m_changeMasterKeyWidget = new ChangeMasterKeyWidget(); + m_changeMasterKeyWidget->setObjectName("changeMasterKeyWidget"); m_changeMasterKeyWidget->headlineLabel()->setText(tr("Change master key")); - m_csvImportWizard = new CsvImportWizard(); - m_csvImportWizard->setObjectName("csvImportWizard"); QFont headlineLabelFont = m_changeMasterKeyWidget->headlineLabel()->font(); headlineLabelFont.setBold(true); headlineLabelFont.setPointSize(headlineLabelFont.pointSize() + 2); m_changeMasterKeyWidget->headlineLabel()->setFont(headlineLabelFont); + m_csvImportWizard = new CsvImportWizard(); + m_csvImportWizard->setObjectName("csvImportWizard"); m_databaseSettingsWidget = new DatabaseSettingsWidget(); m_databaseSettingsWidget->setObjectName("databaseSettingsWidget"); m_databaseOpenWidget = new DatabaseOpenWidget(); @@ -782,6 +784,12 @@ void DatabaseWidget::switchToGroupEdit(Group* group, bool create) void DatabaseWidget::updateMasterKey(bool accepted) { + if (m_importingCsv) { + setCurrentWidget(m_csvImportWizard); + m_csvImportWizard->keyFinished(accepted, m_changeMasterKeyWidget->newMasterKey()); + return; + } + if (accepted) { QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); bool result = m_db->setKey(m_changeMasterKeyWidget->newMasterKey()); @@ -915,6 +923,7 @@ void DatabaseWidget::switchToMasterKeyChange(bool disableCancel) m_changeMasterKeyWidget->clearForms(); m_changeMasterKeyWidget->setCancelEnabled(!disableCancel); setCurrentWidget(m_changeMasterKeyWidget); + m_importingCsv = false; } void DatabaseWidget::switchToDatabaseSettings() @@ -941,9 +950,11 @@ void DatabaseWidget::switchToOpenDatabase(const QString& fileName, const QString void DatabaseWidget::switchToImportCsv(const QString& fileName) { updateFilename(fileName); - switchToMasterKeyChange(); m_csvImportWizard->load(fileName, m_db); - setCurrentWidget(m_csvImportWizard); + m_changeMasterKeyWidget->clearForms(); + m_changeMasterKeyWidget->setCancelEnabled(false); + setCurrentWidget(m_changeMasterKeyWidget); + m_importingCsv = true; } void DatabaseWidget::switchToOpenMergeDatabase(const QString& fileName) diff --git a/src/gui/DatabaseWidget.h b/src/gui/DatabaseWidget.h index 215077594..e9428a702 100644 --- a/src/gui/DatabaseWidget.h +++ b/src/gui/DatabaseWidget.h @@ -236,6 +236,9 @@ private: bool m_searchCaseSensitive; bool m_searchLimitGroup; + // CSV import state + bool m_importingCsv; + // Autoreload QFileSystemWatcher m_fileWatcher; QTimer m_fileWatchTimer; diff --git a/src/gui/csvImport/CsvImportWizard.cpp b/src/gui/csvImport/CsvImportWizard.cpp index eb4b21236..e9a8f4984 100644 --- a/src/gui/csvImport/CsvImportWizard.cpp +++ b/src/gui/csvImport/CsvImportWizard.cpp @@ -28,19 +28,9 @@ CsvImportWizard::CsvImportWizard(QWidget *parent) : DialogyWidget(parent) { m_layout = new QGridLayout(this); - m_pages = new QStackedWidget(parent); - m_layout->addWidget(m_pages, 0, 0); + m_layout->addWidget(m_parse = new CsvImportWidget(this), 0, 0); - m_pages->addWidget(key = new ChangeMasterKeyWidget(m_pages)); - m_pages->addWidget(parse = new CsvImportWidget(m_pages)); - key->headlineLabel()->setText(tr("Import CSV file")); - QFont headLineFont = key->headlineLabel()->font(); - headLineFont.setBold(true); - headLineFont.setPointSize(headLineFont.pointSize() + 2); - key->headlineLabel()->setFont(headLineFont); - - connect(key, SIGNAL(editFinished(bool)), this, SLOT(keyFinished(bool))); - connect(parse, SIGNAL(editFinished(bool)), this, SLOT(parseFinished(bool))); + connect(m_parse, SIGNAL(editFinished(bool)), this, SLOT(parseFinished(bool))); } CsvImportWizard::~CsvImportWizard() @@ -49,21 +39,18 @@ CsvImportWizard::~CsvImportWizard() void CsvImportWizard::load(const QString& filename, Database* database) { m_db = database; - parse->load(filename, database); - key->clearForms(); + m_parse->load(filename, database); } -void CsvImportWizard::keyFinished(bool accepted) +void CsvImportWizard::keyFinished(bool accepted, CompositeKey key) { if (!accepted) { emit importFinished(false); return; } - m_pages->setCurrentIndex(m_pages->currentIndex()+1); - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - bool result = m_db->setKey(key->newMasterKey()); + bool result = m_db->setKey(key); QApplication::restoreOverrideCursor(); if (!result) { diff --git a/src/gui/csvImport/CsvImportWizard.h b/src/gui/csvImport/CsvImportWizard.h index 317018d99..b6414c0c9 100644 --- a/src/gui/csvImport/CsvImportWizard.h +++ b/src/gui/csvImport/CsvImportWizard.h @@ -38,19 +38,17 @@ public: explicit CsvImportWizard(QWidget *parent = nullptr); ~CsvImportWizard(); void load(const QString& filename, Database *database); + void keyFinished(bool accepted, CompositeKey key); signals: void importFinished(bool accepted); private slots: - void keyFinished(bool accepted); void parseFinished(bool accepted); private: Database* m_db; - CsvImportWidget* parse; - ChangeMasterKeyWidget* key; - QStackedWidget *m_pages; + CsvImportWidget* m_parse; QGridLayout *m_layout; }; diff --git a/tests/gui/TestGui.cpp b/tests/gui/TestGui.cpp index 75ce3cc59..8c066c93e 100644 --- a/tests/gui/TestGui.cpp +++ b/tests/gui/TestGui.cpp @@ -49,6 +49,7 @@ #include "gui/DatabaseTabWidget.h" #include "gui/DatabaseWidget.h" #include "gui/CloneDialog.h" +#include "gui/PasswordEdit.h" #include "gui/TotpDialog.h" #include "gui/SetupTotpDialog.h" #include "gui/FileDialog.h" @@ -119,6 +120,43 @@ void TestGui::cleanup() m_dbWidget = nullptr; } +void TestGui::testCreateDatabase() +{ + fileDialog()->setNextFileName(QString(KEEPASSX_TEST_DATA_DIR).append("/NewTestDatabase.kdbx")); + triggerAction("actionDatabaseNew"); + + DatabaseWidget* dbWidget = m_tabWidget->currentDatabaseWidget(); + + QWidget* databaseNewWidget = dbWidget->findChild("changeMasterKeyWidget"); + QList databaseNewWidgets = dbWidget->findChildren("changeMasterKeyWidget"); + PasswordEdit* editPassword = databaseNewWidget->findChild("enterPasswordEdit"); + QVERIFY(editPassword->isVisible()); + + QLineEdit* editPasswordRepeat = databaseNewWidget->findChild("repeatPasswordEdit"); + QVERIFY(editPasswordRepeat->isVisible()); + + m_tabWidget->currentDatabaseWidget()->setCurrentWidget(databaseNewWidget); + + QTest::keyClicks(editPassword, "test"); + QTest::keyClicks(editPasswordRepeat, "test"); + QTest::keyClick(editPasswordRepeat, Qt::Key_Enter); + + QTRY_VERIFY(m_tabWidget->tabText(m_tabWidget->currentIndex()).contains("*")); + + m_db = m_tabWidget->currentDatabaseWidget()->database(); + + // there is a new empty db + QCOMPARE(m_db->rootGroup()->children().size(), 0); + + // clean + MessageBox::setNextAnswer(QMessageBox::No); + triggerAction("actionDatabaseClose"); + Tools::wait(100); + + QFile dbfile(QString(KEEPASSX_TEST_DATA_DIR).append("/NewTestDatabase.kdbx")); + dbfile.remove(); +} + void TestGui::testMergeDatabase() { // It is safe to ignore the warning this line produces diff --git a/tests/gui/TestGui.h b/tests/gui/TestGui.h index 904e5f21e..9929b4e7f 100644 --- a/tests/gui/TestGui.h +++ b/tests/gui/TestGui.h @@ -40,6 +40,7 @@ private slots: void cleanup(); void cleanupTestCase(); + void testCreateDatabase(); void testMergeDatabase(); void testAutoreloadDatabase(); void testTabs(); From d6e8e1be6e1371f9dad6b83c1fa698ac77f218af Mon Sep 17 00:00:00 2001 From: thez3ro Date: Thu, 2 Nov 2017 19:58:45 +0100 Subject: [PATCH 09/79] use QTemporaryFile when creating a database for guitest --- tests/gui/TestGui.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/gui/TestGui.cpp b/tests/gui/TestGui.cpp index 8c066c93e..ffa10b7dd 100644 --- a/tests/gui/TestGui.cpp +++ b/tests/gui/TestGui.cpp @@ -122,7 +122,12 @@ void TestGui::cleanup() void TestGui::testCreateDatabase() { - fileDialog()->setNextFileName(QString(KEEPASSX_TEST_DATA_DIR).append("/NewTestDatabase.kdbx")); + QTemporaryFile tmpFile; + QVERIFY(tmpFile.open()); + QString tmpFileName = tmpFile.fileName(); + tmpFile.remove(); + + fileDialog()->setNextFileName(tmpFileName); triggerAction("actionDatabaseNew"); DatabaseWidget* dbWidget = m_tabWidget->currentDatabaseWidget(); @@ -148,13 +153,10 @@ void TestGui::testCreateDatabase() // there is a new empty db QCOMPARE(m_db->rootGroup()->children().size(), 0); - // clean + // close the new database MessageBox::setNextAnswer(QMessageBox::No); triggerAction("actionDatabaseClose"); Tools::wait(100); - - QFile dbfile(QString(KEEPASSX_TEST_DATA_DIR).append("/NewTestDatabase.kdbx")); - dbfile.remove(); } void TestGui::testMergeDatabase() From 78408cf54ba817f0fb666ce69a701ac10fdf41b0 Mon Sep 17 00:00:00 2001 From: Yen Chi Hsuan Date: Mon, 6 Nov 2017 16:05:39 +0800 Subject: [PATCH 10/79] COPYING: remove a duplicated entry Already in line 46~48 :) --- COPYING | 4 ---- 1 file changed, 4 deletions(-) diff --git a/COPYING b/COPYING index e12f4534c..a6bf0cf46 100644 --- a/COPYING +++ b/COPYING @@ -55,10 +55,6 @@ Files: cmake/GenerateProductVersion.cmake Copyright: 2015 halex2005 License: MIT -Files: cmake/CodeCoverage.cmake -Copyright: 2012 - 2015, Lars Bilke -License: BSD-3-clause - Files: share/icons/application/*/apps/keepassxc.png share/icons/application/scalable/apps/keepassxc.svgz share/icons/application/*/apps/keepassxc-dark.png From 4853014a61f01427ec9cb59c46371c5619e74653 Mon Sep 17 00:00:00 2001 From: AsavarTzeth Date: Thu, 26 Oct 2017 13:00:50 +0200 Subject: [PATCH 11/79] Fix id and appdata validation failures (#1131) According to the AppStream specification org.keepassxc is not a valid id. The product name is missing. This results in failures if one tries to validate the file and makes it unusable where validation is enforced. Additionally it seems specification don't allow the `` tag with component type desktop-application. I am not sure this tag is strictly necessary. In any case validation tests require this to be removed. Fixing both of these issues ensure the AppStream appdata is compliant and works anywhere passing validations is a requirement. Also provide some other fixes and improvements to the appdata. Minor validation failures: - Fix missing captions for screenshots (`appstreamcli`) - Fix descriptions cannot start with `