First commit for 0.2.3, some old functions still need to be ported to the new back-end api, i.e. import and export.

git-svn-id: https://svn.code.sf.net/p/keepassx/code/trunk@104 b624d157-de02-0410-bad0-e51aec6abb33
This commit is contained in:
tarek_saidi
2006-10-14 22:33:41 +00:00
parent 0286b87a41
commit 21f0fea56a
67 changed files with 8909 additions and 6954 deletions

View File

@@ -42,7 +42,7 @@ typedef struct tKeysymMap{
class AutoType:public QObject{
public:
static QWidget* MainWin;
static void perform(CEntry* entry,QString& errors);
static void perform(IEntryHandle* entry,QString& errors);
private:
#ifdef Q_WS_X11
static tKeysymMap KeysymMap[];
@@ -50,7 +50,7 @@ private:
static int getModifiers(Display*,KeySym,int);
static void pressModifiers(Display*,int,bool Press=true);
static void releaseModifiers(Display*,int);
static void templateToKeysyms(const QString& Template, QList<quint16>& KeySymList,CEntry* entry);
static void templateToKeysyms(const QString& Template, QList<quint16>& KeySymList,IEntryHandle* entry);
static void stringToKeysyms(const QString& string,QList<quint16>& KeySymList);
#endif

View File

@@ -23,9 +23,9 @@
QWidget* AutoType::MainWin=NULL;
void AutoType::perform(CEntry* entry, QString& err){
void AutoType::perform(IEntryHandle* entry, QString& err){
QString str;
QMessageBox::warning(NULL,tr("Error"),"This feature is not available under Windows");
}
}

View File

@@ -65,26 +65,28 @@ switch(mods){
}
void AutoType::perform(CEntry* entry, QString& err){
void AutoType::perform(IEntryHandle* entry, QString& err){
struct timespec timeOut,remains;
timeOut.tv_sec = 0;
timeOut.tv_nsec = 300000000; /* 300 milliseconds */
timeOut.tv_nsec = 30000000; /* 300 milliseconds */
for(int i=0;i<10;i++)nanosleep(&timeOut, &remains);
QString str;
int c=entry->Additional.count("Auto-Type:");
QString comment=entry->comment();
int c=comment.count("Auto-Type:");
if(c>1){
err=tr("More than one 'Auto-Type:' key sequence found.\nAllowed is only one per entry.");
return;}
if(c==1){
int start=entry->Additional.indexOf("Auto-Type:")+10;
int start=comment.indexOf("Auto-Type:")+10;
int len;
if(entry->Additional.size()==10)return;
for(len=0;len<entry->Additional.size();len++){
if(entry->Additional.size()==(start+len))break;
if(entry->Additional.at(start+len)==QChar('\n'))break;}
if(comment.size()==10)return;
for(len=0;len<comment.size();len++){
if(comment.size()==(start+len))break;
if(comment.at(start+len)==QChar('\n'))break;
}
if(!len)return;
str=entry->Additional.mid(start,len);
str=comment.mid(start,len);
}
else
str="{USERNAME}{TAB}{PASSWORD}{ENTER}";
@@ -125,21 +127,21 @@ XCloseDisplay(pDisplay);
MainWin->show();
}
void AutoType::templateToKeysyms(const QString& tmpl, QList<quint16>& keys,CEntry* entry){
void AutoType::templateToKeysyms(const QString& tmpl, QList<quint16>& keys,IEntryHandle* entry){
//tmpl must be lower case!!!
if(!tmpl.compare("title")){
stringToKeysyms(entry->Title,keys);
stringToKeysyms(entry->title(),keys);
return;}
if(!tmpl.compare("username")){
stringToKeysyms(entry->UserName,keys);
stringToKeysyms(entry->username(),keys);
return;}
if(!tmpl.compare("url")){
stringToKeysyms(entry->URL,keys);
stringToKeysyms(entry->url(),keys);
return;}
if(!tmpl.compare("password")){
entry->Password.unlock();
stringToKeysyms(entry->Password.string(),keys);
entry->Password.lock();
SecString password=entry->password();
password.unlock();
stringToKeysyms(password,keys);
return;
}
if(!tmpl.compare("space")){
@@ -1163,7 +1165,7 @@ return 0;
#ifdef Q_WS_MAC
#include <QMessageBox>
void AutoType::perform(CEntry* entry, QString& err){
void AutoType::perform(IEntryHandle* entry, QString& err){
QMessageBox::warning(NULL,"AutoType","Sorry, but Auto-Type does not work under Mac OS X yet.","OK");
}
#endif

View File

@@ -32,148 +32,297 @@
#include "main.h"
#include "PwmConfig.h"
#include "EntryView.h"
#include "dialogs/EditEntryDlg.h"
#include "lib/AutoType.h"
KeepassEntryView::KeepassEntryView(QWidget* parent):QTreeWidget(parent){
AutoResizeColumns=true;
IsSearchGroup=false;
int sum=0;
for(int i=0;i<NUM_COLUMNS;i++)
sum+=config.ColumnSizes[i];
for(int i=0;i<NUM_COLUMNS;i++)
ColumnSizes << (float)config.ColumnSizes[i]/(float)sum;
CurrentGroup=0;
updateColumns();
header()->setResizeMode(QHeaderView::Interactive);
header()->setStretchLastSection(false);
connect(header(),SIGNAL(sectionResized(int,int,int)),this,SLOT(OnColumnResized(int,int,int)));
ContextMenu=new QMenu(this);
setAlternatingRowColors(config.AlternatingRowColors);
AutoResizeColumns=true;
int sum=0;
for(int i=0;i<NUM_COLUMNS;i++)
sum+=config.ColumnSizes[i];
for(int i=0;i<NUM_COLUMNS;i++)
ColumnSizes << (float)config.ColumnSizes[i]/(float)sum;
updateColumns();
header()->setResizeMode(QHeaderView::Interactive);
header()->setStretchLastSection(false);
connect(header(),SIGNAL(sectionResized(int,int,int)),this,SLOT(OnColumnResized(int,int,int)));
connect(this,SIGNAL(itemSelectionChanged()),this,SLOT(OnItemsChanged()));
connect(&ClipboardTimer, SIGNAL(timeout()), this, SLOT(OnClipboardTimeOut()));
Clipboard=QApplication::clipboard();
ContextMenu=new QMenu(this);
setAlternatingRowColors(config.AlternatingRowColors);
}
KeepassEntryView::~KeepassEntryView(){
for(int i=0;i<ColumnSizes.size();i++){
config.ColumnSizes[i]=(int)(ColumnSizes[i]*10000.0f);
for(int i=0;i<ColumnSizes.size();i++){
config.ColumnSizes[i]=(int)(ColumnSizes[i]*10000.0f);
}
}
void KeepassEntryView::OnGroupChanged(IGroupHandle* group){
CurrentGroup=group;
showGroup(group);
}
void KeepassEntryView::OnShowSearchResults(){
CurrentGroup=NULL;
showSearchResults();
}
void KeepassEntryView::OnItemsChanged(){
switch(selectedItems().size()){
case 0: emit selectionChanged(NONE);
break;
case 1: emit selectionChanged(SINGLE);
break;
default:emit selectionChanged(MULTIPLE);
}
}
void KeepassEntryView::OnSaveAttachment(){
Q_ASSERT(selectedItems().size()==1);
CEditEntryDlg::saveAttachment(((EntryViewItem*)selectedItems()[0])->EntryHandle,this);
}
void KeepassEntryView::OnCloneEntry(){
QList<QTreeWidgetItem*> entries=selectedItems();
for(int i=0; i<entries.size();i++){
Items.append(new EntryViewItem(this));
Items.back()->EntryHandle=
db->cloneEntry(((EntryViewItem*)entries[i])->EntryHandle);
updateEntry(Items.back());
}
emit fileModified();
}
void KeepassEntryView::OnDeleteEntry(){
QList<QTreeWidgetItem*> entries=selectedItems();
for(int i=0; i<entries.size();i++){
db->deleteEntry(((EntryViewItem*)entries[i])->EntryHandle);
Items.removeAt(Items.indexOf((EntryViewItem*)entries[i]));
delete entries[i];
}
emit fileModified();
}
void KeepassEntryView::updateEntry(EntryViewItem* item){
IEntryHandle* entry = item->EntryHandle;
int j=0;
if(config.Columns[0])item->setText(j++,entry->title());
if(config.Columns[1]){
if(config.ListView_HideUsernames)
item->setText(j++,"******");
else
item->setText(j++,entry->username());}
if(config.Columns[2]){item->setText(j++,entry->url());}
if(config.Columns[3]){
if(config.ListView_HidePasswords)
item->setText(j++,"******");
else{
SecString password=entry->password();
password.unlock();
item->setText(j++,password.string());
}
}
if(config.Columns[4]){
item->setText(j++,entry->comment().section('\n',0,0));}
if(config.Columns[5]){
item->setText(j++,entry->expire().dateToString(Qt::LocalDate));}
if(config.Columns[6]){
item->setText(j++,entry->creation().dateToString(Qt::LocalDate));}
if(config.Columns[7]){
item->setText(j++,entry->lastMod().dateToString(Qt::LocalDate));}
if(config.Columns[8]){
item->setText(j++,entry->lastAccess().dateToString(Qt::LocalDate));}
if(config.Columns[9]){
item->setText(j++,entry->binaryDesc());}
item->setIcon(0,db->icon(entry->image()));
}
void KeepassEntryView::editEntry(EntryViewItem* item){
CEditEntryDlg dlg(db,item->EntryHandle,this,true);
switch(dlg.exec()){
case 0: //canceled or no changes
break;
case 1: //modifications but same group
updateEntry(item);
emit fileModified();
break;
case 2: //entry moved to another group
delete item;
Items.removeAt(Items.indexOf(item));
emit fileModified();
break;
}
}
void KeepassEntryView::OnNewEntry(){
IEntryHandle* NewEntry=db->newEntry(CurrentGroup);
CEditEntryDlg dlg(db,NewEntry,this,true);
if(!dlg.exec()){
db->deleteLastEntry();
}
else{
Items.append(new EntryViewItem(this));
Items.back()->EntryHandle=NewEntry;
updateEntry(Items.back());
emit fileModified();
}
}
void KeepassEntryView::OnEntryActivated(QTreeWidgetItem* item,int Column){
int i=0;
int c=-1;
for(i;i<NUM_COLUMNS;i++){
if(config.Columns[i])c++;
if(c==Column)break;
}
if(c==-1)return;
switch(i){
case 0: editEntry((EntryViewItem*)item);
break;
case 1: OnUsernameToClipboard();
break;
case 2: //OnEditOpenUrl();
break;
case 3: OnPasswordToClipboard();
break;
}
}
void KeepassEntryView::OnEditEntry(){
Q_ASSERT(selectedItems().size()==1);
editEntry((EntryViewItem*)selectedItems()[0]);
}
void KeepassEntryView::OnUsernameToClipboard(){
Clipboard->setText(((EntryViewItem*)selectedItems()[0])->EntryHandle->username(), QClipboard::Clipboard);
ClipboardTimer.setSingleShot(true);
ClipboardTimer.start(config.ClipboardTimeOut*1000);
}
void KeepassEntryView::OnPasswordToClipboard(){
SecString password;
password=((EntryViewItem*)selectedItems()[0])->EntryHandle->password();
password.unlock();
Clipboard->setText(password.string(),QClipboard::Clipboard);
ClipboardTimer.setSingleShot(true);
ClipboardTimer.start(config.ClipboardTimeOut*1000);
}
void KeepassEntryView::OnClipboardTimeOut(){
Clipboard->clear(QClipboard::Clipboard);
}
void KeepassEntryView::contextMenuEvent(QContextMenuEvent* e){
if(itemAt(e->pos())){
EntryViewItem* item=(EntryViewItem*)itemAt(e->pos());
if(selectedItems().size()==0){
setItemSelected(item,true);}
else{
bool AlreadySelected=false;
for(int i=0;i<selectedItems().size();i++){
if(selectedItems()[i]==item){AlreadySelected=true; break;}
}
if(!AlreadySelected){
while(selectedItems().size()){
setItemSelected(selectedItems()[0],false);
}
if(itemAt(e->pos())){
EntryViewItem* item=(EntryViewItem*)itemAt(e->pos());
if(selectedItems().size()==0){
setItemSelected(item,true);
}
else{
if(!isItemSelected(item)){
while(selectedItems().size()){
setItemSelected(selectedItems()[0],false);
}
setItemSelected(item,true);
}
}
}
}
else
{while(selectedItems().size()){
setItemSelected(selectedItems()[0],false);}
}
e->accept();
ContextMenu->popup(e->globalPos());
else
{while(selectedItems().size()){
setItemSelected(selectedItems()[0],false);}
}
e->accept();
ContextMenu->popup(e->globalPos());
}
void KeepassEntryView::resizeEvent(QResizeEvent* e){
resizeColumns();
e->accept();
}
void KeepassEntryView::updateItems(){
updateItems(CurrentGroup);
resizeColumns();
e->accept();
}
void KeepassEntryView::updateItems(unsigned int GroupID){
QList<QTreeWidgetItem*> ItemSelec=selectedItems();
QList<quint32> SelectionIDs;
for(int i=0; i<ItemSelec.size(); i++)
SelectionIDs << ((EntryViewItem*)ItemSelec[i])->pEntry->sID;
IsSearchGroup=false;
clear();
Items.clear();
if(!db)return;
if(!GroupID)return;
CurrentGroup=GroupID;
for(int i=0;i<db->numEntries();i++){
if(db->entry(i).GroupID==GroupID)
setEntry(&db->entry(i));
void KeepassEntryView::showSearchResults(){
clear();
Items.clear();
createItems(SearchResults);
}
if(SelectionIDs.size())
void KeepassEntryView::showGroup(IGroupHandle* group){
clear();
Items.clear();
if(group==NULL)return;
QList<IEntryHandle*>entries=db->entries(group);
createItems(entries);
}
void KeepassEntryView::createItems(QList<IEntryHandle*>& entries){
for(int i=0;i<entries.size();i++){
if(!entries[i]->isValid())continue;
EntryViewItem* item=new EntryViewItem(this);
Items.push_back(item);
Items.back()->EntryHandle=entries[i];
int j=0;
if(config.Columns[0])item->setText(j++,entries[i]->title());
if(config.Columns[1]){
if(config.ListView_HideUsernames)
item->setText(j++,"******");
else
item->setText(j++,entries[i]->username());}
if(config.Columns[2]){item->setText(j++,entries[i]->url());}
if(config.Columns[3]){
if(config.ListView_HidePasswords)
item->setText(j++,"******");
else{
SecString password=entries[i]->password();
password.unlock();
item->setText(j++,password.string());
}
}
if(config.Columns[4]){
item->setText(j++,entries[i]->comment().section('\n',0,0));}
if(config.Columns[5]){
item->setText(j++,entries[i]->expire().dateToString(Qt::LocalDate));}
if(config.Columns[6]){
item->setText(j++,entries[i]->creation().dateToString(Qt::LocalDate));}
if(config.Columns[7]){
item->setText(j++,entries[i]->lastMod().dateToString(Qt::LocalDate));}
if(config.Columns[8]){
item->setText(j++,entries[i]->lastAccess().dateToString(Qt::LocalDate));}
if(config.Columns[9]){
item->setText(j++,entries[i]->binaryDesc());}
Items.back()->setIcon(0,db->icon(entries[i]->image()));
}
}
void KeepassEntryView::updateIcons(){
for(int i=0;i<Items.size();i++){
for(int j=0; j<SelectionIDs.size();j++){
if(Items[i]->pEntry->sID==SelectionIDs[j]) setItemSelected(Items[i],true);}
}
Items[i]->setIcon(0,db->icon(Items[i]->EntryHandle->image()));
}
}
void KeepassEntryView::showSearchResults(QList<quint32>& results){
IsSearchGroup=true;
clear();
Items.clear();
for(int j=0; j<results.size(); j++){
for(int i=0; i<db->numEntries();i++){
if(db->entry(i).sID == results[j])
setEntry(&db->entry(i));
}
}
}
void KeepassEntryView::setEntry(CEntry* entry){
EntryViewItem* tmp=NULL;
Items.push_back(tmp=new EntryViewItem(this));
Items.back()->pEntry=entry;
int j=0;
if(config.Columns[0]){
tmp->setText(j++,entry->Title);}
if(config.Columns[1]){
if(config.ListView_HideUsernames)
tmp->setText(j++,"******");
else
tmp->setText(j++,entry->UserName);}
if(config.Columns[2]){
tmp->setText(j++,entry->URL);}
if(config.Columns[3]){
if(config.ListView_HidePasswords)
tmp->setText(j++,"******");
else{
entry->Password.unlock();
tmp->setText(j++,entry->Password.string());
entry->Password.lock();}}
if(config.Columns[4]){
tmp->setText(j++,entry->Additional.section('\n',0,0));}
if(config.Columns[5]){
tmp->setText(j++,entry->Expire.dateToString(Qt::LocalDate));}
if(config.Columns[6]){
tmp->setText(j++,entry->Creation.dateToString(Qt::LocalDate));}
if(config.Columns[7]){
tmp->setText(j++,entry->LastMod.dateToString(Qt::LocalDate));}
if(config.Columns[8]){
tmp->setText(j++,entry->LastAccess.dateToString(Qt::LocalDate));}
if(config.Columns[9]){
tmp->setText(j++,entry->BinaryDesc);}
Items.back()->setIcon(0,db->icon(entry->ImageID));
}
void KeepassEntryView::setEntry(IEntryHandle* entry){
}
/*
void KeepassEntryView::refreshItems(){
EntryViewItem *tmp=NULL;
for(int i=0;i<Items.size();i++){
tmp=Items[i];
CEntry* entry=tmp->pEntry;
IEntryHandle* entry=tmp->pEntry;
int j=0;
if(config.Columns[0]){
@@ -206,34 +355,34 @@ for(int i=0;i<Items.size();i++){
tmp->setText(j++,entry->BinaryDesc);}
tmp->setIcon(0,db->icon(entry->ImageID));
}
}
}*/
void KeepassEntryView::updateColumns(){
setColumnCount(0);
QStringList cols;
if(config.Columns[0]){
cols << tr("Title");}
if(config.Columns[1]){
cols << tr("Username");}
if(config.Columns[2]){
cols << tr("URL");}
if(config.Columns[3]){
cols << tr("Password");}
if(config.Columns[4]){
cols << tr("Comments");}
if(config.Columns[5]){
cols << tr("Expires");}
if(config.Columns[6]){
cols << tr("Creation");}
if(config.Columns[7]){
cols << tr("Last Change");}
if(config.Columns[8]){
cols << tr("Last Access");}
if(config.Columns[9]){
cols << tr("Attachment");}
setHeaderLabels(cols);
resizeColumns();
setColumnCount(0);
QStringList cols;
if(config.Columns[0]){
cols << tr("Title");}
if(config.Columns[1]){
cols << tr("Username");}
if(config.Columns[2]){
cols << tr("URL");}
if(config.Columns[3]){
cols << tr("Password");}
if(config.Columns[4]){
cols << tr("Comments");}
if(config.Columns[5]){
cols << tr("Expires");}
if(config.Columns[6]){
cols << tr("Creation");}
if(config.Columns[7]){
cols << tr("Last Change");}
if(config.Columns[8]){
cols << tr("Last Access");}
if(config.Columns[9]){
cols << tr("Attachment");}
setHeaderLabels(cols);
resizeColumns();
}
void KeepassEntryView::resizeColumns(){
@@ -315,6 +464,7 @@ QTreeWidget::mousePressEvent(event);
}
void KeepassEntryView::mouseMoveEvent(QMouseEvent *event){
/*
if(IsSearchGroup)
return;
if (!(event->buttons() & Qt::LeftButton))
@@ -365,8 +515,14 @@ mimeData->setData("keepass/entry",QByteArray((char*)&pDragItems,sizeof(void*)));
drag->setMimeData(mimeData);
drag->setPixmap(DragPixmap);
drag->start();
*/
}
void KeepassEntryView::OnAutoType(){
Q_ASSERT(selectedItems().size()==1);
QString error;
AutoType::perform(((EntryViewItem*)selectedItems()[0])->EntryHandle,error);
}
void KeepassEntryView::paintEvent(QPaintEvent * event){
QTreeWidget::paintEvent(event);
@@ -391,30 +547,34 @@ EntryViewItem::EntryViewItem(QTreeWidgetItem *parent, QTreeWidgetItem *preceding
bool EntryViewItem::operator<(const QTreeWidgetItem& other)const{
int SortCol=treeWidget()->sortColumn();
if(SortCol < 5 || SortCol==9){ //columns with string values (Title, Username, Password, URL, Comment)
if(QString::localeAwareCompare(text(SortCol),other.text(SortCol)) < 0)
return true;
else
return false;
}
QDateTime *DateThis;
QDateTime *DateOther;
switch(SortCol){
case 5: DateThis=&pEntry->Expire;
DateOther=&((EntryViewItem&)other).pEntry->Expire;
break;
case 6: DateThis=&pEntry->Creation;
DateOther=&((EntryViewItem&)other).pEntry->Creation;
break;
case 7: DateThis=&pEntry->LastMod;
DateOther=&((EntryViewItem&)other).pEntry->LastMod;
break;
case 8: DateThis=&pEntry->LastAccess;
DateOther=&((EntryViewItem&)other).pEntry->LastAccess;
break;
default:Q_ASSERT(false);
}
return *DateThis < *DateOther;
int SortCol=treeWidget()->sortColumn();
if(SortCol < 5 || SortCol==9){ //columns with string values (Title, Username, Password, URL, Comment)
if(QString::localeAwareCompare(text(SortCol),other.text(SortCol)) < 0)
return true;
else
return false;
}
QDateTime DateThis;
QDateTime DateOther;
//@NICHTVERGESSEN
return false;
/*
switch(SortCol){
case 5: DateThis=&pEntry->Expire;
DateOther=&((EntryViewItem&)other).pEntry->Expire;
break;
case 6: DateThis=&pEntry->Creation;
DateOther=&((EntryViewItem&)other).pEntry->Creation;
break;
case 7: DateThis=&pEntry->LastMod;
DateOther=&((EntryViewItem&)other).pEntry->LastMod;
break;
case 8: DateThis=&pEntry->LastAccess;
DateOther=&((EntryViewItem&)other).pEntry->LastAccess;
break;
default:Q_ASSERT(false);
}
return DateThis < DateOther;
*/
}

View File

@@ -25,55 +25,79 @@
#include <QTreeWidget>
#include <QContextMenuEvent>
#include <QHeaderView>
#include "../PwManager.h"
#include <QTimer>
#include <QClipboard>
#include "../StandardDatabase.h"
#define NUM_COLUMNS 10
class EntryViewItem;
enum SelectionState{NONE,SINGLE,MULTIPLE,SEARCHGROUP};
class KeepassEntryView:public QTreeWidget{
Q_OBJECT
public:
KeepassEntryView(QWidget* parent=0);
~KeepassEntryView();
void updateItems(unsigned int group);
void updateColumns();
void refreshItems();
void showSearchResults(QList<quint32>& results);
Database* db;
vector<EntryViewItem*>Items;
QMenu *ContextMenu;
private:
void setEntry(CEntry* entry);
int CurrentGroup;
QList<float>ColumnSizes;
void resizeColumns();
bool AutoResizeColumns;
QPoint DragStartPos;
QList<QTreeWidgetItem*> DragItems;
QPixmap DragPixmap;
bool IsSearchGroup;
protected:
virtual void contextMenuEvent(QContextMenuEvent *event);
virtual void paintEvent(QPaintEvent* event);
virtual void resizeEvent(QResizeEvent* event);
virtual void mousePressEvent(QMouseEvent *event);
virtual void mouseMoveEvent(QMouseEvent *event);
public slots:
void OnColumnResized(int index,int OldSize, int NewSize);
void updateItems();
Q_OBJECT
public:
KeepassEntryView(QWidget* parent=0);
~KeepassEntryView();
void showSearchResults();
void showGroup(IGroupHandle* group);
void updateColumns();
// void showSearchResults(QList<quint32>& results);
IDatabase* db;
QList<EntryViewItem*>Items;
QList<IEntryHandle*> SearchResults;
QMenu *ContextMenu;
private:
void setEntry(IEntryHandle* entry);
void updateEntry(EntryViewItem*);
void editEntry(EntryViewItem*);
void createItems(QList<IEntryHandle*>& entries);
QClipboard* Clipboard;
QTimer ClipboardTimer;
QList<float>ColumnSizes;
void resizeColumns();
bool AutoResizeColumns;
QPoint DragStartPos;
QList<QTreeWidgetItem*> DragItems;
QPixmap DragPixmap;
IGroupHandle* CurrentGroup;
virtual void contextMenuEvent(QContextMenuEvent *event);
virtual void paintEvent(QPaintEvent* event);
virtual void resizeEvent(QResizeEvent* event);
virtual void mousePressEvent(QMouseEvent *event);
virtual void mouseMoveEvent(QMouseEvent *event);
public slots:
void OnColumnResized(int index,int OldSize, int NewSize);
void OnGroupChanged(IGroupHandle* group);
void OnShowSearchResults();
void OnEntryActivated(QTreeWidgetItem*,int);
void OnNewEntry();
void OnItemsChanged();
void updateIcons();
void OnUsernameToClipboard();
void OnPasswordToClipboard();
void OnEditEntry();
void OnClipboardTimeOut();
void OnCloneEntry();
void OnDeleteEntry();
void OnSaveAttachment();
void OnAutoType();
signals:
void fileModified();
void selectionChanged(SelectionState);
};
class EntryViewItem:public QTreeWidgetItem{
public:
EntryViewItem(QTreeWidget *parent);
EntryViewItem(QTreeWidget *parent, QTreeWidgetItem * preceding);
EntryViewItem(QTreeWidgetItem *parent);
EntryViewItem(QTreeWidgetItem *parent, QTreeWidgetItem * preceding);
CEntry* pEntry;
virtual bool operator<(const QTreeWidgetItem& other)const;
public:
EntryViewItem(QTreeWidget *parent);
EntryViewItem(QTreeWidget *parent, QTreeWidgetItem * preceding);
EntryViewItem(QTreeWidgetItem *parent);
EntryViewItem(QTreeWidgetItem *parent, QTreeWidgetItem * preceding);
IEntryHandle* EntryHandle;
virtual bool operator<(const QTreeWidgetItem& other)const;
};

View File

@@ -36,268 +36,371 @@
#include "main.h"
#include "EntryView.h"
#include "GroupView.h"
#include "dialogs/EditGroupDlg.h"
#define INSERT_AREA_WIDTH 4
KeepassGroupView::KeepassGroupView(QWidget* parent):QTreeWidget(parent){
InsertionMarker=QLine();
db=NULL;
LastHoverItem=NULL;
setHeaderLabels(QStringList()<<tr("Groups"));
ShowSearchGroup=false;
ContextMenu=new QMenu(this);
ContextMenuSearchGroup=new QMenu(this);
db=NULL;
setHeaderLabels(QStringList()<<tr("Groups"));
ContextMenu=new QMenu(this);
ContextMenuSearchGroup=new QMenu(this);
connect(this,SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),this,SLOT(OnCurrentGroupChanged(QTreeWidgetItem*,QTreeWidgetItem*)));
// connect(this,SIGNAL(itemExpanded(QTreeWidgetItem*)),this,SLOT(OnItemExpanded(QTreeWidgetItem*)));
// connect(this,SIGNAL(itemCollapsed(QTreeWidgetItem*)),this,SLOT(OnItemCollapsed(QTreeWidgetItem*)));
}
void KeepassGroupView::selectSearchGroup(){
Q_ASSERT(ShowSearchGroup);
setItemSelected(Items.back(),true);
}
void KeepassGroupView:: dragEnterEvent ( QDragEnterEvent * event ){
if(event->mimeData()->hasFormat("keepass/group")){
DragType=GROUP;
event->accept();
return;
}
if(event->mimeData()->hasFormat("keepass/entry")){
DragType=ENTRY;
event->accept();
return;
}
}
void KeepassGroupView::dragMoveEvent( QDragMoveEvent * event ){
GroupViewItem* item=(GroupViewItem*)itemAt(event->pos());
if(LastHoverItem){
QFont f=LastHoverItem->font(0);
f.setBold(false);
LastHoverItem->setFont(0,f);
}
QLine LastMarker=InsertionMarker;
InsertionMarker=QLine();
if(isSearchResultGroup(item))
event->setAccepted(false);
else
if(DragType==GROUP){
if(item){
QRect ItemRect=visualItemRect(item);
if(!db->isParentGroup(item->pGroup,DragItem->pGroup) && DragItem!=item){
if((ItemRect.height()+ItemRect.y())-event->pos().y() > INSERT_AREA_WIDTH && event->pos().y() > INSERT_AREA_WIDTH){
QFont f=item->font(0);
f.setBold(true);
item->setFont(0,f);
LastHoverItem=item;
event->setAccepted(true);
///@FIXME does not work for top level groups
}
else{
LastHoverItem=NULL;
if(event->pos().y() > INSERT_AREA_WIDTH)
InsertionMarker=QLine(ItemRect.x(),ItemRect.y()+ItemRect.height()
,ItemRect.x()+ItemRect.width(),ItemRect.y()+ItemRect.height());
else
InsertionMarker=QLine(ItemRect.x(),0,ItemRect.x()+ItemRect.width(),0);
}
void KeepassGroupView::createItems(){
clear();
Items.clear();
QList<IGroupHandle*> groups=db->groups();
for(int i=0;i<groups.size();i++){
if(groups[i]->parent()==NULL){
Items.append(new GroupViewItem(this));
Items.back()->setText(0,groups[i]->title());
Items.back()->GroupHandle=groups[i];
addChilds(Items.back());
}
else
event->setAccepted(false);
}
else
LastHoverItem=NULL;
}
else{
if(item){
QFont f=item->font(0);
f.setBold(true);
item->setFont(0,f);
LastHoverItem=item;
event->setAccepted(true);
for(int i=0;i<Items.size();i++){
Items[i]->setIcon(0,db->icon(Items[i]->GroupHandle->image()));
}
else{
event->setAccepted(false);
LastHoverItem=NULL;
}
}
if(!LastMarker.isNull()){
///@FIXME
//this is a very dirty work-around to force a redraw of items at the last marker position
//should be replaced!!!
GroupViewItem* i=(GroupViewItem*)itemAt(0,LastMarker.y1());
if(i)i->setFont(0,i->font(0));
i=(GroupViewItem*)itemAt(0,LastMarker.y1()-1);
if(i)i->setFont(0,i->font(0));
}
update();
SearchResultItem=new GroupViewItem();
SearchResultItem->setText(0,tr("Search Results"));
}
void KeepassGroupView:: dragLeaveEvent ( QDragLeaveEvent * event ){
InsertionMarker=QLine();
if(LastHoverItem){
QFont f=LastHoverItem->font(0);
f.setBold(false);
LastHoverItem->setFont(0,f);
void KeepassGroupView::updateIcons(){
for(int i=0;i<Items.size();i++){
Items[i]->setIcon(0,db->icon(Items[i]->GroupHandle->image()));
}
}
update();
void KeepassGroupView::showSearchResults(){
if(topLevelItem(topLevelItemCount()-1)!=SearchResultItem){
addTopLevelItem(SearchResultItem);
setCurrentItem(SearchResultItem);
}
emit searchResultsSelected();
}
void KeepassGroupView::addChilds(GroupViewItem* item){
QList<IGroupHandle*>childs=item->GroupHandle->childs();
if(!childs.size())
return;
for(int i=0; i<childs.size(); i++){
Items.push_back(new GroupViewItem(item));
Items.back()->setText(0,childs[i]->title());
Items.back()->GroupHandle=childs[i];
addChilds(Items.back());
}
}
void KeepassGroupView::OnDeleteGroup(){
GroupViewItem* item=(GroupViewItem*)currentItem();
if(item){
db->deleteGroup(item->GroupHandle);
delete item;
emit fileModified();
}
}
void KeepassGroupView::OnHideSearchResults(){
takeTopLevelItem(topLevelItemCount()-1);
}
void KeepassGroupView::OnNewGroup(){
GroupViewItem* parent=(GroupViewItem*)currentItem();
CGroup NewGroup;
CEditGroupDialog dlg(db,&NewGroup,parentWidget(),true);
if(dlg.exec()){
IGroupHandle* group;
if(parent){
group=db->addGroup(&NewGroup,parent->GroupHandle);
Items.append(new GroupViewItem(parent));
}
else{
if(topLevelItemCount()){
if(topLevelItem(topLevelItemCount()-1)==SearchResultItem)
Items.append(new GroupViewItem(this,topLevelItem(topLevelItemCount()-2)));
else
Items.append(new GroupViewItem(this,topLevelItem(topLevelItemCount()-1)));
}
else
Items.append(new GroupViewItem(this));
group=db->addGroup(&NewGroup,NULL);
}
Items.back()->GroupHandle=group;
Items.back()->setText(0,group->title());
Items.back()->setIcon(0,db->icon(group->image()));
}
emit fileModified();
}
void KeepassGroupView::OnEditGroup(){
GroupViewItem* item=(GroupViewItem*)currentItem();
CEditGroupDialog dlg(db,item->GroupHandle,parentWidget(),true);
int r=dlg.exec();
if(r){
item->setIcon(0,db->icon(item->GroupHandle->image()));
item->setText(0,item->GroupHandle->title());
if(r==2)emit fileModified();
}
}
void KeepassGroupView::contextMenuEvent(QContextMenuEvent* e){
if(!(GroupViewItem*)itemAt(e->pos()))
setCurrentItem(NULL);
e->accept();
if(currentItem()==SearchResultItem)
ContextMenuSearchGroup->popup(e->globalPos());
else
ContextMenu->popup(e->globalPos());
}
void KeepassGroupView::OnCurrentGroupChanged(QTreeWidgetItem* cur,QTreeWidgetItem* prev){
if(cur){
if(cur==SearchResultItem)
emit searchResultsSelected();
else
emit groupChanged(((GroupViewItem*)cur)->GroupHandle);
}
else
emit groupChanged(NULL);
}
void KeepassGroupView::dragEnterEvent ( QDragEnterEvent * event ){
LastHoverItem=NULL;
InsLinePos=-1;
if(event->mimeData()->hasFormat("application/x-keepassx")){
event->accept();
return;
}
}
void KeepassGroupView::dragLeaveEvent ( QDragLeaveEvent * event ){
if(LastHoverItem){
LastHoverItem->setBackgroundColor(0,QApplication::palette().color(QPalette::Base));
}
if(InsLinePos!=-1){
int RemoveLine=InsLinePos;
InsLinePos=-1;
viewport()->update(QRegion(0,RemoveLine-2,viewport()->width(),4));
}
}
void KeepassGroupView::dropEvent( QDropEvent * event ){
emit fileModified();
InsertionMarker=QLine();
if(LastHoverItem){
QFont f=LastHoverItem->font(0);
f.setBold(false);
LastHoverItem->setFont(0,f);
LastHoverItem=NULL;
}
GroupViewItem* item=(GroupViewItem*)itemAt(event->pos());
if(DragType==GROUP){
if(item){
QRect ItemRect=visualItemRect(item);
if((ItemRect.height()+ItemRect.y())-event->pos().y() > INSERT_AREA_WIDTH && event->pos().y() > INSERT_AREA_WIDTH){
db->moveGroup(DragItem->pGroup,item->pGroup);}
if(LastHoverItem){
LastHoverItem->setBackgroundColor(0,QApplication::palette().color(QPalette::Base));
}
if(InsLinePos!=-1){
int RemoveLine=InsLinePos;
InsLinePos=-1;
viewport()->update(QRegion(0,RemoveLine-2,viewport()->width(),4));
}
GroupViewItem* Item=(GroupViewItem*)itemAt(event->pos());
if(!Item){
qDebug("Append at the end");
db->moveGroup(DragItem->GroupHandle,NULL,-1);
if(DragItem->parent()){
DragItem->parent()->takeChild(DragItem->parent()->indexOfChild(DragItem));
}
else{
if(event->pos().y() > INSERT_AREA_WIDTH){
if(db->getNumberOfChilds(item->pGroup) > 0)
db->moveGroup(DragItem->pGroup,item->pGroup,0);
else
db->moveGroupDirectly(DragItem->pGroup,item->pGroup);
takeTopLevelItem(indexOfTopLevelItem(DragItem));
}
insertTopLevelItem(topLevelItemCount(),DragItem);
if(topLevelItemCount()>1){
if(topLevelItem(topLevelItemCount()-2)==SearchResultItem){
takeTopLevelItem(topLevelItemCount()-2);
insertTopLevelItem(topLevelItemCount(),SearchResultItem);
}
}
emit fileModified();
}
else{
QRect ItemRect=visualItemRect(Item);
if(event->pos().y()>ItemRect.y()+2 && event->pos().y()<ItemRect.y()+ItemRect.height()-2){
qDebug("Append as child of '%s'",((char*)Item->text(0).toUtf8().data()));
db->moveGroup(DragItem->GroupHandle,Item->GroupHandle,-1);
if(DragItem->parent()){
DragItem->parent()->takeChild(DragItem->parent()->indexOfChild(DragItem));
}
else db->moveGroupDirectly(DragItem->pGroup,NULL);
}
else{
takeTopLevelItem(indexOfTopLevelItem(DragItem));
}
Item->insertChild(Item->childCount(),DragItem);
emit fileModified();
}
else{
if(event->pos().y()>ItemRect.y()+2){
qDebug("Insert behind sibling '%s'",((char*)Item->text(0).toUtf8().data()));
if(DragItem->parent()){
DragItem->parent()->takeChild(DragItem->parent()->indexOfChild(DragItem));
}
else{
takeTopLevelItem(indexOfTopLevelItem(DragItem));
}
if(Item->parent()){
int index=Item->parent()->indexOfChild(Item)+1;
db->moveGroup(DragItem->GroupHandle,((GroupViewItem*)Item->parent())->GroupHandle,index);
Item->parent()->insertChild(index,DragItem);
}
else{
int index=indexOfTopLevelItem(Item)+1;
db->moveGroup(DragItem->GroupHandle,NULL,index);
insertTopLevelItem(index,DragItem);
}
emit fileModified();
}
else{
qDebug("Insert before sibling '%s'",((char*)Item->text(0).toUtf8().data()));
if(DragItem->parent()){
DragItem->parent()->takeChild(DragItem->parent()->indexOfChild(DragItem));
}
else{
takeTopLevelItem(indexOfTopLevelItem(DragItem));
}
if(Item->parent()){
int index=Item->parent()->indexOfChild(Item);
db->moveGroup(DragItem->GroupHandle,((GroupViewItem*)Item->parent())->GroupHandle,index);
Item->parent()->insertChild(index,DragItem);
}
else{
int index=indexOfTopLevelItem(Item);
db->moveGroup(DragItem->GroupHandle,NULL,index);
insertTopLevelItem(index,DragItem);
}
emit fileModified();
}
}
}
else db->moveGroup(DragItem->pGroup,NULL);
updateItems();
}else{
Q_ASSERT(item);
QList<QTreeWidgetItem*>* pDragItems=(QList<QTreeWidgetItem*>*)*((QList<QTreeWidgetItem*>**)event->mimeData()->data("keepass/entry").data());
for(int i=0;i<pDragItems->size();i++){
db->moveEntry(((EntryViewItem*)(*pDragItems)[i])->pEntry,item->pGroup);
}
emit entryDropped();
}
void KeepassGroupView::dragMoveEvent( QDragMoveEvent * event ){
if(DragItem){
GroupViewItem* Item=(GroupViewItem*)itemAt(event->pos());
if(!Item){
if(LastHoverItem){
LastHoverItem->setBackgroundColor(0,QApplication::palette().color(QPalette::Base));
LastHoverItem=NULL;
}
if(InsLinePos!=-1){
int RemoveLine=InsLinePos;
InsLinePos=-1;
viewport()->update(QRegion(0,RemoveLine-2,viewport()->width(),4));
}
event->accept();
return;
}
if(Item==DragItem || Item==SearchResultItem){
event->ignore();
return;
}
if(!db->isParent(DragItem->GroupHandle,Item->GroupHandle)){
QRect ItemRect=visualItemRect(Item);
if(event->pos().y()>ItemRect.y()+2 && event->pos().y()<ItemRect.y()+ItemRect.height()-2){
if(InsLinePos!=-1){
int RemoveLine=InsLinePos;
InsLinePos=-1;
viewport()->update(QRegion(0,RemoveLine-2,viewport()->width(),4));
}
if(LastHoverItem != Item){
if(LastHoverItem){
LastHoverItem->setBackgroundColor(0,QApplication::palette().color(QPalette::Base));
}
Item->setBackgroundColor(0,QApplication::palette().color(QPalette::Highlight));
LastHoverItem=Item;
}
}
else{
if(LastHoverItem){
LastHoverItem->setBackgroundColor(0,QApplication::palette().color(QPalette::Base));
LastHoverItem=NULL;
}
if(InsLinePos!=-1){
int RemoveLine=InsLinePos;
InsLinePos=-1;
viewport()->update(QRegion(0,RemoveLine-2,viewport()->width(),4));
}
if(event->pos().y()>ItemRect.y()+2){
InsLinePos=ItemRect.y()+ItemRect.height();
}
else{
InsLinePos=ItemRect.y();
}
InsLineStart=ItemRect.x();
viewport()->update(QRegion(0,InsLinePos-2,viewport()->width(),4));
}
event->accept();
return;
}
}
event->ignore();
}
void KeepassGroupView::paintEvent(QPaintEvent* event){
QTreeWidget::paintEvent(event);
if(InsLinePos != -1){
QPainter painter(viewport());
painter.setBrush(QBrush(QColor(0,0,0),Qt::Dense4Pattern));
painter.setPen(Qt::NoPen);
painter.drawRect(InsLineStart,InsLinePos-2,viewport()->width(),4);
}
}
void KeepassGroupView::mousePressEvent(QMouseEvent *event){
//save event position - maybe this is the start of a drag
if (event->button() == Qt::LeftButton)
DragStartPos = event->pos();
//call base function
QTreeWidget::mousePressEvent(event);
if (event->button() == Qt::LeftButton)
DragStartPos = event->pos();
QTreeWidget::mousePressEvent(event);
}
void KeepassGroupView::mouseMoveEvent(QMouseEvent *event){
if (!(event->buttons() & Qt::LeftButton))
return;
if ((event->pos() - DragStartPos).manhattanLength() < QApplication::startDragDistance())
return;
DragItem=(GroupViewItem*)itemAt(DragStartPos);
if (isSearchResultGroup(DragItem))
return;
if (!(event->buttons() & Qt::LeftButton))
return;
if ((event->pos() - DragStartPos).manhattanLength()
< QApplication::startDragDistance())
return;
DragItem=(GroupViewItem*)itemAt(event->pos());
if(!DragItem)return;
if(DragItem==SearchResultItem){
qDebug("SearchGroup");
DragItem=NULL;
return;
}
setCurrentItem(DragItem);
QDrag *drag = new QDrag(this);
QFontMetrics fontmet(DragItem->font(0));
int DragPixmHeight=16;
if(fontmet.height()>16)DragPixmHeight=fontmet.height();
DragPixmap = QPixmap(fontmet.width(DragItem->text(0))+19,DragPixmHeight);
DragPixmap.fill(QColor(255,255,255));
QPainter painter(&DragPixmap);
painter.setPen(QColor(0,0,0));
painter.setFont(DragItem->font(0));
painter.drawPixmap(0,0,DragItem->icon(0).pixmap(QSize(16,16)));
painter.drawText(19,DragPixmHeight-fontmet.strikeOutPos(),DragItem->text(0));
QMimeData *mimeData = new QMimeData;
mimeData->setData("keepass/group",QByteArray((char*)&(DragItem->pGroup),sizeof(void*)));
drag->setMimeData(mimeData);
drag->setPixmap(DragPixmap);
drag->start();
}
QMimeData *mimeData = new QMimeData;
void KeepassGroupView::updateItems(){
clear();
Items.clear();
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->group(i).Name);
Items.back()->pGroup=&db->group(i);
}
else{
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->group(i).Level<=db->group(i-1).Level){
GroupItemItr j;
for(j=Items.end()-1;j!=Items.begin();j--){
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,db->icon(db->group(i).ImageID));
}
for(int i=0;i<Items.size();i++){
setItemExpanded(Items[i],Items[i]->pGroup->UI_ItemIsExpanded);
}
if(ShowSearchGroup){
Items.push_back(new GroupViewItem(this));
Items.back()->setText(0,tr("Search Results"));
Items.back()->pGroup=NULL;
QFont f=Items.back()->font(0);
f.setItalic(true);
f.setBold(true);
Items.back()->setFont(0,f);
}
mimeData->setData("text/plain;charset=UTF-8",DragItem->text(0).toUtf8());
mimeData->setData("application/x-keepassx",QString("drag-type=group").toUtf8());
drag->setMimeData(mimeData);
Qt::DropAction dropAction = drag->start(Qt::MoveAction);
}
GroupViewItem* KeepassGroupView::getLastSameLevelItem(int level){
for(int i=Items.size()-1;i>=0;i--){
if(Items[i]->pGroup->Level==level){
return Items[i];}
}
return Items.back();
}
void KeepassGroupView::paintEvent(QPaintEvent* event){
QTreeWidget::paintEvent(event);
QPainter painter(viewport());
QPen pen(QColor(100,100,100));
pen.setWidth(2);
pen.setStyle(Qt::DotLine);
painter.setPen(pen);
//qDebug("UPDATE: (%i,%i) %ix%i",event->rect().x(),event->rect().y(),event->rect().width(),event->rect().height());
if(!InsertionMarker.isNull()){
painter.drawLine(InsertionMarker);
}
}
bool KeepassGroupView::isSearchResultGroup(GroupViewItem* item){
if(ShowSearchGroup && (item == Items.back()))return true;
else return false;
}
void KeepassGroupView::contextMenuEvent(QContextMenuEvent* e){
if(!(GroupViewItem*)itemAt(e->pos()) && selectedItems().size()){
setItemSelected(selectedItems()[0],false);
}
e->accept();
if(isSearchResultGroup((GroupViewItem*)itemAt(e->pos())))
ContextMenuSearchGroup->popup(e->globalPos());
else
ContextMenu->popup(e->globalPos());
GroupViewItem::GroupViewItem():QTreeWidgetItem(){
}
GroupViewItem::GroupViewItem(QTreeWidget *parent):QTreeWidgetItem(parent){

View File

@@ -23,60 +23,65 @@
#include <QTreeWidget>
#include <QLine>
#include <QContextMenuEvent>
#include "../PwManager.h"
#include "../StandardDatabase.h"
class GroupViewItem;
typedef vector<GroupViewItem*>::iterator GroupItemItr;
class KeepassGroupView:public QTreeWidget{
Q_OBJECT
public:
KeepassGroupView(QWidget* parent=0);
bool isSearchResultGroup(GroupViewItem* item);
void selectSearchGroup();
Database *db;
bool ShowSearchGroup; //needs a "updateItems()" after a change!
vector<GroupViewItem*>Items;
QMenu *ContextMenu;
QMenu *ContextMenuSearchGroup;
public slots:
void updateItems();
signals:
void fileModified();
void entryDropped();
protected:
virtual void dragEnterEvent ( QDragEnterEvent * event );
virtual void dragMoveEvent ( QDragMoveEvent * event );
virtual void dragLeaveEvent ( QDragLeaveEvent * event );
virtual void dropEvent ( QDropEvent * event );
virtual void mousePressEvent(QMouseEvent *event);
virtual void mouseMoveEvent(QMouseEvent *event);
virtual void paintEvent ( QPaintEvent * event );
virtual void contextMenuEvent(QContextMenuEvent *event);
private:
QLine InsertionMarker;
QPoint DragStartPos;
QPixmap DragPixmap;
GroupViewItem* DragItem;
GroupViewItem* LastHoverItem;
GroupViewItem* getLastSameLevelItem(int level);
enum tDragType{GROUP,ENTRY};
tDragType DragType;
Q_OBJECT
public:
KeepassGroupView(QWidget* parent=0);
IDatabase *db;
QList<GroupViewItem*>Items;
QMenu *ContextMenu;
QMenu *ContextMenuSearchGroup;
GroupViewItem* SearchResultItem;
void createItems();
void showSearchResults();
private:
virtual void dragEnterEvent ( QDragEnterEvent * event );
virtual void dragMoveEvent ( QDragMoveEvent * event );
virtual void dragLeaveEvent ( QDragLeaveEvent * event );
virtual void dropEvent ( QDropEvent * event );
virtual void mousePressEvent(QMouseEvent *event);
virtual void mouseMoveEvent(QMouseEvent *event);
virtual void paintEvent ( QPaintEvent * event );
virtual void contextMenuEvent(QContextMenuEvent *event);
void addChilds(GroupViewItem* item);
QPoint DragStartPos;
GroupViewItem* DragItem;
GroupViewItem* LastHoverItem;
int InsLinePos;
int InsLineStart;
public slots:
void OnCurrentGroupChanged(QTreeWidgetItem*,QTreeWidgetItem*);
void OnDeleteGroup();
void OnNewGroup();
void OnEditGroup();
void updateIcons();
void OnHideSearchResults();
// void OnItemExpanded(QTreeWidgetItem*);
// void OnItemCollapsed(QTreeWidgetItem*);
signals:
void groupChanged(IGroupHandle* NewGroup);
void searchResultsSelected();
void fileModified();
};
class GroupViewItem:public QTreeWidgetItem{
public:
GroupViewItem(QTreeWidget *parent);
GroupViewItem(QTreeWidget *parent, QTreeWidgetItem * preceding);
GroupViewItem(QTreeWidgetItem *parent);
GroupViewItem(QTreeWidgetItem *parent, QTreeWidgetItem * preceding);
CGroup* pGroup;
public:
GroupViewItem();
GroupViewItem(QTreeWidget *parent);
GroupViewItem(QTreeWidget *parent, QTreeWidgetItem * preceding);
GroupViewItem(QTreeWidgetItem *parent);
GroupViewItem(QTreeWidgetItem *parent, QTreeWidgetItem * preceding);
IGroupHandle* GroupHandle;
};
#endif

View File

@@ -21,7 +21,8 @@
#include "SecString.h"
#include <iostream>
#include "crypto/arcfour.h"
#include "random.h"
#include "crypto/yarrow.h"
using namespace std;
CArcFour SecString::RC4;
@@ -101,7 +102,7 @@ for(int i=0; i<str.length(); i++){
void SecString::generateSessionKey(){
CArcFour arc;
unsigned char* sessionkey=new unsigned char[32];
getRandomBytes(sessionkey,32,1,false);
randomize(sessionkey,32);
RC4.setKey(sessionkey,32);
delete [] sessionkey;
}

View File

@@ -25,26 +25,37 @@
#include <qglobal.h>
#include "crypto/arcfour.h"
//! QString based class with in-memory encryption of its content.
/*!
This class can hold a QString object in an encrypted buffer. To get access to the string it is neccassary to unlock the SecString object.
*/
class SecString{
public:
SecString();
~SecString();
void setString(QString& str, bool DelSrc=false);
void lock();
void unlock();
const QString& string();
operator QString();
int length();
static void overwrite(unsigned char* str,int len);
static void overwrite(QString& str);
static void generateSessionKey();
SecString();
~SecString();
/*! Sets the content of the object.
The SecString is locked after this operation.
\param Source The string which should be set as content of the SecString.
\param DelSrc Set this parameter TRUE if you want that SecString overwrites an deletes the source string.*/
void setString(QString& Source, bool DelSrc=false);
/*! Locks the string.
That means that the unencrypted string will be overwritten and deleted and only the encrypted buffer remains.
It is forbidden to call the function string() when the SecString is locked.*/
void lock();
void unlock();
const QString& string();
operator QString();
int length();
static void overwrite(unsigned char* str,int len);
static void overwrite(QString& str);
static void generateSessionKey();
private:
bool locked;
static CArcFour RC4;
QByteArray crypt;
QString plain;
bool locked;
static CArcFour RC4;
QByteArray crypt;
QString plain;
};