Added per-language settings in Preferences dialog

master
Yevgen Muntyan 2006-05-04 01:40:54 -05:00
parent ab006bdeaa
commit 929f17f8c1
26 changed files with 1704 additions and 766 deletions

View File

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

View File

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

View File

@ -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);
/***********************************************************************/

View File

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

View File

@ -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);
}

View File

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

View File

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

View File

@ -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 ();
}

View File

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

View File

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

View File

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

View File

@ -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__ */

View File

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

View File

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

View File

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

View File

@ -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);
}
}
}

View File

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

View File

@ -21,6 +21,7 @@
#include <gtk/gtktextbuffer.h>
#include "mooedit/mootextbtree.h"
#include "mooedit/mootextbuffer.h"
#include "mooedit/moolang-private.h"
G_BEGIN_DECLS

View File

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

View File

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

View File

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

View File

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

View File

@ -5,7 +5,7 @@
<!ENTITY entref "&amp;(#[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>

View File

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

View File

@ -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);
}
}

View File

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