From fbcf0e484e5153194bcff723bdba153c4b2fd5b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20K=C3=BCgler?= Date: Thu, 29 Oct 2009 09:09:01 +0000 Subject: [PATCH] Add capability for Applets to specify X-Plasma-DropUrlPatterns, a QStringList of globs to match a URL dropped onto Plasma. This is orthogonal to the mimetype checking. http://reviewboard.kde.org/r/2005/#review2848 svn path=/trunk/KDE/kdelibs/; revision=1042124 --- applet.cpp | 23 ++++++++++++ applet.h | 8 ++++ containment.cpp | 50 ++++++++++++------------- data/servicetypes/plasma-applet.desktop | 3 ++ 4 files changed, 59 insertions(+), 25 deletions(-) diff --git a/applet.cpp b/applet.cpp index 372408905..cf4f89c01 100644 --- a/applet.cpp +++ b/applet.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -2079,6 +2080,28 @@ KPluginInfo::List Applet::listAppletInfoForMimetype(const QString &mimetype) return KPluginInfo::fromServices(offers); } +KPluginInfo::List Applet::listAppletInfoForUrl(const QUrl &url) +{ + QString constraint = "exist [X-Plasma-DropUrlPatterns]"; + KService::List offers = KServiceTypeTrader::self()->query("Plasma/Applet", constraint); + offers << KServiceTypeTrader::self()->query("Plasma/PopupApplet", constraint); + + KPluginInfo::List allApplets = KPluginInfo::fromServices(offers); + KPluginInfo::List filtered; + foreach (const KPluginInfo &info, allApplets) { + QStringList urlPatterns = info.property("X-Plasma-DropUrlPatterns").toStringList(); + foreach (const QString &glob, urlPatterns) { + QRegExp rx(glob); + rx.setPatternSyntax(QRegExp::Wildcard); + if (rx.exactMatch(url.toString())) { + kDebug() << info.name() << "matches" << glob << url; + filtered << info; + } + } + } + return filtered; +} + QStringList Applet::listCategories(const QString &parentApp, bool visibleOnly) { QString constraint = "exist [X-KDE-PluginInfo-Category]"; diff --git a/applet.h b/applet.h index aa9bef48a..9f7858d50 100644 --- a/applet.h +++ b/applet.h @@ -305,6 +305,14 @@ class PLASMA_EXPORT Applet : public QGraphicsWidget **/ static KPluginInfo::List listAppletInfoForMimetype(const QString &mimetype); + /** + * Returns a list of all known applets associated with a certain URL. + * + * @since 4.4 + * @return list of applets + **/ + static KPluginInfo::List listAppletInfoForUrl(const QUrl &url); + /** * Returns a list of all the categories used by installed applets. * diff --git a/containment.cpp b/containment.cpp index babd87e74..dd4666cf1 100644 --- a/containment.cpp +++ b/containment.cpp @@ -1213,7 +1213,6 @@ void Containment::dragMoveEvent(QGraphicsSceneDragDropEvent *event) d->showDropZoneDelayTimer->stop(); } } else if (!d->showDropZoneDelayTimer->isActive() && immutability() == Plasma::Mutable) { - kDebug() << event->pos().toPoint(); showDropZone(event->pos().toPoint()); } } @@ -1294,12 +1293,6 @@ void ContainmentPrivate::dropData(QPointF scenePos, QPoint screenPos, QGraphicsS QVariantList args; args << url.url(); kDebug() << "can decode" << mimeName << args; - kDebug() << "protocol:" << url.protocol(); - KPluginInfo::List appletList = Applet::listAppletInfoForMimetype(mimeName); - KPluginInfo::List wallpaperList; - if (q->drawWallpaper()) { - wallpaperList = Wallpaper::listWallpaperInfoForMimetype(mimeName); - } // It may be a directory or a file, let's stat KIO::JobFlags flags = KIO::HideProgressInfo; @@ -1418,28 +1411,35 @@ void ContainmentPrivate::remoteAppletReady(Plasma::AccessAppletJob *job) void ContainmentPrivate::dropJobResult(KJob *job) { - if (job->error()) { - // TODO: error feedback - clearDataForMimeJob(qobject_cast(job)); - kDebug() << "ERROR" << job->error() << ' ' << job->errorString(); + KIO::TransferJob* tjob = dynamic_cast(job); + if (!tjob) { + kDebug() << "job is not a KIO::TransferJob, won't handle the drop..."; + clearDataForMimeJob(tjob); + return; } + if (job->error()) { + kDebug() << "ERROR" << tjob->error() << ' ' << tjob->errorString(); + } + // We call mimetypeRetrieved since there might be other mechanisms + // for finding suitable applets. Cleanup happens there as well. + mimeTypeRetrieved(qobject_cast(job), QString()); } void ContainmentPrivate::mimeTypeRetrieved(KIO::Job *job, const QString &mimetype) { kDebug() << "Mimetype Job returns." << mimetype; - if (job->error()) { - // TODO: error feedback + KIO::TransferJob* tjob = dynamic_cast(job); + if (!tjob) { + kDebug() << "job should be a TransferJob, but isn't"; clearDataForMimeJob(job); - kDebug() << "ERROR" << job->error() << ' ' << job->errorString(); + return; + } + KPluginInfo::List appletList = Applet::listAppletInfoForUrl(tjob->url()); + if (mimetype.isEmpty() && !appletList.count()) { + clearDataForMimeJob(job); + kDebug() << "No applets found matching the url (" << tjob->url() << ") or the mimetype (" << mimetype << ")"; return; } else { - KIO::TransferJob* tjob = dynamic_cast(job); - if (!tjob) { - kDebug() << "job should be a TransferJob, but isn't"; - clearDataForMimeJob(job); - return; - } QPointF posi; // will be overwritten with the event's position if (dropPoints.keys().contains(tjob)) { @@ -1458,13 +1458,12 @@ void ContainmentPrivate::mimeTypeRetrieved(KIO::Job *job, const QString &mimetyp return; } - QVariantList args; args << tjob->url().url() << mimetype; kDebug() << "Creating menu for:" << mimetype << posi << args; - KPluginInfo::List appletList = Applet::listAppletInfoForMimetype(mimetype); + appletList << Applet::listAppletInfoForMimetype(mimetype); KPluginInfo::List wallpaperList; if (q->drawWallpaper()) { wallpaperList = Wallpaper::listWallpaperInfoForMimetype(mimetype); @@ -1514,9 +1513,10 @@ void ContainmentPrivate::mimeTypeRetrieved(KIO::Job *job, const QString &mimetyp // Put the job on hold so it can be recycled to fetch the actual content, // which is to be expected when something's dropped onto the desktop and // an applet is to be created with this URL - tjob->putOnHold(); - KIO::Scheduler::publishSlaveOnHold(); - + if (!mimetype.isEmpty() && !tjob->error()) { + tjob->putOnHold(); + KIO::Scheduler::publishSlaveOnHold(); + } QString plugin = actionsToApplets.value(choice); if (plugin.isEmpty()) { //set wallpapery stuff diff --git a/data/servicetypes/plasma-applet.desktop b/data/servicetypes/plasma-applet.desktop index 28f00f11f..ba744151a 100644 --- a/data/servicetypes/plasma-applet.desktop +++ b/data/servicetypes/plasma-applet.desktop @@ -76,6 +76,9 @@ Type=QString [PropertyDef::X-Plasma-DropMimeTypes] Type=QStringList +[PropertyDef::X-Plasma-DropUrlPatterns] +Type=QStringList + [PropertyDef::X-Plasma-DefaultSize] Type=QSize