Active stings plugin, working

master
Yevgen Muntyan 2006-02-27 05:40:15 -06:00
parent 98d747503a
commit 2fa1b8897e
9 changed files with 1490 additions and 449 deletions

View File

@ -19,3 +19,5 @@ missing
.*~
.*\.pcs
.*\.kdevses
.*\.gladep
.*\.bak

View File

@ -0,0 +1,687 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; coding: utf-8 -*-
*
* as-plugin-prefs.c
*
* 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.
*/
#include "as-plugin.h"
#include "mooedit/plugins/activestrings/as-plugin-glade.h"
#include "mooutils/mooprefsdialogpage.h"
enum {
COLUMN_PATTERN,
COLUMN_SCRIPT,
COLUMN_LANG,
COLUMN_ENABLED,
N_COLUMNS
};
static void prefs_page_apply (MooGladeXML *xml);
static void prefs_page_init (MooGladeXML *xml);
static void prefs_page_destroy (MooGladeXML *xml);
static void selection_changed (GtkTreeSelection *selection,
MooGladeXML *xml);
static void set_from_widgets (MooGladeXML *xml,
GtkTreeModel *model,
GtkTreePath *path);
static void set_from_model (MooGladeXML *xml,
GtkTreeModel *model,
GtkTreePath *path);
static void pattern_data_func (GtkTreeViewColumn *column,
GtkCellRenderer *cell,
GtkTreeModel *model,
GtkTreeIter *iter);
static void button_new (MooGladeXML *xml);
static void button_delete (MooGladeXML *xml);
static void button_up (MooGladeXML *xml);
static void button_down (MooGladeXML *xml);
static void pattern_changed (MooGladeXML *xml);
static void enabled_changed (MooGladeXML *xml);
static MooPlugin *
get_plugin (MooGladeXML *xml)
{
return g_object_get_data (G_OBJECT (xml), "as-plugin");
}
static void
setup_script_view (MooTextView *script)
{
MooLangMgr *mgr;
MooLang *lang;
MooIndenter *indent;
g_object_set (script, "highlight-current-line", FALSE, NULL);
mgr = moo_editor_get_lang_mgr (moo_editor_instance ());
lang = moo_lang_mgr_get_lang (mgr, "MooScript");
if (lang)
moo_text_view_set_lang (script, lang);
moo_text_view_set_font_from_string (script, "Monospace");
indent = moo_indenter_new (NULL, NULL);
moo_text_view_set_indenter (script, indent);
g_object_set (indent, "use-tabs", FALSE, "indent", 2, NULL);
g_object_unref (indent);
}
GtkWidget *
_as_plugin_prefs_page (MooPlugin *plugin)
{
GtkWidget *page;
MooGladeXML *xml;
GtkTreeSelection *selection;
GtkTreeView *treeview;
GtkTreeViewColumn *column;
GtkListStore *store;
GtkCellRenderer *cell;
xml = moo_glade_xml_new_empty ();
moo_glade_xml_map_id (xml, "script", MOO_TYPE_TEXT_VIEW);
moo_glade_xml_map_id (xml, "page", MOO_TYPE_PREFS_DIALOG_PAGE);
moo_glade_xml_parse_memory (xml, AS_PLUGIN_GLADE_UI, -1, "page");
page = moo_glade_xml_get_widget (xml, "page");
g_return_val_if_fail (page != NULL, NULL);
g_object_set (page, "label", "Active Strings",
"icon-stock-id", GTK_STOCK_CONVERT, NULL);
g_object_set_data_full (G_OBJECT (xml), "as-plugin",
g_object_ref (plugin), (GDestroyNotify) g_object_unref);
g_object_set_data_full (G_OBJECT (page), "moo-glade-xml", xml,
(GDestroyNotify) g_object_unref);
g_signal_connect_swapped (page, "apply", G_CALLBACK (prefs_page_apply), xml);
g_signal_connect_swapped (page, "init", G_CALLBACK (prefs_page_init), xml);
g_signal_connect_swapped (page, "destroy", G_CALLBACK (prefs_page_destroy), xml);
setup_script_view (moo_glade_xml_get_widget (xml, "script"));
store = gtk_list_store_new (N_COLUMNS,
G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_BOOLEAN);
treeview = moo_glade_xml_get_widget (xml, "treeview");
selection = gtk_tree_view_get_selection (treeview);
g_signal_connect (selection, "changed",
G_CALLBACK (selection_changed), xml);
gtk_tree_view_set_model (treeview, GTK_TREE_MODEL (store));
g_object_unref (store);
column = gtk_tree_view_column_new ();
gtk_tree_view_append_column (treeview, column);
cell = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (column, cell, TRUE);
gtk_tree_view_column_set_cell_data_func (column, cell,
(GtkTreeCellDataFunc) pattern_data_func,
NULL, NULL);
g_signal_connect_swapped (moo_glade_xml_get_widget (xml, "new"),
"clicked", G_CALLBACK (button_new), xml);
g_signal_connect_swapped (moo_glade_xml_get_widget (xml, "delete"),
"clicked", G_CALLBACK (button_delete), xml);
g_signal_connect_swapped (moo_glade_xml_get_widget (xml, "up"),
"clicked", G_CALLBACK (button_up), xml);
g_signal_connect_swapped (moo_glade_xml_get_widget (xml, "down"),
"clicked", G_CALLBACK (button_down), xml);
g_signal_connect_swapped (moo_glade_xml_get_widget (xml, "pattern"),
"changed", G_CALLBACK (pattern_changed), xml);
g_signal_connect_swapped (moo_glade_xml_get_widget (xml, "enabled"),
"toggled", G_CALLBACK (enabled_changed), xml);
return page;
}
static void
pattern_data_func (G_GNUC_UNUSED GtkTreeViewColumn *column,
GtkCellRenderer *cell,
GtkTreeModel *model,
GtkTreeIter *iter)
{
gboolean enabled;
char *pattern;
gtk_tree_model_get (model, iter,
COLUMN_ENABLED, &enabled,
COLUMN_PATTERN, &pattern, -1);
g_object_set (cell, "text", pattern,
"foreground", enabled ? NULL : "grey",
"style", enabled ? PANGO_STYLE_NORMAL : PANGO_STYLE_ITALIC,
NULL);
g_free (pattern);
}
static gboolean
is_empty_string (const char *string)
{
if (!string)
return TRUE;
#define IS_SPACE(c) (c == ' ' || c == '\t' || c == '\r' || c == '\n')
while (*string)
{
if (*string && !IS_SPACE (*string))
return FALSE;
string++;
}
#undef IS_SPACE
return TRUE;
}
static void
save_items (GtkTreeModel *model,
MooMarkupDoc *doc)
{
GtkTreeIter iter;
MooMarkupNode *root;
if (!gtk_tree_model_get_iter_first (model, &iter))
return;
root = moo_markup_create_element (MOO_MARKUP_NODE (doc), AS_XML_ROOT);
do
{
MooMarkupNode *node;
char *pattern, *lang, *script;
gboolean enabled;
gtk_tree_model_get (model, &iter,
COLUMN_PATTERN, &pattern,
COLUMN_LANG, &lang,
COLUMN_SCRIPT, &script,
COLUMN_ENABLED, &enabled,
-1);
if (is_empty_string (script))
{
g_free (script);
script = NULL;
}
if (is_empty_string (lang))
{
g_free (lang);
lang = NULL;
}
if (is_empty_string (pattern))
{
g_free (pattern);
pattern = NULL;
}
if (script)
node = moo_markup_create_text_element (root, AS_XML_ITEM, script);
else
node = moo_markup_create_element (root, AS_XML_ITEM);
if (pattern)
moo_markup_set_prop (node, AS_XML_PROP_PATTERN, pattern);
if (lang)
moo_markup_set_prop (node, AS_XML_PROP_LANG, lang);
if (!enabled)
moo_markup_set_bool_prop (node, AS_XML_PROP_ENABLED, FALSE);
g_free (pattern);
g_free (lang);
g_free (script);
}
while (gtk_tree_model_iter_next (model, &iter));
}
static void
prefs_page_apply (MooGladeXML *xml)
{
GtkTreeIter iter;
GtkTreeModel *model;
GtkTreeSelection *selection;
MooMarkupDoc *doc;
MooMarkupNode *root;
doc = moo_prefs_get_markup ();
g_return_if_fail (doc != NULL);
selection = gtk_tree_view_get_selection (moo_glade_xml_get_widget (xml, "treeview"));
if (gtk_tree_selection_get_selected (selection, &model, &iter))
{
GtkTreePath *path = gtk_tree_model_get_path (model, &iter);
set_from_widgets (xml, model, path);
gtk_tree_path_free (path);
}
root = moo_markup_get_element (MOO_MARKUP_NODE (doc), AS_XML_ROOT);
if (root)
moo_markup_delete_node (root);
save_items (model, doc);
_as_plugin_reload (get_plugin (xml));
}
static void
insert_item (const char *pattern,
const char *script,
const char *lang,
gboolean enabled,
GtkListStore *store)
{
GtkTreeIter iter;
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
COLUMN_PATTERN, pattern,
COLUMN_LANG, lang,
COLUMN_SCRIPT, script,
COLUMN_ENABLED, enabled,
-1);
}
static void
prefs_page_init (MooGladeXML *xml)
{
GtkTreeIter iter;
GtkListStore *store;
GtkTreeModel *model;
model = gtk_tree_view_get_model (moo_glade_xml_get_widget (xml, "treeview"));
store = GTK_LIST_STORE (model);
if (gtk_tree_model_get_iter_first (model, &iter))
while (gtk_list_store_remove (store, &iter))
;
_as_plugin_load (get_plugin (xml), (ASLoadFunc) insert_item, model);
set_from_model (xml, model, NULL);
}
static gboolean
get_selected (MooGladeXML *xml,
GtkTreeModel **model,
GtkTreeIter *iter)
{
GtkTreeSelection *selection;
selection = gtk_tree_view_get_selection (moo_glade_xml_get_widget (xml, "treeview"));
return gtk_tree_selection_get_selected (selection, model, iter);
}
static void
set_from_widgets (MooGladeXML *xml,
GtkTreeModel *model,
GtkTreePath *path)
{
GtkTreeIter iter;
GtkToggleButton *button;
GtkTextBuffer *buffer;
GtkTextIter start, end;
const char *pattern, *lang;
char *script;
gtk_tree_model_get_iter (model, &iter, path);
pattern = gtk_entry_get_text (moo_glade_xml_get_widget (xml, "pattern"));
lang = gtk_entry_get_text (moo_glade_xml_get_widget (xml, "lang"));
button = moo_glade_xml_get_widget (xml, "enabled");
buffer = gtk_text_view_get_buffer (moo_glade_xml_get_widget (xml, "script"));
gtk_text_buffer_get_bounds (buffer, &start, &end);
script = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
COLUMN_PATTERN, pattern,
COLUMN_SCRIPT, script,
COLUMN_LANG, lang,
COLUMN_ENABLED, gtk_toggle_button_get_active (button),
-1);
g_free (script);
}
static void
script_set_text (gpointer view,
const char *text)
{
g_return_if_fail (MOO_IS_TEXT_VIEW (view));
moo_text_view_begin_not_undoable_action (view);
gtk_text_buffer_set_text (gtk_text_view_get_buffer (view), text, -1);
moo_text_view_end_not_undoable_action (view);
}
static void
set_from_model (MooGladeXML *xml,
GtkTreeModel *model,
GtkTreePath *path)
{
GtkTreeIter iter;
GtkWidget *button_new, *button_delete, *button_up, *button_down;
GtkWidget *table;
GtkToggleButton *button_enabled;
GtkEntry *entry_pattern, *entry_lang;
GtkTextView *script_view;
GtkTextBuffer *buffer;
g_signal_handlers_block_by_func (moo_glade_xml_get_widget (xml, "pattern"),
(gpointer) pattern_changed, xml);
g_signal_handlers_block_by_func (moo_glade_xml_get_widget (xml, "enabled"),
(gpointer) enabled_changed, xml);
button_new = moo_glade_xml_get_widget (xml, "new");
button_delete = moo_glade_xml_get_widget (xml, "delete");
button_up = moo_glade_xml_get_widget (xml, "up");
button_down = moo_glade_xml_get_widget (xml, "down");
table = moo_glade_xml_get_widget (xml, "table");
entry_pattern = moo_glade_xml_get_widget (xml, "pattern");
entry_lang = moo_glade_xml_get_widget (xml, "lang");
button_enabled = moo_glade_xml_get_widget (xml, "enabled");
script_view = moo_glade_xml_get_widget (xml, "script");
buffer = gtk_text_view_get_buffer (script_view);
if (path)
gtk_tree_model_get_iter (model, &iter, path);
if (!path)
{
gtk_widget_set_sensitive (button_delete, FALSE);
gtk_widget_set_sensitive (button_up, FALSE);
gtk_widget_set_sensitive (button_down, FALSE);
gtk_widget_set_sensitive (GTK_WIDGET (button_enabled), FALSE);
gtk_widget_set_sensitive (table, FALSE);
gtk_entry_set_text (entry_pattern, "");
gtk_entry_set_text (entry_lang, "");
script_set_text (script_view, "");
gtk_toggle_button_set_active (button_enabled, FALSE);
}
else
{
char *pattern, *lang, *script;
gboolean enabled;
int *indices;
gtk_tree_model_get (model, &iter,
COLUMN_PATTERN, &pattern,
COLUMN_LANG, &lang,
COLUMN_SCRIPT, &script,
COLUMN_ENABLED, &enabled,
-1);
gtk_widget_set_sensitive (button_delete, TRUE);
gtk_widget_set_sensitive (GTK_WIDGET (button_enabled), TRUE);
gtk_widget_set_sensitive (table, TRUE);
gtk_entry_set_text (entry_pattern, pattern ? pattern : "");
gtk_entry_set_text (entry_lang, lang ? lang : "");
script_set_text (script_view, script ? script : "");
gtk_toggle_button_set_active (button_enabled, enabled);
indices = gtk_tree_path_get_indices (path);
gtk_widget_set_sensitive (button_up, indices[0] != 0);
gtk_widget_set_sensitive (button_down, indices[0] !=
gtk_tree_model_iter_n_children (model, NULL) - 1);
}
g_signal_handlers_unblock_by_func (moo_glade_xml_get_widget (xml, "pattern"),
(gpointer) pattern_changed, xml);
g_signal_handlers_unblock_by_func (moo_glade_xml_get_widget (xml, "enabled"),
(gpointer) enabled_changed, xml);
}
static void
selection_changed (GtkTreeSelection *selection,
MooGladeXML *xml)
{
GtkTreeRowReference *old_row;
GtkTreeModel *model;
GtkTreeIter iter;
GtkTreePath *path, *old_path;
old_row = g_object_get_data (G_OBJECT (selection), "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 (selection), "current-row", NULL);
old_row = NULL;
}
if (gtk_tree_selection_get_selected (selection, &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)
set_from_widgets (xml, model, old_path);
set_from_model (xml, model, path);
if (path)
{
GtkTreeRowReference *row;
row = gtk_tree_row_reference_new (model, path);
g_object_set_data_full (G_OBJECT (selection), "current-row", row,
(GDestroyNotify) gtk_tree_row_reference_free);
}
else
{
g_object_set_data (G_OBJECT (selection), "current-row", NULL);
}
gtk_tree_path_free (path);
gtk_tree_path_free (old_path);
}
static void
button_new (MooGladeXML *xml)
{
GtkTreeModel *model;
GtkTreeIter iter, after;
GtkTreeSelection *selection;
GtkTreeView *treeview;
treeview = moo_glade_xml_get_widget (xml, "treeview");
if (!get_selected (xml, &model, &after))
gtk_list_store_append (GTK_LIST_STORE (model), &iter);
else
gtk_list_store_insert_after (GTK_LIST_STORE (model), &iter, &after);
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
COLUMN_PATTERN, "?",
COLUMN_ENABLED, TRUE, -1);
selection = gtk_tree_view_get_selection (treeview);
gtk_tree_selection_select_iter (selection, &iter);
}
static void
button_delete (MooGladeXML *xml)
{
GtkTreeModel *model;
GtkTreeIter iter;
GtkTreeSelection *selection;
GtkTreeView *treeview;
if (!get_selected (xml, &model, &iter))
g_return_if_reached ();
if (!gtk_list_store_remove (GTK_LIST_STORE (model), &iter))
{
int n_children;
n_children = gtk_tree_model_iter_n_children (model, NULL);
if (n_children)
gtk_tree_model_iter_nth_child (model, &iter, NULL,
n_children - 1);
}
if (gtk_tree_model_iter_n_children (model, NULL))
{
treeview = moo_glade_xml_get_widget (xml, "treeview");
selection = gtk_tree_view_get_selection (treeview);
gtk_tree_selection_select_iter (selection, &iter);
}
}
static void
button_up (MooGladeXML *xml)
{
GtkTreeModel *model;
GtkTreeIter iter;
GtkTreeIter swap_with;
GtkTreePath *path, *new_path;
int *indices;
if (!get_selected (xml, &model, &iter))
g_return_if_reached ();
path = gtk_tree_model_get_path (model, &iter);
indices = gtk_tree_path_get_indices (path);
if (!indices[0])
g_return_if_reached ();
new_path = gtk_tree_path_new_from_indices (indices[0] - 1, -1);
gtk_tree_model_get_iter (model, &swap_with, new_path);
gtk_list_store_swap (GTK_LIST_STORE (model), &iter, &swap_with);
set_from_model (xml, model, new_path);
gtk_tree_path_free (new_path);
gtk_tree_path_free (path);
}
static void
button_down (MooGladeXML *xml)
{
GtkTreeModel *model;
GtkTreeIter iter;
GtkTreeIter swap_with;
GtkTreePath *path, *new_path;
int *indices;
int n_children;
if (!get_selected (xml, &model, &iter))
g_return_if_reached ();
path = gtk_tree_model_get_path (model, &iter);
indices = gtk_tree_path_get_indices (path);
n_children = gtk_tree_model_iter_n_children (model, NULL);
if (indices[0] == n_children - 1)
g_return_if_reached ();
new_path = gtk_tree_path_new_from_indices (indices[0] + 1, -1);
gtk_tree_model_get_iter (model, &swap_with, new_path);
gtk_list_store_swap (GTK_LIST_STORE (model), &iter, &swap_with);
set_from_model (xml, model, new_path);
gtk_tree_path_free (new_path);
gtk_tree_path_free (path);
}
static void
pattern_changed (MooGladeXML *xml)
{
GtkEntry *entry;
GtkTreeModel *model;
GtkTreeIter iter;
const char *pattern;
if (!get_selected (xml, &model, &iter))
return;
entry = moo_glade_xml_get_widget (xml, "pattern");
pattern = gtk_entry_get_text (entry);
gtk_list_store_set (GTK_LIST_STORE (model), &iter, COLUMN_PATTERN, pattern, -1);
}
static void
enabled_changed (MooGladeXML *xml)
{
GtkToggleButton *button;
GtkTreeModel *model;
GtkTreeIter iter;
if (!get_selected (xml, &model, &iter))
return;
button = moo_glade_xml_get_widget (xml, "enabled");
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
COLUMN_ENABLED, gtk_toggle_button_get_active (button), -1);
}
static void
prefs_page_destroy (MooGladeXML *xml)
{
GtkTreeSelection *selection;
selection = gtk_tree_view_get_selection (moo_glade_xml_get_widget (xml, "treeview"));
g_signal_handlers_disconnect_by_func (selection, (gpointer) selection_changed, xml);
g_signal_handlers_disconnect_by_func (moo_glade_xml_get_widget (xml, "new"),
(gpointer) button_new, xml);
g_signal_handlers_disconnect_by_func (moo_glade_xml_get_widget (xml, "delete"),
(gpointer) button_delete, xml);
g_signal_handlers_disconnect_by_func (moo_glade_xml_get_widget (xml, "up"),
(gpointer) button_up, xml);
g_signal_handlers_disconnect_by_func (moo_glade_xml_get_widget (xml, "down"),
(gpointer) button_down, xml);
g_signal_handlers_disconnect_by_func (moo_glade_xml_get_widget (xml, "pattern"),
(gpointer) pattern_changed, xml);
g_signal_handlers_disconnect_by_func (moo_glade_xml_get_widget (xml, "enabled"),
(gpointer) enabled_changed, xml);
}

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; coding: utf-8 -*-
*
* ms-plugin-script.c
* as-plugin-script.c
*
* Copyright (C) 2004-2006 by Yevgen Muntyan <muntyan@math.tamu.edu>
*
@ -12,37 +12,37 @@
* See COPYING file that comes with this distribution.
*/
#include "ms-plugin-script.h"
#include "as-plugin-script.h"
static void ms_plugin_context_init_api (MSPluginContext *ctx);
static void as_plugin_context_init_api (ASPluginContext *ctx);
G_DEFINE_TYPE (MSPluginContext, _ms_plugin_context, MS_TYPE_CONTEXT)
G_DEFINE_TYPE (ASPluginContext, _as_plugin_context, MS_TYPE_CONTEXT)
static void
_ms_plugin_context_init (MSPluginContext *ctx)
_as_plugin_context_init (ASPluginContext *ctx)
{
ms_plugin_context_init_api (ctx);
as_plugin_context_init_api (ctx);
}
static void
_ms_plugin_context_class_init (G_GNUC_UNUSED MSPluginContextClass *klass)
_as_plugin_context_class_init (G_GNUC_UNUSED ASPluginContextClass *klass)
{
}
MSContext *
_ms_plugin_context_new (void)
_as_plugin_context_new (void)
{
return g_object_new (MS_TYPE_PLUGIN_CONTEXT, NULL);
return g_object_new (AS_TYPE_PLUGIN_CONTEXT, NULL);
}
static void
ms_plugin_context_setup (MSPluginContext *ctx,
as_plugin_context_setup (ASPluginContext *ctx,
MooEdit *doc,
char *match,
char **parens,
@ -67,7 +67,7 @@ ms_plugin_context_setup (MSPluginContext *ctx,
static void
ms_plugin_context_clear (MSPluginContext *ctx,
as_plugin_context_clear (ASPluginContext *ctx,
guint n_parens)
{
guint i;
@ -81,7 +81,7 @@ ms_plugin_context_clear (MSPluginContext *ctx,
gboolean
_ms_plugin_context_exec (MSContext *ctx,
_as_plugin_context_exec (MSContext *ctx,
MSNode *script,
MooEdit *doc,
GtkTextIter *insert,
@ -92,14 +92,14 @@ _ms_plugin_context_exec (MSContext *ctx,
MSValue *val;
gboolean success;
g_return_val_if_fail (MS_IS_PLUGIN_CONTEXT (ctx), FALSE);
g_return_val_if_fail (AS_IS_PLUGIN_CONTEXT (ctx), FALSE);
g_return_val_if_fail (MS_IS_NODE (script), FALSE);
g_return_val_if_fail (MOO_IS_EDIT (doc), FALSE);
g_return_val_if_fail (insert != NULL, FALSE);
g_return_val_if_fail (match != NULL, FALSE);
g_return_val_if_fail (!n_parens || parens, FALSE);
ms_plugin_context_setup (MS_PLUGIN_CONTEXT (ctx),
as_plugin_context_setup (AS_PLUGIN_CONTEXT (ctx),
doc, match, parens, n_parens);
val = ms_node_eval (script, ctx);
@ -114,7 +114,7 @@ _ms_plugin_context_exec (MSContext *ctx,
ms_context_clear_error (ctx);
}
ms_plugin_context_clear (MS_PLUGIN_CONTEXT (ctx), n_parens);
as_plugin_context_clear (AS_PLUGIN_CONTEXT (ctx), n_parens);
return success;
}
@ -134,7 +134,7 @@ enum {
static const char *builtin_func_names[N_BUILTIN_FUNCS] = {
"bs", "del", "ins", "up", "down", "left", "right", "sel"
"Bs", "Del", "Ins", "Up", "Down", "Left", "Right", "Sel"
};
static MSFunc *builtin_funcs[N_BUILTIN_FUNCS];
@ -143,7 +143,7 @@ static MSFunc *builtin_funcs[N_BUILTIN_FUNCS];
static gboolean
check_one_arg (MSValue **args,
guint n_args,
MSPluginContext *ctx,
ASPluginContext *ctx,
gboolean nonnegative,
int *dest,
int default_val)
@ -185,7 +185,7 @@ check_one_arg (MSValue **args,
static MSValue *
cfunc_bs (MSValue **args,
guint n_args,
MSPluginContext *ctx)
ASPluginContext *ctx)
{
int n;
GtkTextIter start, end;
@ -218,7 +218,7 @@ cfunc_bs (MSValue **args,
static MSValue *
cfunc_del (MSValue **args,
guint n_args,
MSPluginContext *ctx)
ASPluginContext *ctx)
{
int n;
GtkTextIter start, end;
@ -268,7 +268,7 @@ get_cursor (MooEdit *doc,
static MSValue *
cfunc_up (MSValue **args,
guint n_args,
MSPluginContext *ctx)
ASPluginContext *ctx)
{
int line, col, n;
@ -292,7 +292,7 @@ cfunc_up (MSValue **args,
static MSValue *
cfunc_down (MSValue **args,
guint n_args,
MSPluginContext *ctx)
ASPluginContext *ctx)
{
int line, col, n, line_count;
GtkTextBuffer *buffer;
@ -317,7 +317,7 @@ cfunc_down (MSValue **args,
static MSValue *
cfunc_sel (MSValue *arg,
MSPluginContext *ctx)
ASPluginContext *ctx)
{
int n;
GtkTextBuffer *buffer;
@ -362,7 +362,7 @@ move_cursor (MooEdit *doc,
static MSValue *
cfunc_left (MSValue **args,
guint n_args,
MSPluginContext *ctx)
ASPluginContext *ctx)
{
int n;
@ -377,7 +377,7 @@ cfunc_left (MSValue **args,
static MSValue *
cfunc_right (MSValue **args,
guint n_args,
MSPluginContext *ctx)
ASPluginContext *ctx)
{
int n;
@ -392,7 +392,7 @@ cfunc_right (MSValue **args,
static MSValue *
cfunc_ins (MSValue **args,
guint n_args,
MSPluginContext *ctx)
ASPluginContext *ctx)
{
guint i;
GtkTextIter start, end;
@ -435,7 +435,7 @@ init_api (void)
static void
ms_plugin_context_init_api (MSPluginContext *ctx)
as_plugin_context_init_api (ASPluginContext *ctx)
{
guint i;

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; coding: utf-8 -*-
*
* ms-plugin-script.h
* as-plugin-script.h
*
* Copyright (C) 2004-2006 by Yevgen Muntyan <muntyan@math.tamu.edu>
*
@ -12,8 +12,8 @@
* See COPYING file that comes with this distribution.
*/
#ifndef __MS_PLUGIN_SCRIPT_H__
#define __MS_PLUGIN_SCRIPT_H__
#ifndef __AS_PLUGIN_SCRIPT_H__
#define __AS_PLUGIN_SCRIPT_H__
#include "mooutils/mooscript/mooscript-context.h"
#include "mooutils/mooscript/mooscript-node.h"
@ -22,32 +22,32 @@
G_BEGIN_DECLS
#define MS_TYPE_PLUGIN_CONTEXT (_ms_plugin_context_get_type ())
#define MS_PLUGIN_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), MS_TYPE_PLUGIN_CONTEXT, MSPluginContext))
#define MS_PLUGIN_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MS_TYPE_PLUGIN_CONTEXT, MSPluginContextClass))
#define MS_IS_PLUGIN_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), MS_TYPE_PLUGIN_CONTEXT))
#define MS_IS_PLUGIN_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MS_TYPE_PLUGIN_CONTEXT))
#define MS_PLUGIN_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MS_TYPE_PLUGIN_CONTEXT, MSPluginContextClass))
#define AS_TYPE_PLUGIN_CONTEXT (_as_plugin_context_get_type ())
#define AS_PLUGIN_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), AS_TYPE_PLUGIN_CONTEXT, ASPluginContext))
#define AS_PLUGIN_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), AS_TYPE_PLUGIN_CONTEXT, ASPluginContextClass))
#define AS_IS_PLUGIN_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), AS_TYPE_PLUGIN_CONTEXT))
#define AS_IS_PLUGIN_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), AS_TYPE_PLUGIN_CONTEXT))
#define AS_PLUGIN_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), AS_TYPE_PLUGIN_CONTEXT, ASPluginContextClass))
typedef struct _MSPluginContext MSPluginContext;
typedef struct _MSPluginContextClass MSPluginContextClass;
typedef struct _ASPluginContext ASPluginContext;
typedef struct _ASPluginContextClass ASPluginContextClass;
struct _MSPluginContext {
struct _ASPluginContext {
MSContext context;
MooEdit *doc;
};
struct _MSPluginContextClass {
struct _ASPluginContextClass {
MSContextClass context_class;
};
GType _ms_plugin_context_get_type (void) G_GNUC_CONST;
GType _as_plugin_context_get_type (void) G_GNUC_CONST;
MSContext *_ms_plugin_context_new (void);
MSContext *_as_plugin_context_new (void);
gboolean _ms_plugin_context_exec (MSContext *ctx,
gboolean _as_plugin_context_exec (MSContext *ctx,
MSNode *script,
MooEdit *doc,
GtkTextIter *insert,
@ -58,4 +58,4 @@ gboolean _ms_plugin_context_exec (MSContext *ctx,
G_END_DECLS
#endif /* __MS_PLUGIN_SCRIPT_H__ */
#endif /* __AS_PLUGIN_SCRIPT_H__ */

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; coding: utf-8 -*-
*
* ms-plugin.c
* as-plugin.c
*
* Copyright (C) 2004-2006 by Yevgen Muntyan <muntyan@math.tamu.edu>
*
@ -23,34 +23,42 @@
#include "mooedit/mootextview.h"
#include "mooedit/plugins/mooeditplugins.h"
#include "mooutils/eggregex.h"
#include "ms-plugin-script.h"
#include "ms-plugin-xml.h"
#include "as-plugin-script.h"
#include "as-plugin.h"
#include "mooutils/mooscript/mooscript-parser.h"
#include <string.h>
#define MS_PLUGIN_ID "ActiveStrings"
#define MS_DATA "moo-active-strings"
#define MS_WILDCARD '?'
#define AS_PLUGIN_ID "ActiveStrings"
#define AS_DATA "moo-active-strings"
#define AS_WILDCARD '?'
#define PREFS_ROOT MOO_PLUGIN_PREFS_ROOT "/" MS_PLUGIN_ID
#define PREFS_ROOT MOO_PLUGIN_PREFS_ROOT "/" AS_PLUGIN_ID
#define FILE_PREFS_KEY PREFS_ROOT "/file"
typedef struct _MSPlugin MSPlugin;
typedef struct _MSSet MSSet;
typedef struct _MSString MSString;
typedef struct _MSStringInfo MSStringInfo;
typedef struct _MSMatch MSMatch;
typedef struct _ASPlugin ASPlugin;
typedef struct _ASSet ASSet;
typedef struct _ASString ASString;
typedef struct _ASStringInfo ASStringInfo;
typedef struct _ASMatch ASMatch;
typedef struct _ASInfo ASInfo;
struct _MSPlugin {
struct _ASInfo {
char *pattern;
char *script;
char *lang;
guint enabled : 1;
};
struct _ASPlugin {
MooPlugin parent;
MSContext *ctx;
GHashTable *lang_sets;
MSSet *any_lang;
ASSet *any_lang;
};
struct _MSStringInfo {
struct _ASStringInfo {
guint n_wildcards;
char *pattern;
guint pattern_len;
@ -58,14 +66,14 @@ struct _MSStringInfo {
char *script;
};
struct _MSString {
struct _ASString {
guint whole;
guint *parens;
guint n_parens;
};
struct _MSSet {
MSString **strings;
struct _ASSet {
ASString **strings;
char **scripts;
guint n_strings;
EggRegex *regex;
@ -76,7 +84,7 @@ struct _MSSet {
guint n_last_chars;
};
struct _MSMatch {
struct _ASMatch {
guint string_no;
/* all offsets are in chars here */
guint start_offset;
@ -86,23 +94,23 @@ struct _MSMatch {
};
typedef enum {
MS_WORD_BOUNDARY = 1 << 0,
MS_NOT_WORD_BOUNDARY = 1 << 1
} MSOptions;
AS_WORD_BOUNDARY = 1 << 0,
AS_NOT_WORD_BOUNDARY = 1 << 1
} ASOptions;
static gboolean ms_plugin_init (MSPlugin *plugin);
static void ms_plugin_deinit (MSPlugin *plugin);
static void ms_plugin_attach (MSPlugin *plugin,
static gboolean as_plugin_init (ASPlugin *plugin);
static void as_plugin_deinit (ASPlugin *plugin);
static void as_plugin_attach (ASPlugin *plugin,
MooEdit *doc);
static void ms_plugin_detach (MSPlugin *plugin,
static void as_plugin_detach (ASPlugin *plugin,
MooEdit *doc);
static void ms_plugin_do_action (MSPlugin *plugin,
static void as_plugin_do_action (ASPlugin *plugin,
MooEdit *doc,
GtkTextIter *insert,
MSSet *set,
MSMatch *match,
ASSet *set,
ASMatch *match,
char *full_text,
char **parens_text);
@ -112,26 +120,58 @@ static gboolean char_inserted_cb (MooEdit *doc,
GSList *sets);
static void process_match (MooEdit *doc,
GtkTextIter *end,
MSSet *set,
MSMatch *match);
ASSet *set,
ASMatch *match);
static MSSet *ms_set_new (MSStringInfo **strings,
static ASSet *as_set_new (ASStringInfo **strings,
guint n_strings);
static void ms_set_unref (MSSet *set);
static MSSet *ms_set_ref (MSSet *set);
static gboolean ms_set_check_last (MSSet *set,
static void as_set_unref (ASSet *set);
static ASSet *as_set_ref (ASSet *set);
static gboolean as_set_check_last (ASSet *set,
gunichar c);
static gboolean ms_set_match (MSSet *set,
static gboolean as_set_match (ASSet *set,
const char *text,
MSMatch *match);
ASMatch *match);
static void ms_string_info_set_script (MSStringInfo *info,
static void as_string_info_set_script (ASStringInfo *info,
const char *script);
static void ms_string_info_free (MSStringInfo *info);
static void as_string_info_free (ASStringInfo *info);
static void ms_match_destroy (MSMatch *match);
static MSString *ms_string_new (guint n_wildcards);
static void ms_string_free (MSString *s);
static void as_match_destroy (ASMatch *match);
static ASString *as_string_new (guint n_wildcards);
static void as_string_free (ASString *s);
static ASInfo *
as_info_new (const char *pattern,
const char *script,
const char *lang,
gboolean enabled)
{
ASInfo *info;
g_return_val_if_fail (pattern && pattern[0], NULL);
info = g_new0 (ASInfo, 1);
info->pattern = (pattern && pattern[0]) ? g_strdup (pattern) : NULL;
info->script = (script && script[0]) ? g_strdup (script) : NULL;
info->lang = (lang && lang[0]) ? g_ascii_strdown (lang, -1) : NULL;
info->enabled = enabled != 0;
return info;
}
static void
as_info_free (ASInfo *info)
{
if (info)
{
g_free (info->pattern);
g_free (info->script);
g_free (info->lang);
g_free (info);
}
}
static int
@ -143,11 +183,11 @@ cmp_ints (gunichar *c1, gunichar *c2)
static void
append_options (GString *pattern,
MSOptions opts)
ASOptions opts)
{
if (opts & MS_WORD_BOUNDARY)
if (opts & AS_WORD_BOUNDARY)
g_string_append (pattern, "\\b");
else if (opts & MS_NOT_WORD_BOUNDARY)
else if (opts & AS_NOT_WORD_BOUNDARY)
g_string_append (pattern, "\\B");
}
@ -164,15 +204,15 @@ append_escaped (GString *pattern,
}
static MSStringInfo *
ms_string_get_info (const char *string,
MSOptions start_opts,
MSOptions end_opts,
static ASStringInfo *
as_string_get_info (const char *string,
ASOptions start_opts,
ASOptions end_opts,
guint string_no)
{
char *wc, *p;
guint rev_len;
MSStringInfo *info = NULL;
ASStringInfo *info = NULL;
char *rev = NULL;
GString *pattern = NULL;
@ -184,17 +224,17 @@ ms_string_get_info (const char *string,
rev = g_utf8_strreverse (string, -1);
rev_len = strlen (rev);
info = g_new0 (MSStringInfo, 1);
info = g_new0 (ASStringInfo, 1);
if (string[0] == MS_WILDCARD && string[1] != MS_WILDCARD)
if (string[0] == AS_WILDCARD && string[1] != AS_WILDCARD)
{
g_critical ("%s: leading '%c' symbol", G_STRLOC, MS_WILDCARD);
g_critical ("%s: leading '%c' symbol", G_STRLOC, AS_WILDCARD);
goto error;
}
if (rev[0] == MS_WILDCARD && rev[1] != MS_WILDCARD)
if (rev[0] == AS_WILDCARD && rev[1] != AS_WILDCARD)
{
g_critical ("%s: trailing '%c' symbol", G_STRLOC, MS_WILDCARD);
g_critical ("%s: trailing '%c' symbol", G_STRLOC, AS_WILDCARD);
goto error;
}
@ -208,7 +248,7 @@ ms_string_get_info (const char *string,
for (p = rev; *p; )
{
wc = strchr (p, MS_WILDCARD);
wc = strchr (p, AS_WILDCARD);
if (!wc)
{
@ -216,7 +256,7 @@ ms_string_get_info (const char *string,
break;
}
if (wc[1] == MS_WILDCARD)
if (wc[1] == AS_WILDCARD)
{
append_escaped (pattern, p, wc - p + 1);
p = wc + 2;
@ -242,7 +282,7 @@ ms_string_get_info (const char *string,
return info;
error:
ms_string_info_free (info);
as_string_info_free (info);
g_free (rev);
if (pattern)
g_string_free (pattern, TRUE);
@ -251,7 +291,7 @@ error:
static void
ms_string_info_free (MSStringInfo *info)
as_string_info_free (ASStringInfo *info)
{
if (info)
{
@ -263,7 +303,7 @@ ms_string_info_free (MSStringInfo *info)
static void
ms_string_info_set_script (MSStringInfo *info,
as_string_info_set_script (ASStringInfo *info,
const char *script)
{
g_return_if_fail (info != NULL);
@ -272,10 +312,10 @@ ms_string_info_set_script (MSStringInfo *info,
}
static MSString *
ms_string_new (guint n_wildcards)
static ASString *
as_string_new (guint n_wildcards)
{
MSString *s = g_new0 (MSString, 1);
ASString *s = g_new0 (ASString, 1);
if (n_wildcards)
{
@ -288,7 +328,7 @@ ms_string_new (guint n_wildcards)
static void
ms_string_free (MSString *s)
as_string_free (ASString *s)
{
if (s)
{
@ -298,25 +338,25 @@ ms_string_free (MSString *s)
}
static MSSet*
ms_set_new (MSStringInfo **strings,
static ASSet*
as_set_new (ASStringInfo **strings,
guint n_strings)
{
MSSet *set = NULL;
ASSet *set = NULL;
GString *pattern;
guint i, len;
GError *error = NULL;
gunichar *last_chars;
gunichar min_last = 0, max_last = 0;
gboolean hms_wildcard = FALSE;
gboolean has_wildcard = FALSE;
g_return_val_if_fail (strings != NULL, NULL);
g_return_val_if_fail (n_strings != 0, NULL);
set = g_new0 (MSSet, 1);
set = g_new0 (ASSet, 1);
set->ref_count = 1;
set->n_strings = n_strings;
set->strings = g_new (MSString*, n_strings);
set->strings = g_new (ASString*, n_strings);
len = n_strings + 2; /* (||||) */
last_chars = g_new (gunichar, n_strings);
@ -329,10 +369,10 @@ ms_set_new (MSStringInfo **strings,
len += strings[i]->pattern_len;
set->strings[i] = ms_string_new (strings[i]->n_wildcards);
set->strings[i] = as_string_new (strings[i]->n_wildcards);
if (strings[i]->n_wildcards)
hms_wildcard = TRUE;
has_wildcard = TRUE;
}
set->min_last = min_last;
@ -366,7 +406,7 @@ ms_set_new (MSStringInfo **strings,
g_error_free (error);
}
set->scripts = g_new (char*, n_strings);
set->scripts = g_new0 (char*, n_strings);
for (i = 0; i < n_strings; ++i)
{
@ -423,13 +463,13 @@ ms_set_new (MSStringInfo **strings,
error:
g_free (last_chars);
g_string_free (pattern, TRUE);
ms_set_unref (set);
as_set_unref (set);
return NULL;
}
static void
ms_match_destroy (MSMatch *match)
as_match_destroy (ASMatch *match)
{
if (match->n_parens)
g_free (match->parens);
@ -437,9 +477,9 @@ ms_match_destroy (MSMatch *match)
static gboolean
ms_set_match (MSSet *set,
as_set_match (ASSet *set,
const char *text,
MSMatch *match)
ASMatch *match)
{
char *reversed;
int start_pos, end_pos;
@ -509,7 +549,7 @@ out:
static gboolean
ms_set_check_last (MSSet *set,
as_set_check_last (ASSet *set,
gunichar c)
{
guint i;
@ -526,18 +566,15 @@ ms_set_check_last (MSSet *set,
static void
ms_set_unref (MSSet *set)
as_set_unref (ASSet *set)
{
guint i;
if (!set)
return;
if (!--set->ref_count)
if (set && !--set->ref_count)
{
guint i;
for (i = 0; i < set->n_strings; ++i)
{
ms_string_free (set->strings[i]);
as_string_free (set->strings[i]);
g_free (set->scripts[i]);
}
@ -550,7 +587,7 @@ ms_set_unref (MSSet *set)
}
static MSSet *ms_set_ref (MSSet *set)
static ASSet *as_set_ref (ASSet *set)
{
g_return_val_if_fail (set != NULL, NULL);
set->ref_count++;
@ -559,9 +596,9 @@ static MSSet *ms_set_ref (MSSet *set)
static void
ms_string_info_array_free (GPtrArray *ar)
as_string_info_array_free (GPtrArray *ar)
{
g_ptr_array_foreach (ar, (GFunc) ms_string_info_free, NULL);
g_ptr_array_foreach (ar, (GFunc) as_string_info_free, NULL);
g_ptr_array_free (ar, TRUE);
}
@ -569,13 +606,13 @@ ms_string_info_array_free (GPtrArray *ar)
static void
add_lang_sets (const char *lang,
GPtrArray *strings,
MSPlugin *plugin)
ASPlugin *plugin)
{
MSSet *set;
ASSet *set;
g_return_if_fail (strings && strings->len);
set = ms_set_new ((MSStringInfo**) strings->pdata, strings->len);
set = as_set_new ((ASStringInfo**) strings->pdata, strings->len);
if (set)
g_hash_table_insert (plugin->lang_sets, g_strdup (lang), set);
@ -600,7 +637,7 @@ is_nonblank_string (const char *string)
static void
ms_plugin_load_info (MSPlugin *plugin,
as_plugin_load_info (ASPlugin *plugin,
GSList *list)
{
GPtrArray *any_lang;
@ -612,13 +649,13 @@ ms_plugin_load_info (MSPlugin *plugin,
any_lang = g_ptr_array_new ();
lang_strings = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
(GDestroyNotify) ms_string_info_array_free);
(GDestroyNotify) as_string_info_array_free);
for (l = list; l != NULL; l = l->next)
{
GPtrArray *ar;
MSStringInfo *sinfo;
MSInfo *info = l->data;
ASStringInfo *sinfo;
ASInfo *info = l->data;
if (info->lang)
{
@ -635,7 +672,7 @@ ms_plugin_load_info (MSPlugin *plugin,
ar = any_lang;
}
sinfo = ms_string_get_info (info->pattern, 0, 0, ar->len);
sinfo = as_string_get_info (info->pattern, 0, 0, ar->len);
if (!sinfo)
{
@ -649,7 +686,7 @@ ms_plugin_load_info (MSPlugin *plugin,
if (script)
{
ms_string_info_set_script (sinfo, info->script);
as_string_info_set_script (sinfo, info->script);
g_object_unref (script);
}
}
@ -658,54 +695,66 @@ ms_plugin_load_info (MSPlugin *plugin,
}
if (any_lang->len)
plugin->any_lang = ms_set_new ((MSStringInfo**) any_lang->pdata,
plugin->any_lang = as_set_new ((ASStringInfo**) any_lang->pdata,
any_lang->len);
g_hash_table_foreach (lang_strings, (GHFunc) add_lang_sets, plugin);
ms_string_info_array_free (any_lang);
as_string_info_array_free (any_lang);
g_hash_table_destroy (lang_strings);
}
static void
ms_plugin_load (MSPlugin *plugin)
append_item (const char *pattern,
const char *script,
const char *lang,
gboolean enabled,
GSList **list)
{
const char *file;
GSList *info = NULL;
ASInfo *info;
moo_prefs_new_key_string (FILE_PREFS_KEY, NULL);
file = moo_prefs_get_filename (FILE_PREFS_KEY);
if (file)
_ms_load_file (file, &info);
info = as_info_new (pattern, script, lang, enabled);
if (info)
ms_plugin_load_info (plugin, info);
*list = g_slist_prepend (*list, info);
}
g_slist_foreach (info, (GFunc) _ms_info_free, NULL);
static void
as_plugin_load (ASPlugin *plugin)
{
GSList *info = NULL;
_as_plugin_load (MOO_PLUGIN (plugin),
(ASLoadFunc) append_item,
&info);
info = g_slist_reverse (info);
if (info)
as_plugin_load_info (plugin, info);
g_slist_foreach (info, (GFunc) as_info_free, NULL);
g_slist_free (info);
}
static gboolean
ms_plugin_init (MSPlugin *plugin)
as_plugin_init (ASPlugin *plugin)
{
plugin->lang_sets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
(GDestroyNotify) ms_set_unref);
plugin->ctx = _ms_plugin_context_new ();
(GDestroyNotify) as_set_unref);
plugin->ctx = _as_plugin_context_new ();
ms_plugin_load (plugin);
as_plugin_load (plugin);
return TRUE;
}
static void
ms_plugin_deinit (MSPlugin *plugin)
as_plugin_deinit (ASPlugin *plugin)
{
ms_set_unref (plugin->any_lang);
as_set_unref (plugin->any_lang);
g_hash_table_destroy (plugin->lang_sets);
g_object_unref (plugin->ctx);
plugin->any_lang = NULL;
@ -714,32 +763,40 @@ ms_plugin_deinit (MSPlugin *plugin)
}
void
_as_plugin_reload (MooPlugin *plugin)
{
as_plugin_deinit ((ASPlugin*) plugin);
as_plugin_init ((ASPlugin*) plugin);
}
static void
free_sets_list (GSList *list)
{
g_slist_foreach (list, (GFunc) ms_set_unref, NULL);
g_slist_foreach (list, (GFunc) as_set_unref, NULL);
g_slist_free (list);
}
static GSList *
ms_plugin_get_doc_sets (MSPlugin *plugin,
as_plugin_get_doc_sets (ASPlugin *plugin,
MooEdit *doc)
{
char *lang = NULL;
GSList *list = NULL;
if (plugin->any_lang)
list = g_slist_prepend (list, ms_set_ref (plugin->any_lang));
list = g_slist_prepend (list, as_set_ref (plugin->any_lang));
moo_edit_config_get (doc->config, "lang", &lang, NULL);
if (lang)
{
MSSet *set = g_hash_table_lookup (plugin->lang_sets, lang);
ASSet *set = g_hash_table_lookup (plugin->lang_sets, lang);
if (set)
list = g_slist_prepend (list, ms_set_ref (set));
list = g_slist_prepend (list, as_set_ref (set));
}
g_free (lang);
@ -748,14 +805,14 @@ ms_plugin_get_doc_sets (MSPlugin *plugin,
static void
ms_plugin_connect_doc (MSPlugin *plugin,
as_plugin_connect_doc (ASPlugin *plugin,
MooEdit *doc)
{
GSList *sets = ms_plugin_get_doc_sets (plugin, doc);
GSList *sets = as_plugin_get_doc_sets (plugin, doc);
if (sets)
{
g_object_set_data_full (G_OBJECT (doc), MS_DATA, sets,
g_object_set_data_full (G_OBJECT (doc), AS_DATA, sets,
(GDestroyNotify) free_sets_list);
g_signal_connect (doc, "char-inserted",
G_CALLBACK (char_inserted_cb), sets);
@ -764,15 +821,15 @@ ms_plugin_connect_doc (MSPlugin *plugin,
static void
ms_plugin_disconnect_doc (G_GNUC_UNUSED MSPlugin *plugin,
as_plugin_disconnect_doc (G_GNUC_UNUSED ASPlugin *plugin,
MooEdit *doc)
{
GSList *sets = g_object_get_data (G_OBJECT (doc), MS_DATA);
GSList *sets = g_object_get_data (G_OBJECT (doc), AS_DATA);
if (sets)
{
g_signal_handlers_disconnect_by_func (doc, (gpointer) char_inserted_cb, sets);
g_object_set_data (G_OBJECT (doc), MS_DATA, NULL);
g_object_set_data (G_OBJECT (doc), AS_DATA, NULL);
}
}
@ -781,28 +838,28 @@ static void
lang_changed (MooEdit *doc,
G_GNUC_UNUSED guint var_id,
G_GNUC_UNUSED GParamSpec *pspec,
MSPlugin *plugin)
ASPlugin *plugin)
{
ms_plugin_disconnect_doc (plugin, doc);
ms_plugin_connect_doc (plugin, doc);
as_plugin_disconnect_doc (plugin, doc);
as_plugin_connect_doc (plugin, doc);
}
static void
ms_plugin_attach (MSPlugin *plugin,
as_plugin_attach (ASPlugin *plugin,
MooEdit *doc)
{
ms_plugin_connect_doc (plugin, doc);
as_plugin_connect_doc (plugin, doc);
g_signal_connect (doc, "config_notify::lang",
G_CALLBACK (lang_changed), plugin);
}
static void
ms_plugin_detach (MSPlugin *plugin,
as_plugin_detach (ASPlugin *plugin,
MooEdit *doc)
{
ms_plugin_disconnect_doc (plugin, doc);
as_plugin_disconnect_doc (plugin, doc);
g_signal_handlers_disconnect_by_func (doc, (gpointer) lang_changed, plugin);
}
@ -816,16 +873,16 @@ char_inserted_cb (MooEdit *doc,
GtkTextIter iter;
char *slice;
gboolean found;
MSMatch match;
ASMatch match;
GSList *l;
g_return_val_if_fail (sets != NULL, FALSE);
for (l = sets; l != NULL; l = l->next)
{
MSSet *set = l->data;
ASSet *set = l->data;
if (!ms_set_check_last (set, character))
if (!as_set_check_last (set, character))
continue;
iter = *where;
@ -833,14 +890,14 @@ char_inserted_cb (MooEdit *doc,
/* get extra char here */
slice = gtk_text_iter_get_slice (&iter, where);
found = ms_set_match (set, slice, &match);
found = as_set_match (set, slice, &match);
g_free (slice);
if (!found)
continue;
process_match (doc, where, set, &match);
ms_match_destroy (&match);
as_match_destroy (&match);
return TRUE;
}
@ -851,14 +908,14 @@ char_inserted_cb (MooEdit *doc,
static void
process_match (MooEdit *doc,
GtkTextIter *end,
MSSet *set,
MSMatch *match)
ASSet *set,
ASMatch *match)
{
GtkTextIter start;
char *full_text = NULL;
char **parens_text = NULL;
guint i;
MSPlugin *plugin;
ASPlugin *plugin;
start = *end;
gtk_text_iter_backward_chars (&start, match->end_offset);
@ -890,9 +947,9 @@ process_match (MooEdit *doc,
g_print ("\n");
plugin = moo_plugin_lookup (MS_PLUGIN_ID);
plugin = moo_plugin_lookup (AS_PLUGIN_ID);
g_return_if_fail (plugin != NULL);
ms_plugin_do_action (plugin, doc, end, set, match,
as_plugin_do_action (plugin, doc, end, set, match,
full_text, parens_text);
g_free (full_text);
@ -901,11 +958,11 @@ process_match (MooEdit *doc,
static void
ms_plugin_do_action (MSPlugin *plugin,
as_plugin_do_action (ASPlugin *plugin,
MooEdit *doc,
GtkTextIter *insert,
MSSet *set,
MSMatch *match,
ASSet *set,
ASMatch *match,
char *full_text,
char **parens_text)
{
@ -923,26 +980,75 @@ ms_plugin_do_action (MSPlugin *plugin,
return;
}
_ms_plugin_context_exec (plugin->ctx, script, doc, insert,
_as_plugin_context_exec (plugin->ctx, script, doc, insert,
full_text, parens_text, match->n_parens);
g_object_unref (script);
}
MOO_PLUGIN_DEFINE_INFO (ms, MS_PLUGIN_ID,
void
_as_plugin_load (G_GNUC_UNUSED MooPlugin *plugin,
ASLoadFunc func,
gpointer data)
{
MooMarkupDoc *doc;
MooMarkupNode *root, *node;
doc = moo_prefs_get_markup ();
g_return_if_fail (doc != NULL);
root = moo_markup_get_element (MOO_MARKUP_NODE (doc), AS_XML_ROOT);
if (!root)
return;
for (node = root->children; node != NULL; node = node->next)
{
const char *pattern, *lang, *script;
gboolean enabled;
if (!MOO_MARKUP_IS_ELEMENT (node))
continue;
if (strcmp (node->name, AS_XML_ITEM))
{
g_warning ("%s: invalid element '%s'", G_STRLOC, node->name);
continue;
}
pattern = moo_markup_get_prop (node, AS_XML_PROP_PATTERN);
lang = moo_markup_get_prop (node, AS_XML_PROP_LANG);
enabled = moo_markup_get_bool_prop (node, AS_XML_PROP_ENABLED, TRUE);
script = moo_markup_get_content (node);
if (!pattern)
{
g_warning ("%s: patern missing", G_STRLOC);
continue;
}
if (!script || !script[0])
script = NULL;
func (pattern, script, lang, enabled, data);
}
}
MOO_PLUGIN_DEFINE_INFO (as, AS_PLUGIN_ID,
"Active Strings", "Very active",
"Yevgen Muntyan <muntyan@tamu.edu>",
MOO_VERSION);
MOO_PLUGIN_DEFINE_FULL (MS, ms,
ms_plugin_init, ms_plugin_deinit,
MOO_PLUGIN_DEFINE_FULL (AS, as,
as_plugin_init, as_plugin_deinit,
NULL, NULL,
ms_plugin_attach, ms_plugin_detach,
NULL, 0, 0);
as_plugin_attach, as_plugin_detach,
_as_plugin_prefs_page, 0, 0);
gboolean
_moo_active_strings_plugin_init (void)
{
return moo_plugin_register (ms_plugin_get_type ());
return moo_plugin_register (as_plugin_get_type ());
}

View File

@ -0,0 +1,451 @@
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
<glade-interface>
<widget class="GtkWindow" id="window1">
<property name="visible">True</property>
<property name="title" translatable="yes">window1</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="decorated">True</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
<property name="urgency_hint">False</property>
<child>
<widget class="GtkVBox" id="page">
<property name="border_width">6</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkHPaned" id="hpaned1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="position">0</property>
<child>
<widget class="GtkVBox" id="vbox2">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<widget class="GtkTreeView" id="treeview">
<property name="border_width">3</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="headers_visible">False</property>
<property name="rules_hint">False</property>
<property name="reorderable">False</property>
<property name="enable_search">True</property>
<property name="fixed_height_mode">False</property>
<property name="hover_selection">False</property>
<property name="hover_expand">False</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox2">
<property name="border_width">3</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkButton" id="new">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">New item</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">False</property>
<child>
<widget class="GtkImage" id="image3">
<property name="visible">True</property>
<property name="stock">gtk-new</property>
<property name="icon_size">4</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="delete">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Delete item</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">False</property>
<child>
<widget class="GtkImage" id="image4">
<property name="visible">True</property>
<property name="stock">gtk-delete</property>
<property name="icon_size">4</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">3</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="down">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Move item down</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">False</property>
<child>
<widget class="GtkImage" id="image2">
<property name="visible">True</property>
<property name="stock">gtk-go-down</property>
<property name="icon_size">4</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="up">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Move item up</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">False</property>
<child>
<widget class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="stock">gtk-go-up</property>
<property name="icon_size">4</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="shrink">False</property>
<property name="resize">False</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="vbox3">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkHBox" id="hbox3">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkCheckButton" id="enabled">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Set whether the menu item is enabled</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Enabled</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<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>
<property name="homogeneous">False</property>
<property name="row_spacing">0</property>
<property name="column_spacing">0</property>
<child>
<widget class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="label" translatable="yes">Pattern:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="pattern">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">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="GtkScrolledWindow" id="scrolledwindow2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<widget class="GtkTextView" id="script">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="overwrite">False</property>
<property name="accepts_tab">True</property>
<property name="justification">GTK_JUSTIFY_LEFT</property>
<property name="wrap_mode">GTK_WRAP_NONE</property>
<property name="cursor_visible">True</property>
<property name="pixels_above_lines">0</property>
<property name="pixels_below_lines">0</property>
<property name="pixels_inside_wrap">0</property>
<property name="left_margin">3</property>
<property name="right_margin">3</property>
<property name="indent">0</property>
<property name="text" translatable="yes"></property>
</widget>
</child>
</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="x_options">fill</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="label" translatable="yes">Script:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.00999999977648</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">fill</property>
<property name="y_options">fill</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="label" translatable="yes">Files:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="lang">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Enter file type or leave blank to enable it for all files</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="y_options"></property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="shrink">False</property>
<property name="resize">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View File

@ -0,0 +1,46 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; coding: utf-8 -*-
*
* as-plugin.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.
*/
#include "mooedit/mooplugin.h"
#ifndef __AS_PLUGIN_H__
#define __AS_PLUGIN_H__
G_BEGIN_DECLS
#define AS_XML_ROOT "ActiveStrings"
#define AS_XML_ITEM "item"
#define AS_XML_PROP_PATTERN "pattern"
#define AS_XML_PROP_LANG "lang"
#define AS_XML_PROP_ENABLED "enabled"
typedef void (*ASLoadFunc) (const char *pattern,
const char *script,
const char *lang,
gboolean enabled,
gpointer data);
GtkWidget *_as_plugin_prefs_page (MooPlugin *plugin);
void _as_plugin_reload (MooPlugin *plugin);
void _as_plugin_load (MooPlugin *plugin,
ASLoadFunc func,
gpointer data);
G_END_DECLS
#endif /* __AS_PLUGIN_H__ */

View File

@ -1,204 +0,0 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; coding: utf-8 -*-
*
* ms-plugin-xml.c
*
* 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.
*/
#include "ms-plugin-xml.h"
#include "mooutils/moomarkup.h"
#include "mooutils/mooutils-misc.h"
#include <string.h>
#define MS_ROOT "active-strings"
#define MS_ELM "ms"
#define MS_PROP_PATTERN "pattern"
#define MS_PROP_LANG "lang"
MSInfo *
_ms_info_new (const char *pattern,
const char *script,
const char *lang)
{
MSInfo *info;
g_return_val_if_fail (pattern && pattern[0], NULL);
info = g_new0 (MSInfo, 1);
info->pattern = g_strdup (pattern);
info->script = g_strdup (script);
info->lang = lang ? g_ascii_strdown (lang, -1) : NULL;
return info;
}
void
_ms_info_free (MSInfo *info)
{
if (info)
{
g_free (info->pattern);
g_free (info->script);
g_free (info->lang);
g_free (info);
}
}
static MSInfo *
parse_ms_elm (MooMarkupNode *node)
{
const char *pattern;
const char *script;
const char *lang;
pattern = moo_markup_get_prop (node, MS_PROP_PATTERN);
lang = moo_markup_get_prop (node, MS_PROP_LANG);
script = moo_markup_get_content (node);
if (!pattern || !pattern[0])
{
g_warning ("%s: '%s' attribute missing",
G_STRLOC, MS_PROP_PATTERN);
return NULL;
}
return _ms_info_new (pattern, script, lang);
}
gboolean
_ms_load_file (const char *filename,
GSList **list)
{
MooMarkupDoc *doc;
MooMarkupNode *root, *node;
g_return_val_if_fail (filename != NULL, FALSE);
g_return_val_if_fail (list != NULL, FALSE);
doc = moo_markup_parse_file (filename, NULL);
*list = NULL;
if (!doc)
return FALSE;
root = moo_markup_get_root_element (doc, MS_ROOT);
if (!root)
root = MOO_MARKUP_NODE (doc);
for (node = root->children; node != NULL; node = node->next)
{
MSInfo *info;
if (!MOO_MARKUP_IS_ELEMENT (node))
continue;
if (strcmp (node->name, MS_ELM))
{
g_warning ("%s: unknown element '%s'", G_STRLOC, node->name);
continue;
}
info = parse_ms_elm (node);
if (info)
*list = g_slist_prepend (*list, info);
}
*list = g_slist_reverse (*list);
moo_markup_doc_unref (doc);
return TRUE;
}
char *
_ms_format_xml (GSList *list)
{
GString *xml;
GSList *l;
if (!list)
return NULL;
xml = g_string_sized_new (1024);
g_string_append (xml, "<" MS_ROOT ">\n");
for (l = list; l != NULL; l = l->next)
{
MSInfo *info = l->data;
char *tmp;
if (!info || !info->pattern)
{
g_critical ("%s: oops", G_STRLOC);
continue;
}
tmp = g_markup_printf_escaped ("<" MS_ELM "pattern=\"%s\"", info->pattern);
g_string_append (xml, tmp);
g_free (tmp);
if (info->lang)
{
tmp = g_markup_printf_escaped (" lang=\"%s\"", info->lang);
g_string_append (xml, tmp);
g_free (tmp);
}
if (info->script)
{
tmp = g_markup_printf_escaped (">%s</" MS_ELM ">\n", info->script);
g_string_append (xml, tmp);
g_free (tmp);
}
else
{
g_string_append (xml, ">\n");
}
}
g_string_append (xml, "</" MS_ROOT ">\n");
return g_string_free (xml, FALSE);
}
gboolean
_ms_save (const char *filename,
GSList *info)
{
char *xml;
gboolean ret;
GError *error = NULL;
g_return_val_if_fail (filename != NULL, FALSE);
xml = _ms_format_xml (info);
if (!xml)
return moo_unlink (filename) == 0;
ret = moo_save_file_utf8 (filename, xml, -1, &error);
if (!ret)
{
g_warning ("%s: could not save file '%s'", G_STRLOC, filename);
g_warning ("%s: %s", G_STRLOC, error->message);
g_error_free (error);
}
g_free (xml);
return ret;
}

View File

@ -1,47 +0,0 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; coding: utf-8 -*-
*
* ms-plugin-xml.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 __MS_PLUGIN_XML_H__
#define __MS_PLUGIN_XML_H__
#include <glib.h>
G_BEGIN_DECLS
typedef struct _MSInfo MSInfo;
struct _MSInfo {
char *pattern;
char *script;
char *lang;
};
MSInfo *_ms_info_new (const char *pattern,
const char *script,
const char *lang);
void _ms_info_free (MSInfo *info);
gboolean _ms_load_file (const char *filename,
GSList **info);
gboolean _ms_save (const char *filename,
GSList *info);
char *_ms_format_xml (GSList *info);
G_END_DECLS
#endif /* __MS_PLUGIN_XML_H__ */