diff --git a/src/konfigurator/konfigurator.cpp b/src/konfigurator/konfigurator.cpp index c5e51df..77bfe18 100644 --- a/src/konfigurator/konfigurator.cpp +++ b/src/konfigurator/konfigurator.cpp @@ -1,399 +1,399 @@ /* Copyright (C) 2003 George Staikos 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_version.h" #include "konfigurator.h" #include #include #include #include -#include +#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define KWALLETMANAGERINTERFACE "org.kde.KWallet" K_PLUGIN_FACTORY(KWalletFactory, registerPlugin();) KWalletConfig::KWalletConfig(QWidget *parent, const QVariantList &args) : KCModule(parent, args), _cfg(KSharedConfig::openConfig(QStringLiteral("kwalletrc"), KConfig::NoGlobals)) { KAboutData *about = new KAboutData(QStringLiteral("kcmkwallet5"), i18n("KDE Wallet Control Module"), QStringLiteral(KWALLETMANAGER_VERSION_STRING), QString(), KAboutLicense::GPL, i18n("(c) 2003 George Staikos")); about->addAuthor(i18n("George Staikos"), QString(), QStringLiteral("staikos@kde.org")); setAboutData(about); setNeedsAuthorization(true); QVBoxLayout *vbox = new QVBoxLayout(this); vbox->setContentsMargins(0, 0, 0, 0); _wcw = new WalletConfigWidget(this); vbox->addWidget(_wcw); connect(_wcw->_enabled, &QCheckBox::clicked, this, &KWalletConfig::configChanged); connect(_wcw->_launchManager, &QCheckBox::clicked, this, &KWalletConfig::configChanged); connect(_wcw->_autocloseManager, &QCheckBox::clicked, this, &KWalletConfig::configChanged); connect(_wcw->_autoclose, &QCheckBox::clicked, this, &KWalletConfig::configChanged); connect(_wcw->_closeIdle, &QCheckBox::clicked, this, &KWalletConfig::configChanged); connect(_wcw->_openPrompt, &QCheckBox::clicked, this, &KWalletConfig::configChanged); connect(_wcw->_screensaverLock, &QCheckBox::clicked, this, &KWalletConfig::configChanged); connect(_wcw->_localWalletSelected, &QCheckBox::clicked, this, &KWalletConfig::configChanged); connect(_wcw->_idleTime, static_cast(&QSpinBox::valueChanged), this, &KWalletConfig::configChanged); connect(_wcw->_launch, &QPushButton::clicked, this, &KWalletConfig::launchManager); connect(_wcw->_newWallet, &QPushButton::clicked, this, &KWalletConfig::newNetworkWallet); connect(_wcw->_newLocalWallet, &QPushButton::clicked, this, &KWalletConfig::newLocalWallet); connect(_wcw->_localWallet, static_cast(&QComboBox::activated), this, &KWalletConfig::configChanged); connect(_wcw->_defaultWallet, static_cast(&QComboBox::activated), this, &KWalletConfig::configChanged); connect(_wcw->_accessList, &QTreeWidget::customContextMenuRequested, this, &KWalletConfig::customContextMenuRequested); _wcw->_accessList->setAllColumnsShowFocus(true); _wcw->_accessList->setContextMenuPolicy(Qt::CustomContextMenu); updateWalletLists(); if (QDBusConnection::sessionBus().interface()->isServiceRegistered(QStringLiteral("org.kde.kwalletmanager"))) { _wcw->_launch->hide(); } } KWalletConfig::~KWalletConfig() { } void KWalletConfig::updateWalletLists() { const QString p1(_wcw->_localWallet->currentText()); const QString p2(_wcw->_defaultWallet->currentText()); _wcw->_localWallet->clear(); _wcw->_defaultWallet->clear(); const QStringList wl = KWallet::Wallet::walletList(); _wcw->_localWallet->addItems(wl); _wcw->_defaultWallet->addItems(wl); int index = wl.indexOf(p1); if (index != -1) { _wcw->_localWallet->setCurrentIndex(index); } index = wl.indexOf(p2); if (index != -1) { _wcw->_defaultWallet->setCurrentIndex(index); } } QString KWalletConfig::newWallet() { bool ok; const QString n = QInputDialog::getText(this, i18n("New Wallet"), i18n("Please choose a name for the new wallet:"), QLineEdit::Normal, QString(), &ok); if (!ok) { return QString(); } KWallet::Wallet *w = KWallet::Wallet::openWallet(n, topLevelWidget()->winId()); if (!w) { return QString(); } delete w; return n; } void KWalletConfig::newLocalWallet() { const QString n = newWallet(); if (n.trimmed().isEmpty()) { return; } updateWalletLists(); _wcw->_localWallet->setCurrentIndex(_wcw->_localWallet->findText(n)); emit changed(true); } void KWalletConfig::newNetworkWallet() { const QString n = newWallet(); if (n.trimmed().isEmpty()) { return; } updateWalletLists(); _wcw->_defaultWallet->setCurrentIndex(_wcw->_defaultWallet->findText(n)); emit changed(true); } void KWalletConfig::launchManager() { if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(QStringLiteral("org.kde.kwalletmanager5"))) { QProcess::startDetached(QStringLiteral("kwalletmanager5 --show")); } else { QDBusInterface kwalletd(QStringLiteral("org.kde.kwalletmanager5"), QStringLiteral("/kwalletmanager5/MainWindow_1")); kwalletd.call(QStringLiteral("show")); kwalletd.call(QStringLiteral("raise")); } } void KWalletConfig::configChanged() { emit changed(true); } void KWalletConfig::load() { KConfigGroup config(_cfg, "Wallet"); _wcw->_enabled->setChecked(config.readEntry("Enabled", true)); _wcw->_openPrompt->setChecked(config.readEntry("Prompt on Open", false)); _wcw->_launchManager->setChecked(config.readEntry("Launch Manager", false)); _wcw->_autocloseManager->setChecked(! config.readEntry("Leave Manager Open", false)); _wcw->_screensaverLock->setChecked(config.readEntry("Close on Screensaver", false)); _wcw->_autoclose->setChecked(!config.readEntry("Leave Open", true)); _wcw->_closeIdle->setChecked(config.readEntry("Close When Idle", false)); _wcw->_idleTime->setValue(config.readEntry("Idle Timeout", 10)); if (config.hasKey("Default Wallet")) { int defaultWallet_idx = _wcw->_defaultWallet->findText(config.readEntry("Default Wallet")); if (defaultWallet_idx != -1) { _wcw->_defaultWallet->setCurrentIndex(defaultWallet_idx); } else { _wcw->_defaultWallet->setCurrentIndex(0); } } else { _wcw->_defaultWallet->setCurrentIndex(0); } if (config.hasKey("Local Wallet")) { _wcw->_localWalletSelected->setChecked(!config.readEntry("Use One Wallet", false)); int localWallet_idx = _wcw->_localWallet->findText(config.readEntry("Local Wallet")); if (localWallet_idx != -1) { _wcw->_localWallet->setCurrentIndex(localWallet_idx); } else { _wcw->_localWallet->setCurrentIndex(0); } } else { _wcw->_localWalletSelected->setChecked(false); } _wcw->_accessList->clear(); KConfigGroup ad(_cfg, "Auto Deny"); KConfigGroup aa(_cfg, "Auto Allow"); QStringList denykeys = ad.entryMap().keys(); const QStringList keys = aa.entryMap().keys(); for (QStringList::const_iterator i = keys.begin(); i != keys.end(); ++i) { QString walletName = *i; // perform cleanup in the kwalletrc file, by removing entries that correspond to non-existent // (previously deleted, for example) wallets QString path = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation); path.append(QStringLiteral("/kwalletd/%1.kwl").arg(walletName)); if (!QFile::exists(path)) { // if the wallet no longer exists, delete the entries from the configuration file and skip to next entry KConfigGroup cfgAllow = KSharedConfig::openConfig(QStringLiteral("kwalletrc"))->group("Auto Allow"); cfgAllow.deleteEntry(walletName); KConfigGroup cfgDeny = KSharedConfig::openConfig(QStringLiteral("kwalletrc"))->group("Auto Deny"); cfgDeny.deleteEntry(walletName); continue; } const QStringList apps = aa.readEntry(*i, QStringList()); const QStringList denyapps = ad.readEntry(*i, QStringList()); denykeys.removeAll(walletName); QTreeWidgetItem *twi = new QTreeWidgetItem(_wcw->_accessList, QStringList() << walletName); for (QStringList::const_iterator j = apps.begin(), end = apps.end(); j != end; ++j) { new QTreeWidgetItem(twi, QStringList() << QString() << *j << i18n("Always Allow")); } for (QStringList::const_iterator j = denyapps.begin(), end = denyapps.end(); j != end; ++j) { new QTreeWidgetItem(twi, QStringList() << QString() << *j << i18n("Always Deny")); } } for (QStringList::const_iterator i = denykeys.constBegin(), denykeysEnd = denykeys.constEnd(); i != denykeysEnd; ++i) { const QStringList denyapps = ad.readEntry(*i, QStringList()); QTreeWidgetItem *twi = new QTreeWidgetItem(_wcw->_accessList, QStringList() << *i); for (QStringList::const_iterator j = denyapps.begin(), denyappsEnd = denyapps.end(); j != denyappsEnd; ++j) { new QTreeWidgetItem(twi, QStringList() << QString() << *j << i18n("Always Deny")); } } _wcw->_accessList->header()->setSectionResizeMode(QHeaderView::ResizeToContents); emit changed(false); } void KWalletConfig::save() { QVariantMap args; KAuth::Action action = authAction(); if (!action.isValid()) { qDebug() << "There's no authAction, not saving settings"; return; } action.setArguments(args); KAuth::ExecuteJob *j = action.execute(); if (!j->exec()) { if (j->error() == KAuth::ActionReply::AuthorizationDeniedError) { KMessageBox::error(this, i18n("Permission denied."), i18n("KDE Wallet Control Module")); } else { KMessageBox::error(this, i18n("Error while authenticating action:\n%1", j->errorString()), i18n("KDE Wallet Control Module")); } load(); return; } KConfigGroup config(_cfg, "Wallet"); config.writeEntry("Enabled", _wcw->_enabled->isChecked()); config.writeEntry("Launch Manager", _wcw->_launchManager->isChecked()); config.writeEntry("Leave Manager Open", !_wcw->_autocloseManager->isChecked()); config.writeEntry("Leave Open", !_wcw->_autoclose->isChecked()); config.writeEntry("Close When Idle", _wcw->_closeIdle->isChecked()); config.writeEntry("Idle Timeout", _wcw->_idleTime->value()); config.writeEntry("Prompt on Open", _wcw->_openPrompt->isChecked()); config.writeEntry("Close on Screensaver", _wcw->_screensaverLock->isChecked()); config.writeEntry("Use One Wallet", !_wcw->_localWalletSelected->isChecked()); if (_wcw->_localWalletSelected->isChecked()) { config.writeEntry("Local Wallet", _wcw->_localWallet->currentText()); } else { config.deleteEntry("Local Wallet"); } if (_wcw->_defaultWallet->currentIndex() != -1) { config.writeEntry("Default Wallet", _wcw->_defaultWallet->currentText()); } else { config.deleteEntry("Default Wallet"); } // FIXME: won't survive a language change _cfg->deleteGroup("Auto Allow"); _cfg->deleteGroup("Auto Deny"); config = _cfg->group("Auto Allow"); for (int i = 0; i < _wcw->_accessList->topLevelItemCount(); ++i) { QTreeWidgetItem *parentItem = _wcw->_accessList->topLevelItem(i); QStringList al; for (int j = 0; j < parentItem->childCount(); ++j) { QTreeWidgetItem *childItem = parentItem->child(j); if (childItem->text(2) == i18n("Always Allow")) { al << childItem->text(1); } } config.writeEntry(parentItem->text(0), al); } config = _cfg->group("Auto Deny"); for (int i = 0; i < _wcw->_accessList->topLevelItemCount(); ++i) { QTreeWidgetItem *parentItem = _wcw->_accessList->topLevelItem(i); QStringList al; for (int j = 0; j < parentItem->childCount(); ++j) { QTreeWidgetItem *childItem = parentItem->child(j); if (childItem->text(2) == i18n("Always Deny")) { al << childItem->text(1); } } config.writeEntry(parentItem->text(0), al); } _cfg->sync(); // this restarts kwalletd if necessary QDBusInterface kwalletd(QStringLiteral("org.kde.kwalletd5"), QStringLiteral("/modules/kwalletd"), QStringLiteral(KWALLETMANAGERINTERFACE)); // if wallet was deactivated, then kwalletd will exit upon start so check // the status before invoking reconfigure if (kwalletd.isValid()) { // this will eventually make kwalletd exit upon deactivation kwalletd.call(QStringLiteral("reconfigure")); } emit changed(false); } void KWalletConfig::defaults() { _wcw->_enabled->setChecked(true); _wcw->_openPrompt->setChecked(false); _wcw->_launchManager->setChecked(true); _wcw->_autocloseManager->setChecked(false); _wcw->_screensaverLock->setChecked(false); _wcw->_autoclose->setChecked(true); _wcw->_closeIdle->setChecked(false); _wcw->_idleTime->setValue(10); _wcw->_defaultWallet->setCurrentIndex(0); _wcw->_localWalletSelected->setChecked(false); _wcw->_localWallet->setCurrentIndex(0); _wcw->_accessList->clear(); emit changed(true); } QString KWalletConfig::quickHelp() const { return i18n("This configuration module allows you to configure the KDE wallet system."); } void KWalletConfig::customContextMenuRequested(const QPoint &pos) { QTreeWidgetItem *item = _wcw->_accessList->itemAt(pos); if (item && item->parent()) { QMenu *m = new QMenu(this); m->setTitle(item->parent()->text(0)); m->addAction(i18n("&Delete"), this, &KWalletConfig::deleteEntry, Qt::Key_Delete); m->exec(_wcw->_accessList->mapToGlobal(pos)); delete m; } } void KWalletConfig::deleteEntry() { QList items = _wcw->_accessList->selectedItems(); if (items.count() == 1 && items[0]) { delete items[0]; emit changed(true); } } #include "konfigurator.moc" diff --git a/src/konfigurator/savehelper.h b/src/konfigurator/savehelper.h index e39de1c..995ba58 100644 --- a/src/konfigurator/savehelper.h +++ b/src/konfigurator/savehelper.h @@ -1,34 +1,34 @@ /* Copyright (C) 2013 Valentin Rusu 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. */ #ifndef _SAVEHELPER_H_ #define _SAVEHELPER_H_ -#include +#include using namespace KAuth; class SaveHelper : public QObject { Q_OBJECT public Q_SLOTS: ActionReply save(const QVariantMap &args); }; #endif // _SAVEHELPER_H_ diff --git a/src/manager/allyourbase.cpp b/src/manager/allyourbase.cpp index ab6bf0e..c163c95 100644 --- a/src/manager/allyourbase.cpp +++ b/src/manager/allyourbase.cpp @@ -1,709 +1,709 @@ /* Copyright (C) 2003-2005 George Staikos Copyright (C) 2005 Isaac Clerencia 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 "allyourbase.h" #include "kwalletmanager_debug.h" #include #include #include #include #include -#include +#include #include #include #include #include #include #include #include #include #include /**************** * KWalletFolderItem - ListView items to represent kwallet folders */ KWalletFolderItem::KWalletFolderItem(KWallet::Wallet *w, QTreeWidget *parent, const QString &name, int entries) : QTreeWidgetItem(parent, KWalletFolderItemClass), _wallet(w), _name(name), _entries(entries) { setText(0, QStringLiteral("%1 (%2)").arg(_name).arg(_entries)); setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEnabled); setIcon(0, getFolderIcon(KIconLoader::Small)); } QPixmap KWalletFolderItem::getFolderIcon(KIconLoader::Group group) { QPixmap pix = QIcon::fromTheme(_name).pixmap(IconSize(group), IconSize(group)); if (pix.isNull()) { pix = QIcon::fromTheme(_name.toLower()).pixmap(IconSize(group), IconSize(group)); if (pix.isNull()) pix = QIcon::fromTheme(QStringLiteral("folder-red")).pixmap(IconSize(group), IconSize(group)); } return pix; } void KWalletFolderItem::refresh() { const QString saveFolder = _wallet->currentFolder(); _wallet->setFolder(_name); setText(0, QStringLiteral("%1 (%2)").arg(_name).arg(_wallet->entryList().count())); _wallet->setFolder(saveFolder); } void KWalletFolderItem::refreshItemsCount() { int visibleLeafCount = 0; for (int i = 0; i < childCount(); i++) { QTreeWidgetItem *wi = child(i); if (wi->childCount()) { for (int l = 0; l < wi->childCount(); l++) { QTreeWidgetItem *li = wi->child(l); if (!li->isHidden()) { visibleLeafCount++; } } } } setText(0, QStringLiteral("%1 (%2)").arg(_name).arg(visibleLeafCount)); } KWalletContainerItem *KWalletFolderItem::getContainer(KWallet::Wallet::EntryType type) { for (int i = 0; i < childCount(); ++i) { KWalletContainerItem *ci = dynamic_cast(child(i)); if (!ci) { continue; } if (ci->entryType() == type) { return ci; } } return nullptr; } bool KWalletFolderItem::contains(const QString &key) { return (getItem(key) != nullptr); } QTreeWidgetItem *KWalletFolderItem::getItem(const QString &key) { for (int i = 0; i < childCount(); ++i) { KWalletContainerItem *ci = dynamic_cast(child(i)); if (!ci) { continue; } QTreeWidgetItem *tmp = ci->getItem(key); if (tmp) { return tmp; } } return nullptr; } bool KWalletFolderItem::acceptDrop(const QMimeData *mime) const { return mime->hasFormat(QStringLiteral("application/x-kwallet-entry")) || mime->hasFormat(QStringLiteral("text/uri-list")); } QString KWalletFolderItem::name() const { return _name; } KWalletFolderItem::~KWalletFolderItem() { } /**************** * KWalletContainerItem - ListView items to represent kwallet containers, i.e. * passwords, maps, ... */ KWalletContainerItem::KWalletContainerItem(QTreeWidgetItem *parent, const QString &name, KWallet::Wallet::EntryType entryType) : QTreeWidgetItem(parent, QStringList() << name, KWalletContainerItemClass), _type(entryType) { setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled); } KWalletContainerItem::~KWalletContainerItem() { } KWallet::Wallet::EntryType KWalletContainerItem::entryType() { return _type; } bool KWalletContainerItem::contains(const QString &key) { return getItem(key) != nullptr; } QTreeWidgetItem *KWalletContainerItem::getItem(const QString &key) { for (int i = 0; i < childCount(); ++i) { KWalletEntryItem *entryItem = dynamic_cast(child(i)); if (entryItem && entryItem->name() == key) { return entryItem; } } return nullptr; } /**************** * KWalletEntryItem - ListView items to represent kwallet entries */ KWalletEntryItem::KWalletEntryItem(KWallet::Wallet *w, QTreeWidgetItem *parent, const QString &ename) : QTreeWidgetItem(parent, QStringList() << ename, KWalletEntryItemClass), _wallet(w), m_name(ename) { setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled); } KWalletEntryItem::~KWalletEntryItem() { } void KWalletEntryItem::setName(const QString &n) { m_name = n; QTreeWidgetItem::setText(0, n); } void KWalletEntryItem::restoreName() { QTreeWidgetItem::setText(0, m_name); } /**************** * KWalletItem - IconView items to represent wallets */ KWalletItem::KWalletItem(QListWidget *parent, const QString &walletName) : QListWidgetItem(QIcon::fromTheme(QStringLiteral("wallet-closed")), walletName, parent), _open(false) { setFlags(flags() | Qt::ItemIsDropEnabled); } KWalletItem::~KWalletItem() { } void KWalletItem::setOpen(bool state) { if (_open != state) { _open = state; if (_open) { setIcon(QIcon::fromTheme(QStringLiteral("wallet-open"))); } else { setIcon(QIcon::fromTheme(QStringLiteral("wallet-closed"))); } } } static bool decodeEntry(KWallet::Wallet *_wallet, QDataStream &ds) { quint32 magic; ds >> magic; if (magic != KWALLETENTRYMAGIC) { qCDebug(KWALLETMANAGER_LOG) << "bad magic" ; return false; } QString name; QByteArray value; KWallet::Wallet::EntryType et; ds >> name; if (_wallet->hasEntry(name)) { int rc = KMessageBox::warningContinueCancel(nullptr, i18n("An entry by the name '%1' already exists. Would you like to continue?", name)); if (rc == KMessageBox::Cancel) { return false; } } qint32 l; ds >> l; et = KWallet::Wallet::EntryType(l); ds >> value; _wallet->writeEntry(name, value, et); return true; } static bool decodeFolder(KWallet::Wallet *_wallet, QDataStream &ds) { quint32 magic; ds >> magic; if (magic != KWALLETFOLDERMAGIC) { qCDebug(KWALLETMANAGER_LOG) << "bad magic" ; return false; } QString folder; ds >> folder; if (_wallet->hasFolder(folder)) { int rc = KMessageBox::warningYesNoCancel(nullptr, i18n("A folder by the name '%1' already exists. What would you like to do?", folder), QString(), KStandardGuiItem::cont(), KGuiItem(i18n("Replace"))); if (rc == KMessageBox::Cancel) { return false; } if (rc == KMessageBox::No) { _wallet->removeFolder(folder); _wallet->createFolder(folder); } } else { _wallet->createFolder(folder); } _wallet->setFolder(folder); while (!ds.atEnd()) { QString name; QByteArray value; KWallet::Wallet::EntryType et; ds >> name; qint32 l; ds >> l; et = KWallet::Wallet::EntryType(l); ds >> value; _wallet->writeEntry(name, value, et); } return true; } void KWalletItem::processDropEvent(QDropEvent *e) { // We fetch this here at the beginning because we run an event loop further // down which might lead to the event data getting deleted KWalletEntryList *el = nullptr; Qt::DropAction proposedAction = e->proposedAction(); if (e->source() && e->source()->parent() && !strcmp(e->source()->parent()->metaObject()->className(), "KWalletEntryList") && (proposedAction != Qt::CopyAction)) { el = dynamic_cast(e->source()->parent()); } if (e->mimeData()->hasFormat(QStringLiteral("application/x-kwallet-folder")) || e->mimeData()->hasFormat(QStringLiteral("text/uri-list"))) { // FIXME: don't allow the drop if the wallet name is the same KWallet::Wallet *_wallet = KWallet::Wallet::openWallet(text(), listWidget()->topLevelWidget()->winId()); if (!_wallet) { e->ignore(); return; } const QString saveFolder = _wallet->currentFolder(); QByteArray data; if (e->mimeData()->hasFormat(QStringLiteral("application/x-kwallet-folder"))) { data = e->mimeData()->data(QStringLiteral("application/x-kwallet-folder")); e->accept(); } else { // text/uri-list const QList urls = e->mimeData()->urls(); if (urls.isEmpty()) { e->ignore(); return; } QUrl u(urls.first()); if (u.fileName().isEmpty()) { e->ignore(); return; } KIO::StoredTransferJob *job = KIO::storedGet(u); KJobWidgets::setWindow(job, listWidget()); e->accept(); if (job->exec()) { data = job->data(); } else { KMessageBox::error(listWidget(), job->errorString()); } } if (!data.isEmpty()) { QDataStream ds(data); decodeFolder(_wallet, ds); } _wallet->setFolder(saveFolder); delete _wallet; //delete the folder from the source if we were moving if (el) { KWalletFolderItem *fi = dynamic_cast(el->currentItem()); if (fi) { el->_wallet->removeFolder(fi->name()); } } } else { e->ignore(); return; } } /**************** * KWalletEntryList - A listview to store wallet entries */ KWalletEntryList::KWalletEntryList(QWidget *parent, const QString &name) : QTreeWidget(parent), _wallet(nullptr) { setObjectName(name); setColumnCount(1); setHeaderLabel(i18n("Folders")); setRootIsDecorated(true); setDragEnabled(true); setAcceptDrops(true); setDragDropMode(DragDrop); setSelectionMode(SingleSelection); } KWalletEntryList::~KWalletEntryList() { } //returns true if the item has been dropped successfully void KWalletEntryList::itemDropped(QDropEvent *e, QTreeWidgetItem *item) { bool ok = true; bool isEntry; QByteArray data; KWalletEntryList *el = nullptr; QTreeWidgetItem *sel = nullptr; // We fetch this here because we run an event loop further down which might invalidate this Qt::DropAction proposedAction = e->proposedAction(); if (!item) { e->ignore(); return; } //detect if we are dragging from kwallet itself qCDebug(KWALLETMANAGER_LOG) << e->source() << e->source()->metaObject()->className(); if (e->source() && !strcmp(e->source()->metaObject()->className(), "KWalletEntryList")) { el = dynamic_cast(e->source()); if (!el) { KMessageBox::error(this, i18n("An unexpected error occurred trying to drop the item")); } else { sel = el->currentItem(); } } if (e->mimeData()->hasFormat(QStringLiteral("application/x-kwallet-entry"))) { //do nothing if we are in the same folder if (sel && sel->parent()->parent() == KWalletEntryList::getItemFolder(item)) { e->ignore(); return; } isEntry = true; data = e->mimeData()->data(QStringLiteral("application/x-kwallet-entry")); if (data.isEmpty()) { e->ignore(); return; } e->accept(); } else if (e->mimeData()->hasFormat(QStringLiteral("application/x-kwallet-folder"))) { //do nothing if we are in the same wallet if (this == el) { e->ignore(); return; } isEntry = false; data = e->mimeData()->data(QStringLiteral("application/x-kwallet-folder")); if (data.isEmpty()) { e->ignore(); return; } e->accept(); } else if (e->mimeData()->hasFormat(QStringLiteral("text/uri-list"))) { const QList urls = e->mimeData()->urls(); if (urls.isEmpty()) { e->ignore(); return; } QUrl u(urls.first()); if (u.fileName().isEmpty()) { e->ignore(); return; } e->accept(); KIO::StoredTransferJob *job = KIO::storedGet(u); KJobWidgets::setWindow(job, this); if (!job->exec()) { KMessageBox::error(this, job->errorString()); return; } data = job->data(); QByteArray entryMagic(QByteArray::number(KWALLETENTRYMAGIC)); QByteArray folderMagic(QByteArray::number(KWALLETFOLDERMAGIC)); if (data.startsWith(entryMagic)) { isEntry = true; } else if (data.startsWith(folderMagic)) { isEntry = false; } else { qCDebug(KWALLETMANAGER_LOG) << "bad magic" ; return; } } else { e->ignore(); return; } QDataStream ds(data); if (isEntry) { KWalletFolderItem *fi = KWalletEntryList::getItemFolder(item); if (!fi) { KMessageBox::error(this, i18n("An unexpected error occurred trying to drop the entry")); return; } QString saveFolder = _wallet->currentFolder(); _wallet->setFolder(fi->name()); ok = decodeEntry(_wallet, ds); _wallet->setFolder(saveFolder); fi->refresh(); //delete source if we were moving, i.e., we are dragging //from kwalletmanager and Control is not pressed if (ok && el && proposedAction != Qt::CopyAction && sel) { el->_wallet->removeEntry(sel->text(0)); delete sel; } } else { ok = decodeFolder(_wallet, ds); //delete source if we were moving, i.e., we are dragging //from kwalletmanager and Control is not pressed if (ok && el && proposedAction != Qt::CopyAction && sel) { KWalletFolderItem *fi = dynamic_cast(sel); if (fi) { el->_wallet->removeFolder(fi->name()); delete sel; } else { KMessageBox::error(this, i18n("An unexpected error occurred trying to delete the original folder, but the folder has been copied successfully")); } } } } void KWalletEntryList::setWallet(KWallet::Wallet *w) { _wallet = w; } bool KWalletEntryList::existsFolder(const QString &name) { for (int i = 0; i < topLevelItemCount(); ++i) { KWalletFolderItem *fi = dynamic_cast(topLevelItem(i)); if (!fi) { continue; } if (name == fi->name()) { return true; } } return false; } QMimeData *KWalletEntryList::itemMimeData(const QTreeWidgetItem *i) const { QMimeData *sd = nullptr; if (i->type() == KWalletEntryItemClass) { const KWalletEntryItem *ei = dynamic_cast(i); if (!ei) { return nullptr; } KWalletContainerItem *ci = dynamic_cast(ei->parent()); if (!ci) { return nullptr; } sd = new QMimeData(); QByteArray a; QDataStream ds(&a, QIODevice::WriteOnly); ds.setVersion(QDataStream::Qt_3_1); ds << KWALLETENTRYMAGIC; ds << ei->text(0); ds << ci->entryType(); QByteArray value; ei->_wallet->readEntry(i->text(0), value); ds << value; sd->setData(QStringLiteral("application/x-kwallet-entry"), a); } else if (i->type() == KWalletFolderItemClass) { const KWalletFolderItem *fi = dynamic_cast(i); if (!fi) { return nullptr; } sd = new QMimeData(); QByteArray a; QDataStream ds(&a, QIODevice::WriteOnly); ds.setVersion(QDataStream::Qt_3_1); ds << KWALLETFOLDERMAGIC; ds << *fi; sd->setData(QStringLiteral("application/x-kwallet-folder"), a); } return sd; } void KWalletEntryList::mousePressEvent(QMouseEvent *e) { if (e->button() == Qt::LeftButton) { _mousePos = e->pos(); } QTreeWidget::mousePressEvent(e); } void KWalletEntryList::mouseMoveEvent(QMouseEvent *e) { if (!(e->buttons() & Qt::LeftButton)) { return; } if ((e->pos() - _mousePos).manhattanLength() < QApplication::startDragDistance()) { return; } const QTreeWidgetItem *item = itemAt(_mousePos); if (!item || !item->isSelected()) { return; } QMimeData *mimeData = itemMimeData(item); if (mimeData) { QDrag *drag = new QDrag(this); drag->setMimeData(mimeData); drag->setHotSpot(QPoint(0, 0)); drag->exec(); } } void KWalletEntryList::dropEvent(QDropEvent *e) { QTreeWidgetItem *i = itemAt(e->pos()); itemDropped(e, i); } void KWalletEntryList::dragEnterEvent(QDragEnterEvent *e) { e->accept(); } void KWalletEntryList::dragMoveEvent(QDragMoveEvent *e) { QTreeWidgetItem *i = itemAt(e->pos()); e->ignore(); if (i) { if (e->mimeData()->hasFormat(QStringLiteral("application/x-kwallet-entry")) || e->mimeData()->hasFormat(QStringLiteral("text/uri-list"))) { e->accept(); } } if ((e->mimeData()->hasFormat(QStringLiteral("application/x-kwallet-folder")) && e->source() != viewport()) || e->mimeData()->hasFormat(QStringLiteral("text/uri-list"))) { e->accept(); } } KWalletFolderItem *KWalletEntryList::getFolder(const QString &name) { for (int i = 0; i < topLevelItemCount(); ++i) { KWalletFolderItem *fi = dynamic_cast(topLevelItem(i)); if (!fi) { continue; } if (name == fi->name()) { return fi; } } return nullptr; } KWalletFolderItem *KWalletEntryList::getItemFolder(QTreeWidgetItem *item) { switch (item->type()) { case KWalletFolderItemClass: return dynamic_cast(item); case KWalletContainerItemClass: return dynamic_cast(item->parent()); case KWalletEntryItemClass: return dynamic_cast(item->parent()->parent()); } return nullptr; } void KWalletEntryList::selectFirstVisible() { QTreeWidgetItemIterator it(this); while (*it) { QTreeWidgetItem *item = *it++; if (!item->isHidden()) { // if it's a leaf, then select it and quit if (item->childCount() == 0) { // qCDebug(KWALLETMANAGER_LOG) << "selecting " << item->text(0); setCurrentItem(item); break; } } } } void KWalletEntryList::refreshItemsCount() { QTreeWidgetItemIterator it(this); while (*it) { QTreeWidgetItem *item = *it++; KWalletFolderItem *fi = dynamic_cast< KWalletFolderItem * >(item); if (fi) { fi->refreshItemsCount(); } } } class ReturnPressedFilter : public QObject { public: ReturnPressedFilter(QListWidget *parent) : QObject(parent) { parent->installEventFilter(this); } bool eventFilter(QObject * /*watched*/, QEvent *event) override { if (event->type() == QEvent::KeyPress) { QKeyEvent *ke = static_cast(event); if (ke->key() == Qt::Key_Enter || ke->key() == Qt::Key_Return) { QListWidget *p = static_cast(parent()); QMetaObject::invokeMethod(p, "executed", Q_ARG(QListWidgetItem *, p->currentItem())); return true; } } return false; } }; diff --git a/src/manager/allyourbase.h b/src/manager/allyourbase.h index 43a6d0e..a1a4aca 100644 --- a/src/manager/allyourbase.h +++ b/src/manager/allyourbase.h @@ -1,184 +1,184 @@ /* Copyright (C) 2003-2005 George Staikos Copyright (C) 2005 Isaac Clerencia 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. */ #ifndef ALLYOURBASE_H #define ALLYOURBASE_H -#include +#include #include #include #include #include #include #include #include #include #define KWALLETENTRYMAGIC ((quint32) 0x6B776C65) #define KWALLETFOLDERMAGIC ((quint32) 0x6B776C66) enum KWalletListItemClasses { KWalletFolderItemClass = QTreeWidgetItem::UserType, KWalletContainerItemClass, KWalletEntryItemClass, KWalletUnknownClass }; class KWalletEntryItem : public QTreeWidgetItem { public: KWalletEntryItem(KWallet::Wallet *w, QTreeWidgetItem *parent, const QString &ename); virtual ~KWalletEntryItem(); const QString &name() const { return m_name; } void setName(const QString &n); // Cancel renaming void restoreName(); public: KWallet::Wallet *_wallet; private: void setText(int, const QString &) {} // forbidden QString m_name; }; class KWalletContainerItem : public QTreeWidgetItem { public: KWalletContainerItem(QTreeWidgetItem *parent, const QString &name, KWallet::Wallet::EntryType entryType); virtual ~KWalletContainerItem(); public: KWallet::Wallet::EntryType entryType(); bool contains(const QString &itemKey); QTreeWidgetItem *getItem(const QString &itemKey); private: KWallet::Wallet::EntryType _type; }; class KWalletFolderItem : public QTreeWidgetItem { public: KWalletFolderItem(KWallet::Wallet *w, QTreeWidget *parent, const QString &name, int entries); virtual ~KWalletFolderItem(); virtual bool acceptDrop(const QMimeData *mime) const; QString name() const; void refresh(); KWalletContainerItem *getContainer(KWallet::Wallet::EntryType type); QPixmap getFolderIcon(KIconLoader::Group group); bool contains(const QString &itemKey); QTreeWidgetItem *getItem(const QString &itemKey); void refreshItemsCount(); public: KWallet::Wallet *_wallet; private: QString _name; int _entries; }; class KWalletEntryList : public QTreeWidget { Q_OBJECT public: explicit KWalletEntryList(QWidget *parent, const QString &name = QString()); virtual ~KWalletEntryList(); bool existsFolder(const QString &name); KWalletFolderItem *getFolder(const QString &name); void setWallet(KWallet::Wallet *w); protected: void dragEnterEvent(QDragEnterEvent *e) override; void dragMoveEvent(QDragMoveEvent *e) override; void dropEvent(QDropEvent *e) override; void mousePressEvent(QMouseEvent *e) override; void mouseMoveEvent(QMouseEvent *e) override; void itemDropped(QDropEvent *e, QTreeWidgetItem *item); private: static KWalletFolderItem *getItemFolder(QTreeWidgetItem *item); QMimeData *itemMimeData(const QTreeWidgetItem *i) const; public: KWallet::Wallet *_wallet; QPoint _mousePos; public Q_SLOTS: void selectFirstVisible(); void refreshItemsCount(); }; class KWalletItem : public QListWidgetItem { public: KWalletItem(QListWidget *parent, const QString &walletName); virtual ~KWalletItem(); void setOpen(bool state); void processDropEvent(QDropEvent *e); private: bool _open; }; inline QDataStream &operator<<(QDataStream &str, const KWalletEntryItem &w) { QString name = w.text(0); str << name; KWallet::Wallet::EntryType et = w._wallet->entryType(name); str << qint64(et); QByteArray a; w._wallet->readEntry(name, a); str << a; return str; } inline QDataStream &operator<<(QDataStream &str, const KWalletFolderItem &w) { QString oldFolder = w._wallet->currentFolder(); str << w.name(); w._wallet->setFolder(w.name()); const QStringList entries = w._wallet->entryList(); for (const QString &entry : entries) { str << entry; KWallet::Wallet::EntryType et = w._wallet->entryType(entry); str << (qint32)et; QByteArray a; w._wallet->readEntry(entry, a); str << a; } w._wallet->setFolder(oldFolder); return str; } #endif diff --git a/src/manager/applicationsmanager.cpp b/src/manager/applicationsmanager.cpp index 7e4095c..ace75f3 100644 --- a/src/manager/applicationsmanager.cpp +++ b/src/manager/applicationsmanager.cpp @@ -1,56 +1,56 @@ /* Copyright (C) 2013 Valentin Rusu 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 "applicationsmanager.h" #include "connectedappmodel.h" #include "authorizedappmodel.h" -#include "kwallet.h" +#include ApplicationsManager::ApplicationsManager(QWidget *parent): QWidget(parent), _wallet(nullptr), _connectedAppsModel(nullptr), _authorizedAppModel(nullptr) { setupUi(this); } ApplicationsManager::~ApplicationsManager() { delete _connectedAppsModel; delete _authorizedAppModel; } void ApplicationsManager::setWallet(KWallet::Wallet *wallet) { Q_ASSERT(wallet != nullptr); _wallet = wallet; // create the disconnect widget menu _connectedAppsModel = new ConnectedAppModel(_wallet); _connectedApps->setWallet(_wallet); _connectedApps->setModel(_connectedAppsModel); _authorizedAppModel = new AuthorizedAppModel(_wallet); _authorizedApps->setWallet(_wallet); _authorizedApps->setModel(_authorizedAppModel); } diff --git a/src/manager/authorizedappmodel.cpp b/src/manager/authorizedappmodel.cpp index 856d9a7..f156d12 100644 --- a/src/manager/authorizedappmodel.cpp +++ b/src/manager/authorizedappmodel.cpp @@ -1,80 +1,80 @@ /* Copyright (C) 2013 Valentin Rusu 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 "authorizedappmodel.h" #include "kwalletmanager_debug.h" #include -#include +#include #include AuthorizedAppModel::AuthorizedAppModel(KWallet::Wallet *wallet): QStandardItemModel(), _cfg(KSharedConfig::openConfig(QStringLiteral("kwalletrc"), KConfig::NoGlobals)), _wallet(wallet) { // TODO: handle "Auto Deny" applications // KConfigGroup ad(_cfg, "Auto Deny"); KConfigGroup aa(_cfg, "Auto Allow"); QString walletName = _wallet->walletName(); const QStringList keys = aa.entryMap().keys(); for (const QString &cfgWalletName : keys) { if (cfgWalletName == walletName) { const QStringList apps = aa.readEntry(cfgWalletName, QStringList()); int row = 0; for (const QString &appName : apps) { setItem(row, 0, new QStandardItem(appName)); setItem(row, 1, new QStandardItem(QStringLiteral("dummy"))); // this item will be hidden by the disconnect button, see below setIndexWidget call _authorizedAppsIndexMap.insert(appName, QPersistentModelIndex(index(row, 0))); row++; } } } } void AuthorizedAppModel::removeApp(const QString &appName) { if (_authorizedAppsIndexMap.contains(appName)) { QPersistentModelIndex idx = _authorizedAppsIndexMap[appName]; if (idx.isValid()) { if (!removeRow(idx.row())) { qCDebug(KWALLETMANAGER_LOG) << "Remove row failed for app " << appName; } } } else { qCDebug(KWALLETMANAGER_LOG) << "Attempting to remove unknown application " << appName; } QTimer::singleShot(0, this, &AuthorizedAppModel::saveConfig); } void AuthorizedAppModel::saveConfig() { QStringList appList; appList.reserve(rowCount()); for (int r = 0; r < rowCount(); r++) { appList << item(r)->text(); } QString walletName = _wallet->walletName(); KConfigGroup config(_cfg, "Auto Allow"); config.deleteEntry(walletName); config.writeEntry(_wallet->walletName(), appList); _cfg->sync(); } diff --git a/src/manager/connectedapplicationstable.h b/src/manager/connectedapplicationstable.h index 884877f..5ab0946 100644 --- a/src/manager/connectedapplicationstable.h +++ b/src/manager/connectedapplicationstable.h @@ -1,42 +1,42 @@ /* Copyright (C) 2013 Valentin Rusu 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. */ #ifndef CONNECTEDAPPLICATIONSTABLE_H #define CONNECTEDAPPLICATIONSTABLE_H -#include +#include #include class ConnectedApplicationsTable : public QTableView { Q_OBJECT public: explicit ConnectedApplicationsTable(QWidget *parent); void setModel(QAbstractItemModel *model) override; void setWallet(KWallet::Wallet *wallet); protected: void resizeEvent(QResizeEvent *resizeEvent) override; private: KWallet::Wallet *_wallet = nullptr; }; #endif // CONNECTEDAPPLICATIONSTABLE_H diff --git a/src/manager/connectedappmodel.cpp b/src/manager/connectedappmodel.cpp index a688023..07f687f 100644 --- a/src/manager/connectedappmodel.cpp +++ b/src/manager/connectedappmodel.cpp @@ -1,69 +1,69 @@ /* Copyright (C) 2013 Valentin Rusu 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 "connectedappmodel.h" #include "kwalletmanager_debug.h" -#include +#include ConnectedAppModel::ConnectedAppModel(KWallet::Wallet *wallet): QStandardItemModel(), _wallet(wallet) { refresh(); } void ConnectedAppModel::refresh() { clear(); _connectedAppsIndexMap.clear(); _connectedApps = KWallet::Wallet::users(_wallet->walletName()); int row = 0; for (const QString &appName : qAsConst(_connectedApps)) { // for un unknown reason, kwalletd returs empty strings so lets avoid inserting them // FIXME: find out why kwalletd returns empty strings here if (!appName.isEmpty()) { QStandardItem *item = new QStandardItem(appName); item->setEditable(false); setItem(row, 0, item); // this item will be hidden by the disconnect button, see below setIndexWidget call setItem(row, 1, new QStandardItem(QStringLiteral("dummy"))); _connectedAppsIndexMap.insert(appName, QPersistentModelIndex(index(row, 0))); row++; } } } void ConnectedAppModel::removeApp(const QString &appName) { if (_connectedAppsIndexMap.contains(appName)) { QPersistentModelIndex idx = _connectedAppsIndexMap[appName]; if (idx.isValid()) { if (!removeRow(idx.row())) { qCDebug(KWALLETMANAGER_LOG) << "Remove row failed for app " << appName; } } } else { qCDebug(KWALLETMANAGER_LOG) << "Attempting to remove unknown application " << appName; } } diff --git a/src/manager/disconnectappbutton.cpp b/src/manager/disconnectappbutton.cpp index 68b4714..fef7604 100644 --- a/src/manager/disconnectappbutton.cpp +++ b/src/manager/disconnectappbutton.cpp @@ -1,40 +1,40 @@ /* Copyright (C) 2013 Valentin Rusu 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 "disconnectappbutton.h" #include -#include +#include DisconnectAppButton::DisconnectAppButton(const QString &appName, KWallet::Wallet *wallet) : _appName(appName), _wallet(wallet) { setObjectName(QStringLiteral("Disconnect_%1").arg(appName)); setText(i18n("Disconnect")); connect(this, &DisconnectAppButton::clicked, this, &DisconnectAppButton::onClicked); } void DisconnectAppButton::onClicked() { if (_wallet->disconnectApplication(_wallet->walletName(), _appName)) { emit appDisconnected(_appName); } } diff --git a/src/manager/kwalleteditor.cpp b/src/manager/kwalleteditor.cpp index 68156cc..6273b45 100644 --- a/src/manager/kwalleteditor.cpp +++ b/src/manager/kwalleteditor.cpp @@ -1,1328 +1,1328 @@ /* Copyright (C) 2003-2005 George Staikos Copyright (C) 2005 Isaac Clerencia 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 "kwalleteditor.h" #include "kbetterthankdialogbase.h" #include "kwmapeditor.h" #include "allyourbase.h" #include #include #include #include #include #include -#include +#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include QAction *KWalletEditor::_newFolderAction = nullptr; QAction *KWalletEditor::_deleteFolderAction = nullptr; QAction *KWalletEditor::_exportAction = nullptr; QAction *KWalletEditor::_mergeAction = nullptr; QAction *KWalletEditor::_importAction = nullptr; QAction *KWalletEditor::_newEntryAction = nullptr; QAction *KWalletEditor::_renameEntryAction = nullptr; QAction *KWalletEditor::_deleteEntryAction = nullptr; QAction *KWalletEditor::_copyPassAction = nullptr; QAction *KWalletEditor::_alwaysShowContentsAction = nullptr; QAction *KWalletEditor::_alwaysHideContentsAction = nullptr; RegisterCreateActionsMethod KWalletEditor::_registerCreateActionMethod(&KWalletEditor::createActions); KWalletEditor::KWalletEditor(QWidget *parent, const QString &name) : QWidget(parent), _displayedItem(nullptr), _actionCollection(nullptr), _alwaysShowContents(false) { setupUi(this); setObjectName(name); _newWallet = false; _splitter->setStretchFactor(0, 1); _splitter->setStretchFactor(1, 2); _contextMenu = new QMenu(this); _undoChanges->setIcon(QIcon::fromTheme(QStringLiteral("edit-undo"))); _saveChanges->setIcon(QIcon::fromTheme(QStringLiteral("document-save"))); _hasUnsavedChanges = false; QVBoxLayout *box = new QVBoxLayout(_entryListFrame); box->setContentsMargins(0, 0, 0, 0); _entryList = new KWalletEntryList(_entryListFrame, QStringLiteral("Wallet Entry List")); _entryList->setContextMenuPolicy(Qt::CustomContextMenu); _searchLine = new KTreeWidgetSearchLine(_entryListFrame, _entryList); _searchLine->setPlaceholderText(i18n("Search")); connect(_searchLine, &KTreeWidgetSearchLine::textChanged, this, &KWalletEditor::onSearchTextChanged); box->addWidget(_searchLine); box->addWidget(_entryList); _entryStack->setEnabled(true); box = new QVBoxLayout(_entryStack->widget(2)); box->setContentsMargins(0, 0, 0, 0); _mapEditorShowHide = new QCheckBox(i18n("&Show values"), _entryStack->widget(2)); connect(_mapEditorShowHide, &QCheckBox::toggled, this, &KWalletEditor::showHideMapEditorValue); _mapEditor = new KWMapEditor(_currentMap, _entryStack->widget(2)); box->addWidget(_mapEditorShowHide); box->addWidget(_mapEditor); // load splitter size KConfigGroup cg(KSharedConfig::openConfig(), "WalletEditor"); QList splitterSize = cg.readEntry("SplitterSize", QList()); if (splitterSize.size() != 2) { splitterSize.clear(); splitterSize.append(_splitter->width() / 2); splitterSize.append(_splitter->width() / 2); } _splitter->setSizes(splitterSize); _alwaysShowContents = cg.readEntry("AlwaysShowContents", false); _searchLine->setFocus(); connect(_entryList, &KWalletEntryList::currentItemChanged, this, &KWalletEditor::entrySelectionChanged); connect(_entryList, &KWalletEntryList::customContextMenuRequested, this, &KWalletEditor::listContextMenuRequested); connect(_entryList, &KWalletEntryList::itemChanged, this, &KWalletEditor::listItemChanged); connect(_passwordValue, &QTextEdit::textChanged, this, &KWalletEditor::entryEditted); connect(_mapEditor, &KWMapEditor::dirty, this, &KWalletEditor::entryEditted); connect(_undoChanges, &QPushButton::clicked, this, &KWalletEditor::restoreEntry); connect(_saveChanges, &QPushButton::clicked, this, &KWalletEditor::saveEntry); connect(_showContents, &QToolButton::clicked, this, &KWalletEditor::showPasswordContents); connect(_hideContents, &QToolButton::clicked, this, &KWalletEditor::hidePasswordContents); _binaryViewShow->setChecked(_alwaysShowContents); // createActions(); // TODO: remove kwalleteditor.rc file } KWalletEditor::~KWalletEditor() { emit enableFolderActions(false); emit enableWalletActions(false); emit enableContextFolderActions(false); // save splitter size KConfigGroup cg(KSharedConfig::openConfig(), "WalletEditor"); cg.writeEntry("SplitterSize", _splitter->sizes()); cg.writeEntry("AlwaysShowContents", _alwaysShowContents); cg.sync(); delete _w; _w = nullptr; if (_nonLocal) { KWallet::Wallet::closeWallet(_walletName, true); } delete _contextMenu; _contextMenu = nullptr; } void KWalletEditor::setWallet(KWallet::Wallet *wallet, bool isPath) { Q_ASSERT(wallet != nullptr); _walletName = wallet->walletName(); _nonLocal = isPath; _w = wallet; _entryList->setWallet(_w); connect(_w, &KWallet::Wallet::walletOpened, this, &KWalletEditor::walletOpened); connect(_w, &KWallet::Wallet::walletClosed, this, &KWalletEditor::walletClosed); connect(_w, &KWallet::Wallet::folderUpdated, this, &KWalletEditor::updateEntries); connect(_w, SIGNAL(folderListUpdated()), this, SLOT(updateFolderList())); updateFolderList(); emit enableFolderActions(true); emit enableWalletActions(true); emit enableContextFolderActions(true); _mapEditorShowHide->setChecked(false); showHideMapEditorValue(false); setFocus(); _searchLine->setFocus(); } bool KWalletEditor::isOpen() const { return _w != nullptr; } KActionCollection *KWalletEditor::actionCollection() { if (!_actionCollection) { _actionCollection = new KActionCollection(this); } return _actionCollection; } void KWalletEditor::createActions(KActionCollection *actionCollection) { _newFolderAction = actionCollection->addAction(QStringLiteral("create_folder")); _newFolderAction->setText(i18n("&New Folder...")); _newFolderAction->setIcon(QIcon::fromTheme(QStringLiteral("folder-new"))); _deleteFolderAction = actionCollection->addAction(QStringLiteral("delete_folder")); _deleteFolderAction->setText(i18n("&Delete Folder")); _mergeAction = actionCollection->addAction(QStringLiteral("wallet_merge")); _mergeAction->setText(i18n("&Import a wallet...")); _importAction = actionCollection->addAction(QStringLiteral("wallet_import")); _importAction->setText(i18n("&Import XML...")); _exportAction = actionCollection->addAction(QStringLiteral("wallet_export")); _exportAction->setText(i18n("&Export as XML...")); _copyPassAction = actionCollection->addAction(QStringLiteral("copy_action")); _copyPassAction->setText(i18n("&Copy")); actionCollection->setDefaultShortcut(_copyPassAction, Qt::Key_C + Qt::CTRL); _copyPassAction->setEnabled(false); _newEntryAction = actionCollection->addAction(QStringLiteral("new_entry")); _newEntryAction->setText(i18n("&New...")); actionCollection->setDefaultShortcut(_newEntryAction, Qt::Key_Insert); _newEntryAction->setEnabled(false); _renameEntryAction = actionCollection->addAction(QStringLiteral("rename_entry")); _renameEntryAction->setText(i18n("&Rename")); actionCollection->setDefaultShortcut(_renameEntryAction, Qt::Key_F2); _renameEntryAction->setEnabled(false); _deleteEntryAction = actionCollection->addAction(QStringLiteral("delete_entry")); _deleteEntryAction->setText(i18n("&Delete")); actionCollection->setDefaultShortcut(_deleteEntryAction, Qt::Key_Delete); _deleteEntryAction->setEnabled(false); _alwaysShowContentsAction = actionCollection->addAction(QStringLiteral("always_show_contents")); _alwaysShowContentsAction->setText(i18n("Always show contents")); _alwaysShowContentsAction->setCheckable(true); _alwaysHideContentsAction = actionCollection->addAction(QStringLiteral("always_hide_contents")); _alwaysHideContentsAction->setText(i18n("Always hide contents")); _alwaysHideContentsAction->setCheckable(true); } void KWalletEditor::connectActions() { connect(_newFolderAction, &QAction::triggered, this, &KWalletEditor::createFolder); connect(this, &KWalletEditor::enableFolderActions, _newFolderAction, &QAction::setEnabled); connect(_deleteFolderAction, &QAction::triggered, this, &KWalletEditor::deleteFolder); connect(this, &KWalletEditor::enableContextFolderActions, _deleteFolderAction, &QAction::setEnabled); connect(this, &KWalletEditor::enableFolderActions, _deleteFolderAction, &QAction::setEnabled); connect(_mergeAction, &QAction::triggered, this, &KWalletEditor::importWallet); connect(this, &KWalletEditor::enableWalletActions, _mergeAction, &QAction::setEnabled); connect(_importAction, &QAction::triggered, this, &KWalletEditor::importXML); connect(this, &KWalletEditor::enableWalletActions, _importAction, &QAction::setEnabled); connect(_exportAction, &QAction::triggered, this, &KWalletEditor::exportXML); connect(this, &KWalletEditor::enableWalletActions, _exportAction, &QAction::setEnabled); connect(_newEntryAction, &QAction::triggered, this, &KWalletEditor::newEntry); connect(_renameEntryAction, &QAction::triggered, this, &KWalletEditor::renameEntry); connect(_deleteEntryAction, &QAction::triggered, this, &KWalletEditor::deleteEntry); connect(_copyPassAction, &QAction::triggered, this, &KWalletEditor::copyPassword); connect(this, &KWalletEditor::enableWalletActions, _copyPassAction, &QAction::setEnabled); _showContents->addAction(_alwaysShowContentsAction); _alwaysShowContentsAction->setChecked(_alwaysShowContents); connect(_alwaysShowContentsAction, &QAction::triggered, this, &KWalletEditor::onAlwaysShowContents); _hideContents->addAction(_alwaysHideContentsAction); _alwaysHideContentsAction->setChecked(!_alwaysShowContents); connect(_alwaysHideContentsAction, &QAction::triggered, this, &KWalletEditor::onAlwaysHideContents); } void KWalletEditor::disconnectActions() { disconnect(_newFolderAction, &QAction::triggered, this, &KWalletEditor::createFolder); disconnect(this, &KWalletEditor::enableFolderActions, _newFolderAction, &QAction::setEnabled); disconnect(_deleteFolderAction, &QAction::triggered, this, &KWalletEditor::deleteFolder); disconnect(this, &KWalletEditor::enableContextFolderActions, _deleteFolderAction, &QAction::setEnabled); disconnect(this, &KWalletEditor::enableFolderActions, _deleteFolderAction, &QAction::setEnabled); disconnect(_mergeAction, &QAction::triggered, this, &KWalletEditor::importWallet); disconnect(this, &KWalletEditor::enableWalletActions, _mergeAction, &QAction::setEnabled); disconnect(_importAction, &QAction::triggered, this, &KWalletEditor::importXML); disconnect(this, &KWalletEditor::enableWalletActions, _importAction, &QAction::setEnabled); disconnect(_exportAction, &QAction::triggered, this, &KWalletEditor::exportXML); disconnect(this, &KWalletEditor::enableWalletActions, _exportAction, &QAction::setEnabled); disconnect(_newEntryAction, &QAction::triggered, this, &KWalletEditor::newEntry); disconnect(_renameEntryAction, &QAction::triggered, this, &KWalletEditor::renameEntry); disconnect(_deleteEntryAction, &QAction::triggered, this, &KWalletEditor::deleteEntry); disconnect(_copyPassAction, &QAction::triggered, this, &KWalletEditor::copyPassword); disconnect(this, &KWalletEditor::enableWalletActions, _copyPassAction, &QAction::setEnabled); disconnect(_alwaysShowContentsAction, &QAction::triggered, this, &KWalletEditor::onAlwaysShowContents); disconnect(_alwaysHideContentsAction, &QAction::triggered, this, &KWalletEditor::onAlwaysHideContents); } void KWalletEditor::walletClosed() { _w = nullptr; setEnabled(false); emit enableWalletActions(false); emit enableFolderActions(false); } void KWalletEditor::updateFolderList(bool checkEntries) { const QStringList fl = _w->folderList(); QStack trash; for (int i = 0; i < _entryList->topLevelItemCount(); ++i) { KWalletFolderItem *fi = dynamic_cast(_entryList->topLevelItem(i)); if (!fi) { continue; } if (!fl.contains(fi->name())) { trash.push(fi); } } qDeleteAll(trash); trash.clear(); for (QStringList::const_iterator i = fl.begin(); i != fl.end(); ++i) { if (_entryList->existsFolder(*i)) { if (checkEntries) { updateEntries(*i); } continue; } _w->setFolder(*i); const QStringList entries = _w->entryList(); KWalletFolderItem *item = new KWalletFolderItem(_w, _entryList, *i, entries.count()); KWalletContainerItem *pi = new KWalletContainerItem(item, i18n("Passwords"), KWallet::Wallet::Password); KWalletContainerItem *mi = new KWalletContainerItem(item, i18n("Maps"), KWallet::Wallet::Map); KWalletContainerItem *bi = new KWalletContainerItem(item, i18n("Binary Data"), KWallet::Wallet::Stream); KWalletContainerItem *ui = new KWalletContainerItem(item, i18n("Unknown"), KWallet::Wallet::Unknown); for (QStringList::const_iterator j = entries.begin(); j != entries.end(); ++j) { switch (_w->entryType(*j)) { case KWallet::Wallet::Password: new KWalletEntryItem(_w, pi, *j); break; case KWallet::Wallet::Stream: new KWalletEntryItem(_w, bi, *j); break; case KWallet::Wallet::Map: new KWalletEntryItem(_w, mi, *j); break; case KWallet::Wallet::Unknown: default: new QTreeWidgetItem(ui, QStringList() << *j); break; } } _entryList->setEnabled(true); } //check if the current folder has been removed if (!fl.contains(_currentFolder)) { _currentFolder.clear(); _entryTitle->clear(); _iconTitle->clear(); } } void KWalletEditor::deleteFolder() { if (_w) { QTreeWidgetItem *i = _entryList->currentItem(); if (i) { KWalletFolderItem *fi = dynamic_cast(i); if (!fi) { return; } int rc = KMessageBox::warningContinueCancel(this, i18n("Are you sure you wish to delete the folder '%1' from the wallet?", fi->name()), QString(), KStandardGuiItem::del()); if (rc == KMessageBox::Continue) { bool rc = _w->removeFolder(fi->name()); if (!rc) { KMessageBox::sorry(this, i18n("Error deleting folder.")); return; } _currentFolder.clear(); _entryTitle->clear(); _iconTitle->clear(); updateFolderList(); } } } } void KWalletEditor::createFolder() { if (_w) { QString n; bool ok; do { n = QInputDialog::getText(this, i18n("New Folder"), i18n("Please choose a name for the new folder:"), QLineEdit::Normal, QString(), &ok); if (!ok) { return; } if (_entryList->existsFolder(n)) { 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"))); if (rc == KMessageBox::Yes) { continue; } n.clear(); } break; } while (true); _w->createFolder(n); updateFolderList(); } } void KWalletEditor::saveEntry() { int rc = 1; QTreeWidgetItem *item = _displayedItem; // _entryList->currentItem(); _saveChanges->setEnabled(false); _undoChanges->setEnabled(false); _hasUnsavedChanges = false; if (item && _w && item->parent()) { KWalletContainerItem *ci = dynamic_cast(item->parent()); if (ci) { if (ci->entryType() == KWallet::Wallet::Password) { rc = _w->writePassword(item->text(0), _passwordValue->toPlainText()); } else if (ci->entryType() == KWallet::Wallet::Map) { _mapEditor->saveMap(); rc = _w->writeMap(item->text(0), _currentMap); } else { return; } if (rc == 0) { return; } } } KMessageBox::sorry(this, i18n("Error saving entry. Error code: %1", rc)); } void KWalletEditor::restoreEntry() { entrySelectionChanged(_entryList->currentItem()); _hasUnsavedChanges = false; } void KWalletEditor::entryEditted() { _saveChanges->setEnabled(true); _undoChanges->setEnabled(true); _hasUnsavedChanges = true; } void KWalletEditor::entrySelectionChanged(QTreeWidgetItem *item) { // do not forget to save changes if (_saveChanges->isEnabled() && _displayedItem && (_displayedItem != item)) { if (KMessageBox::Yes == KMessageBox::questionYesNo(this, i18n("The contents of the current item has changed.\nDo you want to save changes?"))) { saveEntry(); } else { _saveChanges->setEnabled(false); _undoChanges->setEnabled(false); _hasUnsavedChanges = false; } } KWalletContainerItem *ci = nullptr; KWalletFolderItem *fi = nullptr; // clear the context menu _contextMenu->clear(); _contextMenu->setEnabled(true); // disable the entry actions (reenable them on adding) _newEntryAction->setEnabled(false); _renameEntryAction->setEnabled(false); _deleteEntryAction->setEnabled(false); if (item) { // set the context menu's title _contextMenu->addSection(_contextMenu->fontMetrics().elidedText( item->text(0), Qt::ElideMiddle, 200)); // TODO rtti switch (item->type()) { case KWalletEntryItemClass: ci = dynamic_cast(item->parent()); if (!ci) { return; } fi = dynamic_cast(ci->parent()); if (!fi) { return; } _w->setFolder(fi->name()); _deleteFolderAction->setEnabled(false); // add standard menu items _contextMenu->addAction(_newEntryAction); _contextMenu->addAction(_renameEntryAction); _contextMenu->addAction(_deleteEntryAction); _newEntryAction->setEnabled(true); _renameEntryAction->setEnabled(true); _deleteEntryAction->setEnabled(true); if (ci->entryType() == KWallet::Wallet::Password) { QString pass; if (_w->readPassword(item->text(0), pass) == 0) { _entryStack->setCurrentIndex(4); _entryName->setText(i18n("Password: %1", item->text(0))); _passwordValue->setText(pass); _saveChanges->setEnabled(false); _undoChanges->setEnabled(false); _hasUnsavedChanges = false; } // add a context-menu action for copying passwords _contextMenu->addSeparator(); _contextMenu->addAction(_copyPassAction); if (_alwaysShowContents) { QTimer::singleShot(0, this, &KWalletEditor::showPasswordContents); } } else if (ci->entryType() == KWallet::Wallet::Map) { _entryStack->setCurrentIndex(2); if (_w->readMap(item->text(0), _currentMap) == 0) { _mapEditor->reload(); _entryName->setText(i18n("Name-Value Map: %1", item->text(0))); _saveChanges->setEnabled(false); _undoChanges->setEnabled(false); _hasUnsavedChanges = false; showHideMapEditorValue(_mapEditorShowHide->isChecked()); } } else if (ci->entryType() == KWallet::Wallet::Stream) { _entryStack->setCurrentIndex(3); QByteArray ba; if (_w->readEntry(item->text(0), ba) == 0) { _entryName->setText(i18n("Binary Data: %1", item->text(0))); _saveChanges->setEnabled(false); _undoChanges->setEnabled(false); _hasUnsavedChanges = false; _binaryView->setData(ba); } } break; case KWalletContainerItemClass: ci = dynamic_cast(item); if (!ci) { return; } if (ci->entryType() == KWallet::Wallet::Unknown) { // disable context menu on unknown items _contextMenu->setEnabled(false); } else { // add the context menu action _contextMenu->addAction(_newEntryAction); _newEntryAction->setEnabled(true); } fi = dynamic_cast(item->parent()); if (!fi) { return; } _w->setFolder(fi->name()); _deleteFolderAction->setEnabled(false); _entryName->clear(); _entryStack->setCurrentIndex(0); break; case KWalletFolderItemClass: // add the context menu actions _contextMenu->addAction(_newFolderAction); _contextMenu->addAction(_deleteFolderAction); fi = dynamic_cast(item); if (!fi) { return; } _w->setFolder(fi->name()); _deleteFolderAction->setEnabled(true); _entryName->clear(); _entryStack->setCurrentIndex(0); break; default: // all items but Unknown entries return have their // rtti set. Unknown items can only be deleted. _contextMenu->addAction(_deleteEntryAction); _deleteEntryAction->setEnabled(true); break; } } else { // no item selected. add the "new folder" action to the context menu _contextMenu->addAction(_newFolderAction); } if (fi) { _currentFolder = fi->name(); _entryTitle->setText(QStringLiteral("%1").arg(fi->text(0))); _iconTitle->setPixmap(fi->getFolderIcon(KIconLoader::Toolbar)); } _displayedItem = item; } void KWalletEditor::updateEntries(const QString &folder) { QStack trash; _w->setFolder(folder); const QStringList entries = _w->entryList(); KWalletFolderItem *fi = _entryList->getFolder(folder); if (!fi) { return; } KWalletContainerItem *pi = fi->getContainer(KWallet::Wallet::Password); KWalletContainerItem *mi = fi->getContainer(KWallet::Wallet::Map); KWalletContainerItem *bi = fi->getContainer(KWallet::Wallet::Stream); KWalletContainerItem *ui = fi->getContainer(KWallet::Wallet::Unknown); // Remove deleted entries for (int i = 0; i < pi->childCount(); ++i) { QTreeWidgetItem *twi = pi->child(i); if (!entries.contains(twi->text(0))) { if (twi == _entryList->currentItem()) { entrySelectionChanged(nullptr); } trash.push(twi); } } for (int i = 0; i < mi->childCount(); ++i) { QTreeWidgetItem *twi = mi->child(i); if (!entries.contains(twi->text(0))) { if (twi == _entryList->currentItem()) { entrySelectionChanged(nullptr); } trash.push(twi); } } for (int i = 0; i < bi->childCount(); ++i) { QTreeWidgetItem *twi = bi->child(i); if (!entries.contains(twi->text(0))) { if (twi == _entryList->currentItem()) { entrySelectionChanged(nullptr); } trash.push(twi); } } for (int i = 0; i < ui->childCount(); ++i) { QTreeWidgetItem *twi = ui->child(i); if (!entries.contains(twi->text(0))) { if (twi == _entryList->currentItem()) { entrySelectionChanged(nullptr); } trash.push(twi); } } qDeleteAll(trash); trash.clear(); // Add new entries for (QStringList::const_iterator i = entries.begin(), end = entries.end(); i != end; ++i) { if (fi->contains(*i)) { continue; } switch (_w->entryType(*i)) { case KWallet::Wallet::Password: new KWalletEntryItem(_w, pi, *i); break; case KWallet::Wallet::Stream: new KWalletEntryItem(_w, bi, *i); break; case KWallet::Wallet::Map: new KWalletEntryItem(_w, mi, *i); break; case KWallet::Wallet::Unknown: default: new QTreeWidgetItem(ui, QStringList() << *i); break; } } fi->refresh(); if (fi->name() == _currentFolder) { _entryTitle->setText(QStringLiteral("%1").arg(fi->text(0))); } if (!_entryList->currentItem()) { _entryName->clear(); _entryStack->setCurrentIndex(0); } } void KWalletEditor::listContextMenuRequested(const QPoint &pos) { if (!_contextMenu->isEnabled()) { return; } _contextMenu->popup(_entryList->mapToGlobal(pos)); } void KWalletEditor::copyPassword() { QTreeWidgetItem *item = _entryList->currentItem(); if (_w && item) { QString pass; if (_w->readPassword(item->text(0), pass) == 0) { QApplication::clipboard()->setText(pass); } } } void KWalletEditor::newEntry() { QTreeWidgetItem *item = _entryList->currentItem(); QString n; bool ok; KWalletFolderItem *fi; //set the folder where we're trying to create the new entry if (_w && item) { QTreeWidgetItem *p = item; if (p->type() == KWalletEntryItemClass) { p = item->parent(); } fi = dynamic_cast(p->parent()); if (!fi) { return; } _w->setFolder(fi->name()); } else { return; } do { n = QInputDialog::getText(this, i18n("New Entry"), i18n("Please choose a name for the new entry:"), QLineEdit::Normal, QString(), &ok); if (!ok) { return; } // FIXME: prohibits the use of the subheadings if (fi->contains(n)) { int rc = KMessageBox::questionYesNo(this, i18n("Sorry, that entry already exists. Try again?"), QString(), KGuiItem(i18n("Try Again")), KGuiItem(i18n("Do Not Try"))); if (rc == KMessageBox::Yes) { continue; } n.clear(); } break; } while (true); if (_w && item && !n.isEmpty()) { QTreeWidgetItem *p = item; if (p->type() == KWalletEntryItemClass) { p = item->parent(); } KWalletFolderItem *fi = dynamic_cast(p->parent()); if (!fi) { KMessageBox::error(this, i18n("An unexpected error occurred trying to add the new entry")); return; } _w->setFolder(fi->name()); KWalletEntryItem *ni = new KWalletEntryItem(_w, p, n); KWalletContainerItem *ci = dynamic_cast(p); if (!ci) { KMessageBox::error(this, i18n("An unexpected error occurred trying to add the new entry")); delete ni; return; } if (ci->entryType() == KWallet::Wallet::Password) { _w->writePassword(n, QString()); } else if (ci->entryType() == KWallet::Wallet::Map) { _w->writeMap(n, QMap()); } else if (ci->entryType() == KWallet::Wallet::Stream) { _w->writeEntry(n, QByteArray()); } else { abort(); } _entryList->setCurrentItem(ni); _entryList->scrollToItem(ni); fi->refresh(); _entryTitle->setText(QStringLiteral("%1").arg(fi->text(0))); } } void KWalletEditor::renameEntry() { QTreeWidgetItem *item = _entryList->currentItem(); if (_w && item) { _entryList->editItem(item, 0); } } // Only supports renaming of KWalletEntryItem derived classes. void KWalletEditor::listItemChanged(QTreeWidgetItem *item, int column) { if (item && column == 0) { KWalletEntryItem *i = dynamic_cast(item); if (!i) { return; } const QString t = item->text(0); if (t == i->name()) { return; } if (!_w || t.isEmpty()) { i->restoreName(); return; } if (_w->renameEntry(i->name(), t) == 0) { i->setName(t); KWalletContainerItem *ci = dynamic_cast(item->parent()); if (!ci) { KMessageBox::error(this, i18n("An unexpected error occurred trying to rename the entry")); return; } if (ci->entryType() == KWallet::Wallet::Password) { _entryName->setText(i18n("Password: %1", item->text(0))); } else if (ci->entryType() == KWallet::Wallet::Map) { _entryName->setText(i18n("Name-Value Map: %1", item->text(0))); } else if (ci->entryType() == KWallet::Wallet::Stream) { _entryName->setText(i18n("Binary Data: %1", item->text(0))); } } else { i->restoreName(); } } } void KWalletEditor::deleteEntry() { QTreeWidgetItem *item = _entryList->currentItem(); if (_w && item) { int rc = KMessageBox::warningContinueCancel(this, i18n("Are you sure you wish to delete the item '%1'?", item->text(0)), QString(), KStandardGuiItem::del()); if (rc == KMessageBox::Continue) { KWalletFolderItem *fi = dynamic_cast(item->parent()->parent()); if (!fi) { KMessageBox::error(this, i18n("An unexpected error occurred trying to delete the entry")); return; } _displayedItem = nullptr; _w->removeEntry(item->text(0)); delete item; entrySelectionChanged(_entryList->currentItem()); fi->refresh(); _entryTitle->setText(QStringLiteral("%1").arg(fi->text(0))); } } } void KWalletEditor::changePassword() { KWallet::Wallet::changePassword(_walletName, effectiveWinId()); } void KWalletEditor::walletOpened(bool success) { if (success) { emit enableFolderActions(true); emit enableContextFolderActions(false); emit enableWalletActions(true); updateFolderList(); _entryList->setWallet(_w); } else { if (!_newWallet) { KMessageBox::sorry(this, i18n("Unable to open the requested wallet.")); } } } void KWalletEditor::hidePasswordContents() { _entryStack->setCurrentIndex(4); } void KWalletEditor::showPasswordContents() { _entryStack->setCurrentIndex(1); } void KWalletEditor::showHideMapEditorValue(bool show) { if (show) { _mapEditor->showColumn(2); } else { _mapEditor->hideColumn(2); } } enum MergePlan { Prompt = 0, Always = 1, Never = 2, Yes = 3, No = 4 }; void KWalletEditor::importWallet() { QUrl url = QFileDialog::getOpenFileUrl(this, QString(), QUrl(), QStringLiteral("*.kwl")); if (url.isEmpty()) { return; } QTemporaryFile tmpFile; if (!tmpFile.open()) { KMessageBox::sorry(this, i18n("Unable to create temporary file for downloading '%1'.", url.toDisplayString())); return; } KIO::StoredTransferJob *job = KIO::storedGet(url); KJobWidgets::setWindow(job, this); if (!job->exec()) { KMessageBox::sorry(this, i18n("Unable to access wallet '%1'.", url.toDisplayString())); return; } tmpFile.write(job->data()); tmpFile.flush(); KWallet::Wallet *w = KWallet::Wallet::openWallet(tmpFile.fileName(), effectiveWinId(), KWallet::Wallet::Path); if (w && w->isOpen()) { MergePlan mp = Prompt; QStringList fl = w->folderList(); for (QStringList::ConstIterator f = fl.constBegin(); f != fl.constEnd(); ++f) { if (!w->setFolder(*f)) { continue; } if (!_w->hasFolder(*f)) { _w->createFolder(*f); } _w->setFolder(*f); QMap > map; QSet mergedkeys; // prevents re-merging already merged entries. int rc; rc = w->readMapList(QStringLiteral("*"), map); if (rc == 0) { QMap >::ConstIterator me; for (me = map.constBegin(); me != map.constEnd(); ++me) { bool hasEntry = _w->hasEntry(me.key()); if (hasEntry && mp == Prompt) { KBetterThanKDialogBase *bd; bd = new KBetterThanKDialogBase(this); bd->setLabel(i18n("Folder '%1' already contains an entry '%2'. Do you wish to replace it?", f->toHtmlEscaped(), me.key().toHtmlEscaped())); mp = static_cast(bd->exec()); delete bd; bool ok = false; if (mp == Always || mp == Yes) { ok = true; } if (mp == Yes || mp == No) { // reset mp mp = Prompt; } if (!ok) { continue; } } else if (hasEntry && mp == Never) { continue; } _w->writeMap(me.key(), me.value()); mergedkeys.insert(me.key()); // remember this key has been merged } } QMap pwd; rc = w->readPasswordList(QStringLiteral("*"), pwd); if (rc == 0) { QMap::ConstIterator pe; for (pe = pwd.constBegin(); pe != pwd.constEnd(); ++pe) { bool hasEntry = _w->hasEntry(pe.key()); if (hasEntry && mp == Prompt) { KBetterThanKDialogBase *bd = new KBetterThanKDialogBase(this); bd->setLabel(i18n("Folder '%1' already contains an entry '%2'. Do you wish to replace it?", f->toHtmlEscaped(), pe.key().toHtmlEscaped())); mp = static_cast(bd->exec()); delete bd; bool ok = false; if (mp == Always || mp == Yes) { ok = true; } if (mp == Yes || mp == No) { // reset mp mp = Prompt; } if (!ok) { continue; } } else if (hasEntry && mp == Never) { continue; } _w->writePassword(pe.key(), pe.value()); mergedkeys.insert(pe.key()); // remember this key has been merged } } QMap ent; rc = w->readEntryList(QStringLiteral("*"), ent); if (rc == 0) { QMap::ConstIterator ee; for (ee = ent.constBegin(); ee != ent.constEnd(); ++ee) { // prevent re-merging already merged entries. if (mergedkeys.contains(ee.key())) { continue; } bool hasEntry = _w->hasEntry(ee.key()); if (hasEntry && mp == Prompt) { KBetterThanKDialogBase *bd = new KBetterThanKDialogBase(this); bd->setLabel(i18n("Folder '%1' already contains an entry '%2'. Do you wish to replace it?", f->toHtmlEscaped(), ee.key().toHtmlEscaped())); mp = static_cast(bd->exec()); delete bd; bool ok = false; if (mp == Always || mp == Yes) { ok = true; } if (mp == Yes || mp == No) { // reset mp mp = Prompt; } if (!ok) { continue; } } else if (hasEntry && mp == Never) { continue; } _w->writeEntry(ee.key(), ee.value()); } } } } delete w; updateFolderList(true); restoreEntry(); } void KWalletEditor::importXML() { const QUrl url = QFileDialog::getOpenFileUrl(this, QString(), QUrl(), QStringLiteral("*.xml")); if (url.isEmpty()) { return; } KIO::StoredTransferJob *job = KIO::storedGet(url); KJobWidgets::setWindow(job, this); if (!job->exec()) { KMessageBox::sorry(this, i18n("Unable to access XML file '%1'.", url.toDisplayString())); return; } QDomDocument doc; if (!doc.setContent(job->data())) { KMessageBox::sorry(this, i18n("Error reading XML file '%1' for input.", url.toDisplayString())); return; } QDomElement top = doc.documentElement(); if (top.tagName().toLower() != QLatin1String("wallet")) { KMessageBox::sorry(this, i18n("Error: XML file does not contain a wallet.")); return; } QDomNode n = top.firstChild(); MergePlan mp = Prompt; while (!n.isNull()) { QDomElement e = n.toElement(); if (e.tagName().toLower() != QLatin1String("folder")) { n = n.nextSibling(); continue; } QString fname = e.attribute(QStringLiteral("name")); if (fname.isEmpty()) { n = n.nextSibling(); continue; } if (!_w->hasFolder(fname)) { _w->createFolder(fname); } _w->setFolder(fname); QDomNode enode = e.firstChild(); while (!enode.isNull()) { e = enode.toElement(); QString type = e.tagName().toLower(); QString ename = e.attribute(QStringLiteral("name")); bool hasEntry = _w->hasEntry(ename); if (hasEntry && mp == Prompt) { KBetterThanKDialogBase *bd = new KBetterThanKDialogBase(this); bd->setLabel(i18n("Folder '%1' already contains an entry '%2'. Do you wish to replace it?", fname.toHtmlEscaped(), ename.toHtmlEscaped())); mp = static_cast(bd->exec()); delete bd; bool ok = false; if (mp == Always || mp == Yes) { ok = true; } if (mp == Yes || mp == No) { // reset mp mp = Prompt; } if (!ok) { enode = enode.nextSibling(); continue; } } else if (hasEntry && mp == Never) { enode = enode.nextSibling(); continue; } if (type == QLatin1String("password")) { _w->writePassword(ename, e.text()); } else if (type == QLatin1String("stream")) { _w->writeEntry(ename, KCodecs::base64Decode(e.text().toLatin1())); } else if (type == QLatin1String("map")) { QMap map; QDomNode mapNode = e.firstChild(); while (!mapNode.isNull()) { QDomElement mape = mapNode.toElement(); if (mape.tagName().toLower() == QLatin1String("mapentry")) { map[mape.attribute(QStringLiteral("name"))] = mape.text(); } mapNode = mapNode.nextSibling(); } _w->writeMap(ename, map); } enode = enode.nextSibling(); } n = n.nextSibling(); } updateFolderList(true); restoreEntry(); } void KWalletEditor::exportXML() { QTemporaryFile tf; tf.open(); QXmlStreamWriter xml(&tf); xml.setAutoFormatting(true); xml.writeStartDocument(); const QStringList fl = _w->folderList(); xml.writeStartElement(QStringLiteral("wallet")); xml.writeAttribute(QStringLiteral("name"), _walletName); for (QStringList::const_iterator i = fl.constBegin(), flEnd(fl.constEnd()); i != flEnd; ++i) { xml.writeStartElement(QStringLiteral("folder")); xml.writeAttribute(QStringLiteral("name"), *i); _w->setFolder(*i); QStringList entries = _w->entryList(); for (QStringList::const_iterator j = entries.constBegin(), entriesEnd(entries.constEnd()); j != entriesEnd; ++j) { switch (_w->entryType(*j)) { case KWallet::Wallet::Password: { QString pass; if (_w->readPassword(*j, pass) == 0) { xml.writeStartElement(QStringLiteral("password")); xml.writeAttribute(QStringLiteral("name"), *j); xml.writeCharacters(pass); xml.writeEndElement(); } break; } case KWallet::Wallet::Stream: { QByteArray ba; if (_w->readEntry(*j, ba) == 0) { xml.writeStartElement(QStringLiteral("stream")); xml.writeAttribute(QStringLiteral("name"), *j); xml.writeCharacters(QLatin1String(KCodecs::base64Encode(ba))); xml.writeEndElement(); } break; } case KWallet::Wallet::Map: { QMap map; if (_w->readMap(*j, map) == 0) { xml.writeStartElement(QStringLiteral("map")); xml.writeAttribute(QStringLiteral("name"), *j); for (QMap::ConstIterator k = map.constBegin(), mapEnd(map.constEnd()); k != mapEnd; ++k) { xml.writeStartElement(QStringLiteral("mapentry")); xml.writeAttribute(QStringLiteral("name"), k.key()); xml.writeCharacters(k.value()); xml.writeEndElement(); } xml.writeEndElement(); } break; } case KWallet::Wallet::Unknown: default: break; } } xml.writeEndElement(); } xml.writeEndElement(); xml.writeEndDocument(); tf.flush(); QUrl url = QFileDialog::getSaveFileUrl(this, QString(), QUrl(), QStringLiteral("*.xml")); if (url.isEmpty()) { return; } // #368314: QTemporaryFiles are open in ReadWrite mode, so the QIODevice's position needs to be rewind. tf.seek(0); KIO::StoredTransferJob *putJob = KIO::storedPut(&tf, url, -1); KJobWidgets::setWindow(putJob, this); if (!putJob->exec()) { KMessageBox::sorry(this, i18n("Unable to store to '%1'.", url.toDisplayString())); } } void KWalletEditor::setNewWallet(bool x) { _newWallet = x; } void KWalletEditor::hideEvent(QHideEvent *) { emit enableContextFolderActions(false); emit enableFolderActions(false); emit enableWalletActions(false); disconnectActions(); } void KWalletEditor::showEvent(QShowEvent *) { connectActions(); emit enableContextFolderActions(true); emit enableFolderActions(true); emit enableWalletActions(true); } void KWalletEditor::onSearchTextChanged(const QString &text) { static bool treeIsExpanded = false; if (text.isEmpty()) { if (treeIsExpanded) { _entryList->setCurrentItem(nullptr); // NOTE: the 300 ms here is a value >200 ms used internally by KTreeWidgetSearchLine // TODO: replace this timer with a connection to KTreeWidgetSearchLine::searchUpdated signal introduced with KF5 QTimer::singleShot(300, _entryList, &KWalletEntryList::collapseAll); treeIsExpanded = false; } } else { if (!treeIsExpanded) { _entryList->expandAll(); treeIsExpanded = true; } // NOTE: the 300 ms here is a value >200 ms used internally by KTreeWidgetSearchLine // TODO: replace this timer with a connection to KTreeWidgetSearchLine::searchUpdated signal introduced with KF5 QTimer::singleShot(300, _entryList, &KWalletEntryList::selectFirstVisible); } // TODO: reduce timer count when KTreeWidgetSearchLine::searchUpdated signal will be there QTimer::singleShot(300, _entryList, &KWalletEntryList::refreshItemsCount); } void KWalletEditor::onAlwaysShowContents(bool checked) { _alwaysShowContents = checked; _alwaysHideContentsAction->setChecked(!_alwaysShowContents); showPasswordContents(); } void KWalletEditor::onAlwaysHideContents(bool checked) { _alwaysShowContents = !checked; _alwaysShowContentsAction->setChecked(_alwaysShowContents); if (checked) { hidePasswordContents(); } } bool KWalletEditor::hasUnsavedChanges() const { return _hasUnsavedChanges; } diff --git a/src/manager/kwalleteditor.h b/src/manager/kwalleteditor.h index 1caa59e..46df2f5 100644 --- a/src/manager/kwalleteditor.h +++ b/src/manager/kwalleteditor.h @@ -1,133 +1,133 @@ /* Copyright (C) 2003-2005 George Staikos Copyright (C) 2005 Isaac Clerencia 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. */ #ifndef KWALLETEDITOR_H #define KWALLETEDITOR_H #include "ui_walletwidget.h" -#include +#include #include #include "registercreateactionmethod.h" #include class KActionCollection; class QMenu; class QTreeWidgetItem; class QCheckBox; class KWalletEntryList; class KWMapEditor; class KTreeWidgetSearchLine; class KWalletEditor : public QWidget, public Ui::WalletWidget { Q_OBJECT public: explicit KWalletEditor(QWidget *parent, const QString &name = QString()); virtual ~KWalletEditor(); void setWallet(KWallet::Wallet *wallet, bool isPath = false); bool isOpen() const; bool hasUnsavedChanges() const; void setNewWallet(bool newWallet); protected: void hideEvent(QHideEvent *) override; void showEvent(QShowEvent *) override; public Q_SLOTS: void walletClosed(); void createFolder(); void deleteFolder(); private Q_SLOTS: void updateFolderList(bool checkEntries = false); void entrySelectionChanged(QTreeWidgetItem *item); void listItemChanged(QTreeWidgetItem *, int column); void listContextMenuRequested(const QPoint &pos); void updateEntries(const QString &folder); void newEntry(); void renameEntry(); void deleteEntry(); void entryEditted(); void restoreEntry(); void saveEntry(); void changePassword(); void walletOpened(bool success); void hidePasswordContents(); void showPasswordContents(); void showHideMapEditorValue(bool show); void exportXML(); void importXML(); void importWallet(); void copyPassword(); void onSearchTextChanged(const QString &); void onAlwaysShowContents(bool); void onAlwaysHideContents(bool); Q_SIGNALS: void enableWalletActions(bool enable); void enableFolderActions(bool enable); void enableContextFolderActions(bool enable); public: QString _walletName; private: static void createActions(KActionCollection *); void connectActions(); void disconnectActions(); KActionCollection *actionCollection(); bool _nonLocal; KWallet::Wallet *_w; KWalletEntryList *_entryList; static RegisterCreateActionsMethod _registerCreateActionMethod; static QAction *_newFolderAction, *_deleteFolderAction; static QAction *_exportAction, *_saveAsAction, *_mergeAction, *_importAction; static QAction *_newEntryAction, *_renameEntryAction, *_deleteEntryAction; static QAction *_copyPassAction; QLabel *_details; QString _currentFolder; QMap _currentMap; // save memory by storing // only the most recent map. KWMapEditor *_mapEditor; QCheckBox *_mapEditorShowHide; bool _newWallet; QMenu *_contextMenu; QTreeWidgetItem *_displayedItem; // used to find old item when selection just changed KActionCollection *_actionCollection; QMenu *_controlMenu; QMenu *_walletSubmenu; KTreeWidgetSearchLine *_searchLine; static QAction *_alwaysShowContentsAction, *_alwaysHideContentsAction; bool _alwaysShowContents; bool _hasUnsavedChanges; }; #endif diff --git a/src/manager/kwalletmanager.cpp b/src/manager/kwalletmanager.cpp index 7fc6354..577d252 100644 --- a/src/manager/kwalletmanager.cpp +++ b/src/manager/kwalletmanager.cpp @@ -1,489 +1,489 @@ /* Copyright (C) 2003,2004 George Staikos 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 "kwalletmanagerwidget.h" #include "kwalletpopup.h" #include "kwalleteditor.h" #include "allyourbase.h" #include "kwallet_interface.h" #include "registercreateactionmethod.h" #include "kwalletmanager_debug.h" #include #include #include #include #include #include #include #include -#include +#include #include #include #include #include #include #include #include #include #include #include #include KWalletManager::KWalletManager(QWidget *parent, const QString &name, Qt::WindowFlags f) : KXmlGuiWindow(parent, f) { _kwalletdLaunch = false; _shuttingDown = false; m_kwalletdModule = nullptr; setObjectName(name); RegisterCreateActionsMethod::createActions(actionCollection()); QTimer::singleShot(0, this, &KWalletManager::beginConfiguration); } void KWalletManager::beginConfiguration() { KConfig cfg(QStringLiteral("kwalletrc")); // not sure why this setting isn't in kwalletmanagerrc... KConfigGroup walletConfigGroup(&cfg, "Wallet"); if (walletConfigGroup.readEntry("Enabled", true)){ QTimer::singleShot(0, this, &KWalletManager::configUI); } else { int rc = KMessageBox::warningYesNo(this, i18n("The KDE Wallet system is not enabled. Do you want me to enable it? If not, the KWalletManager will quit as it cannot work without reading the wallets.")); if (rc == KMessageBox::Yes) { walletConfigGroup.writeEntry("Enabled", true); QTimer::singleShot(0, this, &KWalletManager::configUI); } else { QApplication::quit(); } } } void KWalletManager::configUI() { QDBusConnection::sessionBus().registerObject(QStringLiteral("/KWalletManager"), this, QDBusConnection::ExportScriptableSlots); KConfig cfg(QStringLiteral("kwalletrc")); // not sure why this setting isn't in kwalletmanagerrc... KConfigGroup walletConfigGroup(&cfg, "Wallet"); if (walletConfigGroup.readEntry("Launch Manager", false)) { _tray = new KStatusNotifierItem(this); _tray->setObjectName(QStringLiteral("kwalletmanager tray")); _tray->setCategory(KStatusNotifierItem::SystemServices); _tray->setStatus(KStatusNotifierItem::Passive); _tray->setIconByName(QStringLiteral("wallet-closed")); _tray->setToolTip(QStringLiteral("wallet-closed"), i18n("Wallet"), i18n("No wallets open.")); //connect(_tray, SIGNAL(quitSelected()), SLOT(shuttingDown())); const QStringList wl = KWallet::Wallet::walletList(); bool isOpen = false; for (QStringList::ConstIterator it = wl.begin(), end = wl.end(); it != end; ++it) { if (KWallet::Wallet::isOpen(*it)) { _tray->setIconByName(QStringLiteral("wallet-open")); _tray->setToolTip(QStringLiteral("wallet-open"), i18n("Wallet"), i18n("A wallet is open.")); isOpen = true; break; } } if (!isOpen && qApp->isSessionRestored()) { delete _tray; _tray = nullptr; QTimer::singleShot(0, qApp, SLOT(quit())); return; } } else { _tray = nullptr; } _managerWidget = new KWalletManagerWidget(this); updateWalletDisplay(); setCentralWidget(_managerWidget); setAutoSaveSettings(QStringLiteral("MainWindow"), true); QFontMetrics fm = fontMetrics(); _managerWidget->setMinimumSize(16*fm.height(), 18*fm.height()); m_kwalletdModule = new org::kde::KWallet(QStringLiteral("org.kde.kwalletd5"), QStringLiteral("/modules/kwalletd5"), QDBusConnection::sessionBus()); connect(QDBusConnection::sessionBus().interface(), &QDBusConnectionInterface::serviceOwnerChanged, this, &KWalletManager::possiblyRescan); connect(m_kwalletdModule, &OrgKdeKWalletInterface::allWalletsClosed, this, &KWalletManager::allWalletsClosed); connect(m_kwalletdModule, SIGNAL(walletClosed(QString)), this, SLOT(updateWalletDisplay())); connect(m_kwalletdModule, &OrgKdeKWalletInterface::walletOpened, this, &KWalletManager::aWalletWasOpened); connect(m_kwalletdModule, &OrgKdeKWalletInterface::walletDeleted, this, &KWalletManager::updateWalletDisplay); connect(m_kwalletdModule, &OrgKdeKWalletInterface::walletListDirty, this, &KWalletManager::updateWalletDisplay); connect(m_kwalletdModule, &OrgKdeKWalletInterface::walletCreated, this, &KWalletManager::walletCreated); // 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. QAction *action = actionCollection()->addAction(QStringLiteral("wallet_create")); action->setText(i18n("&New Wallet...")); action->setIcon(QIcon::fromTheme(QStringLiteral("kwalletmanager"))); connect(action, &QAction::triggered, this, &KWalletManager::createWallet); action = actionCollection()->addAction(QStringLiteral("wallet_delete")); action->setText(i18n("&Delete Wallet...")); action->setIcon(QIcon::fromTheme(QStringLiteral("trash-empty"))); connect(action, &QAction::triggered, this, &KWalletManager::deleteWallet); _walletsExportAction = actionCollection()->addAction(QStringLiteral("wallet_export_encrypted")); _walletsExportAction->setText(i18n("Export as encrypted")); _walletsExportAction->setIcon(QIcon::fromTheme(QStringLiteral("document-export"))); connect(_walletsExportAction, &QAction::triggered, this, &KWalletManager::exportWallets); action = actionCollection()->addAction(QStringLiteral("wallet_import_encrypted")); action->setText(i18n("&Import encrypted")); action->setIcon(QIcon::fromTheme(QStringLiteral("document-import"))); connect(action, &QAction::triggered, this, &KWalletManager::importWallets); QAction *act = actionCollection()->addAction(QStringLiteral("wallet_settings")); act->setText(i18n("Configure &Wallet...")); act->setIcon(QIcon::fromTheme(QStringLiteral("configure"))); connect(act, &QAction::triggered, this, &KWalletManager::setupWallet); if (_tray) { _tray->contextMenu()->addAction(act); } act = actionCollection()->addAction(QStringLiteral("close_all_wallets")); act->setText(i18n("Close &All Wallets")); connect(act, &QAction::triggered, this, &KWalletManager::closeAllWallets); if (_tray) { _tray->contextMenu()->addAction(act); } KStandardAction::quit(this, SLOT(shuttingDown()), actionCollection()); KStandardAction::keyBindings(guiFactory(), SLOT(configureShortcuts()), actionCollection()); setupGUI(Keys | Save | Create, QStringLiteral("kwalletmanager.rc")); setStandardToolBarMenuEnabled(false); if (_tray) { // _tray->show(); } else { show(); } _walletsExportAction->setDisabled(KWallet::Wallet::walletList().isEmpty()); qApp->setObjectName(QStringLiteral("kwallet")); // hack to fix docs } KWalletManager::~KWalletManager() { _tray = nullptr; delete m_kwalletdModule; m_kwalletdModule = nullptr; } void KWalletManager::kwalletdLaunch() { _kwalletdLaunch = true; } bool KWalletManager::queryClose() { if (hasUnsavedChanges() && !canIgnoreUnsavedChanges()) { return false; } if (!_shuttingDown) { if (!_tray) { qApp->quit(); } else { hide(); } return false; } return true; } void KWalletManager::aWalletWasOpened() { if (_tray) { _tray->setIconByName(QStringLiteral("wallet-open")); _tray->setToolTip(QStringLiteral("wallet-open"), i18n("Wallet"), i18n("A wallet is open.")); _tray->setStatus(KStatusNotifierItem::Active); } updateWalletDisplay(); createGUI(QStringLiteral("kwalletmanager.rc")); } void KWalletManager::updateWalletDisplay() { if (_walletsExportAction) { _walletsExportAction->setDisabled(KWallet::Wallet::walletList().isEmpty()); } _managerWidget->updateWalletDisplay(); } void KWalletManager::walletCreated(const QString &newWalletName) { _managerWidget->updateWalletDisplay(newWalletName); } void KWalletManager::contextMenu(const QPoint &) { } void KWalletManager::closeWallet(const QString &walletName) { if (hasUnsavedChanges(walletName) && !canIgnoreUnsavedChanges()) { return; } 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(), KGuiItem(i18n("Force Closure")), KGuiItem(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.", rc)); } } } updateWalletDisplay(); } void KWalletManager::changeWalletPassword(const QString &walletName) { KWallet::Wallet::changePassword(walletName, effectiveWinId()); } void KWalletManager::openWalletFile(const QString &path) { if (!_managerWidget->openWalletFile(path)) { KMessageBox::sorry(this, i18n("Error opening wallet %1.", path)); } } void KWalletManager::allWalletsClosed() { if (_tray) { _tray->setIconByName(QStringLiteral("wallet-closed")); _tray->setToolTip(QStringLiteral("wallet-closed"), i18n("Wallet"), i18n("No wallets open.")); _tray->setStatus(KStatusNotifierItem::Passive); } possiblyQuit(); } void KWalletManager::possiblyQuit() { KConfig _cfg(QStringLiteral("kwalletrc")); KConfigGroup cfg(&_cfg, "Wallet"); if (_windows.isEmpty() && !isVisible() && !cfg.readEntry("Leave Manager Open", false) && _kwalletdLaunch) { qApp->quit(); } } void KWalletManager::editorClosed(KXmlGuiWindow *e) { _windows.removeAll(e); } void KWalletManager::possiblyRescan(const QString &app, const QString &oldOwner, const QString &newOwner) { Q_UNUSED(oldOwner); Q_UNUSED(newOwner); if (app == QLatin1String("org.kde.kwalletd5")) { updateWalletDisplay(); } } void KWalletManager::createWallet() { QString txt = i18n("Please choose a name for the new wallet:"); QRegExpValidator validator(QRegExp(QLatin1String("^[\\w\\^\\&\\'\\@\\{\\}\\[\\]\\,\\$\\=\\!\\-\\#\\(\\)\\%\\.\\+\\_\\s]+$")), this); if (!KWallet::Wallet::isEnabled()) { // FIXME: KMessageBox::warningYesNo(this, i1_8n("KWallet is not enabled. Do you want to enable it?"), QString(), i18n("Enable"), i18n("Keep Disabled")); return; } QDialog nameDialog(this); nameDialog.setWindowTitle(i18n("New Wallet")); nameDialog.setLayout(new QVBoxLayout); nameDialog.layout()->addWidget(new QLabel(txt)); QLineEdit *lineEdit = new QLineEdit; lineEdit->setValidator(&validator); nameDialog.layout()->addWidget(lineEdit); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); connect(buttonBox, &QDialogButtonBox::accepted, &nameDialog, &QDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, &nameDialog, &QDialog::reject); nameDialog.layout()->addWidget(buttonBox); QString name; do { if (!nameDialog.exec()) { return; } name = lineEdit->text(); if (name.trimmed().isEmpty()) { KMessageBox::error(this, i18n("Empty name is not supported. Please select a new one."), i18n("Create new wallet")); return; } if (_managerWidget->hasWallet(name)) { int rc = KMessageBox::questionYesNo(this, i18n("Sorry, that wallet already exists. Try a new name?"), QString(), KGuiItem(i18n("Try New")), KGuiItem(i18n("Do Not Try"))); if (rc == KMessageBox::No) { return; } lineEdit->clear(); } else { break; } } while (true); // Small race here - the wallet could be created on us already. if (!name.isEmpty()) { // attempt open the wallet to create it, then dispose it // as it'll appear in on the main window via the walletCreated signal // emmitted by the kwalletd KWallet::Wallet::openWallet(name, effectiveWinId()); } } void KWalletManager::deleteWallet() { QString walletName = _managerWidget->activeWalletName(); if (walletName.isEmpty()) { return; } int rc = KMessageBox::warningContinueCancel(this, i18n("Are you sure you wish to delete the wallet '%1'?", walletName), QString(), KStandardGuiItem::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.", rc)); } } void KWalletManager::openWallet(const QString &walletName) { _managerWidget->openWallet(walletName); } void KWalletManager::shuttingDown() { if (hasUnsavedChanges() && !canIgnoreUnsavedChanges()) { return; } _shuttingDown = true; qApp->quit(); } void KWalletManager::setupWallet() { KToolInvocation::startServiceByDesktopName(QStringLiteral("kwalletconfig5")); } void KWalletManager::closeAllWallets() { if (hasUnsavedChanges() && !canIgnoreUnsavedChanges()) { return; } m_kwalletdModule->closeAllWallets(); } void KWalletManager::exportWallets() { const QString path = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/kwalletd/"); const QDir dir(path); dir.mkpath(path); Q_ASSERT(dir.exists()); const QStringList filesList = dir.entryList(QStringList() << QStringLiteral("*.kwl") << QStringLiteral("*.salt"), QDir::Files | QDir::Readable | QDir::NoSymLinks); Q_ASSERT(!filesList.isEmpty()); const QString destination = QFileDialog::getSaveFileName(this,i18n("File name")); if (destination.isEmpty()) { return; } KTar archive(destination); if (!archive.open(QIODevice::WriteOnly)) { KMessageBox::error(this, i18n("Failed to open file for writing")); return; } for (int i = 0; i < filesList.size(); i++) { archive.addLocalFile(path + filesList.at(i), filesList.at(i)); } } void KWalletManager::importWallets() { const QString source = QFileDialog::getOpenFileName(this, i18n("Select file")); const QString destinationDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/kwalletd/"); QDir().mkpath(destinationDir); if (source.isEmpty()) { return; } KTar archive(source); if (!archive.open(QIODevice::ReadOnly)) { KMessageBox::error(this, i18n("Failed to open file")); return; } const KArchiveDirectory *archiveDir = archive.directory(); const QStringList archiveEntries = archiveDir->entries(); for (int i = 0; i < archiveEntries.size(); i++) { if (QFile::exists(destinationDir + archiveEntries.at(i)) && archiveEntries.at(i).endsWith(QLatin1String(".kwl"))) { QString walletName = archiveEntries.at(i); // remove ".kwl" walletName.chop(4); KMessageBox::error(this, i18n("Wallet named %1 already exists, Operation aborted", walletName)); return; } } if (!archiveDir->copyTo(destinationDir, false)) { KMessageBox::error(this,i18n("Failed to copy files")); return; } } bool KWalletManager::hasUnsavedChanges(const QString &name) const { return _managerWidget->hasUnsavedChanges(name); } bool KWalletManager::canIgnoreUnsavedChanges() { int rc = KMessageBox::warningYesNo(this, i18n("Ignore unsaved changes?")); return (rc == KMessageBox::Yes); } diff --git a/src/manager/kwalletmanagerwidget.cpp b/src/manager/kwalletmanagerwidget.cpp index 28da051..435db5f 100644 --- a/src/manager/kwalletmanagerwidget.cpp +++ b/src/manager/kwalletmanagerwidget.cpp @@ -1,225 +1,225 @@ /* * This file is part of the KDE libraries * Copyright (C) 2013 Valentin Rusu * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kwalletmanagerwidget.h" #include "kwalletmanagerwidgetitem.h" #include "kwallet_interface.h" #include "kwalletmanager_debug.h" -#include +#include #include #include #include #include KWalletManagerWidget::KWalletManagerWidget(QWidget *parent, Qt::WindowFlags /*flags*/): KPageWidget(parent) { setFaceType(Auto); setAcceptDrops(true); connect(this, &KWalletManagerWidget::currentPageChanged, this, &KWalletManagerWidget::onCurrentPageChanged); } KWalletManagerWidget::~KWalletManagerWidget() { } void KWalletManagerWidget::onCurrentPageChanged(KPageWidgetItem */*current*/, KPageWidgetItem */*before*/) { } void KWalletManagerWidget::updateWalletDisplay(const QString &selectWallet /* = QString() */) { // NOTE: this method is called upon several kwalletd events static bool alreadyUpdating = false; if (alreadyUpdating) { return; } alreadyUpdating = true; // find out pages corresponding to deleted wallets const QStringList wl = KWallet::Wallet::walletList(); WalletPagesHash::iterator p = _walletPages.begin(); while (p != _walletPages.end()) { if (!wl.contains(p.key())) { // remove the page corresponding to the missing wallet removePage(p.value()); p = _walletPages.erase(p); } else { ++p; } } // add new wallets for (QStringList::const_iterator i = wl.begin(); i != wl.end(); ++i) { const QString &name = *i; if (!_walletPages.contains(name)) { KWalletManagerWidgetItem *wi = new KWalletManagerWidgetItem(this, name); addPage(wi); _walletPages.insert(*i, wi); } } // update existing wallets display, e.g. icon WalletPagesHash::const_iterator cp = _walletPages.constBegin(); WalletPagesHash::const_iterator cend = _walletPages.constEnd(); for (; cp != cend; cp++) { cp.value()->updateWalletDisplay(); } if (!selectWallet.isEmpty()) { setCurrentPage(_walletPages[selectWallet]); } alreadyUpdating = false; } bool KWalletManagerWidget::hasWallet(const QString &name) const { return _walletPages.contains(name); } bool KWalletManagerWidget::openWalletFile(const QString &/*path*/) { Q_ASSERT(0); // TODO: implement this method: add a new tab with an editor centered on a file return false; } bool KWalletManagerWidget::openWallet(const QString &name) { bool result = false; if (_walletPages.contains(name)) { KWalletManagerWidgetItem *wi = _walletPages[name]; setCurrentPage(wi); result = wi->openWallet(); } return result; } QString KWalletManagerWidget::activeWalletName() const { KWalletManagerWidgetItem *page = qobject_cast(currentPage()); if (page) { return page->walletName(); } else { return QString(); } } void KWalletManagerWidget::dragEnterEvent(QDragEnterEvent *e) { if (e->mimeData()->hasFormat(QStringLiteral("application/x-kwallet-wallet"))) { e->accept(); } else { e->ignore(); } } void KWalletManagerWidget::dragMoveEvent(QDragMoveEvent */*e*/) { qCDebug(KWALLETMANAGER_LOG) << "KWalletManagerWidget::dragMoveEvent"; // KUrl dummy; // QListWidgetItem *dummy2; // if (shouldIgnoreDropEvent(e, &dummy, &dummy2)) { // e->ignore(); // } else { // e->accept(); // } } void KWalletManagerWidget::dropEvent(QDropEvent */*e*/) { qCDebug(KWALLETMANAGER_LOG) << "KWalletManagerWidget::dropEvent"; // KUrl u; // QListWidgetItem *item; // if (shouldIgnoreDropEvent(e, &u, &item)) { // e->ignore(); // return; // } // // if (!item) { // // Not dropped over an item thus it is a wallet // const QString dest = KGlobal::dirs()->saveLocation("kwallet") + u.fileName(); // if (QFile::exists(dest)) { // KMessageBox::sorry(viewport(), i18n("That wallet file already exists. You cannot overwrite wallets.")); // e->ignore(); // return; // } // // // FIXME: verify that it is a real wallet file first // KIO::NetAccess::file_copy(u, KUrl(dest)); // e->accept(); // } else { // // Dropped over an item thus it is a folder // KWalletItem *kwi = dynamic_cast(item); // Q_ASSERT(kwi); // if (kwi) { // kwi->processDropEvent(e); // } // } } bool KWalletManagerWidget::shouldIgnoreDropEvent(const QDropEvent */*e*/, QUrl */*u*/) const { return false; // if (e->source() == viewport()) { // return true; // } // // if (!e->provides("application/x-kwallet-folder") && // !e->provides("application/x-kwallet-wallet") && // !e->provides("text/uri-list")) { // return true; // } // // // Over wallets folders, over nothing wallets // *item = itemAt(e->pos()); // const QByteArray edata = e->encodedData(item ? "application/x-kwallet-folder" : "application/x-kwallet-wallet"); // *u = decodeUrl(edata); // if (*u == KUrl()) { // *u = decodeUrl(e->encodedData("text/uri-list")); // } // // return *u == KUrl(); } bool KWalletManagerWidget::hasUnsavedChanges(const QString &name) const { if (name.isEmpty()) { WalletPagesHash::const_iterator cp = _walletPages.constBegin(); WalletPagesHash::const_iterator cend = _walletPages.constEnd(); for (; cp != cend; ++cp) { if (cp.value()->hasUnsavedChanges()) { return true; } } return false; } else { WalletPagesHash::const_iterator it = _walletPages.find(name); if (it == _walletPages.constEnd()) { return false; } return it.value()->hasUnsavedChanges(); } } diff --git a/src/manager/kwalletmanagerwidgetitem.cpp b/src/manager/kwalletmanagerwidgetitem.cpp index 7fb56a3..4d380a7 100644 --- a/src/manager/kwalletmanagerwidgetitem.cpp +++ b/src/manager/kwalletmanagerwidgetitem.cpp @@ -1,52 +1,52 @@ /* * This file is part of the KDE libraries * Copyright (C) 2013 Valentin Rusu * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kwalletmanagerwidgetitem.h" #include "walletcontrolwidget.h" -#include +#include #include KWalletManagerWidgetItem::KWalletManagerWidgetItem(QWidget *widgetParent, const QString &walletName): KPageWidgetItem(_controlWidget = new WalletControlWidget(widgetParent, walletName), walletName), _walletName(walletName) { updateWalletDisplay(); } void KWalletManagerWidgetItem::updateWalletDisplay() { if (KWallet::Wallet::isOpen(_walletName)) { setIcon(QIcon::fromTheme(QStringLiteral("wallet-open"))); } else { setIcon(QIcon::fromTheme(QStringLiteral("wallet-closed"))); } _controlWidget->updateWalletDisplay(); } bool KWalletManagerWidgetItem::openWallet() { return _controlWidget->openWallet(); } bool KWalletManagerWidgetItem::hasUnsavedChanges() const { return (_controlWidget ? _controlWidget->hasUnsavedChanges() : false); } diff --git a/src/manager/kwalletpopup.cpp b/src/manager/kwalletpopup.cpp index 8e188fe..b0503d4 100644 --- a/src/manager/kwalletpopup.cpp +++ b/src/manager/kwalletpopup.cpp @@ -1,124 +1,124 @@ /* Copyright (C) 2003 George Staikos 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 "kwalletpopup.h" #include #include #include #include #include -#include +#include KWalletPopup::KWalletPopup(const QString &wallet, QWidget *parent, const QString &name) : QMenu(parent), _walletName(wallet) { addSection(wallet); setObjectName(name); KActionCollection *ac = new KActionCollection(this/*, "kwallet context actions"*/); ac->setObjectName(QStringLiteral("kwallet context actions")); QAction *act; act = ac->addAction(QStringLiteral("wallet_create")); act->setText(i18n("&New Wallet...")); connect(act, &QAction::triggered, this, &KWalletPopup::createWallet); addAction(act); act = ac->addAction(QStringLiteral("wallet-open")); act->setText(i18n("&Open...")); connect(act, &QAction::triggered, this, &KWalletPopup::openWallet); act->setShortcut(QKeySequence(Qt::Key_Return)); addAction(act); act = ac->addAction(QStringLiteral("wallet_password")); act->setText(i18n("Change &Password...")); connect(act, &QAction::triggered, this, &KWalletPopup::changeWalletPassword); addAction(act); const QStringList ul = KWallet::Wallet::users(wallet); if (!ul.isEmpty()) { QMenu *pm = new QMenu(this); pm->setObjectName(QStringLiteral("Disconnect Apps")); int id = 7000; for (QStringList::const_iterator it = ul.begin(), end(ul.end()); it != end; ++it) { QAction *a = pm->addAction(*it, this, &KWalletPopup::disconnectApp); a->setData(*it); id++; } QAction *act = addMenu(pm); act->setText(i18n("Disconnec&t")); } act = KStandardAction::close(this, SLOT(closeWallet()), ac); ac->addAction(QStringLiteral("wallet_close"), act); // FIXME: let's track this inside the manager so we don't need a dcop // roundtrip here. act->setEnabled(KWallet::Wallet::isOpen(wallet)); addAction(act); act = ac->addAction(QStringLiteral("wallet_delete")); act->setText(i18n("&Delete")); connect(act, &QAction::triggered, this, &KWalletPopup::deleteWallet); act->setShortcut(QKeySequence(Qt::Key_Delete)); addAction(act); } KWalletPopup::~KWalletPopup() { } void KWalletPopup::openWallet() { emit walletOpened(_walletName); } void KWalletPopup::deleteWallet() { emit walletDeleted(_walletName); } void KWalletPopup::closeWallet() { emit walletClosed(_walletName); } void KWalletPopup::changeWalletPassword() { emit walletChangePassword(_walletName); } void KWalletPopup::createWallet() { emit walletCreated(); } void KWalletPopup::disconnectApp() { QAction *a = qobject_cast(sender()); Q_ASSERT(a); if (a) { KWallet::Wallet::disconnectApplication(_walletName, a->data().toString()); } } diff --git a/src/manager/kwmapeditor.cpp b/src/manager/kwmapeditor.cpp index 442950d..09bb886 100644 --- a/src/manager/kwmapeditor.cpp +++ b/src/manager/kwmapeditor.cpp @@ -1,245 +1,245 @@ /* Copyright (C) 2003,2004 George Staikos 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 "kwmapeditor.h" #include #include #include #include #include #include -#include +#include #include #include #include #include #include #include #include #include class InlineEditor : public QTextEdit { public: InlineEditor(KWMapEditor *p) : QTextEdit(), _p(p) { setAttribute(Qt::WA_DeleteOnClose); setWindowFlags(Qt::Widget | Qt::FramelessWindowHint); connect(p, &QObject::destroyed, this, &QWidget::close); } protected: void focusOutEvent(QFocusEvent *e) override { if (e->reason() == Qt::PopupFocusReason) { // TODO: It seems we only get here if we're disturbed // by our own popup. this needs some clearance though. return; } close(); } void keyPressEvent(QKeyEvent *e) override { if (e->key() == Qt::Key_Escape) { e->accept(); close(); } else { e->ignore(); QTextEdit::keyPressEvent(e); } } void contextMenuEvent(QContextMenuEvent *event) override { QMenu *menu = createStandardContextMenu(); popup = menu; popup->exec(event->globalPos()); delete popup; } QPointer _p; QPointer popup; }; class KWMapEditorDelegate : public QItemDelegate { public: KWMapEditorDelegate(KWMapEditor *parent) : QItemDelegate(parent) { } QWidget *createEditor(QWidget *parentWidget, const QStyleOptionViewItem &option, const QModelIndex &index) const override { if (index.column() != 2) { return QItemDelegate::createEditor(parentWidget, option, index); } KWMapEditor *mapEditor = static_cast(parent()); return new InlineEditor(mapEditor); } void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override { if (dynamic_cast(editor)) { KWMapEditor *mapEditor = static_cast(parent()); const QRect geo = mapEditor->visualRect(index); editor->move(mapEditor->mapToGlobal(geo.topLeft())); editor->resize(geo.width(), geo.height() * 3); } else { QItemDelegate::updateEditorGeometry(editor, option, index); } } void setEditorData(QWidget *editor, const QModelIndex &index) const override { InlineEditor *e = dynamic_cast(editor); if (e) { KWMapEditor *mapEditor = static_cast(parent()); e->setText(mapEditor->item(index.row(), index.column())->text()); } else { QItemDelegate::setEditorData(editor, index); } } void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override { InlineEditor *e = dynamic_cast(editor); if (e) { KWMapEditor *mapEditor = static_cast(parent()); mapEditor->item(index.row(), index.column())->setText(e->toPlainText()); } else { QItemDelegate::setModelData(editor, model, index); } } }; KWMapEditor::KWMapEditor(QMap &map, QWidget *parent) : QTableWidget(0, 3, parent), _map(map) { setItemDelegate(new KWMapEditorDelegate(this)); _ac = new KActionCollection(this); _copyAct = KStandardAction::copy(this, SLOT(copy()), _ac); connect(this, &KWMapEditor::itemChanged, this, &KWMapEditor::dirty); connect(this, &KWMapEditor::customContextMenuRequested, this, &KWMapEditor::contextMenu); setSelectionMode(NoSelection); setHorizontalHeaderLabels(QStringList() << QString() << i18n("Key") << i18n("Value")); setContextMenuPolicy(Qt::CustomContextMenu); reload(); } void KWMapEditor::reload() { int row = 0; while ((row = rowCount()) > _map.count()) { removeRow(row - 1); } if ((row = rowCount()) < _map.count()) { setRowCount(_map.count()); for (int x = row; x < rowCount(); ++x) { QToolButton *b = new QToolButton(this); b->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete"))); b->setToolTip(i18n("Delete Entry")); connect(b, &QToolButton::clicked, this, &KWMapEditor::erase); setCellWidget(x, 0, b); if (columnWidth(0) != b->sizeHint().width()) { setColumnWidth(0, b->sizeHint().width()); } setItem(x, 1, new QTableWidgetItem()); setItem(x, 2, new QTableWidgetItem()); } } row = 0; for (QMap::Iterator it = _map.begin(), end = _map.end(); it != end; ++it) { item(row, 1)->setText(it.key()); item(row, 2)->setText(it.value()); row++; } } KWMapEditor::~KWMapEditor() { } void KWMapEditor::erase() { const QObject *o = sender(); for (int i = 0; i < rowCount(); i++) { if (cellWidget(i, 0) == o) { removeRow(i); break; } } emit dirty(); } void KWMapEditor::saveMap() { _map.clear(); for (int i = 0; i < rowCount(); i++) { _map[item(i, 1)->text()] = item(i, 2)->text(); } } void KWMapEditor::addEntry() { int x = rowCount(); insertRow(x); QToolButton *b = new QToolButton(this); b->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete"))); b->setToolTip(i18n("Delete Entry")); connect(b, &QToolButton::clicked, this, &KWMapEditor::erase); setCellWidget(x, 0, b); setItem(x, 1, new QTableWidgetItem()); setItem(x, 2, new QTableWidgetItem()); scrollToItem(item(x, 1)); setCurrentCell(x, 1); emit dirty(); } void KWMapEditor::emitDirty() { emit dirty(); } void KWMapEditor::contextMenu(const QPoint &pos) { QTableWidgetItem *twi = itemAt(pos); _contextRow = row(twi); QMenu *m = new QMenu(this); m->addAction(i18n("&New Entry"), this, &KWMapEditor::addEntry); m->addAction(_copyAct); m->exec(mapToGlobal(pos)); delete m; } void KWMapEditor::copy() { QTableWidgetItem *twi = item(_contextRow, 2); if (twi) { QApplication::clipboard()->setText(twi->text()); } } diff --git a/src/manager/walletcontrolwidget.cpp b/src/manager/walletcontrolwidget.cpp index f59d0ab..0d70e77 100644 --- a/src/manager/walletcontrolwidget.cpp +++ b/src/manager/walletcontrolwidget.cpp @@ -1,186 +1,186 @@ /* Copyright (C) 2013 Valentin Rusu 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 "walletcontrolwidget.h" #include "kwalleteditor.h" #include "applicationsmanager.h" #include "kwalletmanager_debug.h" #include #include #include -#include +#include #include WalletControlWidget::WalletControlWidget(QWidget *parent, const QString &walletName): QWidget(parent), _walletName(walletName), _wallet(nullptr), _walletEditor(nullptr), _applicationsManager(nullptr) { setupUi(this); onSetupWidget(); QTimer::singleShot(1, this, &WalletControlWidget::onSetupWidget); } bool WalletControlWidget::openWallet() { bool result = false; if (_wallet && _wallet->isOpen()) { result = true; // already opened } else { _wallet = KWallet::Wallet::openWallet(_walletName, effectiveWinId()); result = _wallet != nullptr; onSetupWidget(); } return result; } void WalletControlWidget::onSetupWidget() { if (KWallet::Wallet::isOpen(_walletName)) { if (!_wallet) { _wallet = KWallet::Wallet::openWallet(_walletName, effectiveWinId()); if (!_wallet) { qCDebug(KWALLETMANAGER_LOG) << "Weird situation: wallet could not be opened when setting-up the widget."; } } } if (_wallet) { connect(_wallet, &KWallet::Wallet::walletClosed, this, &WalletControlWidget::onWalletClosed); _openClose->setText(i18n("&Close")); if (!_walletEditor) { _walletEditor = new KWalletEditor(_editorFrame); _editorFrameLayout->addWidget(_walletEditor); _walletEditor->setVisible(true); } _walletEditor->setWallet(_wallet); if (!_applicationsManager) { _applicationsManager = new ApplicationsManager(_applicationsFrame); _applicationsFrameLayout->addWidget(_applicationsManager); _applicationsManager->setVisible(true); } _applicationsManager->setWallet(_wallet); _changePassword->setEnabled(true); _stateLabel->setText(i18nc("the 'kdewallet' is currently open (e.g. %1 will be replaced with current wallet name)", "The '%1' wallet is currently open", _walletName)); _tabs->setTabIcon(0, QIcon::fromTheme(QLatin1String("wallet-open")).pixmap(16)); } else { _openClose->setText(i18n("&Open...")); if (_walletEditor) { _walletEditor->setVisible(false); delete _walletEditor; _walletEditor = nullptr; } if (_applicationsManager) { _applicationsManager->setVisible(false); delete _applicationsManager; _applicationsManager = nullptr; } _changePassword->setEnabled(false); _stateLabel->setText(i18n("The wallet is currently closed")); _tabs->setTabIcon(0, QIcon::fromTheme(QStringLiteral("wallet-closed")).pixmap(16)); } } void WalletControlWidget::onOpenClose() { // TODO create some fancy animation here to make _walletEditor appear or dissapear in a fancy way if (_wallet) { if (hasUnsavedChanges()) { int choice = KMessageBox::warningYesNo(this, i18n("Ignore unsaved changes?")); if (choice == KMessageBox::No) { return; } } // Wallet is open, attempt close it 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(), KGuiItem(i18n("Force Closure")), KGuiItem(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.", rc)); } else { _wallet = nullptr; } } } else { _wallet = nullptr; } } else { _wallet = KWallet::Wallet::openWallet(_walletName, window()->winId()); } onSetupWidget(); } void WalletControlWidget::onWalletClosed() { _wallet = nullptr; onSetupWidget(); } void WalletControlWidget::updateWalletDisplay() { // QList existingActions = _disconnect->actions(); // QList::const_iterator i = existingActions.constBegin(); // QList::const_iterator ie = existingActions.constEnd(); // for ( ; i != ie; i++ ) { // _disconnect->removeAction(*i); // } // } void WalletControlWidget::onDisconnectApplication() { QAction *a = qobject_cast(sender()); Q_ASSERT(a); if (a) { KWallet::Wallet::disconnectApplication(_walletName, a->data().toString()); } } void WalletControlWidget::onChangePassword() { KWallet::Wallet::changePassword(_walletName, effectiveWinId()); } bool WalletControlWidget::hasUnsavedChanges() const { return (_walletEditor ? _walletEditor->hasUnsavedChanges() : false); } void WalletControlWidget::hideEvent(QHideEvent *) { } void WalletControlWidget::showEvent(QShowEvent *) { }