allyourbase.cpp 20.3 KB
Newer Older
1
/*
2 3
   Copyright (C) 2003-2005 George Staikos <staikos@kde.org>
   Copyright (C) 2005 Isaac Clerencia <isaac@warp.es>
4 5 6 7 8 9 10 11 12 13 14 15 16

   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
Script Kiddy's avatar
Script Kiddy committed
17 18
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
19 20 21 22
*/

#include "allyourbase.h"

23
#include <KJobWidgets>
Teo Mrnjavac's avatar
Teo Mrnjavac committed
24
#include <klocalizedstring.h>
25
#include <KIO/StoredTransferJob>
26
#include <kmessagebox.h>
Laurent Montel's avatar
Laurent Montel committed
27
#include <qurl.h>
George Staikos's avatar
George Staikos committed
28
#include <kwallet.h>
29

30
#include <QApplication>
Teo Mrnjavac's avatar
Teo Mrnjavac committed
31
#include <QDebug>
32
#include <QDrag>
33
#include <QMimeData>
Laurent Montel's avatar
Laurent Montel committed
34 35 36 37
#include <QPixmap>
#include <QDropEvent>
#include <QDragEnterEvent>
#include <QMouseEvent>
38

39 40 41
/****************
 *  KWalletFolderItem - ListView items to represent kwallet folders
 */
Teo Mrnjavac's avatar
Teo Mrnjavac committed
42 43 44
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
45
    setText(0, QStringLiteral("%1 (%2)").arg(_name).arg(_entries));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
46 47
    setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEnabled);
    setIcon(0, getFolderIcon(KIconLoader::Small));
48 49
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
50 51
QPixmap KWalletFolderItem::getFolderIcon(KIconLoader::Group group)
{
52 53
    QPixmap pix = QIcon::fromTheme(_name).pixmap(IconSize(group), IconSize(group));

Teo Mrnjavac's avatar
Teo Mrnjavac committed
54
    if (pix.isNull())
55 56
        pix = QIcon::fromTheme(_name.toLower()).pixmap(IconSize(group), IconSize(group));

Teo Mrnjavac's avatar
Teo Mrnjavac committed
57
    if (pix.isNull())
Laurent Montel's avatar
Laurent Montel committed
58
        pix = QIcon::fromTheme(QStringLiteral("folder-red")).pixmap(IconSize(group), IconSize(group));
59

Teo Mrnjavac's avatar
Teo Mrnjavac committed
60
    return pix;
61 62
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
63 64
void KWalletFolderItem::refresh()
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
65 66
    const QString saveFolder = _wallet->currentFolder();
    _wallet->setFolder(_name);
Laurent Montel's avatar
Laurent Montel committed
67
    setText(0, QStringLiteral("%1 (%2)").arg(_name).arg(_wallet->entryList().count()));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
68
    _wallet->setFolder(saveFolder);
69 70
}

71 72
void KWalletFolderItem::refreshItemsCount()
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
73 74 75
    int visibleLeafCount = 0;
    for (int i = 0; i < childCount(); i++) {
        QTreeWidgetItem *wi = child(i);
76
        if (wi->childCount()) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
77 78 79
            for (int l = 0; l < wi->childCount(); l++) {
                QTreeWidgetItem *li = wi->child(l);
                if (!li->isHidden()) {
80
                    visibleLeafCount++;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
81
                }
82 83 84
            }
        }
    }
Laurent Montel's avatar
Laurent Montel committed
85
    setText(0, QStringLiteral("%1 (%2)").arg(_name).arg(visibleLeafCount));
86 87
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
88 89
KWalletContainerItem *KWalletFolderItem::getContainer(KWallet::Wallet::EntryType type)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
90 91 92 93 94 95 96 97 98 99
    for (int i = 0; i < childCount(); ++i) {
        KWalletContainerItem *ci = dynamic_cast<KWalletContainerItem *>(child(i));
        if (!ci) {
            continue;
        }
        if (ci->entryType() == type) {
            return ci;
        }
    }
    return 0;
