SF.net SVN: geany:[3681] trunk

ntrel at users.sourceforge.net ntrel at xxxxx
Fri Apr 3 14:23:45 UTC 2009


Revision: 3681
          http://geany.svn.sourceforge.net/geany/?rev=3681&view=rev
Author:   ntrel
Date:     2009-04-03 14:23:45 +0000 (Fri, 03 Apr 2009)

Log Message:
-----------
Merge reorder-filetypes branch:
Make GEANY_FILETYPES_NONE = 0, sort filetype IDs randomly (so we can
append randomly without breaking the ABI).
Make None filetype name = title = _("None").
Add foreach_slist() macro.
Add filetypes_by_title list to GeanyData for plugin API access
- a list of filetype pointers, which includes the None filetype
first. This list stays constant by the time plugins are initialized,
so you can use e.g. g_slist_nth_data(filetypes_by_title, n) to
index the sorted list.

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/plugins/htmlchars.c
    trunk/plugins/saveactions.c
    trunk/src/dialogs.c
    trunk/src/filetypes.c
    trunk/src/filetypes.h
    trunk/src/highlighting.c
    trunk/src/plugindata.h
    trunk/src/plugins.c
    trunk/src/symbols.c
    trunk/src/templates.c
    trunk/src/ui_utils.c
    trunk/src/utils.h

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2009-04-03 13:53:04 UTC (rev 3680)
+++ trunk/ChangeLog	2009-04-03 14:23:45 UTC (rev 3681)
@@ -3,6 +3,20 @@
  * src/filetypes.c, doc/geany.txt:
    Move ActionScript to the Script group.
    Fix wording & typo.
+ * src/templates.c, src/utils.h, src/highlighting.c, src/dialogs.c,
+   src/plugindata.h, src/filetypes.c, src/filetypes.h, src/plugins.c,
+   src/symbols.c, src/ui_utils.c, plugins/saveactions.c,
+   plugins/htmlchars.c:
+   Merge reorder-filetypes branch:
+   Make GEANY_FILETYPES_NONE = 0, sort filetype IDs randomly (so we can
+   append randomly without breaking the ABI).
+   Make None filetype name = title = _("None").
+   Add foreach_slist() macro.
+   Add filetypes_by_title list to GeanyData for plugin API access
+   - a list of filetype pointers, which includes the None filetype
+   first. This list stays constant by the time plugins are initialized,
+   so you can use e.g. g_slist_nth_data(filetypes_by_title, n) to
+   index the sorted list.
 
 
 2009-03-31  Enrico Tröger  <enrico(dot)troeger(at)uvena(dot)de>

Modified: trunk/plugins/htmlchars.c
===================================================================
--- trunk/plugins/htmlchars.c	2009-04-03 13:53:04 UTC (rev 3680)
+++ trunk/plugins/htmlchars.c	2009-04-03 14:23:45 UTC (rev 3681)
@@ -26,6 +26,8 @@
 /* HTML Characters plugin (Inserts HTML character entities like '&') */
 
 #include "geany.h"
+#include <string.h>
+
 #include "support.h"
 #include "plugindata.h"
 #include "document.h"

Modified: trunk/plugins/saveactions.c
===================================================================
--- trunk/plugins/saveactions.c	2009-04-03 13:53:04 UTC (rev 3680)
+++ trunk/plugins/saveactions.c	2009-04-03 14:23:45 UTC (rev 3681)
@@ -603,6 +603,8 @@
 	{
 		GtkWidget *combo;
 		guint i;
+		GSList *node;
+		GeanyFiletype *ft;
 
 		notebook_vbox = gtk_vbox_new(FALSE, 2);
 		inner_vbox = gtk_vbox_new(FALSE, 5);
@@ -624,14 +626,14 @@
 		gtk_box_pack_start(GTK_BOX(inner_vbox), label, FALSE, FALSE, 0);
 
 		pref_widgets.instantsave_ft_combo = combo = gtk_combo_box_new_text();
-		for (i = 0; i < geany->filetypes_array->len; i++)
+		i = 0;
+		foreach_slist(ft, node, geany->filetypes_by_title)
 		{
-			GeanyFiletype *ft = filetypes_index(i);
-
 			gtk_combo_box_append_text(GTK_COMBO_BOX(combo), ft->name);
 
 			if (utils_str_equal(ft->name, instantsave_default_ft))
 				gtk_combo_box_set_active(GTK_COMBO_BOX(combo), i);
+			i++;
 		}
 		gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(combo), 3);
 		gtk_label_set_mnemonic_widget(GTK_LABEL(label), combo);

Modified: trunk/src/dialogs.c
===================================================================
--- trunk/src/dialogs.c	2009-04-03 13:53:04 UTC (rev 3680)
+++ trunk/src/dialogs.c	2009-04-03 14:23:45 UTC (rev 3681)
@@ -90,8 +90,8 @@
 		gboolean ro = (response == GEANY_RESPONSE_VIEW);	/* View clicked */
 
 		/* ignore detect from file item */
-		if (filetype_idx >= 0 && filetype_idx < GEANY_FILETYPES_NONE)
-			ft = filetypes[filetype_idx];
+		if (filetype_idx > 0 && filetype_idx < GEANY_MAX_BUILT_IN_FILETYPES)
+			ft = g_slist_nth_data(filetypes_by_title, filetype_idx);
 		if (encoding_idx >= 0 && encoding_idx < GEANY_ENCODINGS_MAX)
 			charset = encodings[encoding_idx].charset;
 
@@ -177,6 +177,8 @@
 	GtkWidget *viewbtn;
 	guint i;
 	gchar *encoding_string;
+	GeanyFiletype *ft;
+	GSList *node;
 
 	ui_widgets.open_filesel = gtk_file_chooser_dialog_new(_("Open File"), GTK_WINDOW(main_widgets.window),
 			GTK_FILE_CHOOSER_ACTION_OPEN, NULL, NULL);
@@ -207,23 +209,22 @@
 		add_file_open_extra_widget());
 	filetype_combo = ui_lookup_widget(ui_widgets.open_filesel, "filetype_combo");
 
+	gtk_combo_box_append_text(GTK_COMBO_BOX(filetype_combo), _("Detect by file extension"));
 	/* add FileFilters(start with "All Files") */
 	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(ui_widgets.open_filesel),
 				filetypes_create_file_filter(filetypes[GEANY_FILETYPES_NONE]));
 	/* now create meta filter "All Source" */
 	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(ui_widgets.open_filesel),
 				filetypes_create_file_filter_all_source());
-	for (i = 0; i < filetypes_array->len; i++)
+	foreach_slist(ft, node, filetypes_by_title)
 	{
-		if (i == GEANY_FILETYPES_NONE)
+		if (ft->id == GEANY_FILETYPES_NONE)
 			continue;
-
-		gtk_combo_box_append_text(GTK_COMBO_BOX(filetype_combo), filetypes[i]->title);
+		gtk_combo_box_append_text(GTK_COMBO_BOX(filetype_combo), ft->title);
 		gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(ui_widgets.open_filesel),
-				filetypes_create_file_filter(filetypes[i]));
+				filetypes_create_file_filter(ft));
 	}
-	gtk_combo_box_append_text(GTK_COMBO_BOX(filetype_combo), _("Detect by file extension"));
-	gtk_combo_box_set_active(GTK_COMBO_BOX(filetype_combo), filetypes_array->len - 1);
+	gtk_combo_box_set_active(GTK_COMBO_BOX(filetype_combo), 0);
 
 	/* fill encoding combo box */
 	encoding_combo = ui_lookup_widget(ui_widgets.open_filesel, "encoding_combo");

Modified: trunk/src/filetypes.c
===================================================================
--- trunk/src/filetypes.c	2009-04-03 13:53:04 UTC (rev 3680)
+++ trunk/src/filetypes.c	2009-04-03 14:23:45 UTC (rev 3681)
@@ -67,18 +67,35 @@
 
 GPtrArray *filetypes_array = NULL;	/* Dynamic array of filetype pointers */
 
-GHashTable *filetypes_hash = NULL;	/* Hash of filetype pointers based on name keys */
+static GHashTable *filetypes_hash = NULL;	/* Hash of filetype pointers based on name keys */
 
+/** List of filetype pointers sorted by name, but with @c filetypes_index(GEANY_FILETYPES_NONE)
+ * first, as this is usually treated specially.
+ * The list does not change (after filetypes have been initialized), so you can use
+ * @code g_slist_nth_data(filetypes_by_title, n) @endcode and expect the same result at different times. */
+GSList *filetypes_by_title = NULL;
 
-static void create_radio_menu_item(GtkWidget *menu, const gchar *label, GeanyFiletype *ftype);
 
+static void create_radio_menu_item(GtkWidget *menu, GeanyFiletype *ftype);
 
+
 /* Note: remember to update HACKING if this function is renamed. */
 static void init_builtin_filetypes(void)
 {
 	GeanyFiletype *ft;
 
-#define C	/* these macros are only to ease navigation */
+#define NONE	/* these macros are only to ease navigation */
+	ft = filetypes[GEANY_FILETYPES_NONE];
+	ft->lang = -2;
+	ft->name = g_strdup(_("None"));
+	ft->title = g_strdup(_("None"));
+	ft->extension = g_strdup("*");
+	ft->pattern = utils_strv_new("*", NULL);
+	ft->comment_open = NULL;
+	ft->comment_close = NULL;
+	ft->group = GEANY_FILETYPE_GROUP_NONE;
+
+#define C
 	ft = filetypes[GEANY_FILETYPES_C];
 	ft->lang = 0;
 	ft->name = g_strdup("C");
@@ -560,17 +577,6 @@
 	ft->comment_open = g_strdup("--");
 	ft->comment_close = NULL;
 	ft->group = GEANY_FILETYPE_GROUP_COMPILED;
-
-#define ALL
-	ft = filetypes[GEANY_FILETYPES_NONE];
-	ft->lang = -2;
-	ft->name = g_strdup("None");
-	ft->title = g_strdup(_("All files"));
-	ft->extension = g_strdup("*");
-	ft->pattern = utils_strv_new("*", NULL);
-	ft->comment_open = NULL;
-	ft->comment_close = NULL;
-	ft->group = GEANY_FILETYPE_GROUP_NONE;
 }
 
 
@@ -588,7 +594,20 @@
 }
 
 
-/* Add a filetype pointer to the list of available filetypes,
+static gint cmp_filetype(gconstpointer pft1, gconstpointer pft2)
+{
+	const GeanyFiletype *ft1 = pft1, *ft2 = pft2;
+
+	if (ft1->id == GEANY_FILETYPES_NONE)
+		return -1;
+	if (ft2->id == GEANY_FILETYPES_NONE)
+		return 1;
+
+	return utils_str_casecmp(ft1->title, ft2->title);
+}
+
+
+/* Add a filetype pointer to the lists of available filetypes,
  * and set the filetype::id field. */
 static void filetype_add(GeanyFiletype *ft)
 {
@@ -598,6 +617,8 @@
 	ft->id = filetypes_array->len;	/* len will be the index for filetype_array */
 	g_ptr_array_add(filetypes_array, ft);
 	g_hash_table_insert(filetypes_hash, ft->name, ft);
+
+	filetypes_by_title = g_slist_insert_sorted(filetypes_by_title, ft, cmp_filetype);
 }
 
 
@@ -646,61 +667,41 @@
 }
 
 
-#define create_sub_menu(menu, item, title) \
-	(menu) = gtk_menu_new(); \
-	(item) = gtk_menu_item_new_with_mnemonic((title)); \
-	gtk_menu_item_set_submenu(GTK_MENU_ITEM((item)), (menu)); \
-	gtk_container_add(GTK_CONTAINER(filetype_menu), (item)); \
-	gtk_widget_show((item));
+static GtkWidget *group_menus[GEANY_FILETYPE_GROUP_COUNT] = {NULL};
 
-
-static void create_set_filetype_menu(void)
+static void create_sub_menu(GtkWidget *parent, gsize group_id, const gchar *title)
 {
-	filetype_id ft_id;
-	GtkWidget *filetype_menu = ui_lookup_widget(main_widgets.window, "set_filetype1_menu");
-	GtkWidget *sub_menu = filetype_menu;
-	GtkWidget *sub_menu_programming, *sub_menu_scripts, *sub_menu_markup, *sub_menu_misc;
-	GtkWidget *sub_item_programming, *sub_item_scripts, *sub_item_markup, *sub_item_misc;
+	GtkWidget *menu, *item;
 
-	create_sub_menu(sub_menu_programming, sub_item_programming, _("_Programming Languages"));
-	create_sub_menu(sub_menu_scripts, sub_item_scripts, _("_Scripting Languages"));
-	create_sub_menu(sub_menu_markup, sub_item_markup, _("_Markup Languages"));
-	create_sub_menu(sub_menu_misc, sub_item_misc, _("M_iscellaneous Languages"));
+	menu = gtk_menu_new();
+	item = gtk_menu_item_new_with_mnemonic((title));
+	gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu);
+	gtk_container_add(GTK_CONTAINER(parent), item);
+	gtk_widget_show(item);
+	group_menus[group_id] = menu;
+}
 
-	/* Append all filetypes to the filetype menu */
-	for (ft_id = 0; ft_id < filetypes_array->len; ft_id++)
-	{
-		GeanyFiletype *ft = filetypes[ft_id];
-		const gchar *title = ft->title;
 
-		/* insert separators for different filetype groups */
-		switch (ft->group)
-		{
-			case GEANY_FILETYPE_GROUP_COMPILED:	/* programming */
-				sub_menu = sub_menu_programming;
-				break;
+static void add_ft_menu_item(gpointer pft, gpointer user_data)
+{
+	GeanyFiletype *ft = pft;
 
-			case GEANY_FILETYPE_GROUP_SCRIPT:	/* scripts */
-				sub_menu = sub_menu_scripts;
-				break;
+	create_radio_menu_item(group_menus[ft->group], ft);
+}
 
-			case GEANY_FILETYPE_GROUP_MARKUP:	/* markup */
-				sub_menu = sub_menu_markup;
-				break;
 
-			case GEANY_FILETYPE_GROUP_MISC:	/* misc */
-				sub_menu = sub_menu_misc;
-				break;
+static void create_set_filetype_menu(void)
+{
+	GtkWidget *filetype_menu = ui_lookup_widget(main_widgets.window, "set_filetype1_menu");
 
-			case GEANY_FILETYPE_GROUP_NONE:	/* none */
-				sub_menu = filetype_menu;
-				title = _("None");
-				break;
+	create_sub_menu(filetype_menu, GEANY_FILETYPE_GROUP_COMPILED, _("_Programming Languages"));
+	create_sub_menu(filetype_menu, GEANY_FILETYPE_GROUP_SCRIPT, _("_Scripting Languages"));
+	create_sub_menu(filetype_menu, GEANY_FILETYPE_GROUP_MARKUP, _("_Markup Languages"));
+	create_sub_menu(filetype_menu, GEANY_FILETYPE_GROUP_MISC, _("M_iscellaneous Languages"));
 
-			default: break;
-		}
-		create_radio_menu_item(sub_menu, title, ft);
-	}
+	/* Append all filetypes to the filetype menu */
+	filetypes_foreach_named(add_ft_menu_item, NULL);
+	create_radio_menu_item(filetype_menu, filetypes[GEANY_FILETYPES_NONE]);
 }
 
 
@@ -712,11 +713,8 @@
 }
 
 
-typedef gboolean FileTypesPredicate(GeanyFiletype *ft, gpointer user_data);
-
 /* Find a filetype that predicate returns TRUE for, otherwise return NULL. */
-static GeanyFiletype *filetypes_find(gboolean source_only,
-		FileTypesPredicate predicate, gpointer user_data)
+GeanyFiletype *filetypes_find(GCompareFunc predicate, gpointer user_data)
 {
 	guint i;
 
@@ -724,9 +722,6 @@
 	{
 		GeanyFiletype *ft = filetypes[i];
 
-		if (source_only && i == GEANY_FILETYPES_NONE)
-			continue;	/* None is not for source files */
-
 		if (predicate(ft, user_data))
 			return ft;
 	}
@@ -734,12 +729,16 @@
 }
 
 
-static gboolean match_basename(GeanyFiletype *ft, gpointer user_data)
+static gboolean match_basename(gconstpointer pft, gconstpointer user_data)
 {
+	const GeanyFiletype *ft = pft;
 	const gchar *base_filename = user_data;
 	gint j;
 	gboolean ret = FALSE;
 
+	if (ft->id == GEANY_FILETYPES_NONE)
+		return FALSE;
+
 	for (j = 0; ft->pattern[j] != NULL; j++)
 	{
 		GPatternSpec *pattern = g_pattern_spec_new(ft->pattern[j]);
@@ -770,7 +769,7 @@
 	setptr(base_filename, g_utf8_strdown(base_filename, -1));
 #endif
 
-	ft = filetypes_find(TRUE, match_basename, base_filename);
+	ft = filetypes_find(match_basename, base_filename);
 	if (ft == NULL)
 		ft = filetypes[GEANY_FILETYPES_NONE];
 
@@ -982,12 +981,12 @@
 }
 
 
-static void create_radio_menu_item(GtkWidget *menu, const gchar *label, GeanyFiletype *ftype)
+static void create_radio_menu_item(GtkWidget *menu, GeanyFiletype *ftype)
 {
 	static GSList *group = NULL;
 	GtkWidget *tmp;
 
-	tmp = gtk_radio_menu_item_new_with_label(group, label);
+	tmp = gtk_radio_menu_item_new_with_label(group, ftype->title);
 	group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(tmp));
 	ftype->priv->menu_item = tmp;
 	gtk_widget_show(tmp);
@@ -1240,7 +1239,7 @@
 		G_DIR_SEPARATOR_S GEANY_FILEDEFS_SUBDIR G_DIR_SEPARATOR_S "filetypes.", NULL);
 	gint i;
 
-	for (i = 0; i < GEANY_FILETYPES_NONE; i++)
+	for (i = 1; i < GEANY_MAX_BUILT_IN_FILETYPES; i++)
 	{
 		struct build_programs *bp = filetypes[i]->programs;
 		GKeyFile *config_home;
@@ -1301,11 +1300,13 @@
 {
 	GtkFileFilter *new_filter;
 	gint i;
+	const gchar *title;
 
 	g_return_val_if_fail(ft != NULL, NULL);
 
 	new_filter = gtk_file_filter_new();
-	gtk_file_filter_set_name(new_filter, ft->title);
+	title = ft->id == GEANY_FILETYPES_NONE ? _("All files") : ft->title;
+	gtk_file_filter_set_name(new_filter, title);
 
 	for (i = 0; ft->pattern[i]; i++)
 	{
@@ -1480,3 +1481,16 @@
 }
 
 
+/* Does not include ft[GEANY_FILETYPES_NONE], as this is usually treated specially. */
+void filetypes_foreach_named(GFunc callback, gpointer user_data)
+{
+	GSList *node;
+	GeanyFiletype *ft;
+
+	foreach_slist(ft, node, filetypes_by_title)
+	{
+		if (ft->id != GEANY_FILETYPES_NONE)
+			callback(ft, user_data);
+	}
+}
+

Modified: trunk/src/filetypes.h
===================================================================
--- trunk/src/filetypes.h	2009-04-03 13:53:04 UTC (rev 3680)
+++ trunk/src/filetypes.h	2009-04-03 14:23:45 UTC (rev 3681)
@@ -29,66 +29,58 @@
 #include "ScintillaWidget.h"
 
 
-/* Each group should be alpha-sorted, based on filetype::name (not enum name).
- * Warning: remember to break the plugin ABI when adding items. */
-/* TODO: for a stable ABI put GEANY_FILETYPES_NONE first, and use a sorted duplicate
- * filetypes array for GUI elements. */
 typedef enum
 {
-	/* normally compiled languages */
-	GEANY_FILETYPES_ADA = 0,
-	GEANY_FILETYPES_AS,
-	GEANY_FILETYPES_ASM,
-	GEANY_FILETYPES_C,
-	GEANY_FILETYPES_CPP,
-	GEANY_FILETYPES_CS,
-	GEANY_FILETYPES_CAML,
-	GEANY_FILETYPES_D,
-	GEANY_FILETYPES_F77,
-	GEANY_FILETYPES_FORTRAN,
-	GEANY_FILETYPES_BASIC,	/* FreeBasic */
-	GEANY_FILETYPES_GLSL,
-	GEANY_FILETYPES_HASKELL,
-	GEANY_FILETYPES_HAXE,
-	GEANY_FILETYPES_JAVA,
-	GEANY_FILETYPES_PASCAL,
-	GEANY_FILETYPES_VALA,
-	GEANY_FILETYPES_VHDL,
+	GEANY_FILETYPES_NONE = 0,	/* first filetype is always None */
 
-	/* script languages */
-	GEANY_FILETYPES_FERITE,
-	GEANY_FILETYPES_JS,
-	GEANY_FILETYPES_LUA,
-	GEANY_FILETYPES_MAKE,
-	GEANY_FILETYPES_MATLAB,
-	GEANY_FILETYPES_PERL,
 	GEANY_FILETYPES_PHP,
-	GEANY_FILETYPES_PYTHON,
-	GEANY_FILETYPES_R,
+	GEANY_FILETYPES_BASIC,	/* FreeBasic */
+	GEANY_FILETYPES_MATLAB,
 	GEANY_FILETYPES_RUBY,
-	GEANY_FILETYPES_SH,
+	GEANY_FILETYPES_LUA,
+	GEANY_FILETYPES_FERITE,
+	GEANY_FILETYPES_YAML,
+	GEANY_FILETYPES_C,
+	GEANY_FILETYPES_NSIS,
+	GEANY_FILETYPES_GLSL,
+	GEANY_FILETYPES_PO,
+	GEANY_FILETYPES_MAKE,
 	GEANY_FILETYPES_TCL,
-
-	/* markup languages */
-	GEANY_FILETYPES_CSS,
-	GEANY_FILETYPES_DOCBOOK,
-	GEANY_FILETYPES_HTML,
 	GEANY_FILETYPES_XML,
-
-	/* miscellaneous languages */
-	GEANY_FILETYPES_CMAKE,
-	GEANY_FILETYPES_CONF,
+	GEANY_FILETYPES_CSS,
+	GEANY_FILETYPES_REST,
+	GEANY_FILETYPES_HASKELL,
+	GEANY_FILETYPES_JAVA,
+	GEANY_FILETYPES_CAML,
+	GEANY_FILETYPES_AS,
+	GEANY_FILETYPES_R,
 	GEANY_FILETYPES_DIFF,
-	GEANY_FILETYPES_NSIS,
-	GEANY_FILETYPES_PO,
+	GEANY_FILETYPES_HTML,
+	GEANY_FILETYPES_PYTHON,
+	GEANY_FILETYPES_CS,
+	GEANY_FILETYPES_PERL,
+	GEANY_FILETYPES_VALA,
+	GEANY_FILETYPES_PASCAL,
 	GEANY_FILETYPES_LATEX,
-	GEANY_FILETYPES_REST,
+	GEANY_FILETYPES_ASM,
+	GEANY_FILETYPES_CONF,
+	GEANY_FILETYPES_HAXE,
+	GEANY_FILETYPES_CPP,
+	GEANY_FILETYPES_SH,
+	GEANY_FILETYPES_FORTRAN,
 	GEANY_FILETYPES_SQL,
-	GEANY_FILETYPES_YAML,
+	GEANY_FILETYPES_F77,
+	GEANY_FILETYPES_DOCBOOK,
+	GEANY_FILETYPES_D,
+	GEANY_FILETYPES_JS,
+	GEANY_FILETYPES_VHDL,
+	GEANY_FILETYPES_ADA,
+	GEANY_FILETYPES_CMAKE,
 
-	GEANY_FILETYPES_NONE,	/* must be last filetype */
-	GEANY_MAX_BUILT_IN_FILETYPES	/* Use filetypes_array->len instead */
-} filetype_id;
+	/* ^ append items here */
+	GEANY_MAX_BUILT_IN_FILETYPES	/* Don't use this, use filetypes_array->len instead */
+}
+filetype_id;
 
 typedef enum
 {
@@ -96,7 +88,8 @@
 	GEANY_FILETYPE_GROUP_COMPILED,
 	GEANY_FILETYPE_GROUP_SCRIPT,
 	GEANY_FILETYPE_GROUP_MARKUP,
-	GEANY_FILETYPE_GROUP_MISC
+	GEANY_FILETYPE_GROUP_MISC,
+	GEANY_FILETYPE_GROUP_COUNT
 }
 GeanyFiletypeGroupID;
 
@@ -151,10 +144,16 @@
  * Example: filetypes[GEANY_FILETYPES_C]->name = ...; */
 #define filetypes	((GeanyFiletype **)filetypes_array->pdata)
 
+extern GSList *filetypes_by_title;
 
+
 GeanyFiletype *filetypes_lookup_by_name(const gchar *name);
 
+void filetypes_foreach_named(GFunc callback, gpointer user_data);
 
+GeanyFiletype *filetypes_find(GCompareFunc predicate, gpointer user_data);
+
+
 void filetypes_init(void);
 
 void filetypes_init_types(void);

Modified: trunk/src/highlighting.c
===================================================================
--- trunk/src/highlighting.c	2009-04-03 13:53:04 UTC (rev 3680)
+++ trunk/src/highlighting.c	2009-04-03 14:23:45 UTC (rev 3681)
@@ -3435,7 +3435,7 @@
 	filetypes_load_config(filetype_idx, FALSE);	/* load filetypes.ext */
 
 	/* load tags files (some lexers highlight global typenames) */
-	if (filetype_idx < GEANY_FILETYPES_NONE)
+	if (filetype_idx != GEANY_FILETYPES_NONE)
 		symbols_global_tags_loaded(filetype_idx);
 
 	switch (filetype_idx)

Modified: trunk/src/plugindata.h
===================================================================
--- trunk/src/plugindata.h	2009-04-03 13:53:04 UTC (rev 3680)
+++ trunk/src/plugindata.h	2009-04-03 14:23:45 UTC (rev 3681)
@@ -45,13 +45,13 @@
 enum {
 	/** The Application Programming Interface (API) version, incremented
 	 * whenever any plugin data types are modified or appended to. */
-	GEANY_API_VERSION = 137,
+	GEANY_API_VERSION = 138,
 
 	/** The Application Binary Interface (ABI) version, incremented whenever
 	 * existing fields in the plugin data types have to be changed or reordered. */
 	/* This should usually stay the same if fields are only appended, assuming only pointers to
 	 * structs and not structs themselves are declared by plugins. */
-	GEANY_ABI_VERSION = 59
+	GEANY_ABI_VERSION = 62
 };
 
 /** Check the plugin can be loaded by Geany.
@@ -188,6 +188,7 @@
 	struct GeanyToolPrefs		*tool_prefs;		/**< Tool settings */
 	struct GeanyTemplatePrefs	*template_prefs;	/**< Template settings */
 	struct GeanyBuildInfo		*build_info;		/**< Current build information */
+	GSList						*filetypes_by_title; /**< See filetypes.h#filetypes_by_title. */
 }
 GeanyData;
 

