KDE/kdevelop/lib

Andreas Pakulat apaku at gmx.de
Wed May 9 23:48:30 UTC 2007


SVN commit 663076 by apaku:

KDevelop say hello to your new way of handling context menus.

This is a first simple implementation, without the weights or any other extra
logic.  I added a build entry to the project manager view context menu to
demonstrate it.  The docs on the Context class got updated with some hints what
a plugin has to do.

Unfortunately for some unknown reason the signal mapper doesn't work, so only
the dummy buildSelectedItem slot is called at the moment. If anybody can give
me a hint whats wrong there that would be great

CCMAIL: kdevelop-devel at kdevelop.org


 M  +3 -1      interfaces/CMakeLists.txt  
 A             interfaces/context.cpp   kdevcontext.cpp#662974 [License: LGPL (v2+)]
 A             interfaces/context.h   kdevcontext.h#662974 [License: LGPL (v2+)]
 M  +8 -3      interfaces/iplugin.cpp  
 M  +5 -1      interfaces/iplugin.h  
 M  +4 -1      interfaces/iplugincontroller.h  
 D             kdevcontext.cpp  
 D             kdevcontext.h  
 M  +1 -17     plugins/projectmanagerview/projectmanagerview.cpp  
 M  +79 -0     plugins/projectmanagerview/projectmanagerview_part.cpp  
 M  +7 -0      plugins/projectmanagerview/projectmanagerview_part.h  
 M  +5 -17     plugins/projectmanagerview/projecttreeview.cpp  
 M  +0 -1      plugins/projectmanagerview/projecttreeview.h  
 M  +23 -0     shell/plugincontroller.cpp  
 M  +2 -0      shell/plugincontroller.h  


--- trunk/KDE/kdevelop/lib/interfaces/CMakeLists.txt #663075:663076
@@ -4,8 +4,9 @@
 )
 
 set(kdevplatforminterfaces_LIB_SRCS
+    context.cpp
     iplugin.cpp
-	idocument.cpp
+    idocument.cpp
     icore.cpp
     iuicontroller.cpp
     iplugincontroller.cpp
@@ -24,6 +25,7 @@
 install(TARGETS kdevplatforminterfaces DESTINATION ${LIB_INSTALL_DIR} )
 
 install(FILES
+    context.h
     iplugin.h
     icore.h
     iuicontroller.h
--- trunk/KDE/kdevelop/lib/interfaces/iplugin.cpp #663075:663076
@@ -85,10 +85,10 @@
         KXMLGUIClient(), d( new IPluginPrivate )
 {
     // The following cast is safe, there's no component in KDevPlatform that
-    // creates plugins except the plugincontroller. The controller passes 
-    // Core::self() as parent to KServiceTypeTrader::createInstanceFromQuery 
+    // creates plugins except the plugincontroller. The controller passes
+    // Core::self() as parent to KServiceTypeTrader::createInstanceFromQuery
     // so we know the parent is always a Core* pointer.
-    // This is the only way to pass the Core pointer to the plugin during its 
+    // This is the only way to pass the Core pointer to the plugin during its
     // creation so plugins have access to ICore during their creation.
     d->core = static_cast<KDevelop::ICore*>(parent);
     setComponentData( instance );
@@ -179,6 +179,11 @@
     d->m_extensions << ext;
 }
 
+QPair<QString,QList<QAction*> > KDevelop::IPlugin::requestContextMenuActions(
+        KDevelop::Context* )
+{
+    return qMakePair(QString(),QList<QAction*>());
+}
 
 #include "iplugin.moc"
 
--- trunk/KDE/kdevelop/lib/interfaces/iplugin.h #663075:663076
@@ -27,14 +27,15 @@
 
 #include <QList>
 #include <QPointer>
+#include <QPair>
 #include <QtDesigner/QExtensionManager>
 #include "kdevexport.h"
 
 class QWidget;
 class KInstance;
 class KIconLoader;
+class QAction;
 
-
 /**
  * Current KDevelop plugin interface version. Interfaces declare plugin version
  * to make sure old source (or binary) incompatible plugins are not loaded.
@@ -54,6 +55,7 @@
 {
 
 class ICore;
+class Context;
 
 /**
  * The base class for all KDevelop plugins.
@@ -180,6 +182,8 @@
         return qt_extension<Extension*>( extensionManager(), this );
     }
 
+    virtual QPair<QString,QList<QAction*> > requestContextMenuActions( KDevelop::Context* );
+
 public Q_SLOTS:
     /**
      * Re-initialize the global icon loader
--- trunk/KDE/kdevelop/lib/interfaces/iplugincontroller.h #663075:663076
@@ -35,6 +35,7 @@
 #include "kdevexport.h"
 
 class QExtensionManager;
+class KMenu;
 
 namespace KDevelop
 {
@@ -98,7 +99,7 @@
     virtual IPlugin *pluginForExtension(const QString &extension, const QString& pluginname = "" ) = 0;
 
     virtual QList<IPlugin*> allPluginsForExtension(const QString &extension, const QStringList &constraints) = 0;
-    
+
      /**
      * Queries for the plugin which supports given extension interface and returns a pointer to the extension interface.
      * This is the difference between this method and pluginForExtension, what returns the plugin itself.
@@ -152,6 +153,8 @@
 
     virtual QExtensionManager* extensionManager() = 0;
 
+    virtual void buildContextMenu( KDevelop::Context*, KMenu* ) = 0;
+
 Q_SIGNALS:
     void loadingPlugin( const QString& );
     void pluginLoaded( IPlugin* );
--- trunk/KDE/kdevelop/lib/plugins/projectmanagerview/projectmanagerview.cpp #663075:663076
@@ -87,23 +87,7 @@
                 m_projectOverview->selectionModel()->currentIndex() );
         if( item )
         {
-            while( !item->type() == ProjectBaseItem::Project )
-            {
-                ProjectBaseItem* it = dynamic_cast<ProjectBaseItem*>(item->parent());
-                if( !it )
-                    return;
-                item = it;
-            }
-            ProjectItem* prjitem = static_cast<ProjectItem*>(item);
-            IProject* project = item->project();
-            IPlugin* fmgr = project->managerPlugin();
-            IBuildSystemManager* mgr = fmgr->extension<IBuildSystemManager>();
-            if( mgr )
-            {
-                IProjectBuilder* builder = mgr->builder( prjitem );
-                if( builder)
-                  builder->build( item );
-            }
+            m_part->executeProjectBuilder( item );
         }
     }
 };
--- trunk/KDE/kdevelop/lib/plugins/projectmanagerview/projectmanagerview_part.cpp #663075:663076
@@ -30,6 +30,7 @@
 #include "iprojectbuilder.h"
 #include "iprojectcontroller.h"
 #include "importprojectjob.h"
+#include "context.h"
 
 #include <kservicetypetrader.h>
 #include <kgenericfactory.h>
@@ -44,6 +45,7 @@
 #include <QtCore/QFileInfo>
 #include <QtCore/QTimer>
 #include <QtCore/QList>
+#include <QtCore/QSignalMapper>
 
 namespace KDevelop
 {
@@ -71,13 +73,21 @@
 class ProjectManagerViewPartPrivate
 {
 public:
+    ProjectManagerViewPartPrivate() : build_objectname("projectmanagerview_buildaction")
+    {}
     KDevProjectManagerViewFactory *factory;
+    QMap<QString, Context*> contexts;
+    QSignalMapper* contextMenuMapper;
+    const QString build_objectname;
 };
 
 ProjectManagerViewPart::ProjectManagerViewPart( QObject *parent, const QStringList& )
         : IPlugin( ProjectManagerFactory::componentData(), parent ), d(new ProjectManagerViewPartPrivate)
 {
     d->factory = new KDevProjectManagerViewFactory( this );
+    d->contextMenuMapper = new QSignalMapper( this );
+    connect( d->contextMenuMapper, SIGNAL( mapped( const QString& ) ),
+             this, SLOT( executeContextMenuAction( const QString& ) ) );
     core()->uiController()->addToolView( "Project Manager", d->factory );
     setXMLFile( "kdevprojectmanagerview.rc" );
 }
@@ -142,7 +152,76 @@
     core()->uiController()->removeToolView(d->factory);
 }
 
+QPair<QString, QList<QAction*> > ProjectManagerViewPart::requestContextMenuActions( KDevelop::Context* context )
+{
+    if( context->type() == KDevelop::Context::ProjectItemContext )
+    {
+        QList<QAction*> actions;
+        KDevelop::ProjectItemContext* ctx = dynamic_cast<KDevelop::ProjectItemContext*>( context );
+        KDevelop::ProjectBaseItem* item = ctx->item();
+        if ( KDevelop::ProjectFolderItem *folder = item->folder() )
+        {
+            actions << new QAction( i18n( "Folder: %1", folder->url().directory() ), this );
+            //executeProjectBuilder( item );
+            QAction* buildaction = new QAction( i18n( "Build this project" ), this );
+            buildaction->setObjectName(d->build_objectname);
+            d->contextMenuMapper->setMapping( buildaction, buildaction->objectName() );
+            QObject* o = d->contextMenuMapper->mapping( buildaction->objectName() );
+            kDebug() << "Mapping object:" << o << "|" << (o == buildaction) << endl;
+            d->contexts[buildaction->objectName()] = context;
+            kDebug() << "Context Map:" << d->contexts << "|" << d->contexts[buildaction->objectName()] << endl;
+            connect( buildaction, SIGNAL(triggered() ), d->contextMenuMapper, SLOT( map() ) );
+            // This is a workaround to show that the stuff is working, for some reason the signal mapper doesn't work atm
+            connect( buildaction, SIGNAL( triggered() ), this, SLOT( buildSelectedItem() ) );
+            actions << buildaction;
+        }
+        else if ( KDevelop::ProjectFileItem *file = item->file() )
+        {
+            actions << new QAction( i18n( "File: %1", file->url().fileName() ), this );
+        }
+        else if ( KDevelop::ProjectTargetItem *target = item->target() )
+        {
+            actions << new QAction( i18n( "Target: %1", target->text() ), this );
+        }
+        return qMakePair(QString("Project Management"), actions);
+    }
+    return IPlugin::requestContextMenuActions( context );
 }
+
+void ProjectManagerViewPart::executeContextMenuAction( const QString& objectname )
+{
+    if( !d->contexts.contains(objectname) )
+        return;
+    Context* ctxt = d->contexts[objectname];
+    if( ctxt && objectname == d->build_objectname &&
+        ctxt->type() == KDevelop::Context::ProjectItemContext )
+    {
+        ProjectItemContext* prjctxt = dynamic_cast<ProjectItemContext*>(ctxt);
+        executeProjectBuilder( prjctxt->item() );
+    }
+}
+
+void ProjectManagerViewPart::buildSelectedItem()
+{
+    kDebug() << "building selected item" << endl;
+}
+
+void ProjectManagerViewPart::executeProjectBuilder( KDevelop::ProjectBaseItem* item )
+{
+    if( !item )
+        return;
+    IProject* project = item->project();
+    ProjectItem* prjitem = project->projectItem();
+    IPlugin* fmgr = project->managerPlugin();
+    IBuildSystemManager* mgr = fmgr->extension<IBuildSystemManager>();
+    if( mgr )
+    {
+        IProjectBuilder* builder = mgr->builder( prjitem );
+        if( builder)
+          builder->build( item );
+    }
+}
+}
 #include "projectmanagerview_part.moc"
 
 //kate: space-indent on; indent-width 4; tab-width: 4; replace-tabs on; auto-insert-doxygen on; indent-mode cstyle;
--- trunk/KDE/kdevelop/lib/plugins/projectmanagerview/projectmanagerview_part.h #663075:663076
@@ -62,6 +62,11 @@
     // Plugin methods
     virtual void unload();
 
+    QPair<QString, QList<QAction*> > requestContextMenuActions( Context* );
+
+
+    void executeProjectBuilder( KDevelop::ProjectBaseItem* );
+
 Q_SIGNALS:
     void refresh();
     void addedProjectItem(ProjectBaseItem *dom);
@@ -69,6 +74,8 @@
 
 public Q_SLOTS:
     void openURL(const KUrl &url);
+    void executeContextMenuAction( const QString& objectname );
+    void buildSelectedItem();
     void updateDetails(ProjectBaseItem *item);
 
 protected:
--- trunk/KDE/kdevelop/lib/plugins/projectmanagerview/projecttreeview.cpp #663075:663076
@@ -21,7 +21,8 @@
 #include "projecttreeview.h"
 #include "projectmanagerview_part.h"
 #include "projectmodel.h"
-
+#include "context.h"
+#include "iplugincontroller.h"
 #include <QtGui/QHeaderView>
 
 #include <icore.h>
@@ -161,26 +162,13 @@
 {
     QModelIndex index = indexAt( pos );
 
-    if ( ProjectBaseItem *item = projectModel()->item( index ) )
+    if ( KDevelop::ProjectBaseItem *item = projectModel()->item( index ) )
     {
         KMenu menu( this );
 
-        if ( ProjectFolderItem *folder = item->folder() )
-        {
-            menu.addTitle( i18n( "Folder: %1", folder->url().directory() ) );
-        }
-        else if ( ProjectFileItem *file = item->file() )
-        {
-            menu.addTitle( i18n( "File: %1", file->url().fileName() ) );
-        }
-        else if ( ProjectTargetItem *target = item->target() )
-        {
-            menu.addTitle( i18n( "Target: %1", target->text() ) );
-        }
+        KDevelop::ProjectItemContext context(item);
+        d->m_part->core()->pluginController()->buildContextMenu(&context, &menu);
 
-//       ProjectItemContext context(item);
-//       m_part->core()->mainWindow()->fillContextMenu(&menu, &context);
-
         menu.exec( mapToGlobal( pos ) );
     }
 }
--- trunk/KDE/kdevelop/lib/plugins/projectmanagerview/projecttreeview.h #663075:663076
@@ -67,7 +67,6 @@
 
     private:
         class ProjectTreeViewPrivate* const d;
-        ProjectManagerViewPart *m_part;
 };
 
 }
--- trunk/KDE/kdevelop/lib/shell/plugincontroller.cpp #663075:663076
@@ -43,6 +43,8 @@
 #include <kaction.h>
 #include <kxmlguifactory.h>
 #include <kstaticdeleter.h>
+#include <kmenu.h>
+#include <QAction>
 
 #include "iplugin.h"
 #include "profileengine.h"
@@ -453,7 +455,28 @@
     return names;
 }
 
+void PluginController::buildContextMenu( KDevelop::Context* context, KMenu* menu )
+{
+    Q_FOREACH( KPluginInfo* info, d->loadedPlugins.keys() )
+    {
+        IPlugin* plug = d->loadedPlugins[info];
+        QPair<QString, QList<QAction*> > actions = plug->requestContextMenuActions( context );
+        if( actions.first.isEmpty() || actions.second.isEmpty() )
+            continue;
+        if( actions.second.size() == 1 )
+        {
+            QAction* a = actions.second.first();
+            a->setText( a->text() + i18n( " (%1)", actions.first ) );
+            menu->addAction(a);
+        }else
+        {
+            QMenu* submenu = menu->addMenu( actions.first );
+            submenu->addActions( actions.second );
+        }
+    }
 }
+
+}
 #include "plugincontroller.moc"
 
 // kate: space-indent on; indent-width 4; tab-width: 4; replace-tabs on; auto-insert-doxygen on
--- trunk/KDE/kdevelop/lib/shell/plugincontroller.h #663075:663076
@@ -141,6 +141,8 @@
 
     QStringList allPluginNames();
 
+    void buildContextMenu( KDevelop::Context*, KMenu* );
+
 private Q_SLOTS:
     ///A plugin has been destroyed. Cleanup our data structures
     void pluginDestroyed( QObject* );




More information about the KDevelop-devel mailing list