Diffstat (limited to 'pwmanager/pwmanager/pwmview.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | pwmanager/pwmanager/pwmview.cpp | 452 |
1 files changed, 452 insertions, 0 deletions
diff --git a/pwmanager/pwmanager/pwmview.cpp b/pwmanager/pwmanager/pwmview.cpp new file mode 100644 index 0000000..c09fbf5 --- a/dev/null +++ b/pwmanager/pwmanager/pwmview.cpp | |||
@@ -0,0 +1,452 @@ | |||
1 | /*************************************************************************** | ||
2 | * * | ||
3 | * copyright (C) 2003, 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.0.1 of pwmanager | ||
15 | * and was modified to run on embedded devices that run microkde | ||
16 | * | ||
17 | * $Id$ | ||
18 | **************************************************************************/ | ||
19 | |||
20 | #include "pwmview.h" | ||
21 | #include "pwmexception.h" | ||
22 | #include "globalstuff.h" | ||
23 | #include "pwm.h" | ||
24 | #include "rencatwnd.h" | ||
25 | #include "configuration.h" | ||
26 | #include "commentbox.h" | ||
27 | |||
28 | #include <kmessagebox.h> | ||
29 | #include <klocale.h> | ||
30 | |||
31 | #include <qlineedit.h> | ||
32 | #include <qpoint.h> | ||
33 | #include <qapplication.h> | ||
34 | |||
35 | #define COLUMN_DESC 0 | ||
36 | #define COLUMN_NAME 1 | ||
37 | #define COLUMN_PW 2 | ||
38 | #define COLUMN_URL 3 | ||
39 | #define COLUMN_LAUNCHER 4 | ||
40 | |||
41 | |||
42 | PwMView::PwMView(PwM *_mainClass, | ||
43 | QWidget *parent, PwMDoc *_doc, | ||
44 | const char *name) | ||
45 | : PwMViewStyle(parent, name) | ||
46 | { | ||
47 | PWM_ASSERT(_mainClass); | ||
48 | PWM_ASSERT(parent); | ||
49 | PWM_ASSERT(_doc); | ||
50 | setView(this); | ||
51 | doc = _doc; | ||
52 | doc->setListViewPointer(this); | ||
53 | mainClass = _mainClass; | ||
54 | resize(_mainClass->size()); | ||
55 | initStyle(conf()->confWndMainViewStyle()); | ||
56 | initCtxMenu(); | ||
57 | doc->setCurrentView(this); | ||
58 | connect(doc, SIGNAL(dataChanged(PwMDoc *)), this, SLOT(updateView())); | ||
59 | } | ||
60 | |||
61 | PwMView::~PwMView() | ||
62 | { | ||
63 | } | ||
64 | |||
65 | void PwMView::initCtxMenu() | ||
66 | { | ||
67 | ctxMenu = new QPopupMenu(this); | ||
68 | ctxMenu->insertItem(i18n("&Add password"), mainClass, SLOT(addPwd_slot())); | ||
69 | ctxMenu->insertSeparator(); | ||
70 | ctxMenu->insertItem(i18n("&Edit"), mainClass, SLOT(editPwd_slot())); | ||
71 | ctxMenu->insertItem(i18n("&Delete"), mainClass, SLOT(deletePwd_slot())); | ||
72 | ctxMenu->insertSeparator(); | ||
73 | ctxMenu->insertItem(i18n("copy password to clipboard"), | ||
74 | this, SLOT(copyPwToClip())); | ||
75 | ctxMenu->insertItem(i18n("copy username to clipboard"), | ||
76 | this, SLOT(copyNameToClip())); | ||
77 | ctxMenu->insertItem(i18n("copy description to clipboard"), | ||
78 | this, SLOT(copyDescToClip())); | ||
79 | ctxMenu->insertItem(i18n("copy url to clipboard"), | ||
80 | this, SLOT(copyUrlToClip())); | ||
81 | ctxMenu->insertItem(i18n("copy launcher to clipboard"), | ||
82 | this, SLOT(copyLauncherToClip())); | ||
83 | ctxMenu->insertItem(i18n("copy comment to clipboard"), | ||
84 | this, SLOT(copyCommentToClip())); | ||
85 | ctxMenu->insertSeparator(); | ||
86 | ctxMenu->insertItem(i18n("Execute \"Launcher\""), mainClass, | ||
87 | SLOT(execLauncher_slot())); | ||
88 | ctxMenu->insertItem(i18n("Go to \"URL\""), mainClass, | ||
89 | SLOT(goToURL_slot())); | ||
90 | } | ||
91 | |||
92 | void PwMView::resizeEvent(QResizeEvent *) | ||
93 | { | ||
94 | resizeView(size()); | ||
95 | } | ||
96 | |||
97 | void PwMView::refreshCommentTextEdit(QListViewItem *curItem) | ||
98 | { | ||
99 | PWM_ASSERT(commentBox); | ||
100 | if (!curItem) | ||
101 | return; | ||
102 | string comment; | ||
103 | PwMerror ret; | ||
104 | ret = document()->getCommentByLvp(getCurrentCategory(), | ||
105 | lv->childCount() - lv->itemIndex(curItem) - 1, | ||
106 | &comment); | ||
107 | if (ret == e_binEntry) { | ||
108 | commentBox->setContent(i18n("This is a binary entry.\n" | ||
109 | "It is not a normal password-entry, as it contains " | ||
110 | "binary data, which PwManager can't display here.")); | ||
111 | } else if (ret == e_normalEntry) { | ||
112 | commentBox->setContent(comment.c_str()); | ||
113 | } else { | ||
114 | BUG(); | ||
115 | return; | ||
116 | } | ||
117 | lv->ensureItemVisible(curItem); | ||
118 | } | ||
119 | |||
120 | void PwMView::keyReleaseEvent(QKeyEvent * /*e*/) | ||
121 | { | ||
122 | refreshCommentTextEdit(lv->currentItem()); | ||
123 | } | ||
124 | |||
125 | bool PwMView::getCurEntryIndex(unsigned int *index) | ||
126 | { | ||
127 | QListViewItem *current = lv->currentItem(); | ||
128 | if (!current) | ||
129 | return false; | ||
130 | return getDocEntryIndex(index, current); | ||
131 | } | ||
132 | |||
133 | bool PwMView::getDocEntryIndex(unsigned int *index, | ||
134 | const QListViewItem *item) | ||
135 | { | ||
136 | vector<unsigned int> foundPositions; | ||
137 | PwMDataItem curItem; | ||
138 | curItem.desc = item->text(COLUMN_DESC).latin1(); | ||
139 | curItem.name = item->text(COLUMN_NAME).latin1(); | ||
140 | document()->getCommentByLvp(getCurrentCategory(), | ||
141 | lv->childCount() - lv->itemIndex(item) - 1, | ||
142 | &curItem.comment); | ||
143 | curItem.url = item->text(COLUMN_URL).latin1(); | ||
144 | curItem.launcher = item->text(COLUMN_LAUNCHER).latin1(); | ||
145 | document()->findEntry(getCurrentCategory(), curItem, SEARCH_IN_DESC | | ||
146 | SEARCH_IN_NAME | SEARCH_IN_COMMENT | SEARCH_IN_URL | | ||
147 | SEARCH_IN_LAUNCHER, | ||
148 | &foundPositions, true); | ||
149 | if (foundPositions.size()) { | ||
150 | *index = foundPositions[0]; | ||
151 | return true; | ||
152 | } | ||
153 | |||
154 | return false; | ||
155 | } | ||
156 | |||
157 | void PwMView::handleToggle(QListViewItem *item) | ||
158 | { | ||
159 | PWM_ASSERT(doc); | ||
160 | if (!item) | ||
161 | return; | ||
162 | QCheckListItem *clItem = (QCheckListItem *)item; | ||
163 | QString curCat(getCurrentCategory()); | ||
164 | |||
165 | // find document position of this entry. | ||
166 | unsigned int curEntryDocIndex; | ||
167 | if (!getDocEntryIndex(&curEntryDocIndex, item)) | ||
168 | return; | ||
169 | |||
170 | // hack to refresh the comment, if only one item is present | ||
171 | if (lv->childCount() == 1) | ||
172 | refreshCommentTextEdit(lv->currentItem()); | ||
173 | |||
174 | if (doc->isLocked(curCat, curEntryDocIndex) != clItem->isOn()) | ||
175 | return; // this is just a click somewhere on the entry | ||
176 | if (doc->isDeepLocked()) { | ||
177 | PwMerror ret; | ||
178 | ret = doc->deepLock(false); | ||
179 | if (ret != e_success) | ||
180 | clItem->setOn(false); | ||
181 | return; | ||
182 | } | ||
183 | doc->lockAt(curCat, curEntryDocIndex, !clItem->isOn()); | ||
184 | } | ||
185 | |||
186 | void PwMView::handleRightClick(QListViewItem *item, const QPoint &point, int) | ||
187 | { | ||
188 | if (!item) | ||
189 | return; | ||
190 | ctxMenu->move(point); | ||
191 | /* don't use ctxMenu->exec() here, as it generates race conditions | ||
192 | * with the card interface code. Believe it or not. :) | ||
193 | */ | ||
194 | ctxMenu->show(); | ||
195 | } | ||
196 | |||
197 | void PwMView::updateCategories() | ||
198 | { | ||
199 | QString oldSel(getCurrentCategory()); | ||
200 | delAllCategories(); | ||
201 | QStringList catList; | ||
202 | document()->getCategoryList(&catList); | ||
203 | catList.sort(); | ||
204 | #ifndef PWM_EMBEDDED | ||
205 | QStringList::iterator i = catList.begin(), | ||
206 | end = catList.end(); | ||
207 | #else | ||
208 | QStringList::Iterator i = catList.begin(), | ||
209 | end = catList.end(); | ||
210 | #endif | ||
211 | while (i != end) { | ||
212 | addCategory(*i); | ||
213 | ++i; | ||
214 | } | ||
215 | selectCategory(oldSel); | ||
216 | } | ||
217 | |||
218 | void PwMView::shiftToView() | ||
219 | { | ||
220 | int cX = lv->contentsX(); | ||
221 | int cY = lv->contentsY(); | ||
222 | commentBox->clear(); | ||
223 | |||
224 | unsigned int catDocIndex; | ||
225 | if (unlikely( | ||
226 | !(document()->findCategory(getCurrentCategory(), | ||
227 | &catDocIndex)))) { | ||
228 | BUG(); | ||
229 | } | ||
230 | |||
231 | // ensure all listViewPos are set | ||
232 | doc->ensureLvp(); | ||
233 | |||
234 | // clear all tmp-data vectors | ||
235 | unsigned int i, entries = doc->numEntries(catDocIndex); | ||
236 | if (entries) { | ||
237 | mainClass->setVirgin(false); | ||
238 | } | ||
239 | vector<PwMDataItem> tmpSorted; | ||
240 | PwMDataItem currItem; | ||
241 | currItem.clear(); | ||
242 | tmpSorted.insert(tmpSorted.begin(), entries, currItem); | ||
243 | |||
244 | // Sort items and store them in tempoary tmpSorted. | ||
245 | for (i = 0; i < entries; ++i) { | ||
246 | doc->getEntry(catDocIndex, i, &currItem); | ||
247 | tmpSorted[currItem.listViewPos] = currItem; | ||
248 | } | ||
249 | |||
250 | // shift tempoary data to ListView. | ||
251 | tmpDisableSort(); | ||
252 | lv->clear(); | ||
253 | QCheckListItem *newItem; | ||
254 | vector<PwMDataItem>::iterator it = tmpSorted.begin(), | ||
255 | end = tmpSorted.end(); | ||
256 | while (it != end) { | ||
257 | newItem = new ListViewItemPwM(lv); | ||
258 | newItem->setText(COLUMN_DESC, (*it).desc.c_str()); | ||
259 | if ((*it).binary) { | ||
260 | newItem->setText(COLUMN_NAME, ""); | ||
261 | newItem->setText(COLUMN_PW, i18n("<BINARY ENTRY>")); | ||
262 | newItem->setText(COLUMN_URL, ""); | ||
263 | newItem->setText(COLUMN_LAUNCHER, (*it).launcher.c_str()); | ||
264 | } else { | ||
265 | newItem->setText(COLUMN_NAME, (*it).name.c_str()); | ||
266 | if ((*it).lockStat) { | ||
267 | newItem->setText(COLUMN_PW, QString((*it).pw.c_str()) | ||
268 | + " " | ||
269 | + i18n("To unlock click the icon on the left.")); | ||
270 | } else { | ||
271 | newItem->setText(COLUMN_PW, (*it).pw.c_str()); | ||
272 | } | ||
273 | newItem->setText(COLUMN_URL, (*it).url.c_str()); | ||
274 | newItem->setText(COLUMN_LAUNCHER, (*it).launcher.c_str()); | ||
275 | } | ||
276 | newItem->setOn(!((*it).lockStat)); | ||
277 | lv->insertItem(newItem); | ||
278 | ++it; | ||
279 | } | ||
280 | tmpReEnableSort(); | ||
281 | |||
282 | if (cY || cX) | ||
283 | lv->setContentsPos(cX, cY); | ||
284 | } | ||
285 | |||
286 | void PwMView::reorgLp() | ||
287 | { | ||
288 | if (!lv->childCount()) | ||
289 | return; | ||
290 | PWM_ASSERT(doc); | ||
291 | PWM_ASSERT(!doc->isDocEmpty()); | ||
292 | QListViewItem *currItem; | ||
293 | vector<unsigned int> foundPos; | ||
294 | /* This searchIn _should_ be: | ||
295 | *const unsigned int searchIn = SEARCH_IN_DESC; | ||
296 | * But we want backward compatibility (see comment in PwMDoc::addEntry()). | ||
297 | * So we need to search again, if we don't find the entry. (see below) | ||
298 | */ | ||
299 | const unsigned int searchIn = SEARCH_IN_DESC | SEARCH_IN_NAME | | ||
300 | SEARCH_IN_URL | SEARCH_IN_LAUNCHER; | ||
301 | QString curCat(getCurrentCategory()); | ||
302 | PwMDataItem findThis; | ||
303 | unsigned int i, cnt = lv->childCount(); | ||
304 | for (i = 0; i < cnt; ++i) { | ||
305 | currItem = lv->itemAtIndex(i); | ||
306 | findThis.desc = currItem->text(COLUMN_DESC).latin1(); | ||
307 | findThis.name = currItem->text(COLUMN_NAME).latin1(); | ||
308 | findThis.url = currItem->text(COLUMN_URL).latin1(); | ||
309 | findThis.launcher = currItem->text(COLUMN_LAUNCHER).latin1(); | ||
310 | doc->findEntry(curCat, findThis, searchIn, | ||
311 | &foundPos, true); | ||
312 | if (!foundPos.size()) { | ||
313 | /* Did not find the entry. We seem to have a binary | ||
314 | * entry here (pray for it!). So search again with | ||
315 | * the "correct" searchIn flags. | ||
316 | */ | ||
317 | const unsigned int searchIn2 = SEARCH_IN_DESC; | ||
318 | doc->findEntry(curCat, findThis, searchIn2, | ||
319 | &foundPos, true); | ||
320 | if (unlikely(!foundPos.size())) { | ||
321 | BUG(); | ||
322 | continue; | ||
323 | } | ||
324 | /* We assert that it's a binary entry, now. | ||
325 | * No chance to efficiently verify it here. | ||
326 | */ | ||
327 | } | ||
328 | doc->setListViewPos(curCat, foundPos[0], cnt - i - 1); | ||
329 | } | ||
330 | } | ||
331 | |||
332 | void PwMView::selAt(int index) | ||
333 | { | ||
334 | QListViewItem *item = lv->itemAtIndex(index); | ||
335 | if (!item) | ||
336 | return; | ||
337 | lv->setCurrentItem(item); | ||
338 | lv->ensureItemVisible(item); | ||
339 | } | ||
340 | |||
341 | void PwMView::renCatButton_slot() | ||
342 | { | ||
343 | if (doc->isDeepLocked()) | ||
344 | return; | ||
345 | RenCatWnd wnd(this); | ||
346 | if (wnd.exec() == 1) { | ||
347 | QString newName(wnd.getNewName()); | ||
348 | if (newName == "") | ||
349 | return; | ||
350 | document()->renameCategory(getCurrentCategory(), | ||
351 | newName); | ||
352 | } | ||
353 | } | ||
354 | |||
355 | void PwMView::delCatButton_slot() | ||
356 | { | ||
357 | if (doc->isDeepLocked()) | ||
358 | return; | ||
359 | if (numCategories() <= 1) { | ||
360 | mainClass->showStatMsg(i18n("Can't remove the last category.")); | ||
361 | return; | ||
362 | } | ||
363 | if (KMessageBox::questionYesNo(this, | ||
364 | i18n("Do you really want to " | ||
365 | "delete the selected " | ||
366 | "category? All password-" | ||
367 | "entries will be lost in " | ||
368 | "this category!"), | ||
369 | i18n("Delete category?")) | ||
370 | == KMessageBox::No) { | ||
371 | return; | ||
372 | } | ||
373 | document()->delCategory(getCurrentCategory()); | ||
374 | } | ||
375 | |||
376 | void PwMView::copyPwToClip() | ||
377 | { | ||
378 | if (doc->isDeepLocked()) | ||
379 | return; | ||
380 | unsigned int curIndex = 0; | ||
381 | if (!getCurEntryIndex(&curIndex)) | ||
382 | return; | ||
383 | PwMDataItem d; | ||
384 | document()->getDataChangedLock(); | ||
385 | document()->getEntry(getCurrentCategory(), curIndex, &d, true); | ||
386 | document()->putDataChangedLock(); | ||
387 | PwM::copyToClipboard(d.pw.c_str()); | ||
388 | } | ||
389 | |||
390 | void PwMView::copyNameToClip() | ||
391 | { | ||
392 | if (doc->isDeepLocked()) | ||
393 | return; | ||
394 | unsigned int curIndex = 0; | ||
395 | if (!getCurEntryIndex(&curIndex)) | ||
396 | return; | ||
397 | PwMDataItem d; | ||
398 | document()->getEntry(getCurrentCategory(), curIndex, &d); | ||
399 | PwM::copyToClipboard(d.name.c_str()); | ||
400 | } | ||
401 | |||
402 | void PwMView::copyDescToClip() | ||
403 | { | ||
404 | if (doc->isDeepLocked()) | ||
405 | return; | ||
406 | unsigned int curIndex = 0; | ||
407 | if (!getCurEntryIndex(&curIndex)) | ||
408 | return; | ||
409 | PwMDataItem d; | ||
410 | document()->getEntry(getCurrentCategory(), curIndex, &d); | ||
411 | PwM::copyToClipboard(d.desc.c_str()); | ||
412 | } | ||
413 | |||
414 | void PwMView::copyUrlToClip() | ||
415 | { | ||
416 | if (doc->isDeepLocked()) | ||
417 | return; | ||
418 | unsigned int curIndex = 0; | ||
419 | if (!getCurEntryIndex(&curIndex)) | ||
420 | return; | ||
421 | PwMDataItem d; | ||
422 | document()->getEntry(getCurrentCategory(), curIndex, &d); | ||
423 | PwM::copyToClipboard(d.url.c_str()); | ||
424 | } | ||
425 | |||
426 | void PwMView::copyLauncherToClip() | ||
427 | { | ||
428 | if (doc->isDeepLocked()) | ||
429 | return; | ||
430 | unsigned int curIndex = 0; | ||
431 | if (!getCurEntryIndex(&curIndex)) | ||
432 | return; | ||
433 | PwMDataItem d; | ||
434 | document()->getEntry(getCurrentCategory(), curIndex, &d); | ||
435 | PwM::copyToClipboard(d.launcher.c_str()); | ||
436 | } | ||
437 | |||
438 | void PwMView::copyCommentToClip() | ||
439 | { | ||
440 | if (doc->isDeepLocked()) | ||
441 | return; | ||
442 | unsigned int curIndex = 0; | ||
443 | if (!getCurEntryIndex(&curIndex)) | ||
444 | return; | ||
445 | PwMDataItem d; | ||
446 | document()->getEntry(getCurrentCategory(), curIndex, &d); | ||
447 | PwM::copyToClipboard(d.comment.c_str()); | ||
448 | } | ||
449 | |||
450 | #ifndef PWM_EMBEDDED | ||
451 | #include "pwmview.moc" | ||
452 | #endif | ||