100 101
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
102 103
bool KWalletFolderItem::contains(const QString &key)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
104
    return (getItem(key) != 0);
105 106
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
107 108
QTreeWidgetItem *KWalletFolderItem::getItem(const QString &key)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
109 110 111 112 113 114 115 116 117 118 119
    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;
        }
    }
    return 0;
120 121
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
122 123
bool KWalletFolderItem::acceptDrop(const QMimeData *mime) const
{
Laurent Montel's avatar
Laurent Montel committed
124 125
    return mime->hasFormat(QStringLiteral("application/x-kwallet-entry")) ||
           mime->hasFormat(QStringLiteral("text/uri-list"));
126 127
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
128 129
QString KWalletFolderItem::name() const
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
130
    return _name;
131 132
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
133 134
KWalletFolderItem::~KWalletFolderItem()
{
135 136 137 138 139 140
}

/****************
 *  KWalletContainerItem - ListView items to represent kwallet containers, i.e.
 *  passwords, maps, ...
 */
Teo Mrnjavac's avatar
Teo Mrnjavac committed
141 142 143
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
144
    setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled);
145 146
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
147 148
KWalletContainerItem::~KWalletContainerItem()
{
149 150
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
151 152
KWallet::Wallet::EntryType KWalletContainerItem::entryType()
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
153
    return _type;
154 155
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
156 157
bool KWalletContainerItem::contains(const QString &key)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
158
    return getItem(key) != 0;
159 160
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
161 162
QTreeWidgetItem *KWalletContainerItem::getItem(const QString &key)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
163
    for (int i = 0; i < childCount(); ++i) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
164
        KWalletEntryItem *entryItem = dynamic_cast<KWalletEntryItem *>(child(i));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
165 166 167 168 169
        if (entryItem && entryItem->name() == key) {
            return entryItem;
        }
    }
    return 0;
170
}
171

George Staikos's avatar
George Staikos committed
172 173 174
/****************
 *  KWalletEntryItem - ListView items to represent kwallet entries
 */
Teo Mrnjavac's avatar
Teo Mrnjavac committed
175 176 177
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
178
    setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled);
179 180
}

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

Teo Mrnjavac's avatar
Teo Mrnjavac committed
185
void KWalletEntryItem::setName(const QString &n)
186
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
187 188
    m_name = n;
    QTreeWidgetItem::setText(0, n);
189 190 191 192
}

void KWalletEntryItem::restoreName()
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
193
    QTreeWidgetItem::setText(0, m_name);
194 195
}

George Staikos's avatar
George Staikos committed
196
/****************
197
 * KWalletItem - IconView items to represent wallets
George Staikos's avatar
George Staikos committed
198
 */
Teo Mrnjavac's avatar
Teo Mrnjavac committed
199 200 201
KWalletItem::KWalletItem(QListWidget *parent, const QString &walletName)
    : QListWidgetItem(DesktopIcon(QLatin1String("wallet-closed")), walletName, parent), _open(false)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
202
    setFlags(flags() | Qt::ItemIsDropEnabled);
203 204
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
205 206
KWalletItem::~KWalletItem()
{
207 208
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
209 210
void KWalletItem::setOpen(bool state)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
211 212 213
    if (_open != state) {
        _open = state;
        if (_open) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
214
            setIcon(DesktopIcon(QLatin1String("wallet-open")));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
215
        } else {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
216
            setIcon(DesktopIcon(QLatin1String("wallet-closed")));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
217 218
        }
    }
219 220
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
221 222
static bool decodeEntry(KWallet::Wallet *_wallet, QDataStream &ds)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
223 224 225
    quint32 magic;
    ds >> magic;
    if (magic != KWALLETENTRYMAGIC) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
226
        qDebug() << "bad magic" ;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
227 228 229 230 231 232 233
        return false;
    }
    QString name;
    QByteArray value;
    KWallet::Wallet::EntryType et;
    ds >> name;
    if (_wallet->hasEntry(name)) {
Laurent Montel's avatar
Laurent Montel committed
234
        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
235 236 237 238 239 240 241 242 243 244
        if (rc == KMessageBox::Cancel) {
            return false;
        }
    }
    qint32 l;
    ds >> l;
    et = KWallet::Wallet::EntryType(l);
    ds >> value;
    _wallet->writeEntry(name, value, et);
    return true;
