summaryrefslogtreecommitdiffabout
path: root/pwmanager/pwmanager/pwmview.cpp
Unidiff
Diffstat (limited to 'pwmanager/pwmanager/pwmview.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--pwmanager/pwmanager/pwmview.cpp452
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
42PwMView::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
61PwMView::~PwMView()
62{
63}
64
65void 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
92void PwMView::resizeEvent(QResizeEvent *)
93{
94 resizeView(size());
95}
96
97void 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
120void PwMView::keyReleaseEvent(QKeyEvent * /*e*/)
121{
122 refreshCommentTextEdit(lv->currentItem());
123}
124
125bool PwMView::getCurEntryIndex(unsigned int *index)
126{
127 QListViewItem *current = lv->currentItem();
128 if (!current)
129 return false;
130 return getDocEntryIndex(index, current);
131}
132
133bool 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
157void 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
186void 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
197void 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
218void 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
286void 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
332void 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
341void 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
355void 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
376void 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
390void 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
402void 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
414void 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
426void 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
438void 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