kwalletmanager.cpp 16.2 KB
Newer Older
1
/*
2
    SPDX-FileCopyrightText: 2003, 2004 George Staikos <staikos@kde.org>
3

4
    SPDX-License-Identifier: GPL-2.0-or-later
5
6
7
*/

#include "kwalletmanager.h"
8
#include "kwalletmanagerwidget.h"
9
#include "kwalletpopup.h"
10
#include "kwalleteditor.h"
11
#include "allyourbase.h"
12
#include "kwallet_interface.h"
13
#include "registercreateactionmethod.h"
Laurent Montel's avatar
Laurent Montel committed
14
#include "kwalletmanager_debug.h"
15

16
#include <KLocalizedString>
Laurent Montel's avatar
Laurent Montel committed
17
#include <QAction>
18
19
20
21
#include <KConfig>
#include <KMessageBox>
#include <KStandardAction>
#include <KStatusNotifierItem>
22
#include <KWallet>
23
#include <KXMLGUIFactory>
Laurent Montel's avatar
Laurent Montel committed
24
#include <QIcon>
25
26
#include <KActionCollection>
#include <KConfigGroup>
27
#include <KTar>
28
#include <KIO/CommandLauncherJob>
Laurent Montel's avatar
Laurent Montel committed
29

30
#include <QRegExp>
31
#include <QRegExpValidator>
32
#include <QTimer>
33
#include <QFileDialog>
34
35
#include <QDialog>
#include <QLineEdit>
Teo Mrnjavac's avatar
Teo Mrnjavac committed
36

37

38
KWalletManager::KWalletManager(QWidget *parent, const QString &name, Qt::WindowFlags f)
Laurent Montel's avatar
Laurent Montel committed
39
    : KXmlGuiWindow(parent, f)
Laurent Montel's avatar
Laurent Montel committed
40
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
41
42
    _kwalletdLaunch = false;
    _shuttingDown = false;
Laurent Montel's avatar
Laurent Montel committed
43
    m_kwalletdModule = nullptr;
44
    setObjectName(name);
45
46
    RegisterCreateActionsMethod::createActions(actionCollection());

47
    QTimer::singleShot(0, this, &KWalletManager::beginConfiguration);
48
49
50
}

void KWalletManager::beginConfiguration() {
Laurent Montel's avatar
Laurent Montel committed
51
    KConfig cfg(QStringLiteral("kwalletrc"));    // not sure why this setting isn't in kwalletmanagerrc...
52
53
    KConfigGroup walletConfigGroup(&cfg, "Wallet");
    if (walletConfigGroup.readEntry("Enabled", true)){
54
        QTimer::singleShot(0, this, &KWalletManager::configUI);
55
56
57
58
59
    } 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);
60
            QTimer::singleShot(0, this, &KWalletManager::configUI);
61
62
63
64
65
66
67
        } else {
            QApplication::quit();
        }
    }
}

void KWalletManager::configUI() {
Laurent Montel's avatar
Laurent Montel committed
68
69
    QDBusConnection::sessionBus().registerObject(QStringLiteral("/KWalletManager"), this, QDBusConnection::ExportScriptableSlots);
    KConfig cfg(QStringLiteral("kwalletrc"));    // not sure why this setting isn't in kwalletmanagerrc...
Teo Mrnjavac's avatar
Teo Mrnjavac committed
70
71
72
    KConfigGroup walletConfigGroup(&cfg, "Wallet");
    if (walletConfigGroup.readEntry("Launch Manager", false)) {
        _tray = new KStatusNotifierItem(this);
Laurent Montel's avatar
Laurent Montel committed
73
        _tray->setObjectName(QStringLiteral("kwalletmanager tray"));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
74
75
        _tray->setCategory(KStatusNotifierItem::SystemServices);
        _tray->setStatus(KStatusNotifierItem::Passive);
Laurent Montel's avatar
Laurent Montel committed
76
77
        _tray->setIconByName(QStringLiteral("wallet-closed"));
        _tray->setToolTip(QStringLiteral("wallet-closed"), i18n("Wallet"), i18n("No wallets open."));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
78
79
80
        //connect(_tray, SIGNAL(quitSelected()), SLOT(shuttingDown()));
        const QStringList wl = KWallet::Wallet::walletList();
        bool isOpen = false;
Laurent Montel's avatar
Laurent Montel committed
81
        for (QStringList::ConstIterator it = wl.begin(), end = wl.end(); it != end; ++it) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
82
            if (KWallet::Wallet::isOpen(*it)) {
Laurent Montel's avatar
Laurent Montel committed
83
84
                _tray->setIconByName(QStringLiteral("wallet-open"));
                _tray->setToolTip(QStringLiteral("wallet-open"), i18n("Wallet"), i18n("A wallet is open."));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
85
86
87
88
89
90
                isOpen = true;
                break;
            }
        }
        if (!isOpen && qApp->isSessionRestored()) {
            delete _tray;
Laurent Montel's avatar
Laurent Montel committed
91
            _tray = nullptr;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
92
            QTimer::singleShot(0, qApp, SLOT(quit()));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
93
94
95
            return;
        }
    } else {
Laurent Montel's avatar
Laurent Montel committed
96
        _tray = nullptr;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
97
    }
98

99
    _managerWidget = new KWalletManagerWidget(this);
George Staikos's avatar
George Staikos committed
100

Teo Mrnjavac's avatar
Teo Mrnjavac committed
101
102
    updateWalletDisplay();
    setCentralWidget(_managerWidget);
Laurent Montel's avatar
Laurent Montel committed
103
    setAutoSaveSettings(QStringLiteral("MainWindow"), true);
104
105
    QFontMetrics fm = fontMetrics();
    _managerWidget->setMinimumSize(16*fm.height(), 18*fm.height());
106

Laurent Montel's avatar
Laurent Montel committed
107
    m_kwalletdModule = new org::kde::KWallet(QStringLiteral("org.kde.kwalletd5"), QStringLiteral("/modules/kwalletd5"), QDBusConnection::sessionBus());
Laurent Montel's avatar
Laurent Montel committed
108
109
    connect(QDBusConnection::sessionBus().interface(), &QDBusConnectionInterface::serviceOwnerChanged, this,
            &KWalletManager::possiblyRescan);
Laurent Montel's avatar
Laurent Montel committed
110
    connect(m_kwalletdModule, &OrgKdeKWalletInterface::allWalletsClosed, this, &KWalletManager::allWalletsClosed);
Teo Mrnjavac's avatar
Teo Mrnjavac committed
111
112
    connect(m_kwalletdModule, SIGNAL(walletClosed(QString)),
            this, SLOT(updateWalletDisplay()));
Laurent Montel's avatar
Laurent Montel committed
113
114
115
116
    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);
Teo Mrnjavac's avatar
Teo Mrnjavac committed
117
118
119
    // 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.
120

Laurent Montel's avatar
Laurent Montel committed
121
    QAction *action = actionCollection()->addAction(QStringLiteral("wallet_create"));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
122
    action->setText(i18n("&New Wallet..."));
Laurent Montel's avatar
Laurent Montel committed
123
    action->setIcon(QIcon::fromTheme(QStringLiteral("kwalletmanager")));
Laurent Montel's avatar
Laurent Montel committed
124
    connect(action, &QAction::triggered, this, &KWalletManager::createWallet);
125

Laurent Montel's avatar
Laurent Montel committed
126
    action = actionCollection()->addAction(QStringLiteral("wallet_delete"));
Christoph Feck's avatar
Christoph Feck committed
127
    action->setText(i18n("&Delete Wallet..."));
Laurent Montel's avatar
Laurent Montel committed
128
    action->setIcon(QIcon::fromTheme(QStringLiteral("trash-empty")));
Laurent Montel's avatar
Laurent Montel committed
129
    connect(action, &QAction::triggered, this, &KWalletManager::deleteWallet);
130

Laurent Montel's avatar
Laurent Montel committed
131
    _walletsExportAction = actionCollection()->addAction(QStringLiteral("wallet_export_encrypted"));
132
    _walletsExportAction->setText(i18n("Export as encrypted"));
