]> cloud.milkyroute.net Git - dolphin.git/commitdiff
- Add support for file item actions (see http://reviewboard.kde.org/r/5659/)
authorPeter Penz <peter.penz19@gmail.com>
Mon, 25 Oct 2010 13:45:34 +0000 (13:45 +0000)
committerPeter Penz <peter.penz19@gmail.com>
Mon, 25 Oct 2010 13:45:34 +0000 (13:45 +0000)
- Internal cleanups of DolphinContextMenu code

svn path=/trunk/KDE/kdebase/apps/; revision=1189651

src/dolphincontextmenu.cpp
src/dolphincontextmenu.h
src/dolphinmainwindow.cpp
src/settings/services/servicessettingspage.cpp
src/views/versioncontrol/versioncontrolobserver.cpp

index a3d913d6a02a8c9f026ff06c19d7cf121432a691..c2b15401295d176a3661c9c4008a87bb9a0c00b3 100644 (file)
@@ -28,6 +28,8 @@
 
 #include <kactioncollection.h>
 #include <kdesktopfile.h>
+#include <kfileitemactionplugin.h>
+#include <kfileitemactions.h>
 #include <kfileitemlistproperties.h>
 #include <kfileplacesmodel.h>
 #include <kglobal.h>
@@ -41,7 +43,7 @@
 #include <knewfilemenu.h>
 #include <konqmimedata.h>
 #include <konq_operations.h>
-#include <kfileitemactions.h>
+#include <kservice.h>
 #include <klocale.h>
 #include <kpropertiesdialog.h>
 #include <kstandardaction.h>
@@ -60,13 +62,15 @@ DolphinContextMenu::DolphinContextMenu(DolphinMainWindow* parent,
                                        const KFileItem& fileInfo,
                                        const KUrl& baseUrl) :
     m_mainWindow(parent),
-    m_capabilities(0),
     m_fileInfo(fileInfo),
     m_baseUrl(baseUrl),
+    m_baseFileItem(0),
+    m_selectedItems(),
+    m_selectedItemsProperties(0),
     m_context(NoContext),
     m_copyToMenu(parent),
     m_customActions(),
-    m_popup(new KMenu(m_mainWindow)),
+    m_popup(0),
     m_command(None),
     m_shiftPressed(false),
     m_removeAction(0)
@@ -75,9 +79,6 @@ DolphinContextMenu::DolphinContextMenu(DolphinMainWindow* parent,
     // or the items itself. To increase the performance both lists are cached.
     const DolphinView* view = m_mainWindow->activeViewContainer()->view();
     m_selectedItems = view->selectedItems();
-    foreach (const KFileItem &item, m_selectedItems) {
-        m_selectedUrls.append(item.url());
-    }
 
     if (m_keyInfo != 0) {
         if (m_keyInfo->isKeyPressed(Qt::Key_Shift) || m_keyInfo->isKeyLatched(Qt::Key_Shift)) {
@@ -89,12 +90,17 @@ DolphinContextMenu::DolphinContextMenu(DolphinMainWindow* parent,
 
     m_removeAction = new QAction(this);
     connect(m_removeAction, SIGNAL(triggered()), this, SLOT(slotRemoveActionTriggered()));
+
+    m_popup = new KMenu(m_mainWindow);
 }
 
 DolphinContextMenu::~DolphinContextMenu()
 {
-    delete m_capabilities;
-    m_capabilities = 0;
+    delete m_selectedItemsProperties;
+    m_selectedItemsProperties = 0;
+
+    delete m_popup;
+    m_popup = 0;
 }
 
 void DolphinContextMenu::setCustomActions(const QList<QAction*>& actions)
@@ -161,7 +167,7 @@ void DolphinContextMenu::openTrashContextMenu()
 
     addShowMenubarAction();
 
-    QAction* emptyTrashAction = new QAction(KIcon("trash-empty"), i18nc("@action:inmenu", "Empty Trash"), m_popup.data());
+    QAction* emptyTrashAction = new QAction(KIcon("trash-empty"), i18nc("@action:inmenu", "Empty Trash"), m_popup);
     KConfig trashConfig("trashrc", KConfig::SimpleConfig);
     emptyTrashAction->setEnabled(!trashConfig.group("Status").readEntry("Empty", true));
     m_popup->addAction(emptyTrashAction);
@@ -216,7 +222,12 @@ void DolphinContextMenu::openTrashItemContextMenu()
     m_popup->addAction(propertiesAction);
 
     if (m_popup->exec(QCursor::pos()) == restoreAction) {
-        KonqOperations::restoreTrashedItems(m_selectedUrls, m_mainWindow);
+        KUrl::List selectedUrls;
+        foreach (const KFileItem &item, m_selectedItems) {
+            selectedUrls.append(item.url());
+        }
+
+        KonqOperations::restoreTrashedItems(selectedUrls, m_mainWindow);
     }
 }
 
@@ -227,15 +238,15 @@ void DolphinContextMenu::openItemContextMenu()
     QAction* openParentInNewWindowAction = 0;
     QAction* openParentInNewTabAction = 0;
     QAction* addToPlacesAction = 0;
-    if (m_selectedUrls.count() == 1) {
+    if (m_selectedItems.count() == 1) {
         if (m_fileInfo.isDir()) {
             // setup 'Create New' menu
-            DolphinNewFileMenu* newFileMenu = new DolphinNewFileMenu(m_popup.data(), m_mainWindow);
+            DolphinNewFileMenu* newFileMenu = new DolphinNewFileMenu(m_popup, m_mainWindow);
             const DolphinView* view = m_mainWindow->activeViewContainer()->view();
             newFileMenu->setViewShowsHiddenFiles(view->showHiddenFiles());
             newFileMenu->checkUpToDate();
             newFileMenu->setPopupFiles(m_fileInfo.url());
-            newFileMenu->setEnabled(capabilities().supportsWriting());
+            newFileMenu->setEnabled(selectedItemsProperties().supportsWriting());
 
             KMenu* menu = newFileMenu->menu();
             menu->setTitle(i18nc("@title:menu Create new folder, file, link, etc.", "Create New"));
@@ -278,16 +289,18 @@ void DolphinContextMenu::openItemContextMenu()
     m_popup->addSeparator();
 
     KFileItemActions fileItemActions;
-    fileItemActions.setItemListProperties(capabilities());
+    fileItemActions.setItemListProperties(selectedItemsProperties());
     addServiceActions(fileItemActions);
 
-    addVersionControlActions();
+    addFileItemPluginActions();
+
+    addVersionControlPluginActions();
 
     // insert 'Copy To' and 'Move To' sub menus
     if (DolphinSettings::instance().generalSettings()->showCopyMoveMenu()) {
         m_copyToMenu.setItems(m_selectedItems);
-        m_copyToMenu.setReadOnly(!capabilities().supportsWriting());
-        m_copyToMenu.addActionsTo(m_popup.data());
+        m_copyToMenu.setReadOnly(!selectedItemsProperties().supportsWriting());
+        m_copyToMenu.addActionsTo(m_popup);
     }
 
     // insert 'Properties...' entry
@@ -341,14 +354,15 @@ void DolphinContextMenu::openViewportContextMenu()
     m_popup->addAction(pasteAction);
     m_popup->addSeparator();
 
-    // insert service actions
-    const KFileItem item(KFileItem::Unknown, KFileItem::Unknown, m_baseUrl);
-    const KFileItemListProperties baseUrlProperties(KFileItemList() << item);
+    // Insert service actions
+    const KFileItemListProperties baseUrlProperties(KFileItemList() << baseFileItem());
     KFileItemActions fileItemActions;
     fileItemActions.setItemListProperties(baseUrlProperties);
     addServiceActions(fileItemActions);
 
-    addVersionControlActions();
+    addFileItemPluginActions();
+
+    addVersionControlPluginActions();
 
     addCustomActions();
 
@@ -435,7 +449,7 @@ QAction* DolphinContextMenu::createPasteAction()
         action = new QAction(KIcon("edit-paste"), i18nc("@action:inmenu", "Paste Into Folder"), this);
         const QMimeData* mimeData = QApplication::clipboard()->mimeData();
         const KUrl::List pasteData = KUrl::List::fromMimeData(mimeData);
-        action->setEnabled(!pasteData.isEmpty() && capabilities().supportsWriting());
+        action->setEnabled(!pasteData.isEmpty() && selectedItemsProperties().supportsWriting());
         connect(action, SIGNAL(triggered()), m_mainWindow, SLOT(pasteIntoFolder()));
     } else {
         action = m_mainWindow->actionCollection()->action(KStandardAction::name(KStandardAction::Paste));
@@ -444,12 +458,20 @@ QAction* DolphinContextMenu::createPasteAction()
     return action;
 }
 
-KFileItemListProperties& DolphinContextMenu::capabilities()
+KFileItemListProperties& DolphinContextMenu::selectedItemsProperties()
+{
+    if (m_selectedItemsProperties == 0) {
+        m_selectedItemsProperties = new KFileItemListProperties(m_selectedItems);
+    }
+    return *m_selectedItemsProperties;
+}
+
+KFileItem DolphinContextMenu::baseFileItem()
 {
-    if (m_capabilities == 0) {
-        m_capabilities = new KFileItemListProperties(m_selectedItems);
+    if (m_baseFileItem == 0) {
+        m_baseFileItem = new KFileItem(KFileItem::Unknown, KFileItem::Unknown, m_baseUrl);
     }
-    return *m_capabilities;
+    return *m_baseFileItem;
 }
 
 void DolphinContextMenu::addServiceActions(KFileItemActions& fileItemActions)
@@ -457,13 +479,54 @@ void DolphinContextMenu::addServiceActions(KFileItemActions& fileItemActions)
     fileItemActions.setParentWidget(m_mainWindow);
 
     // insert 'Open With...' action or sub menu
-    fileItemActions.addOpenWithActionsTo(m_popup.data(), "DesktopEntryName != 'dolphin'");
+    fileItemActions.addOpenWithActionsTo(m_popup, "DesktopEntryName != 'dolphin'");
 
     // insert 'Actions' sub menu
-    fileItemActions.addServiceActionsTo(m_popup.data());
+    fileItemActions.addServiceActionsTo(m_popup);
+}
+
+void DolphinContextMenu::addFileItemPluginActions()
+{
+    KFileItemListProperties props;
+    if (m_selectedItems.isEmpty()) {
+        props.setItems(KFileItemList() << baseFileItem());
+    } else {
+        props = selectedItemsProperties();
+    }
+
+    QString commonMimeType = props.mimeType();
+    if (commonMimeType.isEmpty()) {
+        commonMimeType = QLatin1String("application/octet-stream");
+    }
+
+    const KService::List pluginServices = KMimeTypeTrader::self()->query(commonMimeType, "KFileItemAction/Plugin", "exist Library");
+    if (pluginServices.isEmpty()) {
+        return;
+    }
+
+    const KConfig config("kservicemenurc", KConfig::NoGlobals);
+    const KConfigGroup showGroup = config.group("Show");
+
+    foreach (const KSharedPtr<KService>& service, pluginServices) {
+        if (!showGroup.readEntry(service->desktopEntryName(), true)) {
+            // The plugin has been disabled
+            continue;
+        }
+
+        KFileItemActionPlugin* plugin = service->createInstance<KFileItemActionPlugin>();
+        if (plugin == 0) {
+            continue;
+        }
+
+        plugin->setParent(m_popup);
+        const QList<QAction*> actions = plugin->actions(props, m_mainWindow);
+        foreach (QAction* action, actions) {
+            m_popup->addAction(action);
+        }
+    }
 }
 
-void DolphinContextMenu::addVersionControlActions()
+void DolphinContextMenu::addVersionControlPluginActions()
 {
     const DolphinView* view = m_mainWindow->activeViewContainer()->view();
     const QList<QAction*> versionControlActions = view->versionControlActions(m_selectedItems);
@@ -485,7 +548,7 @@ void DolphinContextMenu::addCustomActions()
 void DolphinContextMenu::updateRemoveAction()
 {
     const KActionCollection* collection = m_mainWindow->actionCollection();
-    const bool moveToTrash = capabilities().isLocal() && !m_shiftPressed;
+    const bool moveToTrash = selectedItemsProperties().isLocal() && !m_shiftPressed;
 
     // Using m_removeAction->setText(action->text()) does not apply the &-shortcut.
     // This is only done until the original action has been shown at least once. To
index d6b99105367aece4bf1b012310ea51623603dbd8..f0eee235f04bee48682ae8aa3ef33358d2d196b6 100644 (file)
@@ -138,9 +138,33 @@ private:
 
     QAction* createPasteAction();
 
-    KFileItemListProperties& capabilities();
+    KFileItemListProperties& selectedItemsProperties();
+
+    /**
+     * Returns the file item for m_baseUrl.
+     */
+    KFileItem baseFileItem();
+
+    /**
+     * Adds actions that have been installed as service-menu.
+     * (see http://techbase.kde.org/index.php?title=Development/Tutorials/Creating_Konqueror_Service_Menus)
+     */
     void addServiceActions(KFileItemActions& fileItemActions);
-    void addVersionControlActions();
+
+    /**
+     * Adds actions that are provided by a KFileItemActionPlugin.
+     */
+    void addFileItemPluginActions();
+
+    /**
+     * Adds actions that are provided by a KVersionControlPlugin.
+     */
+    void addVersionControlPluginActions();
+
+    /**
+     * Adds custom actions e.g. like the "[x] Expandable Folders"-action
+     * provided in the details view.
+     */
     void addCustomActions();
 
     /**
@@ -168,15 +192,19 @@ private:
     };
 
     DolphinMainWindow* m_mainWindow;
-    KFileItemListProperties* m_capabilities;
+
     KFileItem m_fileInfo;
+
     KUrl m_baseUrl;
+    KFileItem* m_baseFileItem;  /// File item for m_baseUrl
+
     KFileItemList m_selectedItems;
-    KUrl::List m_selectedUrls;
+    KFileItemListProperties* m_selectedItemsProperties;
+
     int m_context;
     KonqCopyToMenu m_copyToMenu;
     QList<QAction*> m_customActions;
-    QScopedPointer<KMenu> m_popup;
+    KMenu* m_popup;
 
     Command m_command;
 
index 0913503d2b3fac166dce9fd7870037f12454881b..f24dd134340f1aec6e3ea0ba419a992da13fc7f0 100644 (file)
@@ -1193,9 +1193,9 @@ void DolphinMainWindow::openContextMenu(const KFileItem& item,
                                         const KUrl& url,
                                         const QList<QAction*>& customActions)
 {
-    DolphinContextMenu contextMenu(this, item, url);
-    contextMenu.setCustomActions(customActions);
-    const DolphinContextMenu::Command command = contextMenu.open();
+    QPointer<DolphinContextMenu> contextMenu = new DolphinContextMenu(this, item, url);
+    contextMenu->setCustomActions(customActions);
+    const DolphinContextMenu::Command command = contextMenu->open();
 
     switch (command) {
     case DolphinContextMenu::OpenParentFolderInNewWindow: {
@@ -1213,6 +1213,8 @@ void DolphinMainWindow::openContextMenu(const KFileItem& item,
     default:
         break;
     }
+
+    delete contextMenu;
 }
 
 void DolphinMainWindow::init()
index 7da29939930fc06fca5a2a4aa1976b618ddd961c..d2ad90e38e0305f620f9178868b0cc547eec4738 100644 (file)
@@ -86,7 +86,7 @@ ServicesSettingsPage::~ServicesSettingsPage()
 
 void ServicesSettingsPage::applySettings()
 {
-    // Apply service menu settings
+    // Apply service menu settingsentries
     KConfig config("kservicemenurc", KConfig::NoGlobals);
     KConfigGroup showGroup = config.group("Show");
 
@@ -146,6 +146,7 @@ void ServicesSettingsPage::loadServices()
     const KConfig config("kservicemenurc", KConfig::NoGlobals);
     const KConfigGroup showGroup = config.group("Show");
 
+    // Load generic services
     const KService::List entries = KServiceTypeTrader::self()->query("KonqPopupMenu/Plugin");
     foreach (const KSharedPtr<KService>& service, entries) {
         const QString file = KStandardDirs::locate("services", service->entryPath());
@@ -156,10 +157,10 @@ void ServicesSettingsPage::loadServices()
         const QString subMenuName = desktopFile.desktopGroup().readEntry("X-KDE-Submenu");
 
         foreach (const KServiceAction& action, serviceActions) {
-            const QString service = action.name();
+            const QString serviceName = action.name();
             const bool addService = !action.noDisplay()
                                     && !action.isSeparator()
-                                    && !isInServicesList(service);
+                                    && !isInServicesList(serviceName);
 
             if (addService) {
                 const QString itemName = subMenuName.isEmpty()
@@ -168,12 +169,26 @@ void ServicesSettingsPage::loadServices()
                 QListWidgetItem* item = new QListWidgetItem(KIcon(action.icon()),
                                                             itemName,
                                                             m_servicesList);
-                item->setData(Qt::UserRole, service);
-                const bool show = showGroup.readEntry(service, true);
+                item->setData(Qt::UserRole, serviceName);
+                const bool show = showGroup.readEntry(serviceName, true);
                 item->setCheckState(show ? Qt::Checked : Qt::Unchecked);
             }
         }
     }
+
+    // Load service plugins that implement the KFileItemActionPlugin interface
+    const KService::List pluginServices = KServiceTypeTrader::self()->query("KFileItemAction/Plugin");
+    foreach (const KSharedPtr<KService>& service, pluginServices) {
+        const QString serviceName = service->desktopEntryName();
+        if (!isInServicesList(serviceName)) {
+            QListWidgetItem* item = new QListWidgetItem(KIcon(service->icon()),
+                                                        service->name(),
+                                                        m_servicesList);
+            item->setData(Qt::UserRole, serviceName);
+            const bool show = showGroup.readEntry(serviceName, true);
+            item->setCheckState(show ? Qt::Checked : Qt::Unchecked);
+        }
+    }
 }
 
 void ServicesSettingsPage::loadVersionControlSystems()
index 51337e097a45869229363c5b4db0402d131250e4..9c3939632d6d10a77262807868161cd8ea781c48 100644 (file)
@@ -282,8 +282,9 @@ KVersionControlPlugin* VersionControlObserver::searchPlugin(const KUrl& director
         for (KService::List::ConstIterator it = pluginServices.constBegin(); it != pluginServices.constEnd(); ++it) {
             if (enabledPlugins.contains((*it)->name())) {
                 KVersionControlPlugin* plugin = (*it)->createInstance<KVersionControlPlugin>();
-                Q_ASSERT(plugin != 0);
-                plugins.append(plugin);
+                if (plugin != 0) {
+                    plugins.append(plugin);
+                }
             }
         }
         if (plugins.isEmpty()) {