File: ownclouddolphinactionplugin.cpp

package info (click to toggle)
nextcloud-desktop 4.0.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 40,404 kB
  • sloc: cpp: 118,401; objc: 752; python: 606; sh: 395; ansic: 391; ruby: 174; makefile: 44; javascript: 32; xml: 6
file content (124 lines) | stat: -rw-r--r-- 5,053 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*
 * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
 * SPDX-FileCopyrightText: 2014 ownCloud GmbH
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include <KPluginFactory>
#include <KAbstractFileItemActionPlugin>
#include <QtNetwork/QLocalSocket>
#include <KFileItem>
#include <KFileItemListProperties>
#include <QAction>
#include <QMenu>
#include <QDir>
#include <QTimer>
#include <QEventLoop>
#include "ownclouddolphinpluginhelper.h"

class OwncloudDolphinPluginAction : public KAbstractFileItemActionPlugin
{
    Q_OBJECT
public:
    explicit OwncloudDolphinPluginAction(QObject* parent, const QList<QVariant>&)
        : KAbstractFileItemActionPlugin(parent) { }

    QList<QAction*> actions(const KFileItemListProperties& fileItemInfos, QWidget* parentWidget) override
    {
        auto helper = OwncloudDolphinPluginHelper::instance();
        if (!helper->isConnected() || !fileItemInfos.isLocal())
            return {};

        // If any of the url is outside of a sync folder, return an empty menu.
        const QList<QUrl> urls = fileItemInfos.urlList();
        const auto paths = helper->paths();
        QByteArray files;
        for (const auto &url : urls) {
            QDir localPath(url.toLocalFile());
            auto localFile = localPath.canonicalPath();
            if (!std::any_of(paths.begin(), paths.end(), [&](const QString &s) {
                    return localFile.startsWith(s);
                }))
                return {};

            if (!files.isEmpty())
                files += '\x1e'; // Record separator
            files += localFile.toUtf8();
        }

        if (helper->version() < "1.1") { // in this case, lexicographic order works
            return legacyActions(fileItemInfos, parentWidget);
        }

        auto menu = new QMenu(parentWidget);
        QEventLoop loop;
        auto con = connect(helper, &OwncloudDolphinPluginHelper::commandRecieved, this, [&](const QByteArray &cmd) {
            if (cmd.startsWith("GET_MENU_ITEMS:END")) {
                loop.quit();
            } else if (cmd.startsWith("MENU_ITEM:")) {
                auto args = QString::fromUtf8(cmd).split(QLatin1Char(':'));
                if (args.size() < 4)
                    return;
                auto action = menu->addAction(args.mid(3).join(QLatin1Char(':')));
                if (args.value(2).contains(QLatin1Char('d')))
                    action->setDisabled(true);
                auto call = args.value(1).toLatin1();
                connect(action, &QAction::triggered, [helper, call, files] {
                    helper->sendCommand(QByteArray(call + ":" + files + "\n").constData());
                });
            }
        });
        QTimer::singleShot(100, &loop, &QEventLoop::quit); // add a timeout to be sure we don't freeze dolphin
        helper->sendCommand(QByteArray("GET_MENU_ITEMS:" + files + "\n").constData());
        loop.exec(QEventLoop::ExcludeUserInputEvents);
        disconnect(con);
        if (menu->actions().isEmpty()) {
            delete menu;
            return {};
        }
        
        menu->setTitle(helper->contextMenuTitle());
        menu->setIcon(QIcon::fromTheme(helper->contextMenuIconName()));
        return { menu->menuAction() };
    }


    QList<QAction *> legacyActions(const KFileItemListProperties &fileItemInfos, QWidget *parentWidget)
    {
        QList<QUrl> urls = fileItemInfos.urlList();
        if (urls.count() != 1)
            return {};
        QDir localPath(urls.first().toLocalFile());
        auto localFile = localPath.canonicalPath();
        auto helper = OwncloudDolphinPluginHelper::instance();
        auto menuaction = new QAction(parentWidget);
        menuaction->setText(helper->contextMenuTitle());
        auto menu = new QMenu(parentWidget);
        menuaction->setMenu(menu);

        auto shareAction = menu->addAction(helper->shareActionTitle());
        connect(shareAction, &QAction::triggered, this, [localFile, helper] {
            helper->sendCommand(QByteArray("SHARE:" + localFile.toUtf8() + "\n").constData());
        });

        if (!helper->copyPrivateLinkTitle().isEmpty()) {
            auto copyPrivateLinkAction = menu->addAction(helper->copyPrivateLinkTitle());
            connect(copyPrivateLinkAction, &QAction::triggered, this, [localFile, helper] {
                helper->sendCommand(QByteArray("COPY_PRIVATE_LINK:" + localFile.toUtf8() + "\n").constData());
            });
        }

        if (!helper->emailPrivateLinkTitle().isEmpty()) {
            auto emailPrivateLinkAction = menu->addAction(helper->emailPrivateLinkTitle());
            connect(emailPrivateLinkAction, &QAction::triggered, this, [localFile, helper] {
                helper->sendCommand(QByteArray("EMAIL_PRIVATE_LINK:" + localFile.toUtf8() + "\n").constData());
            });
        }
        return { menuaction };
    }

};

K_PLUGIN_CLASS_WITH_JSON(OwncloudDolphinPluginAction, APPLICATION_EXECUTABLE "dolphinactionplugin.json")

#include "ownclouddolphinactionplugin.moc"