SF.net SVN: geany: [2559] trunk

ntrel at users.sourceforge.net ntrel at xxxxx
Wed May 7 16:29:50 UTC 2008


Revision: 2559
          http://geany.svn.sourceforge.net/geany/?rev=2559&view=rev
Author:   ntrel
Date:     2008-05-07 09:29:48 -0700 (Wed, 07 May 2008)

Log Message:
-----------
Merge revisions 2537:2558 from the custom-filetypes branch:
Note: this breaks the API.
This commit is to restructure most of the filetypes code that
affects the plugin API, custom filetype support is not implemented.
Add filetypes_array to GeanyData for plugins to access a dynamic
array of filetype pointers.
Remove old filetypes array from API.
Use a hash table for filetypes, using filetype::name keys.
Replace filetypes_get_from_uid() with filetypes_lookup_by_name().
Store filetype::name instead of unique ID when saving sessions.
Remove all filetype UID code.
Add GEANY_MAX_BUILT_IN_FILETYPES.
Remove GEANY_MAX_FILE_TYPES - use filetypes_array->len (or
GEANY_MAX_BUILT_IN_FILETYPES) instead.
Rename GEANY_FILETYPES_ALL GEANY_FILETYPES_NONE.
Make Open dialog file filter work for filetypes added after
GEANY_FILETYPES_NONE (really the None filetype should be made the
first element in filetypes_array, but this would need rewriting
quite a lot of code).
Add deprecated aliases for GEANY_MAX_FILE_TYPES and
GEANY_FILETYPES_ALL.
Remove unused filetype::item field.
Create FullFileType private type that 'inherits' from filetype
(FullFileType* can be cast to filetype*). This is used in
filetype_new() to hide filetype struct fields from the API.
Remove radio_items[] and use FullFileType::menu_item instead.
Make filetypes_detect_from_extension() work for all filetypes
in filetypes_hash.
Add filetype_new() to create and initialize a new filetype.
Refactor open_session_file() from configuration_open_files().
Refactor get_session_file_string() from
configuration_save_session_files().
Refactor create_set_filetype_menu() from filetypes_init().
Move print_filetypes() out of parse_command_line_options();

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/plugins/pluginmacros.h
    trunk/plugins/vcdiff.c
    trunk/src/build.c
    trunk/src/dialogs.c
    trunk/src/document.c
    trunk/src/filetypes.c
    trunk/src/filetypes.h
    trunk/src/highlighting.c
    trunk/src/keyfile.c
    trunk/src/keyfile.h
    trunk/src/main.c
    trunk/src/msgwindow.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.c
    trunk/src/win32.c

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2008-05-07 14:09:12 UTC (rev 2558)
+++ trunk/ChangeLog	2008-05-07 16:29:48 UTC (rev 2559)
@@ -1,3 +1,47 @@
+2008-05-07  Nick Treleaven  <nick(dot)treleaven(at)btinternet(dot)com>
+
+ * src/templates.c, src/build.c, src/utils.c, src/win32.c,
+   src/highlighting.c, src/dialogs.c, src/plugindata.h,
+   src/msgwindow.c, src/keyfile.c, src/keyfile.h, src/filetypes.c,
+   src/filetypes.h, src/document.c, src/plugins.c, src/main.c,
+   src/symbols.c, src/ui_utils.c, plugins/vcdiff.c,
+   plugins/pluginmacros.h:
+   Merge revisions 2537:2558 from the custom-filetypes branch:
+   Note: this breaks the API.
+   This commit is to restructure most of the filetypes code that
+   affects the plugin API, custom filetype support is not implemented.
+   Add filetypes_array to GeanyData for plugins to access a dynamic
+   array of filetype pointers.
+   Remove old filetypes array from API.
+   Use a hash table for filetypes, using filetype::name keys.
+   Replace filetypes_get_from_uid() with filetypes_lookup_by_name().
+   Store filetype::name instead of unique ID when saving sessions.
+   Remove all filetype UID code.
+   Add GEANY_MAX_BUILT_IN_FILETYPES.
+   Remove GEANY_MAX_FILE_TYPES - use filetypes_array->len (or
+   GEANY_MAX_BUILT_IN_FILETYPES) instead.
+   Rename GEANY_FILETYPES_ALL GEANY_FILETYPES_NONE.
+   Make Open dialog file filter work for filetypes added after
+   GEANY_FILETYPES_NONE (really the None filetype should be made the
+   first element in filetypes_array, but this would need rewriting
+   quite a lot of code).
+   Add deprecated aliases for GEANY_MAX_FILE_TYPES and
+   GEANY_FILETYPES_ALL.
+   Remove unused filetype::item field.
+   Create FullFileType private type that 'inherits' from filetype
+   (FullFileType* can be cast to filetype*). This is used in
+   filetype_new() to hide filetype struct fields from the API.
+   Remove radio_items[] and use FullFileType::menu_item instead.
+   Make filetypes_detect_from_extension() work for all filetypes
+   in filetypes_hash.
+   Add filetype_new() to create and initialize a new filetype.
+   Refactor open_session_file() from configuration_open_files().
+   Refactor get_session_file_string() from
+   configuration_save_session_files().
+   Refactor create_set_filetype_menu() from filetypes_init().
+   Move print_filetypes() out of parse_command_line_options();
+
+
 2008-05-06  Enrico Tröger  <enrico(dot)troeger(at)uvena(dot)de>
 
  * doc/geany.txt, doc/geany.html:

Modified: trunk/plugins/pluginmacros.h
===================================================================
--- trunk/plugins/pluginmacros.h	2008-05-07 14:09:12 UTC (rev 2558)
+++ trunk/plugins/pluginmacros.h	2008-05-07 16:29:48 UTC (rev 2559)
@@ -28,7 +28,8 @@
 #define PLUGINMACROS_H
 
 #define app				geany_data->app
-#define doc_array		geany_data->doc_array
+#define doc_array		geany_data->doc_array			/* Allows use of doc_list[] macro */
+#define filetypes_array	geany_data->filetypes_array		/* Allows use of filetypes[] macro */
 #define prefs			geany_data->prefs
 #define project			app->project
 

Modified: trunk/plugins/vcdiff.c
===================================================================
--- trunk/plugins/vcdiff.c	2008-05-07 14:09:12 UTC (rev 2558)
+++ trunk/plugins/vcdiff.c	2008-05-07 16:29:48 UTC (rev 2559)
@@ -286,8 +286,8 @@
 		idx = find_by_filename(filename);
 		if ( idx == -1)
 		{
-			idx = p_document->new_file(filename,
-				geany_data->filetypes[GEANY_FILETYPES_DIFF], text);
+			filetype *ft = p_filetypes->lookup_by_name("Diff");
+			idx = p_document->new_file(filename, ft, text);
 		}
 		else
 		{

Modified: trunk/src/build.c
===================================================================
--- trunk/src/build.c	2008-05-07 14:09:12 UTC (rev 2558)
+++ trunk/src/build.c	2008-05-07 16:29:48 UTC (rev 2559)
@@ -58,7 +58,7 @@
 #include "win32.h"
 
 
-BuildInfo build_info = {GBO_COMPILE, 0, NULL, GEANY_FILETYPES_ALL, NULL};
+BuildInfo build_info = {GBO_COMPILE, 0, NULL, GEANY_FILETYPES_NONE, NULL};
 
 static gchar *current_dir_entered = NULL;
 
@@ -66,7 +66,7 @@
 {
 	GPid pid;
 	gint file_type_id;
-} run_info = {0, GEANY_FILETYPES_ALL};
+} run_info = {0, GEANY_FILETYPES_NONE};
 
 #ifdef G_OS_WIN32
 static const gchar RUN_SCRIPT_CMD[] = "geany_run_script.bat";
