r1284@localhost: muntyan | 2005-12-07 20:15:15 -0600

MooEditConfig
master
Yevgen Muntyan 2005-12-08 08:53:46 +00:00
parent 4acff19405
commit 818d361135
15 changed files with 1243 additions and 846 deletions

View File

@ -24,7 +24,7 @@
</ignoreparts>
<projectdirectory>.</projectdirectory>
<absoluteprojectpath>false</absoluteprojectpath>
<description></description>
<description/>
<secondaryLanguages>
<language>C</language>
</secondaryLanguages>
@ -39,7 +39,7 @@
<mainprogram>./medit</mainprogram>
<directoryradio>executable</directoryradio>
<customdirectory>/</customdirectory>
<programargs></programargs>
<programargs/>
<terminal>false</terminal>
<autocompile>false</autocompile>
<envvars/>
@ -192,18 +192,18 @@
<abortonerror>true</abortonerror>
<numberofjobs>1</numberofjobs>
<dontact>false</dontact>
<makebin></makebin>
<makebin/>
<prio>0</prio>
</make>
</kdevautoproject>
<kdevdebugger>
<general>
<dbgshell></dbgshell>
<dbgshell/>
<programargs>--g-fatal-warnings </programargs>
<gdbpath></gdbpath>
<configGdbScript></configGdbScript>
<runShellScript></runShellScript>
<runGdbScript></runGdbScript>
<gdbpath/>
<configGdbScript/>
<runShellScript/>
<runGdbScript/>
<breakonloadinglibs>true</breakonloadinglibs>
<separatetty>false</separatetty>
<floatingtoolbar>true</floatingtoolbar>
@ -304,7 +304,7 @@
</codecompletion>
<references/>
<creategettersetter>
<prefixGet></prefixGet>
<prefixGet/>
<prefixSet>set</prefixSet>
<prefixVariable>m_,_</prefixVariable>
<parameterName>theValue</parameterName>

View File

@ -116,7 +116,7 @@ mooedit_include_headers = \
mooedit_noinst_headers = \
$(mooedit)/gtksourceiter.h \
$(mooedit)/mooedit-private.h \
$(mooedit)/mooedit-vars.h \
$(mooedit)/mooeditconfig.h \
$(mooedit)/mooeditcolorsprefs-glade.h \
$(mooedit)/mooeditdialogs.h \
$(mooedit)/mooeditfileops.h \
@ -142,6 +142,7 @@ mooedit_sources = \
$(mooedit_noinst_headers) \
$(mooedit)/gtksourceiter.c \
$(mooedit)/mooedit.c \
$(mooedit)/mooeditconfig.c \
$(mooedit)/mooeditdialogs.c \
$(mooedit)/mooeditfileops.c \
$(mooedit)/mootextfind.c \

View File

@ -35,10 +35,8 @@ void _moo_edit_settings_changed (const char *key,
const GValue *newval,
MooEdit *edit);
void _moo_edit_freeze_var_notify (MooEdit *edit);
void _moo_edit_thaw_var_notify (MooEdit *edit);
void _moo_edit_var_notify (MooEdit *edit,
const char *name);
void _moo_edit_freeze_config_notify (MooEdit *edit);
void _moo_edit_thaw_config_notify (MooEdit *edit);
/***********************************************************************/
@ -64,7 +62,7 @@ typedef enum {
typedef struct _VarTable VarTable;
typedef struct _StringList StringList;
typedef struct _UintList UintList;
struct _MooEditPrivate {
@ -94,13 +92,6 @@ struct _MooEditPrivate {
gboolean modified_on_disk;
gboolean deleted_from_disk;
/***********************************************************************/
/* Language and stuff
/*/
VarTable *vars;
StringList *changed_vars;
guint freeze_var_notify;
/***********************************************************************/
/* Preferences
/*/

View File

@ -1,267 +0,0 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; coding: utf-8 -*-
*
* mooedit.h
*
* Copyright (C) 2004-2005 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 __MOO_EDIT_VARS_H__
#define __MOO_EDIT_VARS_H__
#include "mooedit/mooedit-private.h"
G_BEGIN_DECLS
typedef struct {
GHashTable *hash;
} VarPool;
struct _StringList {
GHashTable *hash;
};
struct _VarTable {
VarPool *pool;
GHashTable *hash;
};
typedef struct {
GValue value;
guint dep : 4;
} Var;
static VarPool *var_pool_new (void);
static GParamSpec *var_pool_get_pspec (VarPool *pool,
const char *name);
static const char *var_pool_find_name (VarPool *pool,
const char *alias);
static void var_pool_add (VarPool *pool,
GParamSpec *pspec);
static void var_pool_add_alias (VarPool *pool,
const char *name,
const char *alias);
static StringList *string_list_new (void);
static void string_list_free (StringList *list);
static void string_list_add (StringList *list,
const char *s);
static VarTable *var_table_new (VarPool *pool);
static void var_table_free (VarTable *table);
static Var *var_table_get (VarTable *table,
const char *name);
static void var_table_insert (VarTable *table,
const char *name,
Var *var);
static void var_table_remove (VarTable *table,
const char *name);
static void var_table_remove_by_dep (VarTable *table,
guint dep,
StringList *changed);
static Var *var_new (guint dep,
GType type);
static void var_free (Var *var);
static StringList *
string_list_new (void)
{
StringList *l = g_new0 (StringList, 1);
l->hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
return l;
}
static void
string_list_free (StringList *list)
{
if (list)
{
g_hash_table_destroy (list->hash);
g_free (list);
}
}
static void
string_list_add (StringList *list,
const char *s)
{
g_return_if_fail (list != NULL);
g_return_if_fail (s != NULL);
g_hash_table_insert (list->hash, g_strdup (s), NULL);
}
static VarTable *
var_table_new (VarPool *pool)
{
VarTable *table = g_new0 (VarTable, 1);
table->hash = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, (GDestroyNotify) var_free);
table->pool = pool;
return table;
}
static void
var_table_free (VarTable *table)
{
if (table)
{
g_hash_table_destroy (table->hash);
g_free (table);
}
}
static Var *
var_table_get (VarTable *table,
const char *name)
{
return g_hash_table_lookup (table->hash, name);
}
static void
var_table_insert (VarTable *table,
const char *name,
Var *var)
{
if (var)
g_hash_table_insert (table->hash, g_strdup (name), var);
else
g_hash_table_remove (table->hash, name);
}
static void
var_table_remove (VarTable *table,
const char *name)
{
g_hash_table_remove (table->hash, name);
}
static gboolean
remove_by_dep (const char *name,
Var *val,
gpointer user_data)
{
struct {
StringList *list;
guint dep;
} *data = user_data;
if (val->dep >= data->dep)
{
string_list_add (data->list, name);
return TRUE;
}
else
{
return FALSE;
}
}
static void
var_table_remove_by_dep (VarTable *table,
guint dep,
StringList *changed)
{
struct {
StringList *list;
guint dep;
} data = {changed, dep};
g_hash_table_foreach_remove (table->hash,
(GHRFunc) remove_by_dep,
&data);
}
static Var *
var_new (guint dep,
GType type)
{
Var *var = g_new0 (Var, 1);
g_value_init (&var->value, type);
var->dep = dep;
return var;
}
static void
var_free (Var *var)
{
if (var)
{
g_value_unset (&var->value);
g_free (var);
}
}
static VarPool *
var_pool_new (void)
{
VarPool *pool = g_new0 (VarPool, 1);
pool->hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
(GDestroyNotify) g_param_spec_unref);
return pool;
}
static GParamSpec *
var_pool_get_pspec (VarPool *pool,
const char *name)
{
return g_hash_table_lookup (pool->hash, name);
}
static const char *
var_pool_find_name (VarPool *pool,
const char *alias)
{
GParamSpec *pspec = var_pool_get_pspec (pool, alias);
return pspec ? g_param_spec_get_name (pspec) : NULL;
}
static void
var_pool_add (VarPool *pool,
GParamSpec *pspec)
{
const char *name = g_param_spec_get_name (pspec);
g_param_spec_ref (pspec);
g_param_spec_sink (pspec);
g_hash_table_insert (pool->hash, g_strdup (name), pspec);
}
static void
var_pool_add_alias (VarPool *pool,
const char *name,
const char *alias)
{
GParamSpec *pspec = var_pool_get_pspec (pool, name);
g_return_if_fail (pspec != NULL);
g_param_spec_ref (pspec);
g_hash_table_insert (pool->hash, g_strdup (alias), pspec);
}
G_END_DECLS
#endif /* __MOO_EDIT_VARS_H__ */

View File

@ -23,16 +23,12 @@
#include "mooedit/mooeditdialogs.h"
#include "mooedit/mooeditprefs.h"
#include "mooedit/mootextbuffer.h"
#include "mooedit/mooedit-vars.h"
#include "mooutils/moomarshals.h"
#include "mooutils/moocompat.h"
#include "mooutils/mooutils-gobject.h"
#include <string.h>
static VarPool *moo_edit_var_pool = NULL;
static void moo_edit_init_var_pool (void);
static GObject *moo_edit_constructor (GType type,
guint n_construct_properties,
GObjectConstructParam *construct_param);
@ -47,11 +43,15 @@ static void moo_edit_get_property (GObject *object,
GValue *value,
GParamSpec *pspec);
static void moo_edit_variable_changed (MooEdit *edit,
const char *name);
static void moo_edit_filename_changed (MooEdit *edit,
const char *new_filename);
static void config_changed (MooEdit *edit,
GParamSpec *pspec);
static void moo_edit_config_notify (MooEdit *edit,
guint var_id,
GParamSpec *pspec);
static GtkTextBuffer *get_buffer (MooEdit *edit);
static MooTextBuffer *get_moo_buffer (MooEdit *edit);
@ -64,7 +64,7 @@ enum {
FILENAME_CHANGED,
COMMENT,
UNCOMMENT,
VARIABLE_CHANGED,
CONFIG_NOTIFY,
SAVE_BEFORE,
SAVE_AFTER,
LAST_SIGNAL
@ -72,7 +72,6 @@ enum {
static guint signals[LAST_SIGNAL];
enum {
PROP_0,
PROP_EDITOR
@ -88,20 +87,13 @@ moo_edit_class_init (MooEditClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
moo_edit_register_var (g_param_spec_string (MOO_EDIT_VAR_LANG, MOO_EDIT_VAR_LANG,
MOO_EDIT_VAR_LANG, NULL, 0));
moo_edit_register_var (g_param_spec_string (MOO_EDIT_VAR_INDENT, MOO_EDIT_VAR_INDENT,
MOO_EDIT_VAR_INDENT, NULL, 0));
moo_edit_register_var (g_param_spec_boolean (MOO_EDIT_VAR_STRIP, MOO_EDIT_VAR_STRIP,
MOO_EDIT_VAR_STRIP, FALSE, 0));
gobject_class->set_property = moo_edit_set_property;
gobject_class->get_property = moo_edit_get_property;
gobject_class->constructor = moo_edit_constructor;
gobject_class->finalize = moo_edit_finalize;
klass->variable_changed = moo_edit_variable_changed;
klass->filename_changed = moo_edit_filename_changed;
klass->config_notify = moo_edit_config_notify;
g_object_class_install_property (gobject_class,
PROP_EDITOR,
@ -111,15 +103,15 @@ moo_edit_class_init (MooEditClass *klass)
MOO_TYPE_EDITOR,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
signals[VARIABLE_CHANGED] =
g_signal_new ("variable-changed",
signals[CONFIG_NOTIFY] =
g_signal_new ("config-notify",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (MooEditClass, variable_changed),
G_STRUCT_OFFSET (MooEditClass, config_notify),
NULL, NULL,
_moo_marshal_VOID__STRING,
G_TYPE_NONE, 1,
G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
_moo_marshal_VOID__UINT_POINTER,
G_TYPE_NONE, 2,
G_TYPE_UINT, G_TYPE_POINTER);
signals[DOC_STATUS_CHANGED] =
g_signal_new ("doc-status-changed",
@ -186,12 +178,14 @@ moo_edit_init (MooEdit *edit)
{
MooIndenter *indent;
edit->config = moo_edit_config_new ();
g_signal_connect_swapped (edit->config, "notify",
G_CALLBACK (config_changed), edit);
edit->priv = g_new0 (MooEditPrivate, 1);
edit->priv->file_watch_policy = MOO_EDIT_RELOAD_IF_SAFE;
edit->priv->vars = var_table_new (moo_edit_var_pool);
edit->priv->enable_indentation = TRUE;
indent = moo_indenter_new (edit, NULL);
moo_text_view_set_indenter (MOO_TEXT_VIEW (edit), indent);
@ -249,6 +243,7 @@ moo_edit_finalize (GObject *object)
{
MooEdit *edit = MOO_EDIT (object);
g_object_unref (edit->config);
moo_prefs_notify_disconnect (edit->priv->prefs_notify);
edit->priv->focus_in_handler_id = 0;
@ -261,8 +256,6 @@ moo_edit_finalize (GObject *object)
g_free (edit->priv->display_basename);
g_free (edit->priv->encoding);
var_table_free (edit->priv->vars);
g_free (edit->priv);
edit->priv = NULL;
@ -511,26 +504,6 @@ moo_edit_on_external_changes_get_type (void)
}
GType
moo_edit_var_dep_get_type (void)
{
static GType type = 0;
if (!type)
{
static const GEnumValue values[] = {
{ MOO_EDIT_VAR_DEP_NONE, (char*)"MOO_EDIT_VAR_DEP_NONE", (char*)"none" },
{ MOO_EDIT_VAR_DEP_FILENAME, (char*)"MOO_EDIT_VAR_DEP_FILENAME", (char*)"filename" },
{ MOO_EDIT_VAR_DEP_AUTO, (char*)"MOO_EDIT_VAR_DEP_AUTO", (char*)"auto" },
{ 0, NULL, NULL }
};
type = g_enum_register_static ("MooEditVarDep", values);
}
return type;
}
GType
moo_edit_file_info_get_type (void)
{
@ -538,7 +511,7 @@ moo_edit_file_info_get_type (void)
if (!type)
type = g_boxed_type_register_static ("MooEditFileInfo",
(GBoxedCopyFunc) moo_edit_file_info_copy,
(GBoxedFreeFunc)moo_edit_file_info_free);
(GBoxedFreeFunc) moo_edit_file_info_free);
return type;
}
@ -697,80 +670,6 @@ parse_kate_mode_string (G_GNUC_UNUSED MooEdit *edit,
}
static gboolean
moo_edit_set_var_from_string (MooEdit *edit,
const char *name,
const char *strval)
{
char *normname, *normval;
GParamSpec *pspec;
gboolean result = FALSE;
GValue value;
g_return_val_if_fail (name != NULL, FALSE);
g_return_val_if_fail (strval != NULL, FALSE);
normname = g_strdelimit (g_ascii_strdown (name, -1), "_", '-');
normval = g_ascii_strdown (strval, -1);
pspec = var_pool_get_pspec (moo_edit_var_pool, normname);
value.g_type = 0;
if (!pspec)
goto out;
if (G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_BOOLEAN)
{
if (!strcmp (normval, "yes") || !strcmp (normval, "on") ||
!strcmp (normval, "true") || !strcmp (normval, "1"))
{
g_value_init (&value, G_TYPE_BOOLEAN);
g_value_set_boolean (&value, TRUE);
}
else if (!strcmp (normval, "no") || !strcmp (normval, "off") ||
!strcmp (normval, "false") || !strcmp (normval, "0"))
{
g_value_init (&value, G_TYPE_BOOLEAN);
g_value_set_boolean (&value, FALSE);
}
else
{
goto out;
}
}
else
{
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
if (!moo_value_convert_from_string (normval, &value))
{
g_value_unset (&value);
goto out;
}
}
moo_edit_set_var (edit, normname, &value, MOO_EDIT_VAR_DEP_FILENAME);
result = TRUE;
out:
#if 1
if (!result)
g_warning ("%s: could not set '%s' to '%s'", G_STRLOC, name, strval);
else
g_message ("%s: set '%s' to '%s'", G_STRLOC, normname, normval);
#endif
g_free (normname);
g_free (normval);
if (G_IS_VALUE (&value))
g_value_unset (&value);
return result;
}
static void
set_emacs_var (MooEdit *edit,
char *name,
@ -778,22 +677,27 @@ set_emacs_var (MooEdit *edit,
{
if (!g_ascii_strcasecmp (name, "mode"))
{
moo_edit_set_var_from_string (edit, "lang", val);
moo_edit_config_parse (edit->config, "lang", val,
MOO_EDIT_CONFIG_SOURCE_FILE);
}
else if (!g_ascii_strcasecmp (name, "tab-width"))
{
moo_edit_set_var_from_string (edit, "indent-tab-width", val);
moo_edit_config_parse (edit->config, "indent-tab-width", val,
MOO_EDIT_CONFIG_SOURCE_FILE);
}
else if (!g_ascii_strcasecmp (name, "c-basic-offset"))
{
moo_edit_set_var_from_string (edit, "indent-width", val);
moo_edit_config_parse (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_set_var_from_string (edit, "indent-use-tabs", "false");
moo_edit_config_parse (edit->config, "indent-use-tabs", "false",
MOO_EDIT_CONFIG_SOURCE_FILE);
else
moo_edit_set_var_from_string (edit, "indent-use-tabs", "true");
moo_edit_config_parse (edit->config, "indent-use-tabs", "true",
MOO_EDIT_CONFIG_SOURCE_FILE);
}
}
@ -805,11 +709,20 @@ 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) moo_edit_set_var_from_string);
parse_mode_string (edit, string, " ", (SetVarFunc) set_moo_var);
}
@ -889,16 +802,26 @@ try_mode_strings (MooEdit *edit)
static void
moo_edit_variable_changed (MooEdit *edit,
const char *name)
config_changed (MooEdit *edit,
GParamSpec *pspec)
{
if (!strcmp (name, MOO_EDIT_VAR_LANG))
guint id = moo_edit_config_get_setting_id (pspec);
g_return_if_fail (id != 0);
g_signal_emit (edit, signals[CONFIG_NOTIFY], 0, id, pspec);
}
static void
moo_edit_config_notify (MooEdit *edit,
G_GNUC_UNUSED guint var_id,
GParamSpec *pspec)
{
if (!strcmp (pspec->name, "lang"))
{
char *value = moo_edit_get_string (edit, name);
const char *value = moo_edit_config_get_string (edit->config, "lang");
MooLangMgr *mgr = moo_editor_get_lang_mgr (edit->priv->editor);
MooLang *lang = value ? moo_lang_mgr_get_lang (mgr, value) : NULL;
moo_edit_set_lang (edit, lang);
g_free (value);
}
}
@ -908,29 +831,25 @@ moo_edit_filename_changed (MooEdit *edit,
const char *filename)
{
MooLang *lang = NULL;
const char *lang_id = NULL;
_moo_edit_freeze_var_notify (edit);
_moo_edit_freeze_config_notify (edit);
if (!edit->priv->changed_vars)
edit->priv->changed_vars = string_list_new ();
var_table_remove_by_dep (edit->priv->vars,
MOO_EDIT_VAR_DEP_FILENAME,
edit->priv->changed_vars);
moo_edit_config_unset_by_source (edit->config, MOO_EDIT_CONFIG_SOURCE_FILE);
if (filename)
{
MooLangMgr *mgr = moo_editor_get_lang_mgr (edit->priv->editor);
lang = moo_lang_mgr_get_lang_for_file (mgr, filename);
lang_id = lang->id;
}
moo_edit_set_string (edit, MOO_EDIT_VAR_LANG, lang ? lang->id : NULL,
MOO_EDIT_VAR_DEP_FILENAME);
moo_edit_set_string (edit, MOO_EDIT_VAR_INDENT, NULL,
MOO_EDIT_VAR_DEP_FILENAME);
moo_edit_config_set (edit->config, "lang", MOO_EDIT_CONFIG_SOURCE_FILENAME, lang_id, NULL);
moo_edit_config_set (edit->config, "indent", MOO_EDIT_CONFIG_SOURCE_FILENAME, NULL, NULL);
try_mode_strings (edit);
_moo_edit_thaw_var_notify (edit);
_moo_edit_thaw_config_notify (edit);
}
@ -979,291 +898,303 @@ moo_edit_save_copy (MooEdit *edit,
/* Variables
*/
void
moo_edit_set_var (MooEdit *edit,
const char *name,
const GValue *value,
MooEditVarDep dep)
{
Var *v;
GParamSpec *pspec;
g_return_if_fail (MOO_IS_EDIT (edit));
g_return_if_fail (name != NULL);
g_return_if_fail (!value || G_IS_VALUE (value));
pspec = var_pool_get_pspec (moo_edit_var_pool, name);
g_return_if_fail (pspec != NULL);
g_return_if_fail (!value || G_PARAM_SPEC_VALUE_TYPE (pspec) == G_VALUE_TYPE (value));
name = g_param_spec_get_name (pspec);
v = var_table_get (edit->priv->vars, name);
if (v && v->dep < dep)
return;
if (value)
{
if (!v)
{
v = var_new (dep, G_VALUE_TYPE (value));
var_table_insert (edit->priv->vars, name, v);
}
v->dep = dep;
g_value_copy (value, &v->value);
}
else
{
var_table_remove (edit->priv->vars, name);
}
_moo_edit_var_notify (edit, name);
}
gboolean
moo_edit_get_var (MooEdit *edit,
const char *name,
GValue *value)
{
Var *v;
g_return_val_if_fail (MOO_IS_EDIT (edit), FALSE);
g_return_val_if_fail (name != NULL, FALSE);
g_return_val_if_fail (!value || G_IS_VALUE (value), FALSE);
name = var_pool_find_name (moo_edit_var_pool, name);
g_return_val_if_fail (name != NULL, FALSE);
v = var_table_get (edit->priv->vars, name);
if (v && value)
{
g_return_val_if_fail (G_VALUE_TYPE (&v->value) == G_VALUE_TYPE (value), FALSE);
g_value_copy (&v->value, value);
}
return v != NULL;
}
char*
moo_edit_get_string (MooEdit *edit,
const char *name)
{
GValue val;
char *strval;
g_return_val_if_fail (MOO_IS_EDIT (edit), NULL);
g_return_val_if_fail (name != NULL, NULL);
val.g_type = 0;
g_value_init (&val, G_TYPE_STRING);
if (!moo_edit_get_var (edit, name, &val))
return NULL;
strval = g_value_dup_string (&val);
g_value_unset (&val);
return strval;
}
gboolean
moo_edit_get_bool (MooEdit *edit,
const char *name,
gboolean default_val)
{
GValue val;
g_return_val_if_fail (MOO_IS_EDIT (edit), default_val);
g_return_val_if_fail (name != NULL, default_val);
val.g_type = 0;
g_value_init (&val, G_TYPE_BOOLEAN);
if (!moo_edit_get_var (edit, name, &val))
return default_val;
return g_value_get_boolean (&val);
}
int
moo_edit_get_int (MooEdit *edit,
const char *name,
int default_val)
{
GValue val;
g_return_val_if_fail (MOO_IS_EDIT (edit), default_val);
g_return_val_if_fail (name != NULL, default_val);
val.g_type = 0;
g_value_init (&val, G_TYPE_INT);
if (!moo_edit_get_var (edit, name, &val))
return default_val;
return g_value_get_int (&val);
}
guint
moo_edit_get_uint (MooEdit *edit,
const char *name,
guint default_val)
{
GValue val;
g_return_val_if_fail (MOO_IS_EDIT (edit), default_val);
g_return_val_if_fail (name != NULL, default_val);
val.g_type = 0;
g_value_init (&val, G_TYPE_UINT);
if (!moo_edit_get_var (edit, name, &val))
return default_val;
return g_value_get_uint (&val);
}
// void
// moo_edit_set_var (MooEdit *edit,
// const char *name,
// const GValue *value,
// MooEditVarDep dep)
// {
// Var *v;
// VarSpec *spec;
//
// g_return_if_fail (MOO_IS_EDIT (edit));
// g_return_if_fail (name != NULL);
// g_return_if_fail (!value || G_IS_VALUE (value));
//
// spec = var_pool_get_spec (moo_edit_var_pool, name);
// g_return_if_fail (spec != NULL);
// g_return_if_fail (!value || G_PARAM_SPEC_VALUE_TYPE (spec->pspec) == G_VALUE_TYPE (value));
//
// name = g_param_spec_get_name (spec->pspec);
// v = var_table_get (edit->priv->vars, name);
//
// if (v && v->dep < dep)
// return;
//
// if (value)
// {
// if (!v)
// {
// v = var_new (dep, G_VALUE_TYPE (value));
// var_table_insert (edit->priv->vars, name, v);
// }
//
// v->dep = dep;
// g_value_copy (value, &v->value);
// }
// else
// {
// var_table_remove (edit->priv->vars, name);
// }
//
// _moo_edit_var_notify (edit, spec->id);
// }
//
//
// gboolean
// moo_edit_get_var (MooEdit *edit,
// const char *name,
// GValue *value)
// {
// Var *v;
//
// g_return_val_if_fail (MOO_IS_EDIT (edit), FALSE);
// g_return_val_if_fail (name != NULL, FALSE);
// g_return_val_if_fail (!value || G_IS_VALUE (value), FALSE);
//
// name = var_pool_find_name (moo_edit_var_pool, name);
// g_return_val_if_fail (name != NULL, FALSE);
//
// v = var_table_get (edit->priv->vars, name);
//
// if (v && value)
// {
// g_return_val_if_fail (G_VALUE_TYPE (&v->value) == G_VALUE_TYPE (value), FALSE);
// g_value_copy (&v->value, value);
// }
//
// return v != NULL;
// }
//
//
// char*
// moo_edit_get_string (MooEdit *edit,
// const char *name)
// {
// GValue val;
// char *strval;
//
// g_return_val_if_fail (MOO_IS_EDIT (edit), NULL);
// g_return_val_if_fail (name != NULL, NULL);
//
// val.g_type = 0;
// g_value_init (&val, G_TYPE_STRING);
//
// if (!moo_edit_get_var (edit, name, &val))
// return NULL;
//
// strval = g_value_dup_string (&val);
// g_value_unset (&val);
//
// return strval;
// }
//
//
// gboolean
// moo_edit_get_bool (MooEdit *edit,
// const char *name,
// gboolean default_val)
// {
// GValue val;
//
// g_return_val_if_fail (MOO_IS_EDIT (edit), default_val);
// g_return_val_if_fail (name != NULL, default_val);
//
// val.g_type = 0;
// g_value_init (&val, G_TYPE_BOOLEAN);
//
// if (!moo_edit_get_var (edit, name, &val))
// return default_val;
//
// return g_value_get_boolean (&val);
// }
//
//
// int
// moo_edit_get_int (MooEdit *edit,
// const char *name,
// int default_val)
// {
// GValue val;
//
// g_return_val_if_fail (MOO_IS_EDIT (edit), default_val);
// g_return_val_if_fail (name != NULL, default_val);
//
// val.g_type = 0;
// g_value_init (&val, G_TYPE_INT);
//
// if (!moo_edit_get_var (edit, name, &val))
// return default_val;
//
// return g_value_get_int (&val);
// }
//
//
// guint
// moo_edit_get_uint (MooEdit *edit,
// const char *name,
// guint default_val)
// {
// GValue val;
//
// g_return_val_if_fail (MOO_IS_EDIT (edit), default_val);
// g_return_val_if_fail (name != NULL, default_val);
//
// val.g_type = 0;
// g_value_init (&val, G_TYPE_UINT);
//
// if (!moo_edit_get_var (edit, name, &val))
// return default_val;
//
// return g_value_get_uint (&val);
// }
//
//
// void
// moo_edit_set_string (MooEdit *edit,
// const char *name,
// const char *value,
// MooEditVarDep dep)
// {
// g_return_if_fail (MOO_IS_EDIT (edit));
// g_return_if_fail (name != NULL);
//
// if (value)
// {
// GValue gval;
// gval.g_type = 0;
// g_value_init (&gval, G_TYPE_STRING);
// g_value_set_static_string (&gval, value);
// moo_edit_set_var (edit, name, &gval, dep);
// g_value_unset (&gval);
// }
// else
// {
// moo_edit_set_var (edit, name, NULL, dep);
// }
// }
//
//
// static void
// emit_var_notify (MooEdit *edit,
// guint var_id)
// {
// g_signal_emit (edit, signals[VARIABLE_CHANGED], 0, var_id);
// }
//
//
// void
// _moo_edit_var_notify (MooEdit *edit,
// guint var_id)
// {
// g_return_if_fail (MOO_IS_EDIT (edit));
//
// if (edit->priv->freeze_var_notify)
// {
// if (!edit->priv->changed_vars)
// edit->priv->changed_vars = uint_list_new ();
// uint_list_add (edit->priv->changed_vars, var_id);
// }
// else
// {
// emit_var_notify (edit, var_id);
// }
// }
//
//
void
moo_edit_set_string (MooEdit *edit,
const char *name,
const char *value,
MooEditVarDep dep)
_moo_edit_freeze_config_notify (MooEdit *edit)
{
g_return_if_fail (MOO_IS_EDIT (edit));
g_return_if_fail (name != NULL);
if (value)
{
GValue gval;
gval.g_type = 0;
g_value_init (&gval, G_TYPE_STRING);
g_value_set_static_string (&gval, value);
moo_edit_set_var (edit, name, &gval, dep);
g_value_unset (&gval);
}
else
{
moo_edit_set_var (edit, name, NULL, dep);
}
}
static void
emit_var_notify (MooEdit *edit,
const char *name)
{
g_signal_emit (edit, signals[VARIABLE_CHANGED], 0, name);
g_object_freeze_notify (G_OBJECT (edit->config));
}
void
_moo_edit_var_notify (MooEdit *edit,
const char *name)
_moo_edit_thaw_config_notify (MooEdit *edit)
{
g_return_if_fail (MOO_IS_EDIT (edit));
if (edit->priv->freeze_var_notify)
{
if (!edit->priv->changed_vars)
edit->priv->changed_vars = string_list_new ();
string_list_add (edit->priv->changed_vars, name);
}
else
{
emit_var_notify (edit, name);
}
g_object_thaw_notify (G_OBJECT (edit->config));
}
void
_moo_edit_freeze_var_notify (MooEdit *edit)
{
g_return_if_fail (MOO_IS_EDIT (edit));
edit->priv->freeze_var_notify++;
}
static void
emit_var_notify_cb (const char *varname,
G_GNUC_UNUSED gpointer dummy,
MooEdit *edit)
{
emit_var_notify (edit, varname);
}
void
_moo_edit_thaw_var_notify (MooEdit *edit)
{
g_return_if_fail (MOO_IS_EDIT (edit));
g_return_if_fail (edit->priv->freeze_var_notify > 0);
if (!--edit->priv->freeze_var_notify && edit->priv->changed_vars)
{
StringList *vars = edit->priv->changed_vars;
edit->priv->changed_vars = NULL;
g_object_ref (edit);
g_hash_table_foreach (vars->hash, (GHFunc) emit_var_notify_cb, edit);
g_object_unref (edit);
string_list_free (vars);
}
}
void
moo_edit_register_var (GParamSpec *pspec)
{
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
moo_edit_init_var_pool ();
if (var_pool_get_pspec (moo_edit_var_pool, g_param_spec_get_name (pspec)))
{
g_critical ("%s: variable '%s' already registered",
G_STRLOC, g_param_spec_get_name (pspec));
return;
}
var_pool_add (moo_edit_var_pool, pspec);
}
void
moo_edit_register_var_alias (const char *name,
const char *alias)
{
g_return_if_fail (name != NULL);
g_return_if_fail (alias != NULL);
moo_edit_init_var_pool ();
if (!var_pool_get_pspec (moo_edit_var_pool, name))
{
g_critical ("%s: no variable '%s'", G_STRLOC, name);
return;
}
if (var_pool_get_pspec (moo_edit_var_pool, alias))
{
g_critical ("%s: variable '%s' already registered",
G_STRLOC, alias);
return;
}
var_pool_add_alias (moo_edit_var_pool, name, alias);
}
static void
moo_edit_init_var_pool (void)
{
if (!moo_edit_var_pool)
moo_edit_var_pool = var_pool_new ();
}
//
//
// static void
// emit_var_notify_cb (gpointer id,
// G_GNUC_UNUSED gpointer dummy,
// MooEdit *edit)
// {
// emit_var_notify (edit, GPOINTER_TO_UINT (id));
// }
//
// void
// _moo_edit_thaw_var_notify (MooEdit *edit)
// {
// g_return_if_fail (MOO_IS_EDIT (edit));
// g_return_if_fail (edit->priv->freeze_var_notify > 0);
//
// if (!--edit->priv->freeze_var_notify && edit->priv->changed_vars)
// {
// UintList *vars = edit->priv->changed_vars;
// edit->priv->changed_vars = NULL;
// g_object_ref (edit);
// g_hash_table_foreach (vars->hash, (GHFunc) emit_var_notify_cb, edit);
// g_object_unref (edit);
// uint_list_free (vars);
// }
// }
//
//
// guint
// moo_edit_register_var (GParamSpec *pspec)
// {
// g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), 0);
//
// moo_edit_init_var_pool ();
//
// if (var_pool_get_spec (moo_edit_var_pool, g_param_spec_get_name (pspec)))
// {
// g_critical ("%s: variable '%s' already registered",
// G_STRLOC, g_param_spec_get_name (pspec));
// return 0;
// }
//
// return var_pool_add (moo_edit_var_pool, pspec);
// }
//
//
// void
// moo_edit_register_var_alias (const char *name,
// const char *alias)
// {
// g_return_if_fail (name != NULL);
// g_return_if_fail (alias != NULL);
//
// moo_edit_init_var_pool ();
//
// if (!var_pool_get_spec (moo_edit_var_pool, name))
// {
// g_critical ("%s: no variable '%s'", G_STRLOC, name);
// return;
// }
//
// if (var_pool_get_spec (moo_edit_var_pool, alias))
// {
// g_critical ("%s: variable '%s' already registered",
// G_STRLOC, alias);
// return;
// }
//
// var_pool_add_alias (moo_edit_var_pool, name, alias);
// }
//
//
// static void
// moo_edit_init_var_pool (void)
// {
// if (!moo_edit_var_pool)
// moo_edit_var_pool = var_pool_new ();
// }

View File

@ -17,6 +17,7 @@
#include <mooedit/mootextview.h>
#include <mooedit/moolang.h>
#include <mooedit/mooeditconfig.h>
#include <mooutils/mooprefs.h>
G_BEGIN_DECLS
@ -26,7 +27,6 @@ G_BEGIN_DECLS
#define MOO_TYPE_EDIT_ON_EXTERNAL_CHANGES (moo_edit_on_external_changes_get_type ())
#define MOO_TYPE_EDIT_STATUS (moo_edit_status_get_type ())
#define MOO_TYPE_EDIT_FILE_INFO (moo_edit_file_info_get_type ())
#define MOO_TYPE_EDIT_VAR_DEP (moo_edit_var_dep_get_type ())
#define MOO_EDIT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), MOO_TYPE_EDIT, MooEdit))
#define MOO_EDIT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MOO_TYPE_EDIT, MooEditClass))
@ -35,17 +35,6 @@ G_BEGIN_DECLS
#define MOO_EDIT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MOO_TYPE_EDIT, MooEditClass))
typedef enum {
MOO_EDIT_VAR_DEP_NONE = 0,
MOO_EDIT_VAR_DEP_FILENAME = 1,
MOO_EDIT_VAR_DEP_AUTO = 2
} MooEditVarDep;
#define MOO_EDIT_VAR_LANG "lang"
#define MOO_EDIT_VAR_INDENT "indent"
#define MOO_EDIT_VAR_STRIP "strip"
typedef enum {
MOO_EDIT_DONT_WATCH_FILE = 0,
MOO_EDIT_ALWAYS_ALERT,
@ -78,7 +67,7 @@ typedef struct _MooEditClass MooEditClass;
struct _MooEdit
{
MooTextView parent;
MooEditConfig *config;
MooEditPrivate *priv;
};
@ -95,8 +84,9 @@ struct _MooEditClass
void (* lang_changed) (MooEdit *edit);
void (* variable_changed) (MooEdit *edit,
const char *name);
void (* config_notify) (MooEdit *edit,
guint var_id,
GParamSpec *pspec);
void (* save_before) (MooEdit *edit);
void (* save_after) (MooEdit *edit);
@ -107,7 +97,6 @@ GType moo_edit_get_type (void) G_GNUC_CONST;
GType moo_edit_status_get_type (void) G_GNUC_CONST;
GType moo_edit_on_external_changes_get_type (void) G_GNUC_CONST;
GType moo_edit_file_info_get_type (void) G_GNUC_CONST;
GType moo_edit_var_dep_get_type (void) G_GNUC_CONST;
const char *moo_edit_get_filename (MooEdit *edit);
const char *moo_edit_get_basename (MooEdit *edit);
@ -140,34 +129,6 @@ void moo_edit_set_highlight (MooEdit *edit,
gboolean highlight);
gboolean moo_edit_get_highlight (MooEdit *edit);
void moo_edit_set_var (MooEdit *edit,
const char *name,
const GValue *value,
MooEditVarDep dep);
gboolean moo_edit_get_var (MooEdit *edit,
const char *name,
GValue *value);
char *moo_edit_get_string (MooEdit *edit,
const char *name);
gboolean moo_edit_get_bool (MooEdit *edit,
const char *name,
gboolean default_val);
int moo_edit_get_int (MooEdit *edit,
const char *name,
int default_val);
guint moo_edit_get_uint (MooEdit *edit,
const char *name,
guint default_val);
void moo_edit_set_string (MooEdit *edit,
const char *name,
const char *value,
MooEditVarDep dep);
void moo_edit_register_var (GParamSpec *pspec);
void moo_edit_register_var_alias (const char *name,
const char *alias);
gboolean moo_edit_close (MooEdit *edit,
gboolean ask_confirm);
gboolean moo_edit_save (MooEdit *edit,

705
moo/mooedit/mooeditconfig.c Normal file
View File

@ -0,0 +1,705 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; coding: utf-8 -*-
*
* mooeditconfig.c
*
* Copyright (C) 2004-2005 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.
*/
#define MOOEDIT_COMPILATION
#include "mooedit/mooeditconfig.h"
#include "mooutils/mooutils-gobject.h"
#include <gobject/gvaluecollector.h>
#include <string.h>
#define VALUE(c_,i_) (&(c_)->priv->values[i_])
#define GVALUE(c_,i_) (&VALUE(c_,i_)->gval)
typedef struct _Variable Variable;
typedef struct _VarArray VarArray;
typedef struct _Value Value;
struct _MooEditConfigPrivate {
Value *values;
guint n_values;
guint n_values_allocd__;
};
struct _Value {
GValue gval;
guint source : 16;
};
struct _Variable {
GParamSpec *pspec;
};
struct _VarArray {
Variable *data;
guint len;
};
static MooEditConfig *global;
static GSList *instances;
static VarArray *vars;
static GQuark prop_id_quark;
static void moo_edit_config_finalize (GObject *object);
static void moo_edit_config_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void moo_edit_config_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static void global_changed (GObject *object,
GParamSpec *pspec);
enum {
PROP_0,
PROP_LANG,
PROP_INDENT,
PROP_STRIP,
N_PROPS
};
/* MOO_TYPE_EDIT_CONFIG */
G_DEFINE_TYPE (MooEditConfig, moo_edit_config, G_TYPE_OBJECT)
static void
moo_edit_config_class_init (MooEditConfigClass *klass)
{
guint i;
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->set_property = moo_edit_config_set_property;
gobject_class->get_property = moo_edit_config_get_property;
gobject_class->finalize = moo_edit_config_finalize;
prop_id_quark = g_quark_from_static_string ("MooEditConfigPropId");
vars = (VarArray*) g_array_new (FALSE, TRUE, sizeof (Variable));
g_array_set_size ((GArray*) vars, N_PROPS);
vars->data[PROP_LANG].pspec =
g_param_spec_string ("lang", "lang", "lang", NULL, G_PARAM_READWRITE);
vars->data[PROP_INDENT].pspec =
g_param_spec_string ("indent", "indent", "indent", NULL, G_PARAM_READWRITE);
vars->data[PROP_STRIP].pspec =
g_param_spec_boolean ("strip", "strip", "strip", FALSE, G_PARAM_READWRITE);
for (i = 1; i < N_PROPS; ++i)
{
g_param_spec_set_qdata (vars->data[i].pspec, prop_id_quark, GUINT_TO_POINTER (i));
g_object_class_install_property (gobject_class, i, vars->data[i].pspec);
}
}
static void
moo_edit_config_init (MooEditConfig *config)
{
guint i;
config->priv = g_new0 (MooEditConfigPrivate, 1);
config->priv->values = g_new0 (Value, vars->len);
config->priv->n_values = config->priv->n_values_allocd__ = vars->len;
if (global)
{
instances = g_slist_prepend (instances, config);
for (i = 1; i < vars->len; ++i)
{
g_value_init (GVALUE (config, i), G_VALUE_TYPE (GVALUE (global, i)));
g_value_copy (GVALUE (global, i), GVALUE (config, i));
VALUE(config, i)->source = VALUE(global, i)->source;
}
}
}
static void
moo_edit_config_finalize (GObject *object)
{
guint i;
MooEditConfig *config = MOO_EDIT_CONFIG (object);
instances = g_slist_remove (instances, config);
for (i = 1; i < config->priv->n_values; ++i)
g_value_unset (GVALUE (config, i));
g_free (config->priv->values);
g_free (config->priv);
G_OBJECT_CLASS (moo_edit_config_parent_class)->finalize (object);
}
static void
global_init (void)
{
if (!global)
{
guint i;
global = g_object_new (MOO_TYPE_EDIT_CONFIG, NULL);
for (i = 1; i < vars->len; ++i)
{
g_value_init (GVALUE (global, i), G_PARAM_SPEC_VALUE_TYPE (vars->data[i].pspec));
g_param_value_set_default (vars->data[i].pspec, GVALUE (global, i));
VALUE(global, i)->source = MOO_EDIT_CONFIG_SOURCE_AUTO;
}
g_signal_connect (global, "notify",
G_CALLBACK (global_changed), NULL);
/* XXX read preferences here */
}
}
MooEditConfig *
moo_edit_config_new (void)
{
global_init ();
return g_object_new (MOO_TYPE_EDIT_CONFIG, NULL);
}
static void
moo_edit_config_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
MooEditConfig *config = MOO_EDIT_CONFIG (object);
if (prop_id == 0 || prop_id >= vars->len)
{
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
return;
}
g_assert (config->priv->n_values == vars->len);
g_value_copy (value, GVALUE (config, prop_id));
VALUE (config, prop_id)->source = MOO_EDIT_CONFIG_SOURCE_USER;
g_object_notify (object, pspec->name);
}
static void
moo_edit_config_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
MooEditConfig *config = MOO_EDIT_CONFIG (object);
if (prop_id == 0 || prop_id >= vars->len)
{
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
return;
}
g_assert (config->priv->n_values == vars->len);
g_value_copy (GVALUE (config, prop_id), value);
}
static void
object_notify (MooEditConfig *config,
guint prop_id)
{
g_object_notify (G_OBJECT (config),
vars->data[prop_id].pspec->name);
}
static void
update_prop_from_global (MooEditConfig *config,
gpointer data)
{
guint prop_id = GPOINTER_TO_UINT (data);
g_assert (prop_id > 0 && prop_id < vars->len);
g_assert (prop_id <= config->priv->n_values);
if (prop_id == config->priv->n_values)
{
if (config->priv->n_values_allocd__ == prop_id)
{
Value *tmp;
config->priv->n_values_allocd__ = MAX (config->priv->n_values_allocd__ * 1.2,
config->priv->n_values_allocd__ + 2);
tmp = g_new0 (Value, config->priv->n_values_allocd__);
memcpy (tmp, config->priv->values, config->priv->n_values * sizeof (Value));
g_free (config->priv->values);
config->priv->values = tmp;
}
config->priv->n_values += 1;
g_value_init (GVALUE (config, prop_id), G_VALUE_TYPE (GVALUE (global, prop_id)));
VALUE(config, prop_id)->source = VALUE(global, prop_id)->source;
}
if (VALUE(global, prop_id)->source <= VALUE(config, prop_id)->source)
{
g_value_copy (GVALUE(global, prop_id), GVALUE(config, prop_id));
VALUE(config, prop_id)->source = VALUE(global, prop_id)->source;
object_notify (config, prop_id);
}
}
static void
global_changed (GObject *object,
GParamSpec *pspec)
{
gpointer prop_id;
g_assert (MOO_EDIT_CONFIG (object) == global);
prop_id = g_param_spec_get_qdata (pspec, prop_id_quark);
g_return_if_fail (prop_id != NULL);
g_slist_foreach (instances, (GFunc) g_object_freeze_notify, NULL);
g_slist_foreach (instances, (GFunc) update_prop_from_global, prop_id);
g_slist_foreach (instances, (GFunc) g_object_thaw_notify, NULL);
/* XXX write to preferences here */
}
static void
global_add_prop (GParamSpec *pspec,
guint prop_id)
{
g_assert (global->priv->n_values == prop_id);
if (global->priv->n_values_allocd__ == prop_id)
{
Value *tmp;
global->priv->n_values_allocd__ = MAX (global->priv->n_values_allocd__ * 1.2,
global->priv->n_values_allocd__ + 2);
tmp = g_new0 (Value, global->priv->n_values_allocd__);
memcpy (tmp, global->priv->values, global->priv->n_values * sizeof (Value));
g_free (global->priv->values);
global->priv->values = tmp;
}
global->priv->n_values += 1;
g_value_init (GVALUE (global, prop_id), G_PARAM_SPEC_VALUE_TYPE (pspec));
g_param_value_set_default (pspec, GVALUE (global, prop_id));
VALUE(global, prop_id)->source = MOO_EDIT_CONFIG_SOURCE_AUTO;
/* XXX prefs */
}
guint
moo_edit_config_install_setting (GParamSpec *pspec)
{
GObjectClass *klass;
guint prop_id;
g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), 0);
global_init ();
klass = g_type_class_ref (MOO_TYPE_EDIT_CONFIG);
if (g_object_class_find_property (klass, pspec->name))
{
g_warning ("%s: setting with name '%s' already exists",
G_STRLOC, pspec->name);
return 0;
}
prop_id = vars->len;
g_array_set_size ((GArray*) vars, prop_id + 1);
vars->data[prop_id].pspec = pspec;
g_param_spec_set_qdata (pspec, prop_id_quark, GUINT_TO_POINTER (prop_id));
g_object_class_install_property (klass, prop_id, pspec);
global_add_prop (pspec, prop_id);
g_slist_foreach (instances, (GFunc) g_object_freeze_notify, NULL);
g_slist_foreach (instances, (GFunc) update_prop_from_global, GUINT_TO_POINTER (prop_id));
g_slist_foreach (instances, (GFunc) g_object_thaw_notify, NULL);
g_type_class_unref (klass);
return prop_id;
}
GParamSpec *
moo_edit_config_get_spec (guint id)
{
g_return_val_if_fail (id > 0 && id < vars->len, NULL);
return vars->data[id].pspec;
}
GParamSpec *
moo_edit_config_lookup_spec (const char *name,
guint *id)
{
GParamSpec *pspec;
GObjectClass *klass;
g_return_val_if_fail (name != NULL, NULL);
global_init ();
klass = g_type_class_ref (MOO_TYPE_EDIT_CONFIG);
pspec = g_object_class_find_property (klass, name);
if (id)
{
if (pspec)
*id = GPOINTER_TO_UINT (g_param_spec_get_qdata (pspec, prop_id_quark));
else
*id = 0;
}
g_type_class_unref (klass);
return pspec;
}
static const GValue *
config_get_value (MooEditConfig *config,
const char *setting)
{
guint prop_id;
g_return_val_if_fail (MOO_IS_EDIT_CONFIG (config), NULL);
g_return_val_if_fail (setting != NULL, NULL);
moo_edit_config_lookup_spec (setting, &prop_id);
g_return_val_if_fail (prop_id != 0, NULL);
return GVALUE (config, prop_id);
}
const char *
moo_edit_config_get_string (MooEditConfig *config,
const char *setting)
{
const GValue *val;
g_return_val_if_fail (MOO_IS_EDIT_CONFIG (config), NULL);
g_return_val_if_fail (setting != NULL, NULL);
val = config_get_value (config, setting);
g_return_val_if_fail (val && G_VALUE_HOLDS_STRING (val), NULL);
return g_value_get_string (val);
}
guint
moo_edit_config_get_uint (MooEditConfig *config,
const char *setting)
{
const GValue *val;
g_return_val_if_fail (MOO_IS_EDIT_CONFIG (config), 0);
g_return_val_if_fail (setting != NULL, 0);
val = config_get_value (config, setting);
g_return_val_if_fail (val && G_VALUE_HOLDS_UINT (val), 0);
return g_value_get_uint (val);
}
gboolean
moo_edit_config_get_bool (MooEditConfig *config,
const char *setting)
{
const GValue *val;
g_return_val_if_fail (MOO_IS_EDIT_CONFIG (config), FALSE);
g_return_val_if_fail (setting != NULL, FALSE);
val = config_get_value (config, setting);
g_return_val_if_fail (val && G_VALUE_HOLDS_BOOLEAN (val), FALSE);
return g_value_get_boolean (val);
}
static void
moo_edit_config_set_value (MooEditConfig *config,
guint prop_id,
MooEditConfigSource source,
const GValue *value)
{
Value *val;
g_return_if_fail (MOO_IS_EDIT_CONFIG (config));
g_return_if_fail (prop_id > 0 && prop_id < vars->len);
g_return_if_fail (G_IS_VALUE (value));
g_assert (prop_id < config->priv->n_values);
val = VALUE (config, prop_id);
if (val->source >= source)
{
g_value_copy (value, &val->gval);
val->source = source;
object_notify (config, prop_id);
}
}
static void
moo_edit_config_set_valist (MooEditConfig *config,
const char *first_setting,
MooEditConfigSource source,
va_list var_args)
{
const gchar *name;
g_return_if_fail (MOO_IS_EDIT_CONFIG (config));
g_return_if_fail (first_setting != NULL);
g_object_ref (config);
g_object_freeze_notify (G_OBJECT (config));
name = first_setting;
while (name)
{
GValue value;
GParamSpec *pspec;
gchar *error = NULL;
guint prop_id;
value.g_type = 0;
pspec = moo_edit_config_lookup_spec (name, &prop_id);
if (!pspec)
{
g_warning ("%s: there is no setting named `%s'",
G_STRLOC, name);
break;
}
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
G_VALUE_COLLECT (&value, var_args, 0, &error);
if (error)
{
g_warning ("%s: %s", G_STRLOC, error);
g_free (error);
g_value_unset (&value);
break;
}
moo_edit_config_set_value (config, prop_id, source, &value);
g_value_unset (&value);
name = va_arg (var_args, gchar*);
if (name)
source = va_arg (var_args, guint);
}
g_object_thaw_notify (G_OBJECT (config));
g_object_unref (config);
}
void
moo_edit_config_set (MooEditConfig *config,
const char *first_setting,
MooEditConfigSource source,
...)
{
va_list var_args;
g_return_if_fail (MOO_IS_EDIT_CONFIG (config));
g_return_if_fail (first_setting != NULL);
va_start (var_args, source);
moo_edit_config_set_valist (config, first_setting, source, var_args);
va_end (var_args);
}
void
moo_edit_config_get (MooEditConfig *config,
const char *first_setting,
...)
{
va_list var_args;
g_return_if_fail (MOO_IS_EDIT_CONFIG (config));
va_start (var_args, first_setting);
g_object_get_valist (G_OBJECT (config), first_setting, var_args);
va_end (var_args);
}
void
moo_edit_config_set_global (const char *first_setting,
MooEditConfigSource source,
...)
{
va_list var_args;
g_return_if_fail (first_setting != NULL);
global_init ();
va_start (var_args, source);
moo_edit_config_set_valist (global, first_setting, source, var_args);
va_end (var_args);
}
void
moo_edit_config_get_global (const char *first_setting,
...)
{
va_list var_args;
global_init ();
va_start (var_args, first_setting);
g_object_get_valist (G_OBJECT (global), first_setting, var_args);
va_end (var_args);
}
void
moo_edit_config_unset_by_source (MooEditConfig *config,
MooEditConfigSource source)
{
guint i;
g_return_if_fail (MOO_IS_EDIT_CONFIG (config));
g_object_ref (config);
g_object_freeze_notify (G_OBJECT (config));
for (i = 1; i < vars->len; ++i)
{
Value *val = VALUE (config, i);
if (val->source < source)
continue;
g_param_value_set_default (vars->data[i].pspec, &val->gval);
val->source = MOO_EDIT_CONFIG_SOURCE_AUTO;
if (config != global)
update_prop_from_global (config, GUINT_TO_POINTER (i));
object_notify (config, i);
}
g_object_thaw_notify (G_OBJECT (config));
g_object_unref (config);
}
guint
moo_edit_config_get_setting_id (GParamSpec *pspec)
{
g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), 0);
return GPOINTER_TO_UINT (g_param_spec_get_qdata (pspec, prop_id_quark));
}
static gboolean
parse_boolean (const char *value,
GValue *gval)
{
if (!g_ascii_strcasecmp (value, "true") ||
!g_ascii_strcasecmp (value, "on") ||
!g_ascii_strcasecmp (value, "yes") ||
!g_ascii_strcasecmp (value, "1"))
{
g_value_set_boolean (gval, TRUE);
}
else if (!g_ascii_strcasecmp (value, "false") ||
!g_ascii_strcasecmp (value, "off") ||
!g_ascii_strcasecmp (value, "no") ||
!g_ascii_strcasecmp (value, "0"))
{
g_value_set_boolean (gval, FALSE);
}
else
{
return FALSE;
}
return TRUE;
}
void
moo_edit_config_parse (MooEditConfig *config,
const char *name,
const char *value,
MooEditConfigSource source)
{
GValue gval;
gboolean result = FALSE;
GParamSpec *pspec;
guint prop_id;
g_return_if_fail (MOO_IS_EDIT_CONFIG (config));
g_return_if_fail (name != NULL);
g_return_if_fail (value != NULL);
pspec = moo_edit_config_lookup_spec (name, &prop_id);
if (!pspec)
{
g_warning ("%s: no setting named '%s'", G_STRLOC, name);
return;
}
gval.g_type = 0;
g_value_init (&gval, G_PARAM_SPEC_VALUE_TYPE (pspec));
if (G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_BOOLEAN)
result = parse_boolean (value, &gval);
else
result = moo_value_convert_from_string (value, &gval);
if (result)
moo_edit_config_set_value (config, prop_id, source, &gval);
else
g_warning ("%s: could not convert '%s' to type '%s'",
G_STRLOC, value, g_type_name (G_VALUE_TYPE (&gval)));
g_value_unset (&gval);
}

100
moo/mooedit/mooeditconfig.h Normal file
View File

@ -0,0 +1,100 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; coding: utf-8 -*-
*
* mooeditconfig.h
*
* Copyright (C) 2004-2005 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 __MOO_EDIT_CONFIG_H__
#define __MOO_EDIT_CONFIG_H__
#include <glib-object.h>
G_BEGIN_DECLS
#define MOO_TYPE_EDIT_CONFIG (moo_edit_config_get_type ())
#define MOO_EDIT_CONFIG(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), MOO_TYPE_EDIT_CONFIG, MooEditConfig))
#define MOO_EDIT_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MOO_TYPE_EDIT_CONFIG, MooEditConfigClass))
#define MOO_IS_EDIT_CONFIG(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), MOO_TYPE_EDIT_CONFIG))
#define MOO_IS_EDIT_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MOO_TYPE_EDIT_CONFIG))
#define MOO_EDIT_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MOO_TYPE_EDIT_CONFIG, MooEditConfigClass))
#define MOO_TYPE_EDIT_CONFIG_SOURCE (moo_edit_config_source_get_type ())
typedef struct _MooEditConfig MooEditConfig;
typedef struct _MooEditConfigPrivate MooEditConfigPrivate;
typedef struct _MooEditConfigClass MooEditConfigClass;
typedef enum {
MOO_EDIT_CONFIG_SOURCE_USER = 0,
MOO_EDIT_CONFIG_SOURCE_FILE = 10,
MOO_EDIT_CONFIG_SOURCE_FILENAME = 20,
MOO_EDIT_CONFIG_SOURCE_PREFS = 30,
MOO_EDIT_CONFIG_SOURCE_AUTO = 40
} MooEditConfigSource;
struct _MooEditConfig
{
GObject object;
MooEditConfigPrivate *priv;
};
struct _MooEditConfigClass
{
GObjectClass object_class;
};
GType moo_edit_config_get_type (void) G_GNUC_CONST;
GType moo_edit_config_source_get_type (void) G_GNUC_CONST;
MooEditConfig *moo_edit_config_new (void);
const char *moo_edit_config_get_string (MooEditConfig *config,
const char *setting);
guint moo_edit_config_get_uint (MooEditConfig *config,
const char *setting);
gboolean moo_edit_config_get_bool (MooEditConfig *config,
const char *setting);
void moo_edit_config_set (MooEditConfig *config,
const char *first_setting,
MooEditConfigSource source,
...); /* setting, source, value, ... */
void moo_edit_config_get (MooEditConfig *config,
const char *first_setting,
...); /* alias for g_object_get() */
void moo_edit_config_set_global (const char *first_setting,
MooEditConfigSource source,
...); /* setting, source, value, ... */
void moo_edit_config_get_global (const char *first_setting,
...); /* alias for g_object_get(global, ...) */
void moo_edit_config_parse (MooEditConfig *config,
const char *setting_name,
const char *value,
MooEditConfigSource source);
guint moo_edit_config_install_setting (GParamSpec *pspec);
guint moo_edit_config_get_setting_id (GParamSpec *pspec);
GParamSpec *moo_edit_config_get_spec (guint id);
GParamSpec *moo_edit_config_lookup_spec (const char *name,
guint *id);
void moo_edit_config_unset_by_source (MooEditConfig *config,
MooEditConfigSource source);
G_END_DECLS
#endif /* __MOO_EDIT_CONFIG_H__ */

View File

@ -368,7 +368,7 @@ moo_edit_save_multiple_changes_dialog (GSList *docs,
GSList **to_save)
{
GSList *l;
GtkWidget *dialog, *parent, *label, *treeview;
GtkWidget *dialog, *label, *treeview;
char *msg;
int response;
MooEditDialogResponse retval;

View File

@ -784,12 +784,12 @@ moo_editor_add_doc (MooEditor *editor,
g_hash_table_insert (editor->priv->savers, doc, moo_edit_saver_ref (saver));
if (!moo_edit_get_filename (doc) &&
!moo_edit_get_string (doc, MOO_EDIT_VAR_LANG) &&
!moo_edit_config_get_string (doc->config, "lang") &&
editor->priv->default_lang)
{
moo_edit_set_string (doc, MOO_EDIT_VAR_LANG,
editor->priv->default_lang,
MOO_EDIT_VAR_DEP_AUTO);
moo_edit_config_set (doc->config,
"lang", MOO_EDIT_CONFIG_SOURCE_AUTO,
editor->priv->default_lang, NULL);
}
}
@ -1509,7 +1509,7 @@ do_save (MooEditor *editor,
gboolean result;
gboolean strip;
strip = moo_edit_get_bool (doc, MOO_EDIT_VAR_STRIP, FALSE);
strip = moo_edit_config_get_bool (doc->config, "strip");
if (strip)
moo_text_view_strip_whitespace (MOO_TEXT_VIEW (doc));

View File

@ -1936,7 +1936,7 @@ lang_item_activated (MooEditWindow *window,
g_return_if_fail (doc != NULL);
g_return_if_fail (MOO_IS_EDIT_WINDOW (window));
old_val = moo_edit_get_string (doc, MOO_EDIT_VAR_LANG);
old_val = moo_edit_config_get_string (doc->config, "lang");
if (old_val)
do_set = !lang_name || strcmp (old_val, lang_name);
@ -1944,8 +1944,7 @@ lang_item_activated (MooEditWindow *window,
do_set = !!lang_name;
if (do_set)
moo_edit_set_string (doc, MOO_EDIT_VAR_LANG, lang_name,
MOO_EDIT_VAR_DEP_NONE);
moo_edit_config_set (doc->config, "lang", 0, lang_name, NULL);
}

View File

@ -36,15 +36,15 @@ static void moo_indenter_get_property (GObject *object,
static void character_default (MooIndenter *indenter,
gunichar inserted_char,
GtkTextIter *where);
static void update_variable_default (MooIndenter *indenter,
const char *var);
static void config_changed_default (MooIndenter *indenter,
guint setting_id);
static void variable_changed (MooIndenter *indenter,
const char *var);
static void config_notify (MooIndenter *indenter,
guint var_id);
enum {
UPDATE_VARIABLE,
CONFIG_CHANGED,
CHARACTER,
LAST_SIGNAL
};
@ -59,6 +59,14 @@ enum {
PROP_DOC
};
enum {
SETTING_TAB_WIDTH,
SETTING_USE_TABS,
SETTING_INDENT_WIDTH,
LAST_SETTING
};
static guint settings[LAST_SETTING];
/* MOO_TYPE_INDENTER */
G_DEFINE_TYPE (MooIndenter, moo_indenter, G_TYPE_OBJECT)
@ -75,15 +83,28 @@ moo_indenter_class_init (MooIndenterClass *klass)
gobject_class->get_property = moo_indenter_get_property;
klass->character = character_default;
klass->update_variable = update_variable_default;
klass->config_changed = config_changed_default;
moo_edit_register_var (g_param_spec_uint ("indent-tab-width", "indent-tab-width",
"indent-tab-width", 1, G_MAXUINT, 8, 0));
moo_edit_register_var (g_param_spec_boolean ("indent-use-tabs",
"indent-use-tabs", "indent-use-tabs", TRUE, 0));
moo_edit_register_var_alias ("indent-use-tabs", "use-tabs");
moo_edit_register_var (g_param_spec_uint ("indent-width", "indent-width",
"indent-width", 1, G_MAXUINT, 8, 0));
settings[SETTING_TAB_WIDTH] = moo_edit_config_install_setting (
g_param_spec_uint ("indent-tab-width",
"indent-tab-width",
"indent-tab-width",
1, G_MAXUINT, 8,
G_PARAM_READWRITE));
settings[SETTING_USE_TABS] = moo_edit_config_install_setting (
g_param_spec_boolean ("indent-use-tabs",
"indent-use-tabs",
"indent-use-tabs",
TRUE,
G_PARAM_READWRITE));
settings[SETTING_INDENT_WIDTH] = moo_edit_config_install_setting (
g_param_spec_uint ("indent-width",
"indent-width",
"indent-width",
1, G_MAXUINT, 8,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_DOC,
@ -121,15 +142,15 @@ moo_indenter_class_init (MooIndenterClass *klass)
8,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
signals[UPDATE_VARIABLE] =
g_signal_new ("update-variable",
signals[CONFIG_CHANGED] =
g_signal_new ("config-changed",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (MooIndenterClass, update_variable),
G_STRUCT_OFFSET (MooIndenterClass, config_changed),
NULL, NULL,
_moo_marshal_VOID__STRING,
_moo_marshal_VOID__UINT,
G_TYPE_NONE, 1,
G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
G_TYPE_UINT);
signals[CHARACTER] =
g_signal_new ("character",
@ -165,20 +186,11 @@ moo_indenter_constructor (GType type,
{
guint i;
static const char *vars[] = {
"indent-tab-width",
"indent-width",
"indent-use-tabs"
};
for (i = 0; i < LAST_SETTING; ++i)
config_notify (indent, settings[i]);
for (i = 0; i < G_N_ELEMENTS (vars); ++i)
{
if (moo_edit_get_var (indent->doc, vars[i], NULL))
variable_changed (indent, vars[i]);
}
g_signal_connect_swapped (indent->doc, "variable-changed",
G_CALLBACK (variable_changed),
g_signal_connect_swapped (indent->doc, "config-notify",
G_CALLBACK (config_notify),
indent);
}
@ -193,7 +205,7 @@ moo_indenter_finalize (GObject *object)
if (indent->doc)
g_signal_handlers_disconnect_by_func (indent->doc,
(gpointer) variable_changed,
(gpointer) config_notify,
indent);
G_OBJECT_CLASS(moo_indenter_parent_class)->finalize (object);
@ -269,10 +281,10 @@ static void moo_indenter_get_property (GObject *object,
static void
variable_changed (MooIndenter *indenter,
const char *var)
config_notify (MooIndenter *indenter,
guint var_id)
{
g_signal_emit (indenter, signals[UPDATE_VARIABLE], 0, var);
g_signal_emit (indenter, signals[CONFIG_CHANGED], 0, var_id);
}
@ -690,22 +702,26 @@ moo_indenter_shift_lines (MooIndenter *indenter,
static void
update_variable_default (MooIndenter *indenter,
const char *var)
config_changed_default (MooIndenter *indenter,
guint var_id)
{
if (!strcmp (var, "indent-tab-width"))
MooEdit *doc = indenter->doc;
g_return_if_fail (MOO_IS_EDIT (doc));
if (var_id == settings[SETTING_TAB_WIDTH])
{
guint tab_width = moo_edit_get_uint (indenter->doc, var, 8);
guint tab_width = moo_edit_config_get_uint (doc->config, "indent-tab-width");
g_object_set (indenter, "tab-width", tab_width, NULL);
}
else if (!strcmp (var, "indent-use-tabs"))
else if (var_id == settings[SETTING_USE_TABS])
{
gboolean use_tabs = moo_edit_get_bool (indenter->doc, var, TRUE);
gboolean use_tabs = moo_edit_config_get_bool (doc->config, "indent-use-tabs");
g_object_set (indenter, "use-tabs", use_tabs, NULL);
}
else if (!strcmp (var, "indent-width"))
else if (var_id == settings[SETTING_INDENT_WIDTH])
{
guint width = moo_edit_get_uint (indenter->doc, var, 8);
guint width = moo_edit_config_get_uint (doc->config, "indent-width");
g_object_set (indenter, "indent", width, NULL);
}
}

View File

@ -45,8 +45,8 @@ struct _MooIndenterClass
{
GObjectClass parent_class;
void (*update_variable) (MooIndenter *indenter,
const char *varname);
void (*config_changed) (MooIndenter *indenter,
guint setting_id);
void (*character) (MooIndenter *indenter,
gunichar inserted_char,
GtkTextIter *where);

View File

@ -116,17 +116,6 @@
;; Enumerations and flags ...
(define-enum EditVarDep
(in-module "Moo")
(c-name "MooEditVarDep")
(gtype-id "MOO_TYPE_EDIT_VAR_DEP")
(values
'("none" "MOO_EDIT_VAR_DEP_NONE")
'("filename" "MOO_EDIT_VAR_DEP_FILENAME")
'("auto" "MOO_EDIT_VAR_DEP_AUTO")
)
)
(define-enum EditOnExternalChanges
(in-module "Moo")
(c-name "MooEditOnExternalChanges")
@ -346,36 +335,6 @@
(return-type "gboolean")
)
;; (define-method set_var
;; (of-object "MooEdit")
;; (c-name "moo_edit_set_var")
;; (return-type "none")
;; (parameters
;; '("const-char*" "name")
;; '("const-char*" "value" (null-ok))
;; )
;; )
;; (define-method set_var_full
;; (of-object "MooEdit")
;; (c-name "moo_edit_set_var_full")
;; (return-type "none")
;; (parameters
;; '("const-char*" "name")
;; '("const-char*" "value" (null-ok))
;; '("MooEditVarDep" "dep")
;; )
;; )
;; (define-method get_var
;; (of-object "MooEdit")
;; (c-name "moo_edit_get_var")
;; (return-type "const-char*")
;; (parameters
;; '("const-char*" "name")
;; )
;; )
(define-method close
(of-object "MooEdit")
(c-name "moo_edit_close")

View File

@ -34,4 +34,5 @@ VOID:STRING,INT
VOID:STRING,STRING
VOID:UINT
VOID:UINT,BOXED
VOID:UINT,POINTER
VOID:VOID