diff --git a/kio/CMakeLists.txt b/kio/CMakeLists.txt index 02414026..b381eaec 100644 --- a/kio/CMakeLists.txt +++ b/kio/CMakeLists.txt @@ -1,21 +1,22 @@ include_directories(${CMAKE_SOURCE_DIR}) add_definitions(-DTRANSLATION_DOMAIN="kdeconnect-kio") set(kio_kdeconnect_PART_SRCS kiokdeconnect.cpp ) add_library(kio_kdeconnect MODULE ${kio_kdeconnect_PART_SRCS}) target_link_libraries(kio_kdeconnect kdeconnectinterfaces Qt5::Core Qt5::Gui Qt5::Network KF5::KIOCore KF5::I18n ) ########### install files ############### -install(TARGETS kio_kdeconnect DESTINATION ${PLUGIN_INSTALL_DIR}) -install(FILES kdeconnect.protocol DESTINATION ${SERVICES_INSTALL_DIR}) +set_target_properties(kio_kdeconnect PROPERTIES OUTPUT_NAME "kdeconnect") +set_target_properties(kio_kdeconnect PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/kf5/kio") +install(TARGETS kio_kdeconnect DESTINATION ${KDE_INSTALL_PLUGINDIR}/kf5/kio) diff --git a/kio/kdeconnect.json b/kio/kdeconnect.json new file mode 100644 index 00000000..d37269e0 --- /dev/null +++ b/kio/kdeconnect.json @@ -0,0 +1,26 @@ +{ + "KDE-KIO-Protocols": { + "kdeconnect": { + "Class": ":internet", + "Icon": "kdeconnect", + "copyFromFile": false, + "copyToFile": false, + "deleting": false, + "exec": "kdeconnect", + "input": "none", + "listing": [ + "Name", + "Type", + "Access", + "" + ], + "makedir": false, + "maxInstances": 2, + "moving": false, + "output": "filesystem", + "protocol": "kdeconnect", + "reading": true, + "writing": false + } + } +} diff --git a/kio/kdeconnect.protocol b/kio/kdeconnect.protocol deleted file mode 100644 index 73708447..00000000 --- a/kio/kdeconnect.protocol +++ /dev/null @@ -1,16 +0,0 @@ -[Protocol] -exec=kio_kdeconnect -protocol=kdeconnect -input=none -output=filesystem -copyToFile=false -copyFromFile=false -listing=Name,Type,Access -reading=true -writing=false -makedir=false -deleting=false -moving=false -Icon=kdeconnect -maxInstances=2 - diff --git a/kio/kiokdeconnect.cpp b/kio/kiokdeconnect.cpp index e0d7973d..0bf62a84 100644 --- a/kio/kiokdeconnect.cpp +++ b/kio/kiokdeconnect.cpp @@ -1,234 +1,246 @@ /** * Copyright 2013 Albert Vaca * * 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) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * 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, see . */ #include "kiokdeconnect.h" #include #include #include #include +#include Q_LOGGING_CATEGORY(KDECONNECT_KIO, "kdeconnect.kio") +class KIOPluginForMetaData : public QObject +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.kde.kio.slave.kdeconnect" FILE "kdeconnect.json") +}; + extern "C" int Q_DECL_EXPORT kdemain(int argc, char** argv) { + QCoreApplication app(argc, argv); + app.setApplicationName(QStringLiteral("kio_kdeconnect")); + if (argc != 4) { fprintf(stderr, "Usage: kio_kdeconnect protocol pool app\n"); exit(-1); } KioKdeconnect slave(argv[2], argv[3]); slave.dispatchLoop(); return 0; } //Some useful error mapping KIO::Error toKioError(const QDBusError::ErrorType type) { switch (type) { case QDBusError::NoError: return KIO::Error(KJob::NoError); case QDBusError::NoMemory: return KIO::ERR_OUT_OF_MEMORY; case QDBusError::Timeout: return KIO::ERR_SERVER_TIMEOUT; case QDBusError::TimedOut: return KIO::ERR_SERVER_TIMEOUT; default: return KIO::ERR_INTERNAL; }; }; template bool handleDBusError(QDBusReply& reply, KIO::SlaveBase* slave) { if (!reply.isValid()) { qCDebug(KDECONNECT_KIO) << "Error in DBus request:" << reply.error(); slave->error(toKioError(reply.error().type()),reply.error().message()); return true; } return false; } KioKdeconnect::KioKdeconnect(const QByteArray& pool, const QByteArray& app) : SlaveBase("kdeconnect", pool, app), m_dbusInterface(new DaemonDbusInterface(this)) { } void KioKdeconnect::listAllDevices() { infoMessage(i18n("Listing devices...")); //TODO: Change to all devices and show different icons for connected and disconnected? const QStringList devices = m_dbusInterface->devices(true, true); for (const QString& deviceId : devices) { DeviceDbusInterface interface(deviceId); if (!interface.hasPlugin(QStringLiteral("kdeconnect_sftp"))) continue; const QString path = QStringLiteral("kdeconnect://").append(deviceId).append("/"); const QString name = interface.name(); const QString icon = QStringLiteral("kdeconnect"); KIO::UDSEntry entry; entry.insert(KIO::UDSEntry::UDS_NAME, name); entry.insert(KIO::UDSEntry::UDS_ICON_NAME, icon); entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); entry.insert(KIO::UDSEntry::UDS_ACCESS, S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, QLatin1String("")); entry.insert(KIO::UDSEntry::UDS_URL, path); listEntry(entry); } // We also need a non-null and writable UDSentry for "." KIO::UDSEntry entry; entry.insert(KIO::UDSEntry::UDS_NAME, QStringLiteral(".")); entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); entry.insert(KIO::UDSEntry::UDS_SIZE, 0); entry.insert(KIO::UDSEntry::UDS_ACCESS, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH); listEntry(entry); infoMessage(QLatin1String("")); finished(); } void KioKdeconnect::listDevice() { infoMessage(i18n("Accessing device...")); qCDebug(KDECONNECT_KIO) << "ListDevice" << m_currentDevice; SftpDbusInterface interface(m_currentDevice); QDBusReply mountreply = interface.mountAndWait(); if (handleDBusError(mountreply, this)) { return; } if (!mountreply.value()) { error(KIO::ERR_COULD_NOT_MOUNT, i18n("Could not mount device filesystem")); return; } QDBusReply< QVariantMap > urlreply = interface.getDirectories(); if (handleDBusError(urlreply, this)) { return; } QVariantMap urls = urlreply.value(); for (QVariantMap::iterator it = urls.begin(); it != urls.end(); ++it) { const QString path = it.key(); const QString name = it.value().toString(); const QString icon = QStringLiteral("folder"); KIO::UDSEntry entry; entry.insert(KIO::UDSEntry::UDS_NAME, QStringLiteral("files")); entry.insert(KIO::UDSEntry::UDS_DISPLAY_NAME, name); entry.insert(KIO::UDSEntry::UDS_ICON_NAME, icon); entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); entry.insert(KIO::UDSEntry::UDS_ACCESS, S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, QLatin1String("")); entry.insert(KIO::UDSEntry::UDS_URL, QUrl::fromLocalFile(path).toString()); listEntry(entry); } // We also need a non-null and writable UDSentry for "." KIO::UDSEntry entry; entry.insert(KIO::UDSEntry::UDS_NAME, QStringLiteral(".")); entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); entry.insert(KIO::UDSEntry::UDS_SIZE, 0); entry.insert(KIO::UDSEntry::UDS_ACCESS, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH); listEntry(entry); infoMessage(QLatin1String("")); finished(); } void KioKdeconnect::listDir(const QUrl& url) { qCDebug(KDECONNECT_KIO) << "Listing..." << url; /// Url is not used here because all we could care about the url is the host, and that's already /// handled in @p setHost Q_UNUSED(url); if (!m_dbusInterface->isValid()) { infoMessage(i18n("Could not contact background service.")); finished(); return; } if (m_currentDevice.isEmpty()) { listAllDevices(); } else { listDevice(); } } void KioKdeconnect::stat(const QUrl& url) { qCDebug(KDECONNECT_KIO) << "Stat: " << url; KIO::UDSEntry entry; entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR); statEntry(entry); finished(); } void KioKdeconnect::get(const QUrl& url) { qCDebug(KDECONNECT_KIO) << "Get: " << url; mimeType(QLatin1String("")); finished(); } void KioKdeconnect::setHost(const QString& hostName, quint16 port, const QString& user, const QString& pass) { //This is called before everything else to set the file we want to show qCDebug(KDECONNECT_KIO) << "Setting host: " << hostName; // In this kio only the hostname is used Q_UNUSED(port) Q_UNUSED(user) Q_UNUSED(pass) m_currentDevice = hostName; } +//needed for JSON file embedding +#include "kiokdeconnect.moc"