implemented Database as interface (pure virtual)

git-svn-id: https://svn.code.sf.net/p/keepassx/code/trunk@64 b624d157-de02-0410-bad0-e51aec6abb33
master
tariq 19 years ago
parent 2bf3e5820c
commit 3c7d617599
  1. 40
      src/Database.h
  2. 38
      src/PwManager.cpp
  3. 13
      src/PwManager.h
  4. 6
      src/PwmConfig.cpp
  5. 12
      src/dialogs/EditEntryDlg.cpp
  6. 4
      src/dialogs/EditEntryDlg.h
  7. 26
      src/dialogs/SearchDlg.cpp
  8. 4
      src/dialogs/SearchDlg.h
  9. 24
      src/export/Export_Txt.cpp
  10. 2
      src/export/Export_Txt.h
  11. 2
      src/import/Import_KWalletXml.cpp
  12. 2
      src/import/Import_KWalletXml.h
  13. 2
      src/import/Import_PwManager.cpp
  14. 4
      src/import/Import_PwManager.h
  15. 12
      src/lib/EntryView.cpp
  16. 2
      src/lib/EntryView.h
  17. 28
      src/lib/GroupView.cpp
  18. 2
      src/lib/GroupView.h
  19. 3
      src/mainwindow.cpp
  20. 2
      src/mainwindow.h

@ -79,17 +79,53 @@ static bool UI_ExpandByDefault;
class Database{
public:
Database();
virtual ~Database(){};
virtual bool openDatabase(QString filename, QString& err)=0;
virtual bool saveDatabase()=0;
virtual bool closeDatabase()=0;
virtual void newDatabase()=0;
virtual bool CalcMasterKeyByPassword(QString& password)=0;
virtual bool CalcMasterKeyByFile(QString filename)=0;
virtual bool CalcMasterKeyByFileAndPw(QString filename, QString& password)=0;
virtual bool createKeyFile(const QString& filename)=0;
virtual CGroup& group(unsigned long index)=0;
virtual void setGroup(unsigned long index,CGroup& group)=0;
virtual int numGroups()=0;
virtual CGroup* addGroup(CGroup* parent)=0;
virtual void deleteGroup(CGroup* pGroup)=0;
virtual void deleteGroup(unsigned long ID)=0;
virtual void moveGroup(CGroup* group, CGroup* DstGroup, int pos=-1)=0;
virtual void moveGroupDirectly(CGroup* group, CGroup* DstGroup)=0; //inserts group directly behind DstGroup on the same level
virtual int getGroupIndex(CGroup* group)=0;
virtual int getGroupIndex(unsigned long ID)=0;
virtual int getNumberOfChilds(CGroup* pGroup)=0;
virtual QList<int> getChildIds(CGroup* pGroup)=0;
virtual CEntry& entry(unsigned long index)=0;
virtual void setEntry(unsigned long index,CEntry& Entry)=0;
virtual int numEntries()=0;
virtual CEntry* cloneEntry(CEntry* pEntry)=0;
virtual void deleteEntry(CEntry* pEntry)=0;
virtual void moveEntry(CEntry* pEntry,CGroup* pDstGroup)=0;
virtual CEntry* addEntry()=0;
virtual CEntry* addEntry(CEntry* NewEntry)=0;
virtual void merge(Database* db2)=0;
virtual bool isParentGroup(CGroup* Group,CGroup* PotenialParent)=0;
virtual QString getError()=0; //get first error
virtual QString getErrors()=0; //get all errors in a \n seperated String
Q_UINT32 CryptoAlgorithmus;
Q_UINT32 KeyEncRounds;
QFile* file;
bool modflag;
int SearchGroupID;
QList<CGroup>Groups;
QList<CEntry>Entries;
protected:
Q_UINT8 MasterKey[32];
Q_UINT8 TransformedMasterKey[32];
};
#endif

