summaryrefslogtreecommitdiffabout
authorulf69 <ulf69>2004-10-22 18:48:35 (UTC)
committer ulf69 <ulf69>2004-10-22 18:48:35 (UTC)
commita5274f27dc71e1a0ffae73f32f84f4dd013b4b76 (patch) (unidiff)
tree5c2e3e105fa9df8999752a314455d0f424bf474b
parent163b74a23d102074fc0adefddba5b4fa9d4dd2a5 (diff)
downloadkdepimpi-a5274f27dc71e1a0ffae73f32f84f4dd013b4b76.zip
kdepimpi-a5274f27dc71e1a0ffae73f32f84f4dd013b4b76.tar.gz
kdepimpi-a5274f27dc71e1a0ffae73f32f84f4dd013b4b76.tar.bz2
added csv import/export
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--pwmanager/pwmanager/csv.cpp428
-rw-r--r--pwmanager/pwmanager/csv.h91
-rw-r--r--pwmanager/pwmanager/pwm.cpp85
-rw-r--r--pwmanager/pwmanager/pwm.h4
-rw-r--r--pwmanager/pwmanager/pwmanagerE.pro2
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 @@
1/***************************************************************************
2 * *
3 * copyright (C) 2004 by Michael Buesch *
4 * email: mbuesch@freenet.de *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License version 2 *
8 * as published by the Free Software Foundation. *
9 * *
10 ***************************************************************************/
11
12/***************************************************************************
13 * copyright (C) 2004 by Ulf Schenk
14 * This file is originaly based on version 1.1 of pwmanager
15 * and was modified to run on embedded devices that run microkde
16 * The original file version was 1.2
17 * $Id$
18 **************************************************************************/
19
20#include "csv.h"
21#include "pwmdoc.h"
22#include "pwmexception.h"
23
24#include <kmessagebox.h>
25#include <klocale.h>
26
27 #define MAX_CSV_FILE_SIZE(50 * 1024 * 1024) // bytes
28
29
30Csv::Csv(QWidget *_parent)
31 : parent (_parent)
32{
33}
34
35Csv::~Csv()
36{
37}
38
39bool Csv::importData(const QString &filepath,
40 PwMDoc *doc)
41{
42 bool ret = true;
43 QByteArray d;
44 QFile f(filepath);
45 if (!f.open(IO_ReadOnly)) {
46 KMessageBox::error(parent,
47 i18n("Could not open file.\n"
48 "Does the file exist?"),
49 i18n("Open error."));
50 ret = false;
51 goto out;
52 }
53 if (f.size() > MAX_CSV_FILE_SIZE) {
54 KMessageBox::error(parent,
55 i18n("File too big.\nMaximum file size is 1 Byte.", "File too big.\nMaximum file size is %n Bytes.", MAX_CSV_FILE_SIZE),
56 i18n("File too big."));
57 ret = false;
58 goto out_close;
59 }
60 d = f.readAll();
61 if (d.isEmpty()) {
62 KMessageBox::error(parent,
63 i18n("Could not read file or file empty."),
64 i18n("Reading failed."));
65 ret = false;
66 goto out_close;
67 }
68 if (!doImport(d, doc)) {
69 KMessageBox::error(parent,
70 i18n("Import failed.\n"
71 "Corrupt CSV data format."),
72 i18n("File corrupt."));
73 ret = false;
74 goto out_close;
75 }
76
77out_close:
78 f.close();
79out:
80 return ret;
81}
82
83bool Csv::doImport(const QByteArray &d,
84 PwMDoc *doc)
85{
86 PwMDataItem di;
87 //US ENH: initialize all members:
88 di.clear();
89
90 int refIndex = 0;
91 int ret;
92 QCString s, curCat;
93 int fieldIndex = 0;
94 bool inRecord = false;
95 /* fieldIndex is a reference count to see which
96 * value we are attaching to di.
97 * Valid counts are:
98 * 0 -> category
99 * 1 -> desc
100 * 2 -> name
101 * 3 -> pw
102 * 4 -> url
103 * 5 -> launcher
104 * 6 -> comment
105 */
106
107 while (1) {
108 ret = nextField(&s, d, inRecord, &refIndex);
109 switch (ret) {
110 case 0:
111 // successfully got next field.
112 inRecord = true;
113 switch (fieldIndex) {
114 case 0: // category
115 if (s.isEmpty()) {
116 /* This is special case. It's the category
117 * list terminating empty field.
118 */
119 ++fieldIndex;
120 } else
121 curCat = s;
122 break;
123 case 1:// desc
124 di.desc = s;
125 ++fieldIndex;
126 break;
127 case 2: // name
128 di.name = s;
129 ++fieldIndex;
130 break;
131 case 3: // pw
132 di.pw = s;
133 ++fieldIndex;
134 break;
135 case 4: // url
136 di.url = s;
137 ++fieldIndex;
138 break;
139 case 5: // launcher
140 di.launcher = s;
141 ++fieldIndex;
142 break;
143 case 6: // comment
144 di.comment = s;
145 ++fieldIndex;
146 break;
147 default:
148 /* Too many fields in a record.
149 * We simply throw it away.
150 */
151 break;
152 }
153 break;
154 case 1:
155 // record complete.
156 if (fieldIndex == 6)
157 di.comment = s;
158 inRecord = false;
159 fieldIndex = 0;
160 doc->addEntry(curCat, &di, true);
161 //US ENH: clear di for the next row
162 di.clear();
163 break;
164 case 2:
165 // data completely parsed.
166 doc->flagDirty();
167 return true;
168 case -1:
169 // parse error
170 doc->flagDirty();
171 return false;
172 }
173 }
174 BUG();
175 return false;
176}
177
178int Csv::nextField(QCString *ret,
179 const QByteArray &in,
180 bool inRecord,
181 int *_refIndex)
182{
183 int rv = -2;
184 char c;
185 bool inField = false;
186 bool isQuoted = false;
187 bool searchingTerminator = false;
188 int refIndex;
189 int inSize = static_cast<int>(in.size());
190 ret->truncate(0);
191
192 for (refIndex = *_refIndex; refIndex < inSize; ++refIndex) {
193 c = in.at(refIndex);
194 if (!inField) {
195 // we have to search the field beginning, now.
196 switch (c) {
197 case ' ': // space
198 case '': // tab
199 // hm, still not the beginning. Go on..
200 break;
201 case '\r':
202 case '\n':
203 if (inRecord) {
204 /* This is the end of the last field in
205 * the record.
206 */
207 PWM_ASSERT(ret->isEmpty());
208 rv = 1; // record end
209 goto out;
210 } else {
211 // hm, still not the beginning. Go on..
212 break;
213 }
214 case ',':
215 // Oh, an empty field. How sad.
216 PWM_ASSERT(ret->isEmpty());
217 rv = 0; // field end
218 goto out;
219 case '\"':
220 // this is the quoted beginning.
221 inField = true;
222 isQuoted = true;
223 if (refIndex + 1 >= inSize)
224 goto unexp_eof;
225 break;
226 default:
227 // this is the unquoted beginning.
228 inField = true;
229 isQuoted = false;
230 *ret += c;
231 break;
232 }
233 } else {
234 // we are in the field now. Search the end.
235 if (isQuoted) {
236 if (searchingTerminator) {
237 switch (c) {
238 case '\r':
239 case '\n':
240 rv = 1; // record end
241 goto out;
242 case ',':
243 // found it.
244 rv = 0; // field end
245 goto out;
246 default:
247 // go on.
248 continue;
249 }
250 }
251 switch (c) {
252 case '\"':
253 /* check if this is the end of the
254 * entry, or just an inline escaped quote.
255 */
256 char next;
257 if (refIndex + 1 >= inSize) {
258 // This is the last char, so it's the end.
259 rv = 2; // data end
260 goto out;
261 }
262 next = in.at(refIndex + 1);
263 switch (next) {
264 case '\"':
265 // This is an escaped double quote.
266 // So skip next iteration.
267 refIndex += 1;
268 *ret += c;
269 break;
270 default:
271 /* end of field.
272 * We have to search the comma (or newline...),
273 * which officially terminates the entry.
274 */
275 searchingTerminator = true;
276 break;
277 }
278 break;
279 default:
280 // nothing special about the char. Go on!
281 *ret += c;
282 break;
283 }
284 } else {
285 switch (c) {
286 case '\"':
287 // This is not allowed here.
288 return -1; // parser error
289 case '\r':
290 case '\n':
291 rv = 1; // record end
292 goto out;
293 case ',':
294 rv = 0; // field end
295 goto out;
296 default:
297 // nothing special about the char. Go on!
298 *ret += c;
299 break;
300 }
301 }
302 }
303 }
304 // we are at the end of the stream, now!
305 if (searchingTerminator) {
306 /* Ok, there's no terminating comma (or newline...),
307 * because we are at the end. That's perfectly fine.
308 */
309 PWM_ASSERT(inField);
310 rv = 2; // data end
311 goto out;
312 }
313 if (!isQuoted && inField) {
314 // That's the end of the last unquoted field.
315 rv = 2; // data end
316 goto out;
317 }
318 if (!inField) {
319 // This is expected EOF
320 rv = 2; // data end
321 goto out;
322 }
323
324unexp_eof:
325 printDebug("unexpected EOF :(");
326 return -1; // parser error
327
328out:
329 if (!isQuoted)
330 *ret = ret->stripWhiteSpace();
331 *_refIndex = refIndex + 1;
332 return rv;
333}
334
335bool Csv::exportData(const QString &filepath,
336 PwMDoc *doc)
337{
338 PWM_ASSERT(!doc->isDocEmpty());
339 bool ret = true;
340 if (QFile::exists(filepath)) {
341 int ret;
342 ret = KMessageBox::questionYesNo(parent,
343 i18n("This file does already exist.\n"
344 "Do you want to overwrite it?"),
345 i18n("Overwrite file?"));
346 if (ret == KMessageBox::No)
347 return false;
348 if (!QFile::remove(filepath)) {
349 KMessageBox::error(parent,
350 i18n("Could not delete the old file."),
351 i18n("Delete error."));
352 return false;
353 }
354 }
355 QFile f(filepath);
356 if (!f.open(IO_ReadWrite)) {
357 KMessageBox::error(parent,
358 i18n("Could not open file for writing."),
359 i18n("Open error."));
360 ret = false;
361 goto out;
362 }
363 doc->unlockAll_tempoary();
364 if (!doExport(f, doc))
365 ret = false;
366 doc->unlockAll_tempoary(true);
367 f.close();
368out:
369 return ret;
370}
371
372bool Csv::doExport(QFile &f,
373 PwMDoc *doc)
374{
375 unsigned int numCat = doc->numCategories();
376 unsigned int numEntr;
377 unsigned int i, j;
378 PwMDataItem d;
379 QCString s, catName;
380 QByteArray b;
381
382 for (i = 0; i < numCat; ++i) {
383 numEntr = doc->numEntries(i);
384 catName = newField(doc->getCategory(i)->c_str());
385 for (j = 0; j < numEntr; ++j) {
386 doc->getEntry(i, j, &d);
387 s = catName;
388 s += ",,";
389 s += newField(d.desc.c_str());
390 s += ",";
391 s += newField(d.name.c_str());
392 s += ",";
393 s += newField(d.pw.c_str());
394 s += ",";
395 s += newField(d.url.c_str());
396 s += ",";
397 s += newField(d.launcher.c_str());
398 s += ",";
399 s += newField(d.comment.c_str());
400 s += "\r\n";
401 b = s;
402 // remove \0 termination
403#ifndef PWM_EMBEDDED
404 b.resize(b.size() - 1, QGArray::SpeedOptim);
405#else
406 b.resize(b.size() - 1);
407#endif
408 if (!f.writeBlock(b))
409 return false;
410 }
411 }
412 return true;
413}
414
415QCString Csv::newField(QCString s)
416{
417 if (s.isEmpty())
418 return QCString();
419 QCString ret("\"");
420#ifndef PWM_EMBEDDED
421 s.replace('\"', "\"\"");
422#else
423 s.replace(QRegExp("\""), "\"\"");
424#endif
425 ret += s;
426 ret += "\"";
427 return ret;
428}
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 @@
1/***************************************************************************
2 * *
3 * copyright (C) 2004 by Michael Buesch *
4 * email: mbuesch@freenet.de *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License version 2 *
8 * as published by the Free Software Foundation. *
9 * *
10 ***************************************************************************/
11
12/***************************************************************************
13 * copyright (C) 2004 by Ulf Schenk
14 * This file is originaly based on version 1.1 of pwmanager
15 * and was modified to run on embedded devices that run microkde
16 * The original file version was 1.2
17 * $Id$
18 **************************************************************************/
19
20
21#ifndef __PWMANAGER_CSV_H
22#define __PWMANAGER_CSV_H
23
24#include <qcstring.h>
25#include <qfile.h>
26
27
28class PwMDoc;
29class QString;
30class QWidget;
31
32/** class for CSV (Comma Separated Value) export and import.
33 *
34 * http://www.creativyst.com/Doc/Articles/CSV/CSV01.htm
35 * http://en.wikipedia.org/wiki/Comma-separated_values
36 *
37 * There are two types of CSV output we can produce.
38 * One with Category support (recommended):
39 * "Category 1",, "Desc 1", "Username 1", "Password 1", "URL 1", "Launcher 1", "Comment 1"
40 * "Category 1",, "Desc 2", "Username 2", "Password 2", "URL 2", "Launcher 2", "Comment 2"
41 * ...
42 * The empty "" is neccessary, because in future versions we will
43 * support nested Categories. We want to be future compatible, now.
44 *
45 * And one without Category support:
46 *FIXME: it's not implemented, yet. ;)
47 * "Desc 1", "Username 1", "Password 1", "URL 1", "Launcher 1", "Comment 1"
48 * "Desc 2", "Username 2", "Password 2", "URL 2", "Launcher 2", "Comment 2"
49 * ...
50 *
51 */
52class Csv
53{
54public:
55 Csv(QWidget *_parent);
56 ~Csv();
57
58 /** import data from "filepath" into "doc" */
59 bool importData(const QString &filepath,
60 PwMDoc *doc);
61 /** export data from "doc" to "filepath" */
62 bool exportData(const QString &filepath,
63 PwMDoc *doc);
64
65protected:
66 /** do the import process. */
67 bool doImport(const QByteArray &d,
68 PwMDoc *doc);
69 /** parse for the next field.
70 * @return Return values are:
71 * 0 -> successfully got the next field.
72 * 1 -> record end.
73 * 2 -> data end.
74 * -1 -> parser error.
75 */
76 int nextField(QCString *ret,
77 const QByteArray &in,
78 bool inRecord,
79 int *_refIndex);
80 /** do the export process. */
81 bool doExport(QFile &f,
82 PwMDoc *doc);
83 /** generate a new data field string. */
84 QCString newField(QCString s);
85
86protected:
87 /** current parent widget. */
88 QWidget *parent;
89};
90
91#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
@@ -47,24 +47,25 @@
47#include <qfileinfo.h> 47#include <qfileinfo.h>
48#include <qclipboard.h> 48#include <qclipboard.h>
49 49
50 50
51#include <stdio.h> 51#include <stdio.h>
52 52
53#include "pwm.h" 53#include "pwm.h"
54#include "pwminit.h" 54#include "pwminit.h"
55#include "pwmprint.h" 55#include "pwmprint.h"
56#include "addentrywndimpl.h" 56#include "addentrywndimpl.h"
57#include "globalstuff.h" 57#include "globalstuff.h"
58#include "findwndimpl.h" 58#include "findwndimpl.h"
59#include "csv.h"
59 60
60#ifdef CONFIG_KWALLETIF 61#ifdef CONFIG_KWALLETIF
61# include "kwalletif.h" 62# include "kwalletif.h"
62# include "kwalletemu.h" 63# include "kwalletemu.h"
63#endif 64#endif
64#ifdef CONFIG_KEYCARD 65#ifdef CONFIG_KEYCARD
65# include "pwmkeycard.h" 66# include "pwmkeycard.h"
66#endif 67#endif
67 68
68 69
69 #define DEFAULT_SIZE (QSize(700, 400)) 70 #define DEFAULT_SIZE (QSize(700, 400))
70 71
@@ -104,33 +105,35 @@ enum {
104 BUTTON_POPUP_VIEW_FIND = 0, 105 BUTTON_POPUP_VIEW_FIND = 0,
105 BUTTON_POPUP_VIEW_LOCK, 106 BUTTON_POPUP_VIEW_LOCK,
106 BUTTON_POPUP_VIEW_DEEPLOCK, 107 BUTTON_POPUP_VIEW_DEEPLOCK,
107 BUTTON_POPUP_VIEW_UNLOCK 108 BUTTON_POPUP_VIEW_UNLOCK
108}; 109};
109// Button IDs for "options" popup menu 110// Button IDs for "options" popup menu
110enum { 111enum {
111 BUTTON_POPUP_OPTIONS_CONFIG = 0 112 BUTTON_POPUP_OPTIONS_CONFIG = 0
112}; 113};
113// Button IDs for "export" popup menu (in "file" popup menu) 114// Button IDs for "export" popup menu (in "file" popup menu)
114enum { 115enum {
115 BUTTON_POPUP_EXPORT_TEXT = 0, 116 BUTTON_POPUP_EXPORT_TEXT = 0,
116 BUTTON_POPUP_EXPORT_GPASMAN 117 BUTTON_POPUP_EXPORT_GPASMAN,
118 BUTTON_POPUP_EXPORT_CSV
117#ifdef CONFIG_KWALLETIF 119#ifdef CONFIG_KWALLETIF
118 ,BUTTON_POPUP_EXPORT_KWALLET 120 ,BUTTON_POPUP_EXPORT_KWALLET
119#endif 121#endif
120}; 122};
121// Button IDs for "import" popup menu (in "file" popup menu) 123// Button IDs for "import" popup menu (in "file" popup menu)
122enum { 124enum {
123 BUTTON_POPUP_IMPORT_TEXT = 0, 125 BUTTON_POPUP_IMPORT_TEXT = 0,
124 BUTTON_POPUP_IMPORT_GPASMAN 126 BUTTON_POPUP_IMPORT_GPASMAN,
127 BUTTON_POPUP_IMPORT_CSV
125#ifdef CONFIG_KWALLETIF 128#ifdef CONFIG_KWALLETIF
126 ,BUTTON_POPUP_IMPORT_KWALLET 129 ,BUTTON_POPUP_IMPORT_KWALLET
127#endif 130#endif
128}; 131};
129 132
130#ifdef PWM_EMBEDDED 133#ifdef PWM_EMBEDDED
131// Button IDs for "help" popup menu 134// Button IDs for "help" popup menu
132enum { 135enum {
133 BUTTON_POPUP_HELP_LICENSE = 0, 136 BUTTON_POPUP_HELP_LICENSE = 0,
134 BUTTON_POPUP_HELP_FAQ, 137 BUTTON_POPUP_HELP_FAQ,
135 BUTTON_POPUP_HELP_ABOUT, 138 BUTTON_POPUP_HELP_ABOUT,
136 BUTTON_POPUP_HELP_SYNC, 139 BUTTON_POPUP_HELP_SYNC,
@@ -172,28 +175,30 @@ PwM::PwM(PwMInit *_init, PwMDoc *doc,
172 setFocusPolicy(QWidget::WheelFocus); 175 setFocusPolicy(QWidget::WheelFocus);
173#ifndef PWM_EMBEDDED 176#ifndef PWM_EMBEDDED
174 statusBar()->show(); 177 statusBar()->show();
175#endif 178#endif
176 view = makeNewListView(doc); 179 view = makeNewListView(doc);
177 setCentralWidget(view); 180 setCentralWidget(view);
178 updateCaption(); 181 updateCaption();
179 showStatMsg(i18n("Ready.")); 182 showStatMsg(i18n("Ready."));
180} 183}
181 184
182PwM::~PwM() 185PwM::~PwM()
183{ 186{
187 //qDebug("PwM::~PwM()");
184 disconnect(curDoc(), SIGNAL(docClosed(PwMDoc *)), 188 disconnect(curDoc(), SIGNAL(docClosed(PwMDoc *)),
185 this, SLOT(docClosed(PwMDoc *))); 189 this, SLOT(docClosed(PwMDoc *)));
186 conf()->confWndMainWndSize(size()); 190 conf()->confWndMainWndSize(size());
187 emit closed(this); 191 emit closed(this);
192 //qDebug("PwM::~PwM() emited closed(this)");
188 delete view; 193 delete view;
189} 194}
190 195
191void PwM::initMenubar() 196void PwM::initMenubar()
192{ 197{
193 KIconLoader* picons; 198 KIconLoader* picons;
194#ifndef PWM_EMBEDDED 199#ifndef PWM_EMBEDDED
195 KIconLoader icons; 200 KIconLoader icons;
196 picons = &icons; 201 picons = &icons;
197#else 202#else
198 picons = KGlobal::iconLoader(); 203 picons = KGlobal::iconLoader();
199 204
@@ -232,36 +237,40 @@ void PwM::initMenubar()
232 i18n("&Save"), this, 237 i18n("&Save"), this,
233 SLOT(save_slot()), 0, BUTTON_POPUP_FILE_SAVE); 238 SLOT(save_slot()), 0, BUTTON_POPUP_FILE_SAVE);
234 filePopup->insertItem(QIconSet(picons->loadIcon("filesaveas", KIcon::Small)), 239 filePopup->insertItem(QIconSet(picons->loadIcon("filesaveas", KIcon::Small)),
235 i18n("Save &as..."), 240 i18n("Save &as..."),
236 this, SLOT(saveAs_slot()), 0, 241 this, SLOT(saveAs_slot()), 0,
237 BUTTON_POPUP_FILE_SAVEAS); 242 BUTTON_POPUP_FILE_SAVEAS);
238 filePopup->insertSeparator(); 243 filePopup->insertSeparator();
239 // "file/export" popup menu 244 // "file/export" popup menu
240 exportPopup->insertItem(i18n("&Text-file..."), this, 245 exportPopup->insertItem(i18n("&Text-file..."), this,
241 SLOT(exportToText()), 0, BUTTON_POPUP_EXPORT_TEXT); 246 SLOT(exportToText()), 0, BUTTON_POPUP_EXPORT_TEXT);
242 exportPopup->insertItem(i18n("&Gpasman / Kpasman ..."), this, 247 exportPopup->insertItem(i18n("&Gpasman / Kpasman ..."), this,
243 SLOT(exportToGpasman()), 0, BUTTON_POPUP_EXPORT_GPASMAN); 248 SLOT(exportToGpasman()), 0, BUTTON_POPUP_EXPORT_GPASMAN);
249 exportPopup->insertItem(i18n("&CSV (Comma Separated Value) ..."), this,
250 SLOT(exportToCsv()), 0, BUTTON_POPUP_EXPORT_CSV);
244#ifdef CONFIG_KWALLETIF 251#ifdef CONFIG_KWALLETIF
245 exportPopup->insertItem(i18n("&KWallet..."), this, 252 exportPopup->insertItem(i18n("&KWallet..."), this,
246 SLOT(exportToKWallet()), 0, BUTTON_POPUP_EXPORT_KWALLET); 253 SLOT(exportToKWallet()), 0, BUTTON_POPUP_EXPORT_KWALLET);
247#endif 254#endif
248 filePopup->insertItem(QIconSet(picons->loadIcon("fileexport", KIcon::Small)), 255 filePopup->insertItem(QIconSet(picons->loadIcon("fileexport", KIcon::Small)),
249 i18n("E&xport"), exportPopup, 256 i18n("E&xport"), exportPopup,
250 BUTTON_POPUP_FILE_EXPORT); 257 BUTTON_POPUP_FILE_EXPORT);
251 // "file/import" popup menu 258 // "file/import" popup menu
252 importPopup->insertItem(i18n("&Text-file..."), this, 259 importPopup->insertItem(i18n("&Text-file..."), this,
253 SLOT(importFromText()), 0, BUTTON_POPUP_IMPORT_TEXT); 260 SLOT(importFromText()), 0, BUTTON_POPUP_IMPORT_TEXT);
254 importPopup->insertItem(i18n("&Gpasman / Kpasman ..."), this, 261 importPopup->insertItem(i18n("&Gpasman / Kpasman ..."), this,
255 SLOT(importFromGpasman()), 0, BUTTON_POPUP_IMPORT_GPASMAN); 262 SLOT(importFromGpasman()), 0, BUTTON_POPUP_IMPORT_GPASMAN);
263 importPopup->insertItem(i18n("&CSV (Comma Separated Value) ..."), this,
264 SLOT(importCsv()), 0, BUTTON_POPUP_IMPORT_CSV);
256#ifdef CONFIG_KWALLETIF 265#ifdef CONFIG_KWALLETIF
257 importPopup->insertItem(i18n("&KWallet..."), this, 266 importPopup->insertItem(i18n("&KWallet..."), this,
258 SLOT(importKWallet()), 0, BUTTON_POPUP_IMPORT_KWALLET); 267 SLOT(importKWallet()), 0, BUTTON_POPUP_IMPORT_KWALLET);
259#endif 268#endif
260 filePopup->insertItem(QIconSet(picons->loadIcon("fileimport", KIcon::Small)), 269 filePopup->insertItem(QIconSet(picons->loadIcon("fileimport", KIcon::Small)),
261 i18n("I&mport"), importPopup, 270 i18n("I&mport"), importPopup,
262 BUTTON_POPUP_FILE_IMPORT); 271 BUTTON_POPUP_FILE_IMPORT);
263 filePopup->insertSeparator(); 272 filePopup->insertSeparator();
264 filePopup->insertItem(QIconSet(picons->loadIcon("fileprint", KIcon::Small)), 273 filePopup->insertItem(QIconSet(picons->loadIcon("fileprint", KIcon::Small)),
265 i18n("&Print..."), this, 274 i18n("&Print..."), this,
266 SLOT(print_slot()), 0, BUTTON_POPUP_FILE_PRINT); 275 SLOT(print_slot()), 0, BUTTON_POPUP_FILE_PRINT);
267 filePopup->insertSeparator(); 276 filePopup->insertSeparator();
@@ -1007,24 +1016,96 @@ void PwM::exportToGpasman()
1007 return; 1016 return;
1008 } 1017 }
1009 KMessageBox::error(this, 1018 KMessageBox::error(this,
1010 i18n("Error: Couldn't write to file.\n" 1019 i18n("Error: Couldn't write to file.\n"
1011 "Please check if you have permission to write " 1020 "Please check if you have permission to write "
1012 "to the file in that directory."), 1021 "to the file in that directory."),
1013 i18n("error while writing")); 1022 i18n("error while writing"));
1014 } else 1023 } else
1015 showStatMsg(i18n("Successfully exported data.")); 1024 showStatMsg(i18n("Successfully exported data."));
1016 curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); 1025 curDoc()->timer()->putLock(DocTimer::id_autoLockTimer);
1017} 1026}
1018 1027
1028
1029
1030void PwM::exportToCsv()
1031{
1032 PWM_ASSERT(curDoc());
1033 if (curDoc()->isDocEmpty()) {
1034 KMessageBox::information(this,
1035 i18n
1036 ("Sorry, there is nothing to export;\n"
1037 "please add some passwords first."),
1038 i18n("Nothing to Do"));
1039 return;
1040 }
1041
1042 curDoc()->timer()->getLock(DocTimer::id_autoLockTimer);
1043 QString fn(KFileDialog::getSaveFileName("*.csv", i18n("*|CSV Text File"), this));
1044 if (fn.isEmpty()) {
1045 curDoc()->timer()->putLock(DocTimer::id_autoLockTimer);
1046 return;
1047 }
1048
1049 Csv csv(this);
1050 if (!csv.exportData(fn, curDoc())) {
1051 curDoc()->timer()->putLock(DocTimer::id_autoLockTimer);
1052 showStatMsg(i18n("CSV file export failed."));
1053 return;
1054 }
1055 showStatMsg(i18n("Successfully exported data."));
1056 curDoc()->timer()->putLock(DocTimer::id_autoLockTimer);
1057}
1058
1059bool PwM::importCsv()
1060{
1061 Csv csv(this);
1062 if (!isVirgin()) {
1063 if (KMessageBox::questionYesNo(this,
1064 i18n("Do you want to import the data\n"
1065 "into the current document? (If you\n"
1066 "select \"no\", a new document will be\n"
1067 "opened.)"),
1068 i18n("Import into This Document?"))
1069 == KMessageBox::No) {
1070 // import the data to a new window.
1071 PwM *newInstance = init->createMainWnd();
1072 bool ok = newInstance->importCsv();
1073 if (!ok) {
1074 newInstance->setForceQuit(true);
1075 delete_and_null(newInstance);
1076 }
1077 return ok;
1078 }
1079 }
1080
1081 QString filename = KFileDialog::getOpenFileName("*.csv", i18n("*|CSV Text File"), this);
1082 if (filename.isEmpty())
1083 return false;
1084 curDoc()->timer()->getLock(DocTimer::id_autoLockTimer);
1085 if (!csv.importData(filename, curDoc())) {
1086 curDoc()->timer()->putLock(DocTimer::id_autoLockTimer);
1087 showStatMsg(i18n("CSV file import failed."));
1088 return false;
1089 }
1090 curDoc()->timer()->putLock(DocTimer::id_autoLockTimer);
1091 KMessageBox::information(this,
1092 i18n("Successfully imported the CSV data\n"
1093 "into the current document."), i18n("Successfully Imported"));
1094 showStatMsg(i18n("Successfully imported"));
1095 setVirgin(false);
1096 return true;
1097}
1098
1099
1019void PwM::exportToKWallet() 1100void PwM::exportToKWallet()
1020{ 1101{
1021#ifdef CONFIG_KWALLETIF 1102#ifdef CONFIG_KWALLETIF
1022 if (!checkAndAskForKWalletEmu()) 1103 if (!checkAndAskForKWalletEmu())
1023 return; 1104 return;
1024 PWM_ASSERT(curDoc()); 1105 PWM_ASSERT(curDoc());
1025 if (curDoc()->isDocEmpty()) { 1106 if (curDoc()->isDocEmpty()) {
1026 KMessageBox::information(this, 1107 KMessageBox::information(this,
1027 i18n 1108 i18n
1028 ("Sorry, there's nothing to export.\n" 1109 ("Sorry, there's nothing to export.\n"
1029 "Please first add some passwords."), 1110 "Please first add some passwords."),
1030 i18n("nothing to do")); 1111 i18n("nothing to do"));
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
@@ -115,30 +115,34 @@ public slots:
115 /** file/quit triggered */ 115 /** file/quit triggered */
116 void quitButton_slot(); 116 void quitButton_slot();
117 /** file/save triggered */ 117 /** file/save triggered */
118 void save_slot(); 118 void save_slot();
119 /** file/saveAs triggered */ 119 /** file/saveAs triggered */
120 void saveAs_slot(); 120 void saveAs_slot();
121 /** file/export/text triggered */ 121 /** file/export/text triggered */
122 void exportToText(); 122 void exportToText();
123 /** file/export/gpasman triggered */ 123 /** file/export/gpasman triggered */
124 void exportToGpasman(); 124 void exportToGpasman();
125 /** file/export/kwallet triggered */ 125 /** file/export/kwallet triggered */
126 void exportToKWallet(); 126 void exportToKWallet();
127 /** file/export/csv triggered */
128 void exportToCsv();
127 /** file/import/text triggered */ 129 /** file/import/text triggered */
128 bool importFromText(); 130 bool importFromText();
129 /** file/import/gpasman triggered */ 131 /** file/import/gpasman triggered */
130 bool importFromGpasman(); 132 bool importFromGpasman();
131 /** file/import/kwallet triggered */ 133 /** file/import/kwallet triggered */
132 bool importKWallet(); 134 bool importKWallet();
135 /** file/import/csv triggered */
136 bool importCsv();
133 /** file/print triggered */ 137 /** file/print triggered */
134 void print_slot(); 138 void print_slot();
135 /** manage/add triggered */ 139 /** manage/add triggered */
136 //US ENH : changed code to run with older MOC 140 //US ENH : changed code to run with older MOC
137 141
138 void addPwd_slot(); 142 void addPwd_slot();
139 void addPwd_slot1(QString *pw, PwMDoc *_doc); 143 void addPwd_slot1(QString *pw, PwMDoc *_doc);
140 /** manage/edit triggered */ 144 /** manage/edit triggered */
141 //US ENH : changed code to run with older MOC 145 //US ENH : changed code to run with older MOC
142 void editPwd_slot(); 146 void editPwd_slot();
143 void editPwd_slot1(const QString *category); 147 void editPwd_slot1(const QString *category);
144 void editPwd_slot3(const QString *category, const int *index ,PwMDoc *_doc ); 148 void editPwd_slot3(const QString *category, const int *index ,PwMDoc *_doc );
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
@@ -53,24 +53,25 @@ LIBS += -lstdc++
53#subtbleditimpl.h \ 53#subtbleditimpl.h \
54#compressbzip2.h \ 54#compressbzip2.h \
55 55
56HEADERS = \ 56HEADERS = \
57addentrywnd_emb.h \ 57addentrywnd_emb.h \
58addentrywndimpl.h \ 58addentrywndimpl.h \
59base64.h \ 59base64.h \
60binentrygen.h \ 60binentrygen.h \
61blowfish.h \ 61blowfish.h \
62commentbox.h \ 62commentbox.h \
63compiler.h \ 63compiler.h \
64compressgzip.h \ 64compressgzip.h \
65csv.h \
65findwnd_emb.h \ 66findwnd_emb.h \
66findwndimpl.h \ 67findwndimpl.h \
67genpasswd.h \ 68genpasswd.h \
68getkeycardwnd.h \ 69getkeycardwnd.h \
69getmasterpwwnd_emb.h \ 70getmasterpwwnd_emb.h \
70getmasterpwwndimpl.h \ 71getmasterpwwndimpl.h \
71globalstuff.h \ 72globalstuff.h \
72gpasmanfile.h \ 73gpasmanfile.h \
73htmlgen.h \ 74htmlgen.h \
74htmlparse.h \ 75htmlparse.h \
75ipc.h \ 76ipc.h \
76libgcryptif.h \ 77libgcryptif.h \
@@ -118,24 +119,25 @@ kcmconfigs/pwmconfigwidget.h
118#subtbleditimpl.cpp \ 119#subtbleditimpl.cpp \
119#compressbzip2.cpp 120#compressbzip2.cpp
120 121
121 122
122SOURCES = \ 123SOURCES = \
123addentrywnd_emb.cpp \ 124addentrywnd_emb.cpp \
124addentrywndimpl.cpp \ 125addentrywndimpl.cpp \
125base64.cpp \ 126base64.cpp \
126binentrygen.cpp \ 127binentrygen.cpp \
127blowfish.cpp \ 128blowfish.cpp \
128commentbox.cpp \ 129commentbox.cpp \
129compressgzip.cpp \ 130compressgzip.cpp \
131csv.cpp \
130findwnd_emb.cpp \ 132findwnd_emb.cpp \
131findwndimpl.cpp \ 133findwndimpl.cpp \
132genpasswd.cpp \ 134genpasswd.cpp \
133getkeycardwnd.cpp \ 135getkeycardwnd.cpp \
134getmasterpwwnd_emb.cpp \ 136getmasterpwwnd_emb.cpp \
135getmasterpwwndimpl.cpp \ 137getmasterpwwndimpl.cpp \
136globalstuff.cpp \ 138globalstuff.cpp \
137gpasmanfile.cpp \ 139gpasmanfile.cpp \
138htmlgen.cpp \ 140htmlgen.cpp \
139ipc.cpp \ 141ipc.cpp \
140libgcryptif.cpp \ 142libgcryptif.cpp \
141listobjselectwnd.cpp \ 143listobjselectwnd.cpp \