[geany/geany-plugins] d645bf: Complete the configuration widget of codenav plugin
federeghe
git-noreply at xxxxx
Thu Sep 11 20:39:05 UTC 2014
Branch: refs/heads/master
Author: federeghe <federico.dev at reghe.net>
Committer: federeghe <federico.dev at reghe.net>
Date: Tue, 15 Apr 2014 06:52:28 UTC
Commit: d645bf57477277725851ee6aed2c7a9aa7d96edc
https://github.com/geany/geany-plugins/commit/d645bf57477277725851ee6aed2c7a9aa7d96edc
Log Message:
-----------
Complete the configuration widget of codenav plugin
Modified Paths:
--------------
codenav/src/codenavigation.c
codenav/src/codenavigation.h
codenav/src/switch_head_impl.c
codenav/src/switch_head_impl.h
Modified: codenav/src/codenavigation.c
493 lines changed, 436 insertions(+), 57 deletions(-)
===================================================================
@@ -3,6 +3,7 @@
* part of the "geany-plugins" project.
*
* Copyright 2009 Lionel Fuentes <funto66(at)gmail(dot)com>
+ * Copyright 2014 Federico Reghenzani <federico(dot)dev(at)reghe(dot)net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,11 +21,6 @@
* MA 02110-1301, USA.
*/
-/**
- * Code navigation plugin - plugin which adds facilities for navigating between files.
- * 2009 Lionel Fuentes.
- */
-
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -34,55 +30,147 @@
#include "switch_head_impl.h"
#include "goto_file.h"
-/************************* Global variables ***************************/
-
-/* These items are set by Geany before plugin_init() is called. */
-GeanyPlugin *geany_plugin;
-GeanyData *geany_data;
-GeanyFunctions *geany_functions;
+/************************* Plugin utilities ***************************/
/* Check that the running Geany supports the plugin API used below, and check
* for binary compatibility. */
-PLUGIN_VERSION_CHECK(112)
+PLUGIN_VERSION_CHECK(200)
/* All plugins must set name, description, version and author. */
PLUGIN_SET_TRANSLATABLE_INFO(
LOCALEDIR,
GETTEXT_PACKAGE,
_("Code navigation"),
- _( "This plugin adds features to facilitate navigation between source files.\n"
- "As for the moment, it implements :\n"
- "- switching between a .cpp file and the corresponding .h file\n"
- "- [opening a file by typing its name -> TODO]"), CODE_NAVIGATION_VERSION, "Lionel Fuentes")
+ _( "This plugin adds features to facilitate navigation between source files."),
+ CODE_NAVIGATION_VERSION, "Lionel Fuentes, Federico Reghenzani")
/* Declare "GeanyKeyGroupInfo plugin_key_group_info[1]" and "GeanyKeyGroup *plugin_key_group",
* for Geany to find the keybindings */
PLUGIN_KEY_GROUP(code_navigation, NB_KEY_IDS)
-/***************************** Functions ******************************/
+
+/********************* Data types for the feature *********************/
+/* Column for the configuration widget */
+typedef enum
+{
+ COLUMN_IMPL = 0,
+ COLUMN_HEAD,
+ NB_COLUMNS
+} Column;
+
+/************************* Global variables ***************************/
+
+/* These items are set by Geany before plugin_init() is called. */
+GeanyPlugin *geany_plugin;
+GeanyData *geany_data;
+GeanyFunctions *geany_functions;
+
+static GtkListStore *list_store; /* for settings dialog */
+
+
+/**************************** Prototypes ******************************/
+
+GtkWidget*
+config_widget(void);
+
+static void
+load_configuration();
+
+static void
+on_configure_add_language(GtkWidget* widget, gpointer data);
+
+static void
+on_configure_remove_language(GtkWidget* widget, gpointer data);
+
+static void
+on_configure_cell_edited(GtkCellRendererText* text, gchar* arg1, gchar* arg2, gpointer data);
static void
on_configure_response(GtkDialog *dialog, gint response, gpointer user_data);
-/* ---------------------------------------------------------------------
- * Called by Geany to initialize the plugin.
- * Note: data is the same as geany_data.
- * ---------------------------------------------------------------------
+/***************************** Functions ******************************/
+
+/**
+ * @brief Called by Geany to initialize the plugin.
+ * @note data is the same as geany_data.
*/
void plugin_init(GeanyData *data)
{
log_func();
+ /* Load configuration */
+ load_configuration();
/* Initialize the features */
switch_head_impl_init();
goto_file_init();
}
-/* ---------------------------------------------------------------------
- * Called by Geany to show the plugin's configure dialog. This function
- * is always called after plugin_init() is called.
- * ---------------------------------------------------------------------
+/**
+ * @brief load plugin's configuration or set default values
+ * @param void
+ * @return void
+ *
+ */
+static void load_configuration()
+{
+ GKeyFile *config = NULL;
+ gchar *config_filename = NULL;
+ gchar **impl_list = NULL, **head_list = NULL;
+ gsize head_list_len, impl_list_len;
+ int i;
+
+ /* Load user configuration */
+ config = g_key_file_new();
+ config_filename = g_strconcat(geany->app->configdir, G_DIR_SEPARATOR_S,
+ "plugins", G_DIR_SEPARATOR_S, "codenav", G_DIR_SEPARATOR_S, "codenav.conf", NULL);
+ gboolean is_configured = g_key_file_load_from_file(config, config_filename, G_KEY_FILE_NONE, NULL);
+
+ if ( is_configured ) {
+ log_debug("Loading user configuration");
+ impl_list = g_key_file_get_string_list(config, "switch_head_impl", "implementations_list", &impl_list_len, NULL);
+ head_list = g_key_file_get_string_list(config, "switch_head_impl", "headers_list", &head_list_len, NULL);
+
+ // Wrong lists
+ if ( head_list_len != impl_list_len ) {
+ dialogs_show_msgbox(GTK_MESSAGE_WARNING,
+ _("Codenav head/impl lists should have been same length. " \
+ "Geany will use the default configuration."));
+ fill_default_languages_list();
+ }
+ else
+ fill_languages_list((const gchar**) impl_list, (const gchar**) head_list, head_list_len);
+ }
+ else {
+ log_debug("Fresh configuration");
+ fill_default_languages_list();
+ }
+
+
+ /* Freeing memory */
+ g_key_file_free(config);
+ g_free(config_filename);
+
+ if ( impl_list != NULL ) {
+ for ( i = 0; i < impl_list_len; i++ )
+ g_free(impl_list[i]);
+ g_free(impl_list);
+ }
+ if ( head_list != NULL ) {
+ for ( i = 0; i < head_list_len; i++ )
+ g_free(head_list[i]);
+ g_free(head_list);
+ }
+
+}
+
+/**
+ * @brief Called by Geany to show the plugin's configure dialog. This function
+ * is always called after plugin_init() is called.
+ * @param the plugin GtkWidget*
+ * @return the GtkDialog from Geany
+ *
*/
+
GtkWidget *plugin_configure(GtkDialog *dialog)
{
GtkWidget *vbox;
@@ -92,7 +180,7 @@ GtkWidget *plugin_configure(GtkDialog *dialog)
vbox = gtk_vbox_new(FALSE, 6);
/* Switch header/implementation widget */
- gtk_box_pack_start(GTK_BOX(vbox), switch_head_impl_config_widget(), TRUE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), config_widget(), TRUE, TRUE, 0);
gtk_widget_show_all(vbox);
@@ -102,9 +190,11 @@ GtkWidget *plugin_configure(GtkDialog *dialog)
return vbox;
}
-/* ---------------------------------------------------------------------
- * Called by Geany before unloading the plugin.
- * ---------------------------------------------------------------------
+/**
+ * @brief Called by Geany before unloading the plugin
+ * @param void
+ * @return void
+ *
*/
void plugin_cleanup(void)
{
@@ -115,45 +205,334 @@ void plugin_cleanup(void)
switch_head_impl_cleanup();
}
-/* ---------------------------------------------------------------------
- * Callback called when validating the configuration of the plug-in
- * ---------------------------------------------------------------------
+/**
+ * @brief Callback called when validating the configuration of the plug-in
+ * @param dialog the parent dialog, not very interesting here
+ * @param response OK/Cancel/Apply user action
+ * @param user_data NULL
+ *
+ * @return void
+ *
*/
static void
on_configure_response(GtkDialog* dialog, gint response, gpointer user_data)
{
- /* TODO */
-#if 0
- GKeyFile* key_file = NULL;
- gchar* config_dir = NULL;
- gchar* config_filename = NULL;
+ gint i=0;
+
+ GKeyFile *config = NULL;
+ gchar *config_filename = NULL;
+ gchar *config_dir = NULL;
+ gchar *data;
+
+ gsize list_len;
+ gchar** head_list = NULL;
+ gchar** impl_list = NULL;
+
+ GtkTreeIter iter;
+
+ log_func();
+
+ if(response != GTK_RESPONSE_OK && response != GTK_RESPONSE_APPLY)
+ return;
+
+ /* Write the settings into a file, using GLib's GKeyFile API.
+ * File name :
+ * geany->app->configdir G_DIR_SEPARATOR_S "plugins" G_DIR_SEPARATOR_S
+ * "codenav" G_DIR_SEPARATOR_S "codenav.conf"
+ * e.g. this could be: ~/.config/geany/plugins/codenav/codenav.conf
+ */
+
+ /* Open the GKeyFile */
+ config = g_key_file_new();
+ config_filename = g_strconcat(geany->app->configdir, G_DIR_SEPARATOR_S,
+ "plugins", G_DIR_SEPARATOR_S, "codenav",
+ G_DIR_SEPARATOR_S, "codenav.conf", NULL);
+ config_dir = g_path_get_dirname(config_filename);
+
+ /* Allocate the list */
+ list_len = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(list_store), NULL);
+ impl_list = g_malloc0( sizeof(gchar**) * list_len);
+ head_list = g_malloc0( sizeof(gchar**) * list_len);
+
+ if ( list_len > 0 ) {
+ // Get the first item
+ gtk_tree_model_iter_children (GTK_TREE_MODEL(list_store),&iter,NULL);
+
+ do { /* forall elements in list... */
+
+ /* TODO: remove empty lines */
+
+ gtk_tree_model_get (GTK_TREE_MODEL(list_store),&iter,
+ COLUMN_IMPL,&impl_list[i], -1);
+ gtk_tree_model_get (GTK_TREE_MODEL(list_store),&iter,
+ COLUMN_HEAD,&head_list[i], -1);
+ i++;
+ } while ( gtk_tree_model_iter_next(GTK_TREE_MODEL(list_store), &iter) );
+ }
+
+ /* write lists */
+ g_key_file_set_string_list(config, "switch_head_impl", "implementations_list",
+ (const gchar * const*)impl_list, list_len);
+ g_key_file_set_string_list(config, "switch_head_impl", "headers_list",
+ (const gchar * const*)head_list, list_len);
+
+ if (! g_file_test(config_dir, G_FILE_TEST_IS_DIR) && utils_mkdir(config_dir, TRUE) != 0)
+ {
+ dialogs_show_msgbox(GTK_MESSAGE_ERROR,
+ _("Plugin configuration directory could not be created."));
+ }
+ else
+ {
+ /* write config to file */
+ data = g_key_file_to_data(config, NULL, NULL);
+ utils_write_file(config_filename, data);
+ g_free(data);
+ }
+
+ fill_languages_list((const gchar**)impl_list, (const gchar**)head_list, list_len);
+
+ /* Freeing memory */
+ for ( i=0; i < list_len; i++ ) {
+ g_free(impl_list[i]);
+ g_free(head_list[i]);
+ }
+ g_free(impl_list);
+ g_free(head_list);
+
+ g_free(config_dir);
+ g_free(config_filename);
+ g_key_file_free(config);
+
+}
+
+ /**
+ * @brief Utility function to concatenate the extensions of a language,
+ * separated with a comma, like PHP-implode function.
+ * @param extensions a list of (string) extensions
+ *
+ * @return concatenated string.
+ *
+ */
+static gchar*
+concatenate_extensions(GSList* extensions)
+{
+ GSList* iter_ext;
+ gchar* p_str = NULL;
+ gchar* temp = NULL;
- if(response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY)
+ for(iter_ext = extensions ; iter_ext != NULL ; iter_ext = iter_ext->next)
{
- /* Write the settings into a file, using GLib's GKeyFile API.
- * File name :
- * geany->app->configdir G_DIR_SEPARATOR_S "plugins" G_DIR_SEPARATOR_S "codenav" G_DIR_SEPARATOR_S "codenav.conf"
- * e.g. this could be: ~/.config/geany/plugins/codenav/codenav.conf
- */
+ temp = p_str;
+ p_str = g_strjoin(",", (const gchar*)(iter_ext->data), p_str, NULL);
+ g_free(temp);
+ }
+
+ return p_str;
+}
+
+/**
+ * @brief Utility function to add a language to a GtkListStore
+ * @param list the list where to add lang
+ * @param lang the item to add
+ *
+ * @return void
+ *
+ */
+static void
+add_language(GtkListStore* list, Language* lang)
+{
+ gchar* p_str = NULL;
+ GtkTreeIter tree_iter;
+
+ if(lang->head_extensions == NULL || lang->impl_extensions == NULL)
+ return;
+
+ /* Append an empty row */
+ gtk_list_store_append(list, &tree_iter);
+
+ /* Header extensions */
+ p_str = concatenate_extensions(lang->head_extensions);
+ gtk_list_store_set(list, &tree_iter, COLUMN_HEAD, p_str, -1);
+ g_free(p_str);
+
+ /* Implementation extensions */
+ p_str = concatenate_extensions(lang->impl_extensions);
+ gtk_list_store_set(list, &tree_iter, COLUMN_IMPL, p_str, -1);
+ g_free(p_str);
+}
+
+/**
+ * @brief The configuration widget
+ *
+ * @return The configuration widget
+ *
+ */
+GtkWidget*
+config_widget(void)
+{
+ GtkWidget *help_label;
+ GtkWidget *frame, *vbox, *tree_view;
+ GtkWidget *hbox_buttons, *add_button, *remove_button;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *cell_renderer;
+
+ GSList *iter_lang;
+
+ log_func();
+
+ /* Frame, which is the returned widget */
+ frame = gtk_frame_new(_("Switch header/implementation"));
+
+ /* Main VBox */
+ vbox = gtk_vbox_new(FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(frame), vbox);
+
+ /* Help label */
+ help_label = gtk_label_new(_("You can specify multiple extensions by " \
+ "separating them by commas."));
+ gtk_box_pack_start(GTK_BOX(vbox), help_label, FALSE, FALSE, 6);
+
+ /* ======= Extensions list ======= */
+
+ /* Add a list containing the extensions for each language (headers / implementations) */
+ /* - create the GtkListStore */
+ list_store = gtk_list_store_new(NB_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
+
+ /* - fill the GtkListStore with the extensions of the languages */
+ for(iter_lang = switch_head_impl_get_languages();
+ iter_lang != NULL ; iter_lang = iter_lang->next)
+ add_language(list_store, (Language*)(iter_lang->data));
+
+ /* - create the GtkTreeView */
+ tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list_store));
+
+ /* - add the columns */
+ /* -> implementations : */
+ cell_renderer = gtk_cell_renderer_text_new();
+ g_object_set(G_OBJECT(cell_renderer), "editable", TRUE, NULL);
+ g_signal_connect_after(G_OBJECT(cell_renderer), "edited", G_CALLBACK(on_configure_cell_edited), GINT_TO_POINTER(COLUMN_IMPL));
+ column = gtk_tree_view_column_new_with_attributes( _("Implementations extensions"), cell_renderer,
+ "text", COLUMN_IMPL,
+ NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
+
+ /* -> headers : */
+ cell_renderer = gtk_cell_renderer_text_new();
+ g_object_set(G_OBJECT(cell_renderer), "editable", TRUE, NULL);
+ g_signal_connect_after(G_OBJECT(cell_renderer), "edited", G_CALLBACK(on_configure_cell_edited), GINT_TO_POINTER(COLUMN_HEAD));
+ column = gtk_tree_view_column_new_with_attributes( _("Headers extensions"), cell_renderer,
+ "text", COLUMN_HEAD,
+ NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
+
+
+ /* - finally add the GtkTreeView to the frame's vbox */
+ gtk_box_pack_start(GTK_BOX(vbox), tree_view, TRUE, TRUE, 6);
- /* Open the GKeyFile */
- key_file = g_key_file_new();
- config_dir = g_strconcat(geany->app->configdir,
- G_DIR_SEPARATOR_S "plugins" G_DIR_SEPARATOR_S "codenav" G_DIR_SEPARATOR_S, NULL);
+ /* ========= Buttons ======== */
- config_filename = g_strconcat(config_dir, "codenav.conf", NULL);
+ /* HBox */
+ hbox_buttons = gtk_hbox_new(FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox_buttons, FALSE, FALSE, 0);
- /* Load configuration */
- g_key_file_load_from_file(key_file, config_filename, G_KEY_FILE_NONE, NULL);
+ /* Add the "add" button to the frame's hbox */
+ add_button = gtk_button_new_from_stock(GTK_STOCK_ADD);
+ g_signal_connect(G_OBJECT(add_button), "clicked", G_CALLBACK(on_configure_add_language), tree_view);
+ gtk_box_pack_start(GTK_BOX(hbox_buttons), add_button, FALSE, FALSE, 0);
- /* Write configuration */
- write_switch_head_impl_config(key_file);
+ /* Add the "remove" button to the frame's hbox */
+ remove_button = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
+ g_signal_connect(G_OBJECT(remove_button), "clicked", G_CALLBACK(on_configure_remove_language), tree_view);
+ gtk_box_pack_start(GTK_BOX(hbox_buttons), remove_button, FALSE, FALSE, 0);
- /* Cleanup */
- g_free(config_filename);
- g_free(config_dir);
- g_key_file_free(key_file);
+
+ gtk_widget_grab_focus(tree_view);
+
+ return frame;
+}
+
+ /**
+ * @brief Callback for adding a language in the configuration dialog
+ * @param button the button, not used here
+ * @param data gtktreeview where to act
+ *
+ * @return void
+ *
+ */
+static void
+on_configure_add_language(GtkWidget* button, gpointer data)
+{
+ GtkWidget* tree_view = (GtkWidget*)data;
+ GtkTreeIter tree_iter;
+ GtkTreePath *path;
+ GtkTreeViewColumn* column = NULL;
+ gint nb_lines;
+
+ log_func();
+
+ /* Add a line */
+ gtk_list_store_append(list_store, &tree_iter);
+
+ /* and give the focus to it */
+ nb_lines = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(list_store), NULL);
+ path = gtk_tree_path_new_from_indices(nb_lines-1, -1);
+ column = gtk_tree_view_get_column(GTK_TREE_VIEW(tree_view), 0);
+ gtk_tree_view_set_cursor(GTK_TREE_VIEW(tree_view), path, column, TRUE);
+
+ gtk_tree_path_free(path);
+}
+
+/**
+ * @brief Callback for removing a language in the configuration dialog
+ * @param button the button, not used here
+ * @param data gtktreeview where to act
+ *
+ * @return void
+ *
+ */
+static void
+on_configure_remove_language(GtkWidget* button, gpointer data)
+{
+ GtkTreeView* tree_view = (GtkTreeView*)data;
+ GtkTreeSelection *selection;
+ GtkTreeIter tree_iter;
+
+ log_func();
+
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ if ( ! gtk_tree_selection_get_selected(selection, NULL, &tree_iter) ) {
+ log_debug("Delete without selection!");
+ return;
}
-#endif
+ /* Remove the element */
+ gtk_list_store_remove(list_store, &tree_iter);
+}
+
+/**
+ * @brief Callback called when a cell has been edited in the configuration
+ * dialog
+ * @param renderer field object
+ * @param path
+ * @param text the new text
+ * @param data column where event is called
+ *
+ * @return void
+ *
+ */
+static void
+on_configure_cell_edited(GtkCellRendererText* renderer, gchar* path, gchar* text, gpointer data)
+{
+ GtkTreeIter iter;
+ Column col = (Column)(GPOINTER_TO_INT(data));
+
+ log_func();
+
+ /* TODO: check correctness of text inserted */
+
+ /* Replace old text with new */
+ gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(list_store), &iter, path);
+ gtk_list_store_set(list_store, &iter, col, text, -1);
+
}
Modified: codenav/src/codenavigation.h
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -45,7 +45,7 @@
#include "geanyfunctions.h" /* this wraps geany_functions function pointers */
/* Debug flag */
-/* #define CODE_NAVIGATION_DEBUG */
+#define CODE_NAVIGATION_DEBUG
#define CODE_NAVIGATION_VERSION "0.2"
Modified: codenav/src/switch_head_impl.c
290 lines changed, 52 insertions(+), 238 deletions(-)
===================================================================
@@ -28,45 +28,29 @@
#include "switch_head_impl.h"
#include "utils.h"
-/********************* Data types for the feature *********************/
-/* Structure representing a handled language */
-typedef struct
-{
- const gchar* name;
- GSList* head_extensions; /* e.g. : "h", "hpp", ... */
- GSList* impl_extensions; /* e.g. : "cpp", "cxx", ... */
-} Language;
+/****************************** Useful macro **************************/
+#define HEAD_PREPEND(str_ext) \
+ { lang->head_extensions = g_slist_prepend(lang->head_extensions, g_strdup(str_ext)); }
+#define IMPL_PREPEND(str_ext) \
+ { lang->impl_extensions = g_slist_prepend(lang->impl_extensions, g_strdup(str_ext)); }
-/* Column for the configuration widget */
-typedef enum
-{
- COLUMN_HEAD,
- COLUMN_IMPL,
- NB_COLUMNS
-} Column;
/******************* Global variables for the feature *****************/
static GtkWidget* menu_item = NULL;
static GSList* languages = NULL; /* handled languages */
-/********************** Functions for the feature *********************/
-static void
-fill_default_languages_list(void);
+/**************************** Prototypes ******************************/
+void
+languages_clean(void);
static void
menu_item_activate(guint key_id);
-static void
-on_configure_add_language(GtkWidget* widget, gpointer data);
+/********************** Functions for the feature *********************/
-static void
-on_configure_remove_language(GtkWidget* widget, gpointer data);
-
-static void
-on_configure_cell_edited(GtkCellRendererText* text, gchar* arg1, gchar* arg2, gpointer data);
/* ---------------------------------------------------------------------
* Initialization
@@ -76,7 +60,6 @@ void
switch_head_impl_init(void)
{
GtkWidget* edit_menu;
-
log_func();
edit_menu = ui_lookup_widget(geany->main_widgets->window, "edit1_menu");
@@ -99,8 +82,6 @@ switch_head_impl_init(void)
_("Switch header/implementation"), /* used in the Preferences dialog */
menu_item);
- /* TODO : we should use the languages specified by the user or the default list */
- fill_default_languages_list();
}
/* ---------------------------------------------------------------------
@@ -110,11 +91,15 @@ switch_head_impl_init(void)
void
switch_head_impl_cleanup(void)
{
- GSList* iter = NULL;
-
log_func();
gtk_widget_destroy(menu_item);
+ languages_clean();
+}
+
+void languages_clean(void)
+{
+ GSList* iter = NULL;
for(iter = languages ; iter != NULL ; iter = iter->next)
{
@@ -128,25 +113,54 @@ switch_head_impl_cleanup(void)
}
g_slist_free(languages);
+
+ languages = NULL;
}
+void
+fill_languages_list(const gchar** impl_list, const gchar** head_list, gsize n)
+{
+ gchar **splitted_list;
+ Language* lang = NULL;
+ gint i, j;
+
+ languages_clean();
+
+ for ( i=0; i<n; i++ ) {
+ lang = g_malloc0(sizeof(Language));
+
+ /* Set language implementation extensions */
+ splitted_list = g_strsplit(impl_list[i], ",", 0);
+ for ( j=0; splitted_list[j] != NULL; j++ )
+ IMPL_PREPEND(splitted_list[j]);
+ g_strfreev(splitted_list);
+
+ /* Set language header extensions */
+ splitted_list = g_strsplit(head_list[i], ",", 0);
+ for ( j=0; splitted_list[j] != NULL; j++ )
+ HEAD_PREPEND(splitted_list[j]);
+ g_strfreev(splitted_list);
+
+ /* add current language to main list */
+ languages = g_slist_prepend(languages, lang);
+ }
+
+ /* reverse the list to match correct order */
+ languages = g_slist_reverse(languages);
+
+}
/* ---------------------------------------------------------------------
* Initialize the "languages" list to the default known languages
* ---------------------------------------------------------------------
*/
-static void
+void
fill_default_languages_list(void)
{
Language* lang = NULL;
languages = NULL;
-#define HEAD_PREPEND(str_ext) \
- { lang->head_extensions = g_slist_prepend(lang->head_extensions, g_strdup(str_ext)); }
-#define IMPL_PREPEND(str_ext) \
- { lang->impl_extensions = g_slist_prepend(lang->impl_extensions, g_strdup(str_ext)); }
-
/* C/C++ */
lang = g_malloc0(sizeof(Language));
lang->name = "c_cpp";
@@ -195,8 +209,6 @@ fill_default_languages_list(void)
/* Done : */
languages = g_slist_reverse(languages);
-#undef HEAD_PREPEND
-#undef IMPL_PREPEND
}
/* ---------------------------------------------------------------------
@@ -395,205 +407,7 @@ menu_item_activate(guint key_id)
}
}
-/* ---------------------------------------------------------------------
- * Configuration widget
- * ---------------------------------------------------------------------
- */
-
-/* ----- Utility function to concatenate the extensions of a -----
- * language, separated with a comma. */
-static gchar*
-concatenate_extensions(GSList* extensions)
-{
- GSList* iter_ext;
- gchar* p_str = NULL;
- gchar* temp = NULL;
-
- for(iter_ext = extensions ; iter_ext != NULL ; iter_ext = iter_ext->next)
- {
- temp = p_str;
- p_str = g_strjoin(",", (const gchar*)(iter_ext->data), p_str, NULL);
- g_free(temp);
- }
-
- return p_str;
-}
-
-/* ----- Utility function to add a language to a GtkListStore ----- */
-static void
-add_language(GtkListStore* list_store, Language* lang)
-{
- gchar* p_str = NULL;
- GtkTreeIter tree_iter;
-
- if(lang->head_extensions == NULL || lang->impl_extensions == NULL)
- return;
-
- /* Append an empty row */
- gtk_list_store_append(list_store, &tree_iter);
-
- /* Header extensions */
- p_str = concatenate_extensions(lang->head_extensions);
- gtk_list_store_set(list_store, &tree_iter, COLUMN_HEAD, p_str, -1);
- g_free(p_str);
-
- /* Implementation extensions */
- p_str = concatenate_extensions(lang->impl_extensions);
- gtk_list_store_set(list_store, &tree_iter, COLUMN_IMPL, p_str, -1);
- g_free(p_str);
-}
-
-/* ----- Finally, the configuration widget ----- */
-GtkWidget*
-switch_head_impl_config_widget(void)
+GSList* switch_head_impl_get_languages()
{
- GtkWidget *frame, *vbox, *tree_view;
- GtkWidget *hbox_buttons, *add_button, *remove_button;
- GtkListStore *list_store;
- GtkTreeViewColumn *column;
- GtkCellRenderer *cell_renderer;
-
- GSList *iter_lang;
-
- log_func();
-
- /* Frame, which is the returned widget */
- frame = gtk_frame_new(_("Switch header/implementation"));
-
- /* Main VBox */
- vbox = gtk_vbox_new(FALSE, 0);
- gtk_container_add(GTK_CONTAINER(frame), vbox);
-
- /* ======= Extensions list ======= */
-
- /* Add a list containing the extensions for each language (headers / implementations) */
- /* - create the GtkListStore */
- list_store = gtk_list_store_new(NB_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
-
- /* - fill the GtkListStore with the extensions of the languages */
- for(iter_lang = languages ; iter_lang != NULL ; iter_lang = iter_lang->next)
- add_language(list_store, (Language*)(iter_lang->data));
-
- /* - create the GtkTreeView */
- tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list_store));
-
- /* - add the columns */
- /* -> headers : */
- cell_renderer = gtk_cell_renderer_text_new();
- g_object_set(G_OBJECT(cell_renderer), "editable", TRUE, NULL);
- g_signal_connect(G_OBJECT(cell_renderer), "edited", G_CALLBACK(on_configure_cell_edited), GINT_TO_POINTER(COLUMN_HEAD));
- column = gtk_tree_view_column_new_with_attributes( _("Headers extensions"), cell_renderer,
- "text", COLUMN_HEAD,
- NULL);
- gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
-
- /* -> implementations : */
- cell_renderer = gtk_cell_renderer_text_new();
- g_object_set(G_OBJECT(cell_renderer), "editable", TRUE, NULL);
- g_signal_connect(G_OBJECT(cell_renderer), "edited", G_CALLBACK(on_configure_cell_edited), GINT_TO_POINTER(COLUMN_IMPL));
- column = gtk_tree_view_column_new_with_attributes( _("Implementations extensions"), cell_renderer,
- "text", COLUMN_IMPL,
- NULL);
- gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
-
-
- /* - finally add the GtkTreeView to the frame's vbox */
- gtk_box_pack_start(GTK_BOX(vbox), tree_view, TRUE, TRUE, 6);
-
-
- /* ========= Buttons ======== */
-
- /* HBox */
- hbox_buttons = gtk_hbox_new(FALSE, 0);
- gtk_box_pack_start(GTK_BOX(vbox), hbox_buttons, FALSE, FALSE, 0);
-
- /* Add the "add" button to the frame's hbox */
- add_button = gtk_button_new_from_stock(GTK_STOCK_ADD);
- g_signal_connect(G_OBJECT(add_button), "clicked", G_CALLBACK(on_configure_add_language), tree_view);
- gtk_box_pack_start(GTK_BOX(hbox_buttons), add_button, FALSE, FALSE, 0);
-
- /* Add the "remove" button to the frame's hbox */
- remove_button = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
- gtk_widget_set_sensitive(remove_button, FALSE); /* TODO ! */
- g_signal_connect(G_OBJECT(remove_button), "clicked", G_CALLBACK(on_configure_remove_language), tree_view);
- gtk_box_pack_start(GTK_BOX(hbox_buttons), remove_button, FALSE, FALSE, 0);
-
- return frame;
-}
-
-/* ---------------------------------------------------------------------
- * Callback for adding a language in the configuration dialog
- * ---------------------------------------------------------------------
- */
-static void
-on_configure_add_language(GtkWidget* widget, gpointer data)
-{
- GtkWidget* tree_view = (GtkWidget*)data;
- GtkListStore *list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view)));
- GtkTreeIter tree_iter;
- GtkTreePath *path;
- GtkTreeViewColumn* column = NULL;
- gint nb_lines;
-
- /* Add a line */
- gtk_list_store_append(list_store, &tree_iter);
-
- /* and give the focus to it */
- nb_lines = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(list_store), NULL);
-
- path = gtk_tree_path_new_from_indices(nb_lines-1, -1);
-
- column = gtk_tree_view_get_column(GTK_TREE_VIEW(tree_view), 0);
-
- /* TODO : why isn't the cell being edited, although we say "TRUE" as last parameter ?? */
- gtk_tree_view_set_cursor(GTK_TREE_VIEW(tree_view), path, column, TRUE);
- gtk_widget_grab_focus(tree_view);
-
- gtk_tree_path_free(path);
-}
-
-/* ---------------------------------------------------------------------
- * Callback for removing a language in the configuration dialog
- * ---------------------------------------------------------------------
- */
-static void
-on_configure_remove_language(GtkWidget* widget, gpointer data)
-{
- /* TODO ! */
-}
-
-/* ---------------------------------------------------------------------
- * Callback called when a cell has been edited in the configuration dialog
- * ---------------------------------------------------------------------
- */
-static void
-on_configure_cell_edited(GtkCellRendererText* text, gchar* arg1, gchar* arg2, gpointer data)
-{
- /* TODO !! */
- /* Column col = (Column)(GPOINTER_TO_INT(data)); */
- log_debug("arg1 == %s, arg2 == %s\n", arg1, arg2);
-}
-
-/* ---------------------------------------------------------------------
- * Write the configuration of the feature
- * ---------------------------------------------------------------------
- */
-void
-write_switch_head_impl_config(GKeyFile* key_file)
-{
- /* TODO ! */
- /* This is old code which needs to be updated */
-
-/* lang_names = g_malloc(nb_languages * sizeof(gchar*));
- for(lang_iterator = languages_extensions, i=0 ;
- lang_iterator != NULL ;
- lang_iterator = lang_iterator->next, i++)
- {
- lang_names[i] = ((const LanguageExtensions*)(lang_iterator->data))->language_name;
- }
-
- g_key_file_set_string_list(key_file, "switching", "languages", lang_names, nb_languages);
-
- g_free(lang_names);
-*/
+ return languages;
}
Modified: codenav/src/switch_head_impl.h
23 lines changed, 18 insertions(+), 5 deletions(-)
===================================================================
@@ -3,6 +3,7 @@
* part of the "geany-plugins" project.
*
* Copyright 2009 Lionel Fuentes <funto66(at)gmail(dot)com>
+ * Copyright 2014 Federico Reghenzani <federico(dot)dev(at)reghe(dot)net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,6 +26,14 @@
#include "codenavigation.h"
+/* Structure representing a handled language */
+typedef struct
+{
+ const gchar* name; /* currently not used */
+ GSList* head_extensions; /* e.g. : "h", "hpp", ... */
+ GSList* impl_extensions; /* e.g. : "cpp", "cxx", ... */
+} Language;
+
/* Initialization */
void
switch_head_impl_init(void);
@@ -33,12 +42,16 @@ switch_head_impl_init(void);
void
switch_head_impl_cleanup(void);
-/* Configuration widget */
-GtkWidget*
-switch_head_impl_config_widget(void);
+/* Languages-related */
+void
+fill_default_languages_list(void);
-/* Write the configuration of the feature */
void
-write_switch_head_impl_config(GKeyFile* key_file);
+fill_languages_list(const gchar**, const gchar**, gsize);
+
+
+
+GSList* switch_head_impl_get_languages();
+
#endif /* SWITCH_HEAD_IMPL_H */
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
More information about the Plugins-Commits
mailing list