Diffstat (limited to 'pwmanager/pwmanager/pwmtray.cpp') (more/less context) (show whitespace changes)
-rw-r--r-- | pwmanager/pwmanager/pwmtray.cpp | 482 |
1 files changed, 482 insertions, 0 deletions
diff --git a/pwmanager/pwmanager/pwmtray.cpp b/pwmanager/pwmanager/pwmtray.cpp new file mode 100644 index 0000000..0f286c1 --- a/dev/null +++ b/pwmanager/pwmanager/pwmtray.cpp | |||
@@ -0,0 +1,482 @@ | |||
1 | /*************************************************************************** | ||
2 | * * | ||
3 | * copyright (C) 2003, 2004 by Michael Buesch * | ||
4 | * email: mbuesch@freenet.de * | ||
5 | * * | ||
6 | * Original implementation of the tray-tree * | ||
7 | * (c) by Matt Scifo <mscifo@o1.com> * | ||
8 | * * | ||
9 | * This program is free software; you can redistribute it and/or modify * | ||
10 | * it under the terms of the GNU General Public License version 2 * | ||
11 | * as published by the Free Software Foundation. * | ||
12 | * * | ||
13 | ***************************************************************************/ | ||
14 | |||
15 | /*************************************************************************** | ||
16 | * copyright (C) 2004 by Ulf Schenk | ||
17 | * This file is originaly based on version 1.0.1 of pwmanager | ||
18 | * and was modified to run on embedded devices that run microkde | ||
19 | * | ||
20 | * $Id$ | ||
21 | **************************************************************************/ | ||
22 | |||
23 | #include "pwmtray.h" | ||
24 | #include "pwmexception.h" | ||
25 | #include "pwm.h" | ||
26 | #include "pwmdoc.h" | ||
27 | #include "pwminit.h" | ||
28 | #include "configuration.h" | ||
29 | |||
30 | #include <klocale.h> | ||
31 | |||
32 | |||
33 | void ActiveTreeItem::execIt() | ||
34 | { | ||
35 | #ifndef PWM_EMBEDDED | ||
36 | unsigned int entr = static_cast<unsigned int>(entry); | ||
37 | unsigned int cat = static_cast<unsigned int>(category); | ||
38 | #else | ||
39 | unsigned int entr = (unsigned int)(entry); | ||
40 | unsigned int cat = (unsigned int)(category); | ||
41 | #endif | ||
42 | switch (task) { | ||
43 | case pwToClipboard: { | ||
44 | PwMDataItem d; | ||
45 | doc->getDataChangedLock(); | ||
46 | bool wasLocked = doc->isLocked(cat, entr); | ||
47 | doc->getEntry(cat, entr, &d, true); | ||
48 | if (wasLocked) | ||
49 | doc->lockAt(cat, entr, true); | ||
50 | doc->putDataChangedLock(); | ||
51 | PwM::copyToClipboard(d.pw.c_str()); | ||
52 | break; | ||
53 | } case nameToClipboard: { | ||
54 | PwMDataItem d; | ||
55 | doc->getEntry(cat, entr, &d); | ||
56 | PwM::copyToClipboard(d.name.c_str()); | ||
57 | break; | ||
58 | } case descToClipboard: { | ||
59 | PwMDataItem d; | ||
60 | doc->getEntry(cat, entr, &d); | ||
61 | PwM::copyToClipboard(d.desc.c_str()); | ||
62 | break; | ||
63 | } case urlToClipboard: { | ||
64 | PwMDataItem d; | ||
65 | doc->getEntry(cat, entr, &d); | ||
66 | PwM::copyToClipboard(d.url.c_str()); | ||
67 | break; | ||
68 | } case launcherToClipboard: { | ||
69 | PwMDataItem d; | ||
70 | doc->getEntry(cat, entr, &d); | ||
71 | PwM::copyToClipboard(d.launcher.c_str()); | ||
72 | break; | ||
73 | } case commentToClipboard: { | ||
74 | PwMDataItem d; | ||
75 | doc->getEntry(cat, entr, &d); | ||
76 | PwM::copyToClipboard(d.comment.c_str()); | ||
77 | break; | ||
78 | } case execLauncher: { | ||
79 | doc->execLauncher(cat, entr); | ||
80 | break; | ||
81 | } case goToURL: { | ||
82 | doc->goToURL(cat, entr); | ||
83 | break; | ||
84 | } case openMainWnd: { | ||
85 | // search if there is already an open window. | ||
86 | const QValueList<PwM *> *wl = tray->init->mainWndList(); | ||
87 | #ifndef PWM_EMBEDDED | ||
88 | QValueList<PwM *>::const_iterator i = wl->begin(), | ||
89 | end = wl->end(); | ||
90 | #else | ||
91 | QValueList<PwM *>::ConstIterator i = wl->begin(), | ||
92 | end = wl->end(); | ||
93 | #endif | ||
94 | PwM *wnd; | ||
95 | while (i != end) { | ||
96 | wnd = *i; | ||
97 | if (wnd->curDoc() == doc) { | ||
98 | // now bring this window to the foreground. | ||
99 | if (!wnd->hasFocus()) { | ||
100 | wnd->hide(); | ||
101 | wnd->showNormal(); | ||
102 | wnd->setFocus(); | ||
103 | } | ||
104 | return; | ||
105 | } | ||
106 | ++i; | ||
107 | } | ||
108 | // there is no open window, so open a new one. | ||
109 | tray->init->createMainWnd(QString::null, false, false, doc); | ||
110 | break; | ||
111 | } case closeDoc: { | ||
112 | doc->tryDelete(); | ||
113 | break; | ||
114 | } case lock: { | ||
115 | doc->lockAll(true); | ||
116 | break; | ||
117 | } case deepLock: { | ||
118 | doc->deepLock(); | ||
119 | break; | ||
120 | } case unlock: { | ||
121 | doc->lockAll(false); | ||
122 | break; | ||
123 | } default: { | ||
124 | BUG(); | ||
125 | } | ||
126 | } | ||
127 | } | ||
128 | |||
129 | |||
130 | |||
131 | #ifndef PWM_EMBEDDED | ||
132 | PwMTray::PwMTray(PwMInit *_init, QWidget * parent, const char *name) | ||
133 | : KSystemTray(parent, name) | ||
134 | #else | ||
135 | PwMTray::PwMTray(PwMInit *_init, QWidget * parent, const char *name) | ||
136 | : QWidget(parent, name) | ||
137 | #endif | ||
138 | { | ||
139 | init = _init; | ||
140 | buildMain(); | ||
141 | } | ||
142 | |||
143 | PwMTray::~PwMTray() | ||
144 | { | ||
145 | emit closed(this); | ||
146 | } | ||
147 | |||
148 | //US ENH for embedded tray class | ||
149 | KPopupMenu* PwMTray::contextMenu() | ||
150 | { | ||
151 | if (m_ctxMenu == 0) | ||
152 | { | ||
153 | m_ctxMenu = new KPopupMenu(); | ||
154 | } | ||
155 | |||
156 | return m_ctxMenu; | ||
157 | } | ||
158 | |||
159 | |||
160 | void PwMTray::buildMain() | ||
161 | { | ||
162 | KPopupMenu *ctxMenu = contextMenu(); | ||
163 | |||
164 | ctxMenu->insertSeparator(); | ||
165 | ctxMenu->insertItem(i18n("&New main window..."), this, | ||
166 | SLOT(newMainWnd())); | ||
167 | ctxMenu->insertItem(i18n("&Open file..."), this, | ||
168 | SLOT(openDoc())); | ||
169 | ctxMenu->insertSeparator(); | ||
170 | ctxMenu->insertItem(i18n("&Remove from tray"), this, | ||
171 | SLOT(undock())); | ||
172 | } | ||
173 | |||
174 | void PwMTray::insertActiveTreeItem(KPopupMenu *insertIn, const QString &text, | ||
175 | ActiveTreeItem::Task task, PwMDoc *doc, | ||
176 | int docCategory, int docEntry, | ||
177 | QValueList<int> *activeItemsList) | ||
178 | { | ||
179 | ActiveTreeItem *activeItem; | ||
180 | int id; | ||
181 | |||
182 | activeItem = new ActiveTreeItem(text, insertIn->font(), task, | ||
183 | doc, docCategory, docEntry, | ||
184 | this); | ||
185 | id = insertIn->insertItem(activeItem); | ||
186 | insertIn->connectItem(id, activeItem, SLOT(execIt())); | ||
187 | #ifndef PWM_EMBEDDED | ||
188 | activeItemsList->push_back(id); | ||
189 | #else | ||
190 | activeItemsList->append(id); | ||
191 | #endif | ||
192 | } | ||
193 | |||
194 | void PwMTray::rebuildTree(KPopupMenu *popup, PwMDoc *doc, | ||
195 | QValueList<int> *activeItems) | ||
196 | { | ||
197 | PWM_ASSERT(doc); | ||
198 | PWM_ASSERT(popup); | ||
199 | activeItems->clear(); | ||
200 | popup->clear(); | ||
201 | #ifndef PWM_EMBEDDED | ||
202 | popup->insertTitle(i18n("Categories:")); | ||
203 | #endif | ||
204 | vector<string> catList; | ||
205 | vector<string> entrList; | ||
206 | doc->getCategoryList(&catList); | ||
207 | KPopupMenu *newCatMenu; | ||
208 | KPopupMenu *newEntrMenu; | ||
209 | int i, size = catList.size(); | ||
210 | int j, entries; | ||
211 | for (i = 0; i < size; ++i) { | ||
212 | newCatMenu = new KPopupMenu(popup); | ||
213 | popup->insertItem(catList[i].c_str(), newCatMenu); | ||
214 | doc->getEntryList(i, &entrList); | ||
215 | |||
216 | entries = entrList.size(); | ||
217 | for (j = 0; j < entries; ++j) { | ||
218 | newEntrMenu = new KPopupMenu(newCatMenu); | ||
219 | newCatMenu->insertItem(entrList[j].c_str(), newEntrMenu); | ||
220 | |||
221 | if (doc->isBinEntry(i, j)) { | ||
222 | /* This is a binary entry. Don't insert the usual | ||
223 | * menu items. | ||
224 | */ | ||
225 | #ifndef PWM_EMBEDDED | ||
226 | newEntrMenu->insertTitle(i18n("This is a binary entry.\n" | ||
227 | "It is not a normal password-entry, as it contains " | ||
228 | "binary data, which PwManager can't display here.")); | ||
229 | #endif | ||
230 | continue; | ||
231 | } | ||
232 | |||
233 | insertActiveTreeItem(newEntrMenu, | ||
234 | i18n("copy password to clipboard"), | ||
235 | ActiveTreeItem::pwToClipboard, doc, i, j, | ||
236 | activeItems); | ||
237 | |||
238 | insertActiveTreeItem(newEntrMenu, | ||
239 | i18n("copy username to clipboard"), | ||
240 | ActiveTreeItem::nameToClipboard, doc, i, j, | ||
241 | activeItems); | ||
242 | |||
243 | insertActiveTreeItem(newEntrMenu, | ||
244 | i18n("copy description to clipboard"), | ||
245 | ActiveTreeItem::descToClipboard, doc, i, j, | ||
246 | activeItems); | ||
247 | |||
248 | insertActiveTreeItem(newEntrMenu, | ||
249 | i18n("copy url to clipboard"), | ||
250 | ActiveTreeItem::urlToClipboard, doc, i, j, | ||
251 | activeItems); | ||
252 | |||
253 | insertActiveTreeItem(newEntrMenu, | ||
254 | i18n("copy launcher to clipboard"), | ||
255 | ActiveTreeItem::launcherToClipboard, doc, i, j, | ||
256 | activeItems); | ||
257 | |||
258 | insertActiveTreeItem(newEntrMenu, | ||
259 | i18n("copy comment to clipboard"), | ||
260 | ActiveTreeItem::commentToClipboard, doc, i, j, | ||
261 | activeItems); | ||
262 | |||
263 | newEntrMenu->insertSeparator(); | ||
264 | |||
265 | insertActiveTreeItem(newEntrMenu, | ||
266 | i18n("Execute \"Launcher\""), | ||
267 | ActiveTreeItem::execLauncher, doc, i, j, | ||
268 | activeItems); | ||
269 | |||
270 | insertActiveTreeItem(newEntrMenu, | ||
271 | i18n("Go to \"URL\""), | ||
272 | ActiveTreeItem::goToURL, doc, i, j, | ||
273 | activeItems); | ||
274 | } | ||
275 | } | ||
276 | insertMainWndCtrl(popup, doc); | ||
277 | } | ||
278 | |||
279 | void PwMTray::insertMainWndCtrl(KPopupMenu *menu, PwMDoc *doc) | ||
280 | { | ||
281 | ActiveTreeItem *activeItem; | ||
282 | int id; | ||
283 | |||
284 | #ifndef PWM_EMBEDDED | ||
285 | menu->insertTitle(i18n("Manager:")); | ||
286 | #endif | ||
287 | activeItem = new ActiveTreeItem(i18n("&Open main manager window ..."), | ||
288 | menu->font(), ActiveTreeItem::openMainWnd, | ||
289 | doc, 0, 0, this); | ||
290 | id = menu->insertItem(activeItem); | ||
291 | menu->connectItem(id, activeItem, SLOT(execIt())); | ||
292 | |||
293 | activeItem = new ActiveTreeItem(i18n("&Close this document ..."), | ||
294 | menu->font(), ActiveTreeItem::closeDoc, | ||
295 | doc, 0, 0, this); | ||
296 | id = menu->insertItem(activeItem); | ||
297 | menu->connectItem(id, activeItem, SLOT(execIt())); | ||
298 | |||
299 | menu->insertSeparator(); | ||
300 | |||
301 | activeItem = new ActiveTreeItem(i18n("&Lock all entries"), | ||
302 | menu->font(), ActiveTreeItem::lock, | ||
303 | doc, 0, 0, this); | ||
304 | id = menu->insertItem(activeItem); | ||
305 | menu->connectItem(id, activeItem, SLOT(execIt())); | ||
306 | |||
307 | activeItem = new ActiveTreeItem(i18n("&Deep-lock all entries"), | ||
308 | menu->font(), ActiveTreeItem::deepLock, | ||
309 | doc, 0, 0, this); | ||
310 | id = menu->insertItem(activeItem); | ||
311 | menu->connectItem(id, activeItem, SLOT(execIt())); | ||
312 | |||
313 | activeItem = new ActiveTreeItem(i18n("&Unlock all entries"), | ||
314 | menu->font(), ActiveTreeItem::unlock, | ||
315 | doc, 0, 0, this); | ||
316 | id = menu->insertItem(activeItem); | ||
317 | menu->connectItem(id, activeItem, SLOT(execIt())); | ||
318 | } | ||
319 | |||
320 | void PwMTray::updateTree(PwMDoc *document) | ||
321 | { | ||
322 | PWM_ASSERT(document); | ||
323 | KPopupMenu *treeEntry; | ||
324 | int treeItemNum = -1; | ||
325 | int id = findTreeEntry(document, &treeEntry, &treeItemNum); | ||
326 | if (id == -1) { | ||
327 | // tree-entry doesn't exist, yet. | ||
328 | id = insertTreeEntry(document, &treeEntry); | ||
329 | } | ||
330 | if (treeItemNum != -1) { | ||
331 | // delete all *old* active items | ||
332 | KPopupMenu *ctxMenu = contextMenu(); | ||
333 | QValueList<int> *oldItems = &tree[treeItemNum].activeItems; | ||
334 | #ifndef PWM_EMBEDDED | ||
335 | QValueList<int>::iterator i = oldItems->begin(); | ||
336 | #else | ||
337 | QValueList<int>::Iterator i = oldItems->begin(); | ||
338 | #endif | ||
339 | while (i != oldItems->end()) { | ||
340 | ctxMenu->removeItem(*i); | ||
341 | ++i; | ||
342 | } | ||
343 | oldItems->clear(); | ||
344 | ctxMenu->changeItem(id, document->getTitle()); | ||
345 | } | ||
346 | |||
347 | treeItem newTreeItem; | ||
348 | if (document->isDeepLocked()) { | ||
349 | treeEntry->clear(); | ||
350 | #ifndef PWM_EMBEDDED | ||
351 | treeEntry->insertTitle(i18n("Categories:")); | ||
352 | #endif | ||
353 | QString msg(IS_DEEPLOCKED_SHORTMSG); | ||
354 | msg += " "; | ||
355 | msg += i18n("(Click here to unlock)"); | ||
356 | treeEntry->insertItem(msg, document, | ||
357 | SLOT(_deepUnlock())); | ||
358 | insertMainWndCtrl(treeEntry, document); | ||
359 | } else { | ||
360 | rebuildTree(treeEntry, document, &newTreeItem.activeItems); | ||
361 | } | ||
362 | newTreeItem.menuId = id; | ||
363 | newTreeItem.doc = document; | ||
364 | newTreeItem.menu = treeEntry; | ||
365 | if (treeItemNum == -1) { | ||
366 | #ifndef PWM_EMBEDDED | ||
367 | tree.push_back(newTreeItem); | ||
368 | #else | ||
369 | tree.append(newTreeItem); | ||
370 | #endif | ||
371 | } else { | ||
372 | tree[treeItemNum] = newTreeItem; | ||
373 | } | ||
374 | } | ||
375 | |||
376 | void PwMTray::closeTreeEntry(PwMDoc *document) | ||
377 | { | ||
378 | KPopupMenu *menu; | ||
379 | int treeItem; | ||
380 | int id = findTreeEntry(document, &menu, &treeItem); | ||
381 | if (id != -1) { | ||
382 | removeTreeEntry(id, treeItem, &menu); | ||
383 | } | ||
384 | } | ||
385 | |||
386 | int PwMTray::findTreeEntry(PwMDoc *doc, KPopupMenu **menu, int *treeItem) | ||
387 | { | ||
388 | PWM_ASSERT(doc); | ||
389 | #ifndef PWM_EMBEDDED | ||
390 | int i, count = tree.size(); | ||
391 | #else | ||
392 | int i, count = tree.count(); | ||
393 | #endif | ||
394 | for (i = 0; i < count; ++i) { | ||
395 | if (tree[i].doc == doc) { | ||
396 | if (menu) | ||
397 | *menu = tree[i].menu; | ||
398 | if (treeItem) | ||
399 | *treeItem = i; | ||
400 | return tree[i].menuId; | ||
401 | } | ||
402 | } | ||
403 | if (menu) | ||
404 | *menu = 0; | ||
405 | if (treeItem) | ||
406 | *treeItem = -1; | ||
407 | return -1; | ||
408 | } | ||
409 | |||
410 | int PwMTray::insertTreeEntry(PwMDoc *doc, KPopupMenu **popup) | ||
411 | { | ||
412 | PWM_ASSERT(doc); | ||
413 | PWM_ASSERT(popup); | ||
414 | KPopupMenu *ctxMenu = contextMenu(); | ||
415 | *popup = new KPopupMenu(ctxMenu); | ||
416 | return ctxMenu->insertItem(doc->getTitle(), *popup, -1, 1); | ||
417 | } | ||
418 | |||
419 | void PwMTray::removeTreeEntry(int menuId, int treeItem, KPopupMenu **menu) | ||
420 | { | ||
421 | PWM_ASSERT(menu); | ||
422 | KPopupMenu *ctxMenu = contextMenu(); | ||
423 | ctxMenu->removeItem(menuId); | ||
424 | delete_and_null(*menu); | ||
425 | #ifndef PWM_EMBEDDED | ||
426 | tree.erase(tree.at(treeItem)); | ||
427 | #else | ||
428 | tree.remove(tree.at(treeItem)); | ||
429 | #endif | ||
430 | } | ||
431 | |||
432 | void PwMTray::mouseReleaseEvent(QMouseEvent *e) | ||
433 | { | ||
434 | QWidget *curWnd = init->curWidget(); | ||
435 | KPopupMenu *ctxMenu = contextMenu(); | ||
436 | // give focus to init->curWidget() | ||
437 | if (curWnd && !curWnd->hasFocus()) { | ||
438 | curWnd->hide(); | ||
439 | curWnd->showNormal(); | ||
440 | curWnd->setFocus(); | ||
441 | } | ||
442 | // popup the context menu | ||
443 | ctxMenu->popup(e->globalPos()); | ||
444 | emit clickedIcon(this); | ||
445 | } | ||
446 | |||
447 | void PwMTray::connectDocToTray(PwMDoc *doc) | ||
448 | { | ||
449 | connect(doc, SIGNAL(dataChanged(PwMDoc *)), | ||
450 | this, SLOT(updateTree(PwMDoc *))); | ||
451 | connect(doc, SIGNAL(docClosed(PwMDoc *)), | ||
452 | this, SLOT(closeTreeEntry(PwMDoc *))); | ||
453 | // fake a dataChanged signal for this doc to update the tray tree. | ||
454 | updateTree(doc); | ||
455 | } | ||
456 | |||
457 | void PwMTray::openDoc() | ||
458 | { | ||
459 | // open the document in a new window. | ||
460 | PwM *newInstance = init->createMainWnd(); | ||
461 | PwMDoc *newDoc = newInstance->openDoc(""); | ||
462 | if (!newDoc) { | ||
463 | newInstance->setForceQuit(true); | ||
464 | delete_and_null(newInstance); | ||
465 | } | ||
466 | } | ||
467 | |||
468 | void PwMTray::newMainWnd() | ||
469 | { | ||
470 | init->createMainWnd(); | ||
471 | } | ||
472 | |||
473 | void PwMTray::undock() | ||
474 | { | ||
475 | conf()->confGlobTray(false); | ||
476 | init->initTray(); | ||
477 | // Attention! "this" is already deleted here! | ||
478 | } | ||
479 | |||
480 | #ifndef PWM_EMBEDDED | ||
481 | #include "pwmtray.moc" | ||
482 | #endif | ||