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.



git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@3681 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
Nick Treleaven 2009-04-03 14:23:45 +00:00
commit 1681861fa1
13 changed files with 201 additions and 160 deletions

View File

@ -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>

View File

@ -26,6 +26,8 @@
/* HTML Characters plugin (Inserts HTML character entities like '&amp;') */
#include "geany.h"
#include <string.h>
#include "support.h"
#include "plugindata.h"
#include "document.h"

View File

@ -603,6 +603,8 @@ GtkWidget *plugin_configure(GtkDialog *dialog)
{
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 @@ GtkWidget *plugin_configure(GtkDialog *dialog)
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);

View File

@ -90,8 +90,8 @@ on_file_open_dialog_response (GtkDialog *dialog,
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 @@ static void create_open_file_dialog(void)
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 @@ static void create_open_file_dialog(void)
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");

View File

@ -67,10 +67,16 @@ GeanyFiletypePrivate;
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. */
@ -78,7 +84,18 @@ 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 @@ static void init_builtin_filetypes(void)
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 @@ static GeanyFiletype *filetype_new(void)
}
/* 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 @@ static void filetype_add(GeanyFiletype *ft)
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 @@ static void setup_config_file_menus(void)
}
#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_sub_menu(GtkWidget *parent, gsize group_id, const gchar *title)
{
GtkWidget *menu, *item;
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;
}
static void add_ft_menu_item(gpointer pft, gpointer user_data)
{
GeanyFiletype *ft = pft;
create_radio_menu_item(group_menus[ft->group], ft);
}
static void create_set_filetype_menu(void)
{
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;
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"));
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"));
/* 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;
case GEANY_FILETYPE_GROUP_SCRIPT: /* scripts */
sub_menu = sub_menu_scripts;
break;
case GEANY_FILETYPE_GROUP_MARKUP: /* markup */
sub_menu = sub_menu_markup;
break;
case GEANY_FILETYPE_GROUP_MISC: /* misc */
sub_menu = sub_menu_misc;
break;
case GEANY_FILETYPE_GROUP_NONE: /* none */
sub_menu = filetype_menu;
title = _("None");
break;
default: break;
}
create_radio_menu_item(sub_menu, title, ft);
}
filetypes_foreach_named(add_ft_menu_item, NULL);
create_radio_menu_item(filetype_menu, filetypes[GEANY_FILETYPES_NONE]);
}
@ -712,11 +713,8 @@ void filetypes_init()
}
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 @@ static GeanyFiletype *filetypes_find(gboolean source_only,
{
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 GeanyFiletype *filetypes_find(gboolean source_only,
}
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 @@ GeanyFiletype *filetypes_detect_from_extension(const gchar *utf8_filename)
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 @@ on_filetype_change (GtkMenuItem *menuitem,
}
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 @@ void filetypes_save_commands()
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 *filetypes_create_file_filter(const GeanyFiletype *ft)
{
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 @@ GeanyFiletype *filetypes_index(gint idx)
}
/* 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);
}
}

View File

@ -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_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_DIFF,
GEANY_FILETYPES_NSIS,
GEANY_FILETYPES_PO,
GEANY_FILETYPES_LATEX,
GEANY_FILETYPES_REST,
GEANY_FILETYPES_SQL,
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,
GEANY_FILETYPES_XML,
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_HTML,
GEANY_FILETYPES_PYTHON,
GEANY_FILETYPES_CS,
GEANY_FILETYPES_PERL,
GEANY_FILETYPES_VALA,
GEANY_FILETYPES_PASCAL,
GEANY_FILETYPES_LATEX,
GEANY_FILETYPES_ASM,
GEANY_FILETYPES_CONF,
GEANY_FILETYPES_HAXE,
GEANY_FILETYPES_CPP,
GEANY_FILETYPES_SH,
GEANY_FILETYPES_FORTRAN,
GEANY_FILETYPES_SQL,
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 @@ typedef enum
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,9 +144,15 @@ extern GPtrArray *filetypes_array;
* 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);

View File

@ -3435,7 +3435,7 @@ void highlighting_set_styles(ScintillaObject *sci, gint filetype_idx)
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)

View File

@ -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 @@ typedef struct GeanyData
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;

View File

@ -351,7 +351,8 @@ geany_data_init(void)
&search_prefs,
&tool_prefs,
&template_prefs,
&build_info
&build_info,
filetypes_by_title
};
memcpy(&geany_data, &gd, sizeof(GeanyData));
}

View File

@ -1381,7 +1381,7 @@ static GHashTable *get_tagfile_hash(const GSList *file_list)
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 GHashTable *init_user_tags(void)
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;

View File

@ -362,18 +362,17 @@ on_new_with_template (GtkMenuItem *menuitem,
/* 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);

View File

@ -134,6 +134,14 @@ void ui_set_statusbar(gboolean log, const gchar *format, ...)
}
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,13 +157,7 @@ void ui_update_statusbar(GeanyDocument *doc, gint pos)
const gchar sp[] = " ";
guint line, col;
const gchar *cur_tag;
gchar *filetype_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;
gchar *filetype_name = document_get_filetype(doc)->name;
if (stats_str == NULL)
stats_str = g_string_sized_new(120);

View File

@ -57,6 +57,11 @@
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);