-rw-r--r-- | bin/kdepim/pwmanager/pwmanagerFAQ.txt | 38 | ||||
-rw-r--r-- | pwmanager/pwmanager/pwm.cpp | 57 | ||||
-rw-r--r-- | pwmanager/pwmanager/pwm.h | 8 | ||||
-rw-r--r-- | pwmanager/pwmanager/pwmdoc.cpp | 85 | ||||
-rw-r--r-- | pwmanager/pwmanager/pwmdoc.h | 39 | ||||
-rw-r--r-- | pwmanager/pwmanager/pwmview.cpp | 92 | ||||
-rw-r--r-- | pwmanager/pwmanager/pwmview.h | 25 | ||||
-rw-r--r-- | pwmanager/pwmanager/serializer.cpp | 126 |
8 files changed, 321 insertions, 149 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,10 +1,18 @@ 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 @@ -31,10 +39,32 @@ 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 @@ -131,9 +131,10 @@ enum { // 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 @@ -155,9 +156,9 @@ 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; @@ -357,8 +358,12 @@ void PwM::initMenubar() 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); } @@ -608,8 +613,14 @@ void PwM::addPwd_slot(QString *pw, PwMDoc *_doc) 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(); @@ -618,16 +629,16 @@ void PwM::addPwd_slot(QString *pw, PwMDoc *_doc) 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; } @@ -1286,8 +1297,15 @@ 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> @@ -1325,39 +1343,20 @@ 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(); + + //US curDoc()->sync sets the dirtyFlag in case the sync was successfull. + save(); } 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(); -} - -//called by the syncmanager to indicate that the work has to be saved. -void PwM::sync_save() -{ - PWM_ASSERT(curDoc()); - return curDoc()->sync_save(); -} - - - #endif #ifndef PWM_EMBEDDED 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 @@ -176,8 +176,9 @@ public slots: #ifdef PWM_EMBEDDED void showLicense_slot(); void faq_slot(); void createAboutData_slot(); + void syncHowTo_slot(); #endif protected: /** is this window virgin? */ @@ -271,15 +272,8 @@ protected: #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; 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 @@ -486,9 +486,10 @@ PwMerror PwMDoc::saveDoc(char compress, const QString *file) + " 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)) + " }"); @@ -604,9 +605,11 @@ PwMerror PwMDoc::writeFileHeader(char keyHash, char dataHash, char crypt, char c 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; } @@ -2803,12 +2806,21 @@ 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; @@ -2825,12 +2837,26 @@ void PwMDoc::ensureLvp() 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) { @@ -2847,8 +2873,18 @@ QString PwMDoc::getTitle() * 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); @@ -2926,9 +2962,9 @@ PwMerror PwMDoc::syncronize(KSyncManager* manager, PwMDoc* syncLocal , PwMDoc* s } } 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) @@ -2946,8 +2982,9 @@ PwMerror PwMDoc::syncronize(KSyncManager* manager, PwMDoc* syncLocal , PwMDoc* s } } 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); @@ -2958,10 +2995,10 @@ PwMerror PwMDoc::syncronize(KSyncManager* manager, PwMDoc* syncLocal , PwMDoc* s 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() ); } } @@ -2972,9 +3009,9 @@ PwMerror PwMDoc::syncronize(KSyncManager* manager, PwMDoc* syncLocal , PwMDoc* s 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; @@ -3000,9 +3037,9 @@ PwMerror PwMDoc::syncronize(KSyncManager* manager, PwMDoc* syncLocal , PwMDoc* s 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 ); @@ -3051,8 +3088,9 @@ PwMerror PwMDoc::syncronize(KSyncManager* manager, PwMDoc* syncLocal , PwMDoc* s 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); @@ -3131,18 +3169,18 @@ int PwMDoc::takePwMDataItem( PwMDataItem* local, PwMDataItem* remote, QDateTime 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; @@ -3214,9 +3252,9 @@ bool PwMDoc::sync(KSyncManager* manager, QString filename, int mode) 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; @@ -3266,25 +3304,8 @@ bool PwMDoc::sync(KSyncManager* manager, QString filename, int mode) 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) 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 @@ -129,18 +129,8 @@ struct PwMMetaData 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; @@ -216,20 +206,36 @@ struct PwMDataItem 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; @@ -773,15 +779,8 @@ protected: //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 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 @@ -455,13 +455,93 @@ void PwMView::copyCommentToClip() 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\"> </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")); @@ -477,17 +557,17 @@ PwMDataItemChooser::PwMDataItemChooser( PwMDataItem loc, PwMDataItem rem, bool t 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(); 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 @@ -40,8 +40,9 @@ #include <qevent.h> #include <qfont.h> #include <qobject.h> +#include <qtextbrowser.h> #include <vector> #include <string> @@ -148,8 +149,32 @@ private: 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 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 @@ -26,9 +26,9 @@ #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 @@ -303,8 +303,12 @@ bool Serializer::readEntries(const QDomNode &n, 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); @@ -400,38 +404,44 @@ bool Serializer::extractMeta(const QDomNode &n, 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(); @@ -439,13 +449,8 @@ bool Serializer::extractMeta(const QDomNode &n, printDebug(string("extractMeta(): invalid: ") + name.latin1()); } - if (ok == false) - qDebug("Serializer::extractMeta invalid date or time !!!!!!!!!!!!!"); - - -#endif cur = cur.nextSibling(); } return true; } @@ -603,43 +608,63 @@ bool Serializer::writeMeta(QDomElement *e, { QDomText text; QDomElement tag; - tag = domDoc->createElement(META_CREATE_DATE); + //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)); + text = domDoc->createTextNode(dta.create.toString(Qt::ISODate)); #else - text = domDoc->createTextNode(KGlobal::locale()->formatDateTime(dta.create, KLocale::ISODate)); + text = domDoc->createTextNode(KGlobal::locale()->formatDateTime(dta.create, KLocale::ISODate)); #endif - tag.appendChild(text); - e->appendChild(tag); + tag.appendChild(text); + e->appendChild(tag); + } - tag = domDoc->createElement(META_VALID_DATE); + //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)); + text = domDoc->createTextNode(dta.valid.toString(Qt::ISODate)); #else - text = domDoc->createTextNode(KGlobal::locale()->formatDateTime(dta.valid, KLocale::ISODate)); + text = domDoc->createTextNode(KGlobal::locale()->formatDateTime(dta.valid, KLocale::ISODate)); #endif - tag.appendChild(text); - e->appendChild(tag); + tag.appendChild(text); + e->appendChild(tag); + } - tag = domDoc->createElement(META_EXPIRE_DATE); + //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)); + text = domDoc->createTextNode(dta.expire.toString(Qt::ISODate)); #else - text = domDoc->createTextNode(KGlobal::locale()->formatDateTime(dta.expire, KLocale::ISODate)); + text = domDoc->createTextNode(KGlobal::locale()->formatDateTime(dta.expire, KLocale::ISODate)); #endif - tag.appendChild(text); - e->appendChild(tag); + tag.appendChild(text); + e->appendChild(tag); + } - tag = domDoc->createElement(META_UPDATE_DATE); + //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)); + text = domDoc->createTextNode(dta.update.toString(Qt::ISODate)); #else - text = domDoc->createTextNode(KGlobal::locale()->formatDateTime(dta.update, KLocale::ISODate)); + text = domDoc->createTextNode(KGlobal::locale()->formatDateTime(dta.update, KLocale::ISODate)); #endif - tag.appendChild(text); - e->appendChild(tag); + tag.appendChild(text); + e->appendChild(tag); + } tag = domDoc->createElement(META_UPDATE_INT); text = domDoc->createTextNode(tostr(dta.updateInt).c_str()); tag.appendChild(text); @@ -671,9 +696,9 @@ 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; } @@ -729,9 +754,9 @@ 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; @@ -744,10 +769,9 @@ bool Serializer::addSyncData(QDomElement *e, 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); } |