Modified: trunk/src/plugins.c
===================================================================
--- trunk/src/plugins.c	2009-04-03 13:53:04 UTC (rev 3680)
+++ trunk/src/plugins.c	2009-04-03 14:23:45 UTC (rev 3681)
@@ -351,7 +351,8 @@
 		&search_prefs,
 		&tool_prefs,
 		&template_prefs,
-		&build_info
+		&build_info,
+		filetypes_by_title
 	};
 	memcpy(&geany_data, &gd, sizeof(GeanyData));
 }

Modified: trunk/src/symbols.c
===================================================================
--- trunk/src/symbols.c	2009-04-03 13:53:04 UTC (rev 3680)
+++ trunk/src/symbols.c	2009-04-03 14:23:45 UTC (rev 3681)
@@ -1381,7 +1381,7 @@
 
 		g_free(utf8_fname);
 
-		if (FILETYPE_ID(ft) < GEANY_FILETYPES_NONE)
+		if (FILETYPE_ID(ft) != GEANY_FILETYPES_NONE)
 		{
 			fnames = g_hash_table_lookup(hash, ft);	/* may be NULL */
 			fnames = g_list_append(fnames, fname);
@@ -1417,13 +1417,14 @@
 
 static void load_user_tags(filetype_id ft_id)
 {
-	static guchar tags_loaded[GEANY_FILETYPES_NONE] = {0};
+	static guchar tags_loaded[GEANY_MAX_BUILT_IN_FILETYPES - 1] = {0};
 	static GHashTable *lang_hash = NULL;
 	GList *fnames;
 	const GList *node;
 	const GeanyFiletype *ft = filetypes[ft_id];
 
-	g_return_if_fail(ft_id < GEANY_FILETYPES_NONE);
+	g_return_if_fail(ft_id > 0);
+	g_return_if_fail(ft_id < GEANY_MAX_BUILT_IN_FILETYPES);
 
 	if (tags_loaded[ft_id])
 		return;

Modified: trunk/src/templates.c
===================================================================
--- trunk/src/templates.c	2009-04-03 13:53:04 UTC (rev 3680)
+++ trunk/src/templates.c	2009-04-03 14:23:45 UTC (rev 3681)
@@ -362,18 +362,17 @@
 /* template items for the new file menu */
 static void create_new_menu_items(void)
 {
-	filetype_id ft_id;
+	GeanyFiletype *ft;
+	GSList *node;
 
-	for (ft_id = 0; ft_id < GEANY_MAX_BUILT_IN_FILETYPES; ft_id++)
+	foreach_slist(ft, node, filetypes_by_title)
 	{
+		filetype_id ft_id = ft->id;
 		GtkWidget *tmp_menu, *tmp_button;
-		GeanyFiletype *ft = filetypes[ft_id];
 		const gchar *label = ft->title;
 
 		if (ft_templates[ft_id] == NULL)
 			continue;
-		if (ft_id == GEANY_FILETYPES_NONE)
-			label = _("None");
 
 		tmp_menu = gtk_menu_item_new_with_label(label);
 		gtk_widget_show(tmp_menu);

Modified: trunk/src/ui_utils.c
===================================================================
--- trunk/src/ui_utils.c	2009-04-03 13:53:04 UTC (rev 3680)
+++ trunk/src/ui_utils.c	2009-04-03 14:23:45 UTC (rev 3681)
@@ -134,6 +134,14 @@
 }
 
 
+static GeanyFiletype *document_get_filetype(GeanyDocument *doc)
+{
+	g_return_val_if_fail(doc, NULL);
+
+	return filetypes[FILETYPE_ID(doc->file_type)];
+}
+
+
 /* updates the status bar document statistics */
 void ui_update_statusbar(GeanyDocument *doc, gint pos)
 {
@@ -149,14 +157,8 @@
 		const gchar sp[] = "      ";
 		guint line, col;
 		const gchar *cur_tag;
-		gchar *filetype_name;
+		gchar *filetype_name = document_get_filetype(doc)->name;
 
-		/* workaround to make the name of filetype GEANY_FILETYPES_NONE translatable */
-		if (doc->file_type == NULL || doc->file_type->id == GEANY_FILETYPES_NONE)
-			filetype_name = _("None");
-		else
-			filetype_name = doc->file_type->name;
-
 		if (stats_str == NULL)
 			stats_str = g_string_sized_new(120);
 

Modified: trunk/src/utils.h
===================================================================
--- trunk/src/utils.h	2009-04-03 13:53:04 UTC (rev 3680)
+++ trunk/src/utils.h	2009-04-03 14:23:45 UTC (rev 3681)
@@ -57,7 +57,12 @@
 	for (ptr = ptr_array->pdata, item = *ptr; \
 		ptr < &ptr_array->pdata[ptr_array->len]; ++ptr, item = *ptr)
 
+/* @param node should be a (GSList*), needed for implementation. */
+#define foreach_slist(data_ptr, node, list) \
+	for (node = list, data_ptr = node ? node->data : NULL; node != NULL; \
+		node = g_slist_next(node), data_ptr = node ? node->data : NULL)
 
+
 void utils_open_browser(const gchar *uri);
 
 gint utils_get_line_endings(const gchar* buffer, glong size);


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the Commits mailing list