This is a multi-part message in MIME format. --nextPart3243019.1Z3f0Q291S Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" On Friday 04 July 2014 10:51:16 Olivier Goffart wrote: > Hi, > > I am working with the ownCloud sync client. One of the feature we would like > to have is to display overlay icons in the file managers. The icons should > display the synchronization state, and more importantly the fact that > folders are shared. > > As far as I could see, there is no interface in Konqueror or Dolphin to show > arbitrary overlay icon. > I am aware of KVersionControlPlugin (and we already have such a plugin), but > it's interface is too limited, as only some possibilities are available, > but we would like to display any kind of icons. > > I am then going to implement such interface. > Where should it go? > in a new KFileOverlayIconPlugin class? > Should id go in kio (next KAbstractFileItemActionPlugin)? > Or should it go in lib/konq next to KVersionControlPlugin? > > For the implementation, I believe I can base myself on the > KVersionControlPlugin but returning an QIcon instead of state. Thanks Frank and David for your answer. I drafted some (working) work in progress. The patch is attached. The prototype owncloud plugin is also attached (but the communication protocol is not set in stone and is going to be only released in the next version of the client) So I can have feedback if I'm going in the right direction. I guess I'm too late with this to go into KDE SC 4.14? So my next question is weather there would be another version of Dolphin based on kdelibs, or if I should just go for the frameworks branch. (For some reason, the "shared" icon is suddenly a very important feature for owncloud, and they would like to have it ASAP for the users now that Owncloud 7 (the server) was released) > Please reply to all, I am not subscribed. -- Olivier --nextPart3243019.1Z3f0Q291S Content-Disposition: attachment; filename="0001-WIP-add-KOverlayIconPlugin.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="UTF-8"; name="0001-WIP-add-KOverlayIconPlugin.patch" From 813f0fba8997c079e15dd0cc2509d26c9ae5af7d Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 17 Jul 2014 13:26:56 +0200 Subject: [PATCH] WIP: add KOverlayIconPlugin --- .../src/kitemviews/kfileitemmodelrolesupdater.cpp | 35 ++++++++++++- .../src/kitemviews/kfileitemmodelrolesupdater.h | 9 ++++ lib/konq/CMakeLists.txt | 4 +- lib/konq/koverlayiconplugin.cpp | 30 ++++++++++++ lib/konq/koverlayiconplugin.desktop | 4 ++ lib/konq/koverlayiconplugin.h | 57 ++++++++++++++++++++++ 6 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 lib/konq/koverlayiconplugin.cpp create mode 100644 lib/konq/koverlayiconplugin.desktop create mode 100644 lib/konq/koverlayiconplugin.h diff --git a/dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp b/dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp index 0865d40..840a65d 100644 --- a/dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp +++ b/dolphin/src/kitemviews/kfileitemmodelrolesupdater.cpp @@ -28,9 +28,11 @@ #include #include #include +#include #include "private/kpixmapmodifier.h" #include "private/kdirectorycontentscounter.h" +#include #include #include @@ -129,6 +131,17 @@ KFileItemModelRolesUpdater::KFileItemModelRolesUpdater(KFileItemModel* model, QO m_directoryContentsCounter = new KDirectoryContentsCounter(m_model, this); connect(m_directoryContentsCounter, SIGNAL(result(QString,int)), this, SLOT(slotDirectoryContentsCountReceived(QString,int))); + + + const KService::List pluginServices = KServiceTypeTrader::self()->query("KOverlayIconPlugin"); + + for (KService::List::ConstIterator it = pluginServices.constBegin(); it != pluginServices.constEnd(); ++it) { + KOverlayIconPlugin* plugin = (*it)->createInstance(this); + if (plugin) { + m_overlayIconsPlugin.append(plugin); + connect(plugin, SIGNAL(overlaysChanged(KUrl,QStringList)), this, SLOT(slotOverlaysChanged(KUrl,QStringList))); + } + } } KFileItemModelRolesUpdater::~KFileItemModelRolesUpdater() @@ -1075,7 +1088,11 @@ QHash KFileItemModelRolesUpdater::rolesData(const KFileIte data.insert("type", item.mimeComment()); } - data.insert("iconOverlays", item.overlays()); + QStringList overlays = item.overlays(); + foreach(KOverlayIconPlugin *it, m_overlayIconsPlugin) { + overlays.append(it->getOverlays(item)); + } + data.insert("iconOverlays", overlays); #ifdef HAVE_BALOO if (m_balooFileMonitor) { @@ -1086,6 +1103,22 @@ QHash KFileItemModelRolesUpdater::rolesData(const KFileIte return data; } +void KFileItemModelRolesUpdater::slotOverlaysChanged(const KUrl& url, const QStringList &) +{ + KFileItem item = m_model->fileItem(url); + if (item.isNull()) + return; + int index = m_model->index(item); + QHash data = m_model->data(index); + QStringList overlays = item.overlays(); + foreach(KOverlayIconPlugin *it, m_overlayIconsPlugin) { + overlays.append(it->getOverlays(item)); + } + data.insert("iconOverlays", overlays); + m_model->setData(index, data); +} + + void KFileItemModelRolesUpdater::updateAllPreviews() { if (m_state == Paused) { diff --git a/dolphin/src/kitemviews/kfileitemmodelrolesupdater.h b/dolphin/src/kitemviews/kfileitemmodelrolesupdater.h index a9e979a..6d3add0 100644 --- a/dolphin/src/kitemviews/kfileitemmodelrolesupdater.h +++ b/dolphin/src/kitemviews/kfileitemmodelrolesupdater.h @@ -32,6 +32,7 @@ #include #include +class KOverlayIconPlugin; class KDirectoryContentsCounter; class KFileItemModel; class KJob; @@ -180,6 +181,12 @@ private slots: void slotPreviewJobFinished(); /** + * Is invoked when one of the KOverlayIconPlugin emit the signal that an overlay has changed + */ + void slotOverlaysChanged(const KUrl&, const QStringList&); + + + /** * Resolves the sort role of the next item in m_pendingSortRole, applies it * to the model, and invokes itself if there are any pending items left. If * that is not the case, \a startUpdating() is called. @@ -331,6 +338,8 @@ private: KDirectoryContentsCounter* m_directoryContentsCounter; + QList m_overlayIconsPlugin; + #ifdef HAVE_BALOO Baloo::FileMonitor* m_balooFileMonitor; #endif diff --git a/lib/konq/CMakeLists.txt b/lib/konq/CMakeLists.txt index 8ecbfa9..7381caf 100644 --- a/lib/konq/CMakeLists.txt +++ b/lib/konq/CMakeLists.txt @@ -22,6 +22,7 @@ set(konq_LIB_SRCS konq_historyprovider.cpp kversioncontrolplugin.cpp # used by dolphin and its version control plugins (deprecated) kversioncontrolplugin2.cpp # used by dolphin and its version control plugins + koverlayiconplugin.cpp konq_nameandurlinputdialog.cpp # deprecated (functionality has moved to kdelibs) knewmenu.cpp # deprecated (functionality has moved to kdelibs) @@ -67,8 +68,9 @@ install( FILES konq_fileitemcapabilities.h kversioncontrolplugin.h kversioncontrolplugin2.h + koverlayiconplugin.h konq_historyprovider.h konq_historyentry.h DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel ) -install( FILES konqpopupmenuplugin.desktop konqdndpopupmenuplugin.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR} ) +install( FILES konqpopupmenuplugin.desktop konqdndpopupmenuplugin.desktop koverlayiconplugin.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR} ) diff --git a/lib/konq/koverlayiconplugin.cpp b/lib/konq/koverlayiconplugin.cpp new file mode 100644 index 0000000..6125040 --- /dev/null +++ b/lib/konq/koverlayiconplugin.cpp @@ -0,0 +1,30 @@ +/***************************************************************************** + * Copyright (C) 2014 by Olivier Goffart * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License version 2 as published by the Free Software Foundation. * + * * + * This library 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 * + * Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public License * + * along with this library; see the file COPYING.LIB. If not, write to * + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301, USA. * + *****************************************************************************/ + +#include "koverlayiconplugin.h" +#include + +KOverlayIconPlugin::KOverlayIconPlugin(QObject* parent) : QObject(parent) +{ +} + +KOverlayIconPlugin::~KOverlayIconPlugin() +{ +} + +#include "koverlayiconplugin.moc" diff --git a/lib/konq/koverlayiconplugin.desktop b/lib/konq/koverlayiconplugin.desktop new file mode 100644 index 0000000..65a1170 --- /dev/null +++ b/lib/konq/koverlayiconplugin.desktop @@ -0,0 +1,4 @@ +[Desktop Entry] +Type=ServiceType +X-KDE-ServiceType=KOverlayIconPlugin +Comment=Plugin to add overlay icons in Dolphin diff --git a/lib/konq/koverlayiconplugin.h b/lib/konq/koverlayiconplugin.h new file mode 100644 index 0000000..bcdf31b --- /dev/null +++ b/lib/konq/koverlayiconplugin.h @@ -0,0 +1,57 @@ +/***************************************************************************** + * Copyright (C) 2014 by Olivier Goffart * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License version 2 as published by the Free Software Foundation. * + * * + * This library 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 * + * Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public License * + * along with this library; see the file COPYING.LIB. If not, write to * + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301, USA. * + *****************************************************************************/ + + +#ifndef OverlayIconPlugin_H +#define OverlayIconPlugin_H + +#include +#include + +class KUrl; +class KFileItem; + +/** + * @brief Base class for overlay icon plugins. + * + * Enables the file manager to show custom overlay icons on files. + * + * To write a custom plugin you need to create a .desktop file for your plugin with + * KDE-ServiceTypes=KOverlayIconPlugin + */ +class LIBKONQ_EXPORT KOverlayIconPlugin : public QObject { + Q_OBJECT + void *d; +public: + explicit KOverlayIconPlugin(QObject *parent = 0); + ~KOverlayIconPlugin(); + + /** + * Returns a list of overlay pixmap to add to a file + * This can be a path to an icon, or the icon name + */ + virtual QStringList getOverlays(const KFileItem &item) = 0; +signals: + + /** + * Emit this signal when the list of overlay icon changed for a given URL + */ + void overlaysChanged(const KUrl &url, const QStringList &overlays); +}; + +#endif -- 2.0.1 --nextPart3243019.1Z3f0Q291S Content-Disposition: attachment; filename="ownclouddolphinplugin.cpp" Content-Transfer-Encoding: 7Bit Content-Type: text/x-c++src; charset="UTF-8"; name="ownclouddolphinplugin.cpp" /****************************************************************************** * Copyright (C) 2014 by Olivier Goffart #include #include #include #include #include #include class OwncloudDolphinPlugin : public KOverlayIconPlugin { Q_OBJECT QTcpSocket m_socket; typedef QHash StatusMap; StatusMap m_status; QByteArray m_line; public: explicit OwncloudDolphinPlugin(QObject* parent, const QList&) : KOverlayIconPlugin(parent) { connect(&m_socket, SIGNAL(readyRead()), this, SLOT(readyRead())); tryConnect(); } virtual QStringList getOverlays(const KFileItem& item) { KUrl url = item.url(); if (!url.isLocalFile()) return QStringList(); const QByteArray localFile = url.toLocalFile().toUtf8(); kDebug() << localFile; tryConnect(); if (m_socket.state() == QAbstractSocket::ConnectingState || m_socket.state() == QAbstractSocket::HostLookupState) { if (!m_socket.waitForConnected(100)) { kWarning() << "not connected" << m_socket.errorString(); } } if (m_socket.state() == QAbstractSocket::ConnectedState) { m_socket.write("RETRIEVE_FILE_STATUS:"); m_socket.write(localFile); m_socket.write("\n"); } StatusMap::iterator it = m_status.find(localFile); if (it != m_status.constEnd()) { return overlaysForString(*it); } return QStringList(); } private: void tryConnect() { if (m_socket.state() != QAbstractSocket::UnconnectedState) return; m_socket.connectToHost(QHostAddress::LocalHost, 33001); } QStringList overlaysForString(const QByteArray status) { QStringList r; if (status.startsWith("NOP")) return r; if (status.startsWith("OK")) r << "dialog-ok"; if (status.startsWith("SYNC") || status.startsWith("NEW")) r << "view-refresh"; if (status.contains("+SWM")) r << "document-share"; kDebug() << status << r; 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); kDebug() << "got line " << line; if (line.isEmpty()) continue; QList tokens = line.split(':'); if (tokens.count() != 3) continue; if (tokens[0] != "STATUS" && tokens[0] != "BROADCAST") continue; if (tokens[2].isEmpty()) continue; 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]; emit this->overlaysChanged(KUrl::fromLocalFile(QString::fromUtf8(name)), overlaysForString(status)); } } }; K_PLUGIN_FACTORY(OwncloudDolphinPluginFactory, registerPlugin();) K_EXPORT_PLUGIN(OwncloudDolphinPluginFactory("ownclouddolhpinplugin")) #include "ownclouddolphinplugin.moc" --nextPart3243019.1Z3f0Q291S--