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