245 246
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
247 248
static bool decodeFolder(KWallet::Wallet *_wallet, QDataStream &ds)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
249 250 251
    quint32 magic;
    ds >> magic;
    if (magic != KWALLETFOLDERMAGIC) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
252
        qDebug() << "bad magic" ;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
253 254 255 256 257
        return false;
    }
    QString folder;
    ds >> folder;
    if (_wallet->hasFolder(folder)) {
Laurent Montel's avatar
Laurent Montel committed
258
        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
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282
        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;
283 284
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
285 286
void KWalletItem::processDropEvent(QDropEvent *e)
{
287 288 289 290 291 292 293 294 295 296 297
    // 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
298 299
    if (e->mimeData()->hasFormat(QStringLiteral("application/x-kwallet-folder")) ||
            e->mimeData()->hasFormat(QStringLiteral("text/uri-list"))) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
300 301 302 303 304 305
        // 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;
        }
306

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

309
        QByteArray data;
310

Laurent Montel's avatar
Laurent Montel committed
311 312
        if (e->mimeData()->hasFormat(QStringLiteral("application/x-kwallet-folder"))) {
            data = e->mimeData()->data(QStringLiteral("application/x-kwallet-folder"));
313
            e->accept();
Teo Mrnjavac's avatar
Teo Mrnjavac committed
314 315 316 317 318 319 320
        } else { // text/uri-list
            const QList<QUrl> urls = e->mimeData()->urls();
            if (urls.isEmpty()) {
                e->ignore();
                return;
            }

Laurent Montel's avatar
Laurent Montel committed
321
            QUrl u(urls.first());
Teo Mrnjavac's avatar
Teo Mrnjavac committed
322 323 324 325
            if (u.fileName().isEmpty()) {
                e->ignore();
                return;
            }
326 327 328 329 330 331
            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
332
            } else {
333
                KMessageBox::error(listWidget(), job->errorString());
Teo Mrnjavac's avatar
Teo Mrnjavac committed
334 335
            }
        }
336 337 338 339

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

Teo Mrnjavac's avatar
Teo Mrnjavac committed
342 343 344 345
        _wallet->setFolder(saveFolder);
        delete _wallet;

        //delete the folder from the source if we were moving
346 347 348 349 350
        if (el) {
            KWalletFolderItem *fi =
                dynamic_cast<KWalletFolderItem *>(el->currentItem());
            if (fi) {
                el->_wallet->removeFolder(fi->name());
Teo Mrnjavac's avatar
Teo Mrnjavac committed
351 352 353 354 355 356
            }
        }
    } else {
        e->ignore();
        return;
    }
357
}
358

359 360 361 362
/****************
 *  KWalletEntryList - A listview to store wallet entries
 */