Laurent Montel's avatar
Laurent Montel committed
133
    _walletsExportAction->setIcon(QIcon::fromTheme(QStringLiteral("document-export")));
134
    connect(_walletsExportAction, &QAction::triggered, this, &KWalletManager::exportWallets);
135

Laurent Montel's avatar
Laurent Montel committed
136
    action = actionCollection()->addAction(QStringLiteral("wallet_import_encrypted"));
137
    action->setText(i18n("&Import encrypted"));
Laurent Montel's avatar
Laurent Montel committed
138
    action->setIcon(QIcon::fromTheme(QStringLiteral("document-import")));
139
    connect(action, &QAction::triggered, this, &KWalletManager::importWallets);
140

Laurent Montel's avatar
Laurent Montel committed
141
    QAction *act = actionCollection()->addAction(QStringLiteral("wallet_settings"));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
142
    act->setText(i18n("Configure &Wallet..."));
Laurent Montel's avatar
Laurent Montel committed
143
    act->setIcon(QIcon::fromTheme(QStringLiteral("configure")));
144

Laurent Montel's avatar
Laurent Montel committed
145
    connect(act, &QAction::triggered, this, &KWalletManager::setupWallet);
Teo Mrnjavac's avatar
Teo Mrnjavac committed
146
    if (_tray) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
147
        _tray->contextMenu()->addAction(act);
Teo Mrnjavac's avatar
Teo Mrnjavac committed
148
    }
Laurent Montel's avatar
Laurent Montel committed
149
    act = actionCollection()->addAction(QStringLiteral("close_all_wallets"));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
150
    act->setText(i18n("Close &All Wallets"));
Laurent Montel's avatar
Laurent Montel committed
151
    connect(act, &QAction::triggered, this, &KWalletManager::closeAllWallets);
Teo Mrnjavac's avatar
Teo Mrnjavac committed
152
    if (_tray) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
153
        _tray->contextMenu()->addAction(act);
Teo Mrnjavac's avatar
Teo Mrnjavac committed
154
155
156
    }
    KStandardAction::quit(this, SLOT(shuttingDown()), actionCollection());
    KStandardAction::keyBindings(guiFactory(), SLOT(configureShortcuts()),
Teo Mrnjavac's avatar
Teo Mrnjavac committed
157
                                 actionCollection());
158

Laurent Montel's avatar
Laurent Montel committed
159
    setupGUI(Keys | Save | Create, QStringLiteral("kwalletmanager.rc"));
160
    setStandardToolBarMenuEnabled(false);
161

Teo Mrnjavac's avatar
Teo Mrnjavac committed
162
163
164
165
166
    if (_tray) {
//        _tray->show();
    } else {
        show();
    }
167

168
    _walletsExportAction->setDisabled(KWallet::Wallet::walletList().isEmpty());
Laurent Montel's avatar
Laurent Montel committed
169
    qApp->setObjectName(QStringLiteral("kwallet"));   // hack to fix docs
170
}
171

Teo Mrnjavac's avatar
Teo Mrnjavac committed
172
173
KWalletManager::~KWalletManager()
{
Laurent Montel's avatar
Laurent Montel committed
174
    _tray = nullptr;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
175
    delete m_kwalletdModule;
Laurent Montel's avatar
Laurent Montel committed
176
    m_kwalletdModule = nullptr;
177
}
178

Teo Mrnjavac's avatar
Teo Mrnjavac committed
179
180
void KWalletManager::kwalletdLaunch()
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
181
    _kwalletdLaunch = true;
182
183
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
184
185
bool KWalletManager::queryClose()
{
186
187
188
189
    if (hasUnsavedChanges() && !canIgnoreUnsavedChanges()) {
        return false;
    }

Teo Mrnjavac's avatar
Teo Mrnjavac committed
190
    if (!_shuttingDown) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
191
192
193
194
195
196
197
198
        if (!_tray) {
            qApp->quit();
        } else {
            hide();
        }
        return false;
    }
    return true;
199
200
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
201
202
void KWalletManager::aWalletWasOpened()
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
203
    if (_tray) {
Laurent Montel's avatar
Laurent Montel committed
204
205
        _tray->setIconByName(QStringLiteral("wallet-open"));
        _tray->setToolTip(QStringLiteral("wallet-open"), i18n("Wallet"), i18n("A wallet is open."));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
206
207
208
        _tray->setStatus(KStatusNotifierItem::Active);
    }
    updateWalletDisplay();
Laurent Montel's avatar
Laurent Montel committed
209
    createGUI(QStringLiteral("kwalletmanager.rc"));
210
211
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
212
213
void KWalletManager::updateWalletDisplay()
{
214
215
216
    if (_walletsExportAction) {
        _walletsExportAction->setDisabled(KWallet::Wallet::walletList().isEmpty());
    }
217
    _managerWidget->updateWalletDisplay();
218
219
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
220
void KWalletManager::walletCreated(const QString &newWalletName)
221
222
{
    _managerWidget->updateWalletDisplay(newWalletName);
223
224
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
225
void KWalletManager::contextMenu(const QPoint &)
226
{
227
228
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
229
230
void KWalletManager::closeWallet(const QString &walletName)
{
231
232
233
234
    if (hasUnsavedChanges(walletName) && !canIgnoreUnsavedChanges()) {
        return;
    }

Teo Mrnjavac's avatar
Teo Mrnjavac committed
235
236
237
238
239
240
241
242
243
244
    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));
            }
        }
    }
245

Teo Mrnjavac's avatar
Teo Mrnjavac committed
246
    updateWalletDisplay();
247
248
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
249
250
251
void KWalletManager::changeWalletPassword(const QString &walletName)
{
    KWallet::Wallet::changePassword(walletName, effectiveWinId());
George Staikos's avatar
George Staikos committed
252
253
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
254
255
void KWalletManager::openWalletFile(const QString &path)
{
256
    if (!_managerWidget->openWalletFile(path)) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
257
258
        KMessageBox::sorry(this, i18n("Error opening wallet %1.", path));
    }
259
260
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
261
262
void KWalletManager::allWalletsClosed()
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
263
    if (_tray) {
Laurent Montel's avatar
Laurent Montel committed
264
265
        _tray->setIconByName(QStringLiteral("wallet-closed"));
        _tray->setToolTip(QStringLiteral("wallet-closed"), i18n("Wallet"), i18n("No wallets open."));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
266
267
268
        _tray->setStatus(KStatusNotifierItem::Passive);
    }
    possiblyQuit();
269
270
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
271
272
void KWalletManager::possiblyQuit()
{
Laurent Montel's avatar
Laurent Montel committed
273
    KConfig _cfg(QStringLiteral("kwalletrc"));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
274
275
276
277
278
279
280
    KConfigGroup cfg(&_cfg, "Wallet");
    if (_windows.isEmpty() &&
            !isVisible() &&
            !cfg.readEntry("Leave Manager Open", false) &&
            _kwalletdLaunch) {
        qApp->quit();
    }
281
282
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
283
284
void KWalletManager::editorClosed(KXmlGuiWindow *e)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
285
    _windows.removeAll(e);
286
}
287

Teo Mrnjavac's avatar
Teo Mrnjavac committed
288
289
290
291
void KWalletManager::possiblyRescan(const QString &app, const QString &oldOwner, const QString &newOwner)
{
    Q_UNUSED(oldOwner);
    Q_UNUSED(newOwner);
Lukáš Tinkl's avatar
Lukáš Tinkl committed
292
    if (app == QLatin1String("org.kde.kwalletd5")) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
293
294
        updateWalletDisplay();
    }
295
296
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
297
298
void KWalletManager::createWallet()
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
299
    QString txt = i18n("Please choose a name for the new wallet:");
Teo Mrnjavac's avatar
Teo Mrnjavac committed
300
    QRegExpValidator validator(QRegExp(QLatin1String("^[\\w\\^\\&\\'\\@\\{\\}\\[\\]\\,\\$\\=\\!\\-\\#\\(\\)\\%\\.\\+\\_\\s]+$")), this);
301

Teo Mrnjavac's avatar
Teo Mrnjavac committed
302
303
304
305
    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;
    }
306

307
308
309
310
311
312
313
314
315
316
317
318
319
320
    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;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
321
    do {
322
323
324
        if (!nameDialog.exec()) {
            return;
        }
Teo Mrnjavac's avatar
Teo Mrnjavac committed
325

326
        name = lineEdit->text();
Laurent Montel's avatar
Laurent Montel committed
327
        if (name.trimmed().isEmpty()) {
328
            KMessageBox::error(this, i18n("Empty name is not supported. Please select a new one."), i18n("Create new wallet"));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
329
330
331
            return;
        }

332
        if (_managerWidget->hasWallet(name)) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
333
334
335
336
            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;
            }
337
            lineEdit->clear();
Teo Mrnjavac's avatar
Teo Mrnjavac committed
338
339
340
341
342
343
        } else  {
            break;
        }
    } while (true);

    // Small race here - the wallet could be created on us already.
344
    if (!name.isEmpty()) {
345
346
347
        // 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
348
        KWallet::Wallet::openWallet(name, effectiveWinId());
Teo Mrnjavac's avatar
Teo Mrnjavac committed
349
    }
350
351
}

352
353
354
void KWalletManager::deleteWallet()
{
    QString walletName = _managerWidget->activeWalletName();
355
356
357
    if (walletName.isEmpty()) {
        return;
    }
Teo Mrnjavac's avatar
Teo Mrnjavac committed
358
    int rc = KMessageBox::warningContinueCancel(this, i18n("Are you sure you wish to delete the wallet '%1'?", walletName), QString(), KStandardGuiItem::del());
359
360
361
362
363
364
365
366
367
    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));
    }
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
368
void KWalletManager::openWallet(const QString &walletName)
369
{
370
    _managerWidget->openWallet(walletName);
371
372
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
373
374
void KWalletManager::shuttingDown()
{
375
376
377
378
    if (hasUnsavedChanges() && !canIgnoreUnsavedChanges()) {
        return;
    }

Teo Mrnjavac's avatar
Teo Mrnjavac committed
379
380
    _shuttingDown = true;
    qApp->quit();
381
}
382

Teo Mrnjavac's avatar
Teo Mrnjavac committed
383
384
void KWalletManager::setupWallet()
{
385
386
    auto *job = new KIO::CommandLauncherJob(QStringLiteral("kcmshell5"), {QStringLiteral("kwalletconfig5")});
    job->start();
387
}
388

Teo Mrnjavac's avatar
Teo Mrnjavac committed
389
390
void KWalletManager::closeAllWallets()
{
391
392
393
394
395
    if (hasUnsavedChanges() && !canIgnoreUnsavedChanges()) {
        return;

    }

396
    m_kwalletdModule->closeAllWallets();
397
}
398

399
400
void KWalletManager::exportWallets()
{
401
    const QString path = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/kwalletd/");
402
    const QDir dir(path);
403
    dir.mkpath(path);
404

405
406
    Q_ASSERT(dir.exists());

Laurent Montel's avatar
Laurent Montel committed
407
    const QStringList filesList = dir.entryList(QStringList() << QStringLiteral("*.kwl") << QStringLiteral("*.salt"),
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
                                                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));
    }
George Staikos's avatar
George Staikos committed
426
427
}

428
429
void KWalletManager::importWallets()
{
Lukáš Tinkl's avatar
Lukáš Tinkl committed
430
    const QString source = QFileDialog::getOpenFileName(this, i18n("Select file"));
431
    const QString destinationDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/kwalletd/");
432
    QDir().mkpath(destinationDir);
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448

    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))
Laurent Montel's avatar
Laurent Montel committed
449
                && archiveEntries.at(i).endsWith(QLatin1String(".kwl"))) {
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
            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;
    }

}

466
467
468
469
bool KWalletManager::hasUnsavedChanges(const QString &name) const
{
    return _managerWidget->hasUnsavedChanges(name);
}
Laurent Montel's avatar
Laurent Montel committed
470

471
472
473
474
475
bool KWalletManager::canIgnoreUnsavedChanges()
{
    int rc = KMessageBox::warningYesNo(this, i18n("Ignore unsaved changes?"));
    return (rc == KMessageBox::Yes);
}