Added per-language settings in Preferences dialog
parent
ab006bdeaa
commit
929f17f8c1
|
@ -46,6 +46,7 @@ mooedit_noinst_headers = \
|
|||
$(mooedit)/moohighlighter.h \
|
||||
$(mooedit)/moolang-aux.h \
|
||||
$(mooedit)/moolang-parser.h \
|
||||
$(mooedit)/moolang-private.h \
|
||||
$(mooedit)/moolang-rules.h \
|
||||
$(mooedit)/moolang-strings.h \
|
||||
$(mooedit)/moolinebuffer.h \
|
||||
|
|
|
@ -739,30 +739,12 @@
|
|||
<property name="n_rows">2</property>
|
||||
<property name="n_columns">2</property>
|
||||
<child>
|
||||
<widget class="GtkComboBox" id="color_scheme_combo">
|
||||
<widget class="GtkLabel" id="label99">
|
||||
<property name="visible">True</property>
|
||||
<property name="items" translatable="yes">KDE
|
||||
gvim
|
||||
</property>
|
||||
<property name="label">Font:</property>
|
||||
<property name="moo_sensitive">!use_default_font</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label100">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0.000000</property>
|
||||
<property name="label">Color scheme:</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options"></property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
|
@ -783,16 +765,34 @@ gvim
|
|||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label99">
|
||||
<widget class="GtkLabel" id="label100">
|
||||
<property name="visible">True</property>
|
||||
<property name="label">Font:</property>
|
||||
<property name="moo_sensitive">!use_default_font</property>
|
||||
<property name="xalign">0.000000</property>
|
||||
<property name="label">Color scheme:</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options"></property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkComboBox" id="color_scheme_combo">
|
||||
<property name="visible">True</property>
|
||||
<property name="items" translatable="yes">KDE
|
||||
gvim
|
||||
</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
|
@ -814,6 +814,130 @@ gvim
|
|||
<property name="type">tab</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment3">
|
||||
<property name="visible">True</property>
|
||||
<property name="top_padding">3</property>
|
||||
<property name="bottom_padding">3</property>
|
||||
<property name="left_padding">3</property>
|
||||
<property name="right_padding">3</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox2">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkComboBox" id="lang_combo">
|
||||
<property name="visible">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkTable" id="table">
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">3</property>
|
||||
<property name="n_columns">2</property>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="extensions">
|
||||
<property name="visible">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="mimetypes">
|
||||
<property name="visible">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label_extensions">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">1.000000</property>
|
||||
<property name="label" translatable="yes">Extensions:</property>
|
||||
<property name="pattern"></property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label_mimetypes">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">1.000000</property>
|
||||
<property name="label" translatable="yes">Mime types:</property>
|
||||
<property name="pattern"></property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label9">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">1.000000</property>
|
||||
<property name="label" translatable="yes">Options:</property>
|
||||
<property name="pattern"></property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">GTK_FILL</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="config">
|
||||
<property name="visible">True</property>
|
||||
<property name="tooltip">strip: bool; use-tabs: bool; indent-width: integer</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">3</property>
|
||||
<property name="tab_expand">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label6">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Languages</property>
|
||||
<property name="pattern"></property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">tab</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
|
|
@ -45,6 +45,7 @@ void _moo_edit_init_settings (void);
|
|||
void _moo_edit_apply_settings (MooEdit *edit);
|
||||
void _moo_edit_freeze_config_notify (MooEdit *edit);
|
||||
void _moo_edit_thaw_config_notify (MooEdit *edit);
|
||||
void _moo_edit_update_config (void);
|
||||
|
||||
|
||||
/***********************************************************************/
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; coding: utf-8 -*-
|
||||
*
|
||||
/*
|
||||
* mooedit.c
|
||||
*
|
||||
* Copyright (C) 2004-2006 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||
|
@ -19,6 +18,7 @@
|
|||
#include "mooedit/mooeditdialogs.h"
|
||||
#include "mooedit/mooeditprefs.h"
|
||||
#include "mooedit/mootextbuffer.h"
|
||||
#include "mooedit/moolang-private.h"
|
||||
#include "mooutils/moomarshals.h"
|
||||
#include "mooutils/moocompat.h"
|
||||
#include "mooutils/mooutils-gobject.h"
|
||||
|
@ -761,14 +761,14 @@ set_kate_var (MooEdit *edit,
|
|||
gboolean spaces = FALSE;
|
||||
|
||||
if (moo_edit_config_parse_bool (val, &spaces))
|
||||
moo_edit_config_parse (edit->config, "indent-use-tabs",
|
||||
spaces ? "false" : "true",
|
||||
MOO_EDIT_CONFIG_SOURCE_FILE);
|
||||
moo_edit_config_parse_one (edit->config, "indent-use-tabs",
|
||||
spaces ? "false" : "true",
|
||||
MOO_EDIT_CONFIG_SOURCE_FILE);
|
||||
}
|
||||
else
|
||||
{
|
||||
moo_edit_config_parse (edit->config, name, val,
|
||||
MOO_EDIT_CONFIG_SOURCE_FILE);
|
||||
moo_edit_config_parse_one (edit->config, name, val,
|
||||
MOO_EDIT_CONFIG_SOURCE_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -787,27 +787,27 @@ set_emacs_var (MooEdit *edit,
|
|||
{
|
||||
if (!g_ascii_strcasecmp (name, "mode"))
|
||||
{
|
||||
moo_edit_config_parse (edit->config, "lang", val,
|
||||
MOO_EDIT_CONFIG_SOURCE_FILE);
|
||||
moo_edit_config_parse_one (edit->config, "lang", val,
|
||||
MOO_EDIT_CONFIG_SOURCE_FILE);
|
||||
}
|
||||
else if (!g_ascii_strcasecmp (name, "tab-width"))
|
||||
{
|
||||
moo_edit_config_parse (edit->config, "indent-tab-width", val,
|
||||
MOO_EDIT_CONFIG_SOURCE_FILE);
|
||||
moo_edit_config_parse_one (edit->config, "indent-tab-width", val,
|
||||
MOO_EDIT_CONFIG_SOURCE_FILE);
|
||||
}
|
||||
else if (!g_ascii_strcasecmp (name, "c-basic-offset"))
|
||||
{
|
||||
moo_edit_config_parse (edit->config, "indent-width", val,
|
||||
MOO_EDIT_CONFIG_SOURCE_FILE);
|
||||
moo_edit_config_parse_one (edit->config, "indent-width", val,
|
||||
MOO_EDIT_CONFIG_SOURCE_FILE);
|
||||
}
|
||||
else if (!g_ascii_strcasecmp (name, "indent-tabs-mode"))
|
||||
{
|
||||
if (!g_ascii_strcasecmp (val, "nil"))
|
||||
moo_edit_config_parse (edit->config, "indent-use-tabs", "false",
|
||||
MOO_EDIT_CONFIG_SOURCE_FILE);
|
||||
moo_edit_config_parse_one (edit->config, "indent-use-tabs", "false",
|
||||
MOO_EDIT_CONFIG_SOURCE_FILE);
|
||||
else
|
||||
moo_edit_config_parse (edit->config, "indent-use-tabs", "true",
|
||||
MOO_EDIT_CONFIG_SOURCE_FILE);
|
||||
moo_edit_config_parse_one (edit->config, "indent-use-tabs", "true",
|
||||
MOO_EDIT_CONFIG_SOURCE_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -819,20 +819,11 @@ parse_emacs_mode_string (MooEdit *edit,
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
set_moo_var (MooEdit *edit,
|
||||
char *name,
|
||||
char *val)
|
||||
{
|
||||
moo_edit_config_parse (edit->config, name, val,
|
||||
MOO_EDIT_CONFIG_SOURCE_FILE);
|
||||
}
|
||||
|
||||
static void
|
||||
parse_moo_mode_string (MooEdit *edit,
|
||||
char *string)
|
||||
{
|
||||
parse_mode_string (edit, string, " ", (SetVarFunc) set_moo_var);
|
||||
moo_edit_config_parse (edit->config, string, MOO_EDIT_CONFIG_SOURCE_FILE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -927,7 +918,6 @@ moo_edit_set_lang (MooEdit *edit,
|
|||
MooLang *lang)
|
||||
{
|
||||
MooLang *old_lang;
|
||||
MooEditConfig *config;
|
||||
|
||||
old_lang = moo_text_view_get_lang (MOO_TEXT_VIEW (edit));
|
||||
|
||||
|
@ -936,10 +926,8 @@ moo_edit_set_lang (MooEdit *edit,
|
|||
|
||||
_moo_edit_freeze_config_notify (edit);
|
||||
|
||||
moo_edit_config_unset_by_source (edit->config, MOO_EDIT_CONFIG_SOURCE_LANG);
|
||||
config = moo_edit_config_get_for_lang (moo_lang_id (lang));
|
||||
moo_edit_config_compose (edit->config, config);
|
||||
|
||||
_moo_lang_mgr_update_config (moo_editor_get_lang_mgr (edit->priv->editor),
|
||||
edit->config, moo_lang_id (lang));
|
||||
moo_text_view_set_lang (MOO_TEXT_VIEW (edit), lang);
|
||||
|
||||
_moo_edit_thaw_config_notify (edit);
|
||||
|
@ -987,6 +975,20 @@ moo_edit_config_notify (MooEdit *edit,
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
_moo_edit_update_config (void)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
for (l = _moo_edit_instances; l != NULL; l = l->next)
|
||||
{
|
||||
MooEdit *edit = l->data;
|
||||
_moo_lang_mgr_update_config (moo_editor_get_lang_mgr (edit->priv->editor), edit->config,
|
||||
moo_lang_id (moo_text_view_get_lang (MOO_TEXT_VIEW (edit))));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
moo_edit_filename_changed (MooEdit *edit,
|
||||
const char *filename)
|
||||
|
@ -1002,7 +1004,7 @@ moo_edit_filename_changed (MooEdit *edit,
|
|||
{
|
||||
MooLangMgr *mgr = moo_editor_get_lang_mgr (edit->priv->editor);
|
||||
lang = moo_lang_mgr_get_lang_for_file (mgr, filename);
|
||||
lang_id = lang ? lang->id : NULL;
|
||||
lang_id = lang ? moo_lang_id (lang) : NULL;
|
||||
}
|
||||
|
||||
moo_edit_config_set (edit->config, "lang", MOO_EDIT_CONFIG_SOURCE_FILENAME, lang_id, NULL);
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; coding: utf-8 -*-
|
||||
*
|
||||
/*
|
||||
* mooeditconfig.c
|
||||
*
|
||||
* Copyright (C) 2004-2006 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||
|
@ -58,7 +57,6 @@ static GSList *instances;
|
|||
static VarArray *vars;
|
||||
static GQuark prop_id_quark;
|
||||
static GHashTable *aliases;
|
||||
static GHashTable *lang_configs;
|
||||
|
||||
|
||||
static void moo_edit_config_finalize (GObject *object);
|
||||
|
@ -157,9 +155,6 @@ global_init (void)
|
|||
g_signal_connect (global, "notify",
|
||||
G_CALLBACK (global_changed), NULL);
|
||||
/* XXX read preferences here */
|
||||
|
||||
lang_configs = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
g_free, g_object_unref);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -630,6 +625,22 @@ moo_edit_config_unset_by_source (MooEditConfig *config,
|
|||
}
|
||||
|
||||
|
||||
int
|
||||
moo_edit_config_get_source (MooEditConfig *config,
|
||||
const char *setting)
|
||||
{
|
||||
guint id;
|
||||
|
||||
g_return_val_if_fail (MOO_IS_EDIT_CONFIG (config), 0);
|
||||
g_return_val_if_fail (setting != 0, 0);
|
||||
|
||||
if (!moo_edit_config_lookup_spec (setting, &id, TRUE))
|
||||
g_return_val_if_reached (0);
|
||||
|
||||
return VALUE(config, id)->source;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
moo_edit_config_compose (MooEditConfig *target,
|
||||
MooEditConfig *src)
|
||||
|
@ -719,10 +730,10 @@ parse_boolean (const char *value,
|
|||
|
||||
|
||||
void
|
||||
moo_edit_config_parse (MooEditConfig *config,
|
||||
const char *name,
|
||||
const char *value,
|
||||
MooEditConfigSource source)
|
||||
moo_edit_config_parse_one (MooEditConfig *config,
|
||||
const char *name,
|
||||
const char *value,
|
||||
MooEditConfigSource source)
|
||||
{
|
||||
GValue gval;
|
||||
gboolean result = FALSE;
|
||||
|
@ -759,6 +770,62 @@ moo_edit_config_parse (MooEditConfig *config,
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
moo_edit_config_parse (MooEditConfig *config,
|
||||
const char *string,
|
||||
MooEditConfigSource source)
|
||||
{
|
||||
char **vars, **p;
|
||||
char *copy;
|
||||
|
||||
g_return_if_fail (MOO_IS_EDIT_CONFIG (config));
|
||||
g_return_if_fail (string != NULL);
|
||||
|
||||
copy = g_strdelimit (g_strstrip (g_strdup (string)), ",", ';');
|
||||
vars = g_strsplit (copy, ";", 0);
|
||||
g_free (copy);
|
||||
|
||||
if (!vars)
|
||||
goto out;
|
||||
|
||||
for (p = vars; *p != NULL; p++)
|
||||
{
|
||||
char *sep, *var, *value;
|
||||
|
||||
g_strstrip (*p);
|
||||
sep = strchr (*p, ':');
|
||||
|
||||
if (!sep || sep == *p || !sep[1])
|
||||
goto out;
|
||||
|
||||
var = g_strndup (*p, sep - *p);
|
||||
g_strstrip (var);
|
||||
|
||||
if (!var[0])
|
||||
{
|
||||
g_free (var);
|
||||
goto out;
|
||||
}
|
||||
|
||||
value = sep + 1;
|
||||
g_strstrip (value);
|
||||
|
||||
if (!value)
|
||||
{
|
||||
g_free (var);
|
||||
goto out;
|
||||
}
|
||||
|
||||
moo_edit_config_parse_one (config, var, value, source);
|
||||
|
||||
g_free (var);
|
||||
}
|
||||
|
||||
out:
|
||||
g_strfreev (vars);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
moo_edit_config_install_alias (const char *name,
|
||||
const char *alias)
|
||||
|
@ -797,167 +864,3 @@ moo_edit_config_install_alias (const char *name,
|
|||
g_hash_table_insert (aliases, s1, g_strdup (pspec->name));
|
||||
g_hash_table_insert (aliases, s2, g_strdup (pspec->name));
|
||||
}
|
||||
|
||||
|
||||
MooEditConfig *
|
||||
moo_edit_config_get_for_lang (const char *lang)
|
||||
{
|
||||
MooEditConfig *config;
|
||||
|
||||
global_init ();
|
||||
|
||||
if (!lang)
|
||||
lang = MOO_LANG_NONE;
|
||||
|
||||
config = g_hash_table_lookup (lang_configs, lang);
|
||||
|
||||
if (!config)
|
||||
{
|
||||
config = moo_edit_config_new ();
|
||||
g_hash_table_insert (lang_configs, g_strdup (lang), config);
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
lang_config_set_defaults (void)
|
||||
{
|
||||
MooEditConfig *config;
|
||||
|
||||
config = moo_edit_config_get_for_lang ("makefile");
|
||||
moo_edit_config_parse (config, "use-tabs", "true",
|
||||
MOO_EDIT_CONFIG_SOURCE_LANG);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/* Loading and saving
|
||||
*/
|
||||
|
||||
#define ELEMENT_LANG_CONFIG MOO_EDIT_PREFS_PREFIX "/filetypes"
|
||||
#define ELEMENT_LANG "lang"
|
||||
#define PROP_LANG_ID "id"
|
||||
|
||||
static void
|
||||
load_lang_node (MooMarkupNode *lang_node)
|
||||
{
|
||||
const char *lang_id;
|
||||
MooMarkupNode *node;
|
||||
MooEditConfig *config = NULL;
|
||||
|
||||
lang_id = moo_markup_get_prop (lang_node, PROP_LANG_ID);
|
||||
g_return_if_fail (lang_id != NULL);
|
||||
|
||||
for (node = lang_node->children; node != NULL; node = node->next)
|
||||
{
|
||||
if (!MOO_MARKUP_IS_ELEMENT (node))
|
||||
continue;
|
||||
|
||||
if (!moo_edit_config_lookup_spec (node->name, NULL, TRUE))
|
||||
{
|
||||
g_warning ("%s: no property named '%s'",
|
||||
G_STRLOC, node->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!config)
|
||||
config = moo_edit_config_get_for_lang (lang_id);
|
||||
|
||||
moo_edit_config_parse (config, node->name,
|
||||
moo_markup_get_content (node),
|
||||
MOO_EDIT_CONFIG_SOURCE_LANG);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_moo_edit_config_load (void)
|
||||
{
|
||||
MooMarkupDoc *xml;
|
||||
MooMarkupNode *root, *node;
|
||||
|
||||
lang_config_set_defaults ();
|
||||
|
||||
xml = moo_prefs_get_markup ();
|
||||
g_return_if_fail (xml != NULL);
|
||||
|
||||
root = moo_markup_get_element (MOO_MARKUP_NODE (xml),
|
||||
ELEMENT_LANG_CONFIG);
|
||||
|
||||
if (!root)
|
||||
return;
|
||||
|
||||
for (node = root->children; node != NULL; node = node->next)
|
||||
{
|
||||
if (!MOO_MARKUP_IS_ELEMENT (node))
|
||||
continue;
|
||||
|
||||
if (strcmp (node->name, ELEMENT_LANG))
|
||||
{
|
||||
g_warning ("%s: invalid '%s' element", G_STRLOC, node->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
load_lang_node (node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
save_config (const char *lang_id,
|
||||
MooEditConfig *config,
|
||||
MooMarkupNode *root)
|
||||
{
|
||||
guint i;
|
||||
MooMarkupNode *lang_node = NULL;
|
||||
|
||||
for (i = 1; i < vars->len; ++i)
|
||||
{
|
||||
Value *val = VALUE (config, i);
|
||||
const char *string;
|
||||
|
||||
if (val->source != MOO_EDIT_CONFIG_SOURCE_LANG)
|
||||
continue;
|
||||
|
||||
string = moo_value_convert_to_string (&val->gval);
|
||||
g_return_if_fail (string != NULL);
|
||||
|
||||
if (!lang_node)
|
||||
{
|
||||
lang_node = moo_markup_create_element (root, ELEMENT_LANG);
|
||||
g_return_if_fail (lang_node != NULL);
|
||||
moo_markup_set_prop (lang_node, PROP_LANG_ID, lang_id);
|
||||
}
|
||||
|
||||
moo_markup_create_text_element (lang_node,
|
||||
vars->data[i].pspec->name,
|
||||
string);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_moo_edit_config_save (void)
|
||||
{
|
||||
MooMarkupDoc *xml;
|
||||
MooMarkupNode *root;
|
||||
|
||||
xml = moo_prefs_get_markup ();
|
||||
g_return_if_fail (xml != NULL);
|
||||
|
||||
root = moo_markup_get_element (MOO_MARKUP_NODE (xml),
|
||||
ELEMENT_LANG_CONFIG);
|
||||
|
||||
if (root)
|
||||
moo_markup_delete_node (root);
|
||||
|
||||
if (!lang_configs || !g_hash_table_size (lang_configs))
|
||||
return;
|
||||
|
||||
root = moo_markup_create_element (MOO_MARKUP_NODE (xml),
|
||||
ELEMENT_LANG_CONFIG);
|
||||
g_return_if_fail (root != NULL);
|
||||
|
||||
g_hash_table_foreach (lang_configs, (GHFunc) save_config, root);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; coding: utf-8 -*-
|
||||
*
|
||||
/*
|
||||
* mooeditconfig.h
|
||||
*
|
||||
* Copyright (C) 2004-2006 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||
|
@ -81,10 +80,13 @@ void moo_edit_config_set_global (const char *first_setting,
|
|||
void moo_edit_config_get_global (const char *first_setting,
|
||||
...); /* alias for g_object_get(global, ...) */
|
||||
|
||||
void moo_edit_config_parse (MooEditConfig *config,
|
||||
void moo_edit_config_parse_one (MooEditConfig *config,
|
||||
const char *setting_name,
|
||||
const char *value,
|
||||
MooEditConfigSource source);
|
||||
void moo_edit_config_parse (MooEditConfig *config,
|
||||
const char *string,
|
||||
MooEditConfigSource source);
|
||||
|
||||
guint moo_edit_config_install_setting (GParamSpec *pspec);
|
||||
void moo_edit_config_install_alias (const char *name,
|
||||
|
@ -96,6 +98,8 @@ GParamSpec *moo_edit_config_lookup_spec (const char *name,
|
|||
guint *id,
|
||||
gboolean try_alias);
|
||||
|
||||
int moo_edit_config_get_source (MooEditConfig *config,
|
||||
const char *setting);
|
||||
void moo_edit_config_unset_by_source (MooEditConfig *config,
|
||||
MooEditConfigSource source);
|
||||
|
||||
|
@ -104,10 +108,8 @@ gboolean moo_edit_config_parse_bool (const char *string,
|
|||
|
||||
void moo_edit_config_compose (MooEditConfig *target,
|
||||
MooEditConfig *src);
|
||||
|
||||
MooEditConfig *moo_edit_config_get_for_lang (const char *lang);
|
||||
void _moo_edit_config_load (void);
|
||||
void _moo_edit_config_save (void);
|
||||
void moo_edit_config_update (MooEditConfig *config,
|
||||
const char *lang_id);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "mooedit/mooplugin.h"
|
||||
#include "mooedit/mooeditprefs.h"
|
||||
#include "mooedit/mooedit-private.h"
|
||||
#include "mooedit/moolang-private.h"
|
||||
#include "mooutils/moomenuaction.h"
|
||||
#include "mooutils/moocompat.h"
|
||||
#include "mooutils/moomarshals.h"
|
||||
|
@ -284,7 +285,6 @@ moo_editor_init (MooEditor *editor)
|
|||
|
||||
moo_prefs_new_key_string (moo_edit_setting (MOO_EDIT_PREFS_DEFAULT_LANG),
|
||||
MOO_LANG_NONE);
|
||||
_moo_edit_config_load ();
|
||||
|
||||
editor->priv->prefs_notify =
|
||||
moo_prefs_notify_connect (MOO_EDIT_PREFS_PREFIX "/[^/]*",
|
||||
|
@ -1877,7 +1877,7 @@ apply_prefs (MooEditor *editor)
|
|||
NULL);
|
||||
|
||||
if (color_scheme)
|
||||
moo_lang_mgr_set_active_scheme (editor->priv->lang_mgr, color_scheme);
|
||||
_moo_lang_mgr_set_active_scheme (editor->priv->lang_mgr, color_scheme);
|
||||
|
||||
docs = moo_editor_list_docs (editor);
|
||||
g_slist_foreach (docs, (GFunc) _moo_edit_apply_settings, NULL);
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; coding: utf-8 -*-
|
||||
*
|
||||
/*
|
||||
* mooeditprefspage.c
|
||||
*
|
||||
* Copyright (C) 2004-2006 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||
|
@ -16,17 +15,20 @@
|
|||
#include "mooedit/mooedit-private.h"
|
||||
#include "mooedit/mooeditprefs.h"
|
||||
#include "mooedit/mooeditprefs-glade.h"
|
||||
#include "mooedit/moolang-private.h"
|
||||
#include "mooutils/mooprefsdialog.h"
|
||||
#include "mooutils/moocompat.h"
|
||||
#include "mooutils/moostock.h"
|
||||
#include "mooutils/mooglade.h"
|
||||
#include "mooutils/mooutils-treeview.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
static void prefs_page_init (MooPrefsDialogPage *page);
|
||||
static void prefs_page_apply (MooPrefsDialogPage *page);
|
||||
static void prefs_page_apply_lang_prefs (MooPrefsDialogPage *page);
|
||||
|
||||
static void scheme_combo_init (GtkWidget *combo,
|
||||
static void scheme_combo_init (GtkComboBox *combo,
|
||||
MooEditor *editor);
|
||||
static void scheme_combo_data_func (GtkCellLayout *layout,
|
||||
GtkCellRenderer *cell,
|
||||
|
@ -35,12 +37,18 @@ static void scheme_combo_data_func (GtkCellLayout *layout,
|
|||
static void scheme_combo_set_scheme (GtkComboBox *combo,
|
||||
MooTextStyleScheme *scheme);
|
||||
|
||||
static void default_lang_combo_init (GtkWidget *combo,
|
||||
MooEditor *editor);
|
||||
static void default_lang_combo_init (GtkComboBox *combo,
|
||||
MooPrefsDialogPage *page);
|
||||
static void default_lang_combo_set_lang (GtkComboBox *combo,
|
||||
const char *id);
|
||||
|
||||
static void lang_combo_init (GtkComboBox *combo,
|
||||
MooPrefsDialogPage *page);
|
||||
|
||||
static GtkTreeModel *create_lang_model (MooEditor *editor);
|
||||
|
||||
static MooEditor *page_get_editor (MooPrefsDialogPage *page);
|
||||
static GtkTreeModel *page_get_lang_model (MooPrefsDialogPage *page);
|
||||
static MooTextStyleScheme *page_get_scheme (MooPrefsDialogPage *page);
|
||||
static char *page_get_default_lang (MooPrefsDialogPage *page);
|
||||
|
||||
|
@ -49,7 +57,8 @@ GtkWidget *
|
|||
moo_edit_prefs_page_new (MooEditor *editor)
|
||||
{
|
||||
MooPrefsDialogPage *page;
|
||||
GtkWidget *page_widget, *scheme_combo, *default_lang_combo;
|
||||
GtkWidget *page_widget;
|
||||
GtkComboBox *scheme_combo, *default_lang_combo, *lang_combo;
|
||||
MooGladeXML *xml;
|
||||
|
||||
g_return_val_if_fail (MOO_IS_EDITOR (editor), NULL);
|
||||
|
@ -77,15 +86,17 @@ moo_edit_prefs_page_new (MooEditor *editor)
|
|||
scheme_combo = moo_glade_xml_get_widget (page->xml, "color_scheme_combo");
|
||||
scheme_combo_init (scheme_combo, editor);
|
||||
default_lang_combo = moo_glade_xml_get_widget (page->xml, "default_lang_combo");
|
||||
default_lang_combo_init (default_lang_combo, editor);
|
||||
default_lang_combo_init (default_lang_combo, page);
|
||||
lang_combo = moo_glade_xml_get_widget (page->xml, "lang_combo");
|
||||
lang_combo_init (lang_combo, page);
|
||||
|
||||
return page_widget;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
scheme_combo_init (GtkWidget *combo,
|
||||
MooEditor *editor)
|
||||
scheme_combo_init (GtkComboBox *combo,
|
||||
MooEditor *editor)
|
||||
{
|
||||
GtkListStore *store;
|
||||
MooLangMgr *mgr;
|
||||
|
@ -105,7 +116,7 @@ scheme_combo_init (GtkWidget *combo,
|
|||
gtk_list_store_set (store, &iter, 0, l->data, -1);
|
||||
}
|
||||
|
||||
gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (store));
|
||||
gtk_combo_box_set_model (combo, GTK_TREE_MODEL (store));
|
||||
|
||||
cell = gtk_cell_renderer_text_new ();
|
||||
gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo));
|
||||
|
@ -139,7 +150,8 @@ prefs_page_init (MooPrefsDialogPage *page)
|
|||
MooEditor *editor;
|
||||
MooLangMgr *mgr;
|
||||
MooTextStyleScheme *scheme;
|
||||
GtkComboBox *scheme_combo, *lang_combo;
|
||||
GtkComboBox *scheme_combo, *default_lang_combo;
|
||||
MooTreeHelper *helper;
|
||||
const char *lang;
|
||||
|
||||
editor = page_get_editor (page);
|
||||
|
@ -150,9 +162,12 @@ prefs_page_init (MooPrefsDialogPage *page)
|
|||
scheme_combo = moo_glade_xml_get_widget (page->xml, "color_scheme_combo");
|
||||
scheme_combo_set_scheme (scheme_combo, scheme);
|
||||
|
||||
lang_combo = moo_glade_xml_get_widget (page->xml, "default_lang_combo");
|
||||
default_lang_combo = moo_glade_xml_get_widget (page->xml, "default_lang_combo");
|
||||
lang = moo_prefs_get_string (moo_edit_setting (MOO_EDIT_PREFS_DEFAULT_LANG));
|
||||
default_lang_combo_set_lang (lang_combo, lang);
|
||||
default_lang_combo_set_lang (default_lang_combo, lang);
|
||||
|
||||
helper = g_object_get_data (G_OBJECT (page), "moo-tree-helper");
|
||||
moo_tree_helper_update_widgets (helper);
|
||||
}
|
||||
|
||||
|
||||
|
@ -163,6 +178,24 @@ page_get_editor (MooPrefsDialogPage *page)
|
|||
}
|
||||
|
||||
|
||||
static GtkTreeModel *
|
||||
page_get_lang_model (MooPrefsDialogPage *page)
|
||||
{
|
||||
GtkTreeModel *model;
|
||||
|
||||
model = g_object_get_data (G_OBJECT (page), "moo-lang-model");
|
||||
|
||||
if (!model)
|
||||
{
|
||||
model = create_lang_model (page_get_editor (page));
|
||||
g_object_set_data_full (G_OBJECT (page), "moo-lang-model",
|
||||
model, g_object_unref);
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
scheme_combo_set_scheme (GtkComboBox *combo,
|
||||
MooTextStyleScheme *scheme)
|
||||
|
@ -225,15 +258,111 @@ prefs_page_apply (MooPrefsDialogPage *page)
|
|||
lang = page_get_default_lang (page);
|
||||
moo_prefs_set_string (moo_edit_setting (MOO_EDIT_PREFS_DEFAULT_LANG), lang);
|
||||
g_free (lang);
|
||||
|
||||
prefs_page_apply_lang_prefs (page);
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************/
|
||||
/* Language combo
|
||||
*/
|
||||
|
||||
enum {
|
||||
COLUMN_ID,
|
||||
COLUMN_NAME
|
||||
COLUMN_NAME,
|
||||
COLUMN_LANG,
|
||||
COLUMN_EXTENSIONS,
|
||||
COLUMN_MIMETYPES,
|
||||
COLUMN_CONFIG
|
||||
};
|
||||
|
||||
|
||||
static char *
|
||||
list_to_string (GSList *list)
|
||||
{
|
||||
GString *string = g_string_new (NULL);
|
||||
|
||||
while (list)
|
||||
{
|
||||
g_string_append (string, list->data);
|
||||
|
||||
if ((list = list->next))
|
||||
g_string_append_c (string, ';');
|
||||
}
|
||||
|
||||
return g_string_free (string, FALSE);
|
||||
}
|
||||
|
||||
|
||||
static GtkTreeModel *
|
||||
create_lang_model (MooEditor *editor)
|
||||
{
|
||||
GtkTreeStore *store;
|
||||
MooLangMgr *mgr;
|
||||
GSList *langs, *sections, *l;
|
||||
GtkTreeIter iter;
|
||||
const char *config;
|
||||
|
||||
mgr = moo_editor_get_lang_mgr (editor);
|
||||
langs = moo_lang_mgr_get_available_langs (mgr);
|
||||
sections = moo_lang_mgr_get_sections (mgr);
|
||||
|
||||
store = gtk_tree_store_new (6, G_TYPE_STRING, G_TYPE_STRING, MOO_TYPE_LANG,
|
||||
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
|
||||
|
||||
gtk_tree_store_append (store, &iter, NULL);
|
||||
config = _moo_lang_mgr_get_config (mgr, MOO_LANG_NONE);
|
||||
gtk_tree_store_set (store, &iter, COLUMN_ID, MOO_LANG_NONE,
|
||||
COLUMN_NAME, "None",
|
||||
COLUMN_CONFIG, config,
|
||||
-1);
|
||||
|
||||
/* separator */
|
||||
gtk_tree_store_append (store, &iter, NULL);
|
||||
|
||||
while (sections)
|
||||
{
|
||||
char *section = sections->data;
|
||||
|
||||
gtk_tree_store_append (store, &iter, NULL);
|
||||
gtk_tree_store_set (store, &iter, COLUMN_NAME, section, -1);
|
||||
|
||||
for (l = langs; l != NULL; l = l->next)
|
||||
{
|
||||
MooLang *lang = l->data;
|
||||
|
||||
if (!lang->hidden && !strcmp (lang->section, section))
|
||||
{
|
||||
GtkTreeIter child;
|
||||
char *ext, *mime;
|
||||
|
||||
ext = list_to_string (moo_lang_get_extensions (lang));
|
||||
mime = list_to_string (moo_lang_get_mime_types (lang));
|
||||
|
||||
config = _moo_lang_mgr_get_config (mgr, lang->id);
|
||||
gtk_tree_store_append (store, &child, &iter);
|
||||
gtk_tree_store_set (store, &child, COLUMN_ID, lang->id,
|
||||
COLUMN_NAME, lang->display_name,
|
||||
COLUMN_LANG, lang,
|
||||
COLUMN_CONFIG, config,
|
||||
COLUMN_MIMETYPES, mime,
|
||||
COLUMN_EXTENSIONS, ext,
|
||||
-1);
|
||||
|
||||
g_free (ext);
|
||||
g_free (mime);
|
||||
}
|
||||
}
|
||||
|
||||
g_free (section);
|
||||
sections = g_slist_delete_link (sections, sections);
|
||||
}
|
||||
|
||||
g_slist_free (langs);
|
||||
return GTK_TREE_MODEL (store);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
separator_func (GtkTreeModel *model,
|
||||
GtkTreeIter *iter,
|
||||
|
@ -251,46 +380,37 @@ separator_func (GtkTreeModel *model,
|
|||
}
|
||||
|
||||
static void
|
||||
default_lang_combo_init (GtkWidget *combo,
|
||||
MooEditor *editor)
|
||||
set_sensitive (G_GNUC_UNUSED GtkCellLayout *cell_layout,
|
||||
GtkCellRenderer *cell,
|
||||
GtkTreeModel *model,
|
||||
GtkTreeIter *iter,
|
||||
G_GNUC_UNUSED gpointer data)
|
||||
{
|
||||
GtkListStore *store;
|
||||
MooLangMgr *mgr;
|
||||
GSList *list, *l;
|
||||
g_object_set (cell, "sensitive",
|
||||
!gtk_tree_model_iter_has_child (model, iter),
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
default_lang_combo_init (GtkComboBox *combo,
|
||||
MooPrefsDialogPage *page)
|
||||
{
|
||||
GtkTreeModel *model;
|
||||
GtkCellRenderer *cell;
|
||||
GtkTreeIter iter;
|
||||
|
||||
mgr = moo_editor_get_lang_mgr (editor);
|
||||
list = moo_lang_mgr_get_available_langs (mgr);
|
||||
model = page_get_lang_model (page);
|
||||
g_return_if_fail (model != NULL);
|
||||
|
||||
store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
|
||||
|
||||
gtk_list_store_append (store, &iter);
|
||||
gtk_list_store_set (store, &iter, COLUMN_ID, MOO_LANG_NONE,
|
||||
COLUMN_NAME, "None", -1);
|
||||
/* separator */
|
||||
gtk_list_store_append (store, &iter);
|
||||
|
||||
for (l = list; l != NULL; l = l->next)
|
||||
{
|
||||
MooLang *lang = l->data;
|
||||
gtk_list_store_append (store, &iter);
|
||||
gtk_list_store_set (store, &iter, COLUMN_ID, lang->id,
|
||||
COLUMN_NAME, lang->display_name, -1);
|
||||
}
|
||||
|
||||
gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (store));
|
||||
gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (combo),
|
||||
separator_func, NULL, NULL);
|
||||
gtk_combo_box_set_model (combo, model);
|
||||
gtk_combo_box_set_row_separator_func (combo, separator_func, NULL, NULL);
|
||||
|
||||
cell = gtk_cell_renderer_text_new ();
|
||||
gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo));
|
||||
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE);
|
||||
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), cell,
|
||||
"text", COLUMN_NAME, NULL);
|
||||
|
||||
g_object_unref (store);
|
||||
g_slist_free (list);
|
||||
gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo), cell,
|
||||
set_sensitive, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -302,39 +422,59 @@ str_equal (const char *s1, const char *s2)
|
|||
return !strcmp (s1, s2);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
find_lang_by_id (GtkTreeModel *model,
|
||||
G_GNUC_UNUSED GtkTreePath *path,
|
||||
GtkTreeIter *iter,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct {
|
||||
gboolean found;
|
||||
GtkTreeIter iter;
|
||||
const char *id;
|
||||
} *data = user_data;
|
||||
|
||||
char *lang_id = NULL;
|
||||
|
||||
gtk_tree_model_get (model, iter, COLUMN_ID, &lang_id, -1);
|
||||
|
||||
if (str_equal (data->id, lang_id))
|
||||
{
|
||||
data->found = TRUE;
|
||||
data->iter = *iter;
|
||||
g_free (lang_id);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_free (lang_id);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
default_lang_combo_set_lang (GtkComboBox *combo,
|
||||
const char *id)
|
||||
{
|
||||
gboolean found = FALSE;
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel *model;
|
||||
|
||||
struct {
|
||||
gboolean found;
|
||||
GtkTreeIter iter;
|
||||
const char *id;
|
||||
} data;
|
||||
|
||||
g_return_if_fail (GTK_IS_COMBO_BOX (combo));
|
||||
|
||||
model = gtk_combo_box_get_model (combo);
|
||||
gtk_tree_model_get_iter_first (model, &iter);
|
||||
data.found = FALSE;
|
||||
data.id = id;
|
||||
|
||||
do
|
||||
{
|
||||
char *lang_id;
|
||||
gtk_tree_model_foreach (model,
|
||||
(GtkTreeModelForeachFunc) find_lang_by_id,
|
||||
&data);
|
||||
|
||||
gtk_tree_model_get (model, &iter, COLUMN_ID, &lang_id, -1);
|
||||
|
||||
if (str_equal (id, lang_id))
|
||||
{
|
||||
found = TRUE;
|
||||
g_free (lang_id);
|
||||
break;
|
||||
}
|
||||
|
||||
g_free (lang_id);
|
||||
}
|
||||
while (gtk_tree_model_iter_next (model, &iter));
|
||||
|
||||
g_return_if_fail (found);
|
||||
|
||||
gtk_combo_box_set_active_iter (combo, &iter);
|
||||
g_return_if_fail (data.found);
|
||||
gtk_combo_box_set_active_iter (combo, &data.iter);
|
||||
}
|
||||
|
||||
|
||||
|
@ -357,3 +497,176 @@ page_get_default_lang (MooPrefsDialogPage *page)
|
|||
|
||||
return lang;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************/
|
||||
/* Per-lang settings
|
||||
*/
|
||||
|
||||
static void
|
||||
helper_update_widgets (MooPrefsDialogPage *page,
|
||||
GtkTreeModel *model,
|
||||
G_GNUC_UNUSED GtkTreePath *path,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
GtkEntry *extensions, *mimetypes, *config;
|
||||
GtkWidget *label_extensions, *label_mimetypes;
|
||||
MooLang *lang = NULL;
|
||||
char *ext = NULL, *mime = NULL, *id = NULL, *conf = NULL;
|
||||
|
||||
g_return_if_fail (iter != NULL);
|
||||
|
||||
extensions = moo_glade_xml_get_widget (page->xml, "extensions");
|
||||
label_extensions = moo_glade_xml_get_widget (page->xml, "label_extensions");
|
||||
mimetypes = moo_glade_xml_get_widget (page->xml, "mimetypes");
|
||||
label_mimetypes = moo_glade_xml_get_widget (page->xml, "label_mimetypes");
|
||||
config = moo_glade_xml_get_widget (page->xml, "config");
|
||||
|
||||
gtk_tree_model_get (model, iter,
|
||||
COLUMN_LANG, &lang,
|
||||
COLUMN_MIMETYPES, &mime,
|
||||
COLUMN_EXTENSIONS, &ext,
|
||||
COLUMN_CONFIG, &conf,
|
||||
COLUMN_ID, &id,
|
||||
-1);
|
||||
g_return_if_fail (id != NULL);
|
||||
|
||||
gtk_entry_set_text (extensions, ext ? ext : "");
|
||||
gtk_entry_set_text (mimetypes, mime ? mime : "");
|
||||
gtk_entry_set_text (config, conf ? conf : "");
|
||||
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (extensions), lang != NULL);
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (mimetypes), lang != NULL);
|
||||
gtk_widget_set_sensitive (label_extensions, lang != NULL);
|
||||
gtk_widget_set_sensitive (label_mimetypes, lang != NULL);
|
||||
|
||||
if (lang)
|
||||
moo_lang_unref (lang);
|
||||
|
||||
g_free (conf);
|
||||
g_free (ext);
|
||||
g_free (mime);
|
||||
g_free (id);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
helper_update_model (MooPrefsDialogPage *page,
|
||||
GtkTreeModel *model,
|
||||
G_GNUC_UNUSED GtkTreePath *path,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
GtkEntry *extensions, *mimetypes, *config;
|
||||
const char *ext, *mime, *conf;
|
||||
|
||||
extensions = moo_glade_xml_get_widget (page->xml, "extensions");
|
||||
ext = gtk_entry_get_text (extensions);
|
||||
mimetypes = moo_glade_xml_get_widget (page->xml, "mimetypes");
|
||||
mime = gtk_entry_get_text (mimetypes);
|
||||
config = moo_glade_xml_get_widget (page->xml, "config");
|
||||
conf = gtk_entry_get_text (config);
|
||||
|
||||
gtk_tree_store_set (GTK_TREE_STORE (model), iter,
|
||||
COLUMN_MIMETYPES, mime,
|
||||
COLUMN_EXTENSIONS, ext,
|
||||
COLUMN_CONFIG, conf, -1);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
lang_combo_init (GtkComboBox *combo,
|
||||
MooPrefsDialogPage *page)
|
||||
{
|
||||
GtkTreeModel *model;
|
||||
GtkCellRenderer *cell;
|
||||
MooTreeHelper *helper;
|
||||
|
||||
model = page_get_lang_model (page);
|
||||
g_return_if_fail (model != NULL);
|
||||
|
||||
gtk_combo_box_set_model (combo, model);
|
||||
gtk_combo_box_set_row_separator_func (combo, separator_func, NULL, NULL);
|
||||
|
||||
cell = gtk_cell_renderer_text_new ();
|
||||
gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo));
|
||||
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE);
|
||||
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), cell,
|
||||
"text", COLUMN_NAME, NULL);
|
||||
gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo), cell,
|
||||
set_sensitive, NULL, NULL);
|
||||
|
||||
moo_combo_box_select_first (combo);
|
||||
helper = moo_tree_helper_new (GTK_WIDGET (combo));
|
||||
g_return_if_fail (helper != NULL);
|
||||
|
||||
g_object_set_data_full (G_OBJECT (page), "moo-tree-helper",
|
||||
helper, g_object_unref);
|
||||
g_signal_connect_swapped (helper, "update-widgets",
|
||||
G_CALLBACK (helper_update_widgets), page);
|
||||
g_signal_connect_swapped (helper, "update-model",
|
||||
G_CALLBACK (helper_update_model), page);
|
||||
moo_tree_helper_update_widgets (helper);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
apply_one_lang (GtkTreeModel *model,
|
||||
G_GNUC_UNUSED GtkTreePath *path,
|
||||
GtkTreeIter *iter,
|
||||
MooLangMgr *mgr)
|
||||
{
|
||||
MooLang *lang = NULL;
|
||||
char *config = NULL, *id = NULL;
|
||||
|
||||
gtk_tree_model_get (model, iter,
|
||||
COLUMN_LANG, &lang,
|
||||
COLUMN_ID, &id,
|
||||
COLUMN_CONFIG, &config, -1);
|
||||
|
||||
if (!id)
|
||||
return FALSE;
|
||||
|
||||
if (lang)
|
||||
{
|
||||
char *mime, *ext;
|
||||
|
||||
gtk_tree_model_get (model, iter,
|
||||
COLUMN_MIMETYPES, &mime,
|
||||
COLUMN_EXTENSIONS, &ext, -1);
|
||||
|
||||
_moo_lang_set_mime_types (lang, mime);
|
||||
_moo_lang_set_extensions (lang, ext);
|
||||
|
||||
g_free (mime);
|
||||
g_free (ext);
|
||||
}
|
||||
|
||||
_moo_lang_mgr_set_config (mgr, id, config);
|
||||
|
||||
if (lang)
|
||||
moo_lang_unref (lang);
|
||||
|
||||
g_free (config);
|
||||
g_free (id);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
prefs_page_apply_lang_prefs (MooPrefsDialogPage *page)
|
||||
{
|
||||
GtkTreeModel *model;
|
||||
MooTreeHelper *helper;
|
||||
MooLangMgr *mgr;
|
||||
|
||||
helper = g_object_get_data (G_OBJECT (page), "moo-tree-helper");
|
||||
moo_tree_helper_update_model (helper, NULL, NULL);
|
||||
|
||||
model = page_get_lang_model (page);
|
||||
g_return_if_fail (model != NULL);
|
||||
|
||||
mgr = moo_editor_get_lang_mgr (page_get_editor (page));
|
||||
gtk_tree_model_foreach (model, (GtkTreeModelForeachFunc) apply_one_lang, mgr);
|
||||
_moo_lang_mgr_save_config (mgr);
|
||||
_moo_edit_update_config ();
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#define MOOEDIT_COMPILATION
|
||||
#include "mooedit/statusbar-glade.h"
|
||||
#include "mooedit/mooedit-private.h"
|
||||
#include "mooedit/moolang-private.h"
|
||||
#include "mooedit/mooeditor.h"
|
||||
#include "mooedit/mootextbuffer.h"
|
||||
#include "mooedit/mooeditprefs.h"
|
||||
|
|
|
@ -494,7 +494,7 @@ hl_compute_range (MooHighlighter *hl,
|
|||
{
|
||||
if (!hl->root)
|
||||
hl->root = ctx_node_new (hl, NULL,
|
||||
moo_lang_get_default_context (hl->lang),
|
||||
_moo_lang_get_default_context (hl->lang),
|
||||
FALSE);
|
||||
node = hl->root;
|
||||
}
|
||||
|
|
|
@ -1657,11 +1657,11 @@ _moo_rule_new_from_xml (RuleXML *xml,
|
|||
case MOO_CONTEXT_JUMP:
|
||||
#endif
|
||||
if (xml->end_switch_info.ref.lang)
|
||||
switch_to = moo_lang_mgr_get_context (lang->mgr,
|
||||
xml->end_switch_info.ref.lang,
|
||||
xml->end_switch_info.ref.name);
|
||||
switch_to = _moo_lang_mgr_get_context (lang->mgr,
|
||||
xml->end_switch_info.ref.lang,
|
||||
xml->end_switch_info.ref.name);
|
||||
else
|
||||
switch_to = moo_lang_get_context (lang, xml->end_switch_info.ref.name);
|
||||
switch_to = _moo_lang_get_context (lang, xml->end_switch_info.ref.name);
|
||||
|
||||
if (!switch_to)
|
||||
{
|
||||
|
@ -2137,9 +2137,9 @@ rule_include_xml_create_rule (RuleIncludeXML *xml,
|
|||
MooContext *ctx;
|
||||
|
||||
if (xml->from_lang)
|
||||
ctx = moo_lang_mgr_get_context (lang->mgr, xml->from_lang, xml->from_context);
|
||||
ctx = _moo_lang_mgr_get_context (lang->mgr, xml->from_lang, xml->from_context);
|
||||
else
|
||||
ctx = moo_lang_get_context (lang, xml->from_context);
|
||||
ctx = _moo_lang_get_context (lang, xml->from_context);
|
||||
|
||||
g_return_val_if_fail (ctx != NULL, NULL);
|
||||
|
||||
|
|
|
@ -0,0 +1,295 @@
|
|||
/*
|
||||
* moolang-private.h
|
||||
*
|
||||
* Copyright (C) 2004-2006 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* See COPYING file that comes with this distribution.
|
||||
*/
|
||||
|
||||
#ifndef MOOEDIT_COMPILATION
|
||||
#error "This file may not be used"
|
||||
#endif
|
||||
|
||||
#ifndef __MOO_LANG_PRIVATE_H__
|
||||
#define __MOO_LANG_PRIVATE_H__
|
||||
|
||||
#include "mooedit/moolangmgr.h"
|
||||
#include "mooedit/mooeditconfig.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
typedef struct _MooContext MooContext;
|
||||
typedef struct _MooContextArray MooContextArray;
|
||||
typedef struct _MooCtxSwitch MooCtxSwitch;
|
||||
typedef struct _MooRule MooRule;
|
||||
typedef struct _MooRuleArray MooRuleArray;
|
||||
typedef struct _MooRuleMatchData MooRuleMatchData;
|
||||
typedef struct _MooRuleMatchResult MooRuleMatchResult;
|
||||
|
||||
typedef struct _MooLangMgrClass MooLangMgrClass;
|
||||
|
||||
struct _MooLang {
|
||||
struct _MooLangMgr *mgr;
|
||||
|
||||
GHashTable *context_names; /* char* -> MooContext* */
|
||||
MooContextArray *contexts;
|
||||
|
||||
GHashTable *style_names; /* char* -> MooStyle* */
|
||||
MooTextStyleArray *styles;
|
||||
GHashTable *style_cache;
|
||||
|
||||
char *id; /* not NULL */
|
||||
char *display_name; /* not NULL */
|
||||
char *section; /* not NULL; "Others" by default */
|
||||
char *version; /* not NULL; "" by default */
|
||||
char *author; /* not NULL; "" by default */
|
||||
GSList *mime_types; /* list of mime types */
|
||||
GSList *extensions; /* list of globs */
|
||||
|
||||
char *brackets;
|
||||
char *line_comment;
|
||||
char *block_comment_start;
|
||||
char *block_comment_end;
|
||||
|
||||
char *sample;
|
||||
|
||||
guint hidden : 1;
|
||||
};
|
||||
|
||||
|
||||
struct _MooLangMgr {
|
||||
GObject base;
|
||||
|
||||
GSList *lang_dirs;
|
||||
GSList *langs;
|
||||
GHashTable *lang_names;
|
||||
GHashTable *schemes;
|
||||
MooTextStyleScheme *active_scheme;
|
||||
GHashTable *extensions;
|
||||
GHashTable *mime_types;
|
||||
|
||||
GHashTable *config;
|
||||
|
||||
guint dirs_read : 1;
|
||||
};
|
||||
|
||||
struct _MooLangMgrClass
|
||||
{
|
||||
GObjectClass base_class;
|
||||
};
|
||||
|
||||
|
||||
typedef enum {
|
||||
MOO_CONTEXT_STAY = 0,
|
||||
MOO_CONTEXT_POP,
|
||||
MOO_CONTEXT_SWITCH /*,
|
||||
MOO_CONTEXT_JUMP */
|
||||
} MooCtxSwitchType;
|
||||
|
||||
struct _MooCtxSwitch {
|
||||
MooCtxSwitchType type;
|
||||
|
||||
union {
|
||||
guint num;
|
||||
MooContext *ctx;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
struct _MooRuleArray {
|
||||
MooRule **data;
|
||||
guint len;
|
||||
};
|
||||
|
||||
struct _MooContextArray {
|
||||
MooContext **data;
|
||||
guint len;
|
||||
};
|
||||
|
||||
struct _MooContext {
|
||||
MooLang *lang;
|
||||
char *name;
|
||||
char *style;
|
||||
|
||||
MooRuleArray *rules;
|
||||
|
||||
MooCtxSwitch line_end;
|
||||
};
|
||||
|
||||
|
||||
typedef enum {
|
||||
MOO_RULE_MATCH_FIRST_CHAR = 1 << 0,
|
||||
MOO_RULE_MATCH_FIRST_NON_EMPTY_CHAR = 1 << 1,
|
||||
MOO_RULE_MATCH_FIRST_LINE = 1 << 2,
|
||||
MOO_RULE_MATCH_CASELESS = 1 << 3,
|
||||
MOO_RULE_INCLUDE_INTO_NEXT = 1 << 4
|
||||
} MooRuleFlags;
|
||||
|
||||
typedef enum {
|
||||
MOO_RULE_MATCH_START_ONLY = 1 << 0
|
||||
} MooRuleMatchFlags;
|
||||
|
||||
|
||||
typedef struct {
|
||||
char *string;
|
||||
guint length;
|
||||
guint caseless : 1;
|
||||
} MooRuleAsciiString;
|
||||
|
||||
typedef struct {
|
||||
gpointer regex; /* EggRegex* */
|
||||
guint non_empty : 1;
|
||||
guint left_word_bndry : 1;
|
||||
guint right_word_bndry : 1;
|
||||
} MooRuleRegex;
|
||||
|
||||
typedef struct {
|
||||
char ch;
|
||||
guint caseless : 1;
|
||||
} MooRuleAsciiChar;
|
||||
|
||||
typedef struct {
|
||||
char str[3];
|
||||
} MooRuleAscii2Char;
|
||||
|
||||
typedef struct {
|
||||
char *chars;
|
||||
guint n_chars;
|
||||
} MooRuleAsciiAnyChar;
|
||||
|
||||
typedef struct {
|
||||
MooContext *ctx;
|
||||
} MooRuleInclude;
|
||||
|
||||
|
||||
struct _MooRule
|
||||
{
|
||||
MooRule* (*match) (MooRule *self,
|
||||
const MooRuleMatchData *data,
|
||||
MooRuleMatchResult *result,
|
||||
MooRuleMatchFlags flags);
|
||||
void (*destroy) (MooRule *self);
|
||||
|
||||
char *description;
|
||||
char *style;
|
||||
|
||||
MooContext *context;
|
||||
MooCtxSwitch exit;
|
||||
|
||||
gboolean include_eol;
|
||||
|
||||
MooRuleFlags flags;
|
||||
|
||||
MooRuleArray *child_rules;
|
||||
|
||||
union {
|
||||
MooRuleAsciiString str;
|
||||
MooRuleRegex regex;
|
||||
MooRuleAsciiChar _char;
|
||||
MooRuleAscii2Char _2char;
|
||||
MooRuleAsciiAnyChar anychar;
|
||||
MooRuleInclude incl;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* MooContext
|
||||
*/
|
||||
|
||||
void _moo_context_add_rule (MooContext *ctx,
|
||||
MooRule *rule);
|
||||
void _moo_context_set_eol_stay (MooContext *ctx);
|
||||
void _moo_context_set_eol_pop (MooContext *ctx,
|
||||
guint num);
|
||||
void _moo_context_set_eol_switch (MooContext *ctx,
|
||||
MooContext *target);
|
||||
#if 0
|
||||
void moo_context_set_eol_jump (MooContext *ctx,
|
||||
MooContext *target);
|
||||
#endif
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* MooLang
|
||||
*/
|
||||
|
||||
MooLang *_moo_lang_new (struct _MooLangMgr *mgr,
|
||||
const char *name,
|
||||
const char *section,
|
||||
const char *version,
|
||||
const char *author);
|
||||
|
||||
MooContext *_moo_lang_add_context (MooLang *lang,
|
||||
const char *name,
|
||||
const char *style);
|
||||
MooContext *_moo_lang_get_context (MooLang *lang,
|
||||
const char *ctx_name);
|
||||
MooContext *_moo_lang_get_default_context (MooLang *lang);
|
||||
void _moo_lang_add_style (MooLang *lang,
|
||||
const char *name,
|
||||
const MooTextStyle *style);
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Auxiliary private methods
|
||||
*/
|
||||
|
||||
void _moo_lang_free (MooLang *lang);
|
||||
|
||||
void _moo_lang_scheme_changed (MooLang *lang);
|
||||
void _moo_lang_set_tag_style (MooLang *lang,
|
||||
GtkTextTag *tag,
|
||||
MooContext *ctx,
|
||||
MooRule *rule,
|
||||
MooTextStyleScheme *scheme);
|
||||
void _moo_style_set_tag_style (const MooTextStyle *style,
|
||||
GtkTextTag *tag);
|
||||
void _moo_lang_erase_tag_style (GtkTextTag *tag);
|
||||
|
||||
/* implemented in moohighlighter.c */
|
||||
GtkTextTag *_moo_text_iter_get_syntax_tag (const GtkTextIter *iter);
|
||||
|
||||
/* implemented in moolangmgr.c */
|
||||
void _moo_lang_set_mime_types (MooLang *lang,
|
||||
const char *string);
|
||||
void _moo_lang_set_extensions (MooLang *lang,
|
||||
const char *string);
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* MooLangMgr
|
||||
*/
|
||||
|
||||
MooContext *_moo_lang_mgr_get_context (MooLangMgr *mgr,
|
||||
const char *lang_name,
|
||||
const char *ctx_name);
|
||||
MooTextStyle *_moo_lang_mgr_get_style (MooLangMgr *mgr,
|
||||
const char *lang_name, /* default style if NULL */
|
||||
const char *style_name,
|
||||
MooTextStyleScheme *scheme);
|
||||
void _moo_lang_mgr_set_active_scheme (MooLangMgr *mgr,
|
||||
const char *scheme_name);
|
||||
void _moo_lang_mgr_add_lang (MooLangMgr *mgr,
|
||||
MooLang *lang);
|
||||
const char *_moo_lang_mgr_get_config (MooLangMgr *mgr,
|
||||
const char *lang_id);
|
||||
void _moo_lang_mgr_set_config (MooLangMgr *mgr,
|
||||
const char *lang_id,
|
||||
const char *config);
|
||||
void _moo_lang_mgr_update_config (MooLangMgr *mgr,
|
||||
MooEditConfig *config,
|
||||
const char *lang_id);
|
||||
void _moo_lang_mgr_load_config (MooLangMgr *mgr);
|
||||
void _moo_lang_mgr_save_config (MooLangMgr *mgr);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __MOO_LANG_H__ */
|
|
@ -18,7 +18,7 @@
|
|||
#ifndef __MOO_LANG_RULES_H__
|
||||
#define __MOO_LANG_RULES_H__
|
||||
|
||||
#include "mooedit/moolang.h"
|
||||
#include "mooedit/moolang-private.h"
|
||||
#include "mooutils/eggregex.h"
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
|
|
@ -76,8 +76,8 @@ moo_context_free (MooContext *ctx)
|
|||
|
||||
|
||||
void
|
||||
moo_context_add_rule (MooContext *ctx,
|
||||
MooRule *rule)
|
||||
_moo_context_add_rule (MooContext *ctx,
|
||||
MooRule *rule)
|
||||
{
|
||||
g_return_if_fail (ctx != NULL && rule != NULL);
|
||||
g_return_if_fail (rule->context == NULL);
|
||||
|
@ -87,7 +87,7 @@ moo_context_add_rule (MooContext *ctx,
|
|||
|
||||
|
||||
void
|
||||
moo_context_set_eol_stay (MooContext *ctx)
|
||||
_moo_context_set_eol_stay (MooContext *ctx)
|
||||
{
|
||||
g_return_if_fail (ctx != NULL);
|
||||
ctx->line_end.type = MOO_CONTEXT_STAY;
|
||||
|
@ -96,7 +96,7 @@ moo_context_set_eol_stay (MooContext *ctx)
|
|||
|
||||
|
||||
void
|
||||
moo_context_set_eol_pop (MooContext *ctx,
|
||||
_moo_context_set_eol_pop (MooContext *ctx,
|
||||
guint num)
|
||||
{
|
||||
g_return_if_fail (ctx != NULL);
|
||||
|
@ -107,8 +107,8 @@ moo_context_set_eol_pop (MooContext *ctx,
|
|||
|
||||
|
||||
void
|
||||
moo_context_set_eol_switch (MooContext *ctx,
|
||||
MooContext *target)
|
||||
_moo_context_set_eol_switch (MooContext *ctx,
|
||||
MooContext *target)
|
||||
{
|
||||
g_return_if_fail (ctx != NULL && target != NULL);
|
||||
ctx->line_end.type = MOO_CONTEXT_SWITCH;
|
||||
|
@ -212,11 +212,11 @@ lang_connect_scheme (MooLang *lang,
|
|||
|
||||
|
||||
MooLang*
|
||||
moo_lang_new (MooLangMgr *mgr,
|
||||
const char *name,
|
||||
const char *section,
|
||||
const char *version,
|
||||
const char *author)
|
||||
_moo_lang_new (MooLangMgr *mgr,
|
||||
const char *name,
|
||||
const char *section,
|
||||
const char *version,
|
||||
const char *author)
|
||||
{
|
||||
MooLang *lang;
|
||||
|
||||
|
@ -262,9 +262,9 @@ moo_lang_id (MooLang *lang)
|
|||
|
||||
|
||||
void
|
||||
moo_lang_add_style (MooLang *lang,
|
||||
const char *name,
|
||||
const MooTextStyle *style)
|
||||
_moo_lang_add_style (MooLang *lang,
|
||||
const char *name,
|
||||
const MooTextStyle *style)
|
||||
{
|
||||
MooTextStyle *copy;
|
||||
|
||||
|
@ -300,9 +300,9 @@ moo_lang_unref (MooLang *lang)
|
|||
|
||||
|
||||
MooContext*
|
||||
moo_lang_add_context (MooLang *lang,
|
||||
const char *name,
|
||||
const char *style)
|
||||
_moo_lang_add_context (MooLang *lang,
|
||||
const char *name,
|
||||
const char *style)
|
||||
{
|
||||
MooContext *ctx;
|
||||
|
||||
|
@ -319,8 +319,8 @@ moo_lang_add_context (MooLang *lang,
|
|||
|
||||
|
||||
MooContext*
|
||||
moo_lang_get_context (MooLang *lang,
|
||||
const char *ctx_name)
|
||||
_moo_lang_get_context (MooLang *lang,
|
||||
const char *ctx_name)
|
||||
{
|
||||
g_return_val_if_fail (lang != NULL, NULL);
|
||||
g_return_val_if_fail (ctx_name != NULL, NULL);
|
||||
|
@ -329,7 +329,7 @@ moo_lang_get_context (MooLang *lang,
|
|||
|
||||
|
||||
MooContext*
|
||||
moo_lang_get_default_context (MooLang *lang)
|
||||
_moo_lang_get_default_context (MooLang *lang)
|
||||
{
|
||||
g_return_val_if_fail (lang != NULL, NULL);
|
||||
g_return_val_if_fail (lang->contexts->len != 0, NULL);
|
||||
|
@ -415,14 +415,14 @@ set_tag_style (MooLang *lang,
|
|||
|
||||
if (!style)
|
||||
{
|
||||
style = moo_lang_mgr_get_style (lang->mgr, lang->id, style_name, scheme);
|
||||
style = _moo_lang_mgr_get_style (lang->mgr, lang->id, style_name, scheme);
|
||||
g_return_if_fail (style != NULL);
|
||||
|
||||
if (style->default_style)
|
||||
{
|
||||
MooTextStyle *def_style;
|
||||
|
||||
def_style = moo_lang_mgr_get_style (lang->mgr, NULL, style->default_style, scheme);
|
||||
def_style = _moo_lang_mgr_get_style (lang->mgr, NULL, style->default_style, scheme);
|
||||
|
||||
if (!def_style)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; coding: utf-8 -*-
|
||||
*
|
||||
/*
|
||||
* moolang.h
|
||||
*
|
||||
* Copyright (C) 2004-2006 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||
|
@ -30,223 +29,20 @@ G_BEGIN_DECLS
|
|||
|
||||
|
||||
typedef struct _MooLang MooLang;
|
||||
typedef struct _MooContext MooContext;
|
||||
typedef struct _MooContextArray MooContextArray;
|
||||
typedef struct _MooCtxSwitch MooCtxSwitch;
|
||||
typedef struct _MooRule MooRule;
|
||||
typedef struct _MooRuleArray MooRuleArray;
|
||||
typedef struct _MooRuleMatchData MooRuleMatchData;
|
||||
typedef struct _MooRuleMatchResult MooRuleMatchResult;
|
||||
|
||||
|
||||
struct _MooLang {
|
||||
struct _MooLangMgr *mgr;
|
||||
|
||||
GHashTable *context_names; /* char* -> MooContext* */
|
||||
MooContextArray *contexts;
|
||||
|
||||
GHashTable *style_names; /* char* -> MooStyle* */
|
||||
MooTextStyleArray *styles;
|
||||
GHashTable *style_cache;
|
||||
|
||||
char *id; /* not NULL */
|
||||
char *display_name; /* not NULL */
|
||||
char *section; /* not NULL; "Others" by default */
|
||||
char *version; /* not NULL; "" by default */
|
||||
char *author; /* not NULL; "" by default */
|
||||
GSList *mime_types; /* list of mime types */
|
||||
GSList *extensions; /* list of globs */
|
||||
|
||||
char *brackets;
|
||||
char *line_comment;
|
||||
char *block_comment_start;
|
||||
char *block_comment_end;
|
||||
|
||||
char *sample;
|
||||
|
||||
guint hidden : 1;
|
||||
};
|
||||
|
||||
|
||||
typedef enum {
|
||||
MOO_CONTEXT_STAY = 0,
|
||||
MOO_CONTEXT_POP,
|
||||
MOO_CONTEXT_SWITCH /*,
|
||||
MOO_CONTEXT_JUMP */
|
||||
} MooCtxSwitchType;
|
||||
|
||||
struct _MooCtxSwitch {
|
||||
MooCtxSwitchType type;
|
||||
|
||||
union {
|
||||
guint num;
|
||||
MooContext *ctx;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
struct _MooRuleArray {
|
||||
MooRule **data;
|
||||
guint len;
|
||||
};
|
||||
|
||||
struct _MooContextArray {
|
||||
MooContext **data;
|
||||
guint len;
|
||||
};
|
||||
|
||||
struct _MooContext {
|
||||
MooLang *lang;
|
||||
char *name;
|
||||
char *style;
|
||||
|
||||
MooRuleArray *rules;
|
||||
|
||||
MooCtxSwitch line_end;
|
||||
};
|
||||
|
||||
|
||||
typedef enum {
|
||||
MOO_RULE_MATCH_FIRST_CHAR = 1 << 0,
|
||||
MOO_RULE_MATCH_FIRST_NON_EMPTY_CHAR = 1 << 1,
|
||||
MOO_RULE_MATCH_FIRST_LINE = 1 << 2,
|
||||
MOO_RULE_MATCH_CASELESS = 1 << 3,
|
||||
MOO_RULE_INCLUDE_INTO_NEXT = 1 << 4
|
||||
} MooRuleFlags;
|
||||
|
||||
typedef enum {
|
||||
MOO_RULE_MATCH_START_ONLY = 1 << 0
|
||||
} MooRuleMatchFlags;
|
||||
|
||||
|
||||
typedef struct {
|
||||
char *string;
|
||||
guint length;
|
||||
guint caseless : 1;
|
||||
} MooRuleAsciiString;
|
||||
|
||||
typedef struct {
|
||||
gpointer regex; /* EggRegex* */
|
||||
guint non_empty : 1;
|
||||
guint left_word_bndry : 1;
|
||||
guint right_word_bndry : 1;
|
||||
} MooRuleRegex;
|
||||
|
||||
typedef struct {
|
||||
char ch;
|
||||
guint caseless : 1;
|
||||
} MooRuleAsciiChar;
|
||||
|
||||
typedef struct {
|
||||
char str[3];
|
||||
} MooRuleAscii2Char;
|
||||
|
||||
typedef struct {
|
||||
char *chars;
|
||||
guint n_chars;
|
||||
} MooRuleAsciiAnyChar;
|
||||
|
||||
typedef struct {
|
||||
MooContext *ctx;
|
||||
} MooRuleInclude;
|
||||
|
||||
|
||||
struct _MooRule
|
||||
{
|
||||
MooRule* (*match) (MooRule *self,
|
||||
const MooRuleMatchData *data,
|
||||
MooRuleMatchResult *result,
|
||||
MooRuleMatchFlags flags);
|
||||
void (*destroy) (MooRule *self);
|
||||
|
||||
char *description;
|
||||
char *style;
|
||||
|
||||
MooContext *context;
|
||||
MooCtxSwitch exit;
|
||||
|
||||
gboolean include_eol;
|
||||
|
||||
MooRuleFlags flags;
|
||||
|
||||
MooRuleArray *child_rules;
|
||||
|
||||
union {
|
||||
MooRuleAsciiString str;
|
||||
MooRuleRegex regex;
|
||||
MooRuleAsciiChar _char;
|
||||
MooRuleAscii2Char _2char;
|
||||
MooRuleAsciiAnyChar anychar;
|
||||
MooRuleInclude incl;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
GType moo_lang_get_type (void) G_GNUC_CONST;
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* MooContext
|
||||
*/
|
||||
|
||||
void moo_context_add_rule (MooContext *ctx,
|
||||
MooRule *rule);
|
||||
void moo_context_set_eol_stay (MooContext *ctx);
|
||||
void moo_context_set_eol_pop (MooContext *ctx,
|
||||
guint num);
|
||||
void moo_context_set_eol_switch (MooContext *ctx,
|
||||
MooContext *target);
|
||||
#if 0
|
||||
void moo_context_set_eol_jump (MooContext *ctx,
|
||||
MooContext *target);
|
||||
#endif
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* MooLang
|
||||
*/
|
||||
|
||||
MooLang *moo_lang_new (struct _MooLangMgr *mgr,
|
||||
const char *name,
|
||||
const char *section,
|
||||
const char *version,
|
||||
const char *author);
|
||||
GType moo_lang_get_type (void) G_GNUC_CONST;
|
||||
|
||||
MooLang *moo_lang_ref (MooLang *lang);
|
||||
void moo_lang_unref (MooLang *lang);
|
||||
|
||||
MooContext *moo_lang_add_context (MooLang *lang,
|
||||
const char *name,
|
||||
const char *style);
|
||||
MooContext *moo_lang_get_context (MooLang *lang,
|
||||
const char *ctx_name);
|
||||
MooContext *moo_lang_get_default_context (MooLang *lang);
|
||||
void moo_lang_add_style (MooLang *lang,
|
||||
const char *name,
|
||||
const MooTextStyle *style);
|
||||
|
||||
char *moo_lang_id_from_name (const char *name);
|
||||
/* MOO_LANG_NONE if lang == NULL */
|
||||
const char *moo_lang_id (MooLang *lang);
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Auxiliary private methods
|
||||
*/
|
||||
|
||||
void _moo_lang_free (MooLang *lang);
|
||||
|
||||
void _moo_lang_scheme_changed (MooLang *lang);
|
||||
void _moo_lang_set_tag_style (MooLang *lang,
|
||||
GtkTextTag *tag,
|
||||
MooContext *ctx,
|
||||
MooRule *rule,
|
||||
MooTextStyleScheme *scheme);
|
||||
void _moo_style_set_tag_style (const MooTextStyle *style,
|
||||
GtkTextTag *tag);
|
||||
void _moo_lang_erase_tag_style (GtkTextTag *tag);
|
||||
|
||||
/* implemented in moohighlighter.c */
|
||||
GtkTextTag *_moo_text_iter_get_syntax_tag (const GtkTextIter *iter);
|
||||
/* result of these two must not be modified */
|
||||
GSList *moo_lang_get_extensions (MooLang *lang);
|
||||
GSList *moo_lang_get_mime_types (MooLang *lang);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
@ -42,40 +42,20 @@ static void moo_lang_mgr_finalize (GObject *object);
|
|||
/* MOO_TYPE_LANG_MGR */
|
||||
G_DEFINE_TYPE (MooLangMgr, moo_lang_mgr, G_TYPE_OBJECT)
|
||||
|
||||
enum {
|
||||
LANG_ADDED,
|
||||
LANG_REMOVED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
static void
|
||||
moo_lang_mgr_class_init (MooLangMgrClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = moo_lang_mgr_finalize;
|
||||
}
|
||||
|
||||
signals[LANG_ADDED] =
|
||||
g_signal_new ("lang-added",
|
||||
G_OBJECT_CLASS_TYPE (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (MooLangMgrClass, lang_added),
|
||||
NULL, NULL,
|
||||
_moo_marshal_VOID__STRING,
|
||||
G_TYPE_NONE, 1,
|
||||
G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||
|
||||
signals[LANG_REMOVED] =
|
||||
g_signal_new ("lang-removed",
|
||||
G_OBJECT_CLASS_TYPE (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (MooLangMgrClass, lang_removed),
|
||||
NULL, NULL,
|
||||
_moo_marshal_VOID__STRING,
|
||||
G_TYPE_NONE, 1,
|
||||
G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||
static void
|
||||
string_list_free (gpointer list)
|
||||
{
|
||||
g_slist_foreach (list, (GFunc) g_free, NULL);
|
||||
g_slist_free (list);
|
||||
}
|
||||
|
||||
|
||||
|
@ -89,6 +69,14 @@ moo_lang_mgr_init (MooLangMgr *mgr)
|
|||
mgr->active_scheme);
|
||||
mgr->langs = NULL;
|
||||
mgr->dirs_read = FALSE;
|
||||
|
||||
mgr->extensions = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
g_free, string_list_free);
|
||||
mgr->mime_types = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
g_free, string_list_free);
|
||||
|
||||
mgr->config = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
||||
_moo_lang_mgr_load_config (mgr);
|
||||
}
|
||||
|
||||
|
||||
|
@ -114,6 +102,11 @@ moo_lang_mgr_finalize (GObject *object)
|
|||
g_hash_table_destroy (mgr->schemes);
|
||||
mgr->active_scheme = NULL;
|
||||
|
||||
g_hash_table_destroy (mgr->mime_types);
|
||||
g_hash_table_destroy (mgr->extensions);
|
||||
|
||||
g_hash_table_destroy (mgr->config);
|
||||
|
||||
G_OBJECT_CLASS(moo_lang_mgr_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
@ -261,8 +254,8 @@ load_language_node (MooTextStyleScheme *scheme,
|
|||
|
||||
|
||||
void
|
||||
moo_lang_mgr_set_active_scheme (MooLangMgr *mgr,
|
||||
const char *name)
|
||||
_moo_lang_mgr_set_active_scheme (MooLangMgr *mgr,
|
||||
const char *name)
|
||||
{
|
||||
MooTextStyleScheme *scheme;
|
||||
|
||||
|
@ -286,7 +279,7 @@ moo_lang_mgr_choose_scheme (MooLangMgr *mgr,
|
|||
MooMarkupNode *node)
|
||||
{
|
||||
const char *name = moo_markup_get_prop (node, DEFAULT_SCHEME_PROP);
|
||||
moo_lang_mgr_set_active_scheme (mgr, name);
|
||||
_moo_lang_mgr_set_active_scheme (mgr, name);
|
||||
}
|
||||
|
||||
|
||||
|
@ -537,7 +530,7 @@ moo_lang_build_contexts (MooLang *lang,
|
|||
for (l = xml->syntax->contexts; l != NULL; l = l->next)
|
||||
{
|
||||
ContextXML *ctx_xml = l->data;
|
||||
MooContext *ctx = moo_lang_add_context (lang, ctx_xml->name, ctx_xml->style);
|
||||
MooContext *ctx = _moo_lang_add_context (lang, ctx_xml->name, ctx_xml->style);
|
||||
g_assert (ctx != NULL);
|
||||
}
|
||||
}
|
||||
|
@ -572,45 +565,55 @@ style_new_from_xml (StyleXML *xml)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
moo_lang_parse_mime_types (MooLang *lang,
|
||||
const char *mimetypes)
|
||||
static GSList *
|
||||
parse_mime_types (const char *mimetypes)
|
||||
{
|
||||
char *copy;
|
||||
GSList *list = NULL;
|
||||
char **pieces, **p;
|
||||
|
||||
g_return_if_fail (lang != NULL && mimetypes != NULL);
|
||||
if (!mimetypes || !mimetypes[0])
|
||||
return NULL;
|
||||
|
||||
pieces = g_strsplit (mimetypes, EXTENSION_SEPARATOR, 0);
|
||||
copy = g_strstrip (g_strdup (mimetypes));
|
||||
|
||||
if (!pieces)
|
||||
return;
|
||||
|
||||
for (p = pieces; *p; p++)
|
||||
if (**p)/*XXX*/
|
||||
lang->mime_types = g_slist_prepend (lang->mime_types, g_strdup (*p));
|
||||
|
||||
g_strfreev (pieces);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
moo_lang_parse_extensions (MooLang *lang,
|
||||
const char *extensions)
|
||||
{
|
||||
char **pieces, **p;
|
||||
|
||||
g_return_if_fail (lang != NULL && extensions != NULL);
|
||||
|
||||
pieces = g_strsplit (extensions, EXTENSION_SEPARATOR, 0);
|
||||
|
||||
if (!pieces)
|
||||
return;
|
||||
pieces = g_strsplit (copy, EXTENSION_SEPARATOR, 0);
|
||||
g_return_val_if_fail (pieces != NULL, NULL);
|
||||
|
||||
for (p = pieces; *p; p++)
|
||||
if (**p)
|
||||
lang->extensions = g_slist_prepend (lang->extensions, g_strdup (*p));
|
||||
list = g_slist_prepend (list, g_strdup (*p));
|
||||
|
||||
g_strfreev (pieces);
|
||||
g_free (copy);
|
||||
|
||||
return g_slist_reverse (list);
|
||||
}
|
||||
|
||||
|
||||
static GSList *
|
||||
parse_extensions (const char *extensions)
|
||||
{
|
||||
char *copy;
|
||||
GSList *list = NULL;
|
||||
char **pieces, **p;
|
||||
|
||||
if (!extensions || !extensions[0])
|
||||
return NULL;
|
||||
|
||||
copy = g_strstrip (g_strdup (extensions));
|
||||
|
||||
pieces = g_strsplit (copy, EXTENSION_SEPARATOR, 0);
|
||||
g_return_val_if_fail (pieces != NULL, NULL);
|
||||
|
||||
for (p = pieces; *p; p++)
|
||||
if (**p)
|
||||
list = g_slist_prepend (list, g_strdup (*p));
|
||||
|
||||
g_strfreev (pieces);
|
||||
g_free (copy);
|
||||
|
||||
return g_slist_reverse (list);
|
||||
}
|
||||
|
||||
|
||||
|
@ -628,15 +631,15 @@ moo_lang_finish_build (MooLang *lang,
|
|||
{
|
||||
StyleXML *style_xml = l->data;
|
||||
MooTextStyle *style = style_new_from_xml (style_xml);
|
||||
moo_lang_add_style (lang, style_xml->name, style);
|
||||
_moo_lang_add_style (lang, style_xml->name, style);
|
||||
moo_text_style_free (style);
|
||||
}
|
||||
}
|
||||
|
||||
if (xml->mimetypes)
|
||||
moo_lang_parse_mime_types (lang, xml->mimetypes);
|
||||
lang->mime_types = parse_mime_types (xml->mimetypes);
|
||||
if (xml->extensions)
|
||||
moo_lang_parse_extensions (lang, xml->extensions);
|
||||
lang->extensions = parse_extensions (xml->extensions);
|
||||
|
||||
if (xml->general)
|
||||
{
|
||||
|
@ -655,7 +658,7 @@ moo_lang_finish_build (MooLang *lang,
|
|||
MooContext *ctx, *switch_to;
|
||||
|
||||
ctx_xml = l->data;
|
||||
ctx = moo_lang_get_context (lang, ctx_xml->name);
|
||||
ctx = _moo_lang_get_context (lang, ctx_xml->name);
|
||||
g_assert (ctx != NULL);
|
||||
|
||||
for (rule_link = ctx_xml->rules; rule_link != NULL; rule_link = rule_link->next)
|
||||
|
@ -663,29 +666,29 @@ moo_lang_finish_build (MooLang *lang,
|
|||
RuleXML *rule_xml = rule_link->data;
|
||||
MooRule *rule = _moo_rule_new_from_xml (rule_xml, xml, lang);
|
||||
if (rule)
|
||||
moo_context_add_rule (ctx, rule);
|
||||
_moo_context_add_rule (ctx, rule);
|
||||
}
|
||||
|
||||
switch (ctx_xml->eol_switch_info.type)
|
||||
{
|
||||
case MOO_CONTEXT_STAY:
|
||||
moo_context_set_eol_stay (ctx);
|
||||
_moo_context_set_eol_stay (ctx);
|
||||
break;
|
||||
case MOO_CONTEXT_POP:
|
||||
moo_context_set_eol_pop (ctx, ctx_xml->eol_switch_info.num);
|
||||
_moo_context_set_eol_pop (ctx, ctx_xml->eol_switch_info.num);
|
||||
break;
|
||||
case MOO_CONTEXT_SWITCH:
|
||||
if (ctx_xml->eol_switch_info.ref.lang)
|
||||
switch_to = moo_lang_mgr_get_context (lang->mgr,
|
||||
ctx_xml->eol_switch_info.ref.lang,
|
||||
ctx_xml->eol_switch_info.ref.name);
|
||||
switch_to = _moo_lang_mgr_get_context (lang->mgr,
|
||||
ctx_xml->eol_switch_info.ref.lang,
|
||||
ctx_xml->eol_switch_info.ref.name);
|
||||
else
|
||||
switch_to = moo_lang_get_context (lang, ctx_xml->eol_switch_info.ref.name);
|
||||
switch_to = _moo_lang_get_context (lang, ctx_xml->eol_switch_info.ref.name);
|
||||
|
||||
if (!switch_to)
|
||||
g_critical ("%s: oops", G_STRLOC);
|
||||
else
|
||||
moo_context_set_eol_switch (ctx, switch_to);
|
||||
_moo_context_set_eol_switch (ctx, switch_to);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -732,9 +735,9 @@ moo_lang_mgr_read_dirs (MooLangMgr *mgr)
|
|||
for (l = lang_xml_list; l != NULL; l = l->next)
|
||||
{
|
||||
LangXML *xml = l->data;
|
||||
MooLang *lang = moo_lang_new (mgr, xml->name,
|
||||
xml->section, xml->version,
|
||||
xml->author);
|
||||
MooLang *lang = _moo_lang_new (mgr, xml->name,
|
||||
xml->section, xml->version,
|
||||
xml->author);
|
||||
lang->hidden = xml->hidden;
|
||||
moo_lang_build_contexts (lang, xml);
|
||||
}
|
||||
|
@ -757,16 +760,16 @@ out:
|
|||
|
||||
|
||||
MooContext*
|
||||
moo_lang_mgr_get_context (MooLangMgr *mgr,
|
||||
const char *lang_name,
|
||||
const char *ctx_name)
|
||||
_moo_lang_mgr_get_context (MooLangMgr *mgr,
|
||||
const char *lang_name,
|
||||
const char *ctx_name)
|
||||
{
|
||||
MooLang *lang;
|
||||
g_return_val_if_fail (MOO_IS_LANG_MGR (mgr), NULL);
|
||||
g_return_val_if_fail (lang_name && ctx_name, NULL);
|
||||
lang = moo_lang_mgr_get_lang (mgr, lang_name);
|
||||
g_return_val_if_fail (lang != NULL, NULL);
|
||||
return moo_lang_get_context (lang, ctx_name);
|
||||
return _moo_lang_get_context (lang, ctx_name);
|
||||
}
|
||||
|
||||
|
||||
|
@ -830,10 +833,12 @@ lang_mgr_get_lang_by_extension (MooLangMgr *mgr,
|
|||
|
||||
for (l = mgr->langs; !found && l != NULL; l = l->next)
|
||||
{
|
||||
GSList *g;
|
||||
lang = l->data;
|
||||
GSList *g, *extensions;
|
||||
|
||||
for (g = lang->extensions; !found && g != NULL; g = g->next)
|
||||
lang = l->data;
|
||||
extensions = moo_lang_get_extensions (lang);
|
||||
|
||||
for (g = extensions; !found && g != NULL; g = g->next)
|
||||
{
|
||||
if (g_pattern_match_simple ((char*) g->data, utf8_basename))
|
||||
{
|
||||
|
@ -993,7 +998,8 @@ moo_lang_mgr_get_lang_for_mime_type (MooLangMgr *mgr,
|
|||
{
|
||||
lang = l->data;
|
||||
|
||||
if (g_slist_find_custom (lang->mime_types, mime, (GCompareFunc) strcmp))
|
||||
if (g_slist_find_custom (moo_lang_get_mime_types (lang), mime,
|
||||
(GCompareFunc) strcmp))
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
|
@ -1007,7 +1013,8 @@ moo_lang_mgr_get_lang_for_mime_type (MooLangMgr *mgr,
|
|||
{
|
||||
lang = l->data;
|
||||
|
||||
if (g_slist_find_custom (lang->mime_types, mime, (GCompareFunc) check_mime_subclass))
|
||||
if (g_slist_find_custom (moo_lang_get_mime_types (lang), mime,
|
||||
(GCompareFunc) check_mime_subclass))
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
|
@ -1041,10 +1048,10 @@ moo_lang_get_style (MooLang *lang,
|
|||
|
||||
|
||||
MooTextStyle*
|
||||
moo_lang_mgr_get_style (MooLangMgr *mgr,
|
||||
const char *lang_name,
|
||||
const char *style_name,
|
||||
MooTextStyleScheme *scheme)
|
||||
_moo_lang_mgr_get_style (MooLangMgr *mgr,
|
||||
const char *lang_name,
|
||||
const char *style_name,
|
||||
MooTextStyleScheme *scheme)
|
||||
{
|
||||
const MooTextStyle *scheme_style = NULL;
|
||||
MooTextStyle *lang_style = NULL;
|
||||
|
@ -1121,3 +1128,357 @@ moo_lang_mgr_list_schemes (MooLangMgr *mgr)
|
|||
g_hash_table_foreach (mgr->schemes, (GHFunc) prepend_scheme, &list);
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
string_list_equal (GSList *list1,
|
||||
GSList *list2)
|
||||
{
|
||||
while (list1 && list2)
|
||||
{
|
||||
if (strcmp (list1->data, list2->data))
|
||||
return FALSE;
|
||||
|
||||
list1 = list1->next;
|
||||
list2 = list2->next;
|
||||
}
|
||||
|
||||
return !list1 && !list2;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
moo_lang_set_string (MooLang *lang,
|
||||
GSList *original,
|
||||
GSList *new,
|
||||
GHashTable *hash)
|
||||
{
|
||||
g_return_if_fail (lang != NULL);
|
||||
g_return_if_fail (MOO_IS_LANG_MGR (lang->mgr));
|
||||
|
||||
if (string_list_equal (original, new))
|
||||
{
|
||||
g_hash_table_remove (hash, lang->id);
|
||||
string_list_free (new);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_hash_table_insert (hash, g_strdup (lang->id), new);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_moo_lang_set_mime_types (MooLang *lang,
|
||||
const char *string)
|
||||
{
|
||||
g_return_if_fail (lang != NULL && MOO_IS_LANG_MGR (lang->mgr));
|
||||
moo_lang_set_string (lang, lang->mime_types,
|
||||
parse_mime_types (string),
|
||||
lang->mgr->mime_types);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_moo_lang_set_extensions (MooLang *lang,
|
||||
const char *string)
|
||||
{
|
||||
g_return_if_fail (lang != NULL && MOO_IS_LANG_MGR (lang->mgr));
|
||||
moo_lang_set_string (lang, lang->extensions,
|
||||
parse_extensions (string),
|
||||
lang->mgr->extensions);
|
||||
}
|
||||
|
||||
|
||||
GSList *
|
||||
moo_lang_get_extensions (MooLang *lang)
|
||||
{
|
||||
gpointer orig_key, value;
|
||||
|
||||
g_return_val_if_fail (lang != NULL && MOO_IS_LANG_MGR (lang->mgr), NULL);
|
||||
|
||||
if (g_hash_table_lookup_extended (lang->mgr->extensions, lang->id, &orig_key, &value))
|
||||
return value;
|
||||
else
|
||||
return lang->extensions;
|
||||
}
|
||||
|
||||
|
||||
GSList *
|
||||
moo_lang_get_mime_types (MooLang *lang)
|
||||
{
|
||||
gpointer orig_key, value;
|
||||
|
||||
g_return_val_if_fail (lang != NULL && MOO_IS_LANG_MGR (lang->mgr), NULL);
|
||||
|
||||
if (g_hash_table_lookup_extended (lang->mgr->mime_types, lang->id, &orig_key, &value))
|
||||
return value;
|
||||
else
|
||||
return lang->mime_types;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
_moo_lang_mgr_get_config (MooLangMgr *mgr,
|
||||
const char *lang_id)
|
||||
{
|
||||
g_return_val_if_fail (MOO_IS_LANG_MGR (mgr), NULL);
|
||||
|
||||
if (!lang_id)
|
||||
lang_id = MOO_LANG_NONE;
|
||||
|
||||
return g_hash_table_lookup (mgr->config, lang_id);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_moo_lang_mgr_update_config (MooLangMgr *mgr,
|
||||
MooEditConfig *config,
|
||||
const char *lang_id)
|
||||
{
|
||||
const char *lang_config;
|
||||
|
||||
g_return_if_fail (MOO_IS_LANG_MGR (mgr));
|
||||
g_return_if_fail (MOO_IS_EDIT_CONFIG (config));
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (config));
|
||||
|
||||
moo_edit_config_unset_by_source (config, MOO_EDIT_CONFIG_SOURCE_LANG);
|
||||
|
||||
lang_config = _moo_lang_mgr_get_config (mgr, lang_id);
|
||||
|
||||
if (lang_config)
|
||||
moo_edit_config_parse (config, lang_config,
|
||||
MOO_EDIT_CONFIG_SOURCE_LANG);
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (config));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_moo_lang_mgr_set_config (MooLangMgr *mgr,
|
||||
const char *lang_id,
|
||||
const char *config)
|
||||
{
|
||||
const char *old;
|
||||
char *norm = NULL;
|
||||
|
||||
g_return_if_fail (MOO_IS_LANG_MGR (mgr));
|
||||
|
||||
lang_id = lang_id ? lang_id : MOO_LANG_NONE;
|
||||
old = g_hash_table_lookup (mgr->config, lang_id);
|
||||
|
||||
if (config)
|
||||
{
|
||||
norm = g_strstrip (g_strdup (config));
|
||||
|
||||
if (!norm[0])
|
||||
{
|
||||
g_free (norm);
|
||||
norm = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!norm)
|
||||
g_hash_table_remove (mgr->config, lang_id);
|
||||
else
|
||||
g_hash_table_insert (mgr->config, g_strdup (lang_id), norm);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/* Loading and saving
|
||||
*/
|
||||
|
||||
#define ELEMENT_LANG_CONFIG MOO_EDIT_PREFS_PREFIX "/langs"
|
||||
#define ELEMENT_LANG "lang"
|
||||
#define ELEMENT_EXTENSIONS "extensions"
|
||||
#define ELEMENT_MIME_TYPES "mime-types"
|
||||
#define ELEMENT_CONFIG "config"
|
||||
#define PROP_LANG_ID "id"
|
||||
|
||||
static void
|
||||
load_lang_node (MooLangMgr *mgr,
|
||||
MooMarkupNode *lang_node)
|
||||
{
|
||||
const char *lang_id;
|
||||
MooMarkupNode *node;
|
||||
|
||||
lang_id = moo_markup_get_prop (lang_node, PROP_LANG_ID);
|
||||
g_return_if_fail (lang_id != NULL);
|
||||
|
||||
for (node = lang_node->children; node != NULL; node = node->next)
|
||||
{
|
||||
if (!MOO_MARKUP_IS_ELEMENT (node))
|
||||
continue;
|
||||
|
||||
if (!strcmp (node->name, ELEMENT_EXTENSIONS))
|
||||
{
|
||||
const char *string = moo_markup_get_content (node);
|
||||
GSList *list = parse_extensions (string);
|
||||
g_hash_table_insert (mgr->extensions, g_strdup (lang_id), list);
|
||||
}
|
||||
else if (!strcmp (node->name, ELEMENT_MIME_TYPES))
|
||||
{
|
||||
const char *string = moo_markup_get_content (node);
|
||||
GSList *list = parse_mime_types (string);
|
||||
g_hash_table_insert (mgr->mime_types, g_strdup (lang_id), list);
|
||||
}
|
||||
else if (!strcmp (node->name, ELEMENT_CONFIG))
|
||||
{
|
||||
const char *string = moo_markup_get_content (node);
|
||||
g_hash_table_insert (mgr->config, g_strdup (lang_id), g_strdup (string));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("%s: invalid node '%s'", G_STRLOC, node->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
moo_lang_mgr_set_default_config (MooLangMgr *mgr)
|
||||
{
|
||||
_moo_lang_mgr_set_config (mgr, "makefile", "use-tabs: true");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_moo_lang_mgr_load_config (MooLangMgr *mgr)
|
||||
{
|
||||
MooMarkupDoc *xml;
|
||||
MooMarkupNode *root, *node;
|
||||
|
||||
moo_lang_mgr_set_default_config (mgr);
|
||||
|
||||
xml = moo_prefs_get_markup ();
|
||||
g_return_if_fail (xml != NULL);
|
||||
|
||||
root = moo_markup_get_element (MOO_MARKUP_NODE (xml),
|
||||
ELEMENT_LANG_CONFIG);
|
||||
|
||||
if (!root)
|
||||
return;
|
||||
|
||||
for (node = root->children; node != NULL; node = node->next)
|
||||
{
|
||||
if (!MOO_MARKUP_IS_ELEMENT (node))
|
||||
continue;
|
||||
|
||||
if (strcmp (node->name, ELEMENT_LANG))
|
||||
{
|
||||
g_warning ("%s: invalid '%s' element", G_STRLOC, node->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
load_lang_node (mgr, node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static MooMarkupNode *
|
||||
create_lang_node (MooMarkupNode *root,
|
||||
MooMarkupNode *lang_node,
|
||||
const char *lang_id)
|
||||
{
|
||||
if (!lang_node)
|
||||
{
|
||||
lang_node = moo_markup_create_element (root, ELEMENT_LANG);
|
||||
moo_markup_set_prop (lang_node, PROP_LANG_ID, lang_id);
|
||||
}
|
||||
|
||||
return lang_node;
|
||||
}
|
||||
|
||||
static char *
|
||||
list_to_string (GSList *list)
|
||||
{
|
||||
GString *string = g_string_new (NULL);
|
||||
|
||||
while (list)
|
||||
{
|
||||
g_string_append (string, list->data);
|
||||
|
||||
if ((list = list->next))
|
||||
g_string_append_c (string, ';');
|
||||
}
|
||||
|
||||
return g_string_free (string, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
save_one_lang (MooMarkupNode *root,
|
||||
const char *lang_id,
|
||||
const char *config,
|
||||
GSList *extensions,
|
||||
gboolean save_extensions,
|
||||
GSList *mimetypes,
|
||||
gboolean save_mimetypes)
|
||||
{
|
||||
MooMarkupNode *lang_node = NULL;
|
||||
|
||||
if (save_extensions)
|
||||
{
|
||||
char *string = list_to_string (extensions);
|
||||
lang_node = create_lang_node (root, lang_node, lang_id);
|
||||
moo_markup_create_text_element (lang_node, ELEMENT_EXTENSIONS, string);
|
||||
g_free (string);
|
||||
}
|
||||
|
||||
if (save_mimetypes)
|
||||
{
|
||||
char *string = list_to_string (mimetypes);
|
||||
lang_node = create_lang_node (root, lang_node, lang_id);
|
||||
moo_markup_create_text_element (lang_node, ELEMENT_MIME_TYPES, string);
|
||||
g_free (string);
|
||||
}
|
||||
|
||||
if (config)
|
||||
{
|
||||
lang_node = create_lang_node (root, lang_node, lang_id);
|
||||
moo_markup_create_text_element (lang_node, ELEMENT_CONFIG, config);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_moo_lang_mgr_save_config (MooLangMgr *mgr)
|
||||
{
|
||||
MooMarkupDoc *xml;
|
||||
MooMarkupNode *root;
|
||||
GSList *l;
|
||||
|
||||
g_return_if_fail (MOO_IS_LANG_MGR (mgr));
|
||||
|
||||
xml = moo_prefs_get_markup ();
|
||||
g_return_if_fail (xml != NULL);
|
||||
|
||||
root = moo_markup_get_element (MOO_MARKUP_NODE (xml), ELEMENT_LANG_CONFIG);
|
||||
|
||||
if (root)
|
||||
moo_markup_delete_node (root);
|
||||
|
||||
root = NULL;
|
||||
|
||||
for (l = mgr->langs; l != NULL; l = l->next)
|
||||
{
|
||||
MooLang *lang = l->data;
|
||||
const char *config;
|
||||
GSList *extensions, *mimetypes;
|
||||
|
||||
config = g_hash_table_lookup (mgr->config, lang->id);
|
||||
extensions = moo_lang_get_extensions (lang);
|
||||
mimetypes = moo_lang_get_mime_types (lang);
|
||||
|
||||
if (config || extensions != lang->extensions || mimetypes != lang->mime_types)
|
||||
{
|
||||
if (!root)
|
||||
root = moo_markup_create_element (MOO_MARKUP_NODE (xml), ELEMENT_LANG_CONFIG);
|
||||
g_return_if_fail (root != NULL);
|
||||
|
||||
save_one_lang (root, lang->id, config,
|
||||
extensions, extensions != lang->extensions,
|
||||
mimetypes, mimetypes != lang->mime_types);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; coding: utf-8 -*-
|
||||
*
|
||||
/*
|
||||
* moolangmgr.h
|
||||
*
|
||||
* Copyright (C) 2004-2006 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||
|
@ -32,29 +31,6 @@ G_BEGIN_DECLS
|
|||
|
||||
|
||||
typedef struct _MooLangMgr MooLangMgr;
|
||||
typedef struct _MooLangMgrClass MooLangMgrClass;
|
||||
|
||||
struct _MooLangMgr {
|
||||
GObject base;
|
||||
|
||||
GSList *lang_dirs;
|
||||
GSList *langs;
|
||||
GHashTable *lang_names;
|
||||
GHashTable *schemes;
|
||||
MooTextStyleScheme *active_scheme;
|
||||
guint dirs_read : 1;
|
||||
};
|
||||
|
||||
struct _MooLangMgrClass
|
||||
{
|
||||
GObjectClass base_class;
|
||||
|
||||
void (*lang_added) (MooLangMgr *mgr,
|
||||
const char *lang_name);
|
||||
void (*lang_removed) (MooLangMgr *mgr,
|
||||
const char *lang_name);
|
||||
};
|
||||
|
||||
|
||||
GType moo_lang_mgr_get_type (void) G_GNUC_CONST;
|
||||
|
||||
|
@ -73,24 +49,12 @@ MooLang *moo_lang_mgr_get_lang_for_mime_type (MooLangMgr *mgr,
|
|||
const char *mime_type);
|
||||
MooLang *moo_lang_mgr_get_lang (MooLangMgr *mgr,
|
||||
const char *name);
|
||||
MooContext *moo_lang_mgr_get_context (MooLangMgr *mgr,
|
||||
const char *lang_name,
|
||||
const char *ctx_name);
|
||||
|
||||
GSList *moo_lang_mgr_list_schemes (MooLangMgr *mgr);
|
||||
|
||||
void moo_lang_mgr_read_dirs (MooLangMgr *mgr);
|
||||
|
||||
MooTextStyle *moo_lang_mgr_get_style (MooLangMgr *mgr,
|
||||
const char *lang_name, /* default style if NULL */
|
||||
const char *style_name,
|
||||
MooTextStyleScheme *scheme);
|
||||
MooTextStyleScheme *moo_lang_mgr_get_active_scheme (MooLangMgr *mgr);
|
||||
void moo_lang_mgr_set_active_scheme (MooLangMgr *mgr,
|
||||
const char *scheme_name);
|
||||
|
||||
void _moo_lang_mgr_add_lang (MooLangMgr *mgr,
|
||||
MooLang *lang);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <gtk/gtktextbuffer.h>
|
||||
#include "mooedit/mootextbtree.h"
|
||||
#include "mooedit/mootextbuffer.h"
|
||||
#include "mooedit/moolang-private.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#endif
|
||||
|
||||
#define PLUGIN_PREFS_ENABLED "enabled"
|
||||
#define LANG_ID(lang) ((lang) ? (lang)->id : "none")
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
@ -453,7 +452,7 @@ plugin_attach_doc (MooPlugin *plugin,
|
|||
const char *id;
|
||||
|
||||
lang = moo_text_view_get_lang (MOO_TEXT_VIEW (doc));
|
||||
id = LANG_ID (lang);
|
||||
id = moo_lang_id (lang);
|
||||
|
||||
if (!g_hash_table_lookup (plugin->langs, id))
|
||||
return;
|
||||
|
@ -1007,7 +1006,7 @@ doc_lang_changed (MooEdit *doc)
|
|||
|
||||
window = moo_edit_get_window (doc);
|
||||
lang = moo_text_view_get_lang (MOO_TEXT_VIEW (doc));
|
||||
id = LANG_ID (lang);
|
||||
id = moo_lang_id (lang);
|
||||
|
||||
for (l = plugin_store->list; l != NULL; l = l->next)
|
||||
{
|
||||
|
|
|
@ -465,7 +465,7 @@ _completion_complete (CmplPlugin *plugin,
|
|||
|
||||
lang = moo_text_view_get_lang (MOO_TEXT_VIEW (doc));
|
||||
|
||||
data = cmpl_plugin_load_data (plugin, lang ? lang->id : NULL);
|
||||
data = cmpl_plugin_load_data (plugin, lang ? moo_lang_id (lang) : NULL);
|
||||
g_return_if_fail (data != NULL);
|
||||
|
||||
if (data->cmpl)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE language SYSTEM "language.dtd">
|
||||
<language name="ChangeLog" version="1.04"
|
||||
section="Other" extensions="ChangeLog;changelog"
|
||||
section="Others" extensions="ChangeLog;changelog"
|
||||
author="Dominik Haumann (dhdev@gmx.de)" license="LGPL">
|
||||
|
||||
<syntax>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"FALSE", "NO", "0" mean false.
|
||||
-->
|
||||
<!ENTITY % boolean "true|false|TRUE|FALSE|True|False|0|1">
|
||||
|
||||
<!ENTITY % section "Others|Sources|Markup|Scripts|Scientific">
|
||||
<!ENTITY % def_styles "Normal|Keyword|DataType|Decimal|BaseN|Float|Char|String|Comment|Others|Alert|Function|RegionMarker|Error">
|
||||
|
||||
<!-- rule_type -->
|
||||
|
@ -16,7 +16,7 @@
|
|||
<!ATTLIST language
|
||||
name CDATA #REQUIRED
|
||||
hidden (%boolean;) #IMPLIED
|
||||
section CDATA #IMPLIED
|
||||
section (%section;) #IMPLIED
|
||||
extensions CDATA #IMPLIED
|
||||
mimetypes CDATA #IMPLIED
|
||||
version CDATA #IMPLIED
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<!ENTITY entref "&(#[0-9]+|#[xX][0-9A-Fa-f]+|&name;);">
|
||||
]>
|
||||
<language name="XML" version="1.96" kateversion="2.4" section="Markup"
|
||||
extensions="*.docbook;*.xml;*.rc;*.daml;*.rdf" mimetypes="text/xml;text/book;text/daml;text/rdf"
|
||||
extensions="*.docbook;*.xml;*.daml;*.rdf" mimetypes="text/xml;text/book;text/daml;text/rdf"
|
||||
author="Wilbert Berendsen (wilbert@kde.nl)" license="LGPL">
|
||||
|
||||
<syntax>
|
||||
|
|
|
@ -99,20 +99,20 @@
|
|||
(gtype-id "MOO_TYPE_LANG")
|
||||
(copy-func "moo_lang_ref")
|
||||
(release-func "moo_lang_unref")
|
||||
(fields
|
||||
'("char*" "id")
|
||||
'("char*" "display_name")
|
||||
'("char*" "section")
|
||||
'("char*" "version")
|
||||
'("char*" "author")
|
||||
'("GSList*" "mime_types")
|
||||
'("GSList*" "extensions")
|
||||
'("char*" "brackets")
|
||||
'("char*" "line_comment")
|
||||
'("char*" "block_comment_start")
|
||||
'("char*" "block_comment_end")
|
||||
'("char*" "sample")
|
||||
)
|
||||
;; (fields
|
||||
;; '("char*" "id")
|
||||
;; '("char*" "display_name")
|
||||
;; '("char*" "section")
|
||||
;; '("char*" "version")
|
||||
;; '("char*" "author")
|
||||
;; '("GSList*" "mime_types")
|
||||
;; '("GSList*" "extensions")
|
||||
;; '("char*" "brackets")
|
||||
;; '("char*" "line_comment")
|
||||
;; '("char*" "block_comment_start")
|
||||
;; '("char*" "block_comment_end")
|
||||
;; '("char*" "sample")
|
||||
;; )
|
||||
)
|
||||
|
||||
(define-boxed TextStyle
|
||||
|
|
|
@ -23,10 +23,17 @@
|
|||
#define MOO_TREE_HELPER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MOO_TYPE_TREE_HELPER, MooTreeHelperClass))
|
||||
|
||||
|
||||
typedef enum {
|
||||
TREE_VIEW,
|
||||
COMBO_BOX
|
||||
} WidgetType;
|
||||
|
||||
struct _MooTreeHelper {
|
||||
GtkObject parent;
|
||||
|
||||
GtkTreeView *treeview;
|
||||
WidgetType type;
|
||||
gpointer widget;
|
||||
|
||||
GtkWidget *new_btn;
|
||||
GtkWidget *delete_btn;
|
||||
GtkWidget *up_btn;
|
||||
|
@ -36,16 +43,17 @@ struct _MooTreeHelper {
|
|||
|
||||
GType _moo_tree_helper_get_type (void) G_GNUC_CONST;
|
||||
|
||||
static void moo_tree_helper_new_row (MooTreeHelper *helper);
|
||||
static void moo_tree_helper_delete_row (MooTreeHelper *helper);
|
||||
static void moo_tree_helper_row_up (MooTreeHelper *helper);
|
||||
static void moo_tree_helper_row_down (MooTreeHelper *helper);
|
||||
static void moo_tree_helper_update_widgets (MooTreeHelper *helper,
|
||||
GtkTreeModel *model,
|
||||
GtkTreePath *path);
|
||||
static void moo_tree_helper_update_model (MooTreeHelper *helper,
|
||||
GtkTreeModel *model,
|
||||
GtkTreePath *path);
|
||||
static void moo_tree_helper_new_row (MooTreeHelper *helper);
|
||||
static void moo_tree_helper_delete_row (MooTreeHelper *helper);
|
||||
static void moo_tree_helper_row_up (MooTreeHelper *helper);
|
||||
static void moo_tree_helper_row_down (MooTreeHelper *helper);
|
||||
static void moo_tree_helper_real_update_widgets (MooTreeHelper *helper,
|
||||
GtkTreeModel *model,
|
||||
GtkTreePath *path);
|
||||
static GtkTreeModel *moo_tree_helper_get_model (MooTreeHelper *helper);
|
||||
static gboolean moo_tree_helper_get_selected (MooTreeHelper *helper,
|
||||
GtkTreeModel **model,
|
||||
GtkTreeIter *iter);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (MooTreeHelper, _moo_tree_helper, GTK_TYPE_OBJECT)
|
||||
|
@ -64,8 +72,8 @@ static guint tree_signals[TREE_NUM_SIGNALS];
|
|||
|
||||
|
||||
static void
|
||||
selection_changed (GtkTreeSelection *selection,
|
||||
MooTreeHelper *helper)
|
||||
tree_selection_changed (GtkTreeSelection *selection,
|
||||
MooTreeHelper *helper)
|
||||
{
|
||||
GtkTreeRowReference *old_row;
|
||||
GtkTreeModel *model;
|
||||
|
@ -103,7 +111,7 @@ selection_changed (GtkTreeSelection *selection,
|
|||
if (old_path)
|
||||
moo_tree_helper_update_model (helper, model, old_path);
|
||||
|
||||
moo_tree_helper_update_widgets (helper, model, path);
|
||||
moo_tree_helper_real_update_widgets (helper, model, path);
|
||||
|
||||
if (path)
|
||||
{
|
||||
|
@ -122,23 +130,96 @@ selection_changed (GtkTreeSelection *selection,
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
combo_changed (GtkComboBox *combo,
|
||||
MooTreeHelper *helper)
|
||||
{
|
||||
GtkTreeRowReference *old_row;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
GtkTreePath *path, *old_path;
|
||||
|
||||
g_return_if_fail (MOO_IS_TREE_HELPER (helper));
|
||||
g_return_if_fail (combo == helper->widget);
|
||||
|
||||
old_row = g_object_get_data (G_OBJECT (combo), "moo-tree-helper-current-row");
|
||||
old_path = old_row ? gtk_tree_row_reference_get_path (old_row) : NULL;
|
||||
|
||||
if (old_row && !old_path)
|
||||
{
|
||||
g_object_set_data (G_OBJECT (combo), "moo-tree-helper-current-row", NULL);
|
||||
old_row = NULL;
|
||||
}
|
||||
|
||||
if (moo_tree_helper_get_selected (helper, &model, &iter))
|
||||
{
|
||||
path = gtk_tree_model_get_path (model, &iter);
|
||||
|
||||
if (old_path && !gtk_tree_path_compare (old_path, path))
|
||||
{
|
||||
gtk_tree_path_free (old_path);
|
||||
gtk_tree_path_free (path);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!old_path)
|
||||
return;
|
||||
|
||||
path = NULL;
|
||||
}
|
||||
|
||||
if (old_path)
|
||||
moo_tree_helper_update_model (helper, model, old_path);
|
||||
|
||||
moo_tree_helper_real_update_widgets (helper, model, path);
|
||||
|
||||
if (path)
|
||||
{
|
||||
GtkTreeRowReference *row;
|
||||
row = gtk_tree_row_reference_new (model, path);
|
||||
g_object_set_data_full (G_OBJECT (combo), "moo-tree-helper-current-row", row,
|
||||
(GDestroyNotify) gtk_tree_row_reference_free);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_object_set_data (G_OBJECT (combo), "moo-tree-helper-current-row", NULL);
|
||||
}
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
gtk_tree_path_free (old_path);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
moo_tree_helper_destroy (GtkObject *object)
|
||||
{
|
||||
MooTreeHelper *helper = MOO_TREE_HELPER (object);
|
||||
|
||||
if (helper->treeview)
|
||||
if (helper->widget)
|
||||
{
|
||||
GtkTreeSelection *selection;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (helper->treeview,
|
||||
g_signal_handlers_disconnect_by_func (helper->widget,
|
||||
(gpointer) gtk_object_destroy,
|
||||
helper);
|
||||
|
||||
selection = gtk_tree_view_get_selection (helper->treeview);
|
||||
g_signal_handlers_disconnect_by_func (selection,
|
||||
(gpointer) selection_changed,
|
||||
helper);
|
||||
switch (helper->type)
|
||||
{
|
||||
case TREE_VIEW:
|
||||
selection = gtk_tree_view_get_selection (helper->widget);
|
||||
g_signal_handlers_disconnect_by_func (selection,
|
||||
(gpointer) tree_selection_changed,
|
||||
helper);
|
||||
break;
|
||||
|
||||
case COMBO_BOX:
|
||||
g_signal_handlers_disconnect_by_func (helper->widget,
|
||||
(gpointer) combo_changed,
|
||||
helper);
|
||||
break;
|
||||
}
|
||||
|
||||
if (helper->new_btn)
|
||||
g_signal_handlers_disconnect_by_func (helper->new_btn,
|
||||
|
@ -157,7 +238,7 @@ moo_tree_helper_destroy (GtkObject *object)
|
|||
(gpointer) moo_tree_helper_row_down,
|
||||
helper);
|
||||
|
||||
helper->treeview = NULL;
|
||||
helper->widget = NULL;
|
||||
}
|
||||
|
||||
GTK_OBJECT_CLASS (_moo_tree_helper_parent_class)->destroy (object);
|
||||
|
@ -246,10 +327,25 @@ moo_tree_view_select_first (GtkTreeView *tree_view)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
moo_combo_box_select_first (GtkComboBox *combo)
|
||||
{
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
|
||||
g_return_if_fail (GTK_IS_COMBO_BOX (combo));
|
||||
|
||||
model = gtk_combo_box_get_model (combo);
|
||||
|
||||
if (gtk_tree_model_get_iter_first (model, &iter))
|
||||
gtk_combo_box_set_active_iter (combo, &iter);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
moo_tree_helper_update_widgets (MooTreeHelper *helper,
|
||||
GtkTreeModel *model,
|
||||
GtkTreePath *path)
|
||||
moo_tree_helper_real_update_widgets (MooTreeHelper *helper,
|
||||
GtkTreeModel *model,
|
||||
GtkTreePath *path)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
|
||||
|
@ -289,7 +385,7 @@ moo_tree_helper_update_widgets (MooTreeHelper *helper,
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
void
|
||||
moo_tree_helper_update_model (MooTreeHelper *helper,
|
||||
GtkTreeModel *model,
|
||||
GtkTreePath *path)
|
||||
|
@ -297,16 +393,14 @@ moo_tree_helper_update_model (MooTreeHelper *helper,
|
|||
GtkTreePath *freeme = NULL;
|
||||
GtkTreeIter iter;
|
||||
|
||||
g_return_if_fail (MOO_IS_TREE_HELPER (helper));
|
||||
g_return_if_fail (!model || GTK_IS_TREE_MODEL (model));
|
||||
|
||||
if (!model)
|
||||
model = gtk_tree_view_get_model (helper->treeview);
|
||||
model = moo_tree_helper_get_model (helper);
|
||||
|
||||
if (!path)
|
||||
{
|
||||
GtkTreeSelection *selection = gtk_tree_view_get_selection (helper->treeview);
|
||||
|
||||
if (gtk_tree_selection_get_selected (selection, NULL, &iter))
|
||||
path = freeme = gtk_tree_model_get_path (model, &iter);
|
||||
}
|
||||
if (!path && moo_tree_helper_get_selected (helper, NULL, &iter))
|
||||
path = freeme = gtk_tree_model_get_path (model, &iter);
|
||||
|
||||
if (path)
|
||||
{
|
||||
|
@ -319,6 +413,44 @@ moo_tree_helper_update_model (MooTreeHelper *helper,
|
|||
}
|
||||
|
||||
|
||||
static GtkTreeModel *
|
||||
moo_tree_helper_get_model (MooTreeHelper *helper)
|
||||
{
|
||||
switch (helper->type)
|
||||
{
|
||||
case TREE_VIEW:
|
||||
return gtk_tree_view_get_model (helper->widget);
|
||||
case COMBO_BOX:
|
||||
return gtk_combo_box_get_model (helper->widget);
|
||||
}
|
||||
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
moo_tree_helper_get_selected (MooTreeHelper *helper,
|
||||
GtkTreeModel **model,
|
||||
GtkTreeIter *iter)
|
||||
{
|
||||
GtkTreeSelection *selection;
|
||||
|
||||
switch (helper->type)
|
||||
{
|
||||
case TREE_VIEW:
|
||||
selection = gtk_tree_view_get_selection (helper->widget);
|
||||
return gtk_tree_selection_get_selected (selection, model, iter);
|
||||
|
||||
case COMBO_BOX:
|
||||
if (model)
|
||||
*model = gtk_combo_box_get_model (helper->widget);
|
||||
return gtk_combo_box_get_active_iter (helper->widget, iter);
|
||||
}
|
||||
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
iter_get_index (GtkTreeModel *model,
|
||||
GtkTreeIter *iter)
|
||||
|
@ -348,7 +480,9 @@ moo_tree_helper_new_row (MooTreeHelper *helper)
|
|||
int index;
|
||||
gboolean result;
|
||||
|
||||
selection = gtk_tree_view_get_selection (helper->treeview);
|
||||
g_return_if_fail (helper->type == TREE_VIEW);
|
||||
|
||||
selection = gtk_tree_view_get_selection (helper->widget);
|
||||
|
||||
if (!gtk_tree_selection_get_selected (selection, &model, &iter))
|
||||
index = gtk_tree_model_iter_n_children (model, NULL);
|
||||
|
@ -375,7 +509,9 @@ moo_tree_helper_delete_row (MooTreeHelper *helper)
|
|||
GtkTreePath *path;
|
||||
gboolean result;
|
||||
|
||||
selection = gtk_tree_view_get_selection (helper->treeview);
|
||||
g_return_if_fail (helper->type == TREE_VIEW);
|
||||
|
||||
selection = gtk_tree_view_get_selection (helper->widget);
|
||||
|
||||
if (!gtk_tree_selection_get_selected (selection, &model, &iter))
|
||||
g_return_if_reached ();
|
||||
|
@ -387,6 +523,8 @@ moo_tree_helper_delete_row (MooTreeHelper *helper)
|
|||
if (result && (gtk_tree_model_get_iter (model, &iter, path) ||
|
||||
(gtk_tree_path_prev (path) && gtk_tree_model_get_iter (model, &iter, path))))
|
||||
gtk_tree_selection_select_iter (selection, &iter);
|
||||
else
|
||||
moo_tree_helper_update_widgets (helper);
|
||||
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
|
@ -402,7 +540,9 @@ moo_tree_helper_row_move (MooTreeHelper *helper,
|
|||
GtkTreeSelection *selection;
|
||||
gboolean result;
|
||||
|
||||
selection = gtk_tree_view_get_selection (helper->treeview);
|
||||
g_return_if_fail (helper->type == TREE_VIEW);
|
||||
|
||||
selection = gtk_tree_view_get_selection (helper->widget);
|
||||
|
||||
if (!gtk_tree_selection_get_selected (selection, &model, &iter))
|
||||
g_return_if_reached ();
|
||||
|
@ -418,7 +558,7 @@ moo_tree_helper_row_move (MooTreeHelper *helper,
|
|||
g_signal_emit (helper, tree_signals[MOVE_ROW], 0, model, path, new_path, &result);
|
||||
|
||||
if (result)
|
||||
moo_tree_helper_update_widgets (helper, model, new_path);
|
||||
moo_tree_helper_real_update_widgets (helper, model, new_path);
|
||||
|
||||
gtk_tree_path_free (new_path);
|
||||
gtk_tree_path_free (path);
|
||||
|
@ -447,7 +587,7 @@ _moo_tree_helper_init (G_GNUC_UNUSED MooTreeHelper *helper)
|
|||
|
||||
static void
|
||||
moo_tree_helper_connect (MooTreeHelper *helper,
|
||||
GtkWidget *tree_view,
|
||||
GtkWidget *widget,
|
||||
GtkWidget *new_btn,
|
||||
GtkWidget *delete_btn,
|
||||
GtkWidget *up_btn,
|
||||
|
@ -456,23 +596,40 @@ moo_tree_helper_connect (MooTreeHelper *helper,
|
|||
GtkTreeSelection *selection;
|
||||
|
||||
g_return_if_fail (MOO_IS_TREE_HELPER (helper));
|
||||
g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
|
||||
g_return_if_fail (helper->treeview == NULL);
|
||||
g_return_if_fail (GTK_IS_TREE_VIEW (widget) || GTK_IS_COMBO_BOX (widget));
|
||||
g_return_if_fail (helper->widget == NULL);
|
||||
|
||||
helper->widget = widget;
|
||||
|
||||
if (GTK_IS_TREE_VIEW (widget))
|
||||
helper->type = TREE_VIEW;
|
||||
else
|
||||
helper->type = COMBO_BOX;
|
||||
|
||||
helper->treeview = GTK_TREE_VIEW (tree_view);
|
||||
helper->new_btn = new_btn;
|
||||
helper->delete_btn = delete_btn;
|
||||
helper->up_btn = up_btn;
|
||||
helper->down_btn = down_btn;
|
||||
|
||||
g_signal_connect_swapped (tree_view, "destroy",
|
||||
g_signal_connect_swapped (widget, "destroy",
|
||||
G_CALLBACK (gtk_object_destroy),
|
||||
helper);
|
||||
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
|
||||
g_signal_connect (selection, "changed",
|
||||
G_CALLBACK (selection_changed),
|
||||
helper);
|
||||
switch (helper->type)
|
||||
{
|
||||
case TREE_VIEW:
|
||||
selection = gtk_tree_view_get_selection (helper->widget);
|
||||
g_signal_connect (selection, "changed",
|
||||
G_CALLBACK (tree_selection_changed),
|
||||
helper);
|
||||
break;
|
||||
|
||||
case COMBO_BOX:
|
||||
g_signal_connect (widget, "changed",
|
||||
G_CALLBACK (combo_changed),
|
||||
helper);
|
||||
break;
|
||||
}
|
||||
|
||||
if (new_btn)
|
||||
g_signal_connect_swapped (new_btn, "clicked",
|
||||
|
@ -493,6 +650,43 @@ moo_tree_helper_connect (MooTreeHelper *helper,
|
|||
}
|
||||
|
||||
|
||||
MooTreeHelper *
|
||||
moo_tree_helper_new (GtkWidget *widget)
|
||||
{
|
||||
MooTreeHelper *helper;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_TREE_VIEW (widget) || GTK_IS_COMBO_BOX (widget), NULL);
|
||||
|
||||
helper = g_object_new (MOO_TYPE_TREE_HELPER, NULL);
|
||||
gtk_object_sink (g_object_ref (helper));
|
||||
|
||||
moo_tree_helper_connect (helper, widget, NULL, NULL, NULL, NULL);
|
||||
|
||||
return helper;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
moo_tree_helper_update_widgets (MooTreeHelper *helper)
|
||||
{
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
|
||||
g_return_if_fail (MOO_IS_TREE_HELPER (helper));
|
||||
|
||||
if (moo_tree_helper_get_selected (helper, &model, &iter))
|
||||
{
|
||||
GtkTreePath *path = gtk_tree_model_get_path (model, &iter);
|
||||
moo_tree_helper_real_update_widgets (MOO_TREE_HELPER (helper), model, path);
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
else
|
||||
{
|
||||
moo_tree_helper_real_update_widgets (MOO_TREE_HELPER (helper), NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* MooConfigHelper
|
||||
*/
|
||||
|
@ -803,7 +997,7 @@ button_toggled (MooTreeHelper *helper,
|
|||
WidgetInfo *info;
|
||||
GtkTreeSelection *selection;
|
||||
|
||||
selection = gtk_tree_view_get_selection (helper->treeview);
|
||||
selection = gtk_tree_view_get_selection (helper->widget);
|
||||
|
||||
if (!gtk_tree_selection_get_selected (selection, &model, &iter))
|
||||
return;
|
||||
|
@ -830,7 +1024,7 @@ entry_changed (MooTreeHelper *helper,
|
|||
WidgetInfo *info;
|
||||
GtkTreeSelection *selection;
|
||||
|
||||
selection = gtk_tree_view_get_selection (helper->treeview);
|
||||
selection = gtk_tree_view_get_selection (helper->widget);
|
||||
|
||||
if (!gtk_tree_selection_get_selected (selection, &model, &iter))
|
||||
return;
|
||||
|
@ -1092,29 +1286,3 @@ moo_config_helper_update_model (MooConfigHelper *helper,
|
|||
g_return_if_fail (MOO_IS_CONFIG_HELPER (helper));
|
||||
moo_tree_helper_update_model (MOO_TREE_HELPER (helper), model, path);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
moo_config_helper_update_widgets (MooConfigHelper *helper)
|
||||
{
|
||||
GtkTreeView *treeview;
|
||||
GtkTreeSelection *selection;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
|
||||
g_return_if_fail (MOO_IS_CONFIG_HELPER (helper));
|
||||
|
||||
treeview = MOO_TREE_HELPER (helper)->treeview;
|
||||
selection = gtk_tree_view_get_selection (treeview);
|
||||
|
||||
if (gtk_tree_selection_get_selected (selection, &model, &iter))
|
||||
{
|
||||
GtkTreePath *path = gtk_tree_model_get_path (model, &iter);
|
||||
moo_tree_helper_update_widgets (MOO_TREE_HELPER (helper), model, path);
|
||||
gtk_tree_path_free (path);
|
||||
}
|
||||
else
|
||||
{
|
||||
moo_tree_helper_update_widgets (MOO_TREE_HELPER (helper), model, NULL);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,6 +64,12 @@ struct _MooConfigHelperClass {
|
|||
};
|
||||
|
||||
|
||||
MooTreeHelper *moo_tree_helper_new (GtkWidget *treeview_or_combo);
|
||||
void moo_tree_helper_update_model (MooTreeHelper *helper,
|
||||
GtkTreeModel *model,
|
||||
GtkTreePath *path);
|
||||
void moo_tree_helper_update_widgets (MooTreeHelper *helper);
|
||||
|
||||
MooConfigHelper *moo_config_helper_new (GtkWidget *tree_view,
|
||||
GtkWidget *new_btn,
|
||||
GtkWidget *delete_btn,
|
||||
|
@ -81,6 +87,7 @@ void moo_config_helper_update_widgets (MooConfigHelper *helper)
|
|||
|
||||
|
||||
void moo_tree_view_select_first (GtkTreeView *tree_view);
|
||||
void moo_combo_box_select_first (GtkComboBox *combo);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
|
Loading…
Reference in New Issue