KWalletEntryList::KWalletEntryList(QWidget *parent, const char *name)
Teo Mrnjavac's avatar
Teo Mrnjavac committed
363 364 365 366
    : QTreeWidget(parent),
      _wallet(0)
{
    setObjectName(QLatin1String(name));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
367 368 369 370 371 372
    setColumnCount(1);
    setHeaderLabel(i18n("Folders"));
    setRootIsDecorated(true);
    setDragEnabled(true);
    setAcceptDrops(true);
    setDragDropMode(DragDrop);
373
    setSelectionMode(SingleSelection);
George Staikos's avatar
George Staikos committed
374 375
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
376 377
KWalletEntryList::~KWalletEntryList()
{
George Staikos's avatar
George Staikos committed
378 379
}

380
//returns true if the item has been dropped successfully
Teo Mrnjavac's avatar
Teo Mrnjavac committed
381 382
void KWalletEntryList::itemDropped(QDropEvent *e, QTreeWidgetItem *item)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
383 384
    bool ok = true;
    bool isEntry;
385
    QByteArray data;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
386

Laurent Montel's avatar
Laurent Montel committed
387 388
    KWalletEntryList *el = nullptr;
    QTreeWidgetItem *sel = nullptr;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
389

390 391 392 393 394 395 396 397
    // 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
398
    //detect if we are dragging from kwallet itself
Teo Mrnjavac's avatar
Teo Mrnjavac committed
399
    qDebug() << e->source() << e->source()->metaObject()->className();
Teo Mrnjavac's avatar
Teo Mrnjavac committed
400 401
    if (e->source() && !strcmp(e->source()->metaObject()->className(), "KWalletEntryList")) {

Teo Mrnjavac's avatar
Teo Mrnjavac committed
402
        el = dynamic_cast<KWalletEntryList *>(e->source());
Teo Mrnjavac's avatar
Teo Mrnjavac committed
403 404
        if (!el) {
            KMessageBox::error(this, i18n("An unexpected error occurred trying to drop the item"));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
405
        } else {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
406
            sel = el->currentItem();
Teo Mrnjavac's avatar
Teo Mrnjavac committed
407
        }
Teo Mrnjavac's avatar
Teo Mrnjavac committed
408
    }
George Staikos's avatar
George Staikos committed
409

Laurent Montel's avatar
Laurent Montel committed
410
    if (e->mimeData()->hasFormat(QStringLiteral("application/x-kwallet-entry"))) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
411 412 413 414 415 416 417
        //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
418
        data = e->mimeData()->data(QStringLiteral("application/x-kwallet-entry"));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
419 420 421 422
        if (data.isEmpty()) {
            e->ignore();
            return;
        }
423
        e->accept();
Laurent Montel's avatar
Laurent Montel committed
424
    } else if (e->mimeData()->hasFormat(QStringLiteral("application/x-kwallet-folder"))) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
425 426 427 428 429 430
        //do nothing if we are in the same wallet
        if (this == el) {
            e->ignore();
            return;
        }
        isEntry = false;
Laurent Montel's avatar
Laurent Montel committed
431
        data = e->mimeData()->data(QStringLiteral("application/x-kwallet-folder"));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
432 433 434 435
        if (data.isEmpty()) {
            e->ignore();
            return;
        }
436
        e->accept();
Laurent Montel's avatar
Laurent Montel committed
437
    } else if (e->mimeData()->hasFormat(QStringLiteral("text/uri-list"))) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
438 439 440 441 442
        const QList<QUrl> urls = e->mimeData()->urls();
        if (urls.isEmpty()) {
            e->ignore();
            return;
        }
Laurent Montel's avatar
Laurent Montel committed
443
        QUrl u(urls.first());
Teo Mrnjavac's avatar
Teo Mrnjavac committed
444 445 446 447
        if (u.fileName().isEmpty()) {
            e->ignore();
            return;
        }
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465

        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
466
        } else {
467
            qDebug() << "bad magic" ;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
468 469 470 471 472 473
            return;
        }
    } else {
        e->ignore();
        return;
    }
474 475 476

    QDataStream ds(data);

Teo Mrnjavac's avatar
Teo Mrnjavac committed
477 478 479 480 481 482 483 484
    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());
485
        ok = decodeEntry(_wallet, ds);
Teo Mrnjavac's avatar
Teo Mrnjavac committed
486 487 488 489
        _wallet->setFolder(saveFolder);
        fi->refresh();
        //delete source if we were moving, i.e., we are dragging
        //from kwalletmanager and Control is not pressed
490
        if (ok && el && proposedAction != Qt::CopyAction && sel) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
491 492 493 494
            el->_wallet->removeEntry(sel->text(0));
            delete sel;
        }
    } else {
495
        ok = decodeFolder(_wallet, ds);
Teo Mrnjavac's avatar
Teo Mrnjavac committed
496 497
        //delete source if we were moving, i.e., we are dragging
        //from kwalletmanager and Control is not pressed
498
        if (ok && el && proposedAction != Qt::CopyAction && sel) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
499 500 501 502 503 504 505 506 507
            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"));
            }
        }
    }
