-rw-r--r-- | pwmanager/pwmanager/csv.cpp | 428 | ||||
-rw-r--r-- | pwmanager/pwmanager/csv.h | 91 | ||||
-rw-r--r-- | pwmanager/pwmanager/pwm.cpp | 85 | ||||
-rw-r--r-- | pwmanager/pwmanager/pwm.h | 4 | ||||
-rw-r--r-- | pwmanager/pwmanager/pwmanagerE.pro | 2 |
5 files changed, 608 insertions, 2 deletions
diff --git a/pwmanager/pwmanager/csv.cpp b/pwmanager/pwmanager/csv.cpp new file mode 100644 index 0000000..194edf2 --- a/dev/null +++ b/pwmanager/pwmanager/csv.cpp @@ -0,0 +1,428 @@ +/*************************************************************************** + * * + * copyright (C) 2004 by Michael Buesch * + * email: mbuesch@freenet.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License version 2 * + * as published by the Free Software Foundation. * + * * + ***************************************************************************/ + +/*************************************************************************** + * copyright (C) 2004 by Ulf Schenk + * This file is originaly based on version 1.1 of pwmanager + * and was modified to run on embedded devices that run microkde + * The original file version was 1.2 + * $Id$ + **************************************************************************/ + +#include "csv.h" +#include "pwmdoc.h" +#include "pwmexception.h" + +#include <kmessagebox.h> +#include <klocale.h> + +#define MAX_CSV_FILE_SIZE (50 * 1024 * 1024) // bytes + + +Csv::Csv(QWidget *_parent) + : parent (_parent) +{ +} + +Csv::~Csv() +{ +} + +bool Csv::importData(const QString &filepath, + PwMDoc *doc) +{ + bool ret = true; + QByteArray d; + QFile f(filepath); + if (!f.open(IO_ReadOnly)) { + KMessageBox::error(parent, + i18n("Could not open file.\n" + "Does the file exist?"), + i18n("Open error.")); + ret = false; + goto out; + } + if (f.size() > MAX_CSV_FILE_SIZE) { + KMessageBox::error(parent, + i18n("File too big.\nMaximum file size is 1 Byte.", "File too big.\nMaximum file size is %n Bytes.", MAX_CSV_FILE_SIZE), + i18n("File too big.")); + ret = false; + goto out_close; + } + d = f.readAll(); + if (d.isEmpty()) { + KMessageBox::error(parent, + i18n("Could not read file or file empty."), + i18n("Reading failed.")); + ret = false; + goto out_close; + } + if (!doImport(d, doc)) { + KMessageBox::error(parent, + i18n("Import failed.\n" + "Corrupt CSV data format."), + i18n("File corrupt.")); + ret = false; + goto out_close; + } + +out_close: + f.close(); +out: + return ret; +} + +bool Csv::doImport(const QByteArray &d, + PwMDoc *doc) +{ + PwMDataItem di; + //US ENH: initialize all members: + di.clear(); + + int refIndex = 0; + int ret; + QCString s, curCat; + int fieldIndex = 0; + bool inRecord = false; + /* fieldIndex is a reference count to see which + * value we are attaching to di. + * Valid counts are: + * 0 -> category + * 1 -> desc + * 2 -> name + * 3 -> pw + * 4 -> url + * 5 -> launcher + * 6 -> comment + */ + + while (1) { + ret = nextField(&s, d, inRecord, &refIndex); + switch (ret) { + case 0: + // successfully got next field. + inRecord = true; + switch (fieldIndex) { + case 0: // category + if (s.isEmpty()) { + /* This is special case. It's the category + * list terminating empty field. + */ + ++fieldIndex; + } else + curCat = s; + break; + case 1: // desc + di.desc = s; + ++fieldIndex; + break; + case 2: // name + di.name = s; + ++fieldIndex; + break; + case 3: // pw + di.pw = s; + ++fieldIndex; + break; + case 4: // url + di.url = s; + ++fieldIndex; + break; + case 5: // launcher + di.launcher = s; + ++fieldIndex; + break; + case 6: // comment + di.comment = s; + ++fieldIndex; + break; + default: + /* Too many fields in a record. + * We simply throw it away. + */ + break; + } + break; + case 1: + // record complete. + if (fieldIndex == 6) + di.comment = s; + inRecord = false; + fieldIndex = 0; + doc->addEntry(curCat, &di, true); + //US ENH: clear di for the next row + di.clear(); + break; + case 2: + // data completely parsed. + doc->flagDirty(); + return true; + case -1: + // parse error + doc->flagDirty(); + return false; + } + } + BUG(); + return false; +} + +int Csv::nextField(QCString *ret, + const QByteArray &in, + bool inRecord, + int *_refIndex) +{ + int rv = -2; + char c; + bool inField = false; + bool isQuoted = false; + bool searchingTerminator = false; + int refIndex; + int inSize = static_cast<int>(in.size()); + ret->truncate(0); + + for (refIndex = *_refIndex; refIndex < inSize; ++refIndex) { + c = in.at(refIndex); + if (!inField) { + // we have to search the field beginning, now. + switch (c) { + case ' ': // space + case ' ': // tab + // hm, still not the beginning. Go on.. + break; + case '\r': + case '\n': + if (inRecord) { + /* This is the end of the last field in + * the record. + */ + PWM_ASSERT(ret->isEmpty()); + rv = 1; // record end + goto out; + } else { + // hm, still not the beginning. Go on.. + break; + } + case ',': + // Oh, an empty field. How sad. + PWM_ASSERT(ret->isEmpty()); + rv = 0; // field end + goto out; + case '\"': + // this is the quoted beginning. + inField = true; + isQuoted = true; + if (refIndex + 1 >= inSize) + goto unexp_eof; + break; + default: + // this is the unquoted beginning. + inField = true; + isQuoted = false; + *ret += c; + break; + } + } else { + // we are in the field now. Search the end. + if (isQuoted) { + if (searchingTerminator) { + switch (c) { + case '\r': + case '\n': + rv = 1; // record end + goto out; + case ',': + // found it. + rv = 0; // field end + goto out; + default: + // go on. + continue; + } + } + switch (c) { + case '\"': + /* check if this is the end of the + * entry, or just an inline escaped quote. + */ + char next; + if (refIndex + 1 >= inSize) { + // This is the last char, so it's the end. + rv = 2; // data end + goto out; + } + next = in.at(refIndex + 1); + switch (next) { + case '\"': + // This is an escaped double quote. + // So skip next iteration. + refIndex += 1; + *ret += c; + break; + default: + /* end of field. + * We have to search the comma (or newline...), + * which officially terminates the entry. + */ + searchingTerminator = true; + break; + } + break; + default: + // nothing special about the char. Go on! + *ret += c; + break; + } + } else { + switch (c) { + case '\"': + // This is not allowed here. + return -1; // parser error + case '\r': + case '\n': + rv = 1; // record end + goto out; + case ',': + rv = 0; // field end + goto out; + default: + // nothing special about the char. Go on! + *ret += c; + break; + } + } + } + } + // we are at the end of the stream, now! + if (searchingTerminator) { + /* Ok, there's no terminating comma (or newline...), + * because we are at the end. That's perfectly fine. + */ + PWM_ASSERT(inField); + rv = 2; // data end + goto out; + } + if (!isQuoted && inField) { + // That's the end of the last unquoted field. + rv = 2; // data end + goto out; + } + if (!inField) { + // This is expected EOF + rv = 2; // data end + goto out; + } + +unexp_eof: + printDebug("unexpected EOF :("); + return -1; // parser error + +out: + if (!isQuoted) + *ret = ret->stripWhiteSpace(); + *_refIndex = refIndex + 1; + return rv; +} + +bool Csv::exportData(const QString &filepath, + PwMDoc *doc) +{ + PWM_ASSERT(!doc->isDocEmpty()); + bool ret = true; + if (QFile::exists(filepath)) { + int ret; + ret = KMessageBox::questionYesNo(parent, + i18n("This file does already exist.\n" + "Do you want to overwrite it?"), + i18n("Overwrite file?")); + if (ret == KMessageBox::No) + return false; + if (!QFile::remove(filepath)) { + KMessageBox::error(parent, + i18n("Could not delete the old file."), + i18n("Delete error.")); + return false; + } + } + QFile f(filepath); + if (!f.open(IO_ReadWrite)) { + KMessageBox::error(parent, + i18n("Could not open file for writing."), + i18n("Open error.")); + ret = false; + goto out; + } + doc->unlockAll_tempoary(); + if (!doExport(f, doc)) + ret = false; + doc->unlockAll_tempoary(true); + f.close(); +out: + return ret; +} + +bool Csv::doExport(QFile &f, + PwMDoc *doc) +{ + unsigned int numCat = doc->numCategories(); + unsigned int numEntr; + unsigned int i, j; + PwMDataItem d; + QCString s, catName; + QByteArray b; + + for (i = 0; i < numCat; ++i) { + numEntr = doc->numEntries(i); + catName = newField(doc->getCategory(i)->c_str()); + for (j = 0; j < numEntr; ++j) { + doc->getEntry(i, j, &d); + s = catName; + s += ",,"; + s += newField(d.desc.c_str()); + s += ","; + s += newField(d.name.c_str()); + s += ","; + s += newField(d.pw.c_str()); + s += ","; + s += newField(d.url.c_str()); + s += ","; + s += newField(d.launcher.c_str()); + s += ","; + s += newField(d.comment.c_str()); + s += "\r\n"; + b = s; + // remove \0 termination +#ifndef PWM_EMBEDDED + b.resize(b.size() - 1, QGArray::SpeedOptim); +#else + b.resize(b.size() - 1); +#endif + if (!f.writeBlock(b)) + return false; + } + } + return true; +} + +QCString Csv::newField(QCString s) +{ + if (s.isEmpty()) + return QCString(); + QCString ret("\""); +#ifndef PWM_EMBEDDED + s.replace('\"', "\"\""); +#else + s.replace(QRegExp("\""), "\"\""); +#endif + ret += s; + ret += "\""; + return ret; +} diff --git a/pwmanager/pwmanager/csv.h b/pwmanager/pwmanager/csv.h new file mode 100644 index 0000000..6f3c1e1 --- a/dev/null +++ b/pwmanager/pwmanager/csv.h @@ -0,0 +1,91 @@ +/*************************************************************************** + * * + * copyright (C) 2004 by Michael Buesch * + * email: mbuesch@freenet.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License version 2 * + * as published by the Free Software Foundation. * + * * + ***************************************************************************/ + +/*************************************************************************** + * copyright (C) 2004 by Ulf Schenk + * This file is originaly based on version 1.1 of pwmanager + * and was modified to run on embedded devices that run microkde + * The original file version was 1.2 + * $Id$ + **************************************************************************/ + + +#ifndef __PWMANAGER_CSV_H +#define __PWMANAGER_CSV_H + +#include <qcstring.h> +#include <qfile.h> + + +class PwMDoc; +class QString; +class QWidget; + +/** class for CSV (Comma Separated Value) export and import. + * + * http://www.creativyst.com/Doc/Articles/CSV/CSV01.htm + * http://en.wikipedia.org/wiki/Comma-separated_values + * + * There are two types of CSV output we can produce. + * One with Category support (recommended): + * "Category 1",, "Desc 1", "Username 1", "Password 1", "URL 1", "Launcher 1", "Comment 1" + * "Category 1",, "Desc 2", "Username 2", "Password 2", "URL 2", "Launcher 2", "Comment 2" + * ... + * The empty "" is neccessary, because in future versions we will + * support nested Categories. We want to be future compatible, now. + * + * And one without Category support: + *FIXME: it's not implemented, yet. ;) + * "Desc 1", "Username 1", "Password 1", "URL 1", "Launcher 1", "Comment 1" + * "Desc 2", "Username 2", "Password 2", "URL 2", "Launcher 2", "Comment 2" + * ... + * + */ +class Csv +{ +public: + Csv(QWidget *_parent); + ~Csv(); + + /** import data from "filepath" into "doc" */ + bool importData(const QString &filepath, + PwMDoc *doc); + /** export data from "doc" to "filepath" */ + bool exportData(const QString &filepath, + PwMDoc *doc); + +protected: + /** do the import process. */ + bool doImport(const QByteArray &d, + PwMDoc *doc); + /** parse for the next field. + * @return Return values are: + * 0 -> successfully got the next field. + * 1 -> record end. + * 2 -> data end. + * -1 -> parser error. + */ + int nextField(QCString *ret, + const QByteArray &in, + bool inRecord, + int *_refIndex); + /** do the export process. */ + bool doExport(QFile &f, + PwMDoc *doc); + /** generate a new data field string. */ + QCString newField(QCString s); + +protected: + /** current parent widget. */ + QWidget *parent; +}; + +#endif // __PWMANAGER_CSV_H diff --git a/pwmanager/pwmanager/pwm.cpp b/pwmanager/pwmanager/pwm.cpp index 66d26d6..ac0c978 100644 --- a/pwmanager/pwmanager/pwm.cpp +++ b/pwmanager/pwmanager/pwm.cpp @@ -1,1373 +1,1454 @@ /*************************************************************************** * * * copyright (C) 2003, 2004 by Michael Buesch * * email: mbuesch@freenet.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation. * * * ***************************************************************************/ /*************************************************************************** * copyright (C) 2004 by Ulf Schenk * This file is originaly based on version 1.0.1 of pwmanager * and was modified to run on embedded devices that run microkde * * $Id$ **************************************************************************/ #include <klocale.h> #include <klistview.h> #include <ktoolbar.h> #include <kfiledialog.h> #include <kiconloader.h> #include <kmessagebox.h> #ifndef PWM_EMBEDDED #include <kmenubar.h> #include <kstatusbar.h> #include <dcopclient.h> #include "configwndimpl.h" #include "configuration.h" #else #include <qmenubar.h> #include <qmessagebox.h> #include <pwmprefs.h> #include <kpimglobalprefs.h> #include <kcmconfigs/kcmpwmconfig.h> #include <kcmconfigs/kcmkdepimconfig.h> #include <kcmultidialog.h> #endif #include <qpixmap.h> #include <qcheckbox.h> #include <qspinbox.h> #include <qlineedit.h> #include <qfileinfo.h> #include <qclipboard.h> #include <stdio.h> #include "pwm.h" #include "pwminit.h" #include "pwmprint.h" #include "addentrywndimpl.h" #include "globalstuff.h" #include "findwndimpl.h" +#include "csv.h" #ifdef CONFIG_KWALLETIF # include "kwalletif.h" # include "kwalletemu.h" #endif #ifdef CONFIG_KEYCARD # include "pwmkeycard.h" #endif #define DEFAULT_SIZE (QSize(700, 400)) // Button IDs for "file" popup menu enum { BUTTON_POPUP_FILE_NEW = 0, BUTTON_POPUP_FILE_OPEN, BUTTON_POPUP_FILE_CLOSE, BUTTON_POPUP_FILE_SAVE, BUTTON_POPUP_FILE_SAVEAS, BUTTON_POPUP_FILE_EXPORT, BUTTON_POPUP_FILE_IMPORT, BUTTON_POPUP_FILE_PRINT, BUTTON_POPUP_FILE_QUIT }; // Button IDs for "manage" popup menu enum { BUTTON_POPUP_MANAGE_ADD = 0, BUTTON_POPUP_MANAGE_EDIT, BUTTON_POPUP_MANAGE_DEL, BUTTON_POPUP_MANAGE_CHANGEMP }; // Button IDs for chipcard popup menu enum { #ifdef CONFIG_KEYCARD BUTTON_POPUP_CHIPCARD_GENNEW = 0, BUTTON_POPUP_CHIPCARD_DEL, BUTTON_POPUP_CHIPCARD_READID, BUTTON_POPUP_CHIPCARD_SAVEBACKUP, BUTTON_POPUP_CHIPCARD_REPLAYBACKUP #else // CONFIG_KEYCARD BUTTON_POPUP_CHIPCARD_NO = 0 #endif // CONFIG_KEYCARD }; // Button IDs for "view" popup menu enum { BUTTON_POPUP_VIEW_FIND = 0, BUTTON_POPUP_VIEW_LOCK, BUTTON_POPUP_VIEW_DEEPLOCK, BUTTON_POPUP_VIEW_UNLOCK }; // Button IDs for "options" popup menu enum { BUTTON_POPUP_OPTIONS_CONFIG = 0 }; // Button IDs for "export" popup menu (in "file" popup menu) enum { BUTTON_POPUP_EXPORT_TEXT = 0, - BUTTON_POPUP_EXPORT_GPASMAN + BUTTON_POPUP_EXPORT_GPASMAN, + BUTTON_POPUP_EXPORT_CSV #ifdef CONFIG_KWALLETIF ,BUTTON_POPUP_EXPORT_KWALLET #endif }; // Button IDs for "import" popup menu (in "file" popup menu) enum { BUTTON_POPUP_IMPORT_TEXT = 0, - BUTTON_POPUP_IMPORT_GPASMAN + BUTTON_POPUP_IMPORT_GPASMAN, + BUTTON_POPUP_IMPORT_CSV #ifdef CONFIG_KWALLETIF ,BUTTON_POPUP_IMPORT_KWALLET #endif }; #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_SYNC, BUTTON_POPUP_HELP_WHATSNEW }; #endif // Button IDs for toolbar enum { BUTTON_TOOL_NEW = 0, BUTTON_TOOL_OPEN, BUTTON_TOOL_SAVE, BUTTON_TOOL_SAVEAS, BUTTON_TOOL_PRINT, BUTTON_TOOL_ADD, BUTTON_TOOL_EDIT, BUTTON_TOOL_DEL, BUTTON_TOOL_FIND, BUTTON_TOOL_LOCK, BUTTON_TOOL_DEEPLOCK, BUTTON_TOOL_UNLOCK }; PwM::PwM(PwMInit *_init, PwMDoc *doc, bool virginity, QWidget *parent, const char *name) : KMainWindow(parent, "HALLO") , forceQuit (false) , forceMinimizeToTray (false) { init = _init; connect(doc, SIGNAL(docClosed(PwMDoc *)), this, SLOT(docClosed(PwMDoc *))); initMenubar(); initToolbar(); initMetrics(); setVirgin(virginity); setFocusPolicy(QWidget::WheelFocus); #ifndef PWM_EMBEDDED statusBar()->show(); #endif view = makeNewListView(doc); setCentralWidget(view); updateCaption(); showStatMsg(i18n("Ready.")); } PwM::~PwM() { + //qDebug("PwM::~PwM()"); disconnect(curDoc(), SIGNAL(docClosed(PwMDoc *)), this, SLOT(docClosed(PwMDoc *))); conf()->confWndMainWndSize(size()); emit closed(this); + //qDebug("PwM::~PwM() emited closed(this)"); delete view; } void PwM::initMenubar() { KIconLoader* picons; #ifndef PWM_EMBEDDED KIconLoader icons; picons = &icons; #else picons = KGlobal::iconLoader(); syncPopup = new KPopupMenu(this); syncManager = new KSyncManager((QWidget*)this, (KSyncInterface*)this, KSyncManager::PWMPI, PWMPrefs::instance(), syncPopup); syncManager->setBlockSave(false); connect ( syncPopup, SIGNAL( activated ( int ) ), syncManager, SLOT (slotSyncMenu( int ) ) ); syncManager->fillSyncMenu(); #endif filePopup = new KPopupMenu(this); importPopup = new KPopupMenu(filePopup); exportPopup = new KPopupMenu(filePopup); managePopup = new KPopupMenu(this); #ifdef CONFIG_KEYCARD chipcardPopup = new KPopupMenu(this); #endif // CONFIG_KEYCARD viewPopup = new KPopupMenu(this); optionsPopup = new KPopupMenu(this); // "file" popup menu filePopup->insertItem(QIconSet(picons->loadIcon("filenew", KIcon::Small)), i18n("&New"), this, SLOT(new_slot()), 0, BUTTON_POPUP_FILE_NEW); filePopup->insertItem(QIconSet(picons->loadIcon("fileopen", KIcon::Small)), i18n("&Open"), this, SLOT(open_slot()), 0, BUTTON_POPUP_FILE_OPEN); filePopup->insertItem(QIconSet(picons->loadIcon("fileclose", KIcon::Small)), i18n("&Close"), this, SLOT(close_slot()), 0, BUTTON_POPUP_FILE_CLOSE); filePopup->insertSeparator(); filePopup->insertItem(QIconSet(picons->loadIcon("filesave", KIcon::Small)), i18n("&Save"), this, SLOT(save_slot()), 0, BUTTON_POPUP_FILE_SAVE); filePopup->insertItem(QIconSet(picons->loadIcon("filesaveas", KIcon::Small)), i18n("Save &as..."), this, SLOT(saveAs_slot()), 0, BUTTON_POPUP_FILE_SAVEAS); filePopup->insertSeparator(); // "file/export" popup menu exportPopup->insertItem(i18n("&Text-file..."), this, SLOT(exportToText()), 0, BUTTON_POPUP_EXPORT_TEXT); exportPopup->insertItem(i18n("&Gpasman / Kpasman ..."), this, SLOT(exportToGpasman()), 0, BUTTON_POPUP_EXPORT_GPASMAN); + exportPopup->insertItem(i18n("&CSV (Comma Separated Value) ..."), this, + SLOT(exportToCsv()), 0, BUTTON_POPUP_EXPORT_CSV); #ifdef CONFIG_KWALLETIF exportPopup->insertItem(i18n("&KWallet..."), this, SLOT(exportToKWallet()), 0, BUTTON_POPUP_EXPORT_KWALLET); #endif filePopup->insertItem(QIconSet(picons->loadIcon("fileexport", KIcon::Small)), i18n("E&xport"), exportPopup, BUTTON_POPUP_FILE_EXPORT); // "file/import" popup menu importPopup->insertItem(i18n("&Text-file..."), this, SLOT(importFromText()), 0, BUTTON_POPUP_IMPORT_TEXT); importPopup->insertItem(i18n("&Gpasman / Kpasman ..."), this, SLOT(importFromGpasman()), 0, BUTTON_POPUP_IMPORT_GPASMAN); + importPopup->insertItem(i18n("&CSV (Comma Separated Value) ..."), this, + SLOT(importCsv()), 0, BUTTON_POPUP_IMPORT_CSV); #ifdef CONFIG_KWALLETIF importPopup->insertItem(i18n("&KWallet..."), this, SLOT(importKWallet()), 0, BUTTON_POPUP_IMPORT_KWALLET); #endif filePopup->insertItem(QIconSet(picons->loadIcon("fileimport", KIcon::Small)), i18n("I&mport"), importPopup, BUTTON_POPUP_FILE_IMPORT); filePopup->insertSeparator(); filePopup->insertItem(QIconSet(picons->loadIcon("fileprint", KIcon::Small)), i18n("&Print..."), this, SLOT(print_slot()), 0, BUTTON_POPUP_FILE_PRINT); filePopup->insertSeparator(); filePopup->insertItem(QIconSet(picons->loadIcon("exit", KIcon::Small)), i18n("&Quit"), this, SLOT(quitButton_slot()), 0, BUTTON_POPUP_FILE_QUIT); menuBar()->insertItem(i18n("&File"), filePopup); // "manage" popup menu managePopup->insertItem(QIconSet(picons->loadIcon("pencil", KIcon::Small)), i18n("&Add password"), this, SLOT(addPwd_slot()), 0, BUTTON_POPUP_MANAGE_ADD); managePopup->insertItem(QIconSet(picons->loadIcon("edit", KIcon::Small)), i18n("&Edit"), this, SLOT(editPwd_slot()), 0, BUTTON_POPUP_MANAGE_EDIT); managePopup->insertItem(QIconSet(picons->loadIcon("editdelete", KIcon::Small)), i18n("&Delete"), this, SLOT(deletePwd_slot()), 0, BUTTON_POPUP_MANAGE_DEL); managePopup->insertSeparator(); managePopup->insertItem(QIconSet(picons->loadIcon("rotate", KIcon::Small)), i18n("Change &Master Password"), this, SLOT(changeMasterPwd_slot()), 0, BUTTON_POPUP_MANAGE_CHANGEMP); menuBar()->insertItem(i18n("&Manage"), managePopup); // "chipcard" popup menu #ifdef CONFIG_KEYCARD chipcardPopup->insertItem(QIconSet(picons->loadIcon("filenew", KIcon::Small)), i18n("&Generate new key-card"), this, SLOT(genNewCard_slot()), 0, BUTTON_POPUP_CHIPCARD_GENNEW); chipcardPopup->insertItem(QIconSet(picons->loadIcon("editdelete", KIcon::Small)), i18n("&Erase key-card"), this, SLOT(eraseCard_slot()), 0, BUTTON_POPUP_CHIPCARD_DEL); chipcardPopup->insertItem(QIconSet(picons->loadIcon("", KIcon::Small)), i18n("Read card-&ID"), this, SLOT(readCardId_slot()), 0, BUTTON_POPUP_CHIPCARD_READID); chipcardPopup->insertSeparator(); chipcardPopup->insertItem(QIconSet(picons->loadIcon("2rightarrow", KIcon::Small)), i18n("&Make card backup-image"), this, SLOT(makeCardBackup_slot()), 0, BUTTON_POPUP_CHIPCARD_SAVEBACKUP); chipcardPopup->insertItem(QIconSet(picons->loadIcon("2leftarrow", KIcon::Small)), i18n("&Replay card backup-image"), this, SLOT(replayCardBackup_slot()), 0, BUTTON_POPUP_CHIPCARD_REPLAYBACKUP); menuBar()->insertItem(i18n("&Chipcard manager"), chipcardPopup); #endif // CONFIG_KEYCARD // "view" popup menu viewPopup->insertItem(QIconSet(picons->loadIcon("find", KIcon::Small)), i18n("&Find"), this, SLOT(find_slot()), 0, BUTTON_POPUP_VIEW_FIND); viewPopup->insertSeparator(); viewPopup->insertItem(QIconSet(picons->loadIcon("halfencrypted", KIcon::Small)), i18n("&Lock all entries"), this, SLOT(lockWnd_slot()), 0, BUTTON_POPUP_VIEW_LOCK); viewPopup->insertItem(QIconSet(picons->loadIcon("encrypted", KIcon::Small)), i18n("&Deep-lock all entries"), this, SLOT(deepLockWnd_slot()), 0, BUTTON_POPUP_VIEW_DEEPLOCK); viewPopup->insertItem(QIconSet(picons->loadIcon("decrypted", KIcon::Small)), i18n("&Unlock all entries"), this, SLOT(unlockWnd_slot()), 0, BUTTON_POPUP_VIEW_UNLOCK); menuBar()->insertItem(i18n("&View"), viewPopup); // "options" popup menu optionsPopup->insertItem(QIconSet(picons->loadIcon("configure", KIcon::Small)), i18n("&Configure..."), this, SLOT(config_slot()), BUTTON_POPUP_OPTIONS_CONFIG); menuBar()->insertItem(i18n("&Options"), optionsPopup); // "help" popup menu #ifndef PWM_EMBEDDED helpPopup = helpMenu(QString::null, false); #else menuBar()->insertItem(i18n("&Sync"), syncPopup); helpPopup = new KPopupMenu(this); helpPopup->insertItem(i18n("&License"), this, SLOT(showLicense_slot()), 0, BUTTON_POPUP_HELP_LICENSE); helpPopup->insertItem(i18n("&Faq"), this, SLOT(faq_slot()), 0, 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); helpPopup->insertItem(i18n("&What's New"), this, SLOT(whatsnew_slot()), 0, BUTTON_POPUP_HELP_WHATSNEW); #endif menuBar()->insertItem(i18n("&Help"), helpPopup); } void PwM::initToolbar() { KIconLoader* picons; #ifndef PWM_EMBEDDED KIconLoader icons; picons = &icons; #else picons = KGlobal::iconLoader(); #endif #ifdef PWM_EMBEDDED if ( QApplication::desktop()->width() > 320 ) #endif { toolBar()->insertButton(picons->loadIcon("filenew", KIcon::Toolbar), BUTTON_TOOL_NEW, SIGNAL(clicked(int)), this, SLOT(new_slot()), true, i18n("New")); toolBar()->insertButton(picons->loadIcon("fileopen", KIcon::Toolbar), BUTTON_TOOL_OPEN, SIGNAL(clicked(int)), this, SLOT(open_slot()), true, i18n("Open")); toolBar()->insertSeparator(); } toolBar()->insertButton(picons->loadIcon("filesave", KIcon::Toolbar), BUTTON_TOOL_SAVE, SIGNAL(clicked(int)), this, SLOT(save_slot()), true, i18n("Save")); toolBar()->insertButton(picons->loadIcon("filesaveas", KIcon::Toolbar), BUTTON_TOOL_SAVEAS, SIGNAL(clicked(int)), this, SLOT(saveAs_slot()), true, i18n("Save as")); toolBar()->insertButton(picons->loadIcon("fileprint", KIcon::Toolbar), BUTTON_TOOL_PRINT, SIGNAL(clicked(int)), this, SLOT(print_slot()), true, i18n("Print...")); toolBar()->insertSeparator(); toolBar()->insertButton(picons->loadIcon("pencil", KIcon::Toolbar), BUTTON_TOOL_ADD, SIGNAL(clicked(int)), this, SLOT(addPwd_slot()), true, i18n("Add password")); toolBar()->insertButton(picons->loadIcon("edit", KIcon::Toolbar), BUTTON_TOOL_EDIT, SIGNAL(clicked(int)), this, SLOT(editPwd_slot()), true, i18n("Edit password")); toolBar()->insertButton(picons->loadIcon("editdelete", KIcon::Toolbar), BUTTON_TOOL_DEL, SIGNAL(clicked(int)), this, SLOT(deletePwd_slot()), true, i18n("Delete password")); toolBar()->insertSeparator(); toolBar()->insertButton(picons->loadIcon("find", KIcon::Toolbar), BUTTON_TOOL_FIND, SIGNAL(clicked(int)), this, SLOT(find_slot()), true, i18n("Find entry")); toolBar()->insertSeparator(); toolBar()->insertButton(picons->loadIcon("halfencrypted", KIcon::Toolbar), BUTTON_TOOL_LOCK, SIGNAL(clicked(int)), this, SLOT(lockWnd_slot()), true, i18n("Lock all entries")); toolBar()->insertButton(picons->loadIcon("encrypted", KIcon::Toolbar), BUTTON_TOOL_DEEPLOCK, SIGNAL(clicked(int)), this, SLOT(deepLockWnd_slot()), true, i18n("Deep-Lock all entries")); toolBar()->insertButton(picons->loadIcon("decrypted", KIcon::Toolbar), BUTTON_TOOL_UNLOCK, SIGNAL(clicked(int)), this, SLOT(unlockWnd_slot()), true, i18n("Unlock all entries")); } void PwM::initMetrics() { QSize s = conf()->confWndMainWndSize(); if (s.isValid()) resize(s); else resize(DEFAULT_SIZE); } void PwM::updateCaption() { setPlainCaption(curDoc()->getTitle() + " - " PROG_NAME " " PACKAGE_VER); } void PwM::hideEvent(QHideEvent *) { if (isMinimized()) { if (init->tray()) { forceMinimizeToTray = true; close(); } int mmlock = conf()->confGlobMinimizeLock(); switch (mmlock) { case 0: // don't lock anything break; case 1: { // normal lock curDoc()->lockAll(true); break; } case 2: { // deep-lock curDoc()->deepLock(); break; } default: WARN(); } } } void PwM::setVirgin(bool v) { if (virgin == v) return; virgin = v; filePopup->setItemEnabled(BUTTON_POPUP_FILE_SAVE, !v); filePopup->setItemEnabled(BUTTON_POPUP_FILE_SAVEAS, !v); filePopup->setItemEnabled(BUTTON_POPUP_FILE_EXPORT, !v); filePopup->setItemEnabled(BUTTON_POPUP_FILE_PRINT, !v); managePopup->setItemEnabled(BUTTON_POPUP_MANAGE_EDIT, !v); managePopup->setItemEnabled(BUTTON_POPUP_MANAGE_DEL, !v); managePopup->setItemEnabled(BUTTON_POPUP_MANAGE_CHANGEMP, !v); viewPopup->setItemEnabled(BUTTON_POPUP_VIEW_LOCK, !v); viewPopup->setItemEnabled(BUTTON_POPUP_VIEW_DEEPLOCK, !v); viewPopup->setItemEnabled(BUTTON_POPUP_VIEW_UNLOCK, !v); viewPopup->setItemEnabled(BUTTON_POPUP_VIEW_FIND, !v); toolBar()->setItemEnabled(BUTTON_TOOL_SAVE, !v); toolBar()->setItemEnabled(BUTTON_TOOL_SAVEAS, !v); toolBar()->setItemEnabled(BUTTON_TOOL_PRINT, !v); toolBar()->setItemEnabled(BUTTON_TOOL_EDIT, !v); toolBar()->setItemEnabled(BUTTON_TOOL_DEL, !v); toolBar()->setItemEnabled(BUTTON_TOOL_LOCK, !v); toolBar()->setItemEnabled(BUTTON_TOOL_DEEPLOCK, !v); toolBar()->setItemEnabled(BUTTON_TOOL_UNLOCK, !v); toolBar()->setItemEnabled(BUTTON_TOOL_FIND, !v); } void PwM::new_slot() { init->createMainWnd(); } //US ENH void PwM::open_slot() { open_slot(""); } void PwM::open_slot(QString fn) { openDoc(fn); } PwMDoc * PwM::openDoc(QString filename, bool openDeepLocked) { if (!isVirgin()) { // open the document in a new window. PwM *newInstance = init->createMainWnd(); PwMDoc *newDoc = newInstance->openDoc(filename, openDeepLocked); if (!newDoc) { newInstance->setForceQuit(true); delete_and_null(newInstance); } return newDoc; } if (!curDoc()->openDocUi(curDoc(), filename, openDeepLocked)) return 0; showStatMsg(i18n("Successfully opened file.")); updateCaption(); setVirgin(false); return curDoc(); } PwMView * PwM::makeNewListView(PwMDoc *doc) { PwMView *ret = new PwMView(this, this, doc); ret->setFont(conf()->confGlobEntryFont()); ret->show(); return ret; } void PwM::close_slot() { close(); } void PwM::quitButton_slot() { init->shutdownApp(0); } void PwM::save_slot() { save(); } bool PwM::save() { if (!curDoc()->saveDocUi(curDoc())) return false; showStatMsg(i18n("Successfully saved data.")); updateCaption(); return true; } void PwM::saveAs_slot() { saveAs(); } bool PwM::saveAs() { if (!curDoc()->saveAsDocUi(curDoc())) return false; showStatMsg(i18n("Successfully saved data.")); updateCaption(); return true; } //US ENH : changed code to run with older MOC void PwM::addPwd_slot() { addPwd_slot1(0, 0); } void PwM::addPwd_slot1(QString *pw, PwMDoc *_doc) { PwMDoc *doc; if (_doc) { doc = _doc; } else { doc = curDoc(); } PWM_ASSERT(doc); doc->timer()->getLock(DocTimer::id_autoLockTimer); #ifndef PWM_EMBEDDED AddEntryWndImpl w; #else AddEntryWndImpl w(this, "addentrywndimpl"); #endif vector<string> catList; doc->getCategoryList(&catList); unsigned i, size = catList.size(); for (i = 0; i < size; ++i) { w.addCategory(catList[i].c_str()); } w.setCurrCategory(view->getCurrentCategory()); if (pw) 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\",\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\nentries" "has been reached.\nYou can't add more entries."), i18n("maximum number of entries")); doc->timer()->putLock(DocTimer::id_autoLockTimer); return; } } setVirgin(false); doc->timer()->putLock(DocTimer::id_autoLockTimer); } //US ENH : changed code to run with older MOC void PwM::editPwd_slot() { editPwd_slot3(0,0,0); } void PwM::editPwd_slot1(const QString *category) { editPwd_slot3(category, 0, 0); } void PwM::editPwd_slot3(const QString *category, const int *index, PwMDoc *_doc) { PwMDoc *doc; if (_doc) { doc = _doc; } else { doc = curDoc(); } PWM_ASSERT(doc); if (doc->isDocEmpty()) return; if (doc->isDeepLocked()) return; doc->timer()->getLock(DocTimer::id_autoLockTimer); unsigned int curEntryIndex; if (index) { curEntryIndex = *index; } else { if (!(view->getCurEntryIndex(&curEntryIndex))) { printDebug("couldn't get index. Maybe we have a binary entry here."); doc->timer()->putLock(DocTimer::id_autoLockTimer); return; } } QString curCategory; if (category) { curCategory = *category; } else { curCategory = view->getCurrentCategory(); } PwMDataItem currItem; if (!doc->getEntry(curCategory, curEntryIndex, &currItem, true)) { doc->timer()->putLock(DocTimer::id_autoLockTimer); return; } BUG_ON(currItem.binary); AddEntryWndImpl w; vector<string> catList; doc->getCategoryList(&catList); unsigned i, size = catList.size(); for (i = 0; i < size; ++i) { w.addCategory(catList[i].c_str()); } w.setCurrCategory(curCategory); w.setDescription(currItem.desc.c_str()); w.setUsername(currItem.name.c_str()); w.setPassword(currItem.pw.c_str()); w.setUrl(currItem.url.c_str()); w.setLauncher(currItem.launcher.c_str()); w.setComment(currItem.comment.c_str()); if (w.exec() == 1) { currItem.desc = w.getDescription().latin1(); currItem.name = w.getUsername().latin1(); currItem.pw = w.getPassword().latin1(); currItem.comment = w.getComment().latin1(); currItem.url = w.getUrl().latin1(); currItem.launcher = w.getLauncher().latin1(); if (!doc->editEntry(curCategory, w.getCategory(), curEntryIndex, &currItem)) { KMessageBox::error(this, i18n("Couldn't edit the entry.\n" "Maybe you changed the category and\n" "this entry is already present\nin the new " "category?"), i18n("couldn't edit entry.")); doc->timer()->putLock(DocTimer::id_autoLockTimer); return; } } doc->timer()->putLock(DocTimer::id_autoLockTimer); } void PwM::deletePwd_slot() { PWM_ASSERT(curDoc()); if (curDoc()->isDocEmpty()) return; if (curDoc()->isDeepLocked()) return; curDoc()->timer()->getLock(DocTimer::id_autoLockTimer); unsigned int curEntryIndex = 0; if (!(view->getCurEntryIndex(&curEntryIndex))) { printDebug("couldn't get index"); curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); return; } PwMDataItem currItem; QString curCategory = view->getCurrentCategory(); if (!curDoc()->getEntry(curCategory, curEntryIndex, &currItem)) { printDebug("couldn't get entry"); curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); return; } if (KMessageBox:: questionYesNo(this, i18n ("Do you really want to delete\nthe selected entry") + " \n\"" + QString(currItem.desc.c_str()) + "\" ?", i18n("delete?")) == KMessageBox::Yes) { curDoc()->delEntry(curCategory, curEntryIndex); } curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); } void PwM::changeMasterPwd_slot() { PWM_ASSERT(curDoc()); curDoc()->changeCurrentPw(); } void PwM::lockWnd_slot() { PWM_ASSERT(curDoc()); curDoc()->lockAll(true); } void PwM::deepLockWnd_slot() { PWM_ASSERT(curDoc()); curDoc()->deepLock(); } void PwM::unlockWnd_slot() { PWM_ASSERT(curDoc()); curDoc()->lockAll(false); } void PwM::config_slot() { int oldStyle = conf()->confWndMainViewStyle(); #ifdef PWM_EMBEDDED KCMultiDialog* ConfigureDialog = new KCMultiDialog( "PIM", this ,"pwmconfigdialog", true ); KCMPwmConfig* pwmcfg = new KCMPwmConfig( ConfigureDialog->getNewVBoxPage(i18n( "PwManager")) , "KCMPwmConfig" ); ConfigureDialog->addModule(pwmcfg ); KCMKdePimConfig* kdelibcfg = new KCMKdePimConfig( ConfigureDialog->getNewVBoxPage(i18n( "Global")) , "KCMKdeLibConfig" ); ConfigureDialog->addModule(kdelibcfg ); #ifndef DESKTOP_VERSION ConfigureDialog->showMaximized(); #endif if ( ConfigureDialog->exec() ) KMessageBox::information( this, i18n("Some changes are only\neffective after a restart!\n") ); delete ConfigureDialog; #else //PWM_EMBEDDED // display the configuration window (modal mode) if (!conf()->showConfWnd(this)) return; #endif int newStyle = conf()->confWndMainViewStyle(); // reinitialize tray init->initTray(); // reinitialize KWallet emulation init->initKWalletEmu(); PwMDocList *_dl = PwMDoc::getOpenDocList(); const vector<PwMDocList::listItem> *dl = _dl->getList(); vector<PwMDocList::listItem>::const_iterator i = dl->begin(), end = dl->end(); PwMDoc *doc; while (i != end) { doc = (*i).doc; // unlock-without-mpw timeout doc->timer()->start(DocTimer::id_mpwTimer); // auto-lock timeout doc->timer()->start(DocTimer::id_autoLockTimer); ++i; } const QValueList<PwM *> *ml = init->mainWndList(); #ifndef PWM_EMBEDDED QValueList<PwM *>::const_iterator i2 = ml->begin(), end2 = ml->end(); #else QValueList<PwM *>::ConstIterator i2 = ml->begin(), end2 = ml->end(); #endif PwM *pwm; while (i2 != end2) { pwm = *i2; // reinitialize the window style. if (oldStyle != newStyle) pwm->curView()->initStyle(newStyle); // set the new font pwm->curView()->setFont(conf()->confGlobEntryFont()); ++i2; } } void PwM::activateMpButton(bool activate) { managePopup->setItemEnabled(BUTTON_POPUP_MANAGE_CHANGEMP, activate); } void PwM::closeEvent(QCloseEvent *e) { e->accept(); } void PwM::docClosed(PwMDoc *doc) { PARAM_UNUSED(doc); PWM_ASSERT(doc == curDoc()); close(); } void PwM::find_slot() { PWM_ASSERT(curDoc()); if (curDoc()->isDocEmpty()) return; if (curDoc()->isDeepLocked()) return; curDoc()->timer()->getLock(DocTimer::id_autoLockTimer); FindWndImpl findWnd(view); findWnd.exec(); curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); } void PwM::exportToText() { PWM_ASSERT(curDoc()); if (curDoc()->isDocEmpty()) { KMessageBox::information(this, i18n ("Sorry, there's nothing to export.\n" "Please first add some passwords."), i18n("nothing to do")); return; } curDoc()->timer()->getLock(DocTimer::id_autoLockTimer); QString fn(KFileDialog::getSaveFileName(QString::null, i18n("*|plain-text file"), this)); if (fn == "") { curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); return; } PwMerror ret = curDoc()->exportToText(&fn); if (ret != e_success) { KMessageBox::error(this, i18n("Error: Couldn't write to file.\n" "Please check if you have permission to write\n" "to the file in that directory."), i18n("error while writing")); } else showStatMsg(i18n("Successfully exported data.")); curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); } bool PwM::importFromText() { if (!isVirgin()) { if (KMessageBox::questionYesNo(this, i18n("Do you want to import the data\n" "into the current document? (If you\n" "select \"no\", a new document will be\n" "opened.)"), i18n("import into this document?")) == KMessageBox::No) { // import the data to a new window. PwM *newInstance = init->createMainWnd(); bool ok = newInstance->importFromText(); if (!ok) { newInstance->setForceQuit(true); delete_and_null(newInstance); } return ok; } } curDoc()->timer()->getLock(DocTimer::id_autoLockTimer); PwMerror ret; QString path(KFileDialog::getOpenFileName(QString::null, i18n("*|PWM-exported text file"), this)); if (path == "") goto cancelImport; ret = curDoc()->importFromText(&path, 0); if (ret == e_fileFormat) { KMessageBox::error(this, i18n("Could not read file-format.\n" "This seems to be _not_ a valid file\n" "exported by PwM."), i18n("invalid file-format")); goto cancelImport; } else if (ret == e_invalidArg) { BUG(); goto cancelImport; } else if (ret != e_success) { KMessageBox::error(this, i18n("Could not import file!\n" "Do you have permission to read this file?\n" "Do you have enough free memory?"), i18n("import failed")); goto cancelImport; } setVirgin(false); curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); return true; cancelImport: curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); return false; } void PwM::exportToGpasman() { PWM_ASSERT(curDoc()); if (curDoc()->isDocEmpty()) { KMessageBox::information(this, i18n ("Sorry, there's nothing to export.\n" "Please first add some passwords."), i18n("nothing to do")); return; } curDoc()->timer()->getLock(DocTimer::id_autoLockTimer); QString fn(KFileDialog::getSaveFileName(QString::null, i18n("*|Gpasman or Kpasman file"), this)); if (fn == "") { curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); return; } PwMerror ret = curDoc()->exportToGpasman(&fn); if (ret != e_success) { if (ret == e_noPw) { curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); return; } KMessageBox::error(this, i18n("Error: Couldn't write to file.\n" "Please check if you have permission to write " "to the file in that directory."), i18n("error while writing")); } else showStatMsg(i18n("Successfully exported data.")); curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); } + + +void PwM::exportToCsv() +{ + PWM_ASSERT(curDoc()); + if (curDoc()->isDocEmpty()) { + KMessageBox::information(this, + i18n + ("Sorry, there is nothing to export;\n" + "please add some passwords first."), + i18n("Nothing to Do")); + return; + } + + curDoc()->timer()->getLock(DocTimer::id_autoLockTimer); + QString fn(KFileDialog::getSaveFileName("*.csv", i18n("*|CSV Text File"), this)); + if (fn.isEmpty()) { + curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); + return; + } + + Csv csv(this); + if (!csv.exportData(fn, curDoc())) { + curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); + showStatMsg(i18n("CSV file export failed.")); + return; + } + showStatMsg(i18n("Successfully exported data.")); + curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); +} + +bool PwM::importCsv() +{ + Csv csv(this); + if (!isVirgin()) { + if (KMessageBox::questionYesNo(this, + i18n("Do you want to import the data\n" + "into the current document? (If you\n" + "select \"no\", a new document will be\n" + "opened.)"), + i18n("Import into This Document?")) + == KMessageBox::No) { + // import the data to a new window. + PwM *newInstance = init->createMainWnd(); + bool ok = newInstance->importCsv(); + if (!ok) { + newInstance->setForceQuit(true); + delete_and_null(newInstance); + } + return ok; + } + } + + QString filename = KFileDialog::getOpenFileName("*.csv", i18n("*|CSV Text File"), this); + if (filename.isEmpty()) + return false; + curDoc()->timer()->getLock(DocTimer::id_autoLockTimer); + if (!csv.importData(filename, curDoc())) { + curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); + showStatMsg(i18n("CSV file import failed.")); + return false; + } + curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); + KMessageBox::information(this, + i18n("Successfully imported the CSV data\n" + "into the current document."), i18n("Successfully Imported")); + showStatMsg(i18n("Successfully imported")); + setVirgin(false); + return true; +} + + void PwM::exportToKWallet() { #ifdef CONFIG_KWALLETIF if (!checkAndAskForKWalletEmu()) return; PWM_ASSERT(curDoc()); if (curDoc()->isDocEmpty()) { KMessageBox::information(this, i18n ("Sorry, there's nothing to export.\n" "Please first add some passwords."), i18n("nothing to do")); init->initKWalletEmu(); return; } curDoc()->timer()->getLock(DocTimer::id_autoLockTimer); KWalletIf walletIf(this); if (walletIf.kwalletExport(curDoc())) { KMessageBox::information(this, i18n("Successfully exported the data of the current " "document to KWallet."), i18n("Successfully exported data.")); showStatMsg(i18n("Successfully exported data.")); } init->initKWalletEmu(); curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); #endif // CONFIG_KWALLETIF } bool PwM::importFromGpasman() { if (!isVirgin()) { if (KMessageBox::questionYesNo(this, i18n("Do you want to import the data\n" "into the current document? (If you\n" "select \"no\", a new document will be\n" "opened.)"), i18n("import into this document?")) == KMessageBox::No) { // import the data to a new window. PwM *newInstance = init->createMainWnd(); bool ok = newInstance->importFromGpasman(); if (!ok) { newInstance->setForceQuit(true); delete_and_null(newInstance); } return ok; } } curDoc()->timer()->getLock(DocTimer::id_autoLockTimer); PwMerror ret; QString path(KFileDialog::getOpenFileName(QString::null, i18n("*|Gpasman or Kpasman file"), this)); if (path == "") goto cancelImport; ret = curDoc()->importFromGpasman(&path); if (ret == e_wrongPw) { if (KMessageBox::questionYesNo(this, i18n ("This is probably the wrong master-password\n" "you have typed in.\n" "There is no real way to determine the\n" "correctness of the password in the Gpasman\n" "file-format. But I think this\n" "password ist wrong.\n" "Do you want to continue nevertheless?"), i18n("password error")) == KMessageBox::No) { goto cancelImport; } } else if (ret != e_success) { KMessageBox::error(this, i18n("Could not import file!\n" "Do you have permission to read this file?"), i18n("import failed")); goto cancelImport; } setVirgin(false); curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); return true; cancelImport: curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); return false; } #ifdef CONFIG_KWALLETIF bool PwM::checkAndAskForKWalletEmu() { if (init->kwalletEmu()) { /* KWallet emulation is enabled. We can't import/export * data from/to it, while emulation is active. */ if (KMessageBox::questionYesNo(this, i18n("KWallet emulation is enabled.\n" "You can't import or export data from/to " "the original KWallet, while the emulation " "is active.\n" "Do you want to tempoarly disable the KWallet emulation?"), i18n("Tempoarly disable KWallet emulation?")) == KMessageBox::Yes) { init->initKWalletEmu(true); PWM_ASSERT(!init->kwalletEmu()); return true; } return false; } return true; } #endif // CONFIG_KWALLETIF bool PwM::importKWallet() { #ifdef CONFIG_KWALLETIF if (!checkAndAskForKWalletEmu()) return false; KWalletIf walletIf(this); if (!isVirgin()) { if (KMessageBox::questionYesNo(this, i18n("Do you want to import the data " "into the current document? (If you " "select \"no\", a new document will be " "opened.)"), i18n("import into this document?")) == KMessageBox::No) { // import the data to a new window. PwM *newInstance = init->createMainWnd(); bool ok = newInstance->importKWallet(); if (!ok) { newInstance->setForceQuit(true); delete_and_null(newInstance); goto exit_fail; } else { goto exit_ok; } } } curDoc()->timer()->getLock(DocTimer::id_autoLockTimer); if (!walletIf.kwalletImport(curDoc())) { curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); showStatMsg(i18n("KWallet import failed")); goto exit_fail; } KMessageBox::information(this, i18n("Successfully imported the KWallet data " "into the current document."), i18n("successfully imported")); showStatMsg(i18n("successfully imported")); setVirgin(false); curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); exit_ok: init->initKWalletEmu(); return true; exit_fail: init->initKWalletEmu(); #endif // CONFIG_KWALLETIF return false; } void PwM::print_slot() { curDoc()->timer()->getLock(DocTimer::id_autoLockTimer); #ifndef PWM_EMBEDDED PwMPrint p(curDoc(), this); p.printNow(); #else qDebug("PwM::print_slot , PRINTING IS NOT IMPLEMENTED"); #endif curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); } void PwM::genNewCard_slot() { #ifdef CONFIG_KEYCARD init->keycard()->genNewCard(); #endif } void PwM::eraseCard_slot() { #ifdef CONFIG_KEYCARD init->keycard()->eraseCard(); #endif } void PwM::readCardId_slot() { #ifdef CONFIG_KEYCARD init->keycard()->displayKey(); #endif } void PwM::makeCardBackup_slot() { #ifdef CONFIG_KEYCARD init->keycard()->makeBackupImage(); #endif } void PwM::replayCardBackup_slot() { #ifdef CONFIG_KEYCARD init->keycard()->replayBackupImage(); #endif } void PwM::execLauncher_slot() { PWM_ASSERT(curDoc()); if (curDoc()->isDeepLocked()) return; unsigned int curEntryIndex; if (!view->getCurEntryIndex(&curEntryIndex)) return; bool ret = curDoc()->execLauncher(view->getCurrentCategory(), curEntryIndex); if (ret) showStatMsg(i18n("Executed the \"Launcher\".")); else showStatMsg(i18n("ERROR: Couldn't execute the \"Launcher\"!")); } void PwM::goToURL_slot() { PWM_ASSERT(curDoc()); if (curDoc()->isDeepLocked()) return; unsigned int curEntryIndex; if (!view->getCurEntryIndex(&curEntryIndex)) return; bool ret = curDoc()->goToURL(view->getCurrentCategory(), curEntryIndex); if (ret) showStatMsg(i18n("started browser with current URL.")); else showStatMsg(i18n("ERROR: Couldn't start browser! Maybe invalid URL?")); } void PwM::copyToClipboard(const QString &s) { QClipboard *cb = QApplication::clipboard(); #ifndef PWM_EMBEDDED if (cb->supportsSelection()) cb->setText(s, QClipboard::Selection); cb->setText(s, QClipboard::Clipboard); #else cb->setText(s); #endif } void PwM::showStatMsg(const QString &msg) { #ifndef PWM_EMBEDDED KStatusBar *statBar = statusBar(); statBar->message(msg, STATUSBAR_MSG_TIMEOUT * 1000); #else qDebug("Statusbar : %s",msg.latin1()); #endif } void PwM::focusInEvent(QFocusEvent *e) { if (e->gotFocus()) { emit gotFocus(this); } else if (e->lostFocus()) { emit lostFocus(this); } } #ifdef PWM_EMBEDDED void PwM::whatsnew_slot() { KApplication::showFile( "KDE-Pim/Pi Version Info", "kdepim/WhatsNew.txt" ); } void PwM::showLicense_slot() { KApplication::showLicence(); } void PwM::faq_slot() { KApplication::showFile( "PWM/Pi FAQ", "kdepim/pwmanager/pwmanagerFAQ.txt" ); } void 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" "(PWM/Pi) " +version + " - " + #ifdef DESKTOP_VERSION "Desktop Edition\n" #else "PDA-Edition\n" "for: Zaurus 5500 / 7x0 / 8x0\n" #endif "(c) 2004 Ulf Schenk\n" "(c) 2004 Lutz Rogowski\n" "(c) 1997-2004, The KDE PIM Team\n" "(c) Michael Buesch - main programming\nand current maintainer\nmbuesch@freenet.de\n" "Matt Scifo - mscifo@o1.com\n" "Elias Probst - elias.probst@gmx.de\n" "George Staikos - staikos@kde.org\n" "Matthew Palmer - mjp16@uow.edu.au\n" "Olivier Sessink - gpasman@nl.linux.org\n" "The libgcrypt developers -\nBlowfish and SHA1 algorithms\nftp://ftp.gnupg.org/gcrypt/alpha/libgcrypt/\n" "Troy Engel - tengel@sonic.net\n" "Wickey - wickey@gmx.at\n" "Ian MacGregor - original documentation author.\n" ); } //this are the overwritten callbackmethods from the syncinterface 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; } #endif #ifndef PWM_EMBEDDED #include "pwm.moc" #endif diff --git a/pwmanager/pwmanager/pwm.h b/pwmanager/pwmanager/pwm.h index 6ab9d6b..5822d59 100644 --- a/pwmanager/pwmanager/pwm.h +++ b/pwmanager/pwmanager/pwm.h @@ -1,293 +1,297 @@ /*************************************************************************** * * * copyright (C) 2003, 2004 by Michael Buesch * * email: mbuesch@freenet.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation. * * * ***************************************************************************/ /*************************************************************************** * copyright (C) 2004 by Ulf Schenk * This file is originaly based on version 1.0.1 of pwmanager * and was modified to run on embedded devices that run microkde * * $Id$ **************************************************************************/ #ifndef __PWM_H #define __PWM_H #include <kpopupmenu.h> #include <klistview.h> #include <kmainwindow.h> #ifndef PWM_EMBEDDED #include <kwin.h> #include <kapp.h> #include <kdeversion.h> #else #include <ksyncmanager.h> #endif #include <kaction.h> #include <qglobal.h> #include "pwmview.h" #include "pwmexception.h" /** timeout for displaying a message on the status-bar (in seconds) */ #define STATUSBAR_MSG_TIMEOUT 5 class PwMInit; class KSyncManager; /** PwM is the base class of the project */ #ifndef PWM_EMBEDDED //MOC_SKIP_BEGIN class PwM : public KMainWindow //MOC_SKIP_END #else class PwM : public KMainWindow, public KSyncInterface #endif { Q_OBJECT public: friend class PwMView; /** construtor */ PwM(PwMInit *_init, PwMDoc *doc, bool virginity = true, QWidget* parent = 0, const char *name = 0); /** destructor */ ~PwM(); /** copy some text to the global clipboard */ static void copyToClipboard(const QString &s); /** returns pointer to the view */ PwMView * curView() { return view; } /** returns pointer to the currently using document. */ PwMDoc * curDoc() { return curView()->document(); } /** open a new doc with the given filename */ PwMDoc * openDoc(QString filename, bool openDeepLocked = false); /** show a message on the global status bar. * The message times out after some seconds. */ void showStatMsg(const QString &msg); /** ask the user where to save the doc (if it has not been saved, yet) * and write the data to disk. */ bool save(); /** ask the user where to save the doc * and write the data to disk. */ bool saveAs(); /** force quit. Quit this window, always! Don't minimize it */ bool isForceQuit() { return forceQuit; } /** set forceQuit */ void setForceQuit(bool force) { forceQuit = force; } /** force minimize this window */ bool isForceMinimizeToTray() { return forceMinimizeToTray; } /** set forceMinimizeToTray */ void setForceMinimizeToTray(bool force) { forceMinimizeToTray = force; } public slots: /** file/new triggered */ void new_slot(); /** file/open triggered */ //US ENH void open_slot(); void open_slot(QString fn); /** file/close triggered */ void close_slot(); /** file/quit triggered */ void quitButton_slot(); /** file/save triggered */ void save_slot(); /** file/saveAs triggered */ void saveAs_slot(); /** file/export/text triggered */ void exportToText(); /** file/export/gpasman triggered */ void exportToGpasman(); /** file/export/kwallet triggered */ void exportToKWallet(); + /** file/export/csv triggered */ + void exportToCsv(); /** file/import/text triggered */ bool importFromText(); /** file/import/gpasman triggered */ bool importFromGpasman(); /** file/import/kwallet triggered */ bool importKWallet(); + /** file/import/csv triggered */ + bool importCsv(); /** file/print triggered */ void print_slot(); /** manage/add triggered */ //US ENH : changed code to run with older MOC void addPwd_slot(); void addPwd_slot1(QString *pw, PwMDoc *_doc); /** manage/edit triggered */ //US ENH : changed code to run with older MOC void editPwd_slot(); void editPwd_slot1(const QString *category); void editPwd_slot3(const QString *category, const int *index ,PwMDoc *_doc ); /** manage/delete triggered */ void deletePwd_slot(); /** execute the "Launcher" entry */ void execLauncher_slot(); /** open browser with URL entry */ void goToURL_slot(); /** manage/changeMasterPwd triggered */ void changeMasterPwd_slot(); /** lock current document */ void lockWnd_slot(); /** deeplock current document */ void deepLockWnd_slot(); /** window/unlock triggered */ void unlockWnd_slot(); /** find item */ void find_slot(); /** configure clicked */ void config_slot(); /** (de)activate the "change master pw" button in the menu-bar */ void activateMpButton(bool activate = true); /** generate a new chipcard */ void genNewCard_slot(); /** completely erase the current card */ void eraseCard_slot(); /** returns the ID number of the current card */ void readCardId_slot(); /** make backup image of the current card */ void makeCardBackup_slot(); /** write backup image to current card */ void replayCardBackup_slot(); #ifdef PWM_EMBEDDED void whatsnew_slot(); void showLicense_slot(); void faq_slot(); void createAboutData_slot(); void syncHowTo_slot(); #endif protected: /** is this window virgin? */ bool isVirgin() { return virgin; } /** add/remove virginity */ void setVirgin(bool v); /** initialize the menubar */ void initMenubar(); /** initialize the toolbar */ void initToolbar(); /** initialize the window-metrics */ void initMetrics(); /** close-event */ void closeEvent(QCloseEvent *e); /** creates a new PwM-ListView and returns it */ PwMView * makeNewListView(PwMDoc *doc); /** Window hide-event */ void hideEvent(QHideEvent *); /** is this window minimized? */ bool isMinimized() { #ifndef PWM_EMBEDDED #if KDE_VERSION >= KDE_MAKE_VERSION(3, 2, 0) return KWin::windowInfo(winId()).isMinimized(); #else // KDE_VERSION return KWin::info(winId()).isIconified(); #endif // KDE_VERSION #else return false; #endif } /** window got the focus */ void focusInEvent(QFocusEvent *e); /** update the caption string */ void updateCaption(); #ifdef CONFIG_KWALLETIF /** check if kwalletemu is enabled and ask the user what to do */ bool checkAndAskForKWalletEmu(); #endif // CONFIG_KWALLETIF protected slots: /** doc got closed */ void docClosed(PwMDoc *doc); signals: /** window got closed (by user or someone else) */ void closed(PwM *wnd); /** window got the focus (was brought to foreground) */ void gotFocus(PwM *wnd); /** window lost the focus */ void lostFocus(PwM *wnd); protected: /** pointer to the view active in this KMainWindow */ PwMView *view; /** pointer to the init class */ PwMInit *init; /** has this window already lost its virginity? * Means is there an open working document */ bool virgin; /** "file" popup-menu */ KPopupMenu *filePopup; /** "manage" popup-menu */ KPopupMenu *managePopup; #ifdef CONFIG_KEYCARD /** "chipcard" popup-menu */ KPopupMenu *chipcardPopup; #endif // CONFIG_KEYCARD /** "view" popup-menu */ KPopupMenu *viewPopup; /** "options" popup-menu */ KPopupMenu *optionsPopup; /** "help" popup-menu */ KPopupMenu *helpPopup; /** "export" popup-menu */ KPopupMenu *exportPopup; /** "import" popup-menu */ KPopupMenu *importPopup; /** force quit this window? */ bool forceQuit; /** force minimize this window to the tray */ bool forceMinimizeToTray; private: #ifdef PWM_EMBEDDED //this are the overwritten callbackmethods from the syncinterface virtual bool sync(KSyncManager* manager, QString filename, int mode); // LR ******************************* // sync stuff! QPopupMenu *syncPopup; KSyncManager* syncManager; #endif }; #endif diff --git a/pwmanager/pwmanager/pwmanagerE.pro b/pwmanager/pwmanager/pwmanagerE.pro index 1445bcf..c46e937 100644 --- a/pwmanager/pwmanager/pwmanagerE.pro +++ b/pwmanager/pwmanager/pwmanagerE.pro @@ -1,169 +1,171 @@ TEMPLATE = app CONFIG += qt warn_on TARGET = pwmpi OBJECTS_DIR = obj/$(PLATFORM) MOC_DIR = moc/$(PLATFORM) DESTDIR=$(QPEDIR)/bin INCLUDEPATH += . ../../ ../../qtcompat ../../qtcompat/xml ../../libkdepim ../../microkde ../../microkde/kdecore ../../microkde/kdeui ../../microkde/kutils ../libcrypt/crypt ../libcrypt/error $(QPEDIR)/include DEFINES += PWM_EMBEDDED CONFIG_PWMANAGER_GCRY #enable this setting if you want debugoutput for pwmanager #DEFINES += CONFIG_DEBUG LIBS += -L../libcrypt/$(PLATFORM) LIBS += -lmicrokde LIBS += -lmicroqtcompat LIBS += -lmicrokdepim LIBS += -L$(QPEDIR)/lib LIBS += -lqpe LIBS += -lzlib #LIBS += -lbz2 #LIBS += -lkpmicrogcrypt LIBS += -ljpeg LIBS += $(QTOPIALIB) LIBS += -lkpmicrocipher LIBS += -lkpmicroerror LIBS += -lkpmicrompi LIBS += -lstdc++ #INTERFACES = \ #addentrywnd.ui \ #configwnd.ui \ #findwnd.ui \ #getmasterpwwnd.ui \ #pwgenwnd.ui \ #setmasterpwwnd.ui \ #subtbledit.ui #INTERFACES = \ #subtbledit.ui \ #HEADERS = \ #configuration_31compat.h \ #configuration.h \ #configwnd.h \ #configwndimpl.h \ #selftest.h #subtbledit.h \ #subtbleditimpl.h \ #compressbzip2.h \ HEADERS = \ addentrywnd_emb.h \ addentrywndimpl.h \ base64.h \ binentrygen.h \ blowfish.h \ commentbox.h \ compiler.h \ compressgzip.h \ +csv.h \ findwnd_emb.h \ findwndimpl.h \ genpasswd.h \ getkeycardwnd.h \ getmasterpwwnd_emb.h \ getmasterpwwndimpl.h \ globalstuff.h \ gpasmanfile.h \ htmlgen.h \ htmlparse.h \ ipc.h \ libgcryptif.h \ listobjselectwnd.h \ listviewpwm.h \ printtext.h \ pwgenwnd_emb.h \ pwgenwndimpl.h \ pwmdoc.h \ pwmdocui.h \ pwmexception.h \ pwm.h \ pwminit.h \ pwmprefs.h \ pwmprint.h \ pwmtray.h \ pwmview.h \ pwmviewstyle_0.h \ pwmviewstyle_1.h \ pwmviewstyle.h \ randomizer.h \ rc2.h \ rencatwnd.h \ serializer.h \ setmasterpwwnd_emb.h \ setmasterpwwndimpl.h \ sha1.h \ waitwnd.h \ kcmconfigs/kcmpwmconfig.h \ kcmconfigs/pwmconfigwidget.h #sources that need not be build #SOURCES = \ #advcommeditimpl.cpp \ #configuration.cpp \ #configwnd.cpp \ #configwndimpl.cpp \ #configuration_31compat.cpp \ #htmlparse.cpp \ #printtext.cpp \ #selftest.cpp \ #pwmprint.cpp \ #spinforsignal.cpp #subtbledit.cpp \ #subtbleditimpl.cpp \ #compressbzip2.cpp SOURCES = \ addentrywnd_emb.cpp \ addentrywndimpl.cpp \ base64.cpp \ binentrygen.cpp \ blowfish.cpp \ commentbox.cpp \ compressgzip.cpp \ +csv.cpp \ findwnd_emb.cpp \ findwndimpl.cpp \ genpasswd.cpp \ getkeycardwnd.cpp \ getmasterpwwnd_emb.cpp \ getmasterpwwndimpl.cpp \ globalstuff.cpp \ gpasmanfile.cpp \ htmlgen.cpp \ ipc.cpp \ libgcryptif.cpp \ listobjselectwnd.cpp \ listviewpwm.cpp \ main.cpp \ pwgenwnd_emb.cpp \ pwgenwndimpl.cpp \ pwm.cpp \ pwmdoc.cpp \ pwmdocui.cpp \ pwmexception.cpp \ pwminit.cpp \ pwmprefs.cpp \ pwmtray.cpp \ pwmview.cpp \ pwmviewstyle_0.cpp \ pwmviewstyle_1.cpp \ pwmviewstyle.cpp \ randomizer.cpp \ rc2.cpp \ rencatwnd.cpp \ serializer.cpp \ setmasterpwwnd_emb.cpp \ setmasterpwwndimpl.cpp \ sha1.cpp \ waitwnd.cpp \ kcmconfigs/kcmpwmconfig.cpp \ kcmconfigs/pwmconfigwidget.cpp |