Implement opening/closing databases.

This commit is contained in:
Felix Geyer 2011-11-13 14:55:20 +01:00
parent 0e41ed72dd
commit c7ed5f8421
10 changed files with 463 additions and 10 deletions

View File

@ -44,12 +44,14 @@ set(keepassx_SOURCES
format/KeePass2Writer.cpp
format/KeePass2XmlReader.cpp
format/KeePass2XmlWriter.cpp
gui/DatabaseManager.cpp
gui/DatabaseWidget.cpp
gui/EditEntryWidget.cpp
gui/EntryModel.cpp
gui/EntryView.cpp
gui/GroupModel.cpp
gui/GroupView.cpp
gui/KeyOpenDialog.cpp
gui/MainWindow.cpp
keys/CompositeKey.cpp
keys/Key.h
@ -65,12 +67,14 @@ set(keepassx_MOC
core/Entry.h
core/Group.h
core/Metadata.h
gui/DatabaseManager.h
gui/DatabaseWidget.h
gui/EditEntryWidget.h
gui/EntryModel.h
gui/EntryView.h
gui/GroupModel.h
gui/GroupView.h
gui/KeyOpenDialog.h
gui/MainWindow.h
streams/HashedBlockStream.h
streams/LayeredStream.h
@ -82,6 +86,7 @@ set(keepassx_FORMS
gui/EditEntryWidget.ui
gui/EditEntryWidgetMain.ui
gui/EditEntryWidgetNotes.ui
gui/KeyOpenDialog.ui
gui/MainWindow.ui
)

155
src/gui/DatabaseManager.cpp Normal file
View File

@ -0,0 +1,155 @@
/*
* Copyright (C) 2011 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "DatabaseManager.h"
#include <QtCore/QFileInfo>
#include <QtGui/QFileDialog>
#include <QtGui/QTabWidget>
#include "core/Database.h"
#include "core/Metadata.h"
#include "format/KeePass2XmlReader.h"
#include "gui/DatabaseWidget.h"
#include "gui/KeyOpenDialog.h"
DatabaseManagerStruct::DatabaseManagerStruct()
: file(0)
, dbWidget(0)
, modified(false)
, readOnly(false)
{
}
DatabaseManager::DatabaseManager(QTabWidget* tabWidget)
: m_tabWidget(tabWidget)
, m_window(tabWidget->window())
{
connect(m_tabWidget, SIGNAL(tabCloseRequested(int)), SLOT(closeDatabase(int)));
}
void DatabaseManager::openDatabase()
{
QString fileName = QFileDialog::getOpenFileName(m_window, tr("Open database"), QString(),
tr("KeePass 2 Database").append(" (*.kdbx)"));
if (!fileName.isEmpty()) {
openDatabase(fileName);
}
}
void DatabaseManager::openDatabase(const QString& fileName)
{
DatabaseManagerStruct dbStruct;
QScopedPointer<QFile> file(new QFile(fileName));
if (!file->open(QIODevice::ReadWrite)) {
if (!file->open(QIODevice::ReadOnly)) {
// can only open read-only
dbStruct.readOnly = true;
}
else {
// can't open
return;
}
}
Database* db;
do {
QScopedPointer<KeyOpenDialog> keyDialog(new KeyOpenDialog(m_window));
if (keyDialog->exec() == QDialog::Rejected) {
return;
}
file->reset();
db = m_reader.readDatabase(file.data(), keyDialog->key());
} while (!db);
dbStruct.file = file.take();
dbStruct.dbWidget = new DatabaseWidget(db, m_tabWidget);
m_dbList.insert(db, dbStruct);
m_tabWidget->addTab(dbStruct.dbWidget, "");
updateTabName(db);
connect(db->metadata(), SIGNAL(nameTextChanged(Database*)), SLOT(updateTabName(Database*)));
}
void DatabaseManager::closeDatabase(Database* db)
{
Q_ASSERT(db);
const DatabaseManagerStruct& dbStruct = m_dbList.value(db);
if (dbStruct.modified) {
// TODO message box
}
int index = databaseIndex(db);
Q_ASSERT(index != -1);
m_tabWidget->removeTab(index);
delete dbStruct.dbWidget;
delete db;
}
void DatabaseManager::closeDatabase(int index)
{
closeDatabase(indexDatabase(index));
}
void DatabaseManager::updateTabName(Database* db)
{
int index = databaseIndex(db);
Q_ASSERT(index != -1);
const DatabaseManagerStruct& dbStruct = m_dbList.value(db);
QString filename = QFileInfo(*dbStruct.file).completeBaseName();
QString tabName;
if (db->metadata()->name().isEmpty()) {
tabName = filename;
}
else {
tabName = QString("%1 [%2]").arg(db->metadata()->name().arg(filename));
}
m_tabWidget->setTabText(index, tabName);
}
int DatabaseManager::databaseIndex(Database* db)
{
QWidget* dbWidget = m_dbList.value(db).dbWidget;
return m_tabWidget->indexOf(dbWidget);
}
Database* DatabaseManager::indexDatabase(int index)
{
QWidget* dbWidget = m_tabWidget->widget(index);
QHashIterator<Database*, DatabaseManagerStruct> i(m_dbList);
while (i.hasNext()) {
i.next();
if (i.value().dbWidget == dbWidget) {
return i.key();
}
}
return 0;
}

67
src/gui/DatabaseManager.h Normal file
View File

@ -0,0 +1,67 @@
/*
* Copyright (C) 2011 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEEPASSX_DATABASEMANAGER_H
#define KEEPASSX_DATABASEMANAGER_H
#include <QtCore/QHash>
#include <QtCore/QObject>
#include "format/KeePass2Reader.h"
#include "format/KeePass2Writer.h"
class QFile;
class QTabWidget;
struct DatabaseManagerStruct
{
DatabaseManagerStruct();
QFile* file;
QWidget* dbWidget;
bool modified;
bool readOnly;
};
class DatabaseManager : public QObject
{
Q_OBJECT
public:
DatabaseManager(QTabWidget* tabWidget);
void openDatabase(const QString& fileName);
void closeDatabase(Database* db);
public Q_SLOTS:
void openDatabase();
void closeDatabase(int index);
private Q_SLOTS:
void updateTabName(Database* db);
private:
int databaseIndex(Database* db);
Database* indexDatabase(int index);
QTabWidget* m_tabWidget;
QWidget* m_window;
KeePass2Reader m_reader;
KeePass2Writer m_writer;
QHash<Database*, DatabaseManagerStruct> m_dbList;
};
#endif // KEEPASSX_DATABASEMANAGER_H

50
src/gui/KeyOpenDialog.cpp Normal file
View File

@ -0,0 +1,50 @@
/*
* Copyright (C) 2011 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "KeyOpenDialog.h"
#include "ui_KeyOpenDialog.h"
#include "keys/PasswordKey.h"
KeyOpenDialog::KeyOpenDialog(QWidget* parent)
: QDialog(parent)
, m_ui(new Ui::KeyOpenDialog())
{
m_ui->setupUi(this);
connect(m_ui->buttonBox, SIGNAL(accepted()), SLOT(createKey()));
}
KeyOpenDialog::~KeyOpenDialog()
{
}
CompositeKey KeyOpenDialog::key()
{
return m_key;
}
void KeyOpenDialog::createKey()
{
if (m_ui->checkPassword->isChecked()) {
m_key.addKey(PasswordKey(m_ui->editPassword->text()));
}
if (m_ui->checkKeyFile->isChecked()) {
// TODO read key file
}
}

49
src/gui/KeyOpenDialog.h Normal file
View File

@ -0,0 +1,49 @@
/*
* Copyright (C) 2011 Felix Geyer <debfx@fobos.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 or (at your option)
* version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEEPASSX_KEYOPENDIALOG_H
#define KEEPASSX_KEYOPENDIALOG_H
#include <QtCore/QScopedPointer>
#include <QtGui/QDialog>
#include "keys/CompositeKey.h"
namespace Ui {
class KeyOpenDialog;
}
class KeyOpenDialog : public QDialog
{
Q_OBJECT
public:
explicit KeyOpenDialog(QWidget* parent = 0);
~KeyOpenDialog();
CompositeKey key();
private Q_SLOTS:
void createKey();
private:
QScopedPointer<Ui::KeyOpenDialog> m_ui;
CompositeKey m_key;
Q_DISABLE_COPY(KeyOpenDialog)
};
#endif // KEEPASSX_KEYOPENDIALOG_H

113
src/gui/KeyOpenDialog.ui Normal file
View File

@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>KeyOpenDialog</class>
<widget class="QDialog" name="KeyOpenDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>353</width>
<height>172</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QCheckBox" name="checkPassword">
<property name="text">
<string>Password:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="editPassword"/>
</item>
<item>
<widget class="QPushButton" name="buttonTogglePassword">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="checkKeyFile">
<property name="text">
<string>Key File:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QComboBox" name="comboKeyFile">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonBrowseFile">
<property name="text">
<string>Browse</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>KeyOpenDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>KeyOpenDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -19,16 +19,15 @@
#include "core/Database.h"
#include "core/Metadata.h"
#include "gui/DatabaseManager.h"
#include "gui/DatabaseWidget.h"
MainWindow::MainWindow()
{
setupUi(this);
m_dbManager = new DatabaseManager(tabWidget);
connect(actionOpenDatabase, SIGNAL(triggered()), m_dbManager, SLOT(openDatabase()));
connect(actionQuit, SIGNAL(triggered()), SLOT(close()));
}
void MainWindow::addDatabase(Database* db)
{
QWidget* databaseWidget = new DatabaseWidget(db, tabWidget);
tabWidget->addTab(databaseWidget, db->metadata()->name());
}

View File

@ -21,6 +21,7 @@
#include "ui_MainWindow.h"
class Database;
class DatabaseManager;
class MainWindow : public QMainWindow, private Ui::MainWindow
{
@ -28,7 +29,9 @@ class MainWindow : public QMainWindow, private Ui::MainWindow
public:
MainWindow();
void addDatabase(Database* db);
private:
DatabaseManager* m_dbManager;
};
#endif // KEEPASSX_MAINWINDOW_H

View File

@ -20,6 +20,12 @@
<property name="currentIndex">
<number>-1</number>
</property>
<property name="tabsClosable">
<bool>true</bool>
</property>
<property name="movable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
@ -37,6 +43,8 @@
<property name="title">
<string>File</string>
</property>
<addaction name="actionOpenDatabase"/>
<addaction name="separator"/>
<addaction name="actionQuit"/>
</widget>
<widget class="QMenu" name="menuHelp">
@ -59,6 +67,11 @@
<string>About</string>
</property>
</action>
<action name="actionOpenDatabase">
<property name="text">
<string>Open database</string>
</property>
</action>
</widget>
<resources/>
<connections/>

View File

@ -39,15 +39,14 @@ int main(int argc, char **argv)
password.setPassword("a");
key.addKey(password);
KeePass2Reader* xreader = new KeePass2Reader();
Database* db = xreader->readDatabase(QString(KEEPASSX_TEST_DIR).append("/NewDatabase.kdbx"), key);
//KeePass2Reader* xreader = new KeePass2Reader();
//Database* db = xreader->readDatabase(QString(KEEPASSX_TEST_DIR).append("/NewDatabase.kdbx"), key);
//KeePass2XmlReader* reader = new KeePass2XmlReader();
//Database* db = reader->readDatabase(QString(KEEPASSX_TEST_DIR).append("/NewDatabase.xml"));
MainWindow mainWindow;
mainWindow.show();
mainWindow.addDatabase(db);
return app.exec();
}