508 509
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
510 511
void KWalletEntryList::setWallet(KWallet::Wallet *w)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
512
    _wallet = w;
513
}
514

Teo Mrnjavac's avatar
Teo Mrnjavac committed
515 516
bool KWalletEntryList::existsFolder(const QString &name)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
517 518 519 520 521 522 523 524 525 526
    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;
527 528
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
529 530
QMimeData *KWalletEntryList::itemMimeData(const QTreeWidgetItem *i) const
{
Laurent Montel's avatar
Laurent Montel committed
531
    QMimeData *sd = nullptr;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
532
    if (i->type() == KWalletEntryItemClass) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
533
        const KWalletEntryItem *ei = dynamic_cast<const KWalletEntryItem *>(i);
Teo Mrnjavac's avatar
Teo Mrnjavac committed
534
        if (!ei) {
Laurent Montel's avatar
Laurent Montel committed
535
            return nullptr;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
536
        }
Teo Mrnjavac's avatar
Teo Mrnjavac committed
537
        KWalletContainerItem *ci = dynamic_cast<KWalletContainerItem *>(ei->parent());
Teo Mrnjavac's avatar
Teo Mrnjavac committed
538
        if (!ci) {
Laurent Montel's avatar
Laurent Montel committed
539
            return nullptr;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
540 541 542 543 544 545 546 547 548 549 550 551
        }
        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
552
        sd->setData(QStringLiteral("application/x-kwallet-entry"), a);
Teo Mrnjavac's avatar
Teo Mrnjavac committed
553
    } else if (i->type() == KWalletFolderItemClass) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
554
        const KWalletFolderItem *fi = dynamic_cast<const KWalletFolderItem *>(i);
Teo Mrnjavac's avatar
Teo Mrnjavac committed
555
        if (!fi) {
Laurent Montel's avatar
Laurent Montel committed
556
            return nullptr;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
557 558 559 560 561 562 563 564 565
        }
        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
566
        sd->setData(QStringLiteral("application/x-kwallet-folder"), a);
Teo Mrnjavac's avatar
Teo Mrnjavac committed
567 568
    }
    return sd;
Albert Astals Cid's avatar
Albert Astals Cid committed
569 570
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
571 572 573
void KWalletEntryList::mousePressEvent(QMouseEvent *e)
{
    if (e->button() == Qt::LeftButton) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
574
        _mousePos = e->pos();
Teo Mrnjavac's avatar
Teo Mrnjavac committed
575 576
    }
    QTreeWidget::mousePressEvent(e);
Albert Astals Cid's avatar
Albert Astals Cid committed
577 578
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
579 580 581
void KWalletEntryList::mouseMoveEvent(QMouseEvent *e)
{
    if (!(e->buttons() & Qt::LeftButton)) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
582
        return;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
583 584
    }
    if ((e->pos() - _mousePos).manhattanLength() < QApplication::startDragDistance()) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
585
        return;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
586 587
    }

Teo Mrnjavac's avatar
Teo Mrnjavac committed
588
    const QTreeWidgetItem *item = itemAt(_mousePos);
Teo Mrnjavac's avatar
Teo Mrnjavac committed
589
    if (!item || !item->isSelected()) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
590
        return;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
591 592
    }

Teo Mrnjavac's avatar
Teo Mrnjavac committed
593 594 595 596
    QMimeData *mimeData = itemMimeData(item);
    if (mimeData) {
        QDrag *drag = new QDrag(this);
        drag->setMimeData(mimeData);
Teo Mrnjavac's avatar
Teo Mrnjavac committed
597
        drag->setHotSpot(QPoint(0, 0));
Teo Mrnjavac's avatar
Teo Mrnjavac committed
598 599
        drag->exec();
    }
Albert Astals Cid's avatar
Albert Astals Cid committed
600 601
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
602 603
void KWalletEntryList::dropEvent(QDropEvent *e)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
604 605
    QTreeWidgetItem *i = itemAt(e->pos());
    itemDropped(e, i);
606
}
607

Teo Mrnjavac's avatar
Teo Mrnjavac committed
608 609
void KWalletEntryList::dragEnterEvent(QDragEnterEvent *e)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
610
    e->accept();
Albert Astals Cid's avatar
Albert Astals Cid committed
611 612
}

Teo Mrnjavac's avatar
Teo Mrnjavac committed
613 614
void KWalletEntryList::dragMoveEvent(QDragMoveEvent *e)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
615 616 617
    QTreeWidgetItem *i = itemAt(e->pos());
    e->ignore();
    if (i) {
Laurent Montel's avatar
Laurent Montel committed
618 619
        if (e->mimeData()->hasFormat(QStringLiteral("application/x-kwallet-entry")) ||
                e->mimeData()->hasFormat(QStringLiteral("text/uri-list"))) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
620 621 622
            e->accept();
        }
    }
Laurent Montel's avatar
Laurent Montel committed
623
    if ((e->mimeData()->hasFormat(QStringLiteral("application/x-kwallet-folder")) &&
Teo Mrnjavac's avatar
Teo Mrnjavac committed
624
            e->source() != viewport()) ||
Laurent Montel's avatar
Laurent Montel committed
625
            e->mimeData()->hasFormat(QStringLiteral("text/uri-list"))) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
626 627
        e->accept();
    }
628
}
629

Teo Mrnjavac's avatar
Teo Mrnjavac committed
630 631
KWalletFolderItem *KWalletEntryList::getFolder(const QString &name)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
632 633 634 635 636 637 638 639 640 641
    for (int i = 0; i < topLevelItemCount(); ++i) {
        KWalletFolderItem *fi = dynamic_cast<KWalletFolderItem *>(topLevelItem(i));
        if (!fi) {
            continue;
        }
        if (name == fi->name()) {
            return fi;
        }
    }
    return 0;
642
}
643

Teo Mrnjavac's avatar
Teo Mrnjavac committed
644 645
KWalletFolderItem *KWalletEntryList::getItemFolder(QTreeWidgetItem *item)
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
646
    switch (item->type()) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
647 648 649 650 651 652
    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
653 654
    }
    return 0;
George Staikos's avatar
George Staikos committed
655 656
}

657 658 659 660 661 662 663
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
664
            if (item->childCount() == 0) {
Teo Mrnjavac's avatar
Teo Mrnjavac committed
665
//                 qDebug() << "selecting " << item->text(0);
666 667 668 669 670 671 672
                setCurrentItem(item);
                break;
            }
        }
    }
}

673 674 675 676 677
void KWalletEntryList::refreshItemsCount()
{
    QTreeWidgetItemIterator it(this);
    while (*it) {
        QTreeWidgetItem *item = *it++;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
678
        KWalletFolderItem *fi = dynamic_cast< KWalletFolderItem * >(item);
679 680 681 682 683 684
        if (fi) {
            fi->refreshItemsCount();
        }
    }
}

685 686
class ReturnPressedFilter : public QObject
{
Teo Mrnjavac's avatar
Teo Mrnjavac committed
687
public:
Laurent Montel's avatar
Laurent Montel committed
688
    ReturnPressedFilter(QListWidget *parent) : QObject(parent)
Teo Mrnjavac's avatar
Teo Mrnjavac committed
689 690 691 692
    {
        parent->installEventFilter(this);
    }

Laurent Montel's avatar
Laurent Montel committed
693
    bool eventFilter(QObject * /*watched*/, QEvent *event) Q_DECL_OVERRIDE
Teo Mrnjavac's avatar
Teo Mrnjavac committed
694 695 696 697
    {
        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
698
                QListWidget *p = static_cast<QListWidget *>(parent());
Teo Mrnjavac's avatar
Teo Mrnjavac committed
699 700
                QMetaObject::invokeMethod(p, "executed", Q_ARG(QListWidgetItem *, p->currentItem()));
                return true;
Teo Mrnjavac's avatar
Teo Mrnjavac committed
701 702
            }
        }
Teo Mrnjavac's avatar
Teo Mrnjavac committed
703 704
        return false;
    }
705 706
};

Laurent Montel's avatar
Laurent Montel committed
707