[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    extragear/graphics/digikam/digikam
From:       Andi Clemens <andi.clemens () gmx ! net>
Date:       2009-04-19 14:07:34
Message-ID: 1240150054.534870.5173.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 956205 by aclemens:

Handle multiple item selection in OpenWith menu.
Now only those applications are listed that can work with the selected
mime types. If none of the services is able to work with all selected
items, the service submenu is removed and a simple action 'Open With...'
is added, which will open the KOpenWithDialog instead.

 M  +57 -24    contextmenuhelper.cpp  
 M  +2 -1      contextmenuhelper.h  


--- trunk/extragear/graphics/digikam/digikam/contextmenuhelper.cpp #956204:956205
@@ -46,6 +46,7 @@
 #include <kstandardaction.h>
 #include <kopenwithdialog.h>
 #include <krun.h>
+#include <kfileitem.h>
 
 // LibKIPI includes
 
@@ -174,10 +175,30 @@
 
 void ContextMenuHelper::addServicesMenu()
 {
-    // TODO: handle multiple selections correctly
-    KMimeType::Ptr mimePtr = KMimeType::findByUrl(d->selectedItems.first(), 0, true, true);
-    KService::List offers = KMimeTypeTrader::self()->query(mimePtr->name());
+    // This code is inspired from KonqMenuActions:
+    // kdebase/apps/lib/konq/konq_menuactions.cpp
 
+    QStringList mimeTypes;
+    foreach(const KUrl& item, d->selectedItems)
+    {
+        const QString mimeType = KMimeType::findByUrl(item, 0, true, true)->name();
+        if (!mimeTypes.contains(mimeType))
+            mimeTypes << mimeType;
+    }
+
+    // Query trader
+    const QString firstMimeType = mimeTypes.takeFirst();
+    const QString constraintTemplate = "'%1' in ServiceTypes";
+    QStringList constraints;
+    foreach(const QString& mimeType, mimeTypes)
+    {
+        constraints << constraintTemplate.arg(mimeType);
+    }
+
+    KService::List offers = KMimeTypeTrader::self()->query(firstMimeType,
+                                                           "Application",
+                                                           constraints.join( " and "));
+
     // remove duplicate service entries
     QSet<QString> seenApps;
     for (KService::List::iterator it = offers.begin(); it != offers.end();)
@@ -194,41 +215,53 @@
         }
     }
 
-    KMenu *servicesMenu = new KMenu(d->parent);
-    qDeleteAll(servicesMenu->actions());
+    if (!offers.isEmpty())
+    {
+        KMenu *servicesMenu = new KMenu(d->parent);
+        qDeleteAll(servicesMenu->actions());
 
-    QAction* menuAction = servicesMenu->menuAction();
-    menuAction->setText(i18n("Open With"));
+        QAction* serviceAction = servicesMenu->menuAction();
+        serviceAction->setText(i18n("Open With"));
 
-    foreach (KService::Ptr service, offers)
-    {
-        QString text = service->name().replace( '&', "&&" );
-        QAction* action = servicesMenu->addAction(text);
-        action->setIcon(KIcon(service->icon()));
-        action->setData(service->name());
-        d->servicesMap[text] = service;
-    }
+        foreach (KService::Ptr service, offers)
+        {
+            QString name = service->name().replace( '&', "&&" );
+            QAction* action = servicesMenu->addAction(name);
+            action->setIcon(KIcon(service->icon()));
+            action->setData(service->name());
+            d->servicesMap[name] = service;
+        }
 
-    if (!servicesMenu->isEmpty())
         servicesMenu->addSeparator();
+        servicesMenu->addAction(i18n("Other..."));
 
-    servicesMenu->addAction(i18n("Other Application..."));
+        addAction(serviceAction);
 
-    addAction(menuAction);
+        connect(servicesMenu, SIGNAL(triggered(QAction*)),
+                this, SLOT(slotOpenWith(QAction*)));
+    }
+    else
+    {
+        QAction *serviceAction = new QAction(i18n("Open With..."), this);
+        addAction(serviceAction);
 
-    connect(servicesMenu, SIGNAL(triggered(QAction*)),
-            this, SLOT(openWith(QAction*)));
+        connect(serviceAction, SIGNAL(triggered()),
+                this, SLOT(slotOpenWith()));
+    }
 }
 
-void ContextMenuHelper::openWith(QAction* action)
+void ContextMenuHelper::slotOpenWith()
 {
-    if (!action)
-        return;
+    // call the slot with an "empty" action
+    slotOpenWith(0);
+}
 
+void ContextMenuHelper::slotOpenWith(QAction* action)
+{
     KService::Ptr service;
     KUrl::List list = d->selectedItems;
 
-    QString name = action->data().toString();
+    QString name = action ? action->data().toString() : QString();
     if (name.isEmpty())
     {
         KOpenWithDialog dlg(list);
--- trunk/extragear/graphics/digikam/digikam/contextmenuhelper.h #956204:956205
@@ -322,7 +322,8 @@
 
 private Q_SLOTS:
 
-    void openWith(QAction* action);
+    void slotOpenWith();
+    void slotOpenWith(QAction* action);
 
 private:
 

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic