• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeutils API Reference
  • KDE Home
  • Contact Us
 

kwallet

  • sources
  • kde-4.14
  • kdeutils
  • kwalletmanager
  • src
  • manager
kwalleteditor.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003-2005 George Staikos <staikos@kde.org>
3  Copyright (C) 2005 Isaac Clerencia <isaac@warp.es>
4 
5  This program is free software; you can redistribute it and/or
6  modify it under the terms of the GNU General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; see the file COPYING. If not, write to
17  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  Boston, MA 02110-1301, USA.
19 */
20 
21 #include "kwalleteditor.h"
22 #include "kbetterthankdialogbase.h"
23 #include "kwmapeditor.h"
24 #include "allyourbase.h"
25 
26 #include <stdlib.h>
27 #include <QDomElement>
28 #include <QDomNode>
29 #include <QDomDocument>
30 #include <QXmlStreamWriter>
31 #include <kaction.h>
32 #include <kdebug.h>
33 #include <kdialog.h>
34 #include <kfiledialog.h>
35 #include <kinputdialog.h>
36 #include <kio/netaccess.h>
37 #include <kactioncollection.h>
38 #include <klocale.h>
39 #include <kcodecs.h>
40 #include <kmessagebox.h>
41 #include <kmenu.h>
42 #include <ksqueezedtextlabel.h>
43 #include <kstandarddirs.h>
44 #include <kstandardaction.h>
45 
46 #include <ktemporaryfile.h>
47 #include <kxmlguifactory.h>
48 #include <QCheckBox>
49 #include <QClipboard>
50 #include <QPushButton>
51 #include <QTimer>
52 #include <QSet>
53 #include <QTextStream>
54 #include <QList>
55 #include <QVBoxLayout>
56 #include <QStack>
57 #include <QToolButton>
58 
59 #include <assert.h>
60 #include <ktoolbar.h>
61 #include <kicon.h>
62 #include <KAction>
63 #include <KTreeWidgetSearchLine>
64 
65 QAction *KWalletEditor::_newFolderAction =0;
66 QAction *KWalletEditor::_deleteFolderAction =0;
67 QAction *KWalletEditor::_exportAction =0;
68 QAction *KWalletEditor::_saveAsAction =0;
69 QAction *KWalletEditor::_mergeAction =0;
70 QAction *KWalletEditor::_importAction =0;
71 KAction *KWalletEditor::_newEntryAction =0;
72 KAction *KWalletEditor::_renameEntryAction =0;
73 KAction *KWalletEditor::_deleteEntryAction =0;
74 KAction *KWalletEditor::_copyPassAction =0;
75 QAction *KWalletEditor::_alwaysShowContentsAction =0;
76 QAction *KWalletEditor::_alwaysHideContentsAction =0;
77 
78 RegisterCreateActionsMethod KWalletEditor::_registerCreateActionMethod(&KWalletEditor::createActions);
79 
80 
81 KWalletEditor::KWalletEditor(QWidget* parent, const char *name)
82 : QWidget(parent), _displayedItem(0), _actionCollection(0), _alwaysShowContents(false) {
83  setupUi( this );
84  setObjectName( QLatin1String( name ) );
85  _newWallet = false;
86  _splitter->setStretchFactor(0, 1);
87  _splitter->setStretchFactor(1, 2);
88  _contextMenu = new KMenu(this);
89 
90  _undoChanges->setIcon(KIcon( QLatin1String( "edit-undo" )));
91  _saveChanges->setIcon(KIcon( QLatin1String( "document-save" )));
92 
93  QVBoxLayout *box = new QVBoxLayout(_entryListFrame);
94  box->setMargin(0);
95  _entryList = new KWalletEntryList(_entryListFrame, "Wallet Entry List");
96  _entryList->setContextMenuPolicy(Qt::CustomContextMenu);
97  _searchLine = new KTreeWidgetSearchLine(_entryListFrame, _entryList);
98  _searchLine->setClickMessage(i18n("Search"));
99  connect(_searchLine, SIGNAL(textChanged(QString)), this, SLOT(onSearchTextChanged(QString)));
100  box->addWidget(_searchLine);
101  box->addWidget(_entryList);
102 
103  _entryStack->setEnabled(true);
104 
105  box = new QVBoxLayout(_entryStack->widget(2));
106  box->setMargin(0);
107  _mapEditorShowHide = new QCheckBox(i18n("&Show values"), _entryStack->widget(2));
108  connect(_mapEditorShowHide, SIGNAL(toggled(bool)), this, SLOT(showHideMapEditorValue(bool)));
109  _mapEditor = new KWMapEditor(_currentMap, _entryStack->widget(2));
110  box->addWidget(_mapEditorShowHide);
111  box->addWidget(_mapEditor);
112 
113  // load splitter size
114  KConfigGroup cg(KGlobal::config(), "WalletEditor");
115  QList<int> splitterSize = cg.readEntry("SplitterSize", QList<int>());
116  if (splitterSize.size() != 2) {
117  splitterSize.clear();
118  splitterSize.append(_splitter->width()/2);
119  splitterSize.append(_splitter->width()/2);
120  }
121  _splitter->setSizes(splitterSize);
122  _alwaysShowContents = cg.readEntry("AlwaysShowContents", false);
123 
124  _searchLine->setFocus();
125 
126  connect(_entryList, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
127  this, SLOT(entrySelectionChanged(QTreeWidgetItem*)));
128  connect(_entryList,
129  SIGNAL(customContextMenuRequested(QPoint)),
130  this,
131  SLOT(listContextMenuRequested(QPoint)));
132  connect(_entryList,
133  SIGNAL(itemChanged(QTreeWidgetItem*,int)),
134  this,
135  SLOT(listItemChanged(QTreeWidgetItem*,int)));
136 
137  connect(_passwordValue, SIGNAL(textChanged()),
138  this, SLOT(entryEditted()));
139  connect(_mapEditor, SIGNAL(dirty()),
140  this, SLOT(entryEditted()));
141 
142  connect(_undoChanges, SIGNAL(clicked()),
143  this, SLOT(restoreEntry()));
144  connect(_saveChanges, SIGNAL(clicked()),
145  this, SLOT(saveEntry()));
146 
147  connect(_showContents, SIGNAL(clicked()),
148  this, SLOT(showPasswordContents()));
149  connect(_hideContents, SIGNAL(clicked()),
150  this, SLOT(hidePasswordContents()));
151 
152 // createActions();
153  // TODO: remove kwalleteditor.rc file
154 }
155 
156 KWalletEditor::~KWalletEditor() {
157  emit enableFolderActions(false);
158  emit enableWalletActions(false);
159  emit enableContextFolderActions(false);
160  // save splitter size
161  KConfigGroup cg(KGlobal::config(), "WalletEditor");
162  cg.writeEntry("SplitterSize", _splitter->sizes());
163  cg.writeEntry("AlwaysShowContents", _alwaysShowContents);
164  cg.sync();
165 
166  delete _w;
167  _w = 0L;
168  if (_nonLocal) {
169  KWallet::Wallet::closeWallet(_walletName, true);
170  }
171  delete _contextMenu;
172  _contextMenu = NULL;
173 }
174 
175 void KWalletEditor::setWallet(KWallet::Wallet* wallet, bool isPath)
176 {
177  Q_ASSERT(wallet != 0);
178  _walletName = wallet->walletName();
179  _nonLocal = isPath;
180 
181  _w = wallet;
182  _entryList->setWallet(_w);
183  connect(_w, SIGNAL(walletOpened(bool)), this, SLOT(walletOpened(bool)));
184  connect(_w, SIGNAL(walletClosed()), this, SLOT(walletClosed()));
185  connect(_w, SIGNAL(folderUpdated(QString)), this, SLOT(updateEntries(QString)));
186  connect(_w, SIGNAL(folderListUpdated()), this, SLOT(updateFolderList()));
187  updateFolderList();
188 
189  emit enableFolderActions(true);
190  emit enableWalletActions(true);
191  emit enableContextFolderActions(true);
192 
193  _mapEditorShowHide->setChecked(false);
194  showHideMapEditorValue(false);
195 
196  setFocus();
197  _searchLine->setFocus();
198 }
199 
200 KActionCollection* KWalletEditor::actionCollection()
201 {
202  if (_actionCollection == 0) {
203  _actionCollection = new KActionCollection(this);
204  }
205  return _actionCollection;
206 }
207 
208 void KWalletEditor::createActions(KActionCollection* actionCollection) {
209  _newFolderAction = actionCollection->addAction( QLatin1String( "create_folder" ));
210  _newFolderAction->setText( i18n("&New Folder...") );
211  _newFolderAction->setIcon( KIcon( QLatin1String( "folder-new" )) );
212 
213  _deleteFolderAction = actionCollection->addAction( QLatin1String( "delete_folder" ) );
214  _deleteFolderAction->setText( i18n("&Delete Folder") );
215 
216  _mergeAction = actionCollection->addAction( QLatin1String( "wallet_merge" ));
217  _mergeAction->setText( i18n("&Import Wallet...") );
218 
219  _importAction= actionCollection->addAction( QLatin1String( "wallet_import" ) );
220  _importAction->setText( i18n("&Import XML...") );
221 
222  _exportAction = actionCollection->addAction( QLatin1String( "wallet_export" ) );
223  _exportAction->setText( i18n("&Export as XML...") );
224 
225  _saveAsAction = KStandardAction::saveAs(0, 0, actionCollection);
226 
227  _copyPassAction = actionCollection->addAction( QLatin1String( "copy_action" ) );
228  _copyPassAction->setText( i18n("&Copy") );
229  _copyPassAction->setShortcut( Qt::Key_C + Qt::CTRL );
230  _copyPassAction->setEnabled(false);
231 
232  _newEntryAction = actionCollection->addAction( QLatin1String( "new_entry" ) );
233  _newEntryAction->setText( i18n( "&New..." ) );
234  _newEntryAction->setShortcut( Qt::Key_Insert );
235  _newEntryAction->setEnabled(false);
236 
237  _renameEntryAction = actionCollection->addAction( QLatin1String( "rename_entry" ) );
238  _renameEntryAction->setText( i18n( "&Rename" ) );
239  _renameEntryAction->setShortcut( Qt::Key_F2 );
240  _renameEntryAction->setEnabled(false);
241 
242  _deleteEntryAction = actionCollection->addAction( QLatin1String( "delete_entry" ) );
243  _deleteEntryAction->setText( i18n( "&Delete" ) );
244  _deleteEntryAction->setShortcut( Qt::Key_Delete );
245  _deleteEntryAction->setEnabled(false);
246 
247  _alwaysShowContentsAction = actionCollection->addAction( QLatin1String( "always_show_contents" ));
248  _alwaysShowContentsAction->setText( i18n("Always show contents") );
249  _alwaysShowContentsAction->setCheckable(true);
250 
251  _alwaysHideContentsAction = actionCollection->addAction( QLatin1String( "always_hide_contents") );
252  _alwaysHideContentsAction->setText( i18n("Always hide contents") );
253  _alwaysHideContentsAction->setCheckable(true);
254 }
255 
256 void KWalletEditor::connectActions()
257 {
258  connect(_newFolderAction, SIGNAL(triggered(bool)), SLOT(createFolder()));
259  connect(this, SIGNAL(enableFolderActions(bool)), _newFolderAction, SLOT(setEnabled(bool)));
260 
261  connect(_deleteFolderAction, SIGNAL(triggered(bool)), SLOT(deleteFolder()));
262  connect(this, SIGNAL(enableContextFolderActions(bool)), _deleteFolderAction, SLOT(setEnabled(bool)));
263  connect(this, SIGNAL(enableFolderActions(bool)), _deleteFolderAction, SLOT(setEnabled(bool)));
264 
265  connect(_mergeAction, SIGNAL(triggered(bool)), SLOT(importWallet()));
266  connect(this, SIGNAL(enableWalletActions(bool)), _mergeAction, SLOT(setEnabled(bool)));
267 
268  connect(_importAction, SIGNAL(triggered(bool)), SLOT(importXML()));
269  connect(this, SIGNAL(enableWalletActions(bool)), _importAction, SLOT(setEnabled(bool)));
270 
271  connect(_exportAction, SIGNAL(triggered(bool)), SLOT(exportXML()));
272  connect(this, SIGNAL(enableWalletActions(bool)), _exportAction, SLOT(setEnabled(bool)));
273 
274  connect(_saveAsAction, SIGNAL(triggered(bool)), SLOT(saveAs()));
275  connect(this, SIGNAL(enableWalletActions(bool)), _saveAsAction, SLOT(setEnabled(bool)));
276 
277  connect(_newEntryAction, SIGNAL(triggered(bool)), SLOT(newEntry()));
278 
279  connect(_renameEntryAction, SIGNAL(triggered(bool)), SLOT(renameEntry()));
280 
281  connect(_deleteEntryAction, SIGNAL(triggered(bool)), SLOT(deleteEntry()));
282 
283  connect(_copyPassAction, SIGNAL(triggered(bool)), SLOT(copyPassword()));
284  connect(this, SIGNAL(enableWalletActions(bool)), _copyPassAction, SLOT(setEnabled(bool)));
285 
286  _showContents->addAction(_alwaysShowContentsAction);
287  _alwaysShowContentsAction->setChecked(_alwaysShowContents);
288  connect(_alwaysShowContentsAction, SIGNAL(triggered(bool)), SLOT(onAlwaysShowContents(bool)));
289 
290  _hideContents->addAction(_alwaysHideContentsAction);
291  _alwaysHideContentsAction->setChecked(!_alwaysShowContents);
292  connect(_alwaysHideContentsAction, SIGNAL(triggered(bool)), SLOT(onAlwaysHideContents(bool)));
293 }
294 
295 void KWalletEditor::disconnectActions()
296 {
297  disconnect(_newFolderAction, SIGNAL(triggered(bool)), this, SLOT(createFolder()));
298  disconnect(this, SIGNAL(enableFolderActions(bool)), _newFolderAction, SLOT(setEnabled(bool)));
299 
300  disconnect(_deleteFolderAction, SIGNAL(triggered(bool)), this, SLOT(deleteFolder()));
301  disconnect(this, SIGNAL(enableContextFolderActions(bool)), _deleteFolderAction, SLOT(setEnabled(bool)));
302  disconnect(this, SIGNAL(enableFolderActions(bool)), _deleteFolderAction, SLOT(setEnabled(bool)));
303 
304  disconnect(_mergeAction, SIGNAL(triggered(bool)), this, SLOT(importWallet()));
305  disconnect(this, SIGNAL(enableWalletActions(bool)), _mergeAction, SLOT(setEnabled(bool)));
306 
307  disconnect(_importAction, SIGNAL(triggered(bool)), this, SLOT(importXML()));
308  disconnect(this, SIGNAL(enableWalletActions(bool)), _importAction, SLOT(setEnabled(bool)));
309 
310  disconnect(_exportAction, SIGNAL(triggered(bool)), this, SLOT(exportXML()));
311  disconnect(this, SIGNAL(enableWalletActions(bool)), _exportAction, SLOT(setEnabled(bool)));
312 
313  disconnect(_saveAsAction, SIGNAL(triggered(bool)), this, SLOT(saveAs()));
314  disconnect(this, SIGNAL(enableWalletActions(bool)), _saveAsAction, SLOT(setEnabled(bool)));
315 
316  disconnect(_newEntryAction, SIGNAL(triggered(bool)), this, SLOT(newEntry()));
317 
318  disconnect(_renameEntryAction, SIGNAL(triggered(bool)), this, SLOT(renameEntry()));
319 
320  disconnect(_deleteEntryAction, SIGNAL(triggered(bool)), this, SLOT(deleteEntry()));
321 
322  disconnect(_copyPassAction, SIGNAL(triggered(bool)), this, SLOT(copyPassword()));
323  disconnect(this, SIGNAL(enableWalletActions(bool)), _copyPassAction, SLOT(setEnabled(bool)));
324 
325  disconnect(_alwaysShowContentsAction, SIGNAL(triggered(bool)), this, SLOT(onAlwaysShowContents(bool)));
326  disconnect(_alwaysHideContentsAction, SIGNAL(triggered(bool)), this, SLOT(onAlwaysHideContents(bool)));
327 }
328 
329 void KWalletEditor::walletClosed() {
330  _w = 0L;
331  setEnabled(false);
332  emit enableWalletActions(false);
333  emit enableFolderActions(false);
334 }
335 
336 
337 void KWalletEditor::updateFolderList(bool checkEntries) {
338  const QStringList fl = _w->folderList();
339  QStack<QTreeWidgetItem*> trash;
340 
341  for (int i = 0; i < _entryList->topLevelItemCount(); ++i) {
342  KWalletFolderItem *fi = dynamic_cast<KWalletFolderItem *>(_entryList->topLevelItem(i));
343  if (!fi) {
344  continue;
345  }
346  if (!fl.contains(fi->name())) {
347  trash.push(fi);
348  }
349  }
350 
351  qDeleteAll(trash);
352  trash.clear();
353 
354  for (QStringList::const_iterator i = fl.begin(); i != fl.end(); ++i) {
355  if (_entryList->existsFolder(*i)) {
356  if (checkEntries) {
357  updateEntries(*i);
358  }
359  continue;
360  }
361 
362  _w->setFolder(*i);
363  const QStringList entries = _w->entryList();
364  KWalletFolderItem *item = new KWalletFolderItem(_w,_entryList, *i, entries.count());
365 
366  KWalletContainerItem *pi = new KWalletContainerItem(item, i18n("Passwords"),KWallet::Wallet::Password);
367  KWalletContainerItem *mi = new KWalletContainerItem(item, i18n("Maps"),KWallet::Wallet::Map);
368  KWalletContainerItem *bi = new KWalletContainerItem(item, i18n("Binary Data"),KWallet::Wallet::Stream);
369  KWalletContainerItem *ui = new KWalletContainerItem(item, i18n("Unknown"),KWallet::Wallet::Unknown);
370 
371  for (QStringList::const_iterator j = entries.begin(); j != entries.end(); ++j) {
372  switch (_w->entryType(*j)) {
373  case KWallet::Wallet::Password:
374  new KWalletEntryItem(_w, pi, *j);
375  break;
376  case KWallet::Wallet::Stream:
377  new KWalletEntryItem(_w, bi, *j);
378  break;
379  case KWallet::Wallet::Map:
380  new KWalletEntryItem(_w, mi, *j);
381  break;
382  case KWallet::Wallet::Unknown:
383  default:
384  new QTreeWidgetItem(ui, QStringList() << *j);
385  break;
386  }
387  }
388  _entryList->setEnabled(true);
389  }
390 
391  //check if the current folder has been removed
392  if (!fl.contains(_currentFolder)) {
393  _currentFolder.clear();
394  _entryTitle->clear();
395  _iconTitle->clear();
396  }
397 }
398 
399 void KWalletEditor::deleteFolder() {
400  if (_w) {
401  QTreeWidgetItem *i = _entryList->currentItem();
402  if (i) {
403  KWalletFolderItem *fi = dynamic_cast<KWalletFolderItem *>(i);
404  if (!fi) {
405  return;
406  }
407 
408  int rc = KMessageBox::warningContinueCancel(this, i18n("Are you sure you wish to delete the folder '%1' from the wallet?", fi->name()),QString(),KStandardGuiItem::del());
409  if (rc == KMessageBox::Continue) {
410  bool rc = _w->removeFolder(fi->name());
411  if (!rc) {
412  KMessageBox::sorry(this, i18n("Error deleting folder."));
413  return;
414  }
415  _currentFolder.clear();
416  _entryTitle->clear();
417  _iconTitle->clear();
418  updateFolderList();
419  }
420  }
421  }
422 }
423 
424 
425 void KWalletEditor::createFolder() {
426  if (_w) {
427  QString n;
428  bool ok;
429 
430  do {
431  n = KInputDialog::getText(i18n("New Folder"),
432  i18n("Please choose a name for the new folder:"),
433  QString(),
434  &ok,
435  this);
436 
437  if (!ok) {
438  return;
439  }
440 
441  if (_entryList->existsFolder(n)) {
442  int rc = KMessageBox::questionYesNo(this, i18n("Sorry, that folder name is in use. Try again?"), QString(), KGuiItem(i18n("Try Again")), KGuiItem(i18n("Do Not Try")));
443  if (rc == KMessageBox::Yes) {
444  continue;
445  }
446  n.clear();
447  }
448  break;
449  } while (true);
450 
451  _w->createFolder(n);
452  updateFolderList();
453  }
454 }
455 
456 void KWalletEditor::saveEntry() {
457  int rc = 1;
458  QTreeWidgetItem *item = _displayedItem; // _entryList->currentItem();
459  _saveChanges->setEnabled(false);
460  _undoChanges->setEnabled(false);
461 
462  if (item && _w && item->parent()) {
463  KWalletContainerItem *ci = dynamic_cast<KWalletContainerItem*>(item->parent());
464  if (ci) {
465  if (ci->entryType() == KWallet::Wallet::Password) {
466  rc = _w->writePassword(item->text(0), _passwordValue->toPlainText());
467  } else if (ci->entryType() == KWallet::Wallet::Map) {
468  _mapEditor->saveMap();
469  rc = _w->writeMap(item->text(0), _currentMap);
470  } else {
471  return;
472  }
473 
474  if (rc == 0) {
475  return;
476  }
477  }
478  }
479 
480  KMessageBox::sorry(this, i18n("Error saving entry. Error code: %1", rc));
481 }
482 
483 
484 void KWalletEditor::restoreEntry() {
485  entrySelectionChanged(_entryList->currentItem());
486 }
487 
488 
489 void KWalletEditor::entryEditted() {
490  _saveChanges->setEnabled(true);
491  _undoChanges->setEnabled(true);
492 }
493 
494 
495 void KWalletEditor::entrySelectionChanged(QTreeWidgetItem *item) {
496  // do not forget to save changes
497  if ( _saveChanges->isEnabled() && _displayedItem && (_displayedItem != item) ){
498  if ( KMessageBox::Yes == KMessageBox::questionYesNo(this,
499  i18n("The contents of the current item has changed.\nDo you want to save changes?"))) {
500  saveEntry();
501  } else {
502  _saveChanges->setEnabled(false);
503  _undoChanges->setEnabled(false);
504  }
505  }
506  KWalletContainerItem *ci = 0L;
507  KWalletFolderItem *fi = 0L;
508 
509  // clear the context menu
510  _contextMenu->clear();
511  _contextMenu->setEnabled(true);
512  // disable the entry actions (reenable them on adding)
513  _newEntryAction->setEnabled(false);
514  _renameEntryAction->setEnabled(false);
515  _deleteEntryAction->setEnabled(false);
516 
517  if (item)
518  {
519  // set the context menu's title
520  _contextMenu->addTitle(_contextMenu->fontMetrics().elidedText(
521  item->text(0), Qt::ElideMiddle, 200 ) );
522 
523  // TODO rtti
524  switch (item->type()) {
525  case KWalletEntryItemClass:
526  ci = dynamic_cast<KWalletContainerItem*>(item->parent());
527  if (!ci) {
528  return;
529  }
530  fi = dynamic_cast<KWalletFolderItem*>(ci->parent());
531  if (!fi) {
532  return;
533  }
534  _w->setFolder(fi->name());
535  _deleteFolderAction->setEnabled(false);
536 
537  // add standard menu items
538  _contextMenu->addAction( _newEntryAction );
539  _contextMenu->addAction( _renameEntryAction );
540  _contextMenu->addAction( _deleteEntryAction );
541  _newEntryAction->setEnabled(true);
542  _renameEntryAction->setEnabled(true);
543  _deleteEntryAction->setEnabled(true);
544 
545  if (ci->entryType() == KWallet::Wallet::Password) {
546  QString pass;
547  if (_w->readPassword(item->text(0), pass) == 0) {
548  _entryStack->setCurrentIndex(4);
549  _entryName->setText(i18n("Password: %1",
550  item->text(0)));
551  _passwordValue->setText(pass);
552  _saveChanges->setEnabled(false);
553  _undoChanges->setEnabled(false);
554  }
555  // add a context-menu action for copying passwords
556  _contextMenu->addSeparator();
557  _contextMenu->addAction( _copyPassAction );
558  if(_alwaysShowContents) {
559  QTimer::singleShot(0, this, SLOT(showPasswordContents()));
560  }
561  } else if (ci->entryType() == KWallet::Wallet::Map) {
562  _entryStack->setCurrentIndex(2);
563  if (_w->readMap(item->text(0), _currentMap) == 0) {
564  _mapEditor->reload();
565  _entryName->setText(i18n("Name-Value Map: %1", item->text(0)));
566  _saveChanges->setEnabled(false);
567  _undoChanges->setEnabled(false);
568  showHideMapEditorValue(_mapEditorShowHide->isChecked());
569  }
570  } else if (ci->entryType() == KWallet::Wallet::Stream) {
571  _entryStack->setCurrentIndex(3);
572  QByteArray ba;
573  if (_w->readEntry(item->text(0), ba) == 0) {
574  _entryName->setText(i18n("Binary Data: %1",
575  item->text(0)));
576  _saveChanges->setEnabled(false);
577  _undoChanges->setEnabled(false);
578  }
579  }
580  break;
581 
582  case KWalletContainerItemClass:
583  ci = dynamic_cast<KWalletContainerItem*>(item);
584  if (!ci) {
585  return;
586  }
587  if (ci->entryType() == KWallet::Wallet::Unknown) {
588  // disable context menu on unknown items
589  _contextMenu->setEnabled(false);
590  } else {
591  // add the context menu action
592  _contextMenu->addAction( _newEntryAction );
593  _newEntryAction->setEnabled(true);
594  }
595 
596  fi = dynamic_cast<KWalletFolderItem*>(item->parent());
597  if (!fi) {
598  return;
599  }
600  _w->setFolder(fi->name());
601  _deleteFolderAction->setEnabled(false);
602  _entryName->clear();
603  _entryStack->setCurrentIndex(0);
604  break;
605 
606  case KWalletFolderItemClass:
607  // add the context menu actions
608  _contextMenu->addAction( _newFolderAction );
609  _contextMenu->addAction( _deleteFolderAction );
610 
611  fi = dynamic_cast<KWalletFolderItem*>(item);
612  if (!fi) {
613  return;
614  }
615  _w->setFolder(fi->name());
616  _deleteFolderAction->setEnabled(true);
617  _entryName->clear();
618  _entryStack->setCurrentIndex(0);
619  break;
620 
621  default:
622  // all items but Unknown entries return have their
623  // rtti set. Unknown items can only be deleted.
624  _contextMenu->addAction( _deleteEntryAction );
625  _deleteEntryAction->setEnabled(true);
626  break;
627  }
628  } else {
629  // no item selected. add the "new folder" action to the context menu
630  _contextMenu->addAction( _newFolderAction );
631  }
632 
633  if (fi) {
634  _currentFolder = fi->name();
635  _entryTitle->setText(QString::fromLatin1("<font size=\"+1\">%1</font>").arg(fi->text(0)));
636  _iconTitle->setPixmap(fi->getFolderIcon(KIconLoader::Toolbar));
637  }
638 
639  _displayedItem = item;
640 }
641 
642 void KWalletEditor::updateEntries(const QString& folder) {
643  QStack<QTreeWidgetItem*> trash;
644 
645  _w->setFolder(folder);
646  const QStringList entries = _w->entryList();
647 
648  KWalletFolderItem *fi = _entryList->getFolder(folder);
649 
650  if (!fi) {
651  return;
652  }
653 
654  KWalletContainerItem *pi = fi->getContainer(KWallet::Wallet::Password);
655  KWalletContainerItem *mi = fi->getContainer(KWallet::Wallet::Map);
656  KWalletContainerItem *bi = fi->getContainer(KWallet::Wallet::Stream);
657  KWalletContainerItem *ui = fi->getContainer(KWallet::Wallet::Unknown);
658 
659  // Remove deleted entries
660  for (int i = 0; i < pi->childCount(); ++i) {
661  QTreeWidgetItem *twi = pi->child(i);
662  if (!entries.contains(twi->text(0))) {
663  if (twi == _entryList->currentItem()) {
664  entrySelectionChanged(0L);
665  }
666  trash.push(twi);
667  }
668  }
669 
670  for (int i = 0; i < mi->childCount(); ++i) {
671  QTreeWidgetItem *twi = mi->child(i);
672  if (!entries.contains(twi->text(0))) {
673  if (twi == _entryList->currentItem()) {
674  entrySelectionChanged(0L);
675  }
676  trash.push(twi);
677  }
678  }
679 
680  for (int i = 0; i < bi->childCount(); ++i) {
681  QTreeWidgetItem *twi = bi->child(i);
682  if (!entries.contains(twi->text(0))) {
683  if (twi == _entryList->currentItem()) {
684  entrySelectionChanged(0L);
685  }
686  trash.push(twi);
687  }
688  }
689 
690  for (int i = 0; i < ui->childCount(); ++i) {
691  QTreeWidgetItem *twi = ui->child(i);
692  if (!entries.contains(twi->text(0))) {
693  if (twi == _entryList->currentItem()) {
694  entrySelectionChanged(0L);
695  }
696  trash.push(twi);
697  }
698  }
699 
700  qDeleteAll(trash);
701  trash.clear();
702 
703  // Add new entries
704  for (QStringList::const_iterator i = entries.begin(); i != entries.end(); ++i) {
705  if (fi->contains(*i)){
706  continue;
707  }
708 
709  switch (_w->entryType(*i)) {
710  case KWallet::Wallet::Password:
711  new KWalletEntryItem(_w, pi, *i);
712  break;
713  case KWallet::Wallet::Stream:
714  new KWalletEntryItem(_w, bi, *i);
715  break;
716  case KWallet::Wallet::Map:
717  new KWalletEntryItem(_w, mi, *i);
718  break;
719  case KWallet::Wallet::Unknown:
720  default:
721  new QTreeWidgetItem(ui, QStringList() << *i);
722  break;
723  }
724  }
725  fi->refresh();
726  if (fi->name() == _currentFolder) {
727  _entryTitle->setText(QString::fromLatin1("<font size=\"+1\">%1</font>").arg(fi->text(0)));
728  }
729  if (!_entryList->currentItem()) {
730  _entryName->clear();
731  _entryStack->setCurrentIndex(0);
732  }
733 }
734 
735 void KWalletEditor::listContextMenuRequested(const QPoint& pos) {
736  if (!_contextMenu->isEnabled()) {
737  return;
738  }
739 
740  _contextMenu->popup(_entryList->mapToGlobal(pos));
741 }
742 
743 
744 void KWalletEditor::copyPassword() {
745  QTreeWidgetItem *item = _entryList->currentItem();
746  if (_w && item) {
747  QString pass;
748  if (_w->readPassword(item->text(0), pass) == 0) {
749  QApplication::clipboard()->setText(pass);
750  }
751  }
752 }
753 
754 
755 void KWalletEditor::newEntry() {
756  QTreeWidgetItem *item = _entryList->currentItem();
757  QString n;
758  bool ok;
759 
760  KWalletFolderItem *fi;
761 
762  //set the folder where we're trying to create the new entry
763  if (_w && item) {
764  QTreeWidgetItem *p = item;
765  if (p->type() == KWalletEntryItemClass) {
766  p = item->parent();
767  }
768  fi = dynamic_cast<KWalletFolderItem *>(p->parent());
769  if (!fi) {
770  return;
771  }
772  _w->setFolder(fi->name());
773  } else {
774  return;
775  }
776 
777  do {
778  n = KInputDialog::getText(i18n("New Entry"),
779  i18n("Please choose a name for the new entry:"),
780  QString(),
781  &ok,
782  this);
783 
784  if (!ok) {
785  return;
786  }
787 
788  // FIXME: prohibits the use of the subheadings
789  if (fi->contains(n)) {
790  int rc = KMessageBox::questionYesNo(this, i18n("Sorry, that entry already exists. Try again?"), QString(), KGuiItem(i18n("Try Again")), KGuiItem(i18n("Do Not Try")));
791  if (rc == KMessageBox::Yes) {
792  continue;
793  }
794  n.clear();
795  }
796  break;
797  } while (true);
798 
799  if (_w && item && !n.isEmpty()) {
800  QTreeWidgetItem *p = item;
801  if (p->type() == KWalletEntryItemClass) {
802  p = item->parent();
803  }
804 
805  KWalletFolderItem *fi = dynamic_cast<KWalletFolderItem *>(p->parent());
806  if (!fi) {
807  KMessageBox::error(this, i18n("An unexpected error occurred trying to add the new entry"));
808  return;
809  }
810  _w->setFolder(fi->name());
811 
812  KWalletEntryItem *ni = new KWalletEntryItem(_w, p, n);
813 
814  KWalletContainerItem *ci = dynamic_cast<KWalletContainerItem*>(p);
815  if (!ci) {
816  KMessageBox::error(this, i18n("An unexpected error occurred trying to add the new entry"));
817  delete ni;
818  return;
819  }
820  if (ci->entryType() == KWallet::Wallet::Password) {
821  _w->writePassword(n, QString());
822  } else if (ci->entryType() == KWallet::Wallet::Map) {
823  _w->writeMap(n, QMap<QString,QString>());
824  } else if (ci->entryType() == KWallet::Wallet::Stream) {
825  _w->writeEntry(n, QByteArray());
826  } else {
827  abort();
828  }
829 
830  _entryList->setCurrentItem(ni);
831  _entryList->scrollToItem(ni);
832 
833  fi->refresh();
834  _entryTitle->setText(QString::fromLatin1("<font size=\"+1\">%1</font>").arg(fi->text(0)));
835  }
836 }
837 
838 
839 void KWalletEditor::renameEntry() {
840  QTreeWidgetItem *item = _entryList->currentItem();
841  if (_w && item) {
842  _entryList->editItem(item, 0);
843  }
844 }
845 
846 
847 // Only supports renaming of KWalletEntryItem derived classes.
848 void KWalletEditor::listItemChanged(QTreeWidgetItem* item, int column) {
849  if (item && column == 0) {
850  KWalletEntryItem *i = dynamic_cast<KWalletEntryItem*>(item);
851  if (!i) {
852  return;
853  }
854 
855  const QString t = item->text(0);
856  if (t == i->name()) {
857  return;
858  }
859  if (!_w || t.isEmpty()) {
860  i->restoreName();
861  return;
862  }
863 
864  if (_w->renameEntry(i->name(), t) == 0) {
865  i->setName(t);
866  KWalletContainerItem *ci = dynamic_cast<KWalletContainerItem*>(item->parent());
867  if (!ci) {
868  KMessageBox::error(this, i18n("An unexpected error occurred trying to rename the entry"));
869  return;
870  }
871  if (ci->entryType() == KWallet::Wallet::Password) {
872  _entryName->setText(i18n("Password: %1", item->text(0)));
873  } else if (ci->entryType() == KWallet::Wallet::Map) {
874  _entryName->setText(i18n("Name-Value Map: %1", item->text(0)));
875  } else if (ci->entryType() == KWallet::Wallet::Stream) {
876  _entryName->setText(i18n("Binary Data: %1", item->text(0)));
877  }
878  } else {
879  i->restoreName();
880  }
881  }
882 }
883 
884 
885 void KWalletEditor::deleteEntry() {
886  QTreeWidgetItem *item = _entryList->currentItem();
887  if (_w && item) {
888  int rc = KMessageBox::warningContinueCancel(this, i18n("Are you sure you wish to delete the item '%1'?", item->text(0)),QString(),KStandardGuiItem::del());
889  if (rc == KMessageBox::Continue) {
890  KWalletFolderItem *fi = dynamic_cast<KWalletFolderItem *>(item->parent()->parent());
891  if (!fi) {
892  KMessageBox::error(this, i18n("An unexpected error occurred trying to delete the entry"));
893  return;
894  }
895  _displayedItem = 0;
896  _w->removeEntry(item->text(0));
897  delete item;
898  entrySelectionChanged(_entryList->currentItem());
899  fi->refresh();
900  _entryTitle->setText(QString::fromLatin1("<font size=\"+1\">%1</font>").arg(fi->text(0)));
901  }
902  }
903 }
904 
905 void KWalletEditor::changePassword()
906 {
907  KWallet::Wallet::changePassword(_walletName, effectiveWinId());
908 }
909 
910 
911 void KWalletEditor::walletOpened(bool success) {
912  if (success) {
913  emit enableFolderActions(true);
914  emit enableContextFolderActions(false);
915  emit enableWalletActions(true);
916  updateFolderList();
917  _entryList->setWallet(_w);
918  } else {
919  if (!_newWallet) {
920  KMessageBox::sorry(this, i18n("Unable to open the requested wallet."));
921  }
922  }
923 }
924 
925 
926 void KWalletEditor::hidePasswordContents() {
927  _entryStack->setCurrentIndex(4);
928 }
929 
930 
931 void KWalletEditor::showPasswordContents() {
932  _entryStack->setCurrentIndex(1);
933 }
934 
935 
936 void KWalletEditor::showHideMapEditorValue(bool show) {
937  if (show) {
938  _mapEditor->showColumn(2);
939  } else {
940  _mapEditor->hideColumn(2);
941  }
942 }
943 
944 
945 enum MergePlan { Prompt = 0, Always = 1, Never = 2, Yes = 3, No = 4 };
946 
947 void KWalletEditor::importWallet() {
948  KUrl url = KFileDialog::getOpenUrl(KUrl(), QLatin1String( "*.kwl" ), this);
949  if (url.isEmpty()) {
950  return;
951  }
952 
953  QString tmpFile;
954  if (!KIO::NetAccess::download(url, tmpFile, this)) {
955  KMessageBox::sorry(this, i18n("Unable to access wallet '<b>%1</b>'.", url.prettyUrl()));
956  return;
957  }
958 
959  KWallet::Wallet *w = KWallet::Wallet::openWallet(tmpFile, winId(), KWallet::Wallet::Path);
960  if (w && w->isOpen()) {
961  MergePlan mp = Prompt;
962  QStringList fl = w->folderList();
963  for (QStringList::ConstIterator f = fl.constBegin(); f != fl.constEnd(); ++f) {
964  if (!w->setFolder(*f)) {
965  continue;
966  }
967 
968  if (!_w->hasFolder(*f)) {
969  _w->createFolder(*f);
970  }
971 
972  _w->setFolder(*f);
973 
974  QMap<QString, QMap<QString, QString> > map;
975  QSet<QString> mergedkeys; // prevents re-merging already merged entries.
976  int rc;
977  rc = w->readMapList(QLatin1String( "*" ), map);
978  if (rc == 0) {
979  QMap<QString, QMap<QString, QString> >::ConstIterator me;
980  for (me = map.constBegin(); me != map.constEnd(); ++me) {
981  bool hasEntry = _w->hasEntry(me.key());
982  if (hasEntry && mp == Prompt) {
983  KBetterThanKDialogBase *bd;
984  bd = new KBetterThanKDialogBase(this);
985  bd->setLabel(i18n("Folder '<b>%1</b>' already contains an entry '<b>%2</b>'. Do you wish to replace it?", Qt::escape(*f), Qt::escape(me.key())));
986  mp = (MergePlan)bd->exec();
987  delete bd;
988  bool ok = false;
989  if (mp == Always || mp == Yes) {
990  ok = true;
991  }
992  if (mp == Yes || mp == No) {
993  // reset mp
994  mp = Prompt;
995  }
996  if (!ok) {
997  continue;
998  }
999  } else if (hasEntry && mp == Never) {
1000  continue;
1001  }
1002  _w->writeMap(me.key(), me.value());
1003  mergedkeys.insert(me.key()); // remember this key has been merged
1004  }
1005  }
1006 
1007  QMap<QString, QString> pwd;
1008  rc = w->readPasswordList(QLatin1String( "*" ), pwd);
1009  if (rc == 0) {
1010  QMap<QString, QString>::ConstIterator pe;
1011  for (pe = pwd.constBegin(); pe != pwd.constEnd(); ++pe) {
1012  bool hasEntry = _w->hasEntry(pe.key());
1013  if (hasEntry && mp == Prompt) {
1014  KBetterThanKDialogBase *bd;
1015  bd = new KBetterThanKDialogBase(this);
1016  bd->setLabel(i18n("Folder '<b>%1</b>' already contains an entry '<b>%2</b>'. Do you wish to replace it?", Qt::escape(*f), Qt::escape(pe.key())));
1017  mp = (MergePlan)bd->exec();
1018  delete bd;
1019  bool ok = false;
1020  if (mp == Always || mp == Yes) {
1021  ok = true;
1022  }
1023  if (mp == Yes || mp == No) {
1024  // reset mp
1025  mp = Prompt;
1026  }
1027  if (!ok) {
1028  continue;
1029  }
1030  } else if (hasEntry && mp == Never) {
1031  continue;
1032  }
1033  _w->writePassword(pe.key(), pe.value());
1034  mergedkeys.insert(pe.key()); // remember this key has been merged
1035  }
1036  }
1037 
1038  QMap<QString, QByteArray> ent;
1039  rc = w->readEntryList(QLatin1String( "*" ), ent);
1040  if (rc == 0) {
1041  QMap<QString, QByteArray>::ConstIterator ee;
1042  for (ee = ent.constBegin(); ee != ent.constEnd(); ++ee) {
1043  // prevent re-merging already merged entries.
1044  if (mergedkeys.contains(ee.key())) {
1045  continue;
1046  }
1047  bool hasEntry = _w->hasEntry(ee.key());
1048  if (hasEntry && mp == Prompt) {
1049  KBetterThanKDialogBase *bd;
1050  bd = new KBetterThanKDialogBase(this);
1051  bd->setLabel(i18n("Folder '<b>%1</b>' already contains an entry '<b>%2</b>'. Do you wish to replace it?", Qt::escape(*f), Qt::escape(ee.key())));
1052  mp = (MergePlan)bd->exec();
1053  delete bd;
1054  bool ok = false;
1055  if (mp == Always || mp == Yes) {
1056  ok = true;
1057  }
1058  if (mp == Yes || mp == No) {
1059  // reset mp
1060  mp = Prompt;
1061  }
1062  if (!ok) {
1063  continue;
1064  }
1065  } else if (hasEntry && mp == Never) {
1066  continue;
1067  }
1068  _w->writeEntry(ee.key(), ee.value());
1069  }
1070  }
1071  }
1072  }
1073 
1074  delete w;
1075 
1076  KIO::NetAccess::removeTempFile(tmpFile);
1077  updateFolderList(true);
1078  restoreEntry();
1079 }
1080 
1081 
1082 void KWalletEditor::importXML() {
1083  KUrl url = KFileDialog::getOpenUrl( KUrl(), QLatin1String( "*.xml" ), this);
1084  if (url.isEmpty()) {
1085  return;
1086  }
1087 
1088  QString tmpFile;
1089  if (!KIO::NetAccess::download(url, tmpFile, this)) {
1090  KMessageBox::sorry(this, i18n("Unable to access XML file '<b>%1</b>'.", url.prettyUrl()));
1091  return;
1092  }
1093 
1094  QFile qf(tmpFile);
1095  if (!qf.open(QIODevice::ReadOnly)) {
1096  KMessageBox::sorry(this, i18n("Error opening XML file '<b>%1</b>' for input.", url.prettyUrl()));
1097  KIO::NetAccess::removeTempFile(tmpFile);
1098  return;
1099  }
1100 
1101  QDomDocument doc(tmpFile);
1102  if (!doc.setContent(&qf)) {
1103  KMessageBox::sorry(this, i18n("Error reading XML file '<b>%1</b>' for input.", url.prettyUrl()));
1104  KIO::NetAccess::removeTempFile(tmpFile);
1105  return;
1106  }
1107 
1108  QDomElement top = doc.documentElement();
1109  if (top.tagName().toLower() != QLatin1String( "wallet" )) {
1110  KMessageBox::sorry(this, i18n("Error: XML file does not contain a wallet."));
1111  KIO::NetAccess::removeTempFile(tmpFile);
1112  return;
1113  }
1114 
1115  QDomNode n = top.firstChild();
1116  MergePlan mp = Prompt;
1117  while (!n.isNull()) {
1118  QDomElement e = n.toElement();
1119  if (e.tagName().toLower() != QLatin1String( "folder" )) {
1120  n = n.nextSibling();
1121  continue;
1122  }
1123 
1124  QString fname = e.attribute(QLatin1String( "name" ));
1125  if (fname.isEmpty()) {
1126  n = n.nextSibling();
1127  continue;
1128  }
1129  if (!_w->hasFolder(fname)) {
1130  _w->createFolder(fname);
1131  }
1132  _w->setFolder(fname);
1133  QDomNode enode = e.firstChild();
1134  while (!enode.isNull()) {
1135  e = enode.toElement();
1136  QString type = e.tagName().toLower();
1137  QString ename = e.attribute(QLatin1String( "name" ));
1138  bool hasEntry = _w->hasEntry(ename);
1139  if (hasEntry && mp == Prompt) {
1140  KBetterThanKDialogBase *bd;
1141  bd = new KBetterThanKDialogBase(this);
1142  bd->setLabel(i18n("Folder '<b>%1</b>' already contains an entry '<b>%2</b>'. Do you wish to replace it?", Qt::escape(fname), Qt::escape(ename)));
1143  mp = (MergePlan)bd->exec();
1144  delete bd;
1145  bool ok = false;
1146  if (mp == Always || mp == Yes) {
1147  ok = true;
1148  }
1149  if (mp == Yes || mp == No) { // reset mp
1150  mp = Prompt;
1151  }
1152  if (!ok) {
1153  enode = enode.nextSibling();
1154  continue;
1155  }
1156  } else if (hasEntry && mp == Never) {
1157  enode = enode.nextSibling();
1158  continue;
1159  }
1160 
1161  if (type == QLatin1String( "password" )) {
1162  _w->writePassword(ename, e.text());
1163  } else if (type == QLatin1String( "stream" )) {
1164  _w->writeEntry(ename, KCodecs::base64Decode(e.text().toLatin1()));
1165  } else if (type == QLatin1String( "map" )) {
1166  QMap<QString,QString> map;
1167  QDomNode mapNode = e.firstChild();
1168  while (!mapNode.isNull()) {
1169  QDomElement mape = mapNode.toElement();
1170  if (mape.tagName().toLower() == QLatin1String( "mapentry" )) {
1171  map[mape.attribute(QLatin1String( "name" ))] = mape.text();
1172  }
1173  mapNode = mapNode.nextSibling();
1174  }
1175  _w->writeMap(ename, map);
1176  }
1177  enode = enode.nextSibling();
1178  }
1179  n = n.nextSibling();
1180  }
1181 
1182  KIO::NetAccess::removeTempFile(tmpFile);
1183  updateFolderList(true);
1184  restoreEntry();
1185 }
1186 
1187 
1188 void KWalletEditor::exportXML() {
1189  KTemporaryFile tf;
1190  tf.open();
1191  QXmlStreamWriter xml(&tf);
1192  xml.setAutoFormatting(true);
1193  xml.writeStartDocument();
1194  const QStringList fl = _w->folderList();
1195 
1196  xml.writeStartElement(QLatin1String( "wallet" ));
1197  xml.writeAttribute(QLatin1String( "name" ), _walletName);
1198  for (QStringList::const_iterator i = fl.constBegin(); i != fl.constEnd(); ++i) {
1199  xml.writeStartElement(QLatin1String( "folder" ));
1200  xml.writeAttribute(QLatin1String( "name" ), *i);
1201  _w->setFolder(*i);
1202  QStringList entries = _w->entryList();
1203  for (QStringList::const_iterator j = entries.constBegin(); j != entries.constEnd(); ++j) {
1204  switch (_w->entryType(*j)) {
1205  case KWallet::Wallet::Password:
1206  {
1207  QString pass;
1208  if (_w->readPassword(*j, pass) == 0) {
1209  xml.writeStartElement(QLatin1String( "password" ));
1210  xml.writeAttribute(QLatin1String( "name" ), *j);
1211  xml.writeCharacters(pass);
1212  xml.writeEndElement();
1213  }
1214  break;
1215  }
1216  case KWallet::Wallet::Stream:
1217  {
1218  QByteArray ba;
1219  if (_w->readEntry(*j, ba) == 0) {
1220  xml.writeStartElement(QLatin1String( "stream" ));
1221  xml.writeAttribute(QLatin1String( "name" ), *j);
1222  xml.writeCharacters(QLatin1String( KCodecs::base64Encode(ba) ));
1223  xml.writeEndElement();
1224  }
1225  break;
1226  }
1227  case KWallet::Wallet::Map:
1228  {
1229  QMap<QString,QString> map;
1230  if (_w->readMap(*j, map) == 0) {
1231  xml.writeStartElement(QLatin1String( "map" ));
1232  xml.writeAttribute(QLatin1String( "name" ), *j);
1233  for (QMap<QString,QString>::ConstIterator k = map.constBegin(); k != map.constEnd(); ++k) {
1234  xml.writeStartElement(QLatin1String( "mapentry" ));
1235  xml.writeAttribute(QLatin1String( "name" ), k.key());
1236  xml.writeCharacters(k.value());
1237  xml.writeEndElement();
1238  }
1239  xml.writeEndElement();
1240  }
1241  break;
1242  }
1243  case KWallet::Wallet::Unknown:
1244  default:
1245  break;
1246  }
1247  }
1248  xml.writeEndElement();
1249  }
1250 
1251  xml.writeEndElement();
1252  xml.writeEndDocument();
1253  tf.flush();
1254 
1255  KUrl url = KFileDialog::getSaveUrl(KUrl(), QLatin1String( "*.xml" ), this);
1256 
1257  if (!url.isEmpty()) {
1258  KIO::NetAccess::dircopy(KUrl::fromPath(tf.fileName()), url, this);
1259  }
1260 }
1261 
1262 
1263 void KWalletEditor::setNewWallet(bool x) {
1264  _newWallet = x;
1265 }
1266 
1267 
1268 void KWalletEditor::saveAs() {
1269  KUrl url = KFileDialog::getSaveUrl(KUrl(), QLatin1String( "*.kwl" ), this);
1270  if (!url.isEmpty()) {
1271  // Sync() kwalletd
1272  if (_nonLocal) {
1273  KIO::NetAccess::dircopy(_walletName, url, this);
1274  } else {
1275  QString path = KGlobal::dirs()->saveLocation("kwallet") + QLatin1Char( '/' ) + _walletName + QLatin1String( ".kwl" );
1276  KIO::NetAccess::dircopy(KUrl::fromPath(path), url, this);
1277  }
1278  }
1279 }
1280 
1281 void KWalletEditor::hideEvent(QHideEvent* )
1282 {
1283  emit enableContextFolderActions(false);
1284  emit enableFolderActions(false);
1285  emit enableWalletActions(false);
1286  disconnectActions();
1287  _saveAsAction->setEnabled(false);
1288 }
1289 
1290 void KWalletEditor::showEvent(QShowEvent* )
1291 {
1292  connectActions();
1293  emit enableContextFolderActions(true);
1294  emit enableFolderActions(true);
1295  emit enableWalletActions(true);
1296 }
1297 
1298 void KWalletEditor::onSearchTextChanged(const QString& text)
1299 {
1300  static bool treeIsExpanded = false;
1301  if (text.isEmpty()) {
1302  if (treeIsExpanded) {
1303  _entryList->setCurrentItem(NULL);
1304  // NOTE: the 300 ms here is a value >200 ms used internally by KTreeWidgetSearchLine
1305  // TODO: replace this timer with a connection to KTreeWidgetSearchLine::searchUpdated signal introduced with KF5
1306  QTimer::singleShot(300, _entryList, SLOT(collapseAll()));
1307  treeIsExpanded = false;
1308  }
1309  } else {
1310  if (!treeIsExpanded) {
1311  _entryList->expandAll();
1312  treeIsExpanded = true;
1313  }
1314  // NOTE: the 300 ms here is a value >200 ms used internally by KTreeWidgetSearchLine
1315  // TODO: replace this timer with a connection to KTreeWidgetSearchLine::searchUpdated signal introduced with KF5
1316  QTimer::singleShot(300, _entryList, SLOT(selectFirstVisible()));
1317  }
1318  // TODO: reduce timer count when KTreeWidgetSearchLine::searchUpdated signal will be there
1319  QTimer::singleShot(300, _entryList, SLOT(refreshItemsCount()));
1320 }
1321 
1322 void KWalletEditor::onAlwaysShowContents(bool checked)
1323 {
1324  _alwaysShowContents = checked;
1325  _alwaysHideContentsAction->setChecked(!_alwaysShowContents);
1326  showPasswordContents();
1327 }
1328 
1329 void KWalletEditor::onAlwaysHideContents(bool checked)
1330 {
1331  _alwaysShowContents = !checked;
1332  _alwaysShowContentsAction->setChecked(_alwaysShowContents);
1333  if (checked) {
1334  hidePasswordContents();
1335  }
1336 }
1337 
1338 #include "kwalleteditor.moc"
1339 
QHideEvent
QWidget::customContextMenuRequested
void customContextMenuRequested(const QPoint &pos)
QAction::setText
void setText(const QString &text)
QList::clear
void clear()
QWidget
QWidget::setupUi
void setupUi(QWidget *widget)
RegisterCreateActionsMethod
This class is intended to avoid coupling between the main window and it's contained widgets that hand...
Definition: registercreateactionmethod.h:40
Never
Definition: kwalleteditor.cpp:945
QXmlStreamWriter
QByteArray
QTreeWidgetItem::child
QTreeWidgetItem * child(int index) const
QDomElement::attribute
QString attribute(const QString &name, const QString &defValue) const
Prompt
Definition: kwalleteditor.cpp:945
QTreeWidget::scrollToItem
void scrollToItem(const QTreeWidgetItem *item, QAbstractItemView::ScrollHint hint)
KWalletEditor::enableContextFolderActions
void enableContextFolderActions(bool enable)
KWalletEditor::KWalletEditor
KWalletEditor(QWidget *parent, const char *name=0)
Definition: kwalleteditor.cpp:81
QAction::setChecked
void setChecked(bool)
KWalletContainerItem
Definition: allyourbase.h:63
KWalletEditor::hideEvent
virtual void hideEvent(QHideEvent *)
Definition: kwalleteditor.cpp:1281
KMenu
QStack::push
void push(const T &t)
kwalleteditor.h
KWalletEntryList::getFolder
KWalletFolderItem * getFolder(const QString &name)
Definition: allyourbase.cpp:600
QMap::constBegin
const_iterator constBegin() const
QAction::setIcon
void setIcon(const QIcon &icon)
QMap< QString, QString >
KBetterThanKDialogBase
Definition: kbetterthankdialogbase.h:27
QStringList::contains
bool contains(const QString &str, Qt::CaseSensitivity cs) const
KWalletEditor::deleteFolder
void deleteFolder()
Definition: kwalleteditor.cpp:399
QWidget::mapToGlobal
QPoint mapToGlobal(const QPoint &pos) const
KWalletFolderItem::getFolderIcon
QPixmap getFolderIcon(KIconLoader::Group group)
Definition: allyourbase.cpp:51
KWalletFolderItem
Definition: allyourbase.h:77
QDialog::exec
int exec()
KWalletEditor::enableFolderActions
void enableFolderActions(bool enable)
KWalletEditor::setWallet
void setWallet(KWallet::Wallet *wallet, bool isPath=false)
Definition: kwalleteditor.cpp:175
KWalletFolderItem::getContainer
KWalletContainerItem * getContainer(KWallet::Wallet::EntryType type)
Definition: allyourbase.cpp:87
KWalletEntryList
Definition: allyourbase.h:100
QPoint
QDomNode
KWalletFolderItemClass
Definition: allyourbase.h:39
KWMapEditor::saveMap
void saveMap()
Definition: kwmapeditor.cpp:199
QSet::insert
const_iterator insert(const T &value)
KWalletEditor::createFolder
void createFolder()
Definition: kwalleteditor.cpp:425
QObject::disconnect
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
QList::const_iterator
QFile
KWalletFolderItem::name
QString name() const
Definition: allyourbase.cpp:123
QList::size
int size() const
KWalletEditor::~KWalletEditor
virtual ~KWalletEditor()
Definition: kwalleteditor.cpp:156
QDomNode::nextSibling
QDomNode nextSibling() const
KWalletEntryItemClass
Definition: allyourbase.h:41
QString::clear
void clear()
QDomNode::toElement
QDomElement toElement() const
KWalletEditor::enableWalletActions
void enableWalletActions(bool enable)
QVector::clear
void clear()
QWidget::setEnabled
void setEnabled(bool)
QBoxLayout::addWidget
void addWidget(QWidget *widget, int stretch, QFlags< Qt::AlignmentFlag > alignment)
QList::count
int count(const T &value) const
QList::append
void append(const T &value)
QDomElement::text
QString text() const
QWidget::x
int x() const
KWalletEntryItem::restoreName
void restoreName()
Definition: allyourbase.cpp:177
QApplication::clipboard
QClipboard * clipboard()
QShowEvent
QWidget::setFocus
void setFocus()
QCheckBox
QObject::setObjectName
void setObjectName(const QString &name)
QString::isEmpty
bool isEmpty() const
QMap::constEnd
const_iterator constEnd() const
Always
Definition: kwalleteditor.cpp:945
KWalletEntryList::setWallet
void setWallet(KWallet::Wallet *w)
Definition: allyourbase.cpp:492
KWMapEditor
Definition: kwmapeditor.h:30
QVBoxLayout
KWalletContainerItemClass
Definition: allyourbase.h:40
QSet
KWalletEditor::showEvent
virtual void showEvent(QShowEvent *)
Definition: kwalleteditor.cpp:1290
QWidget::winId
WId winId() const
QTreeWidget::currentItem
QTreeWidgetItem * currentItem() const
QString
QList
QtConcurrent::map
QFuture< void > map(Sequence &sequence, MapFunction function)
KWalletFolderItem::refresh
void refresh()
Definition: allyourbase.cpp:64
KWalletEntryItem::name
const QString & name() const
Definition: allyourbase.h:50
QLayout::setMargin
void setMargin(int margin)
QStringList
QTableView::showColumn
void showColumn(int column)
QList::end
iterator end()
QString::toLower
QString toLower() const
KWalletEditor::_walletName
QString _walletName
Definition: kwalleteditor.h:101
QLatin1Char
QWidget::setContextMenuPolicy
void setContextMenuPolicy(Qt::ContextMenuPolicy policy)
QDomDocument
KWalletEditor::walletClosed
void walletClosed()
Definition: kwalleteditor.cpp:329
QTreeView::expandAll
void expandAll()
QTreeWidgetItem::parent
QTreeWidgetItem * parent() const
QAction::setCheckable
void setCheckable(bool)
QSet::contains
bool contains(const T &value) const
QDomNode::isNull
bool isNull() const
KWalletEntryItem
Definition: allyourbase.h:45
QTreeWidget::setCurrentItem
void setCurrentItem(QTreeWidgetItem *item)
QMap::key
const Key key(const T &value) const
QAbstractButton::setChecked
void setChecked(bool)
kbetterthankdialogbase.h
KWalletEditor::setNewWallet
void setNewWallet(bool newWallet)
Definition: kwalleteditor.cpp:1263
QDomNode::firstChild
QDomNode firstChild() const
QString::toLatin1
QByteArray toLatin1() const
KWalletContainerItem::entryType
KWallet::Wallet::EntryType entryType()
Definition: allyourbase.cpp:142
QTreeWidgetItem
QLatin1String
KWalletFolderItem::contains
bool contains(const QString &itemKey)
Definition: allyourbase.cpp:100
Qt::escape
QString escape(const QString &plain)
Yes
Definition: kwalleteditor.cpp:945
KBetterThanKDialogBase::setLabel
virtual void setLabel(const QString &label)
Definition: kbetterthankdialogbase.cpp:38
QAction
QList::ConstIterator
typedef ConstIterator
allyourbase.h
KWalletEntryList::existsFolder
bool existsFolder(const QString &name)
Definition: allyourbase.cpp:496
KWalletEntryItem::setName
void setName(const QString &n)
Definition: allyourbase.cpp:171
QString::fromLatin1
QString fromLatin1(const char *str, int size)
MergePlan
MergePlan
Definition: kwalleteditor.cpp:945
QClipboard::setText
void setText(const QString &text, Mode mode)
QTreeWidgetItem::type
int type() const
QDomElement::tagName
QString tagName() const
QTreeWidget::topLevelItem
QTreeWidgetItem * topLevelItem(int index) const
kwmapeditor.h
QList::constEnd
const_iterator constEnd() const
QList::constBegin
const_iterator constBegin() const
QTreeWidget::topLevelItemCount
topLevelItemCount
QWidget::effectiveWinId
WId effectiveWinId() const
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QDomElement
QTreeWidgetItem::childCount
int childCount() const
QTreeWidgetItem::text
QString text(int column) const
QList::begin
iterator begin()
QAction::setEnabled
void setEnabled(bool)
No
Definition: kwalleteditor.cpp:945
QTreeWidget::editItem
void editItem(QTreeWidgetItem *item, int column)
QStack
KWMapEditor::reload
void reload()
Definition: kwmapeditor.cpp:150
QMap::value
const T value(const Key &key) const
QTimer::singleShot
singleShot
QTableView::hideColumn
void hideColumn(int column)
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:42:01 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kwallet

Skip menu "kwallet"
  • Main Page
  • Namespace List
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdeutils API Reference

Skip menu "kdeutils API Reference"
  • ark
  • filelight
  • kcalc
  • kcharselect
  • kdf
  • kfloppy
  • kgpg
  • ktimer
  • kwallet
  • sweeper

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal