allyourbase.cpp 19.4 KB
Newer Older
1
/*
2
3
    SPDX-FileCopyrightText: 2003-2005 George Staikos <staikos@kde.org>
    SPDX-FileCopyrightText: 2005 Isaac Clerencia <isaac@warp.es>
4

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

#include "allyourbase.h"
Laurent Montel's avatar
Laurent Montel committed
9
#include "kwalletmanager_debug.h"
10

11
#include <KJobWidgets>
12
#include <KLocalizedString>
13
#include <KIO/StoredTransferJob>
14
#include <KMessageBox>
Laurent Montel's avatar
Laurent Montel committed
15
#include <QUrl>
16

17
#include <QApplication>
Teo Mrnjavac's avatar
Teo Mrnjavac committed
18
#include <QDebug>
19
#include <QDrag>
20
#include <QMimeData>
Laurent Montel's avatar
Laurent Montel committed
21
#include <QIcon>
22

23
24
25
/****************
 *  KWalletFolderItem - ListView items to represent kwallet folders
 */
Teo Mrnjavac's avatar
Teo Mrnjavac committed
26
27
28
KWalletFolderItem::KWalletFolderItem(KWallet::Wallet *w, QTreeWidget *parent, const QString &name, int entries)
    : QTreeWidgetItem(parent, KWalletFolderItemClass), _wallet(w), _name(name), _entries(entries)
{
Laurent Montel's avatar
Laurent Montel committed
29
    setText(0, QStringLiteral("%1 (%2)").arg(_name).arg(_entries));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
30
    setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEnabled);
31
    setIcon(0, getFolderIcon());
32
33
}

34
QIcon KWalletFolderItem::getFolderIcon()
Teo Mrnjavac's avatar
Teo Mrnjavac committed
35
{
Nicolas Fella's avatar
Nicolas Fella committed
36
    return QIcon::fromTheme(_name, QIcon::fromTheme(_name.toLower(), QIcon::fromTheme(QStringLiteral("folder"))));
37
38
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
39
40
void KWalletFolderItem::refresh()
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
41
42
    const QString saveFolder = _wallet->currentFolder();
    _wallet->setFolder(_name);
Laurent Montel's avatar
Laurent Montel committed
43
    setText(0, QStringLiteral("%1 (%2)").arg(_name).arg(_wallet->entryList().count()));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
44
    _wallet->setFolder(saveFolder);
45
46
}

47
48
void KWalletFolderItem::refreshItemsCount()
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
49
50
51
    int visibleLeafCount = 0;
    for (int i = 0; i < childCount(); i++) {
        QTreeWidgetItem *wi = child(i);
52
        if (wi->childCount()) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
53
54
55
            for (int l = 0; l < wi->childCount(); l++) {
                QTreeWidgetItem *li = wi->child(l);
                if (!li->isHidden()) {
56
                    visibleLeafCount++;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
57
                }
58
59
60
            }
        }
    }
Laurent Montel's avatar
Laurent Montel committed
61
    setText(0, QStringLiteral("%1 (%2)").arg(_name).arg(visibleLeafCount));
62
63
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
64
65
KWalletContainerItem *KWalletFolderItem::getContainer(KWallet::Wallet::EntryType type)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
66
67
68
69
70
71
72
73
74
    for (int i = 0; i < childCount(); ++i) {
        KWalletContainerItem *ci = dynamic_cast<KWalletContainerItem *>(child(i));
        if (!ci) {
            continue;
        }
        if (ci->entryType() == type) {
            return ci;
        }
    }
Laurent Montel's avatar
Laurent Montel committed
75
    return nullptr;
76
77
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
78
79
bool KWalletFolderItem::contains(const QString &key)
{
Laurent Montel's avatar
Laurent Montel committed
80
    return (getItem(key) != nullptr);
81
82
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
83
84
QTreeWidgetItem *KWalletFolderItem::getItem(const QString &key)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
85
86
87
88
89
90
91
92
93
94
    for (int i = 0; i < childCount(); ++i) {
        KWalletContainerItem *ci = dynamic_cast<KWalletContainerItem *>(child(i));
        if (!ci) {
            continue;
        }
        QTreeWidgetItem *tmp = ci->getItem(key);
        if (tmp) {
            return tmp;
        }
    }
Laurent Montel's avatar
Laurent Montel committed
95
    return nullptr;
96
97
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
98
99
bool KWalletFolderItem::acceptDrop(const QMimeData *mime) const
{
Laurent Montel's avatar
Laurent Montel committed
100
101
    return mime->hasFormat(QStringLiteral("application/x-kwallet-entry")) ||
           mime->hasFormat(QStringLiteral("text/uri-list"));
102
103
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
104
105
QString KWalletFolderItem::name() const
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
106
    return _name;
107
108
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
109
110
KWalletFolderItem::~KWalletFolderItem()
{
111
112
113
114
115
116
}

/****************
 *  KWalletContainerItem - ListView items to represent kwallet containers, i.e.
 *  passwords, maps, ...
 */
Teo Mrnjavac's avatar
Teo Mrnjavac committed
117
118
119
KWalletContainerItem::KWalletContainerItem(QTreeWidgetItem *parent, const QString &name, KWallet::Wallet::EntryType entryType)
    : QTreeWidgetItem(parent, QStringList() << name, KWalletContainerItemClass), _type(entryType)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
120
    setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled);
121
122
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
123
124
KWalletContainerItem::~KWalletContainerItem()
{
125
126
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
127
128
KWallet::Wallet::EntryType KWalletContainerItem::entryType()
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
129
    return _type;
130
131
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
132
133
bool KWalletContainerItem::contains(const QString &key)
{
Laurent Montel's avatar
Laurent Montel committed
134
    return getItem(key) != nullptr;
135
136
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
137
138
QTreeWidgetItem *KWalletContainerItem::getItem(const QString &key)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
139
    for (int i = 0; i < childCount(); ++i) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
140
        KWalletEntryItem *entryItem = dynamic_cast<KWalletEntryItem *>(child(i));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
141
142
143
144
        if (entryItem && entryItem->name() == key) {
            return entryItem;
        }
    }
Laurent Montel's avatar
Laurent Montel committed
145
    return nullptr;
146
}
147

George Staikos's avatar
George Staikos committed
148
149
150
/****************
 *  KWalletEntryItem - ListView items to represent kwallet entries
 */
Teo Mrnjavac's avatar
Teo Mrnjavac committed
151
152
153
KWalletEntryItem::KWalletEntryItem(KWallet::Wallet *w, QTreeWidgetItem *parent, const QString &ename)
    : QTreeWidgetItem(parent, QStringList() << ename, KWalletEntryItemClass), _wallet(w), m_name(ename)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
154
    setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled);
155
156
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
157
158
KWalletEntryItem::~KWalletEntryItem()
{
159
}
160

Teo Mrnjavac's avatar
Teo Mrnjavac committed
161
void KWalletEntryItem::setName(const QString &n)
162
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
163
164
    m_name = n;
    QTreeWidgetItem::setText(0, n);
165
166
167
168
}

void KWalletEntryItem::restoreName()
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
169
    QTreeWidgetItem::setText(0, m_name);
170
171
}

George Staikos's avatar
George Staikos committed
172
/****************
173
 * KWalletItem - IconView items to represent wallets
George Staikos's avatar
George Staikos committed
174
 */
Teo Mrnjavac's avatar
Teo Mrnjavac committed
175
KWalletItem::KWalletItem(QListWidget *parent, const QString &walletName)
Laurent Montel's avatar
Laurent Montel committed
176
    : QListWidgetItem(QIcon::fromTheme(QStringLiteral("wallet-closed")), walletName, parent), _open(false)
Teo Mrnjavac's avatar
Teo Mrnjavac committed
177
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
178
    setFlags(flags() | Qt::ItemIsDropEnabled);
179
180
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
181
182
KWalletItem::~KWalletItem()
{
183
184
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
185
186
void KWalletItem::setOpen(bool state)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
187
188
189
    if (_open != state) {
        _open = state;
        if (_open) {
Laurent Montel's avatar
Laurent Montel committed
190
            setIcon(QIcon::fromTheme(QStringLiteral("wallet-open")));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
191
        } else {
Laurent Montel's avatar
Laurent Montel committed
192
            setIcon(QIcon::fromTheme(QStringLiteral("wallet-closed")));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
193
194
        }
    }
195
196
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
197
198
static bool decodeEntry(KWallet::Wallet *_wallet, QDataStream &ds)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
199
200
201
    quint32 magic;
    ds >> magic;
    if (magic != KWALLETENTRYMAGIC) {
Laurent Montel's avatar
Laurent Montel committed
202
        qCDebug(KWALLETMANAGER_LOG) << "bad magic" ;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
203
204
205
206
207
208
209
        return false;
    }
    QString name;
    QByteArray value;
    KWallet::Wallet::EntryType et;
    ds >> name;
    if (_wallet->hasEntry(name)) {
Laurent Montel's avatar
Laurent Montel committed
210
        int rc = KMessageBox::warningContinueCancel(nullptr, i18n("An entry by the name '%1' already exists. Would you like to continue?", name));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
211
212
213
214
215
216
217
218
219
220
        if (rc == KMessageBox::Cancel) {
            return false;
        }
    }
    qint32 l;
    ds >> l;
    et = KWallet::Wallet::EntryType(l);
    ds >> value;
    _wallet->writeEntry(name, value, et);
    return true;
221
222
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
223
224
static bool decodeFolder(KWallet::Wallet *_wallet, QDataStream &ds)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
225
226
227
    quint32 magic;
    ds >> magic;
    if (magic != KWALLETFOLDERMAGIC) {
Laurent Montel's avatar
Laurent Montel committed
228
        qCDebug(KWALLETMANAGER_LOG) << "bad magic" ;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
229
230
231
232
233
        return false;
    }
    QString folder;
    ds >> folder;
    if (_wallet->hasFolder(folder)) {
Laurent Montel's avatar
Laurent Montel committed
234
        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")));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
        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;
259
260
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
261
262
void KWalletItem::processDropEvent(QDropEvent *e)
{
263
264
265
266
267
268
269
270
271
272
273
    // 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<KWalletEntryList *>(e->source()->parent());
    }

Laurent Montel's avatar
Laurent Montel committed
274
275
    if (e->mimeData()->hasFormat(QStringLiteral("application/x-kwallet-folder")) ||
            e->mimeData()->hasFormat(QStringLiteral("text/uri-list"))) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
276
277
278
279
280
281
        // 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;
        }
282

Teo Mrnjavac's avatar
Teo Mrnjavac committed
283
        const QString saveFolder = _wallet->currentFolder();
284

285
        QByteArray data;
286

Laurent Montel's avatar
Laurent Montel committed
287
288
        if (e->mimeData()->hasFormat(QStringLiteral("application/x-kwallet-folder"))) {
            data = e->mimeData()->data(QStringLiteral("application/x-kwallet-folder"));
289
            e->accept();
Teo Mrnjavac's avatar
Teo Mrnjavac committed
290
291
292
293
294
295
296
        } else { // text/uri-list
            const QList<QUrl> urls = e->mimeData()->urls();
            if (urls.isEmpty()) {
                e->ignore();
                return;
            }

Laurent Montel's avatar
Laurent Montel committed
297
            QUrl u(urls.first());
Teo Mrnjavac's avatar
Teo Mrnjavac committed
298
299
300
301
            if (u.fileName().isEmpty()) {
                e->ignore();
                return;
            }
302
303
304
305
306
307
            KIO::StoredTransferJob *job = KIO::storedGet(u);
            KJobWidgets::setWindow(job, listWidget());

            e->accept();
            if (job->exec()) {
                data = job->data();
Teo Mrnjavac's avatar
Teo Mrnjavac committed
308
            } else {
309
                KMessageBox::error(listWidget(), job->errorString());
Teo Mrnjavac's avatar
Teo Mrnjavac committed
310
311
            }
        }
312
313
314
315

        if (!data.isEmpty()) {
            QDataStream ds(data);
            decodeFolder(_wallet, ds);
Teo Mrnjavac's avatar
Teo Mrnjavac committed
316
        }
317

Teo Mrnjavac's avatar
Teo Mrnjavac committed
318
319
320
321
        _wallet->setFolder(saveFolder);
        delete _wallet;

        //delete the folder from the source if we were moving
322
323
324
325
326
        if (el) {
            KWalletFolderItem *fi =
                dynamic_cast<KWalletFolderItem *>(el->currentItem());
            if (fi) {
                el->_wallet->removeFolder(fi->name());
Teo Mrnjavac's avatar
Teo Mrnjavac committed
327
328
329
330
331
332
            }
        }
    } else {
        e->ignore();
        return;
    }
333
}
334

335
336
337
/****************
 *  KWalletEntryList - A listview to store wallet entries
 */
Laurent Montel's avatar
Laurent Montel committed
338
KWalletEntryList::KWalletEntryList(QWidget *parent, const QString &name)
Teo Mrnjavac's avatar
Teo Mrnjavac committed
339
    : QTreeWidget(parent),
Laurent Montel's avatar
Laurent Montel committed
340
      _wallet(nullptr)
Teo Mrnjavac's avatar
Teo Mrnjavac committed
341
{
Laurent Montel's avatar
Laurent Montel committed
342
    setObjectName(name);
Teo Mrnjavac's avatar
Teo Mrnjavac committed
343
344
345
346
347
348
    setColumnCount(1);
    setHeaderLabel(i18n("Folders"));
    setRootIsDecorated(true);
    setDragEnabled(true);
    setAcceptDrops(true);
    setDragDropMode(DragDrop);
349
    setSelectionMode(SingleSelection);
George Staikos's avatar
George Staikos committed
350
351
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
352
353
KWalletEntryList::~KWalletEntryList()
{
George Staikos's avatar
George Staikos committed
354
355
}

356
//returns true if the item has been dropped successfully
Teo Mrnjavac's avatar
Teo Mrnjavac committed
357
358
void KWalletEntryList::itemDropped(QDropEvent *e, QTreeWidgetItem *item)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
359
360
    bool ok = true;
    bool isEntry;
361
    QByteArray data;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
362

Laurent Montel's avatar
Laurent Montel committed
363
364
    KWalletEntryList *el = nullptr;
    QTreeWidgetItem *sel = nullptr;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
365

366
367
368
369
370
371
372
373
    // 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;
    }

Teo Mrnjavac's avatar
Teo Mrnjavac committed
374
    //detect if we are dragging from kwallet itself
Laurent Montel's avatar
Laurent Montel committed
375
    qCDebug(KWALLETMANAGER_LOG) << e->source() << e->source()->metaObject()->className();
Teo Mrnjavac's avatar
Teo Mrnjavac committed
376
377
    if (e->source() && !strcmp(e->source()->metaObject()->className(), "KWalletEntryList")) {

Teo Mrnjavac's avatar
Teo Mrnjavac committed
378
        el = dynamic_cast<KWalletEntryList *>(e->source());
Teo Mrnjavac's avatar
Teo Mrnjavac committed
379
380
        if (!el) {
            KMessageBox::error(this, i18n("An unexpected error occurred trying to drop the item"));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
381
        } else {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
382
            sel = el->currentItem();
Teo Mrnjavac's avatar
Teo Mrnjavac committed
383
        }
Teo Mrnjavac's avatar
Teo Mrnjavac committed
384
    }
George Staikos's avatar
George Staikos committed
385

Laurent Montel's avatar
Laurent Montel committed
386
    if (e->mimeData()->hasFormat(QStringLiteral("application/x-kwallet-entry"))) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
387
388
389
390
391
392
393
        //do nothing if we are in the same folder
        if (sel && sel->parent()->parent() ==
                KWalletEntryList::getItemFolder(item)) {
            e->ignore();
            return;
        }
        isEntry = true;
Laurent Montel's avatar
Laurent Montel committed
394
        data = e->mimeData()->data(QStringLiteral("application/x-kwallet-entry"));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
395
396
397
398
        if (data.isEmpty()) {
            e->ignore();
            return;
        }
399
        e->accept();
Laurent Montel's avatar
Laurent Montel committed
400
    } else if (e->mimeData()->hasFormat(QStringLiteral("application/x-kwallet-folder"))) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
401
402
403
404
405
406
        //do nothing if we are in the same wallet
        if (this == el) {
            e->ignore();
            return;
        }
        isEntry = false;
Laurent Montel's avatar
Laurent Montel committed
407
        data = e->mimeData()->data(QStringLiteral("application/x-kwallet-folder"));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
408
409
410
411
        if (data.isEmpty()) {
            e->ignore();
            return;
        }
412
        e->accept();
Laurent Montel's avatar
Laurent Montel committed
413
    } else if (e->mimeData()->hasFormat(QStringLiteral("text/uri-list"))) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
414
415
416
417
418
        const QList<QUrl> urls = e->mimeData()->urls();
        if (urls.isEmpty()) {
            e->ignore();
            return;
        }
Laurent Montel's avatar
Laurent Montel committed
419
        QUrl u(urls.first());
Teo Mrnjavac's avatar
Teo Mrnjavac committed
420
421
422
423
        if (u.fileName().isEmpty()) {
            e->ignore();
            return;
        }
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441

        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;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
442
        } else {
Laurent Montel's avatar
Laurent Montel committed
443
            qCDebug(KWALLETMANAGER_LOG) << "bad magic" ;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
444
445
446
447
448
449
            return;
        }
    } else {
        e->ignore();
        return;
    }
450
451
452

    QDataStream ds(data);

Teo Mrnjavac's avatar
Teo Mrnjavac committed
453
454
455
456
457
458
459
460
    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());
461
        ok = decodeEntry(_wallet, ds);
Teo Mrnjavac's avatar
Teo Mrnjavac committed
462
463
464
465
        _wallet->setFolder(saveFolder);
        fi->refresh();
        //delete source if we were moving, i.e., we are dragging
        //from kwalletmanager and Control is not pressed
466
        if (ok && el && proposedAction != Qt::CopyAction && sel) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
467
468
469
470
            el->_wallet->removeEntry(sel->text(0));
            delete sel;
        }
    } else {
471
        ok = decodeFolder(_wallet, ds);
Teo Mrnjavac's avatar
Teo Mrnjavac committed
472
473
        //delete source if we were moving, i.e., we are dragging
        //from kwalletmanager and Control is not pressed
474
        if (ok && el && proposedAction != Qt::CopyAction && sel) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
475
476
477
478
479
480
481
482
483
            KWalletFolderItem *fi = dynamic_cast<KWalletFolderItem *>(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"));
            }
        }
    }
484
485
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
486
487
void KWalletEntryList::setWallet(KWallet::Wallet *w)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
488
    _wallet = w;
489
}
490

Teo Mrnjavac's avatar
Teo Mrnjavac committed
491
492
bool KWalletEntryList::existsFolder(const QString &name)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
493
494
495
496
497
498
499
500
501
502
    for (int i = 0; i < topLevelItemCount(); ++i) {
        KWalletFolderItem *fi = dynamic_cast<KWalletFolderItem *>(topLevelItem(i));
        if (!fi) {
            continue;
        }
        if (name == fi->name()) {
            return true;
        }
    }
    return false;
503
504
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
505
506
QMimeData *KWalletEntryList::itemMimeData(const QTreeWidgetItem *i) const
{
Laurent Montel's avatar
Laurent Montel committed
507
    QMimeData *sd = nullptr;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
508
    if (i->type() == KWalletEntryItemClass) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
509
        const KWalletEntryItem *ei = dynamic_cast<const KWalletEntryItem *>(i);
Teo Mrnjavac's avatar
Teo Mrnjavac committed
510
        if (!ei) {
Laurent Montel's avatar
Laurent Montel committed
511
            return nullptr;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
512
        }
Teo Mrnjavac's avatar
Teo Mrnjavac committed
513
        KWalletContainerItem *ci = dynamic_cast<KWalletContainerItem *>(ei->parent());
Teo Mrnjavac's avatar
Teo Mrnjavac committed
514
        if (!ci) {
Laurent Montel's avatar
Laurent Montel committed
515
            return nullptr;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
516
517
518
519
520
521
522
523
524
525
526
527
        }
        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;
Laurent Montel's avatar
Laurent Montel committed
528
        sd->setData(QStringLiteral("application/x-kwallet-entry"), a);
Teo Mrnjavac's avatar
Teo Mrnjavac committed
529
    } else if (i->type() == KWalletFolderItemClass) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
530
        const KWalletFolderItem *fi = dynamic_cast<const KWalletFolderItem *>(i);
Teo Mrnjavac's avatar
Teo Mrnjavac committed
531
        if (!fi) {
Laurent Montel's avatar
Laurent Montel committed
532
            return nullptr;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
533
534
535
536
537
538
539
540
541
        }
        sd = new QMimeData();
        QByteArray a;
        QDataStream ds(&a, QIODevice::WriteOnly);

        ds.setVersion(QDataStream::Qt_3_1);

        ds << KWALLETFOLDERMAGIC;
        ds << *fi;
Laurent Montel's avatar
Laurent Montel committed
542
        sd->setData(QStringLiteral("application/x-kwallet-folder"), a);
Teo Mrnjavac's avatar
Teo Mrnjavac committed
543
544
    }
    return sd;
Albert Astals Cid's avatar
Albert Astals Cid committed
545
546
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
547
548
549
void KWalletEntryList::mousePressEvent(QMouseEvent *e)
{
    if (e->button() == Qt::LeftButton) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
550
        _mousePos = e->pos();
Teo Mrnjavac's avatar
Teo Mrnjavac committed
551
552
    }
    QTreeWidget::mousePressEvent(e);
Albert Astals Cid's avatar
Albert Astals Cid committed
553
554
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
555
556
557
void KWalletEntryList::mouseMoveEvent(QMouseEvent *e)
{
    if (!(e->buttons() & Qt::LeftButton)) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
558
        return;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
559
560
    }
    if ((e->pos() - _mousePos).manhattanLength() < QApplication::startDragDistance()) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
561
        return;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
562
563
    }

Teo Mrnjavac's avatar
Teo Mrnjavac committed
564
    const QTreeWidgetItem *item = itemAt(_mousePos);
Teo Mrnjavac's avatar
Teo Mrnjavac committed
565
    if (!item || !item->isSelected()) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
566
        return;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
567
568
    }

Teo Mrnjavac's avatar
Teo Mrnjavac committed
569
570
571
572
    QMimeData *mimeData = itemMimeData(item);
    if (mimeData) {
        QDrag *drag = new QDrag(this);
        drag->setMimeData(mimeData);
Teo Mrnjavac's avatar
Teo Mrnjavac committed
573
        drag->setHotSpot(QPoint(0, 0));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
574
575
        drag->exec();
    }
Albert Astals Cid's avatar
Albert Astals Cid committed
576
577
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
578
579
void KWalletEntryList::dropEvent(QDropEvent *e)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
580
581
    QTreeWidgetItem *i = itemAt(e->pos());
    itemDropped(e, i);
582
}
583

Teo Mrnjavac's avatar
Teo Mrnjavac committed
584
585
void KWalletEntryList::dragEnterEvent(QDragEnterEvent *e)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
586
    e->accept();
Albert Astals Cid's avatar
Albert Astals Cid committed
587
588
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
589
590
void KWalletEntryList::dragMoveEvent(QDragMoveEvent *e)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
591
592
593
    QTreeWidgetItem *i = itemAt(e->pos());
    e->ignore();
    if (i) {
Laurent Montel's avatar
Laurent Montel committed
594
595
        if (e->mimeData()->hasFormat(QStringLiteral("application/x-kwallet-entry")) ||
                e->mimeData()->hasFormat(QStringLiteral("text/uri-list"))) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
596
597
598
            e->accept();
        }
    }
Laurent Montel's avatar
Laurent Montel committed
599
    if ((e->mimeData()->hasFormat(QStringLiteral("application/x-kwallet-folder")) &&
Teo Mrnjavac's avatar
Teo Mrnjavac committed
600
            e->source() != viewport()) ||
Laurent Montel's avatar
Laurent Montel committed
601
            e->mimeData()->hasFormat(QStringLiteral("text/uri-list"))) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
602
603
        e->accept();
    }
604
}
605

Teo Mrnjavac's avatar
Teo Mrnjavac committed
606
607
KWalletFolderItem *KWalletEntryList::getFolder(const QString &name)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
608
609
610
611
612
613
614
615
616
    for (int i = 0; i < topLevelItemCount(); ++i) {
        KWalletFolderItem *fi = dynamic_cast<KWalletFolderItem *>(topLevelItem(i));
        if (!fi) {
            continue;
        }
        if (name == fi->name()) {
            return fi;
        }
    }
Laurent Montel's avatar
Laurent Montel committed
617
    return nullptr;
618
}
619

Teo Mrnjavac's avatar
Teo Mrnjavac committed
620
621
KWalletFolderItem *KWalletEntryList::getItemFolder(QTreeWidgetItem *item)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
622
    switch (item->type()) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
623
624
625
626
627
628
    case KWalletFolderItemClass:
        return dynamic_cast<KWalletFolderItem *>(item);
    case KWalletContainerItemClass:
        return dynamic_cast<KWalletFolderItem *>(item->parent());
    case KWalletEntryItemClass:
        return dynamic_cast<KWalletFolderItem *>(item->parent()->parent());
Teo Mrnjavac's avatar
Teo Mrnjavac committed
629
    }
Laurent Montel's avatar
Laurent Montel committed
630
    return nullptr;
George Staikos's avatar
George Staikos committed
631
632
}

633
634
635
636
637
638
639
void KWalletEntryList::selectFirstVisible()
{
    QTreeWidgetItemIterator it(this);
    while (*it) {
        QTreeWidgetItem *item = *it++;
        if (!item->isHidden()) {
            // if it's a leaf, then select it and quit
Teo Mrnjavac's avatar
Teo Mrnjavac committed
640
            if (item->childCount() == 0) {
Laurent Montel's avatar
Laurent Montel committed
641
//                 qCDebug(KWALLETMANAGER_LOG) << "selecting " << item->text(0);
642
643
644
645
646
647
648
                setCurrentItem(item);
                break;
            }
        }
    }
}

649
650
651
652
653
void KWalletEntryList::refreshItemsCount()
{
    QTreeWidgetItemIterator it(this);
    while (*it) {
        QTreeWidgetItem *item = *it++;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
654
        KWalletFolderItem *fi = dynamic_cast< KWalletFolderItem * >(item);
655
656
657
658
659
660
        if (fi) {
            fi->refreshItemsCount();
        }
    }
}

661
662
class ReturnPressedFilter : public QObject
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
663
public:
Laurent Montel's avatar
Laurent Montel committed
664
    ReturnPressedFilter(QListWidget *parent) : QObject(parent)
Teo Mrnjavac's avatar
Teo Mrnjavac committed
665
666
667
668
    {
        parent->installEventFilter(this);
    }

Laurent Montel's avatar
Laurent Montel committed
669
    bool eventFilter(QObject * /*watched*/, QEvent *event) override
Teo Mrnjavac's avatar
Teo Mrnjavac committed
670
671
672
673
    {
        if (event->type() == QEvent::KeyPress) {
            QKeyEvent *ke = static_cast<QKeyEvent *>(event);
            if (ke->key() == Qt::Key_Enter || ke->key() == Qt::Key_Return) {
Laurent Montel's avatar
Laurent Montel committed
674
                QListWidget *p = static_cast<QListWidget *>(parent());
Teo Mrnjavac's avatar
Teo Mrnjavac committed
675
676
                QMetaObject::invokeMethod(p, "executed", Q_ARG(QListWidgetItem *, p->currentItem()));
                return true;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
677
678
            }
        }
Teo Mrnjavac's avatar
Teo Mrnjavac committed
679
680
        return false;
    }
681
682
};

Laurent Montel's avatar
Laurent Montel committed
683