summaryrefslogtreecommitdiffabout
Side-by-side diff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--bin/kdepim/pwmanager/pwmanagerFAQ.txt38
-rw-r--r--pwmanager/pwmanager/pwm.cpp57
-rw-r--r--pwmanager/pwmanager/pwm.h8
-rw-r--r--pwmanager/pwmanager/pwmdoc.cpp85
-rw-r--r--pwmanager/pwmanager/pwmdoc.h37
-rw-r--r--pwmanager/pwmanager/pwmview.cpp92
-rw-r--r--pwmanager/pwmanager/pwmview.h25
-rw-r--r--pwmanager/pwmanager/serializer.cpp86
8 files changed, 300 insertions, 128 deletions
diff --git a/bin/kdepim/pwmanager/pwmanagerFAQ.txt b/bin/kdepim/pwmanager/pwmanagerFAQ.txt
index 7bfe368..a28f07b 100644
--- a/bin/kdepim/pwmanager/pwmanagerFAQ.txt
+++ b/bin/kdepim/pwmanager/pwmanagerFAQ.txt
@@ -1,12 +1,20 @@
Q:
-What is PWM/Pi
+What is PWM/Pi?
Q:
For which platform is PWM/Pi available?
Q:
-Can I exchange the password files from PWM/Pi and PwManager
+Can I exchange the password files from PWM/Pi and PwManager?
+Q:
+Does Export/Import keep sync information in place?
+Q:
+Can PWM/Pi sync categories?
+Q:
+Which crypto, hash and compress algorithm is applied to the remote file
+while syncing?
+
*************************************************************************
Q:
What is PWM/Pi
A:
PWM/Pi is the platform-independend version of PwManager 1.0.1, written by
@@ -29,13 +37,35 @@ Can I exchange the password files from PWM/Pi and PwManager
A:
The password files of PWM/Pi can not be exchanged with all versions up
to 1.0.1 of PwManager.
However, Michael will integrate our changes into a PwManager release
1.1, and the password files of that release will then be interchangable
with PWM/Pi
-
-
+*************************************************************************
+Q:
+Does Export/Import keep sync information in place
+A:
+Exporting data from PwManager removes all sync related information
+(Meta information) from the data. Because of that, a subsequent import
+results in "new" entries that will be handled as new entries when
+syncing them with an existing password file.
+*************************************************************************
+Q:
+Can PWM/Pi sync categories?
+A:
+No. PWM/Pi does not sync categories. It syncs all pw entries of the file
+without checking for the entries categories.
+A sync operation does not move modified entries from one category to another.
+Only if the sync operation has to create a new pw entry, it checks for the
+existance of the category and creates it if not existent.
+*************************************************************************
+Q:
+Which crypto, hash and compress algorithm is applied to the remote file
+while syncing?
+A: The sync operation applies the local crypt, hash and compress algorithm
+to both, the local and remote copy of the passwordfile and with thus
+overwrites the settings of the remote PwManager application.
diff --git a/pwmanager/pwmanager/pwm.cpp b/pwmanager/pwmanager/pwm.cpp
index 014e809..57b4432 100644
--- a/pwmanager/pwmanager/pwm.cpp
+++ b/pwmanager/pwmanager/pwm.cpp
@@ -129,13 +129,14 @@ enum {
#ifdef PWM_EMBEDDED
// Button IDs for "help" popup menu
enum {
BUTTON_POPUP_HELP_LICENSE = 0,
BUTTON_POPUP_HELP_FAQ,
- BUTTON_POPUP_HELP_ABOUT
+ BUTTON_POPUP_HELP_ABOUT,
+ BUTTON_POPUP_HELP_SYNC
};
#endif
// Button IDs for toolbar
enum {
BUTTON_TOOL_NEW = 0,
@@ -153,13 +154,13 @@ enum {
};
PwM::PwM(PwMInit *_init, PwMDoc *doc,
bool virginity,
QWidget *parent, const char *name)
- : KMainWindow(parent, name)
+ : KMainWindow(parent, "HALLO")
, forceQuit (false)
, forceMinimizeToTray (false)
{
init = _init;
connect(doc, SIGNAL(docClosed(PwMDoc *)),
this, SLOT(docClosed(PwMDoc *)));
@@ -355,12 +356,16 @@ void PwM::initMenubar()
BUTTON_POPUP_HELP_FAQ);
helpPopup->insertItem(i18n("&About PwManager"), this,
SLOT(createAboutData_slot()), 0,
BUTTON_POPUP_HELP_ABOUT);
+ helpPopup->insertItem(i18n("&Sync HowTo"), this,
+ SLOT(syncHowTo_slot()), 0,
+ BUTTON_POPUP_HELP_SYNC);
+
#endif
menuBar()->insertItem(i18n("&Help"), helpPopup);
}
void PwM::initToolbar()
@@ -606,30 +611,36 @@ void PwM::addPwd_slot(QString *pw, PwMDoc *_doc)
w.pwLineEdit->setText(*pw);
tryAgain:
if (w.exec() == 1)
{
PwMDataItem d;
+
+ //US BUG: to initialize all values of curEntr with meaningfulldata,
+ // we call clear on it. Reason: Metadata will be uninitialized otherwise.
+ // another option would be to create a constructor for PwMDataItem
+ d.clear(true);
+
d.desc = w.getDescription().latin1();
d.name = w.getUsername().latin1();
d.pw = w.getPassword().latin1();
d.comment = w.getComment().latin1();
d.url = w.getUrl().latin1();
d.launcher = w.getLauncher().latin1();
PwMerror ret = doc->addEntry(w.getCategory(), &d);
if (ret == e_entryExists) {
KMessageBox::error(this,
i18n
- ("An entry with this \"Description\", "
+ ("An entry with this \"Description\",\n"
"does already exist.\n"
"Please select another description."),
i18n("entry already exists."));
goto tryAgain;
} else if (ret == e_maxAllowedEntr) {
- KMessageBox::error(this, i18n("The maximum possible number of entries "
- "has been reached. You can't add more entries."),
+ KMessageBox::error(this, i18n("The maximum possible number of\nentries"
+ "has been reached.\nYou can't add more entries."),
i18n("maximum number of entries"));
doc->timer()->putLock(DocTimer::id_autoLockTimer);
return;
}
}
setVirgin(false);
@@ -1284,12 +1295,19 @@ void PwM::showLicense_slot()
void PwM::faq_slot()
{
KApplication::showFile( "PWM/Pi FAQ", "kdepim/pwmanager/pwmanagerFAQ.txt" );
}
+void PwM::syncHowTo_slot()
+{
+ qDebug("PwM::syncHowTo_slot");
+ KApplication::showFile( "KDE-Pim/Pi Synchronization HowTo", "kdepim/SyncHowto.txt" );
+}
+
+
void PwM::createAboutData_slot()
{
QString version;
#include <../version>
QMessageBox::about( this, "About PwManager/Pi",
"PwManager/Platform-independent\n"
@@ -1323,43 +1341,24 @@ void PwM::createAboutData_slot()
bool PwM::sync(KSyncManager* manager, QString filename, int mode)
{
PWM_ASSERT(curDoc());
bool ret = curDoc()->sync(manager, filename, mode);
+ qDebug("PwM::sync save now: ret=%i", ret);
+
if (ret == true) {
//US BUG: what can we call here to update the view of the current doc?
//mViewManager->refreshView();
- }
-
- return ret;
-}
-//called by the syncmanager to indicate that the work has to be marked as dirty.
-void PwM::sync_setModified()
-{
- PWM_ASSERT(curDoc());
- curDoc()->sync_setModified();
-}
-
-//called by the syncmanager to ask if the dirty flag is set.
-bool PwM::sync_isModified()
-{
- PWM_ASSERT(curDoc());
- return curDoc()->sync_isModified();
+ //US curDoc()->sync sets the dirtyFlag in case the sync was successfull.
+ save();
}
-//called by the syncmanager to indicate that the work has to be saved.
-void PwM::sync_save()
-{
- PWM_ASSERT(curDoc());
- return curDoc()->sync_save();
+ return ret;
}
-
-
-
#endif
#ifndef PWM_EMBEDDED
#include "pwm.moc"
#endif
diff --git a/pwmanager/pwmanager/pwm.h b/pwmanager/pwmanager/pwm.h
index 7c6bf0d..6ed9d34 100644
--- a/pwmanager/pwmanager/pwm.h
+++ b/pwmanager/pwmanager/pwm.h
@@ -174,12 +174,13 @@ public slots:
void replayCardBackup_slot();
#ifdef PWM_EMBEDDED
void showLicense_slot();
void faq_slot();
void createAboutData_slot();
+ void syncHowTo_slot();
#endif
protected:
/** is this window virgin? */
bool isVirgin()
{ return virgin; }
@@ -269,19 +270,12 @@ protected:
private:
#ifdef PWM_EMBEDDED
//this are the overwritten callbackmethods from the syncinterface
virtual bool sync(KSyncManager* manager, QString filename, int mode);
- //called by the syncmanager to indicate that the work has to marked as dirty.
- virtual void sync_setModified();
- //called by the syncmanager to ask if the dirty flag is set.
- virtual bool sync_isModified();
- //called by the syncmanager to indicate that the work has to be saved.
- virtual void sync_save();
-
// LR *******************************
// sync stuff!
QPopupMenu *syncPopup;
KSyncManager* syncManager;
#endif
diff --git a/pwmanager/pwmanager/pwmdoc.cpp b/pwmanager/pwmanager/pwmdoc.cpp
index 0ac5517..2a7b11d 100644
--- a/pwmanager/pwmanager/pwmdoc.cpp
+++ b/pwmanager/pwmanager/pwmdoc.cpp
@@ -484,13 +484,14 @@ PwMerror PwMDoc::saveDoc(char compress, const QString *file)
printWarn(string("removing file ")
+ tmpFileMoved.latin1()
+ " failed!");
}
}
ret = e_success;
- printDebug(string("writing file { compress: ")
+ printDebug(string("writing file { name: ")
+ + filename.latin1() + " compress: "
+ tostr(static_cast<int>(compress)) + " cryptAlgo: "
+ tostr(static_cast<int>(cryptAlgo)) + " hashAlgo: "
+ tostr(static_cast<int>(hashAlgo))
+ " }");
goto out;
out_moveback:
@@ -602,13 +603,15 @@ out_success:
PwMerror PwMDoc::writeFileHeader(char keyHash, char dataHash, char crypt, char compress,
QString *pw, QFile *f)
{
PWM_ASSERT(pw);
PWM_ASSERT(f);
- PWM_ASSERT(listView);
+ //US ENH: or maybe a bug: checking here for listView does not make sense because we do not check anywhere else
+ //Wenn I sync, I open a doc without a view => listView is 0 => Assertion
+ //US PWM_ASSERT(listView);
if (f->writeBlock(FILE_ID_HEADER, strlen(FILE_ID_HEADER)) !=
static_cast<Q_LONG>(strlen(FILE_ID_HEADER))) {
return e_writeFile;
}
if (f->putch(PWM_FILE_VER) == -1 ||
f->putch(keyHash) == -1 ||
@@ -2801,16 +2804,25 @@ PwMerror PwMDoc::importFromGpasman(const QString *file)
void PwMDoc::ensureLvp()
{
if (isDocEmpty())
return;
+ //US ENH BUG: when using syncronizing, this way of sorting
+ //is not sufficient, because there might be empty spaces
+ // at the beginning. But this algorythm only can add elements
+ //to the end.The result are crashes because of listoverflows
+ //we need something to fill all gaps.
vector< vector<PwMDataItem>::iterator > undefined;
+ vector< vector<PwMDataItem>::iterator > sorted;
vector< vector<PwMDataItem>::iterator >::iterator undefBegin,
undefEnd,
undefI;
+ vector< vector<PwMDataItem>::iterator >::iterator sortedBegin,
+ sortedEnd,
+ sortedI;
vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
catEnd = dti.dta.end(),
catI = catBegin;
vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
int lvpTop, tmpLvp;
@@ -2823,16 +2835,30 @@ void PwMDoc::ensureLvp()
entrI = entrBegin;
while (entrI != entrEnd) {
tmpLvp = entrI->listViewPos;
if (tmpLvp == -1)
undefined.push_back(entrI);
- else if (tmpLvp > lvpTop)
- lvpTop = tmpLvp;
+ else
+ sorted[tmpLvp] = entrI;
+ //US else if (tmpLvp > lvpTop)
+ //US lvpTop = tmpLvp;
++entrI;
}
+
+ //now we have all undefied in the collection. Now insert the existing
+ sortedBegin = sorted.begin();
+ sortedEnd = sorted.end();
+ sortedI = sortedBegin;
+
+ while (sortedI != sortedEnd) {
+ tmpLvp = (*sortedI)->listViewPos;
+ undefined[tmpLvp] = *sortedI;
+ ++sortedI;
+ }
+
undefBegin = undefined.begin();
undefEnd = undefined.end();
undefI = undefBegin;
while (undefI != undefEnd) {
(*undefI)->listViewPos = ++lvpTop;
++undefI;
@@ -2845,12 +2871,22 @@ QString PwMDoc::getTitle()
{
/* NOTE: We have to ensure, that the returned title
* is unique and not reused somewhere else while
* this document is valid (open).
*/
QString title(getFilename());
+
+ //US ENH: The whole filename on PDAs is too long. So use only the last characters
+ if (QApplication::desktop()->width() < 640)
+ {
+ if (title.length() > 30)
+ title = "..." + title.right(30);
+
+ }
+
+
if (title.isEmpty()) {
if (unnamedNum == 0) {
unnamedNum = PwMDocList::getNewUnnamedNumber();
PWM_ASSERT(unnamedNum != 0);
}
title = DEFAULT_TITLE;
@@ -2924,13 +2960,13 @@ PwMerror PwMDoc::syncronize(KSyncManager* manager, PwMDoc* syncLocal , PwMDoc* s
qDebug("PwMDoc::syncronize : newly created local sync data could not be found");
return e_syncError;
}
}
syncItemLocal = syncLocal->getSyncDataEntry(index);
- qDebug("Last Sync %s ", syncItemLocal->lastSyncDate.toString().latin1());
+ qDebug("Last Sync Local %s ", syncItemLocal->lastSyncDate.toString().latin1());
//Step 2. Find syncinfo in remote file and create if not existent.
found = syncRemote->findSyncData(mCurrentSyncName, &index);
if (found == false)
{
qDebug("FULLDATE 1");
@@ -2944,39 +2980,40 @@ PwMerror PwMDoc::syncronize(KSyncManager* manager, PwMDoc* syncLocal , PwMDoc* s
qDebug("PwMDoc::syncronize : newly created remote sync data could not be found");
return e_syncError;
}
}
syncItemRemote = syncRemote->getSyncDataEntry(index);
+ qDebug("Last Sync Remote %s ", syncItemRemote->lastSyncDate.toString().latin1());
//and remove the found entry here. We will reenter it later again.
//US syncRemote->delSyncDataEntry(index, true);
if ( syncItemLocal->lastSyncDate == mLastSync ) {
qDebug("FULLDATE 2");
fullDateRange = true;
}
if ( ! fullDateRange ) {
if ( syncItemLocal->lastSyncDate != syncItemRemote->lastSyncDate ) {
- // qDebug("set fulldate to true %s %s" ,addresseeLSync->dtStart().toString().latin1(), addresseeRSync->dtStart().toString().latin1() );
- //qDebug("%d %d %d %d ", addresseeLSync->dtStart().time().second(), addresseeLSync->dtStart().time().msec() , addresseeRSync->dtStart().time().second(), addresseeRSync->dtStart().time().msec());
+ // qDebug("set fulldate to true %s %s" ,syncItemLocal->lastSyncDate.toString().latin1(), syncItemRemote->lastSyncDate.toString().latin1() );
+ // qDebug("%d %d %d %d ", syncItemLocal->lastSyncDate.time().second(), addresseeLSync->dtStart().time().msec() , addresseeRSync->dtStart().time().second(), addresseeRSync->dtStart().time().msec());
fullDateRange = true;
qDebug("FULLDATE 3 %s %s", syncItemLocal->lastSyncDate.toString().latin1() , syncItemRemote->lastSyncDate.toString().latin1() );
}
}
// fullDateRange = true; // debug only!
if ( fullDateRange )
mLastSync = QDateTime::currentDateTime().addDays( -100*365);
else
mLastSync = syncItemLocal->lastSyncDate;
qDebug("*************************** ");
- // qDebug("mLastAddressbookSync %s ",mLastAddressbookSync.toString().latin1() );
+ qDebug("mLastSync %s ",mLastSync.toString().latin1() );
QStringList er = syncRemote->getIDEntryList();
PwMDataItem* inRemote ;//= er.first();
PwMDataItem* inLocal;
unsigned int catLocal, indexLocal;
unsigned int catRemote, indexRemote;
@@ -2998,13 +3035,13 @@ PwMerror PwMDoc::syncronize(KSyncManager* manager, PwMDoc* syncLocal , PwMDoc* s
inLocal = syncLocal->findEntryByID( uid, &catLocal, &indexLocal );
inRemote = syncRemote->findEntryByID( uid, &catRemote, &indexRemote );
PWM_ASSERT(inRemote);
if ( inLocal != 0 ) { // maybe conflict - same uid in both files
if ( (take = takePwMDataItem( inLocal, inRemote, mLastSync, mode, fullDateRange) ) ) {
- //qDebug("take %d %s ", take, inL.summary().latin1());
+ qDebug("take %d %s ", take, inLocal->desc.c_str());
if ( take == 3 )
return e_syncError;
if ( take == 1 ) {// take local
//US syncRemote->removeAddressee( inRemote );
(*inRemote) = (*inLocal);
//US syncRemote->insertAddressee( inRemote , false);
@@ -3049,12 +3086,13 @@ PwMerror PwMDoc::syncronize(KSyncManager* manager, PwMDoc* syncLocal , PwMDoc* s
qApp->processEvents();
if (manager->isProgressBarCanceled())
return e_syncError;
if ( incCounter % modulo == 0 )
manager->showProgressBar(incCounter);
uid = el[ incCounter ];
+ qDebug("sync uid %s from local file", uid.latin1());
inLocal = syncLocal->findEntryByID( uid, &catLocal, &indexLocal );
inRemote = syncRemote->findEntryByID( uid, &catRemote, &indexRemote );
PWM_ASSERT(inLocal);
if ( inRemote == 0 ) {
@@ -3129,22 +3167,22 @@ int PwMDoc::takePwMDataItem( PwMDataItem* local, PwMDataItem* remote, QDateTime
return 0;
qDebug(" %d %d conflict on %s %s ", mode, full, local->desc.c_str(), remote->desc.c_str() );
//qDebug("%s %d %s %d", local->lastModified().toString().latin1() , localMod, remote->lastModified().toString().latin1(), remoteMod);
//qDebug("%d %d %d %d ", local->lastModified().time().second(), local->lastModified().time().msec(), remote->lastModified().time().second(), remote->lastModified().time().msec() );
- //full = true; //debug only
+ full = true; //debug only
if ( full ) {
- bool equ = true;//US ( (*local) == (*remote) );
+ bool equ = ( (*local) == (*remote) );
if ( equ ) {
- //qDebug("equal ");
+ qDebug("equal ");
if ( mode < SYNC_PREF_FORCE_LOCAL )
return 0;
- }//else //debug only
- //qDebug("not equal %s %s ", local->summary().latin1(), remote->summary().latin1());
+ }else //debug only
+ qDebug("not equal %s %s ", local->desc.c_str(), remote->desc.c_str());
}
int result;
bool localIsNew;
//qDebug("%s -- %s mLastCalendarSync %s lastsync %s --- local %s remote %s ",local->summary().latin1(), remote->summary().latin1(),mLastCalendarSync.toString().latin1() ,lastSync.toString().latin1() , local->lastModified().toString().latin1() , remote->lastModified().toString().latin1() );
@@ -3212,13 +3250,13 @@ bool PwMDoc::sync(KSyncManager* manager, QString filename, int mode)
if (this->isDeepLocked()) {
PwMerror ret = this->deepLock(false);
if (ret != e_success)
return false;
}
- //2) construct and open a new doc on the stack(automatic cleanup) for remote file.
+ //2) construct and open a new doc on the stack(automatic cleanup of remote file).
PwMDoc syncTarget(this, "synctarget");
PwMDoc* pSyncTarget = &syncTarget;
PwMerror err = pSyncTarget->openDoc(&filename, 1 /*== open with all entries locked*/);
@@ -3264,29 +3302,12 @@ bool PwMDoc::sync(KSyncManager* manager, QString filename, int mode)
}
else {
return false;
}
}
-//called by the syncmanager to indicate that the work has to marked as dirty.
-void PwMDoc::sync_setModified()
-{
- flagDirty();
-}
-
-//called by the syncmanager to ask if the dirty flag is set.
-bool PwMDoc::sync_isModified()
-{
- return isDirty();
-}
-
-//called by the syncmanager to indicate that the work has to be saved.
-void PwMDoc::sync_save()
-{
- saveDoc(conf()->confGlobCompression());
-}
#endif
bool PwMDoc::findSyncData(const QString &syncname, unsigned int *index)
{
vector<PwMSyncItem>::iterator i = dti.syncDta.begin(),
diff --git a/pwmanager/pwmanager/pwmdoc.h b/pwmanager/pwmanager/pwmdoc.h
index 2e9547e..6a1dd30 100644
--- a/pwmanager/pwmanager/pwmdoc.h
+++ b/pwmanager/pwmanager/pwmdoc.h
@@ -127,22 +127,12 @@ struct PwMMetaData
expire = QDateTime();
update = QDateTime();
updateInt = 0;
uniqueid = KApplication::randomString(8);
}
- PwMMetaData& operator = (const PwMMetaData& x)
- {
- create = x.create;
- expire = x.expire;
- update = x.update;
- updateInt = x.updateInt;
- uniqueid = x.uniqueid;
- return *this;
- }
-
inline bool isValid() const
{
if (valid.isNull())
return true;
return (valid < QDateTime::currentDateTime());
}
@@ -214,24 +204,40 @@ struct PwMDataItem
lockStat = true;
listViewPos = -1;
binary = false;
if (clearMeta)
meta.clear();
}
+ //US ENH: we need this operator to compare two items if we have no unique ids
+ //available. Generaly this happens before the first sync
+ bool PwMDataItem::operator==( const PwMDataItem &a ) const
+ {
+ qDebug("oper==%s", a.desc.c_str());
+ if ( desc != a.desc ) return false;
+ if ( name != a.name ) return false;
+ if ( pw != a.pw ) return false;
+ if ( comment != a.comment ) return false;
+ if ( url != a.url ) return false;
+ if ( launcher != a.launcher ) return false;
+ //all other field will not be checked.
+ return true;
+ }
+ //US ENH:this operator is used to copy an elements data during syncronization
+ //Attention: listViewPos will not be copied. So the position will stay the same.
PwMDataItem& operator = (const PwMDataItem& x)
{
- qDebug("oper=%s", x.desc.c_str());
+ // qDebug("oper=%s", x.desc.c_str());
desc = x.desc;
name = x.name;
pw = x.pw;
comment = x.comment;
url = x.url;
launcher = x.launcher;
lockStat = x.lockStat;
- listViewPos = x.listViewPos;
+ //Do not copy listViewPos!!! listViewPos = x.listViewPos;
binary = x.binary;
meta = x.meta;
rev = x.rev;
return *this;
}
@@ -771,19 +777,12 @@ protected:
// 3 cancel
int takePwMDataItem( PwMDataItem* local, PwMDataItem* remote, QDateTime lastSync, int mode , bool full );
//the following methods are the overwritten callbackmethods from the syncinterface
virtual bool sync(KSyncManager* manager, QString filename, int mode);
- //called by the syncmanager to indicate that the work has to be marked as dirty.
- virtual void sync_setModified();
- //called by the syncmanager to ask if the dirty flag is set.
- virtual bool sync_isModified();
- //called by the syncmanager to indicate that the work has to be saved.
- virtual void sync_save();
-
#endif
private:
//US ENH: helpermethods to access the sync data for a certain syncname.
// It returns the syncdatas index
bool findSyncData(const QString &syncname, unsigned int *index);
diff --git a/pwmanager/pwmanager/pwmview.cpp b/pwmanager/pwmanager/pwmview.cpp
index e23ce25..e53124f 100644
--- a/pwmanager/pwmanager/pwmview.cpp
+++ b/pwmanager/pwmanager/pwmview.cpp
@@ -453,17 +453,97 @@ void PwMView::copyCommentToClip()
return;
PwMDataItem d;
document()->getEntry(getCurrentCategory(), curIndex, &d);
PwM::copyToClipboard(d.comment.c_str());
}
+/************************************************************************
+ *
+ *
+ *
+ ************************************************************************/
+
+
+PwMDataItemView::PwMDataItemView( QWidget *parent, const char *name )
+ : QTextBrowser( parent, name )
+
+
+{
+//US setWrapPolicy( QTextEdit::AtWordBoundary );
+ setLinkUnderline( false );
+ // setVScrollBarMode( QScrollView::AlwaysOff );
+ //setHScrollBarMode( QScrollView::AlwaysOff );
+
+//US QStyleSheet *sheet = styleSheet();
+//US QStyleSheetItem *link = sheet->item( "a" );
+//US link->setColor( KGlobalSettings::linkColor() );
+
+}
+
+void PwMDataItemView::setPwMDataItem( const PwMDataItem& a )
+
+{
+ mItem = a;
+ // clear view
+ setText( QString::null );
+
+
+ QString dynamicPart;
+ QString format = "<tr><td align=\"right\"><b>%1</b></td>"
+ "<td align=\"left\">%2</td></tr>";
+
+ dynamicPart += format
+ .arg( i18n("Description") )
+ .arg( mItem.desc.c_str() );
+ dynamicPart += format
+ .arg( i18n("Name") )
+ .arg( mItem.name.c_str() );
+
+ dynamicPart += format
+ .arg( i18n("Password") )
+ .arg( mItem.pw.c_str() );
+
+ QString comment(mItem.pw.c_str());
+ dynamicPart += format
+ .arg( i18n("Comment") )
+ .arg( comment.replace( QRegExp("\n"), "<br>" ) );
+
+ dynamicPart += format
+ .arg( i18n("URL") )
+ .arg( mItem.url.c_str() );
+
+ dynamicPart += format
+ .arg( i18n("Launcher") )
+ .arg( mItem.launcher.c_str() );
+
+ QString mText = "<table><td colspan=\"2\">&nbsp;</td>";
+
+ mText += dynamicPart;
+ mText += "</table>";
+
+ // at last display it...
+ setText( mText );
+
+}
+
+PwMDataItem PwMDataItemView::pwmdataitem() const
+{
+ return mItem;
+}
+
+/************************************************************************
+ *
+ *
+ *
+ ************************************************************************/
-PwMDataItemChooser::PwMDataItemChooser( PwMDataItem loc, PwMDataItem rem, bool takeloc, QWidget *parent, const char *name ) : KDialogBase(parent,name,
- true ,i18n("Conflict! Please choose Entry!"),Ok|User1|Close,Close, false)
+PwMDataItemChooser::PwMDataItemChooser( PwMDataItem loc, PwMDataItem rem, bool takeloc, QWidget *parent, const char *name )
+ : KDialogBase(parent, name, true ,
+ i18n("Conflict! Please choose Entry!"),Ok|User1|Close,Close, false)
{
findButton( Close )->setText( i18n("Cancel Sync"));
findButton( Ok )->setText( i18n("Remote"));
findButton( User1 )->setText( i18n("Local"));
QWidget* topframe = new QWidget( this );
setMainWidget( topframe );
@@ -475,21 +555,21 @@ PwMDataItemChooser::PwMDataItemChooser( PwMDataItem loc, PwMDataItem rem, bool t
}
QVBox* subframe = new QVBox( topframe );
bl->addWidget(subframe );
QLabel* lab = new QLabel( i18n("Local Entry"), subframe );
if ( takeloc )
lab->setBackgroundColor(Qt::green.light() );
- // AddresseeView * av = new AddresseeView( subframe );
- // av->setAddressee( loc );
+ PwMDataItemView * av = new PwMDataItemView( subframe );
+ av->setPwMDataItem( loc );
subframe = new QVBox( topframe );
bl->addWidget(subframe );
lab = new QLabel( i18n("Remote Entry"), subframe );
if ( !takeloc )
lab->setBackgroundColor(Qt::green.light() );
- // av = new AddresseeView( subframe );
- // av->setAddressee( rem );
+ av = new PwMDataItemView( subframe );
+ av->setPwMDataItem( rem );
QObject::connect(findButton( Ok ),SIGNAL(clicked()),this, SLOT(slot_remote()));
QObject::connect(this,SIGNAL(user1Clicked()),this, SLOT(slot_local()));
#ifndef DESKTOP_VERSION
showMaximized();
#else
resize ( 640, 400 );
diff --git a/pwmanager/pwmanager/pwmview.h b/pwmanager/pwmanager/pwmview.h
index 75cce51..e42b17a 100644
--- a/pwmanager/pwmanager/pwmview.h
+++ b/pwmanager/pwmanager/pwmview.h
@@ -38,12 +38,13 @@
#include <klocale.h>
#include <kdialogbase.h>
#include <qevent.h>
#include <qfont.h>
#include <qobject.h>
+#include <qtextbrowser.h>
#include <vector>
#include <string>
using std::string;
using std::vector;
@@ -146,12 +147,36 @@ private:
PwMDoc *doc;
/** pointer to the main class "PwM" */
PwM *mainClass;
};
+//US ENH basic widget to view an password entry. We need it for the sync stuff.
+//But might be oif interest for other functionalities as well.
+class PwMDataItemView : public QTextBrowser
+{
+ public:
+ PwMDataItemView( QWidget *parent = 0, const char *name = 0 );
+
+ /**
+ Sets the PwMDataItem object. It is displayed immediately.
+
+ @param a The PwMDataItem object.
+ */
+ void setPwMDataItem( const PwMDataItem& a );
+
+ /**
+ Returns the current PwMDataItem object.
+ */
+ PwMDataItem pwmdataitem() const;
+
+ private:
+ PwMDataItem mItem;
+};
+
+
//US ENH we need this chooser when syncing results in a conflict
class PwMDataItemChooser : public KDialogBase
{
Q_OBJECT
public:
diff --git a/pwmanager/pwmanager/serializer.cpp b/pwmanager/pwmanager/serializer.cpp
index 203f82c..5c6568f 100644
--- a/pwmanager/pwmanager/serializer.cpp
+++ b/pwmanager/pwmanager/serializer.cpp
@@ -24,13 +24,13 @@
#ifdef PWM_EMBEDDED
#include <kglobal.h>
#include <klocale.h>
#endif
/* enable/disable serializer debugging (0/1) */
-#define SERIALIZER_DEBUG 0
+#define SERIALIZER_DEBUG 1
/* use the old xml tags for writing (0/1) */
#define USE_OLD_TAGS 0
/* write a CDATA section (0/1) */
#define WRITE_CDATA_SEC 0
@@ -301,12 +301,16 @@ bool Serializer::readEntries(const QDomNode &n,
vector<PwMDataItem> *dta)
{
QDomNodeList nl(n.childNodes());
QDomNode cur;
unsigned int numEntr = nl.count(), i;
PwMDataItem curEntr;
+ //US BUG: to initialize all values of curEntr with meaningfulldata,
+ // we call clear on it. Reason: Information in the file we will read might be incomplete.
+ // e.g. the metadata is missing.
+ curEntr.clear(true);
dta->clear();
for (i = 0; i < numEntr; ++i) {
cur = nl.item(i);
if (cur.nodeName().left(1) == ENTRY_PREFIX_NEW ||
cur.nodeName().left(6) == ENTRY_PREFIX_OLD) {
@@ -398,56 +402,57 @@ bool Serializer::extractMeta(const QDomNode &n,
name = cur.nodeName();
val = cur.toElement().text();
if (val == "") {
cur = cur.nextSibling();
continue;
}
+
+ //US BUG: The transformation of an empty date into an ISO date and back is different on different systems/compilers.
+ //because of that it is possible that here some values are not set, which means they are null.
+ //US ENH: at the same moment we need backwardcompatibility. So older versions might have stored invalid dates.
+
+ QDateTime dtval; //dtval should be invalid by definition.
+
+ if ((name == META_CREATE_DATE) ||
+ (name == META_VALID_DATE) ||
+ (name == META_EXPIRE_DATE) ||
+ (name == META_UPDATE_DATE))
+ {
+ //qDebug("Serializer::extractMeta:: val:%s, empty:%i, length:%i",val.utf8(), val.isEmpty(), val.length());
+
#ifndef PWM_EMBEDDED
- if (name == META_CREATE_DATE) {
- dta->create = QDateTime::fromString(val, Qt::ISODate);
- } else if (name == META_VALID_DATE) {
- dta->valid = QDateTime::fromString(val, Qt::ISODate);
- } else if (name == META_EXPIRE_DATE) {
- dta->expire = QDateTime::fromString(val, Qt::ISODate);
- } else if (name == META_UPDATE_DATE) {
- dta->update = QDateTime::fromString(val, Qt::ISODate);
- } else if (name == META_UPDATE_INT) {
- dta->updateInt = strtoul(val.latin1(), 0, 10);
- } else if (name == META_UNIQUEID) {
- dta->uniqueid = unescapeEntryData(val).latin1();
- } else {
- printDebug(string("extractMeta(): invalid: ")
- + name.latin1());
- }
+ dtval = QDateTime::fromString(val, Qt::ISODate);
#else
+ bool ok;
+ dtval = KGlobal::locale()->readDateTime(val, KLocale::ISODate, &ok);
+
+ if (ok == false)
+ qDebug("Serializer::extractMeta invalid date or time !!!!!!!!!!!!!");
+#endif
+ //if the parsed data is wrong, dtval should be invalid at this time.
- bool ok = true;
+ }
if (name == META_CREATE_DATE) {
- dta->create = KGlobal::locale()->readDateTime(val, KLocale::ISODate, &ok);
+ dta->create = dtval;
} else if (name == META_VALID_DATE) {
- dta->valid = KGlobal::locale()->readDateTime(val, KLocale::ISODate, &ok);
+ dta->valid = dtval;
} else if (name == META_EXPIRE_DATE) {
- dta->expire = KGlobal::locale()->readDateTime(val, KLocale::ISODate, &ok);
+ dta->expire = dtval;
} else if (name == META_UPDATE_DATE) {
- dta->update = KGlobal::locale()->readDateTime(val, KLocale::ISODate, &ok);
+ dta->update = dtval;
} else if (name == META_UPDATE_INT) {
dta->updateInt = strtoul(val.latin1(), 0, 10);
} else if (name == META_UNIQUEID) {
dta->uniqueid = unescapeEntryData(val).latin1();
} else {
printDebug(string("extractMeta(): invalid: ")
+ name.latin1());
}
- if (ok == false)
- qDebug("Serializer::extractMeta invalid date or time !!!!!!!!!!!!!");
-
-
-#endif
cur = cur.nextSibling();
}
return true;
}
bool Serializer::checkValid()
@@ -601,47 +606,67 @@ bool Serializer::writeEntry(QDomElement *e,
bool Serializer::writeMeta(QDomElement *e,
const PwMMetaData &dta)
{
QDomText text;
QDomElement tag;
+ //US BUG!!!: The transformation of an empty date into an ISO date is different on different systems/compilers.
+ //So do not transform an empty value at all.
+ if (dta.create.isValid())
+ {
tag = domDoc->createElement(META_CREATE_DATE);
#ifndef PWM_EMBEDDED
text = domDoc->createTextNode(dta.create.toString(Qt::ISODate));
#else
text = domDoc->createTextNode(KGlobal::locale()->formatDateTime(dta.create, KLocale::ISODate));
#endif
tag.appendChild(text);
e->appendChild(tag);
+ }
+ //US BUG!!!: The transformation of an empty date into an ISO date is different on different systems/compilers.
+ //So do not transform an empty value at all.
+ if (dta.valid.isValid())
+ {
tag = domDoc->createElement(META_VALID_DATE);
#ifndef PWM_EMBEDDED
text = domDoc->createTextNode(dta.valid.toString(Qt::ISODate));
#else
text = domDoc->createTextNode(KGlobal::locale()->formatDateTime(dta.valid, KLocale::ISODate));
#endif
tag.appendChild(text);
e->appendChild(tag);
+ }
+ //US BUG!!!: The transformation of an empty date into an ISO date is different on different systems/compilers.
+ //So do not transform an empty value at all.
+ if (dta.expire.isValid())
+ {
tag = domDoc->createElement(META_EXPIRE_DATE);
#ifndef PWM_EMBEDDED
text = domDoc->createTextNode(dta.expire.toString(Qt::ISODate));
#else
text = domDoc->createTextNode(KGlobal::locale()->formatDateTime(dta.expire, KLocale::ISODate));
#endif
tag.appendChild(text);
e->appendChild(tag);
+ }
+ //US BUG!!!: The transformation of an empty date into an ISO date is different on different systems/compilers.
+ //So do not transform an empty value at all.
+ if (dta.update.isValid())
+ {
tag = domDoc->createElement(META_UPDATE_DATE);
#ifndef PWM_EMBEDDED
text = domDoc->createTextNode(dta.update.toString(Qt::ISODate));
#else
text = domDoc->createTextNode(KGlobal::locale()->formatDateTime(dta.update, KLocale::ISODate));
#endif
tag.appendChild(text);
e->appendChild(tag);
+ }
tag = domDoc->createElement(META_UPDATE_INT);
text = domDoc->createTextNode(tostr(dta.updateInt).c_str());
tag.appendChild(text);
e->appendChild(tag);
@@ -669,13 +694,13 @@ QString Serializer::escapeEntryData(QString dta)
QString Serializer::unescapeEntryData(QString dta)
{
#ifndef PWM_EMBEDDED
dta.replace("$>--endl--<$", "\n");
dta.replace("||>", "]]>");
#else
- dta.replace(QRegExp("$>--endl--<$"), "\n");
+ dta.replace(QRegExp("\\$>--endl--<\\$"), "\n");
dta.replace(QRegExp("||>"), "]]>");
#endif
return dta;
}
@@ -727,13 +752,13 @@ bool Serializer::readSyncData(const QDomNode &n, vector<PwMSyncItem> *dta)
bool Serializer::addSyncData(QDomElement *e,
const vector<PwMSyncItem> &dta)
{
unsigned int numSync = dta.size(), i;
QString curId, curDeviceName;
- QDomElement curSync, curSyncDate;
+ QDomElement curSync;
QDomText text;
for (i = 0; i < numSync; ++i) {
curId = SYNC_TARGET_PREFIX;
curId += tostr(i).c_str();
curDeviceName = dta[i].syncName.c_str();
@@ -742,14 +767,13 @@ bool Serializer::addSyncData(QDomElement *e,
#ifndef PWM_EMBEDDED
text = domDoc->createTextNode(dta[i].lastSyncDate.toString(Qt::ISODate));
#else
text = domDoc->createTextNode(KGlobal::locale()->formatDateTime(dta[i].lastSyncDate, KLocale::ISODate));
#endif
- curSyncDate.appendChild(text);
- curSync.appendChild(curSyncDate);
+ curSync.appendChild(text);
e->appendChild(curSync);
}
return true;
}