mirror of
https://github.com/nextcloud/desktop.git
synced 2025-10-26 11:17:43 +00:00
Dolphin shell integration: share code between two plugins
This commit is contained in:
parent
731d4b3d4d
commit
82d1d04774
@ -32,10 +32,11 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
add_definitions(-DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS)
|
||||
|
||||
kcoreaddons_add_plugin(ownclouddolphinplugin INSTALL_NAMESPACE "kf5/overlayicon" JSON ownclouddolphinplugin.json SOURCES ownclouddolphinplugin.cpp)
|
||||
kcoreaddons_add_plugin(ownclouddolphinplugin INSTALL_NAMESPACE "kf5/overlayicon" JSON ownclouddolphinplugin.json
|
||||
SOURCES ownclouddolphinplugin.cpp ownclouddolphinpluginhelper.cpp)
|
||||
target_link_libraries(ownclouddolphinplugin Qt5::Network KF5::CoreAddons KF5::KIOCore KF5::KIOWidgets)
|
||||
|
||||
add_library(ownclouddolphinpluginaction MODULE ownclouddolphinpluginaction.cpp)
|
||||
add_library(ownclouddolphinpluginaction MODULE ownclouddolphinpluginaction.cpp ownclouddolphinpluginhelper.cpp)
|
||||
target_link_libraries(ownclouddolphinpluginaction Qt5::Network KF5::CoreAddons KF5::KIOCore KF5::KIOWidgets)
|
||||
install(FILES ownclouddolphinpluginaction.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
|
||||
install(TARGETS ownclouddolphinpluginaction DESTINATION ${KDE_INSTALL_PLUGINDIR})
|
||||
|
||||
@ -21,41 +21,34 @@
|
||||
#include <KPluginFactory>
|
||||
#include <QtNetwork/QLocalSocket>
|
||||
#include <KIOCore/kfileitem.h>
|
||||
|
||||
#include <QTimer>
|
||||
#include "ownclouddolphinpluginhelper.h"
|
||||
|
||||
class OwncloudDolphinPlugin : public KOverlayIconPlugin
|
||||
{
|
||||
Q_PLUGIN_METADATA(IID "com.owncloud.ovarlayiconplugin" FILE "ownclouddolphinplugin.json");
|
||||
Q_OBJECT
|
||||
|
||||
QLocalSocket m_socket;
|
||||
typedef QHash<QByteArray, QByteArray> StatusMap;
|
||||
StatusMap m_status;
|
||||
QByteArray m_line;
|
||||
|
||||
public:
|
||||
explicit OwncloudDolphinPlugin(QObject* parent = 0) : KOverlayIconPlugin(parent) {
|
||||
connect(&m_socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
|
||||
tryConnect();
|
||||
|
||||
OwncloudDolphinPlugin() {
|
||||
auto helper = OwncloudDolphinPluginHelper::instance();
|
||||
QObject::connect(helper, &OwncloudDolphinPluginHelper::commandRecieved,
|
||||
this, &OwncloudDolphinPlugin::slotCommandRecieved);
|
||||
}
|
||||
|
||||
virtual QStringList getOverlays(const QUrl& url) override {
|
||||
QStringList getOverlays(const QUrl& url) override {
|
||||
auto helper = OwncloudDolphinPluginHelper::instance();
|
||||
if (!helper->isConnected())
|
||||
return QStringList();
|
||||
if (!url.isLocalFile())
|
||||
return QStringList();
|
||||
const QByteArray localFile = url.toLocalFile().toUtf8();
|
||||
// kDebug() << localFile;
|
||||
|
||||
tryConnect();
|
||||
if (m_socket.state() == QLocalSocket::ConnectingState) {
|
||||
if (!m_socket.waitForConnected(100)) {
|
||||
// kWarning() << "not connected" << m_socket.errorString();
|
||||
}
|
||||
}
|
||||
if (m_socket.state() == QLocalSocket::ConnectedState) {
|
||||
m_socket.write("RETRIEVE_FILE_STATUS:");
|
||||
m_socket.write(localFile);
|
||||
m_socket.write("\n");
|
||||
}
|
||||
helper->sendCommand("RETRIEVE_FILE_STATUS:" + localFile + "\n");
|
||||
|
||||
StatusMap::iterator it = m_status.find(localFile);
|
||||
if (it != m_status.constEnd()) {
|
||||
@ -64,18 +57,8 @@ public:
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private:
|
||||
void tryConnect() {
|
||||
if (m_socket.state() != QLocalSocket::UnconnectedState)
|
||||
return;
|
||||
QString runtimeDir = QFile::decodeName(qgetenv("XDG_RUNTIME_DIR"));
|
||||
QString socketPath = runtimeDir + "/" + "ownCloud" + "/socket";
|
||||
m_socket.connectToServer(socketPath);
|
||||
}
|
||||
|
||||
QStringList overlaysForString(const QByteArray status) {
|
||||
QStringList overlaysForString(const QByteArray &status) {
|
||||
QStringList r;
|
||||
if (status.startsWith("NOP"))
|
||||
return r;
|
||||
@ -91,33 +74,23 @@ private:
|
||||
return r;
|
||||
}
|
||||
|
||||
private slots:
|
||||
void readyRead() {
|
||||
while (m_socket.bytesAvailable()) {
|
||||
m_line += m_socket.readLine();
|
||||
if (!m_line.endsWith("\n"))
|
||||
continue;
|
||||
QByteArray line;
|
||||
qSwap(line, m_line);
|
||||
line.chop(1);
|
||||
if (line.isEmpty())
|
||||
continue;
|
||||
QList<QByteArray> tokens = line.split(':');
|
||||
if (tokens.count() != 3)
|
||||
continue;
|
||||
if (tokens[0] != "STATUS" && tokens[0] != "BROADCAST")
|
||||
continue;
|
||||
if (tokens[2].isEmpty())
|
||||
continue;
|
||||
void slotCommandRecieved(const QByteArray &line) {
|
||||
|
||||
const QByteArray name = tokens[2];
|
||||
QByteArray &status = m_status[name]; // reference to the item in the hash
|
||||
if (status == tokens[1])
|
||||
continue;
|
||||
status = tokens[1];
|
||||
QList<QByteArray> tokens = line.split(':');
|
||||
if (tokens.count() != 3)
|
||||
return;
|
||||
if (tokens[0] != "STATUS" && tokens[0] != "BROADCAST")
|
||||
return;
|
||||
if (tokens[2].isEmpty())
|
||||
return;
|
||||
|
||||
emit this->overlaysChanged(QUrl::fromLocalFile(QString::fromUtf8(name)), overlaysForString(status));
|
||||
}
|
||||
const QByteArray name = tokens[2];
|
||||
QByteArray &status = m_status[name]; // reference to the item in the hash
|
||||
if (status == tokens[1])
|
||||
return;
|
||||
status = tokens[1];
|
||||
|
||||
emit overlaysChanged(QUrl::fromLocalFile(QString::fromUtf8(name)), overlaysForString(status));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Type=Service
|
||||
Name=Owncloud
|
||||
X-KDE-ServiceTypes=KOverlayIconPlugin
|
||||
MimeType=text/plain;
|
||||
X-KDE-Library=ownclouddolphinplugin
|
||||
@ -24,102 +24,39 @@
|
||||
#include <KIOCore/kfileitem.h>
|
||||
#include <KIOCore/KFileItemListProperties>
|
||||
#include <QtWidgets/QAction>
|
||||
|
||||
|
||||
class Connector : QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
QLocalSocket m_socket;
|
||||
QByteArray m_line;
|
||||
QVector<QString> m_paths;
|
||||
QString m_shareActionString;
|
||||
|
||||
Connector() {
|
||||
connect(&m_socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
|
||||
tryConnect();
|
||||
}
|
||||
|
||||
|
||||
void tryConnect() {
|
||||
|
||||
if (m_socket.state() != QLocalSocket::UnconnectedState)
|
||||
return;
|
||||
QString runtimeDir = QFile::decodeName(qgetenv("XDG_RUNTIME_DIR"));
|
||||
QString socketPath = runtimeDir + "/" + "ownCloud" + "/socket";
|
||||
m_socket.connectToServer(socketPath);
|
||||
if (m_socket.state() == QLocalSocket::ConnectingState) {
|
||||
m_socket.waitForConnected(100);
|
||||
}
|
||||
if (m_socket.state() == QLocalSocket::ConnectedState) {
|
||||
m_socket.write("SHARE_MENU_TITLE:\n");
|
||||
m_socket.flush();
|
||||
}
|
||||
}
|
||||
|
||||
private slots:
|
||||
void readyRead() {
|
||||
while (m_socket.bytesAvailable()) {
|
||||
m_line += m_socket.readLine();
|
||||
if (!m_line.endsWith("\n"))
|
||||
continue;
|
||||
QByteArray line;
|
||||
qSwap(line, m_line);
|
||||
line.chop(1);
|
||||
if (line.isEmpty())
|
||||
continue;
|
||||
if (line.startsWith("REGISTER_PATH:")) {
|
||||
QString file = QString::fromUtf8(line.mid(line.indexOf(':') + 1));
|
||||
m_paths.append(file);
|
||||
continue;
|
||||
} else if (line.startsWith("SHARE_MENU_TITLE:")) {
|
||||
m_shareActionString = QString::fromUtf8(line.mid(line.indexOf(':') + 1));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#include <QtCore/QTimer>
|
||||
#include "ownclouddolphinpluginhelper.h"
|
||||
|
||||
class OwncloudDolphinPluginAction : public KAbstractFileItemActionPlugin
|
||||
{
|
||||
public:
|
||||
explicit OwncloudDolphinPluginAction(QObject* parent, const QList<QVariant>&) : KAbstractFileItemActionPlugin(parent) {
|
||||
}
|
||||
explicit OwncloudDolphinPluginAction(QObject* parent, const QList<QVariant>&)
|
||||
: KAbstractFileItemActionPlugin(parent) { }
|
||||
|
||||
QList<QAction*> actions(const KFileItemListProperties& fileItemInfos, QWidget* parentWidget) Q_DECL_OVERRIDE
|
||||
{
|
||||
static Connector connector;
|
||||
connector.tryConnect();
|
||||
|
||||
auto helper = OwncloudDolphinPluginHelper::instance();
|
||||
QList<QUrl> urls = fileItemInfos.urlList();
|
||||
if (urls.count() != 1 || connector.m_socket.state() != QLocalSocket::ConnectedState)
|
||||
if (urls.count() != 1 || !helper->isConnected())
|
||||
return {};
|
||||
|
||||
auto url = urls.first();
|
||||
|
||||
|
||||
if (!url.isLocalFile())
|
||||
return {};
|
||||
auto localFile = url.toLocalFile();
|
||||
|
||||
|
||||
if (!std::any_of(connector.m_paths.begin(), connector.m_paths.end(), [&](const QString &s) {
|
||||
const auto paths = helper->paths();
|
||||
if (!std::any_of(paths.begin(), paths.end(), [&](const QString &s) {
|
||||
return localFile.startsWith(s);
|
||||
} ))
|
||||
return {};
|
||||
|
||||
auto act = new QAction(parentWidget);
|
||||
act->setText(connector.m_shareActionString);
|
||||
auto socket = &connector.m_socket;
|
||||
connect(act, &QAction::triggered, this, [localFile, socket] {
|
||||
socket->write("SHARE:");
|
||||
socket->write(localFile.toUtf8());
|
||||
socket->write("\n");
|
||||
socket->flush();
|
||||
act->setText(helper->shareActionString());
|
||||
connect(act, &QAction::triggered, this, [localFile, helper] {
|
||||
helper->sendCommand("SHARE:"+localFile.toUtf8()+"\n");
|
||||
} );
|
||||
|
||||
return { act };
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@ -2,5 +2,5 @@
|
||||
Type=Service
|
||||
Name=OwncloudAction
|
||||
ServiceTypes=KFileItemAction/Plugin
|
||||
MimeType=text/plain;
|
||||
MimeType=application/octet-stream;inode/directory;
|
||||
X-KDE-Library=ownclouddolphinpluginaction
|
||||
|
||||
@ -0,0 +1,98 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2014 by Olivier Goffart <ogoffart@woboq.com *
|
||||
* *
|
||||
* 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; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
|
||||
******************************************************************************/
|
||||
|
||||
#include <QtNetwork/QLocalSocket>
|
||||
#include <qcoreevent.h>
|
||||
#include <QFile>
|
||||
#include "ownclouddolphinpluginhelper.h"
|
||||
|
||||
OwncloudDolphinPluginHelper* OwncloudDolphinPluginHelper::instance()
|
||||
{
|
||||
static OwncloudDolphinPluginHelper self;
|
||||
return &self;
|
||||
}
|
||||
|
||||
OwncloudDolphinPluginHelper::OwncloudDolphinPluginHelper()
|
||||
{
|
||||
connect(&_socket, &QLocalSocket::connected, this, &OwncloudDolphinPluginHelper::slotConnected);
|
||||
connect(&_socket, &QLocalSocket::readyRead, this, &OwncloudDolphinPluginHelper::slotReadyRead);
|
||||
_connectTimer.start(45 * 1000, Qt::VeryCoarseTimer, this);
|
||||
tryConnect();
|
||||
}
|
||||
|
||||
void OwncloudDolphinPluginHelper::timerEvent(QTimerEvent *e)
|
||||
{
|
||||
if (e->timerId() == _connectTimer.timerId()) {
|
||||
tryConnect();
|
||||
return;
|
||||
}
|
||||
QObject::timerEvent(e);
|
||||
}
|
||||
|
||||
bool OwncloudDolphinPluginHelper::isConnected() const
|
||||
{
|
||||
return _socket.state() == QLocalSocket::ConnectedState;
|
||||
}
|
||||
|
||||
void OwncloudDolphinPluginHelper::sendCommand(const char* data)
|
||||
{
|
||||
_socket.write(data);
|
||||
_socket.flush();
|
||||
}
|
||||
|
||||
void OwncloudDolphinPluginHelper::slotConnected()
|
||||
{
|
||||
sendCommand("SHARE_MENU_TITLE:\n");
|
||||
}
|
||||
|
||||
void OwncloudDolphinPluginHelper::tryConnect()
|
||||
{
|
||||
if (_socket.state() != QLocalSocket::UnconnectedState) {
|
||||
return;
|
||||
}
|
||||
QString runtimeDir = QFile::decodeName(qgetenv("XDG_RUNTIME_DIR"));
|
||||
QString socketPath = runtimeDir + QLatin1String("/ownCloud/socket");
|
||||
_socket.connectToServer(socketPath);
|
||||
}
|
||||
|
||||
void OwncloudDolphinPluginHelper::slotReadyRead()
|
||||
{
|
||||
while (_socket.bytesAvailable()) {
|
||||
_line += _socket.readLine();
|
||||
if (!_line.endsWith("\n"))
|
||||
continue;
|
||||
QByteArray line;
|
||||
qSwap(line, _line);
|
||||
line.chop(1);
|
||||
if (line.isEmpty())
|
||||
continue;
|
||||
|
||||
if (line.startsWith("REGISTER_PATH:")) {
|
||||
auto col = line.indexOf(':');
|
||||
QString file = QString::fromUtf8(line.constData() + col + 1, line.size() - col - 1);
|
||||
_paths.append(file);
|
||||
continue;
|
||||
} else if (line.startsWith("SHARE_MENU_TITLE:")) {
|
||||
auto col = line.indexOf(':');
|
||||
_shareActionString = QString::fromUtf8(line.constData() + col + 1, line.size() - col - 1);
|
||||
continue;
|
||||
}
|
||||
emit commandRecieved(line);
|
||||
}
|
||||
}
|
||||
51
shell_integration/dolphin_kf5/ownclouddolphinpluginhelper.h
Normal file
51
shell_integration/dolphin_kf5/ownclouddolphinpluginhelper.h
Normal file
@ -0,0 +1,51 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2014 by Olivier Goffart <ogoffart@woboq.com *
|
||||
* *
|
||||
* 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; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#include <QObject>
|
||||
#include <QBasicTimer>
|
||||
#include <QLocalSocket>
|
||||
|
||||
class OwncloudDolphinPluginHelper : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static OwncloudDolphinPluginHelper *instance();
|
||||
|
||||
QString shareActionString() const { return _shareActionString; }
|
||||
bool isConnected() const;
|
||||
void sendCommand(const char *data);
|
||||
QVector<QString> paths() const { return _paths; }
|
||||
|
||||
signals:
|
||||
void commandRecieved(const QByteArray &cmd);
|
||||
|
||||
protected:
|
||||
void timerEvent(QTimerEvent*) override;
|
||||
|
||||
private:
|
||||
OwncloudDolphinPluginHelper();
|
||||
void slotConnected();
|
||||
void slotReadyRead();
|
||||
void tryConnect();
|
||||
QLocalSocket _socket;
|
||||
QByteArray _line;
|
||||
QVector<QString> _paths;
|
||||
QString _shareActionString;
|
||||
QBasicTimer _connectTimer;
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user