summaryrefslogtreecommitdiffabout
path: root/pwmanager/pwmanager/pwmview.cpp
Side-by-side diff
Diffstat (limited to 'pwmanager/pwmanager/pwmview.cpp') (more/less context) (show 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 @@
+/***************************************************************************
+ * *
+ * 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 "pwmview.h"
+#include "pwmexception.h"
+#include "globalstuff.h"
+#include "pwm.h"
+#include "rencatwnd.h"
+#include "configuration.h"
+#include "commentbox.h"
+
+#include <kmessagebox.h>
+#include <klocale.h>
+
+#include <qlineedit.h>
+#include <qpoint.h>
+#include <qapplication.h>
+
+#define COLUMN_DESC 0
+#define COLUMN_NAME 1
+#define COLUMN_PW 2
+#define COLUMN_URL 3
+#define COLUMN_LAUNCHER 4
+
+
+PwMView::PwMView(PwM *_mainClass,
+ QWidget *parent, PwMDoc *_doc,
+ const char *name)
+ : PwMViewStyle(parent, name)
+{
+ PWM_ASSERT(_mainClass);
+ PWM_ASSERT(parent);
+ PWM_ASSERT(_doc);
+ setView(this);
+ doc = _doc;
+ doc->setListViewPointer(this);
+ mainClass = _mainClass;
+ resize(_mainClass->size());
+ initStyle(conf()->confWndMainViewStyle());
+ initCtxMenu();
+ doc->setCurrentView(this);
+ connect(doc, SIGNAL(dataChanged(PwMDoc *)), this, SLOT(updateView()));
+}
+
+PwMView::~PwMView()
+{
+}
+
+void PwMView::initCtxMenu()
+{
+ ctxMenu = new QPopupMenu(this);
+ ctxMenu->insertItem(i18n("&Add password"), mainClass, SLOT(addPwd_slot()));
+ ctxMenu->insertSeparator();
+ ctxMenu->insertItem(i18n("&Edit"), mainClass, SLOT(editPwd_slot()));
+ ctxMenu->insertItem(i18n("&Delete"), mainClass, SLOT(deletePwd_slot()));
+ ctxMenu->insertSeparator();
+ ctxMenu->insertItem(i18n("copy password to clipboard"),
+ this, SLOT(copyPwToClip()));
+ ctxMenu->insertItem(i18n("copy username to clipboard"),
+ this, SLOT(copyNameToClip()));
+ ctxMenu->insertItem(i18n("copy description to clipboard"),
+ this, SLOT(copyDescToClip()));
+ ctxMenu->insertItem(i18n("copy url to clipboard"),
+ this, SLOT(copyUrlToClip()));
+ ctxMenu->insertItem(i18n("copy launcher to clipboard"),
+ this, SLOT(copyLauncherToClip()));
+ ctxMenu->insertItem(i18n("copy comment to clipboard"),
+ this, SLOT(copyCommentToClip()));
+ ctxMenu->insertSeparator();
+ ctxMenu->insertItem(i18n("Execute \"Launcher\""), mainClass,
+ SLOT(execLauncher_slot()));
+ ctxMenu->insertItem(i18n("Go to \"URL\""), mainClass,
+ SLOT(goToURL_slot()));
+}
+
+void PwMView::resizeEvent(QResizeEvent *)
+{
+ resizeView(size());
+}
+
+void PwMView::refreshCommentTextEdit(QListViewItem *curItem)
+{
+ PWM_ASSERT(commentBox);
+ if (!curItem)
+ return;
+ string comment;
+ PwMerror ret;
+ ret = document()->getCommentByLvp(getCurrentCategory(),
+ lv->childCount() - lv->itemIndex(curItem) - 1,
+ &comment);
+ if (ret == e_binEntry) {
+ commentBox->setContent(i18n("This is a binary entry.\n"
+ "It is not a normal password-entry, as it contains "
+ "binary data, which PwManager can't display here."));
+ } else if (ret == e_normalEntry) {
+ commentBox->setContent(comment.c_str());
+ } else {
+ BUG();
+ return;
+ }
+ lv->ensureItemVisible(curItem);
+}
+
+void PwMView::keyReleaseEvent(QKeyEvent * /*e*/)
+{
+ refreshCommentTextEdit(lv->currentItem());
+}
+
+bool PwMView::getCurEntryIndex(unsigned int *index)
+{
+ QListViewItem *current = lv->currentItem();
+ if (!current)
+ return false;
+ return getDocEntryIndex(index, current);
+}
+
+bool PwMView::getDocEntryIndex(unsigned int *index,
+ const QListViewItem *item)
+{
+ vector<unsigned int> foundPositions;
+ PwMDataItem curItem;
+ curItem.desc = item->text(COLUMN_DESC).latin1();
+ curItem.name = item->text(COLUMN_NAME).latin1();
+ document()->getCommentByLvp(getCurrentCategory(),
+ lv->childCount() - lv->itemIndex(item) - 1,
+ &curItem.comment);
+ curItem.url = item->text(COLUMN_URL).latin1();
+ curItem.launcher = item->text(COLUMN_LAUNCHER).latin1();
+ document()->findEntry(getCurrentCategory(), curItem, SEARCH_IN_DESC |
+ SEARCH_IN_NAME | SEARCH_IN_COMMENT | SEARCH_IN_URL |
+ SEARCH_IN_LAUNCHER,
+ &foundPositions, true);
+ if (foundPositions.size()) {
+ *index = foundPositions[0];
+ return true;
+ }
+
+ return false;
+}
+
+void PwMView::handleToggle(QListViewItem *item)
+{
+ PWM_ASSERT(doc);
+ if (!item)
+ return;
+ QCheckListItem *clItem = (QCheckListItem *)item;
+ QString curCat(getCurrentCategory());
+
+ // find document position of this entry.
+ unsigned int curEntryDocIndex;
+ if (!getDocEntryIndex(&curEntryDocIndex, item))
+ return;
+
+ // hack to refresh the comment, if only one item is present
+ if (lv->childCount() == 1)
+ refreshCommentTextEdit(lv->currentItem());
+
+ if (doc->isLocked(curCat, curEntryDocIndex) != clItem->isOn())
+ return; // this is just a click somewhere on the entry
+ if (doc->isDeepLocked()) {
+ PwMerror ret;
+ ret = doc->deepLock(false);
+ if (ret != e_success)
+ clItem->setOn(false);
+ return;
+ }
+ doc->lockAt(curCat, curEntryDocIndex, !clItem->isOn());
+}
+
+void PwMView::handleRightClick(QListViewItem *item, const QPoint &point, int)
+{
+ if (!item)
+ return;
+ ctxMenu->move(point);
+ /* don't use ctxMenu->exec() here, as it generates race conditions
+ * with the card interface code. Believe it or not. :)
+ */
+ ctxMenu->show();
+}
+
+void PwMView::updateCategories()
+{
+ QString oldSel(getCurrentCategory());
+ delAllCategories();
+ QStringList catList;
+ document()->getCategoryList(&catList);
+ catList.sort();
+#ifndef PWM_EMBEDDED
+ QStringList::iterator i = catList.begin(),
+ end = catList.end();
+#else
+ QStringList::Iterator i = catList.begin(),
+ end = catList.end();
+#endif
+ while (i != end) {
+ addCategory(*i);
+ ++i;
+ }
+ selectCategory(oldSel);
+}
+
+void PwMView::shiftToView()
+{
+ int cX = lv->contentsX();
+ int cY = lv->contentsY();
+ commentBox->clear();
+
+ unsigned int catDocIndex;
+ if (unlikely(
+ !(document()->findCategory(getCurrentCategory(),
+ &catDocIndex)))) {
+ BUG();
+ }
+
+ // ensure all listViewPos are set
+ doc->ensureLvp();
+
+ // clear all tmp-data vectors
+ unsigned int i, entries = doc->numEntries(catDocIndex);
+ if (entries) {
+ mainClass->setVirgin(false);
+ }
+ vector<PwMDataItem> tmpSorted;
+ PwMDataItem currItem;
+ currItem.clear();
+ tmpSorted.insert(tmpSorted.begin(), entries, currItem);
+
+ // Sort items and store them in tempoary tmpSorted.
+ for (i = 0; i < entries; ++i) {
+ doc->getEntry(catDocIndex, i, &currItem);
+ tmpSorted[currItem.listViewPos] = currItem;
+ }
+
+ // shift tempoary data to ListView.
+ tmpDisableSort();
+ lv->clear();
+ QCheckListItem *newItem;
+ vector<PwMDataItem>::iterator it = tmpSorted.begin(),
+ end = tmpSorted.end();
+ while (it != end) {
+ newItem = new ListViewItemPwM(lv);
+ newItem->setText(COLUMN_DESC, (*it).desc.c_str());
+ if ((*it).binary) {
+ newItem->setText(COLUMN_NAME, "");
+ newItem->setText(COLUMN_PW, i18n("<BINARY ENTRY>"));
+ newItem->setText(COLUMN_URL, "");
+ newItem->setText(COLUMN_LAUNCHER, (*it).launcher.c_str());
+ } else {
+ newItem->setText(COLUMN_NAME, (*it).name.c_str());
+ if ((*it).lockStat) {
+ newItem->setText(COLUMN_PW, QString((*it).pw.c_str())
+ + " "
+ + i18n("To unlock click the icon on the left."));
+ } else {
+ newItem->setText(COLUMN_PW, (*it).pw.c_str());
+ }
+ newItem->setText(COLUMN_URL, (*it).url.c_str());
+ newItem->setText(COLUMN_LAUNCHER, (*it).launcher.c_str());
+ }
+ newItem->setOn(!((*it).lockStat));
+ lv->insertItem(newItem);
+ ++it;
+ }
+ tmpReEnableSort();
+
+ if (cY || cX)
+ lv->setContentsPos(cX, cY);
+}
+
+void PwMView::reorgLp()
+{
+ if (!lv->childCount())
+ return;
+ PWM_ASSERT(doc);
+ PWM_ASSERT(!doc->isDocEmpty());
+ QListViewItem *currItem;
+ vector<unsigned int> foundPos;
+ /* This searchIn _should_ be:
+ * const unsigned int searchIn = SEARCH_IN_DESC;
+ * But we want backward compatibility (see comment in PwMDoc::addEntry()).
+ * So we need to search again, if we don't find the entry. (see below)
+ */
+ const unsigned int searchIn = SEARCH_IN_DESC | SEARCH_IN_NAME |
+ SEARCH_IN_URL | SEARCH_IN_LAUNCHER;
+ QString curCat(getCurrentCategory());
+ PwMDataItem findThis;
+ unsigned int i, cnt = lv->childCount();
+ for (i = 0; i < cnt; ++i) {
+ currItem = lv->itemAtIndex(i);
+ findThis.desc = currItem->text(COLUMN_DESC).latin1();
+ findThis.name = currItem->text(COLUMN_NAME).latin1();
+ findThis.url = currItem->text(COLUMN_URL).latin1();
+ findThis.launcher = currItem->text(COLUMN_LAUNCHER).latin1();
+ doc->findEntry(curCat, findThis, searchIn,
+ &foundPos, true);
+ if (!foundPos.size()) {
+ /* Did not find the entry. We seem to have a binary
+ * entry here (pray for it!). So search again with
+ * the "correct" searchIn flags.
+ */
+ const unsigned int searchIn2 = SEARCH_IN_DESC;
+ doc->findEntry(curCat, findThis, searchIn2,
+ &foundPos, true);
+ if (unlikely(!foundPos.size())) {
+ BUG();
+ continue;
+ }
+ /* We assert that it's a binary entry, now.
+ * No chance to efficiently verify it here.
+ */
+ }
+ doc->setListViewPos(curCat, foundPos[0], cnt - i - 1);
+ }
+}
+
+void PwMView::selAt(int index)
+{
+ QListViewItem *item = lv->itemAtIndex(index);
+ if (!item)
+ return;
+ lv->setCurrentItem(item);
+ lv->ensureItemVisible(item);
+}
+
+void PwMView::renCatButton_slot()
+{
+ if (doc->isDeepLocked())
+ return;
+ RenCatWnd wnd(this);
+ if (wnd.exec() == 1) {
+ QString newName(wnd.getNewName());
+ if (newName == "")
+ return;
+ document()->renameCategory(getCurrentCategory(),
+ newName);
+ }
+}
+
+void PwMView::delCatButton_slot()
+{
+ if (doc->isDeepLocked())
+ return;
+ if (numCategories() <= 1) {
+ mainClass->showStatMsg(i18n("Can't remove the last category."));
+ return;
+ }
+ if (KMessageBox::questionYesNo(this,
+ i18n("Do you really want to "
+ "delete the selected "
+ "category? All password-"
+ "entries will be lost in "
+ "this category!"),
+ i18n("Delete category?"))
+ == KMessageBox::No) {
+ return;
+ }
+ document()->delCategory(getCurrentCategory());
+}
+
+void PwMView::copyPwToClip()
+{
+ if (doc->isDeepLocked())
+ return;
+ unsigned int curIndex = 0;
+ if (!getCurEntryIndex(&curIndex))
+ return;
+ PwMDataItem d;
+ document()->getDataChangedLock();
+ document()->getEntry(getCurrentCategory(), curIndex, &d, true);
+ document()->putDataChangedLock();
+ PwM::copyToClipboard(d.pw.c_str());
+}
+
+void PwMView::copyNameToClip()
+{
+ if (doc->isDeepLocked())
+ return;
+ unsigned int curIndex = 0;
+ if (!getCurEntryIndex(&curIndex))
+ return;
+ PwMDataItem d;
+ document()->getEntry(getCurrentCategory(), curIndex, &d);
+ PwM::copyToClipboard(d.name.c_str());
+}
+
+void PwMView::copyDescToClip()
+{
+ if (doc->isDeepLocked())
+ return;
+ unsigned int curIndex = 0;
+ if (!getCurEntryIndex(&curIndex))
+ return;
+ PwMDataItem d;
+ document()->getEntry(getCurrentCategory(), curIndex, &d);
+ PwM::copyToClipboard(d.desc.c_str());
+}
+
+void PwMView::copyUrlToClip()
+{
+ if (doc->isDeepLocked())
+ return;
+ unsigned int curIndex = 0;
+ if (!getCurEntryIndex(&curIndex))
+ return;
+ PwMDataItem d;
+ document()->getEntry(getCurrentCategory(), curIndex, &d);
+ PwM::copyToClipboard(d.url.c_str());
+}
+
+void PwMView::copyLauncherToClip()
+{
+ if (doc->isDeepLocked())
+ return;
+ unsigned int curIndex = 0;
+ if (!getCurEntryIndex(&curIndex))
+ return;
+ PwMDataItem d;
+ document()->getEntry(getCurrentCategory(), curIndex, &d);
+ PwM::copyToClipboard(d.launcher.c_str());
+}
+
+void PwMView::copyCommentToClip()
+{
+ if (doc->isDeepLocked())
+ return;
+ unsigned int curIndex = 0;
+ if (!getCurEntryIndex(&curIndex))
+ return;
+ PwMDataItem d;
+ document()->getEntry(getCurrentCategory(), curIndex, &d);
+ PwM::copyToClipboard(d.comment.c_str());
+}
+
+#ifndef PWM_EMBEDDED
+#include "pwmview.moc"
+#endif