@@ -1642,7 +1642,7 @@
 	if (idx == -1)
 		idx = document_get_cur_idx();
 	if (idx == -1 ||
-		(FILETYPE_ID(doc_list[idx].file_type) == GEANY_FILETYPES_ALL &&
+		(FILETYPE_ID(doc_list[idx].file_type) == GEANY_FILETYPES_NONE &&
 			doc_list[idx].file_name == NULL))
 	{
 		gtk_widget_set_sensitive(lookup_widget(app->window, "menu_build1"), FALSE);
@@ -1703,7 +1703,7 @@
 		((ft->actions->can_compile ||
 		ft->actions->can_link ||
 		ft->actions->can_exec) &&
-		FILETYPE_ID(ft) != GEANY_FILETYPES_ALL);
+		FILETYPE_ID(ft) != GEANY_FILETYPES_NONE);
 	if (menu_items->item_set_args)
 		gtk_widget_set_sensitive(menu_items->item_set_args, can_set_args);
 
@@ -1776,7 +1776,7 @@
 
 
 /* Creates the relevant build menu if necessary.
- * If filetype_idx is -1, the current filetype is used, or GEANY_FILETYPES_ALL */
+ * If filetype_idx is -1, the current filetype is used, or GEANY_FILETYPES_NONE */
 BuildMenuItems *build_get_menu_items(gint filetype_idx)
 {
 	BuildMenuItems *items;

Modified: trunk/src/dialogs.c
===================================================================
--- trunk/src/dialogs.c	2008-05-07 14:09:12 UTC (rev 2558)
+++ trunk/src/dialogs.c	2008-05-07 16:29:48 UTC (rev 2559)
@@ -87,7 +87,9 @@
 		gchar *charset = NULL;
 		gboolean ro = (response == GEANY_RESPONSE_VIEW);	/* View clicked */
 
-		if (filetype_idx >= 0 && filetype_idx < GEANY_FILETYPES_ALL) ft = filetypes[filetype_idx];
+		/* ignore detect from file item */
+		if (filetype_idx >= 0 && filetype_idx < GEANY_FILETYPES_NONE)
+			ft = filetypes[filetype_idx];
 		if (encoding_idx >= 0 && encoding_idx < GEANY_ENCODINGS_MAX)
 			charset = encodings[encoding_idx].charset;
 
@@ -169,7 +171,7 @@
 	GtkWidget *filetype_combo, *encoding_combo;
 	GtkWidget *viewbtn;
 	GtkTooltips *tooltips = GTK_TOOLTIPS(lookup_widget(app->window, "tooltips"));
-	gint i;
+	guint i;
 	gchar *encoding_string;
 
 	ui_widgets.open_filesel = gtk_file_chooser_dialog_new(_("Open File"), GTK_WINDOW(app->window),
@@ -201,18 +203,21 @@
 
 	/* 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_ALL]));
+				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 < GEANY_MAX_FILE_TYPES - 1; i++)
+	for (i = 0; i < filetypes_array->len; i++)
 	{
+		if (i == GEANY_FILETYPES_NONE)
+			continue;
+
 		gtk_combo_box_append_text(GTK_COMBO_BOX(filetype_combo), filetypes[i]->title);
 		gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(ui_widgets.open_filesel),
 				filetypes_create_file_filter(filetypes[i]));
 	}
 	gtk_combo_box_append_text(GTK_COMBO_BOX(filetype_combo), _("Detect by file extension"));
-	gtk_combo_box_set_active(GTK_COMBO_BOX(filetype_combo), GEANY_MAX_FILE_TYPES - 1);
+	gtk_combo_box_set_active(GTK_COMBO_BOX(filetype_combo), filetypes_array->len - 1);
 
 	/* fill encoding combo box */
 	encoding_combo = lookup_widget(ui_widgets.open_filesel, "encoding_combo");
@@ -550,7 +555,7 @@
 	{
 		gchar *fname = NULL;
 
-		if (doc_list[idx].file_type != NULL && doc_list[idx].file_type->id != GEANY_FILETYPES_ALL &&
+		if (doc_list[idx].file_type != NULL && doc_list[idx].file_type->id != GEANY_FILETYPES_NONE &&
 			doc_list[idx].file_type->extension != NULL)
 			fname = g_strconcat(GEANY_STRING_UNTITLED, ".",
 								doc_list[idx].file_type->extension, NULL);

Modified: trunk/src/document.c
===================================================================
--- trunk/src/document.c	2008-05-07 14:09:12 UTC (rev 2558)
+++ trunk/src/document.c	2008-05-07 16:29:48 UTC (rev 2559)
@@ -633,13 +633,13 @@
 	/* store the opened encoding for undo/redo */
 	store_saved_encoding(idx);
 
-	/*document_set_filetype(idx, (ft == NULL) ? filetypes[GEANY_FILETYPES_ALL] : ft);*/
+	/*document_set_filetype(idx, (ft == NULL) ? filetypes[GEANY_FILETYPES_NONE] : ft);*/
 	if (ft == NULL && filename != NULL) /* guess the filetype from the filename if one is given */
 		ft = filetypes_detect_from_file(idx);
 
 	document_set_filetype(idx, ft);	/* also clears taglist */
 	if (ft == NULL)
-		highlighting_set_styles(doc_list[idx].sci, GEANY_FILETYPES_ALL);
+		highlighting_set_styles(doc_list[idx].sci, GEANY_FILETYPES_NONE);
 	ui_set_window_title(idx);
 	build_menu_update(idx);
 	document_update_tag_list(idx, FALSE);
@@ -1294,7 +1294,7 @@
 	if (! DOC_IDX_VALID(idx)) return FALSE;
 
 	/* detect filetype */
-	if (FILETYPE_ID(doc_list[idx].file_type) == GEANY_FILETYPES_ALL)
+	if (FILETYPE_ID(doc_list[idx].file_type) == GEANY_FILETYPES_NONE)
 	{
 		filetype *ft = filetypes_detect_from_file(idx);
 

Modified: trunk/src/filetypes.c
===================================================================
--- trunk/src/filetypes.c	2008-05-07 14:09:12 UTC (rev 2558)
+++ trunk/src/filetypes.c	2008-05-07 16:29:48 UTC (rev 2559)
@@ -37,72 +37,32 @@
 #include "utils.h"
 #include "document.h"
 #include "sciwrappers.h"
+#include "ui_utils.h"
 
 
-filetype *filetypes[GEANY_MAX_FILE_TYPES];
+/* This type 'inherits' from filetype so FullFileType* can be cast to filetype*. */
+typedef struct FullFileType
+{
+	filetype	public;
+	/* Private fields */
+	GtkWidget	*menu_item;			/* holds a pointer to the menu item for this filetype */
+	gboolean	keyfile_loaded;
+}
+FullFileType;
 
 
-/* This is the order of unique ids used in the config file.
- * The order must not be changed but can be appended to. */
-enum
-{
-	FILETYPE_UID_C = 0,		/* 0 */
-	FILETYPE_UID_CPP,		/* 1 */
-	FILETYPE_UID_JAVA,		/* 2 */
-	FILETYPE_UID_PERL,		/* 3 */
-	FILETYPE_UID_PHP,		/* 4 */
-	FILETYPE_UID_XML,		/* 5 */
-	FILETYPE_UID_DOCBOOK,	/* 6 */
-	FILETYPE_UID_PYTHON,	/* 7 */
-	FILETYPE_UID_LATEX,		/* 8 */
-	FILETYPE_UID_PASCAL,	/* 9 */
-	FILETYPE_UID_SH,		/* 10 */
-	FILETYPE_UID_MAKE,		/* 11 */
-	FILETYPE_UID_CSS,		/* 12 */
-	FILETYPE_UID_CONF,		/* 13 */
-	FILETYPE_UID_ASM,		/* 14 */
-	FILETYPE_UID_SQL,		/* 15 */
-	FILETYPE_UID_CAML,		/* 16 */
-	FILETYPE_UID_OMS,		/* 17 */
-	FILETYPE_UID_RUBY,		/* 18 */
-	FILETYPE_UID_TCL,		/* 19 */
-	FILETYPE_UID_ALL,		/* 20 */
-	FILETYPE_UID_D,			/* 21 */
-	FILETYPE_UID_FORTRAN,	/* 22 */
-	FILETYPE_UID_DIFF,		/* 23 */
-	FILETYPE_UID_FERITE,	/* 24 */
-	FILETYPE_UID_HTML,		/* 25 */
-	FILETYPE_UID_VHDL,		/* 26 */
-	FILETYPE_UID_JS,		/* 27 */
-	FILETYPE_UID_LUA,		/* 28 */
-	FILETYPE_UID_HASKELL,	/* 29 */
-	FILETYPE_UID_CS,		/* 30 */
-	FILETYPE_UID_BASIC,		/* 31 */
-	FILETYPE_UID_HAXE,		/* 32 */
-	FILETYPE_UID_REST		/* 33 */
-};
+GPtrArray *filetypes_array = NULL;	/* Dynamic array of filetype pointers */
 
+GHashTable *filetypes_hash = NULL;	/* Hash of filetype pointers based on name keys */
 
-static GtkWidget *radio_items[GEANY_MAX_FILE_TYPES];
 
-static void filetypes_create_menu_item(GtkWidget *menu, const gchar *label, filetype *ftype);
+static void create_radio_menu_item(GtkWidget *menu, const gchar *label, filetype *ftype);
 
 
-/* Create the filetype array and fill it with the known filetypes. */
-void filetypes_init_types()
+static void init_builtin_filetypes(void)
 {
-	filetype_id ft_id;
-
-	for (ft_id = 0; ft_id < GEANY_MAX_FILE_TYPES; ft_id++)
-	{
-		filetypes[ft_id] = g_new0(filetype, 1);
-		filetypes[ft_id]->programs = g_new0(struct build_programs, 1);
-		filetypes[ft_id]->actions = g_new0(struct build_actions, 1);
-	}
-
 #define C	/* these macros are only to ease navigation */
 	filetypes[GEANY_FILETYPES_C]->id = GEANY_FILETYPES_C;
-	filetypes[GEANY_FILETYPES_C]->uid = FILETYPE_UID_C;
 	filetypes[GEANY_FILETYPES_C]->lang = 0;
 	filetypes[GEANY_FILETYPES_C]->name = g_strdup("C");
 	filetypes[GEANY_FILETYPES_C]->title = g_strdup_printf(_("%s source file"), "C");
@@ -113,7 +73,6 @@
 
 #define CPP
 	filetypes[GEANY_FILETYPES_CPP]->id = GEANY_FILETYPES_CPP;
-	filetypes[GEANY_FILETYPES_CPP]->uid = FILETYPE_UID_CPP;
 	filetypes[GEANY_FILETYPES_CPP]->lang = 1;
 	filetypes[GEANY_FILETYPES_CPP]->name = g_strdup("C++");
 	filetypes[GEANY_FILETYPES_CPP]->title = g_strdup_printf(_("%s source file"), "C++");
@@ -125,7 +84,6 @@
 
 #define CS
 	filetypes[GEANY_FILETYPES_CS]->id = GEANY_FILETYPES_CS;
-	filetypes[GEANY_FILETYPES_CS]->uid = FILETYPE_UID_CS;
 	filetypes[GEANY_FILETYPES_CS]->lang = 25;
 	filetypes[GEANY_FILETYPES_CS]->name = g_strdup("C#");
 	filetypes[GEANY_FILETYPES_CS]->title = g_strdup_printf(_("%s source file"), "C#");
@@ -136,7 +94,6 @@
 
 #define D
 	filetypes[GEANY_FILETYPES_D]->id = GEANY_FILETYPES_D;
-	filetypes[GEANY_FILETYPES_D]->uid = FILETYPE_UID_D;
 	filetypes[GEANY_FILETYPES_D]->lang = 17;
 	filetypes[GEANY_FILETYPES_D]->name = g_strdup("D");
 	filetypes[GEANY_FILETYPES_D]->title = g_strdup_printf(_("%s source file"), "D");
@@ -148,7 +105,6 @@
 #define JAVA
 	filetypes[GEANY_FILETYPES_JAVA]->id = GEANY_FILETYPES_JAVA;
 	filetypes[GEANY_FILETYPES_JAVA]->name = g_strdup("Java");
-	filetypes[GEANY_FILETYPES_JAVA]->uid = FILETYPE_UID_JAVA;
 	filetypes[GEANY_FILETYPES_JAVA]->lang = 2;
 	filetypes[GEANY_FILETYPES_JAVA]->title = g_strdup_printf(_("%s source file"), "Java");
 	filetypes[GEANY_FILETYPES_JAVA]->extension = g_strdup("java");
@@ -158,7 +114,6 @@
 
 #define PAS /* to avoid warnings when building under Windows, the symbol PASCAL is there defined */
 	filetypes[GEANY_FILETYPES_PASCAL]->id = GEANY_FILETYPES_PASCAL;
-	filetypes[GEANY_FILETYPES_PASCAL]->uid = FILETYPE_UID_PASCAL;
 	filetypes[GEANY_FILETYPES_PASCAL]->lang = 4;
 	filetypes[GEANY_FILETYPES_PASCAL]->name = g_strdup("Pascal");
 	filetypes[GEANY_FILETYPES_PASCAL]->title = g_strdup_printf(_("%s source file"), "Pascal");
@@ -170,7 +125,6 @@
 
 #define ASM
 	filetypes[GEANY_FILETYPES_ASM]->id = GEANY_FILETYPES_ASM;
-	filetypes[GEANY_FILETYPES_ASM]->uid = FILETYPE_UID_ASM;
 	filetypes[GEANY_FILETYPES_ASM]->lang = 9;
 	filetypes[GEANY_FILETYPES_ASM]->name = g_strdup("ASM");
 	filetypes[GEANY_FILETYPES_ASM]->title = g_strdup_printf(_("%s source file"), "Assembler");
@@ -181,7 +135,6 @@
 
 #define BASIC
 	filetypes[GEANY_FILETYPES_BASIC]->id = GEANY_FILETYPES_BASIC;
-	filetypes[GEANY_FILETYPES_BASIC]->uid = FILETYPE_UID_BASIC;
 	filetypes[GEANY_FILETYPES_BASIC]->lang = 26;
 	filetypes[GEANY_FILETYPES_BASIC]->name = g_strdup("FreeBasic");
 	filetypes[GEANY_FILETYPES_BASIC]->title = g_strdup_printf(_("%s source file"), "FreeBasic");
@@ -192,7 +145,6 @@
 
 #define FORTRAN
 	filetypes[GEANY_FILETYPES_FORTRAN]->id = GEANY_FILETYPES_FORTRAN;
-	filetypes[GEANY_FILETYPES_FORTRAN]->uid = FILETYPE_UID_FORTRAN;
 	filetypes[GEANY_FILETYPES_FORTRAN]->lang = 18;
 	filetypes[GEANY_FILETYPES_FORTRAN]->name = g_strdup("Fortran");
 	filetypes[GEANY_FILETYPES_FORTRAN]->title = g_strdup_printf(_("%s source file"), "Fortran (F77)");
@@ -204,7 +156,6 @@
 
 #define CAML
 	filetypes[GEANY_FILETYPES_CAML]->id = GEANY_FILETYPES_CAML;
-	filetypes[GEANY_FILETYPES_CAML]->uid = FILETYPE_UID_CAML;
 	filetypes[GEANY_FILETYPES_CAML]->lang = -2;
 	filetypes[GEANY_FILETYPES_CAML]->name = g_strdup("CAML");
 	filetypes[GEANY_FILETYPES_CAML]->title = g_strdup_printf(_("%s source file"), "(O)Caml");
@@ -215,7 +166,6 @@
 
 #define PERL
 	filetypes[GEANY_FILETYPES_PERL]->id = GEANY_FILETYPES_PERL;
-	filetypes[GEANY_FILETYPES_PERL]->uid = FILETYPE_UID_PERL;
 	filetypes[GEANY_FILETYPES_PERL]->lang = 5;
 	filetypes[GEANY_FILETYPES_PERL]->name = g_strdup("Perl");
 	filetypes[GEANY_FILETYPES_PERL]->title = g_strdup_printf(_("%s source file"), "Perl");
@@ -227,7 +177,6 @@
 
 #define PHP
 	filetypes[GEANY_FILETYPES_PHP]->id = GEANY_FILETYPES_PHP;
-	filetypes[GEANY_FILETYPES_PHP]->uid = FILETYPE_UID_PHP;
 	filetypes[GEANY_FILETYPES_PHP]->lang = 6;
 	filetypes[GEANY_FILETYPES_PHP]->name = g_strdup("PHP");
 	filetypes[GEANY_FILETYPES_PHP]->title = g_strdup_printf(_("%s source file"), "PHP");
@@ -239,7 +188,6 @@
 
 #define JAVASCRIPT
 	filetypes[GEANY_FILETYPES_JS]->id = GEANY_FILETYPES_JS;
-	filetypes[GEANY_FILETYPES_JS]->uid = FILETYPE_UID_JS;
 	filetypes[GEANY_FILETYPES_JS]->lang = 23;
 	filetypes[GEANY_FILETYPES_JS]->name = g_strdup("Javascript");
 	filetypes[GEANY_FILETYPES_JS]->title = g_strdup_printf(_("%s source file"), "Javascript");
@@ -250,7 +198,6 @@
 
 #define PYTHON
 	filetypes[GEANY_FILETYPES_PYTHON]->id = GEANY_FILETYPES_PYTHON;
-	filetypes[GEANY_FILETYPES_PYTHON]->uid = FILETYPE_UID_PYTHON;
 	filetypes[GEANY_FILETYPES_PYTHON]->lang = 7;
 	filetypes[GEANY_FILETYPES_PYTHON]->name = g_strdup("Python");
 	filetypes[GEANY_FILETYPES_PYTHON]->title = g_strdup_printf(_("%s source file"), "Python");
@@ -261,7 +208,6 @@
 
 #define RUBY
 	filetypes[GEANY_FILETYPES_RUBY]->id = GEANY_FILETYPES_RUBY;
-	filetypes[GEANY_FILETYPES_RUBY]->uid = FILETYPE_UID_RUBY;
 	filetypes[GEANY_FILETYPES_RUBY]->lang = 14;
 	filetypes[GEANY_FILETYPES_RUBY]->name = g_strdup("Ruby");
 	filetypes[GEANY_FILETYPES_RUBY]->title = g_strdup_printf(_("%s source file"), "Ruby");
@@ -272,7 +218,6 @@
 
 #define TCL
 	filetypes[GEANY_FILETYPES_TCL]->id = GEANY_FILETYPES_TCL;
-	filetypes[GEANY_FILETYPES_TCL]->uid = FILETYPE_UID_TCL;
 	filetypes[GEANY_FILETYPES_TCL]->lang = 15;
 	filetypes[GEANY_FILETYPES_TCL]->name = g_strdup("Tcl");
 	filetypes[GEANY_FILETYPES_TCL]->title = g_strdup_printf(_("%s source file"), "Tcl");
@@ -283,7 +228,6 @@
 
 #define LUA
 	filetypes[GEANY_FILETYPES_LUA]->id = GEANY_FILETYPES_LUA;
-	filetypes[GEANY_FILETYPES_LUA]->uid = FILETYPE_UID_LUA;
 	filetypes[GEANY_FILETYPES_LUA]->lang = 22;
 	filetypes[GEANY_FILETYPES_LUA]->name = g_strdup("Lua");
 	filetypes[GEANY_FILETYPES_LUA]->title = g_strdup_printf(_("%s source file"), "Lua");
@@ -294,7 +238,6 @@
 
 #define FERITE
 	filetypes[GEANY_FILETYPES_FERITE]->id = GEANY_FILETYPES_FERITE;
-	filetypes[GEANY_FILETYPES_FERITE]->uid = FILETYPE_UID_FERITE;
 	filetypes[GEANY_FILETYPES_FERITE]->lang = 19;
 	filetypes[GEANY_FILETYPES_FERITE]->name = g_strdup("Ferite");
 	filetypes[GEANY_FILETYPES_FERITE]->title = g_strdup_printf(_("%s source file"), "Ferite");
@@ -305,7 +248,6 @@
 
 #define HASKELL
 	filetypes[GEANY_FILETYPES_HASKELL]->id = GEANY_FILETYPES_HASKELL;
-	filetypes[GEANY_FILETYPES_HASKELL]->uid = FILETYPE_UID_HASKELL;
 	filetypes[GEANY_FILETYPES_HASKELL]->lang = 24;
 	filetypes[GEANY_FILETYPES_HASKELL]->name = g_strdup("Haskell");
 	filetypes[GEANY_FILETYPES_HASKELL]->title = g_strdup_printf(_("%s source file"), "Haskell");
@@ -316,7 +258,6 @@
 
 #define SH
 	filetypes[GEANY_FILETYPES_SH]->id = GEANY_FILETYPES_SH;
-	filetypes[GEANY_FILETYPES_SH]->uid = FILETYPE_UID_SH;
 	filetypes[GEANY_FILETYPES_SH]->lang = 16;
 	filetypes[GEANY_FILETYPES_SH]->name = g_strdup("Sh");
 	filetypes[GEANY_FILETYPES_SH]->title = g_strdup(_("Shell script file"));
@@ -328,7 +269,6 @@
 
 #define MAKE
 	filetypes[GEANY_FILETYPES_MAKE]->id = GEANY_FILETYPES_MAKE;
-	filetypes[GEANY_FILETYPES_MAKE]->uid = FILETYPE_UID_MAKE;
 	filetypes[GEANY_FILETYPES_MAKE]->lang = 3;
 	filetypes[GEANY_FILETYPES_MAKE]->name = g_strdup("Make");
 	filetypes[GEANY_FILETYPES_MAKE]->title = g_strdup(_("Makefile"));
@@ -340,7 +280,6 @@
 
 #define XML
 	filetypes[GEANY_FILETYPES_XML]->id = GEANY_FILETYPES_XML;
-	filetypes[GEANY_FILETYPES_XML]->uid = FILETYPE_UID_XML;
 	filetypes[GEANY_FILETYPES_XML]->lang = -2;
 	filetypes[GEANY_FILETYPES_XML]->name = g_strdup("XML");
 	filetypes[GEANY_FILETYPES_XML]->title = g_strdup(_("XML document"));
@@ -352,7 +291,6 @@
 
 #define DOCBOOK
 	filetypes[GEANY_FILETYPES_DOCBOOK]->id = GEANY_FILETYPES_DOCBOOK;
-	filetypes[GEANY_FILETYPES_DOCBOOK]->uid = FILETYPE_UID_DOCBOOK;
 	filetypes[GEANY_FILETYPES_DOCBOOK]->lang = 12;
 	filetypes[GEANY_FILETYPES_DOCBOOK]->name = g_strdup("Docbook");
 	filetypes[GEANY_FILETYPES_DOCBOOK]->title = g_strdup_printf(_("%s source file"), "Docbook");
@@ -363,7 +301,6 @@
 
 #define HTML
 	filetypes[GEANY_FILETYPES_HTML]->id = GEANY_FILETYPES_HTML;
-	filetypes[GEANY_FILETYPES_HTML]->uid = FILETYPE_UID_HTML;
 	filetypes[GEANY_FILETYPES_HTML]->lang = 29;
 	filetypes[GEANY_FILETYPES_HTML]->name = g_strdup("HTML");
 	filetypes[GEANY_FILETYPES_HTML]->title = g_strdup_printf(_("%s source file"), "HTML");
@@ -375,7 +312,6 @@
 
 #define CSS
 	filetypes[GEANY_FILETYPES_CSS]->id = GEANY_FILETYPES_CSS;
-	filetypes[GEANY_FILETYPES_CSS]->uid = FILETYPE_UID_CSS;
 	filetypes[GEANY_FILETYPES_CSS]->lang = 13;
 	filetypes[GEANY_FILETYPES_CSS]->name = g_strdup("CSS");
 	filetypes[GEANY_FILETYPES_CSS]->title = g_strdup(_("Cascading StyleSheet"));
@@ -386,7 +322,6 @@
 
 #define SQL
 	filetypes[GEANY_FILETYPES_SQL]->id = GEANY_FILETYPES_SQL;
-	filetypes[GEANY_FILETYPES_SQL]->uid = FILETYPE_UID_SQL;
 	filetypes[GEANY_FILETYPES_SQL]->lang = 11;
 	filetypes[GEANY_FILETYPES_SQL]->name = g_strdup("SQL");
 	filetypes[GEANY_FILETYPES_SQL]->title = g_strdup(_("SQL Dump file"));
@@ -397,7 +332,6 @@
 
 #define LATEX
 	filetypes[GEANY_FILETYPES_LATEX]->id = GEANY_FILETYPES_LATEX;
-	filetypes[GEANY_FILETYPES_LATEX]->uid = FILETYPE_UID_LATEX;
 	filetypes[GEANY_FILETYPES_LATEX]->lang = 8;
 	filetypes[GEANY_FILETYPES_LATEX]->name = g_strdup("LaTeX");
 	filetypes[GEANY_FILETYPES_LATEX]->title = g_strdup_printf(_("%s source file"), "LaTeX");
@@ -408,7 +342,6 @@
 
 #define OMS
 	filetypes[GEANY_FILETYPES_OMS]->id = GEANY_FILETYPES_OMS;
-	filetypes[GEANY_FILETYPES_OMS]->uid = FILETYPE_UID_OMS;
 	filetypes[GEANY_FILETYPES_OMS]->lang = -2;
 	filetypes[GEANY_FILETYPES_OMS]->name = g_strdup("O-Matrix");
 	filetypes[GEANY_FILETYPES_OMS]->title = g_strdup_printf(_("%s source file"), "O-Matrix");
@@ -419,7 +352,6 @@
 
 #define VHDL
 	filetypes[GEANY_FILETYPES_VHDL]->id = GEANY_FILETYPES_VHDL;
-	filetypes[GEANY_FILETYPES_VHDL]->uid = FILETYPE_UID_VHDL;
 	filetypes[GEANY_FILETYPES_VHDL]->lang = 21;
 	filetypes[GEANY_FILETYPES_VHDL]->name = g_strdup("VHDL");
 	filetypes[GEANY_FILETYPES_VHDL]->title = g_strdup_printf(_("%s source file"), "VHDL");
@@ -430,7 +362,6 @@
 
 #define DIFF
 	filetypes[GEANY_FILETYPES_DIFF]->id = GEANY_FILETYPES_DIFF;
-	filetypes[GEANY_FILETYPES_DIFF]->uid = FILETYPE_UID_DIFF;
 	filetypes[GEANY_FILETYPES_DIFF]->lang = 20;
 	filetypes[GEANY_FILETYPES_DIFF]->name = g_strdup("Diff");
 	filetypes[GEANY_FILETYPES_DIFF]->title = g_strdup(_("Diff file"));
@@ -441,7 +372,6 @@
 
 #define CONF
 	filetypes[GEANY_FILETYPES_CONF]->id = GEANY_FILETYPES_CONF;
-	filetypes[GEANY_FILETYPES_CONF]->uid = FILETYPE_UID_CONF;
 	filetypes[GEANY_FILETYPES_CONF]->lang = 10;
 	filetypes[GEANY_FILETYPES_CONF]->name = g_strdup("Conf");
 	filetypes[GEANY_FILETYPES_CONF]->title = g_strdup(_("Config file"));
@@ -453,7 +383,6 @@
 
 #define HAXE
 	filetypes[GEANY_FILETYPES_HAXE]->id = GEANY_FILETYPES_HAXE;
-	filetypes[GEANY_FILETYPES_HAXE]->uid = FILETYPE_UID_HAXE;
 	filetypes[GEANY_FILETYPES_HAXE]->lang = 27;
 	filetypes[GEANY_FILETYPES_HAXE]->name = g_strdup("Haxe");
 	filetypes[GEANY_FILETYPES_HAXE]->title = g_strdup_printf(_("%s source file"), "Haxe");
@@ -464,7 +393,6 @@
 
 #define REST
 	filetypes[GEANY_FILETYPES_REST]->id = GEANY_FILETYPES_REST;
-	filetypes[GEANY_FILETYPES_REST]->uid = FILETYPE_UID_REST;
 	filetypes[GEANY_FILETYPES_REST]->lang = 28;
 	filetypes[GEANY_FILETYPES_REST]->name = g_strdup("reStructuredText");
 	filetypes[GEANY_FILETYPES_REST]->title = g_strdup(_("reStructuredText file"));
@@ -475,18 +403,70 @@
 	filetypes[GEANY_FILETYPES_REST]->comment_close = NULL;
 
 #define ALL
-	filetypes[GEANY_FILETYPES_ALL]->id = GEANY_FILETYPES_ALL;
-	filetypes[GEANY_FILETYPES_ALL]->name = g_strdup("None");
-	filetypes[GEANY_FILETYPES_ALL]->uid = FILETYPE_UID_ALL;
-	filetypes[GEANY_FILETYPES_ALL]->lang = -2;
-	filetypes[GEANY_FILETYPES_ALL]->title = g_strdup(_("All files"));
-	filetypes[GEANY_FILETYPES_ALL]->extension = g_strdup("*");
-	filetypes[GEANY_FILETYPES_ALL]->pattern = utils_strv_new("*", NULL);
-	filetypes[GEANY_FILETYPES_ALL]->comment_open = NULL;
-	filetypes[GEANY_FILETYPES_ALL]->comment_close = NULL;
+	filetypes[GEANY_FILETYPES_NONE]->id = GEANY_FILETYPES_NONE;
+	filetypes[GEANY_FILETYPES_NONE]->name = g_strdup("None");
+	filetypes[GEANY_FILETYPES_NONE]->lang = -2;
+	filetypes[GEANY_FILETYPES_NONE]->title = g_strdup(_("All files"));
+	filetypes[GEANY_FILETYPES_NONE]->extension = g_strdup("*");
+	filetypes[GEANY_FILETYPES_NONE]->pattern = utils_strv_new("*", NULL);
+	filetypes[GEANY_FILETYPES_NONE]->comment_open = NULL;
+	filetypes[GEANY_FILETYPES_NONE]->comment_close = NULL;
 }
 
 
+/* initialize fields. */
+static filetype *filetype_new(void)
+{
+	FullFileType *fft = g_new0(FullFileType, 1);
+	filetype *ft = (filetype*) fft;
+
+/*
+	ft->id = GEANY_FILETYPES_OTHER;
+*/
+	ft->lang = -2;	/* assume no tagmanager parser */
+	ft->programs = g_new0(struct build_programs, 1);
+	ft->actions = g_new0(struct build_actions, 1);
+	return ft;
+}
+
+
+/* Add a filetype pointer to the list of available filetypes. */
+static void filetype_add(filetype *ft)
+{
+	g_return_if_fail(ft);
+	g_return_if_fail(ft->name);
+
+	g_ptr_array_add(filetypes_array, ft);
+	g_hash_table_insert(filetypes_hash, ft->name, ft);
+}
+
+
+/* Create the filetypes array and fill it with the known filetypes. */
+void filetypes_init_types()
+{
+	filetype_id ft_id;
+
+	g_return_if_fail(filetypes_array == NULL);
+	g_return_if_fail(filetypes_hash == NULL);
+
+	filetypes_array = g_ptr_array_sized_new(GEANY_MAX_BUILT_IN_FILETYPES);
+	filetypes_hash = g_hash_table_new(g_str_hash, g_str_equal);
+
+	/* Create built-in filetypes */
+	for (ft_id = 0; ft_id < GEANY_MAX_BUILT_IN_FILETYPES; ft_id++)
+	{
+		filetypes[ft_id] = filetype_new();
+	}
+	init_builtin_filetypes();
+
+	/* Add built-in filetypes to the hash now the name fields are set */
+	for (ft_id = 0; ft_id < GEANY_MAX_BUILT_IN_FILETYPES; ft_id++)
+	{
+		filetype_add(filetypes[ft_id]);
+	}
+}
+
+
 #define create_sub_menu(menu, item, title) \
 	(menu) = gtk_menu_new(); \
 	(item) = gtk_menu_item_new_with_mnemonic((title)); \
@@ -495,8 +475,7 @@
 	gtk_widget_show((item));
 
 
-/* Calls filetypes_init_types() and creates the filetype menu. */
-void filetypes_init()
+static void create_set_filetype_menu()
 {
 	filetype_id ft_id;
 	GtkWidget *filetype_menu = lookup_widget(app->window, "set_filetype1_menu");
@@ -504,15 +483,13 @@
 	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;
 
-	filetypes_init_types();
-
 	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"));
 
 	/* Append all filetypes to the filetype menu */
-	for (ft_id = 0; ft_id < GEANY_MAX_FILE_TYPES; ft_id++)
+	for (ft_id = 0; ft_id < filetypes_array->len; ft_id++)
 	{
 		filetype *ft = filetypes[ft_id];
 		const gchar *title = ft->title;
@@ -540,7 +517,7 @@
 				sub_menu = sub_menu_misc;
 				break;
 			}
-			case GEANY_FILETYPES_ALL:	/* none */
+			case GEANY_FILETYPES_NONE:	/* none */
 			{
 				sub_menu = filetype_menu;
 				title = _("None");
@@ -548,25 +525,42 @@
 			}
 			default: break;
 		}
-		ft->item = NULL;
-		filetypes_create_menu_item(sub_menu, title, ft);
+		create_radio_menu_item(sub_menu, title, ft);
 	}
 }
 
 
-/* If uid is valid, return corresponding filetype, otherwise NULL. */
-filetype *filetypes_get_from_uid(gint uid)
+void filetypes_init()
 {
-	gint i;
+	filetypes_init_types();
+	create_set_filetype_menu();
+}
 
-	for (i = 0; i < GEANY_MAX_FILE_TYPES; i++)
+
+static gboolean match_basename(G_GNUC_UNUSED gpointer key, gpointer value, gpointer user_data)
+{
+	filetype *ft = value;
+	const gchar *base_filename = user_data;
+	gint j;
+	gboolean ret = FALSE;
+
+	/* Don't match '*' because it comes before any custom filetypes */
+	if (ft->id == GEANY_FILETYPES_NONE)
+		return FALSE;
+
+	for (j = 0; ft->pattern[j] != NULL; j++)
 	{
-		filetype *ft = filetypes[i];
+		GPatternSpec *pattern = g_pattern_spec_new(ft->pattern[j]);
 
-		if (ft->uid == (guint) uid)
-			return ft;
+		if (g_pattern_match_string(pattern, base_filename))
+		{
+			ret = TRUE;
+			g_pattern_spec_free(pattern);
+			break;
+		}
+		g_pattern_spec_free(pattern);
 	}
-	return NULL;
+	return ret;
 }
 
 
@@ -574,34 +568,22 @@
  * utf8_filename can include the full path. */
 filetype *filetypes_detect_from_extension(const gchar *utf8_filename)
 {
-	GPatternSpec *pattern;
 	gchar *base_filename;
-	gint i, j;
+	filetype *ft;
 
-	/* to match against the basename of the file(because of Makefile*) */
+	/* to match against the basename of the file (because of Makefile*) */
 	base_filename = g_path_get_basename(utf8_filename);
 #ifdef G_OS_WIN32
 	/* use lower case basename */
 	setptr(base_filename, g_utf8_strdown(base_filename, -1));
 #endif
 
-	for(i = 0; i < GEANY_MAX_FILE_TYPES; i++)
-	{
-		for (j = 0; filetypes[i]->pattern[j] != NULL; j++)
-		{
-			pattern = g_pattern_spec_new(filetypes[i]->pattern[j]);
-			if (g_pattern_match_string(pattern, base_filename))
-			{
-				g_free(base_filename);
-				g_pattern_spec_free(pattern);
-				return filetypes[i];
-			}
-			g_pattern_spec_free(pattern);
-		}
-	}
+	ft = g_hash_table_find(filetypes_hash, match_basename, base_filename);
+	if (ft == NULL)
+		ft = filetypes[GEANY_FILETYPES_NONE];
 
 	g_free(base_filename);
-	return filetypes[GEANY_FILETYPES_ALL];
+	return ft;
 }
 
 
@@ -684,7 +666,7 @@
 		return ft;
 
 	if (utf8_filename == NULL)
-		return filetypes[GEANY_FILETYPES_ALL];
+		return filetypes[GEANY_FILETYPES_NONE];
 
 	return filetypes_detect_from_extension(utf8_filename);
 }
@@ -697,7 +679,7 @@
 	gchar *line;
 
 	if (! DOC_IDX_VALID(idx))
-		return filetypes[GEANY_FILETYPES_ALL];
+		return filetypes[GEANY_FILETYPES_NONE];
 
 	line = sci_get_line(doc_list[idx].sci, 0);
 	ft = filetypes_detect_from_file_internal(doc_list[idx].file_name, line);
@@ -731,12 +713,16 @@
 
 void filetypes_select_radio_item(const filetype *ft)
 {
+	FullFileType *fft;
+
 	/* app->ignore_callback has to be set by the caller */
+	g_return_if_fail(app->ignore_callback);
+
 	if (ft == NULL)
-		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
-			radio_items[filetypes[GEANY_FILETYPES_ALL]->id]), TRUE);
-	else
-		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(radio_items[ft->id]), TRUE);
+		ft = filetypes[GEANY_FILETYPES_NONE];
+
+	fft = (FullFileType*)ft;
+	gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(fft->menu_item), TRUE);
 }
 
 
@@ -751,46 +737,68 @@
 }
 
 
-static void filetypes_create_menu_item(GtkWidget *menu, const gchar *label, filetype *ftype)
+static void create_radio_menu_item(GtkWidget *menu, const gchar *label, filetype *ftype)
 {
 	static GSList *group = NULL;
 	GtkWidget *tmp;
+	FullFileType *fft = (FullFileType*)ftype;
 
 	tmp = gtk_radio_menu_item_new_with_label(group, label);
 	group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(tmp));
-	radio_items[ftype->id] = tmp;
+	fft->menu_item = tmp;
 	gtk_widget_show(tmp);
 	gtk_container_add(GTK_CONTAINER(menu), tmp);
 	g_signal_connect((gpointer) tmp, "activate", G_CALLBACK(on_filetype_change), (gpointer) ftype);
 }
 
 
+#if 0
+/* Remove a filetype pointer from the list of available filetypes. */
+static void filetype_remove(filetype *ft)
+{
+	g_return_if_fail(ft);
+
+	g_ptr_array_remove(filetypes_array, ft);
+
+	if (!g_hash_table_remove(filetypes_hash, ft))
+		g_warning("Could not remove filetype %p!", ft);
+}
+#endif
+
+
+static void filetype_free(gpointer data, G_GNUC_UNUSED gpointer user_data)
+{
+	filetype *ft = data;
+
+	g_return_if_fail(ft != NULL);
+
+	g_free(ft->name);
+	g_free(ft->title);
+	g_free(ft->extension);
+	g_free(ft->comment_open);
+	g_free(ft->comment_close);
+	g_free(ft->context_action_cmd);
+	g_free(ft->programs->compiler);
+	g_free(ft->programs->linker);
+	g_free(ft->programs->run_cmd);
+	g_free(ft->programs->run_cmd2);
+	g_free(ft->programs);
+	g_free(ft->actions);
+
+	g_strfreev(ft->pattern);
+	g_free(ft);
+}
+
+
 /* frees the array and all related pointers */
 void filetypes_free_types()
 {
-	gint i;
+	g_return_if_fail(filetypes_array != NULL);
+	g_return_if_fail(filetypes_hash != NULL);
 
-	for(i = 0; i < GEANY_MAX_FILE_TYPES; i++)
-	{
-		if (filetypes[i])
-		{
-			g_free(filetypes[i]->name);
-			g_free(filetypes[i]->title);
-			g_free(filetypes[i]->extension);
-			g_free(filetypes[i]->comment_open);
-			g_free(filetypes[i]->comment_close);
-			g_free(filetypes[i]->context_action_cmd);
-			g_free(filetypes[i]->programs->compiler);
-			g_free(filetypes[i]->programs->linker);
-			g_free(filetypes[i]->programs->run_cmd);
-			g_free(filetypes[i]->programs->run_cmd2);
-			g_free(filetypes[i]->programs);
-			g_free(filetypes[i]->actions);
-
-			g_strfreev(filetypes[i]->pattern);
-			g_free(filetypes[i]);
-		}
-	}
+	g_ptr_array_foreach(filetypes_array, filetype_free, NULL);
+	g_ptr_array_free(filetypes_array, TRUE);
+	g_hash_table_destroy(filetypes_hash);
 }
 
 
@@ -900,19 +908,19 @@
 void filetypes_load_config(gint ft_id)
 {
 	GKeyFile *config, *config_home;
-	static gboolean loaded[GEANY_MAX_FILE_TYPES] = {FALSE};
+	FullFileType *fft = (FullFileType*)filetypes[ft_id];
 
-	g_return_if_fail(ft_id >= 0 && ft_id < GEANY_MAX_FILE_TYPES);
+	g_return_if_fail(ft_id >= 0 && ft_id < (gint) filetypes_array->len);
 
-	if (loaded[ft_id])
+	if (fft->keyfile_loaded)
 		return;
-	loaded[ft_id] = TRUE;
+	fft->keyfile_loaded = TRUE;
 
 	config = g_key_file_new();
 	config_home = g_key_file_new();
 	{
-		/* highlighting uses GEANY_FILETYPES_ALL for common settings */
-		gchar *ext = (ft_id != GEANY_FILETYPES_ALL) ?
+		/* highlighting uses GEANY_FILETYPES_NONE for common settings */
+		gchar *ext = (ft_id != GEANY_FILETYPES_NONE) ?
 			filetypes_get_conf_extension(ft_id) : g_strdup("common");
 		gchar *f0 = g_strconcat(app->datadir, G_DIR_SEPARATOR_S "filetypes.", ext, NULL);
 		gchar *f = g_strconcat(app->configdir,
@@ -957,7 +965,7 @@
 		G_DIR_SEPARATOR_S GEANY_FILEDEFS_SUBDIR G_DIR_SEPARATOR_S "filetypes.", NULL);
 	gint i;
 
-	for (i = 0; i < GEANY_FILETYPES_ALL; i++)
+	for (i = 0; i < GEANY_FILETYPES_NONE; i++)
 	{
 		struct build_programs *bp = filetypes[i]->programs;
 		GKeyFile *config_home;
@@ -995,19 +1003,21 @@
 GtkFileFilter *filetypes_create_file_filter_all_source()
 {
 	GtkFileFilter *new_filter;
-	gint i, j;
+	guint i, j;
 
 	new_filter = gtk_file_filter_new();
 	gtk_file_filter_set_name(new_filter, _("All Source"));
 
-	for (i = 0; i < GEANY_FILETYPES_ALL; i++)
+	for (i = 0; i < filetypes_array->len; i++)
 	{
+		if (i == GEANY_FILETYPES_NONE)
+			continue;
+
 		for (j = 0; filetypes[i]->pattern[j]; j++)
 		{
 			gtk_file_filter_add_pattern(new_filter, filetypes[i]->pattern[j]);
 		}
 	}
-
 	return new_filter;
 }
 
@@ -1040,3 +1050,17 @@
 }
 
 
+/** Find a filetype pointer from its @c name field. */
+filetype *filetypes_lookup_by_name(const gchar *name)
+{
+	filetype *ft;
+
+	g_return_val_if_fail(NZV(name), NULL);
+
+	ft = g_hash_table_lookup(filetypes_hash, name);
+	if (ft == NULL)
+		geany_debug("Could not find filetype '%s'.", name);
+	return ft;
+}
+
+

Modified: trunk/src/filetypes.h
===================================================================
--- trunk/src/filetypes.h	2008-05-07 14:09:12 UTC (rev 2558)
+++ trunk/src/filetypes.h	2008-05-07 16:29:48 UTC (rev 2559)
@@ -77,13 +77,13 @@
 	GEANY_FILETYPES_REST,
 	GEANY_FILETYPES_SQL,
 
-	GEANY_FILETYPES_ALL,	/* must be last filetype, used for 'None' item. */
-	GEANY_MAX_FILE_TYPES
+	GEANY_FILETYPES_NONE,	/* must be last filetype */
+	GEANY_MAX_BUILT_IN_FILETYPES	/* Use filetypes_array->len instead */
 } filetype_id;
 
 /* Safe wrapper to get the id field of a possibly NULL filetype pointer. */
 #define FILETYPE_ID(filetype_ptr) \
-	(((filetype_ptr) != NULL) ? (filetype_ptr)->id : GEANY_FILETYPES_ALL)
+	(((filetype_ptr) != NULL) ? (filetype_ptr)->id : GEANY_FILETYPES_NONE)
 
 
 struct build_actions
@@ -105,8 +105,6 @@
 struct filetype
 {
 	filetype_id		  id;
-	guint	 		  uid;				/* unique id as reference for saved filetype in config file */
-	GtkWidget		 *item;				/* holds a pointer to the menu item for this filetypes */
 	langType 		  lang;				/* represents the langType of tagmanager(see the table */
 										/* in tagmanager/parsers.h), -1 represents all, -2 none */
 	gchar	 		 *name;				/* will be used as name for tagmanager */
@@ -121,12 +119,16 @@
 	struct build_actions	*actions;
 };
 
-extern filetype *filetypes[GEANY_MAX_FILE_TYPES];
+extern GPtrArray *filetypes_array;
 
+/* Wrap filetypes_array so it can be used with C array syntax.
+ * Example: filetypes[GEANY_FILETYPES_C]->name = ...; */
+#define filetypes	((filetype **)filetypes_array->pdata)
 
-/* If uid is valid, return corresponding filetype, otherwise NULL. */
-filetype *filetypes_get_from_uid(gint uid);
 
+filetype *filetypes_lookup_by_name(const gchar *name);
+
+
 /* Calls filetypes_init_types() and creates the filetype menu. */
 void filetypes_init(void);
 

Modified: trunk/src/highlighting.c
===================================================================
--- trunk/src/highlighting.c	2008-05-07 14:09:12 UTC (rev 2558)
+++ trunk/src/highlighting.c	2008-05-07 16:29:48 UTC (rev 2559)
@@ -52,7 +52,7 @@
 } StyleSet;
 
 /* each filetype has a styleset except GEANY_FILETYPE_ALL */
-static StyleSet style_sets[GEANY_MAX_FILE_TYPES - 1] = {{NULL, NULL, NULL}};
+static StyleSet style_sets[GEANY_MAX_BUILT_IN_FILETYPES - 1] = {{NULL, NULL, NULL}};
 
 
 enum	/* Geany common styling */
@@ -273,7 +273,7 @@
 {
 	HighlightingStyle *style_ptr;
 
-	if (ft == GEANY_FILETYPES_ALL)
+	if (ft == GEANY_FILETYPES_NONE)
 		style_ptr = &common_style_set.styling[styling_index];
 	else
 		style_ptr = &style_sets[ft].styling[styling_index];
@@ -289,7 +289,7 @@
 {
 	gint i;
 
-	for (i = 0; i < GEANY_MAX_FILE_TYPES - 1; i++)
+	for (i = 0; i < GEANY_MAX_BUILT_IN_FILETYPES - 1; i++)
 	{
 		StyleSet *style_ptr;
 		style_ptr = &style_sets[i];
@@ -555,10 +555,10 @@
 
 	SSM(sci, SCI_SETFOLDMARGINCOLOUR, 1, invert(common_style_set.styling[GCS_MARGIN_FOLDING].background));
 	/*SSM(sci, SCI_SETFOLDMARGINHICOLOUR, 1, invert(common_style_set.styling[GCS_MARGIN_FOLDING].background));*/
-	set_sci_style(sci, STYLE_LINENUMBER, GEANY_FILETYPES_ALL, GCS_MARGIN_LINENUMBER);
-	set_sci_style(sci, STYLE_BRACELIGHT, GEANY_FILETYPES_ALL, GCS_BRACE_GOOD);
-	set_sci_style(sci, STYLE_BRACEBAD, GEANY_FILETYPES_ALL, GCS_BRACE_BAD);
-	set_sci_style(sci, STYLE_INDENTGUIDE, GEANY_FILETYPES_ALL, GCS_INDENT_GUIDE);
+	set_sci_style(sci, STYLE_LINENUMBER, GEANY_FILETYPES_NONE, GCS_MARGIN_LINENUMBER);
+	set_sci_style(sci, STYLE_BRACELIGHT, GEANY_FILETYPES_NONE, GCS_BRACE_GOOD);
+	set_sci_style(sci, STYLE_BRACEBAD, GEANY_FILETYPES_NONE, GCS_BRACE_BAD);
+	set_sci_style(sci, STYLE_INDENTGUIDE, GEANY_FILETYPES_NONE, GCS_INDENT_GUIDE);
 
 	/* bold = common whitespace settings enabled */
 	SSM(sci, SCI_SETWHITESPACEFORE, common_style_set.styling[GCS_WHITE_SPACE].bold,
@@ -1864,11 +1864,11 @@
 
 static void styleset_none(ScintillaObject *sci)
 {
-	const filetype_id ft_id = GEANY_FILETYPES_ALL;
+	const filetype_id ft_id = GEANY_FILETYPES_NONE;
 
 	SSM(sci, SCI_SETLEXER, SCLEX_NULL, 0);
 
-	set_sci_style(sci, STYLE_DEFAULT, GEANY_FILETYPES_ALL, GCS_DEFAULT);
+	set_sci_style(sci, STYLE_DEFAULT, GEANY_FILETYPES_NONE, GCS_DEFAULT);
 
 	styleset_common(sci, 5, ft_id);
 
@@ -2944,12 +2944,12 @@
 void highlighting_init_styles(gint filetype_idx, GKeyFile *config, GKeyFile *configh)
 {
 	/* All stylesets depend on filetypes.common */
-	if (filetype_idx != GEANY_FILETYPES_ALL)
-		filetypes_load_config(GEANY_FILETYPES_ALL);
+	if (filetype_idx != GEANY_FILETYPES_NONE)
+		filetypes_load_config(GEANY_FILETYPES_NONE);
 
 	switch (filetype_idx)
 	{
-		init_styleset_case(GEANY_FILETYPES_ALL,		common);
+		init_styleset_case(GEANY_FILETYPES_NONE,		common);
 		init_styleset_case(GEANY_FILETYPES_ASM,		asm);
 		init_styleset_case(GEANY_FILETYPES_BASIC,	basic);
 		init_styleset_case(GEANY_FILETYPES_C,		c);
@@ -2997,7 +2997,7 @@
 	filetypes_load_config(filetype_idx);	/* load filetypes.ext */
 
 	/* load tags files (some lexers highlight global typenames) */
-	if (filetype_idx < GEANY_FILETYPES_ALL)
+	if (filetype_idx < GEANY_FILETYPES_NONE)
 		symbols_global_tags_loaded(filetype_idx);
 
 	switch (filetype_idx)
@@ -3035,7 +3035,7 @@
 		styleset_case(GEANY_FILETYPES_VHDL,		vhdl);
 		styleset_case(GEANY_FILETYPES_XML,		xml);
 		default:
-		styleset_case(GEANY_FILETYPES_ALL,		none);
+		styleset_case(GEANY_FILETYPES_NONE,		none);
 	}
 }
 
@@ -3046,7 +3046,7 @@
  * style_id is a Scintilla lexer style, see scintilla/SciLexer.h */
 const HighlightingStyle *highlighting_get_style(gint ft_id, gint style_id)
 {
-	if (ft_id < 0 || ft_id > GEANY_MAX_FILE_TYPES)
+	if (ft_id < 0 || ft_id > GEANY_MAX_BUILT_IN_FILETYPES)
 		return NULL;
 
 	if (style_sets[ft_id].styling == NULL)

Modified: trunk/src/keyfile.c
===================================================================
--- trunk/src/keyfile.c	2008-05-07 14:09:12 UTC (rev 2558)
+++ trunk/src/keyfile.c	2008-05-07 16:29:48 UTC (rev 2559)
@@ -115,6 +115,27 @@
 }
 
 
+static gchar *get_session_file_string(gint idx)
+{
+	gchar *fname;
+	filetype *ft = doc_list[idx].file_type;
+
+	if (ft == NULL)	/* can happen when saving a new file when quitting */
+		ft = filetypes[GEANY_FILETYPES_NONE];
+
+	fname = g_strdup_printf("%d;%s;%d;%d;%d;%d;%d;%s;",
+		sci_get_current_position(doc_list[idx].sci),
+		ft->name,
+		doc_list[idx].readonly,
+		encodings_get_idx_from_charset(doc_list[idx].encoding),
+		doc_list[idx].use_tabs,
+		doc_list[idx].auto_indent,
+		doc_list[idx].line_wrapping,
+		doc_list[idx].file_name);
+	return fname;
+}
+
+
 void configuration_save_session_files(GKeyFile *config)
 {
 	gint idx, npage;
@@ -133,20 +154,9 @@
 		if (idx >= 0 && g_path_is_absolute(DOC_FILENAME(idx)))
 		{
 			gchar *fname;
-			filetype *ft = doc_list[idx].file_type;
 
-			if (ft == NULL)	/* can happen when saving a new file when quitting */
-				ft = filetypes[GEANY_FILETYPES_ALL];
 			g_snprintf(entry, 13, "FILE_NAME_%d", j);
-			fname = g_strdup_printf("%d;%d;%d;%d;%d;%d;%d;%s;",
-				sci_get_current_position(doc_list[idx].sci),
-				ft->uid,
-				doc_list[idx].readonly,
-				encodings_get_idx_from_charset(doc_list[idx].encoding),
-				doc_list[idx].use_tabs,
-				doc_list[idx].auto_indent,
-				doc_list[idx].line_wrapping,
-				doc_list[idx].file_name);
+			fname = get_session_file_string(idx);
 			g_key_file_set_string(config, "files", entry, fname);
 			g_free(fname);
 			j++;
@@ -801,14 +811,58 @@
 }
 
 
+static gboolean open_session_file(gchar **tmp)
+{
+	guint pos;
+	const gchar *ft_name;
+	gchar *locale_filename;
+	gint enc_idx;
+	gboolean ro, use_tabs, auto_indent, line_wrapping;
+	gboolean ret = FALSE;
+
+	pos = atoi(tmp[0]);
+	ft_name = tmp[1];
+	ro = atoi(tmp[2]);
+	enc_idx = atoi(tmp[3]);
+	use_tabs = atoi(tmp[4]);
+	auto_indent = atoi(tmp[5]);
+	line_wrapping = atoi(tmp[6]);
+	/* try to get the locale equivalent for the filename */
+	locale_filename = utils_get_locale_from_utf8(tmp[7]);
+
+	if (g_file_test(locale_filename, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_SYMLINK))
+	{
+		filetype *ft = filetypes_lookup_by_name(ft_name);
+		gint new_idx = document_open_file_full(
+			-1, locale_filename, pos, ro, ft,
+			(enc_idx >= 0 && enc_idx < GEANY_ENCODINGS_MAX) ?
+				encodings[enc_idx].charset : NULL);
+
+		if (DOC_IDX_VALID(new_idx))
+		{
+			document_set_use_tabs(new_idx, use_tabs);
+			document_set_line_wrapping(new_idx, line_wrapping);
+			doc_list[new_idx].auto_indent = auto_indent;
+			ret = TRUE;
+		}
+	}
+	else
+	{
+		geany_debug("Could not find file '%s'.", tmp[7]);
+	}
+
+	g_free(locale_filename);
+	return ret;
+}
+
+
 /* Open session files
  * Note: notebook page switch handler and adding to recent files list is always disabled
  * for all files opened within this function */
-gboolean configuration_open_files(void)
+void configuration_open_files(void)
 {
 	gint i;
-	guint pos;
-	gboolean ret = FALSE, failure = FALSE;
+	gboolean failure = FALSE;
 
 	/* necessary to set it to TRUE for project session support */
 	main_status.opening_session_files = TRUE;
@@ -822,43 +876,8 @@
 
 		if (tmp != NULL && g_strv_length(tmp) == 8)
 		{
-			gchar *locale_filename;
-			gint ft_uid, enc_idx;
-			gboolean ro, use_tabs, auto_indent, line_wrapping;
-
-			pos = atoi(tmp[0]);
-			ft_uid = atoi(tmp[1]);
-			ro = atoi(tmp[2]);
-			enc_idx = atoi(tmp[3]);
-			use_tabs = atoi(tmp[4]);
-			auto_indent = atoi(tmp[5]);
-			line_wrapping = atoi(tmp[6]);
-			/* try to get the locale equivalent for the filename */
-			locale_filename = utils_get_locale_from_utf8(tmp[7]);
-
-			if (g_file_test(locale_filename, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_SYMLINK))
-			{
-				filetype *ft = filetypes_get_from_uid(ft_uid);
-				gint new_idx = document_open_file_full(
-					-1, locale_filename, pos, ro, ft,
-					(enc_idx >= 0 && enc_idx < GEANY_ENCODINGS_MAX) ?
-						encodings[enc_idx].charset : NULL);
-
-				if (DOC_IDX_VALID(new_idx))
-				{
-					document_set_use_tabs(new_idx, use_tabs);
-					document_set_line_wrapping(new_idx, line_wrapping);
-					doc_list[new_idx].auto_indent = auto_indent;
-					ret = TRUE;
-				}
-			}
-			else
-			{
+			if (! open_session_file(tmp))
 				failure = TRUE;
-				geany_debug("Could not find file '%s'.", tmp[7]);
-			}
-
-			g_free(locale_filename);
 		}
 		g_strfreev(tmp);
 
@@ -882,7 +901,7 @@
 		ui_set_statusbar(TRUE, _("Failed to load one or more session files."));
 	else if (session_notebook_page >= 0)
 	{
-		/* exlicitly allow notebook switch page callback to be called for window title,
+		/* explicitly allow notebook switch page callback to be called for window title,
 		 * encoding settings and so other things */
 		main_status.opening_session_files = FALSE;
 		/** TODO if session_notebook_page is equal to the current notebook tab(the last opened)
@@ -890,7 +909,6 @@
 		gtk_notebook_set_current_page(GTK_NOTEBOOK(app->notebook), session_notebook_page);
 	}
 	main_status.opening_session_files = FALSE;
-	return ret;
 }
 
 
@@ -963,7 +981,7 @@
 	g_key_file_set_comment(config, NULL, NULL,
 		"*** This file generated by: geany --generate-data-files ***", NULL);
 	/* add filetype keys */
-	for (i = 0; i < GEANY_MAX_FILE_TYPES; i++)
+	for (i = 0; i < filetypes_array->len; i++)
 	{
 		g_key_file_set_string_list(config, "Extensions", filetypes[i]->name,
 			(const gchar**) filetypes[i]->pattern, g_strv_length(filetypes[i]->pattern));
@@ -1008,7 +1026,7 @@
 	g_key_file_load_from_file(userconfig, userconfigfile, G_KEY_FILE_NONE, NULL);
 
 	/* read the keys */
-	for (i = 0; i < GEANY_MAX_FILE_TYPES; i++)
+	for (i = 0; i < filetypes_array->len; i++)
 	{
 		gboolean userset =
 			g_key_file_has_key(userconfig, "Extensions", filetypes[i]->name, NULL);

Modified: trunk/src/keyfile.h
===================================================================
--- trunk/src/keyfile.h	2008-05-07 14:09:12 UTC (rev 2558)
+++ trunk/src/keyfile.h	2008-05-07 16:29:48 UTC (rev 2559)
@@ -30,7 +30,7 @@
 
 gboolean configuration_load(void);
 
-gboolean configuration_open_files(void);
+void configuration_open_files(void);
 
 void configuration_reload_default_session(void);
 

Modified: trunk/src/main.c
===================================================================
--- trunk/src/main.c	2008-05-07 14:09:12 UTC (rev 2558)
+++ trunk/src/main.c	2008-05-07 16:29:48 UTC (rev 2559)
@@ -473,6 +473,21 @@
 }
 
 
+static void print_filetypes(void)
+{
+	guint i;
+
+	filetypes_init_types();
+	printf("Geany's internal filetype names:\n");
+
+	for (i = 0; i < filetypes_array->len; i++)
+	{
+		printf("%s\n", filetypes[i]->name);
+	}
+	filetypes_free_types();
+}
+
+
 static void parse_command_line_options(gint *argc, gchar ***argv)
 {
 	GError *error = NULL;
@@ -585,13 +600,7 @@
 
 	if (ft_names)
 	{
-		printf("Geany's internal filetype names:\n");
-		filetypes_init_types();
-		for (i = 0; i < GEANY_MAX_FILE_TYPES; i++)
-		{
-			printf("%s\n", filetypes[i]->name);
-		}
-		filetypes_free_types();
+		print_filetypes();
 		exit(0);
 	}
 
@@ -870,7 +879,9 @@
 			load_project_file();
 
 			/* load session files into tabs, as they are found in the session_files variable */
-			if (! configuration_open_files())
+			configuration_open_files();
+
+			if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(app->notebook)) == 0)
 			{
 				ui_update_popup_copy_items(-1);
 				ui_update_popup_reundo_items(-1);

Modified: trunk/src/msgwindow.c
===================================================================
--- trunk/src/msgwindow.c	2008-05-07 14:09:12 UTC (rev 2558)
+++ trunk/src/msgwindow.c	2008-05-07 16:29:48 UTC (rev 2559)
@@ -737,7 +737,7 @@
 		case GEANY_FILETYPES_LATEX:
 			/* ./kommtechnik_2b.tex:18: Emergency stop. */
 		case GEANY_FILETYPES_MAKE:	/* Assume makefile is building with gcc */
-		case GEANY_FILETYPES_ALL:
+		case GEANY_FILETYPES_NONE:
 		default:	/* The default is a GNU gcc type error */
 		{
 			if (build_info.file_type_id == GEANY_FILETYPES_JAVA &&

Modified: trunk/src/plugindata.h
===================================================================
--- trunk/src/plugindata.h	2008-05-07 14:09:12 UTC (rev 2558)
+++ trunk/src/plugindata.h	2008-05-07 16:29:48 UTC (rev 2559)
@@ -30,17 +30,17 @@
  **/
 
 
-#ifndef PLUGIN_H
-#define PLUGIN_H
+#ifndef PLUGINDATA_H
+#define PLUGINDATA_H
 
 /* The API version should be incremented whenever any plugin data types below are
  * modified or appended to. */
-static const gint api_version = 53;
+static const gint api_version = 56;
 
 /* The ABI version should be incremented whenever existing fields in the plugin
  * data types below have to be changed or reordered. It should stay the same if fields
  * are only appended, as this doesn't affect existing fields. */
-static const gint abi_version = 24;
+static const gint abi_version = 27;
 
 /** Check the plugin can be loaded by Geany.
  * This performs runtime checks that try to ensure:
@@ -155,9 +155,9 @@
 {
 	GeanyApp	*app;					/**< Geany application data fields */
 	GtkWidget	*tools_menu;			/**< Most plugins should add menu items to the Tools menu only */
-	GArray		*doc_array;				/**< Dynamic array of document pointers */
-	struct filetype		**filetypes;
-	struct GeanyPrefs	*prefs;
+	GArray		*doc_array;				/**< Dynamic array of document structs */
+	GPtrArray	*filetypes_array;		/**< Dynamic array of filetype pointers */
+	struct GeanyPrefs	*prefs;			/* Note: this will be split up in future versions */
 	struct EditorPrefs	*editor_prefs;	/**< Editor settings */
 	struct BuildInfo	*build_info;	/**< Current build information */
 
@@ -367,7 +367,7 @@
 typedef struct FiletypeFuncs
 {
 	filetype*	(*detect_from_filename) (const gchar *utf8_filename);
-	filetype*	(*get_from_uid) (gint uid);
+	filetype*	(*lookup_by_name) (const gchar *name);
 }
 FiletypeFuncs;
 
@@ -396,7 +396,8 @@
 typedef struct NavQueueFuncs
 {
 	gboolean		(*goto_line) (gint old_idx, gint new_idx, gint line);
-}NavQueueFuncs;
+}
+NavQueueFuncs;
 
 
 /* Deprecated aliases */
@@ -407,6 +408,12 @@
 #define VERSION_CHECK(api_required) \
 	PLUGIN_VERSION_CHECK(api_required)
 
-#endif
+#define GEANY_MAX_FILE_TYPES \
+	filetypes_array->len
 
+#define GEANY_FILETYPES_ALL \
+	GEANY_FILETYPES_NONE
+
+#endif	/* GEANY_DISABLE_DEPRECATED */
+
 #endif

Modified: trunk/src/plugins.c
===================================================================
--- trunk/src/plugins.c	2008-05-07 14:09:12 UTC (rev 2558)
+++ trunk/src/plugins.c	2008-05-07 16:29:48 UTC (rev 2559)
@@ -227,7 +227,7 @@
 
 static FiletypeFuncs filetype_funcs = {
 	&filetypes_detect_from_filename,
-	&filetypes_get_from_uid
+	&filetypes_lookup_by_name
 };
 
 static NavQueueFuncs navqueue_funcs = {
@@ -267,7 +267,7 @@
 	geany_data.app = app;
 	geany_data.tools_menu = lookup_widget(app->window, "tools1_menu");
 	geany_data.doc_array = doc_array;
-	geany_data.filetypes = filetypes;
+	geany_data.filetypes_array = filetypes_array;
 	geany_data.prefs = &prefs;
 	geany_data.editor_prefs = &editor_prefs;
 	geany_data.build_info = &build_info;

Modified: trunk/src/symbols.c
===================================================================
--- trunk/src/symbols.c	2008-05-07 14:09:12 UTC (rev 2558)
+++ trunk/src/symbols.c	2008-05-07 16:29:48 UTC (rev 2559)
@@ -1102,7 +1102,7 @@
 
 		g_free(utf8_fname);
 
-		if (FILETYPE_ID(ft) < GEANY_FILETYPES_ALL)
+		if (FILETYPE_ID(ft) < GEANY_FILETYPES_NONE)
 		{
 			fnames = g_hash_table_lookup(hash, ft);	/* may be NULL */
 			fnames = g_list_append(fnames, fname);
@@ -1138,13 +1138,13 @@
 
 static void load_user_tags(filetype_id ft_id)
 {
-	static guchar tags_loaded[GEANY_FILETYPES_ALL] = {0};
+	static guchar tags_loaded[GEANY_FILETYPES_NONE] = {0};
 	static GHashTable *lang_hash = NULL;
 	GList *fnames;
 	const GList *node;
 	const filetype *ft = filetypes[ft_id];
 
-	g_return_if_fail(ft_id < GEANY_FILETYPES_ALL);
+	g_return_if_fail(ft_id < GEANY_FILETYPES_NONE);
 
 	if (tags_loaded[ft_id])
 		return;

Modified: trunk/src/templates.c
===================================================================
--- trunk/src/templates.c	2008-05-07 14:09:12 UTC (rev 2558)
+++ trunk/src/templates.c	2008-05-07 16:29:48 UTC (rev 2559)
@@ -226,7 +226,7 @@
 ";
 
 static gchar *templates[GEANY_MAX_TEMPLATES];
-static gchar *ft_templates[GEANY_MAX_FILE_TYPES] = {NULL};
+static gchar *ft_templates[GEANY_MAX_BUILT_IN_FILETYPES] = {NULL};
 
 
 /* some simple macros to reduce code size and make the code readable */
@@ -290,7 +290,7 @@
 {
 	filetype_id ft_id;
 
-	for (ft_id = 0; ft_id < GEANY_MAX_FILE_TYPES; ft_id++)
+	for (ft_id = 0; ft_id < GEANY_MAX_BUILT_IN_FILETYPES; ft_id++)
 	{
 		gchar *ext = filetypes_get_conf_extension(ft_id);
 		gchar *shortname = g_strconcat("filetype.", ext, NULL);
@@ -298,7 +298,7 @@
 
 		switch (ft_id)
 		{
-			case GEANY_FILETYPES_ALL:	TEMPLATES_CREATE_FILE(fname, templates_filetype_none); break;
+			case GEANY_FILETYPES_NONE:	TEMPLATES_CREATE_FILE(fname, templates_filetype_none); break;
 			case GEANY_FILETYPES_C:		TEMPLATES_CREATE_FILE(fname, templates_filetype_c); break;
 			case GEANY_FILETYPES_CPP:	TEMPLATES_CREATE_FILE(fname, templates_filetype_cpp); break;
 			case GEANY_FILETYPES_D:		TEMPLATES_CREATE_FILE(fname, templates_filetype_d); break;
@@ -338,7 +338,7 @@
 	GtkWidget *template_menu = lookup_widget(app->window, "menu_new_with_template1_menu");
 	filetype_id ft_id;
 
-	for (ft_id = 0; ft_id < GEANY_MAX_FILE_TYPES; ft_id++)
+	for (ft_id = 0; ft_id < GEANY_MAX_BUILT_IN_FILETYPES; ft_id++)
 	{
 		GtkWidget *tmp_menu, *tmp_button;
 		filetype *ft = filetypes[ft_id];
@@ -346,7 +346,7 @@
 
 		if (ft_templates[ft_id] == NULL)
 			continue;
-		if (ft_id == GEANY_FILETYPES_ALL)
+		if (ft_id == GEANY_FILETYPES_NONE)
 			label = _("None");
 		tmp_menu = gtk_menu_item_new_with_label(label);
 		tmp_button = gtk_menu_item_new_with_label(label);
@@ -482,7 +482,7 @@
 			break;
 		}
 
-		case GEANY_FILETYPES_ALL:
+		case GEANY_FILETYPES_NONE:
 		{
 			line_prefix = "";
 			break;
@@ -545,7 +545,7 @@
 
 	if (fname == NULL)
 	{
-		if (ft_id == GEANY_FILETYPES_ALL)
+		if (ft_id == GEANY_FILETYPES_NONE)
 			shortname = g_strdup(GEANY_STRING_UNTITLED);
 		else
 			shortname = g_strconcat(GEANY_STRING_UNTITLED, ".", ft->extension, NULL);
@@ -580,7 +580,7 @@
 	gchar *ft_template = NULL;
 	gchar *file_header = NULL;
 
-	if (FILETYPE_ID(ft) == GEANY_FILETYPES_ALL)
+	if (FILETYPE_ID(ft) == GEANY_FILETYPES_NONE)
 		return get_file_template(ft);
 
 	file_header = templates_get_template_fileheader(ft->id, NULL);	/* file template only used for new files */

Modified: trunk/src/ui_utils.c
===================================================================
--- trunk/src/ui_utils.c	2008-05-07 14:09:12 UTC (rev 2558)
+++ trunk/src/ui_utils.c	2008-05-07 16:29:48 UTC (rev 2559)
@@ -130,8 +130,8 @@
 		const gchar *cur_tag;
 		gchar *filetype_name;
 
-		/* workaround to make the name of filetype GEANY_FILETYPES_ALL translatable */
-		if (doc_list[idx].file_type == NULL || doc_list[idx].file_type->id == GEANY_FILETYPES_ALL)
+		/* workaround to make the name of filetype GEANY_FILETYPES_NONE translatable */
+		if (doc_list[idx].file_type == NULL || doc_list[idx].file_type->id == GEANY_FILETYPES_NONE)
 			filetype_name = _("None");
 		else
 			filetype_name = doc_list[idx].file_type->name;

Modified: trunk/src/utils.c
===================================================================
--- trunk/src/utils.c	2008-05-07 14:09:12 UTC (rev 2558)
+++ trunk/src/utils.c	2008-05-07 16:29:48 UTC (rev 2559)
@@ -607,7 +607,7 @@
 	/* parse the current function name here because TM line numbers may have changed,
 	 * and it would take too long to reparse the whole file. */
 	if (doc_list[idx].file_type != NULL &&
-		doc_list[idx].file_type->id != GEANY_FILETYPES_ALL)
+		doc_list[idx].file_type->id != GEANY_FILETYPES_NONE)
 	{
 		const gint fn_fold = get_function_fold_number(idx);
 

Modified: trunk/src/win32.c
===================================================================
--- trunk/src/win32.c	2008-05-07 14:09:12 UTC (rev 2558)
+++ trunk/src/win32.c	2008-05-07 16:29:48 UTC (rev 2559)
@@ -88,14 +88,14 @@
 	GString *all_patterns = g_string_sized_new(100);
 	gchar *tmp;
 
-	for (i = 0; i < GEANY_MAX_FILE_TYPES; i++)
+	for (i = 0; i < filetypes_array->len; i++)
 	{
 		tmp = g_strjoinv(";", filetypes[i]->pattern);
 		g_string_append_printf(str, "%s\t%s\t", filetypes[i]->title, tmp);
 		g_free(tmp);
 	}
 	/* create meta file filter "All Source" */
-	for (i = 0; i < GEANY_MAX_FILE_TYPES; i++)
+	for (i = 0; i < filetypes_array->len; i++)
 	{
 		for (j = 0; filetypes[i]->pattern[j] != NULL; j++)
 		{
@@ -128,14 +128,14 @@
 	if (project_files)
 	{
 		string = g_strconcat(_("Geany project files"), "\t", "*." GEANY_PROJECT_EXT, "\t",
-			filetypes[GEANY_FILETYPES_ALL]->title, "\t",
-			filetypes[GEANY_FILETYPES_ALL]->pattern[0], "\t", NULL);
+			filetypes[GEANY_FILETYPES_NONE]->title, "\t",
+			filetypes[GEANY_FILETYPES_NONE]->pattern[0], "\t", NULL);
 	}
 	else
 	{
 		string = g_strconcat(_("Executables"), "\t", "*.exe;*.bat;*.cmd", "\t",
-			filetypes[GEANY_FILETYPES_ALL]->title, "\t",
-			filetypes[GEANY_FILETYPES_ALL]->pattern[0], "\t", NULL);
+			filetypes[GEANY_FILETYPES_NONE]->title, "\t",
+			filetypes[GEANY_FILETYPES_NONE]->pattern[0], "\t", NULL);
 	}
 
 	/* replace all "\t"s by \0 */
@@ -332,7 +332,7 @@
 	of.lpstrFilter = filters;
 
 	of.lpstrCustomFilter = NULL;
-	of.nFilterIndex = GEANY_FILETYPES_ALL + 1;
+	of.nFilterIndex = GEANY_FILETYPES_NONE + 1;
 	of.lpstrFile = fname;
 	of.lpstrInitialDir = initial_dir;
 	of.nMaxFile = 2048;


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