diff options
Diffstat (limited to 'kwallet/kwalletmanager.cpp')
-rw-r--r-- | kwallet/kwalletmanager.cpp | 423 |
1 files changed, 423 insertions, 0 deletions
diff --git a/kwallet/kwalletmanager.cpp b/kwallet/kwalletmanager.cpp new file mode 100644 index 0000000..a4fe6cf --- /dev/null +++ b/kwallet/kwalletmanager.cpp @@ -0,0 +1,423 @@ +/* + Copyright (C) 2003,2004 George Staikos <staikos@kde.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + + +#include "kwalletmanager.h" +#include "kwalletpopup.h" +#include "kwalleteditor.h" +#include "allyourbase.h" + +#include <dcopclient.h> +#include <dcopref.h> +#include <kaction.h> +#include <kapplication.h> +#include <kconfig.h> +#include <kdebug.h> +#include <kiconloader.h> +#include <kiconview.h> +#include <kinputdialog.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <kstdaction.h> +#include <ksystemtray.h> +#include <kwallet.h> + +#include <qaccel.h> +#include <qguardedptr.h> +#include <qptrstack.h> +#include <qregexp.h> +#include <qtimer.h> +#include <qtooltip.h> + +KWalletManager::KWalletManager(QWidget *parent, const char *name, WFlags f) +: KMainWindow(parent, name, f), DCOPObject("KWalletManager") { + KGlobal::dirs()->addResourceType("kwallet", "share/apps/kwallet"); + _kwalletdLaunch = false; + QAccel *accel = new QAccel(this, "kwalletmanager"); + + KApplication::dcopClient()->setQtBridgeEnabled(false); + _shuttingDown = false; + KConfig cfg("kwalletrc"); // not sure why this setting isn't in kwalletmanagerrc... + KConfigGroup walletConfigGroup(&cfg, "Wallet"); + _dcopRef = 0L; + if (walletConfigGroup.readBoolEntry("Launch Manager", true)) { + _tray = new KSystemTray(this, "kwalletmanager tray"); + _tray->setPixmap(loadSystemTrayIcon("wallet_closed")); + QToolTip::add(_tray, i18n("KDE Wallet: No wallets open.")); + connect(_tray, SIGNAL(quitSelected()), SLOT(shuttingDown())); + QStringList wl = KWallet::Wallet::walletList(); + bool isOpen = false; + for (QStringList::Iterator it = wl.begin(); it != wl.end(); ++it) { + if (KWallet::Wallet::isOpen(*it)) { + _tray->setPixmap(loadSystemTrayIcon("wallet_open")); + QToolTip::remove(_tray); + QToolTip::add(_tray, i18n("KDE Wallet: A wallet is open.")); + isOpen = true; + break; + } + } + if (!isOpen && kapp->isRestored()) { + delete _tray; + _tray = 0L; + QTimer::singleShot( 0, kapp, SLOT( quit())); + return; + } + } else { + _tray = 0L; + } + + _iconView = new KWalletIconView(this, "kwalletmanager icon view"); + connect(_iconView, SIGNAL(executed(QIconViewItem*)), this, SLOT(openWallet(QIconViewItem*))); + connect(_iconView, SIGNAL(contextMenuRequested(QIconViewItem*, const QPoint&)), this, SLOT(contextMenu(QIconViewItem*, const QPoint&))); + + updateWalletDisplay(); + setCentralWidget(_iconView); + _iconView->setMinimumSize(320, 200); + + _dcopRef = new DCOPRef("kded", "kwalletd"); + _dcopRef->dcopClient()->setNotifications(true); + connect(_dcopRef->dcopClient(), + SIGNAL(applicationRemoved(const QCString&)), + this, + SLOT(possiblyRescan(const QCString&))); + connect(_dcopRef->dcopClient(), + SIGNAL(applicationRegistered(const QCString&)), + this, + SLOT(possiblyRescan(const QCString&))); + + connectDCOPSignal(_dcopRef->app(), _dcopRef->obj(), "allWalletsClosed()", "allWalletsClosed()", false); + connectDCOPSignal(_dcopRef->app(), _dcopRef->obj(), "walletClosed(QString)", "updateWalletDisplay()", false); + connectDCOPSignal(_dcopRef->app(), _dcopRef->obj(), "walletOpened(QString)", "aWalletWasOpened()", false); + connectDCOPSignal(_dcopRef->app(), _dcopRef->obj(), "walletDeleted(QString)", "updateWalletDisplay()", false); + connectDCOPSignal(_dcopRef->app(), _dcopRef->obj(), "walletListDirty()", "updateWalletDisplay()", false); + + // FIXME: slight race - a wallet can open, then we get launched, but the + // wallet closes before we are done opening. We will then stay + // open. Must check that a wallet is still open here. + + new KAction(i18n("&New Wallet..."), "kwalletmanager", 0, this, + SLOT(createWallet()), actionCollection(), + "wallet_create"); + KAction *act = new KAction(i18n("Configure &Wallet..."), "configure", + 0, this, SLOT(setupWallet()), actionCollection(), + "wallet_settings"); + if (_tray) { + act->plug(_tray->contextMenu()); + } + act = new KAction(i18n("Close &All Wallets"), 0, 0, this, + SLOT(closeAllWallets()), actionCollection(), + "close_all_wallets"); + if (_tray) { + act->plug(_tray->contextMenu()); + } + KStdAction::quit(this, SLOT(shuttingDown()), actionCollection()); + KStdAction::keyBindings(guiFactory(), SLOT(configureShortcuts()), +actionCollection()); + + createGUI("kwalletmanager.rc"); + accel->connectItem(accel->insertItem(Key_Return), this, SLOT(openWallet())); + accel->connectItem(accel->insertItem(Key_Delete), this, SLOT(deleteWallet())); + + if (_tray) { + _tray->show(); + } else { + show(); + } + + kapp->setName("kwallet"); // hack to fix docs +} + + +KWalletManager::~KWalletManager() { + _tray = 0L; + delete _dcopRef; + _dcopRef = 0L; +} + + +void KWalletManager::kwalletdLaunch() { + _kwalletdLaunch = true; +} + + +bool KWalletManager::queryClose() { + if (!_shuttingDown && !kapp->sessionSaving()) { + if (!_tray) { + kapp->quit(); + } else { + hide(); + } + return false; + } + return true; +} + + +void KWalletManager::aWalletWasOpened() { + if (_tray) { + _tray->setPixmap(loadSystemTrayIcon("wallet_open")); + QToolTip::remove(_tray); + QToolTip::add(_tray, i18n("KDE Wallet: A wallet is open.")); + } + updateWalletDisplay(); +} + + +void KWalletManager::updateWalletDisplay() { +QStringList wl = KWallet::Wallet::walletList(); +QPtrStack<QIconViewItem> trash; + + for (QIconViewItem *item = _iconView->firstItem(); item; item = item->nextItem()) { + if (!wl.contains(item->text())) { + trash.push(item); + } + } + + trash.setAutoDelete(true); + trash.clear(); + + for (QStringList::Iterator i = wl.begin(); i != wl.end(); ++i) { + if (!_iconView->findItem(*i)) { + // FIXME: if KWallet::Wallet::isOpen(*i) then show + // a different icon! + new KWalletItem(_iconView, *i); + } else { + // FIXME: See if icon needs to be updated + } + } +} + + +void KWalletManager::contextMenu(QIconViewItem *item, const QPoint& pos) { + if (item) { + QGuardedPtr<KWalletPopup> popupMenu = new KWalletPopup(item->text(), this); + connect(popupMenu, SIGNAL(walletOpened(const QString&)), this, SLOT(openWallet(const QString&))); + connect(popupMenu, SIGNAL(walletClosed(const QString&)), this, SLOT(closeWallet(const QString&))); + connect(popupMenu, SIGNAL(walletDeleted(const QString&)), this, SLOT(deleteWallet(const QString&))); + connect(popupMenu, SIGNAL(walletChangePassword(const QString&)), this, SLOT(changeWalletPassword(const QString&))); + connect(popupMenu, SIGNAL(walletCreated()), this, SLOT(createWallet())); + popupMenu->exec(pos); + delete popupMenu; + } +} + + +void KWalletManager::deleteWallet(const QString& walletName) { + int rc = KMessageBox::warningContinueCancel(this, i18n("Are you sure you wish to delete the wallet '%1'?").arg(walletName),"",KStdGuiItem::del()); + if (rc != KMessageBox::Continue) { + return; + } + rc = KWallet::Wallet::deleteWallet(walletName); + if (rc != 0) { + KMessageBox::sorry(this, i18n("Unable to delete the wallet. Error code was %1.").arg(rc)); + } + updateWalletDisplay(); +} + + +void KWalletManager::closeWallet(const QString& walletName) { + int rc = KWallet::Wallet::closeWallet(walletName, false); + if (rc != 0) { + rc = KMessageBox::warningYesNo(this, i18n("Unable to close wallet cleanly. It is probably in use by other applications. Do you wish to force it closed?"), QString::null, i18n("Force Closure"), i18n("Do Not Force")); + if (rc == KMessageBox::Yes) { + rc = KWallet::Wallet::closeWallet(walletName, true); + if (rc != 0) { + KMessageBox::sorry(this, i18n("Unable to force the wallet closed. Error code was %1.").arg(rc)); + } + } + } + + updateWalletDisplay(); +} + + +void KWalletManager::changeWalletPassword(const QString& walletName) { + KWallet::Wallet::changePassword(walletName); +} + + +void KWalletManager::openWalletFile(const QString& path) { + KWalletEditor *we = new KWalletEditor(path, true, this, "Wallet Editor"); + if (we->isOpen()) { + connect(we, SIGNAL(editorClosed(KMainWindow*)), + this, SLOT(editorClosed(KMainWindow*))); + we->show(); + } else { + KMessageBox::sorry(this, i18n("Error opening wallet %1.").arg(path)); + delete we; + } +} + + +void KWalletManager::openWallet() { + QIconViewItem *item = _iconView->currentItem(); + openWallet(item); +} + +void KWalletManager::deleteWallet() { + QIconViewItem *item = _iconView->currentItem(); + if (item) { + deleteWallet(item->text()); + } +} + + +void KWalletManager::openWallet(const QString& walletName) { + openWallet(walletName, false); +} + + +void KWalletManager::openWallet(const QString& walletName, bool newWallet) { + // Don't allow a wallet to open in two windows + for (KMainWindow *w = _windows.first(); w; w = _windows.next()) { + KWalletEditor *e = static_cast<KWalletEditor*>(w); + if (e->isOpen() && e->_walletName == walletName) { + w->raise(); + return; + } + } + + KWalletEditor *we = new KWalletEditor(walletName, false, this, "Wallet Editor"); + we->setNewWallet(newWallet); + if (we->isOpen()) { + connect(we, SIGNAL(editorClosed(KMainWindow*)), + this, SLOT(editorClosed(KMainWindow*))); + we->show(); + _windows.append(we); + } else if (!newWallet) { + KMessageBox::sorry(this, i18n("Error opening wallet %1.").arg(walletName)); + delete we; + } +} + + +void KWalletManager::openWallet(QIconViewItem *item) { + if (item) { + openWallet(item->text()); + } +} + + +void KWalletManager::allWalletsClosed() { + if (_tray) { + _tray->setPixmap(loadSystemTrayIcon("wallet_closed")); + QToolTip::remove(_tray); + QToolTip::add(_tray, i18n("KDE Wallet: No wallets open.")); + } + possiblyQuit(); +} + + +void KWalletManager::possiblyQuit() { + KConfig cfg("kwalletrc"); + cfg.setGroup("Wallet"); + if (_windows.isEmpty() && + !isVisible() && + !cfg.readBoolEntry("Leave Manager Open", false) && + _kwalletdLaunch) { + kapp->quit(); + } +} + + +void KWalletManager::editorClosed(KMainWindow* e) { + _windows.remove(e); +} + + +void KWalletManager::possiblyRescan(const QCString& app) { + if (app == "kded") { + updateWalletDisplay(); + } +} + + +void KWalletManager::createWallet() { + QString n; + bool ok; + // FIXME: support international names + QRegExp regexp("^[A-Za-z0-9]+[A-Za-z0-9_\\s\\-]*$"); + QString txt = i18n("Please choose a name for the new wallet:"); + + if (!KWallet::Wallet::isEnabled()) { + // FIXME: KMessageBox::warningYesNo(this, i1_8n("KWallet is not enabled. Do you want to enable it?"), QString::null, i18n("Enable"), i18n("Keep Disabled")); + return; + } + + do { + n = KInputDialog::getText(i18n("New Wallet"), + txt, + QString::null, + &ok, + this); + + if (!ok) { + return; + } + + if (_iconView->findItem(n)) { + int rc = KMessageBox::questionYesNo(this, i18n("Sorry, that wallet already exists. Try a new name?"), QString::null, i18n("Try New"), i18n("Do Not Try")); + if (rc == KMessageBox::Yes) { + continue; + } + n = QString::null; + } else if (regexp.exactMatch(n)) { + break; + } else { + txt = i18n("Please choose a name that contains only alphanumeric characters:"); + } + } while (true); + + // Small race here - the wallet could be created on us already. + if (!n.isEmpty()) { + openWallet(n, true); + } +} + + +void KWalletManager::shuttingDown() { + _shuttingDown = true; + kapp->quit(); +} + + +void KWalletManager::setupWallet() { + KApplication::startServiceByDesktopName("kwallet_config"); +} + + +void KWalletManager::closeAllWallets() { + _dcopRef->call("closeAllWallets"); +} + + +QPixmap KWalletManager::loadSystemTrayIcon(const QString &icon) { +#if KDE_IS_VERSION(3, 1, 90) + return KSystemTray::loadIcon(icon); +#else + KConfig *appCfg = kapp->config(); + KConfigGroupSaver configSaver(appCfg, "System Tray"); + int iconWidth = appCfg->readNumEntry("systrayIconWidth", 22); + return kapp->iconLoader()->loadIcon( icon, KIcon::Panel, iconWidth ); +#endif +} + + +#include "kwalletmanager.moc" |