@ -536,10 +536,6 @@ PwDatabase::PwDatabase(){
SearchGroupID=-1;
}
PwDatabase::~PwDatabase(){
}
void PwDatabase::newDatabase(){
file=new QFile();
}
@ -941,18 +937,18 @@ return i;
}
void PwDatabase::merge(PwDatabase* db){
for(int i=0;i<db->Groups.size();i++){
void PwDatabase::merge(Database* db){
for(int i=0;i<db->numGroups();i++){
int NewGroupID;
if(isGroupIdInUse(db->Groups[i].ID)==true) NewGroupID=getNewGroupId();
else NewGroupID=db->Groups[i].ID;
for(int j=0;j<db->Entries.size();j++){
if(db->Entries[j].GroupID==db->Groups[i].ID){
Entries.push_back(db->Entries[j]);
if(isGroupIdInUse(db->group(i).ID)==true) NewGroupID=getNewGroupId();
else NewGroupID=db->group(i).ID;
for(int j=0;j<db->numEntries();j++){
if(db->entry(j).GroupID==db->group(i).ID){
Entries.push_back(db->entry(j));
Entries.back().GroupID=NewGroupID;
Entries.back().sID=getNewEntrySid();}
}
Groups.push_back(db->Groups[i]);
Groups.push_back(db->group(i));
Groups.back().ID=NewGroupID;
}
}
@ -1122,6 +1118,24 @@ for(i=GroupIndex+1; i<Groups.size(); i++){
return (i-GroupIndex-1);
}
CGroup& PwDatabase::group(unsigned long index){
return Groups[index];}
void PwDatabase::setGroup(unsigned long index,CGroup& group){
Groups[index]=group;}
int PwDatabase::numGroups(){
return Groups.size();
}
CEntry& PwDatabase::entry(unsigned long index){
return Entries[index];}
void PwDatabase::setEntry(unsigned long index,CEntry& entry){
Entries[index]=entry;}
int PwDatabase::numEntries(){
return Entries.size();}
void memcpyFromLEnd32(Q_UINT32* dst,char* src){

@ -44,7 +44,6 @@ class PwDatabase:QObject,public Database{
Q_OBJECT
public:
PwDatabase();
~ PwDatabase();
bool openDatabase(QString filename, QString& err);
bool saveDatabase();
bool closeDatabase();
@ -54,6 +53,9 @@ public:
bool CalcMasterKeyByFileAndPw(QString filename, QString& password);
bool createKeyFile(const QString& filename);
CGroup& group(unsigned long index);
void setGroup(unsigned long index,CGroup& group);
int numGroups();
CGroup* addGroup(CGroup* parent);
void deleteGroup(CGroup* pGroup);
void deleteGroup(unsigned long ID);
@ -64,17 +66,21 @@ public:
int getNumberOfChilds(CGroup* pGroup);
QList<int> getChildIds(CGroup* pGroup);
CEntry& entry(unsigned long index);
void setEntry(unsigned long index,CEntry& Entry);
int numEntries();
CEntry* cloneEntry(CEntry* pEntry);
void deleteEntry(CEntry* pEntry);
void moveEntry(CEntry* pEntry,CGroup* pDstGroup);
CEntry* addEntry();
CEntry* addEntry(CEntry* NewEntry);
void merge(PwDatabase* db2);
void merge(Database* db2);
bool isParentGroup(CGroup* Group,CGroup* PotenialParent);
QString getError(); //get first error
QString getErrors(); //get all errors in a \n seperated String
QList<CGroup>Groups;
QList<CEntry>Entries;
private:
bool IsMetaStream(CEntry& Entry);
bool parseMetaStream(const CEntry& Entry);
@ -87,6 +93,7 @@ private:
bool convHexToBinaryKey(char* HexKey, char* dst);
QStringList Errors;
QList<CEntry> UnkownMetaStreams;
};

@ -44,9 +44,9 @@ EntryDetails=ini.GetValueB("UI","ShowEntryDetails",true);
OpenLast=ini.GetValueB("Options","RememberLastFile",true);
LastFile=ini.GetValue("Options","LastFile","").c_str();
ParseColumnString(ini.GetValue("UI","Columns","1111100000").c_str(),Columns);
BannerColor1=ParseColorString(ini.GetValue("Options","BannerColor1","0,104,176").c_str());
BannerColor2=ParseColorString(ini.GetValue("Options","BannerColor2","213,239,255").c_str());
BannerTextColor=ParseColorString(ini.GetValue("Options","BannerTextColor","4,0,80").c_str());
BannerColor1=ParseColorString(ini.GetValue("Options","BannerColor1","0,85,127").c_str());
BannerColor2=ParseColorString(ini.GetValue("Options","BannerColor2","0,117,175").c_str());
BannerTextColor=ParseColorString(ini.GetValue("Options","BannerTextColor","222,222,222").c_str());
ShowPasswords=ini.GetValueB("Options","ShowPasswords",false);
OpenUrlCommand=ini.GetValue("Options","UrlCmd","kfmclient openURL %1").c_str();
Language=ini.GetValue("Options","LangFile","").c_str();

@ -43,7 +43,7 @@
CEditEntryDlg::CEditEntryDlg(PwDatabase* _db, CEntry* _entry,QWidget* parent, const char* name, bool modal, Qt::WFlags fl)
CEditEntryDlg::CEditEntryDlg(Database* _db, CEntry* _entry,QWidget* parent, const char* name, bool modal, Qt::WFlags fl)
: QDialog(parent,name, modal,fl)
{
Q_ASSERT(_db);
@ -143,11 +143,11 @@ Combo_IconPicker->setCurrentItem(entry->ImageID);
void CEditEntryDlg::InitGroupComboBox(){
QString tmp;
int i;
for(i=0;i!=db->Groups.size();i++){
for(i=0;i!=db->numGroups();i++){
tmp="";
for(int j=0;j<db->Groups[i].Level;j++)tmp+=" ";
Combo_Group->insertItem(EntryIcons[db->Groups[i].ImageID],
tmp+db->Groups[i].Name,i);
for(int j=0;j<db->group(i).Level;j++)tmp+=" ";
Combo_Group->insertItem(EntryIcons[db->group(i).ImageID],
tmp+db->group(i).Name,i);
}
Combo_Group->setCurrentItem(db->getGroupIndex(entry->GroupID));
}
@ -190,7 +190,7 @@ QString s=Edit_Password->text();
entry->Password.setString(s,true);
entry->Additional=Edit_Comment->text();
if(Combo_Group->currentItem()!=db->getGroupIndex(entry->GroupID)){
db->moveEntry(entry,&db->Groups[Combo_Group->currentItem()]);
db->moveEntry(entry,&db->group(Combo_Group->currentItem()));
EntryMoved=true; ModFlag=true;
}
entry->ImageID=Combo_IconPicker->currentItem();

@ -31,7 +31,7 @@ class CEditEntryDlg : public QDialog, public Ui_EditEntryDialog
Q_OBJECT
public:
CEditEntryDlg(PwDatabase* _db, CEntry* _entry,QWidget* parent = 0, const char* name = 0, bool modal = FALSE, Qt::WFlags fl = 0);
CEditEntryDlg(Database* _db, CEntry* _entry,QWidget* parent = 0, const char* name = 0, bool modal = FALSE, Qt::WFlags fl = 0);
~CEditEntryDlg();
virtual void showEvent(QShowEvent *);
/*$PUBLIC_FUNCTIONS$*/
@ -48,7 +48,7 @@ protected slots:
public:
CEntry* entry;
PwDatabase* db;
Database* db;
QPixmap* banner_pixmap;
bool ModFlag;

@ -27,7 +27,7 @@
#include <qregexp.h>
#include <qmessagebox.h>
CSearchDlg::CSearchDlg(PwDatabase* _db,CGroup* pGroup,QWidget* parent, const char* name, bool modal, Qt::WFlags fl)
CSearchDlg::CSearchDlg(Database* _db,CGroup* pGroup,QWidget* parent, const char* name, bool modal, Qt::WFlags fl)
: QDialog(parent,name, modal,fl)
{
setupUi(this);
@ -80,30 +80,30 @@ if(txt==""){
QMessageBox::information(this,tr("Notice"),tr("Please enter a search string."),tr("OK"));
return;}
for(int i=0;i<db->Entries.size();i++){
for(int i=0;i<db->numEntries();i++){
if(group){
if(checkBox_Recursive->isChecked()){
QList<int> groups=db->getChildIds(group);
groups << group->ID;
bool IsInAnyGroup=false;
for(int j=0; j<groups.size();j++){
if(db->Entries[i].GroupID == groups[j]){IsInAnyGroup=true; break;}}
if(db->entry(i).GroupID == groups[j]){IsInAnyGroup=true; break;}}
if(!IsInAnyGroup)continue;
}
else
if(db->Entries[i].GroupID != group->ID)continue;
if(db->entry(i).GroupID != group->ID)continue;
}
bool hit=false;
if(checkBox_Title->isChecked()) hit=hit||search(db->Entries[i].Title);
if(checkBox_Username->isChecked()) hit=hit||search(db->Entries[i].UserName);
if(checkBox_URL->isChecked()) hit=hit||search(db->Entries[i].URL);
if(checkBox_Comment->isChecked()) hit=hit||search(db->Entries[i].Additional);
if(checkBox_Attachment->isChecked()) hit=hit||search(db->Entries[i].BinaryDesc);
db->Entries[i].Password.unlock();
if(checkBox_Password->isChecked()) hit=hit||search(db->Entries[i].Password.string());
db->Entries[i].Password.lock();
if(hit)Hits.push_back(db->Entries[i].sID);
if(checkBox_Title->isChecked()) hit=hit||search(db->entry(i).Title);
if(checkBox_Username->isChecked()) hit=hit||search(db->entry(i).UserName);
if(checkBox_URL->isChecked()) hit=hit||search(db->entry(i).URL);
if(checkBox_Comment->isChecked()) hit=hit||search(db->entry(i).Additional);
if(checkBox_Attachment->isChecked()) hit=hit||search(db->entry(i).BinaryDesc);
db->entry(i).Password.unlock();
if(checkBox_Password->isChecked()) hit=hit||search(db->entry(i).Password.string());
db->entry(i).Password.lock();
if(hit)Hits.push_back(db->entry(i).sID);
}
done(1);

@ -27,7 +27,7 @@ class CSearchDlg : public QDialog, public Ui_Search_Dlg
{
Q_OBJECT
public:
CSearchDlg(PwDatabase* _db, CGroup* pGroup=NULL,QWidget* parent = 0, const char* name = 0,
CSearchDlg(Database* _db, CGroup* pGroup=NULL,QWidget* parent = 0, const char* name = 0,
bool modal = FALSE, Qt::WFlags fl = 0 );
~CSearchDlg();
QList<Q_UINT32> Hits;
@ -40,7 +40,7 @@ private:
QString txt;
CGroup* group;
bool regexp;
PwDatabase* db;
Database* db;
bool search(const QString& str);
};

@ -36,25 +36,25 @@ QString GroupTemplate=QString("\n\
*** Group: %1 ***\n\
");
bool Export_Txt::exportFile(const QString& filename,PwDatabase* db,QString& err){
bool Export_Txt::exportFile(const QString& filename,Database* db,QString& err){
QFile file(filename);
if(!file.open(QIODevice::Truncate | QIODevice::WriteOnly)){
err+=tr("Could not open file (FileError=%1)").arg(file.error());
return false;
}
for(int g=0;g<db->Groups.size();g++){
file.write(GroupTemplate.arg(db->Groups[g].Name).utf8());
for(int e=0;e<db->Entries.size();e++){
if(db->Groups[g].ID==db->Entries[e].GroupID){
db->Entries[e].Password.unlock();
file.write(EntryTemplate.arg(db->Entries[e].Title)
.arg(db->Entries[e].UserName)
.arg(db->Entries[e].URL)
.arg(db->Entries[e].Password.string())
.arg(db->Entries[e].Additional.replace('\n',"\n "))
for(int g=0;g<db->numGroups();g++){
file.write(GroupTemplate.arg(db->group(g).Name).utf8());
for(int e=0;e<db->numEntries();e++){
if(db->group(g).ID==db->entry(e).GroupID){
db->entry(e).Password.unlock();
file.write(EntryTemplate.arg(db->entry(e).Title)
.arg(db->entry(e).UserName)
.arg(db->entry(e).URL)
.arg(db->entry(e).Password.string())
.arg(db->entry(e).Additional.replace('\n',"\n "))
.utf8());
db->Entries[e].Password.lock();
db->entry(e).Password.lock();
}
}
}

@ -24,7 +24,7 @@
class Export_Txt:public QObject{
public:
bool exportFile(const QString& filename,PwDatabase* db,QString& err);
bool exportFile(const QString& filename,Database* db,QString& err);
};

@ -25,7 +25,7 @@
#include <qdom.h>
using namespace std;
bool Import_KWalletXml::importFile(QString FileName,PwDatabase* pwm,QString& err){
bool Import_KWalletXml::importFile(QString FileName,Database* pwm,QString& err){
QFile file(FileName);
if(!file.exists()){
err+=QObject::tr("File not found.");

@ -24,7 +24,7 @@
class Import_KWalletXml{
public:
bool importFile(QString FileName,PwDatabase* db,QString& err);
bool importFile(QString FileName,Database* db,QString& err);
private:
};

@ -27,7 +27,7 @@
#include "Import_PwManager.h"
using namespace std;
bool Import_PwManager::importFile(QString filename, QString password, PwDatabase* db, QString& err){
bool Import_PwManager::importFile(QString filename, QString password, Database* db, QString& err){
database=db;
QFile file(filename);
char* buffer=NULL;

@ -26,13 +26,13 @@
class Import_PwManager{
public:
bool importFile(QString FileName, QString Password,PwDatabase* db,QString& err);
bool importFile(QString FileName, QString Password,Database* db,QString& err);
private:
bool KeyFlag; // true=Password, false=Chipcard
int Compression; // 0=none, 1=gzip, 2=bzip2
unsigned char KeyHash[20];
unsigned char DataHash[20];
PwDatabase* database;
Database* database;
bool parseXmlContent(char* content);
bool xml_parseEntryAttributes(QDomElement* EntryTag,CGroup* parent);

@ -104,9 +104,9 @@ Items.clear();
if(!db)return;
if(!GroupID)return;
CurrentGroup=GroupID;
for(int i=0;i<db->Entries.size();i++){
if(db->Entries[i].GroupID==GroupID)
setEntry(&db->Entries[i]);
for(int i=0;i<db->numEntries();i++){
if(db->entry(i).GroupID==GroupID)
setEntry(&db->entry(i));
}
}
@ -115,9 +115,9 @@ IsSearchGroup=true;
clear();
Items.clear();
for(int j=0; j<results.size(); j++){
for(int i=0; i<db->Entries.size();i++){
if(db->Entries[i].sID == results[j])
setEntry(&db->Entries[i]);
for(int i=0; i<db->numEntries();i++){
if(db->entry(i).sID == results[j])
setEntry(&db->entry(i));
}
}
}

@ -41,7 +41,7 @@ public:
void updateColumns();
void refreshItems();
void showSearchResults(QList<Q_UINT32>& results);
PwDatabase* db;
Database* db;
vector<EntryViewItem*>Items;
QMenu *ContextMenu;
private:

@ -209,29 +209,29 @@ void KeepassGroupView::updateItems(){
clear();
Items.clear();
for(int i=0; i<db->Groups.size();i++){
if(db->Groups[i].Level==0){
for(int i=0; i<db->numGroups();i++){
if(db->group(i).Level==0){
if(Items.size()) Items.push_back(new GroupViewItem(this,getLastSameLevelItem(0)));
else Items.push_back(new GroupViewItem(this));
Items.back()->setText(0,db->Groups[i].Name);
Items.back()->pGroup=&db->Groups[i];
Items.back()->setText(0,db->group(i).Name);
Items.back()->pGroup=&db->group(i);
}
else{
if(db->Groups[i].Level>db->Groups[i-1].Level){
Items.push_back(new GroupViewItem(Items.back(),getLastSameLevelItem(db->Groups[i].Level)));
Items.back()->setText(0,db->Groups[i].Name);
Items.back()->pGroup=&db->Groups[i];
if(db->group(i).Level>db->group(i-1).Level){
Items.push_back(new GroupViewItem(Items.back(),getLastSameLevelItem(db->group(i).Level)));
Items.back()->setText(0,db->group(i).Name);
Items.back()->pGroup=&db->group(i);
}
if(db->Groups[i].Level<=db->Groups[i-1].Level){
if(db->group(i).Level<=db->group(i-1).Level){
GroupItemItr j;
for(j=Items.end()-1;j!=Items.begin();j--){
if((*j)->pGroup->Level<db->Groups[i].Level)break;}
Items.push_back(new GroupViewItem((*j),getLastSameLevelItem(db->Groups[i].Level)));
Items.back()->setText(0,db->Groups[i].Name);
Items.back()->pGroup=&db->Groups[i];
if((*j)->pGroup->Level<db->group(i).Level)break;}
Items.push_back(new GroupViewItem((*j),getLastSameLevelItem(db->group(i).Level)));
Items.back()->setText(0,db->group(i).Name);
Items.back()->pGroup=&db->group(i);
}
}
Items.back()->setIcon(0,EntryIcons[db->Groups[i].ImageID]);
Items.back()->setIcon(0,EntryIcons[db->group(i).ImageID]);
}
for(int i=0;i<Items.size();i++){

@ -35,7 +35,7 @@ public:
void updateItems();
bool isSearchResultGroup(GroupViewItem* item);
void selectSearchGroup();
PwDatabase *db;
Database *db;
bool ShowSearchGroup; //needs a "updateItems()" after a change!
vector<GroupViewItem*>Items;
QMenu *ContextMenu;

@ -464,7 +464,7 @@ if(EntryView->selectedItems().size()!=1){
CEntry& entry=*((EntryViewItem*)(EntryView->selectedItems()[0]))->pEntry;
QString str=tr("<B>Group: </B>%1 <B>Title: </B>%2 <B>Username: </B>%3 <B>URL: </B><a href=%4>%4</a> <B>Password: </B>%5 <B>Creation: </B>%6 <B>Last Change: </B>%7 <B>LastAccess: </B>%8 <B>Expires: </B>%9");
//todo: a "CGroup* PwDatabase::getGroup(CEntry*)" method would be a good idea
str=str.arg(db->Groups[db->getGroupIndex(entry.GroupID)].Name).arg(entry.Title);
str=str.arg(db->group(db->getGroupIndex(entry.GroupID)).Name).arg(entry.Title);
if(!config.ListView_HideUsernames) str=str.arg(entry.UserName);
else str=str.arg("****");
@ -626,7 +626,6 @@ if(filename==QString())return;
Export_Txt exp;
QString err;
exp.exportFile(filename,db,err);
}
void KeepassMainWindow::OnImportFromPwm(){

@ -49,7 +49,7 @@ class KeepassMainWindow : public QMainWindow, public Ui_MainWindow{
Q_OBJECT
public:
KeepassMainWindow (const QString& ArgFile,QWidget *parent=0, Qt::WFlags flags=0);
PwDatabase* db;
Database* db;
bool Start;
signals: