Hello world advanced plugin: Anjuta Developers Reference Manual

## Hello world advanced plugin

We begin by writing the header file hello-world.h. It is a standard GObject class definition, minus the standard macro definitions. You can define the macros if you want, but for our hello-world plugin, we don't need it and have been removed for simplicity. Notice that our HelloWorldPlugin class is derived from abstract AnjutaPlugin class. All Anjuta plugins derive from this base class.

    #ifndef _HELLO_WORLD_PLUGIN_
    #define _HELLO_WORLD_PLUGIN_

    #include <libanjuta/anjuta-plugin.h>

    typedef struct {
    	AnjutaPlugin parent;

    	/* Hello world widget */
    	GtkWidget *widget;

    	/* Action group */
    	GObject* action_group;

    	/* UI merge ID. Required to unmerge it later */
    	gint uiid;

    } HelloWorldPlugin;

    typedef struct {
    	AnjutaPluginClass parent_class;
    } HelloWorldPluginClass;

    #endif

Next implement our plugin in hello-world.c file. We will be accessing a Document Manager plugin using IAnjutaDocumentManager interface, because all document manager plugins implement and expose this interface. If you use other interfaces, you can include their respective Plugin interfaces. For our hello-world plugin we begin by including following header files.

    /* Project configuration file */
    #include <config.h>

    /* Document manager interface */
    #include <libanjuta/interfaces/ianjuta-document-manager.h>

    /* plugin header file */
    #include "hello-world.h"

    /* Parent class. Part of standard class definition */
    static gpointer parent_class;

We have one action in our plugin and here is the callback for that. In this function, we are querying AnjutaShell for a plugin implementing IAnjutaDocumentManager interface and getting the current Editor. Editor is then checked to see if it implements IAnjutaFile interface, using which we determine filename of currently active editor. If the editor doesn't support IAnjutaFile interface, we show an error dialog.

    static void
    on_hello_action_activate (GtkAction *action, HelloWorldPlugin *plugin)
    {
    	IAnjutaDocument *doc;
    	IAnjutaDocumentManager *docman;
    	GtkWindow *parent_win;
    	gchar *filename;

    	/* We are using Anjuta widow as parent for displaying the dialog */
    	parent_win = GTK_WINDOW (ANJUTA_PLUGIN (plugin)->shell);

    	/* Query for object implementing IAnjutaDocumentManager interface */
    	docman = anjuta_shell_get_interface (ANJUTA_PLUGIN (plugin)->shell,
    	                                     IAnjutaDocumentManager, NULL);

    	/* Get current document */
    	doc = ianjuta_document_manager_get_current_document (docman, NULL);
    	filename = ianjuta_document_get_filename (doc, NULL);

    	/* Display the filename */
    	anjuta_util_dialog_info (parent_win,
    	                         "Current filename is: %s", filename);
    	g_free (filename);
    }

We then define our action entry. This is required for registering actions and UI merging. If your plugin doesn't have UI, they are not required. We have only one action, so there is only one entry defined. Read AnjutaUI and GtkUIManager for more details.

    static GtkActionEntry actions[] = {
    	{
    		"ActionFileHelloWorld",                   /* Action name */
    		GTK_STOCK_NEW,                            /* Stock icon, if any */
    		N_("_Hello world action"),                /* Display label */
    		NULL,                                     /* short-cut */
    		N_("This is hello world action"),         /* Tooltip */
    		G_CALLBACK (on_hello_action_activate)    /* action callback */
    	}
    };

We then implement activate() and deactivate() virtual methods of AnjutaPlugin class. They are called when plugin is activated and deactivated respectively. We put our UI merging, action registration and widgets additions in activate() method and undo them in deactivate() method.

    #define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta-hello-world.ui"

    static void
    activate_plugin (AnjutaPlugin *plugin)
    {
    	GtkWidget *wid;
    	AnjutaUI *ui;
    	HelloWorldPlugin *hello_plugin;
    	GtkActionGroup* action_group;

    	hello_plugin = (HelloWorldPlugin*) plugin;
    	ui = anjuta_shell_get_ui (plugin->shell, NULL);

    	/* Create hello plugin widget */
    	wid = gtk_label_new ("Hello World Plugin!!");
    	hello_plugin->widget = wid;

    	/* Add our actions */
    	action_group =
    	    anjuta_ui_add_action_group_entries (ui, "ActionGroupHello",
    	                                        _("Hello world"),
    	                                        actions,
    	                                        G_N_ELEMENTS (actions),
    	                                        plugin);
    	hello_plugin->action_group = action_group;

    	/* Merge UI */
    	hello_plugin->uiid = anjuta_ui_merge (ui, UI_FILE);

    	/* Add widget in Shell. Any number of widgets can be added */
    	anjuta_shell_add_widget (plugin->shell, wid,
    	                         "AnjutaHelloWorldPlugin",
    	                         _("HelloWorldPlugin"),
    	                         GTK_STOCK_ABOUT,
    	                         ANJUTA_SHELL_PLACEMENT_CENTER,
    	                         NULL);

    	return TRUE; /* FALSE if activation failed */
    }

    static gboolean
    deactivate_plugin (AnjutaPlugin *plugin)
    {
    	AnjutaUI *ui;
    	HelloWorldPlugin *hello_plugin;

    	hello_plugin = (HelloWorldPlugin*) plugin;
    	ui = anjuta_shell_get_ui (plugin->shell, NULL);

    	/* Remove widgets from Shell */
    	anjuta_shell_remove_widget (plugin->shell,
    	                            hello_plugin->widget,
    	                            NULL);
    	/* Unmerge UI */
    	anjuta_ui_unmerge (ui, hello_plugin->uiid);

    	/* Remove Action groups */
    	anjuta_ui_remove_action_group (ui, hello_plugin->action_group);

    	/* FALSE if plugin doesn't want to deactivate */
    	return TRUE;
    }

Followed by standard class definition. Notice that activate() and deactivate() methods are overridden in class_init() function.

    static void
    hello_world_plugin_instance_init (GObject *obj)
    {
    	HelloWorldPlugin *plugin = (HelloWorldPlugin*) obj;
    	plugin->uiid = 0;
    	plugin->widget = NULL;
    	plugin->action_group = NULL;
    }

    static void
    hello_world_plugin_class_init (GObjectClass *klass)
    {
    	AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);

    	parent_class = g_type_class_peek_parent (klass);

    	plugin_class->activate = activate_plugin;
    	plugin_class->deactivate = deactivate_plugin;
    }

    /* This line will change when we implement interfaces */
    ANJUTA_PLUGIN_BOILERPLATE (HelloWorldPlugin, hello_world_plugin);

    /* This sets up codes to register our plugin */
    ANJUTA_SIMPLE_PLUGIN (HelloWorldPlugin, hello_world_plugin);

That's it. We can now create the build structure to build it.