diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 52 | ||||
-rw-r--r-- | src/anjuta-plugin-sdk.plugin.in | 5 | ||||
-rw-r--r-- | src/anjuta-plugin-sdk.png | bin | 0 -> 3056 bytes | |||
-rw-r--r-- | src/plugin.c | 472 | ||||
-rw-r--r-- | src/plugin.h | 50 |
5 files changed, 579 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..fc54af5 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,52 @@ +# Sample Makefile for a anjuta plugin. + +# Plugin Icon file +anjuta_plugin_sdk_pixmapsdir = $(anjuta_image_dir) +anjuta_plugin_sdk_pixmaps_DATA = anjuta-plugin-sdk.png + +# Plugin description file +plugin_in_files = anjuta-plugin-sdk.plugin.in +%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache + +anjuta_plugin_sdk_plugindir = $(anjuta_plugin_dir) +anjuta_plugin_sdk_plugin_DATA = $(plugin_in_files:.plugin.in=.plugin) + +# NOTE : +# The naming convention is very intentional +# We are forced to use the prefix 'lib' by automake and libtool +# There is probably a way to avoid it but it is not worth to effort +# to find out. +# The 'anjuta_' prfix is a safety measure to avoid conflicts where the +# plugin 'libpython.so' needs to link with the real 'libpython.so' + +# Include paths +INCLUDES = \ + -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \ + -DANJUTA_DATA_DIR=\"$(anjuta_data_dir)\" \ + -DANJUTA_PLUGIN_DIR=\"$(anjuta_plugin_dir)\" \ + -DANJUTA_IMAGE_DIR=\"$(anjuta_image_dir)\" \ + -DANJUTA_GLADE_DIR=\"$(anjuta_glade_dir)\" \ + -DANJUTA_UI_DIR=\"$(anjuta_ui_dir)\" \ + -DPACKAGE_DATA_DIR=\"$(datadir)\" \ + -DPACKAGE_SRC_DIR=\"$(srcdir)\" \ + $(LIBANJUTA_CFLAGS) + +# Where to install the plugin +plugindir = $(anjuta_plugin_dir) + +# The plugin +plugin_LTLIBRARIES = libanjuta-plugin-sdk.la + +# Plugin sources +libanjuta_plugin_sdk_la_SOURCES = plugin.c plugin.h + +# Plugin dependencies +libanjuta_plugin_sdk_la_LIBADD = \ + $(LIBANJUTA_LIBS) + +EXTRA_DIST = \ + $(plugin_in_files) \ + $(anjuta_plugin_sdk_plugin_DATA) \ + $(anjuta_plugin_sdk_ui_DATA) \ + $(anjuta_plugin_sdk_glade_DATA) \ + $(anjuta_plugin_sdk_pixmaps_DATA) diff --git a/src/anjuta-plugin-sdk.plugin.in b/src/anjuta-plugin-sdk.plugin.in new file mode 100644 index 0000000..edcbb17 --- /dev/null +++ b/src/anjuta-plugin-sdk.plugin.in @@ -0,0 +1,5 @@ +[Anjuta Plugin] +Location=anjuta-plugin-sdk:AnjutaPluginSdk +Icon=anjuta-plugin-sdk.png +_Name=Anjuta external SDK plugin +_Description=A plugin that allows integration with an external SDK. diff --git a/src/anjuta-plugin-sdk.png b/src/anjuta-plugin-sdk.png Binary files differnew file mode 100644 index 0000000..3cd250b --- /dev/null +++ b/src/anjuta-plugin-sdk.png diff --git a/src/plugin.c b/src/plugin.c new file mode 100644 index 0000000..076cc31 --- /dev/null +++ b/src/plugin.c @@ -0,0 +1,472 @@ +/* + * Copyright (C) 2007 OpenedHand Ltd. + * Authored by: Rob Bradford <rob@o-hand.com> + * + * This is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, version 2 of the License. + * + * This software is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <config.h> +#include <libanjuta/anjuta-shell.h> +#include <libanjuta/anjuta-debug.h> +#include <libanjuta/interfaces/ianjuta-document-manager.h> + +#include "plugin.h" + +#define PREFS_PROP_SDK_ROOT "sdk.root" +#define PREFS_PROP_TRIPLET "sdk.triplet" + +static gpointer anjuta_plugin_sdk_parent_class; + +static gchar * +file_chooser_property_get_cb (AnjutaProperty *prop) +{ + GtkWidget *chooser = NULL; + gchar *filename = NULL; + + chooser = anjuta_property_get_widget (prop); + filename = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (chooser)); + + return filename; +} + +static void +file_chooser_property_set_cb (AnjutaProperty *prop, const gchar *value) +{ + GtkWidget *chooser = NULL; + + chooser = anjuta_property_get_widget (prop); + + if (value != NULL && chooser != NULL) + gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser), value); +} + +static void +sdk_root_file_chooser_changed_cb (GtkFileChooserButton *button, gpointer userdata) +{ + AnjutaPluginSdk *sp = (AnjutaPluginSdk *)userdata; + gchar *filename = NULL; + + filename = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (button)); + + anjuta_preferences_set (ANJUTA_PREFERENCES (sp->prefs), PREFS_PROP_SDK_ROOT, + filename); + g_free (filename); +} + +static void +update_path (AnjutaPluginSdk *sp) +{ + char *path = NULL; + gchar **pathv = NULL; + gchar **new_pathv = NULL; + + gchar **path_it = NULL; + gchar **new_path_it = NULL; + + gchar *new_path_component = NULL; + + if (sp->triplet != NULL && sp->sdk_root != NULL) + { + new_path_component = g_build_filename (sp->sdk_root, "bin", NULL); + } + + g_debug ("New path component: %s", new_path_component); + + /* get current path. do not free */ + path = getenv ("PATH"); + + g_debug ("Current path: %s", path); + + /* split old path up */ + pathv = g_strsplit (path, ":", -1); + + /* allocate memory for new pathv */ + new_pathv = g_malloc0 ((g_strv_length (pathv) + 2) * (sizeof (gchar *))); + + /* new pathv iterator */ + new_path_it = new_pathv; + + /* insert at the front if we have something to insert */ + if (new_path_component) + { + *new_path_it = new_path_component; + new_path_it++; + } + + /* iterate through */ + for (path_it = pathv; *path_it != NULL; path_it++) + { + /* Check for the old component */ + if (sp->path_component && g_str_equal (*path_it, sp->path_component)) + { + path_it++; /* skip over */ + } + + *new_path_it = *path_it; + new_path_it++; + } + + + /* Create our new path */ + path = g_strjoinv (":", new_pathv); + setenv ("PATH", path, 1); + + g_debug ("New path: %s", path); + + /* Save the component */ + g_free (sp->path_component); + sp->path_component = new_path_component; +} + +static void +update_environment (AnjutaPluginSdk *sp) +{ + gchar *tmp = NULL; + + g_free (sp->sdk_root); + g_free (sp->triplet); + + sp->sdk_root = anjuta_preferences_get (ANJUTA_PREFERENCES (sp->prefs), + PREFS_PROP_SDK_ROOT); + sp->triplet = anjuta_preferences_get (ANJUTA_PREFERENCES (sp->prefs), + PREFS_PROP_TRIPLET); + + if (sp->triplet == NULL || sp->sdk_root == NULL) + { + /* unset environment keys */ + unsetenv ("PKG_CONFIG_SYSROOT_DIR"); + unsetenv ("PKG_CONFIG_PATH"); + unsetenv ("CONFIG_SITE"); + } + + update_path (sp); + + tmp = g_build_filename (sp->sdk_root, sp->triplet, NULL); + setenv ("PKG_CONFIG_SYSROOT_DIR", tmp, 1); + g_free (tmp); + + tmp = g_build_filename (sp->sdk_root, sp->triplet, "lib", "pkgconfig", NULL); + setenv ("PKG_CONFIG_PATH", tmp, 1); + g_free (tmp); + + tmp = g_build_filename (sp->sdk_root, "site-config", NULL); + setenv ("CONFIG_SITE", tmp, 1); + g_free (tmp); +} + +static void +cleanup_environment (AnjutaPluginSdk *sp) +{ + g_free (sp->triplet); + g_free (sp->sdk_root); + + sp->triplet = NULL; + sp->sdk_root = NULL; + + update_path (sp); +} + +static void +update_configure_opts (AnjutaPluginSdk *sp) +{ + /* + * can't do anything to update the option. must instead do it in the + * session-load signal + */ +} + +/* idle callback used to aggregate updates */ +static gboolean +update_environment_idle_cb (gpointer userdata) +{ + update_environment ((AnjutaPluginSdk *)userdata); + return FALSE; +} + +static void +sdk_root_preference_notify_cb (GConfClient *client, guint cnxn_id, + GConfEntry *entry, gpointer userdata) +{ + AnjutaPluginSdk *sp = (AnjutaPluginSdk *)userdata; + + if (!sp->update_environment_idle) + g_idle_add (update_environment_idle_cb, sp); +} + +static void +triplet_preference_notify_cb (GConfClient *client, guint cnxn_id, + GConfEntry *entry, gpointer userdata) +{ + AnjutaPluginSdk *sp = (AnjutaPluginSdk *)userdata; + + if (!sp->update_environment_idle) + g_idle_add (update_environment_idle_cb, sp); + + update_configure_opts (sp); +} + +/* + * cb that gets fired when the session is loaded up, we use this fiddle with + * the configure option to add our --host option for cross compiling + */ +static void +load_session_cb (AnjutaShell *shell, AnjutaSessionPhase phase, + AnjutaSession *session, gpointer userdata) +{ + AnjutaPluginSdk *sp = (AnjutaPluginSdk *)userdata; + gchar *tmp = NULL; + gchar *configure_opts = NULL; + + tmp = anjuta_session_get_string (session, "Build", + "Configure parameters"); + + if (sp->triplet) + { + if (tmp != NULL) + { + /* check if already present */ + if (strstr (tmp, "--host=") == NULL) + { + configure_opts = g_strdup_printf ("%s --host=%s", tmp, sp->triplet); + } + } else { + configure_opts = g_strdup_printf ("--host=%s", sp->triplet); + } + + anjuta_session_set_string (session, "Build", + "Configure parameters", configure_opts); + } + + g_free (configure_opts); + g_free (tmp); +} + +static void +anjuta_plugin_sdk_setup_preferences (AnjutaPluginSdk *sp) +{ + GtkWidget *vbox; + GtkSizeGroup *opts_labels_group; + GtkSizeGroup *opts_fields_group; + GtkWidget *frame; + GtkWidget *inner_vbox; + GtkWidget *hbox; + GtkWidget *label; + GtkWidget *chooser; + GtkWidget *entry; + GtkWidget *inner_alignment; + gboolean res; + + sp->prefs = anjuta_preferences_new (); + + /* Create main vbox */ + vbox = gtk_vbox_new (FALSE, 6); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 6); + + /* Frame for options */ + frame = gtk_frame_new (_("<b>SDK options</b>")); + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 2); + label = gtk_frame_get_label_widget (GTK_FRAME (frame)); + gtk_label_set_use_markup (GTK_LABEL (label), TRUE); + gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE); + + /* size groups for files */ + opts_labels_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + opts_fields_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + + /* Pack inner vbox */ + inner_vbox = gtk_vbox_new (FALSE, 6); + inner_alignment = gtk_alignment_new (0, 0.5, 1, 1); + g_object_set (inner_alignment, "left-padding", 12, "top-padding", 6, NULL); + gtk_container_add (GTK_CONTAINER (inner_alignment), inner_vbox); + gtk_container_add (GTK_CONTAINER (frame), inner_alignment); + + /* Widgets for sdk root */ + hbox = gtk_hbox_new (FALSE, 6); + gtk_box_pack_start (GTK_BOX (inner_vbox), hbox, TRUE, FALSE, 0); + + /* label */ + label = gtk_label_new (_("SDK root: ")); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + gtk_size_group_add_widget (opts_labels_group, label); + gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5); + + /* chooser */ + chooser = gtk_file_chooser_button_new (_("Select SDK root"), + GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER); + sp->sdk_root_chooser = chooser; + gtk_box_pack_start (GTK_BOX (hbox), chooser, TRUE, TRUE, 0); + gtk_size_group_add_widget (opts_fields_group, label); + + /* register prop */ + res = anjuta_preferences_register_property_custom (ANJUTA_PREFERENCES (sp->prefs), + chooser, + PREFS_PROP_SDK_ROOT, + NULL, + ANJUTA_PROPERTY_DATA_TYPE_TEXT, + 0, + file_chooser_property_set_cb, + file_chooser_property_get_cb); + + if (!res) + g_warning ("Error adding preference for SDK root"); + + /* signal for file changed */ + g_signal_connect (chooser, "current-folder-changed", + (GCallback)sdk_root_file_chooser_changed_cb, sp); + + /* Widgets for toolchain triplet */ + hbox = gtk_hbox_new (FALSE, 6); + gtk_box_pack_start (GTK_BOX (inner_vbox), hbox, TRUE, FALSE, 0); + + /* label */ + label = gtk_label_new (_("Toolchain triplet: ")); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + gtk_size_group_add_widget (opts_labels_group, label); + gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5); + + /* entry */ + entry = gtk_entry_new (); + sp->triplet_entry = entry; + gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0); + gtk_size_group_add_widget (opts_fields_group, label); + + /* register prop */ + res = anjuta_preferences_register_property_raw (ANJUTA_PREFERENCES (sp->prefs), + entry, + PREFS_PROP_TRIPLET, + NULL, + 0, + ANJUTA_PROPERTY_OBJECT_TYPE_ENTRY, + ANJUTA_PROPERTY_DATA_TYPE_TEXT); + + if (!res) + g_warning ("Error adding preference for triplet"); + + /* Add a label requesting restart */ + label = gtk_label_new (_("<i>Anjuta must be restarted for these changes to take effect</i>")); + gtk_label_set_use_markup (GTK_LABEL (label), TRUE); + gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 2); + gtk_widget_show_all (vbox); + + /* add page */ + anjuta_preferences_dialog_add_page (ANJUTA_PREFERENCES_DIALOG (sp->prefs), + _("SDK"), "SDK", NULL, + vbox); + + /* callbacks for when the preferences are changed */ + sp->sdk_root_notifyid = anjuta_preferences_notify_add (ANJUTA_PREFERENCES (sp->prefs), + PREFS_PROP_SDK_ROOT, + sdk_root_preference_notify_cb, + sp, + NULL); + sp->triplet_notifyid = anjuta_preferences_notify_add (ANJUTA_PREFERENCES (sp->prefs), + PREFS_PROP_TRIPLET, + triplet_preference_notify_cb, + sp, + NULL); +} + +static void +anjuta_plugin_sdk_unsetup_preferences (AnjutaPluginSdk *sp) +{ + /* remove page */ + anjuta_preferences_dialog_remove_page (ANJUTA_PREFERENCES_DIALOG (sp->prefs), + "SDK"); + + /* remove callbacks */ + anjuta_preferences_notify_remove (ANJUTA_PREFERENCES (sp->prefs), + sp->sdk_root_notifyid); + anjuta_preferences_notify_remove (ANJUTA_PREFERENCES (sp->prefs), + sp->triplet_notifyid); +} + +static gboolean +anjuta_plugin_sdk_activate (AnjutaPlugin *plugin) +{ + AnjutaUI *ui; + AnjutaPluginSdk *sp = (AnjutaPluginSdk *)plugin; + + ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (plugin)->shell, NULL); + + anjuta_plugin_sdk_setup_preferences (sp); + + update_environment (sp); + + /* hook up a signal for session loading */ + + g_signal_connect (ANJUTA_PLUGIN (plugin)->shell, + "load-session", (GCallback)load_session_cb, sp); + + return TRUE; +} + +static gboolean +anjuta_plugin_sdk_deactivate (AnjutaPlugin *plugin) +{ + AnjutaPluginSdk *sp = (AnjutaPluginSdk *)plugin; + + anjuta_plugin_sdk_unsetup_preferences (sp); + cleanup_environment (sp); + + g_signal_handlers_disconnect_by_func (ANJUTA_PLUGIN (plugin)->shell, + load_session_cb, sp); + + g_free (sp->sdk_root); + g_free (sp->triplet); + g_free (sp->path_component); + + return TRUE; +} + +static void +anjuta_plugin_sdk_finalize (GObject *obj) +{ + if (G_OBJECT_CLASS (anjuta_plugin_sdk_parent_class)->finalize) + G_OBJECT_CLASS (anjuta_plugin_sdk_parent_class)->finalize (obj); +} + +static void +anjuta_plugin_sdk_dispose (GObject *obj) +{ + AnjutaPluginSdk *sp = (AnjutaPluginSdk *)obj; + + if (sp->prefs) + { + gtk_widget_destroy (sp->prefs); + sp->prefs = NULL; + } + + if (G_OBJECT_CLASS (anjuta_plugin_sdk_parent_class)->dispose) + G_OBJECT_CLASS (anjuta_plugin_sdk_parent_class)->dispose (obj); +} + +static void +anjuta_plugin_sdk_instance_init (GObject *obj) +{ +} + +static void +anjuta_plugin_sdk_class_init (GObjectClass *klass) +{ + AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass); + + anjuta_plugin_sdk_parent_class = g_type_class_peek_parent (klass); + + plugin_class->activate = anjuta_plugin_sdk_activate; + plugin_class->deactivate = anjuta_plugin_sdk_deactivate; + klass->finalize = anjuta_plugin_sdk_finalize; + klass->dispose = anjuta_plugin_sdk_dispose; +} + +ANJUTA_PLUGIN_BOILERPLATE (AnjutaPluginSdk, anjuta_plugin_sdk); +ANJUTA_SIMPLE_PLUGIN (AnjutaPluginSdk, anjuta_plugin_sdk); diff --git a/src/plugin.h b/src/plugin.h new file mode 100644 index 0000000..56bcaca --- /dev/null +++ b/src/plugin.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2007 OpenedHand Ltd. + * Authored by: Rob Bradford <rob@o-hand.com> + * + * This is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, version 2 of the License. + * + * This software is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _ANJUTA_PLUGIN_SDK_H_ +#define _ANJUTA_PLUGIN_SDK_H_ + +#include <libanjuta/anjuta-plugin.h> + +typedef struct _AnjutaPluginSdk AnjutaPluginSdk; +typedef struct _AnjutaPluginSdkClass AnjutaPluginSdkClass; + +struct _AnjutaPluginSdk +{ + AnjutaPlugin parent; + + GtkWidget *prefs; + + GtkWidget *sdk_root_chooser; + GtkWidget *triplet_entry; + + guint sdk_root_notifyid; + guint triplet_notifyid; + + guint update_environment_idle; + + gchar *triplet; + gchar *sdk_root; + + gchar *path_component; +}; + +struct _AnjutaPluginSdkClass +{ + AnjutaPluginClass parent_class; +}; +#endif |