2006-08-15 22:18:16 -07:00
|
|
|
/*
|
|
|
|
* moocommand.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.
|
|
|
|
*/
|
|
|
|
|
2006-08-31 08:21:39 -07:00
|
|
|
#define MOOEDIT_COMPILATION
|
|
|
|
#include "mooedit/moocommand-private.h"
|
2006-08-15 22:18:16 -07:00
|
|
|
#include "mooedit/moocommand-script.h"
|
|
|
|
#include "mooedit/moocommand-exe.h"
|
|
|
|
#include "mooedit/mooeditwindow.h"
|
2006-09-01 10:37:47 -07:00
|
|
|
#include "mooedit/moooutputfiltersimple.h"
|
2006-08-19 00:50:56 -07:00
|
|
|
#include "mooedit/mooedit-enums.h"
|
2006-08-15 22:18:16 -07:00
|
|
|
#include <gtk/gtkwindow.h>
|
|
|
|
#include <gtk/gtktextview.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
2006-08-31 08:21:39 -07:00
|
|
|
#define KEY_TYPE "type"
|
|
|
|
#define KEY_OPTIONS "options"
|
2006-08-17 21:53:34 -07:00
|
|
|
|
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
G_DEFINE_TYPE (MooCommand, moo_command, G_TYPE_OBJECT)
|
2006-08-16 22:08:49 -07:00
|
|
|
G_DEFINE_TYPE (MooCommandType, moo_command_type, G_TYPE_OBJECT)
|
2006-08-15 22:18:16 -07:00
|
|
|
G_DEFINE_TYPE (MooCommandContext, moo_command_context, G_TYPE_OBJECT)
|
|
|
|
|
|
|
|
enum {
|
|
|
|
CTX_PROP_0,
|
|
|
|
CTX_PROP_DOC,
|
|
|
|
CTX_PROP_WINDOW
|
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
CMD_PROP_0,
|
2006-08-16 18:27:19 -07:00
|
|
|
CMD_PROP_OPTIONS
|
2006-08-15 22:18:16 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
GValue value;
|
|
|
|
} Variable;
|
|
|
|
|
|
|
|
struct _MooCommandContextPrivate {
|
|
|
|
GHashTable *vars;
|
|
|
|
gpointer window;
|
|
|
|
gpointer doc;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct _MooCommandData {
|
|
|
|
guint ref_count;
|
2006-08-31 08:21:39 -07:00
|
|
|
char **data;
|
|
|
|
guint len;
|
|
|
|
char *code;
|
2006-08-15 22:18:16 -07:00
|
|
|
};
|
|
|
|
|
2006-09-01 10:37:47 -07:00
|
|
|
typedef struct {
|
|
|
|
char *name;
|
|
|
|
MooCommandFilterFactory factory_func;
|
|
|
|
gpointer data;
|
|
|
|
GDestroyNotify data_notify;
|
|
|
|
} FilterInfo;
|
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
|
|
|
|
static GHashTable *registered_types;
|
2006-09-01 10:37:47 -07:00
|
|
|
static GHashTable *registered_filters;
|
2006-08-15 22:18:16 -07:00
|
|
|
|
|
|
|
|
2006-08-31 08:21:39 -07:00
|
|
|
static Variable *variable_new (const GValue *value);
|
|
|
|
static void variable_free (Variable *var);
|
|
|
|
static void moo_command_data_take_code (MooCommandData *data,
|
|
|
|
char *code);
|
2006-08-15 22:18:16 -07:00
|
|
|
|
|
|
|
|
|
|
|
MooCommand *
|
|
|
|
moo_command_create (const char *name,
|
2006-08-16 18:27:19 -07:00
|
|
|
const char *options,
|
2006-08-15 22:18:16 -07:00
|
|
|
MooCommandData *data)
|
|
|
|
{
|
2006-08-16 22:08:49 -07:00
|
|
|
MooCommandType *type;
|
2006-08-15 22:18:16 -07:00
|
|
|
|
2006-08-16 22:08:49 -07:00
|
|
|
g_return_val_if_fail (name != NULL, NULL);
|
2006-08-15 22:18:16 -07:00
|
|
|
|
2006-08-16 22:08:49 -07:00
|
|
|
type = moo_command_type_lookup (name);
|
2006-08-15 22:18:16 -07:00
|
|
|
g_return_val_if_fail (type != NULL, NULL);
|
|
|
|
|
2006-08-16 22:08:49 -07:00
|
|
|
return _moo_command_type_create_command (type, data, options);
|
2006-08-15 22:18:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2006-08-16 22:08:49 -07:00
|
|
|
moo_command_type_register (const char *name,
|
|
|
|
const char *display_name,
|
2006-08-31 08:21:39 -07:00
|
|
|
MooCommandType *type,
|
|
|
|
char **keys)
|
2006-08-16 22:08:49 -07:00
|
|
|
{
|
|
|
|
MooCommandTypeClass *klass;
|
|
|
|
|
|
|
|
g_return_if_fail (name != NULL);
|
|
|
|
g_return_if_fail (display_name != NULL);
|
|
|
|
g_return_if_fail (MOO_IS_COMMAND_TYPE (type));
|
|
|
|
|
|
|
|
klass = MOO_COMMAND_TYPE_GET_CLASS (type);
|
|
|
|
g_return_if_fail (klass->create_command != NULL);
|
|
|
|
g_return_if_fail (klass->create_widget != NULL);
|
|
|
|
g_return_if_fail (klass->load_data != NULL);
|
|
|
|
g_return_if_fail (klass->save_data != NULL);
|
2006-08-23 00:38:16 -07:00
|
|
|
g_return_if_fail (klass->data_equal != NULL);
|
2006-08-15 22:18:16 -07:00
|
|
|
|
|
|
|
if (registered_types != NULL)
|
|
|
|
{
|
2006-08-16 22:08:49 -07:00
|
|
|
MooCommandType *old = g_hash_table_lookup (registered_types, name);
|
2006-08-15 22:18:16 -07:00
|
|
|
|
2006-08-16 22:08:49 -07:00
|
|
|
if (old)
|
2006-08-15 22:18:16 -07:00
|
|
|
{
|
|
|
|
g_warning ("reregistering command type '%s'", name);
|
2006-08-16 22:08:49 -07:00
|
|
|
g_hash_table_remove (registered_types, name);
|
|
|
|
g_object_unref (old);
|
2006-08-15 22:18:16 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!registered_types)
|
|
|
|
registered_types = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
|
|
|
|
2006-08-16 22:08:49 -07:00
|
|
|
type->name = g_strdup (name);
|
|
|
|
type->display_name = g_strdup (display_name);
|
2006-08-31 08:21:39 -07:00
|
|
|
type->keys = g_strdupv (keys);
|
|
|
|
type->n_keys = keys ? g_strv_length (keys) : 0;
|
2006-08-15 22:18:16 -07:00
|
|
|
|
2006-08-16 22:08:49 -07:00
|
|
|
g_hash_table_insert (registered_types, g_strdup (name), g_object_ref (type));
|
2006-08-15 22:18:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-08-16 22:08:49 -07:00
|
|
|
MooCommandType *
|
2006-08-16 18:27:19 -07:00
|
|
|
moo_command_type_lookup (const char *name)
|
2006-08-15 22:18:16 -07:00
|
|
|
{
|
2006-08-16 22:08:49 -07:00
|
|
|
MooCommandType *type = NULL;
|
2006-08-16 18:27:19 -07:00
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
g_return_val_if_fail (name != NULL, FALSE);
|
2006-08-16 18:27:19 -07:00
|
|
|
|
|
|
|
if (registered_types != NULL)
|
|
|
|
type = g_hash_table_lookup (registered_types, name);
|
|
|
|
|
2006-08-16 22:08:49 -07:00
|
|
|
return type;
|
2006-08-16 18:27:19 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2006-08-16 22:08:49 -07:00
|
|
|
add_type_hash_cb (G_GNUC_UNUSED const char *name,
|
|
|
|
MooCommandType *type,
|
2006-08-16 18:27:19 -07:00
|
|
|
GSList **list)
|
|
|
|
{
|
2006-08-16 22:08:49 -07:00
|
|
|
*list = g_slist_prepend (*list, type);
|
2006-08-16 18:27:19 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
GSList *
|
|
|
|
moo_command_list_types (void)
|
|
|
|
{
|
|
|
|
GSList *list = NULL;
|
|
|
|
|
|
|
|
if (registered_types)
|
|
|
|
g_hash_table_foreach (registered_types, (GHFunc) add_type_hash_cb, &list);
|
|
|
|
|
|
|
|
return g_slist_reverse (list);
|
2006-08-15 22:18:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-08-16 22:08:49 -07:00
|
|
|
static void
|
|
|
|
moo_command_type_init (G_GNUC_UNUSED MooCommandType *type)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
moo_command_type_finalize (GObject *object)
|
|
|
|
{
|
|
|
|
MooCommandType *type = MOO_COMMAND_TYPE (object);
|
|
|
|
g_free (type->name);
|
|
|
|
g_free (type->display_name);
|
|
|
|
G_OBJECT_CLASS (moo_command_type_parent_class)->finalize (object);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
moo_command_type_class_init (MooCommandTypeClass *klass)
|
|
|
|
{
|
|
|
|
G_OBJECT_CLASS (klass)->finalize = moo_command_type_finalize;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MooCommand *
|
|
|
|
_moo_command_type_create_command (MooCommandType *type,
|
|
|
|
MooCommandData *data,
|
|
|
|
const char *options)
|
|
|
|
{
|
|
|
|
MooCommand *cmd;
|
|
|
|
|
|
|
|
g_return_val_if_fail (MOO_IS_COMMAND_TYPE (type), NULL);
|
|
|
|
g_return_val_if_fail (MOO_COMMAND_TYPE_GET_CLASS(type)->create_command != NULL, NULL);
|
|
|
|
|
|
|
|
if (data)
|
|
|
|
moo_command_data_ref (data);
|
|
|
|
else
|
2006-08-31 08:21:39 -07:00
|
|
|
data = moo_command_data_new (type->n_keys);
|
2006-08-16 22:08:49 -07:00
|
|
|
|
|
|
|
cmd = MOO_COMMAND_TYPE_GET_CLASS (type)->create_command (type, data, options);
|
|
|
|
|
|
|
|
moo_command_data_unref (data);
|
|
|
|
return cmd;
|
|
|
|
}
|
|
|
|
|
|
|
|
GtkWidget *
|
|
|
|
_moo_command_type_create_widget (MooCommandType *type)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (MOO_IS_COMMAND_TYPE (type), NULL);
|
|
|
|
g_return_val_if_fail (MOO_COMMAND_TYPE_GET_CLASS(type)->create_widget != NULL, NULL);
|
|
|
|
return MOO_COMMAND_TYPE_GET_CLASS (type)->create_widget (type);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
_moo_command_type_load_data (MooCommandType *type,
|
|
|
|
GtkWidget *widget,
|
|
|
|
MooCommandData *data)
|
|
|
|
{
|
|
|
|
g_return_if_fail (MOO_IS_COMMAND_TYPE (type));
|
|
|
|
g_return_if_fail (MOO_COMMAND_TYPE_GET_CLASS(type)->load_data != NULL);
|
|
|
|
g_return_if_fail (GTK_IS_WIDGET (widget));
|
|
|
|
g_return_if_fail (data != NULL);
|
|
|
|
MOO_COMMAND_TYPE_GET_CLASS(type)->load_data (type, widget, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
_moo_command_type_save_data (MooCommandType *type,
|
|
|
|
GtkWidget *widget,
|
|
|
|
MooCommandData *data)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (MOO_IS_COMMAND_TYPE (type), FALSE);
|
|
|
|
g_return_val_if_fail (MOO_COMMAND_TYPE_GET_CLASS(type)->save_data != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
|
|
|
|
g_return_val_if_fail (data != NULL, FALSE);
|
|
|
|
return MOO_COMMAND_TYPE_GET_CLASS (type)->save_data (type, widget, data);
|
|
|
|
}
|
|
|
|
|
2006-08-23 00:38:16 -07:00
|
|
|
gboolean
|
|
|
|
_moo_command_type_data_equal (MooCommandType *type,
|
|
|
|
MooCommandData *data1,
|
|
|
|
MooCommandData *data2)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (MOO_IS_COMMAND_TYPE (type), FALSE);
|
|
|
|
g_return_val_if_fail (MOO_COMMAND_TYPE_GET_CLASS(type)->data_equal != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (data1 != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (data2 != NULL, FALSE);
|
|
|
|
return MOO_COMMAND_TYPE_GET_CLASS (type)->data_equal (type, data1, data2);
|
|
|
|
}
|
|
|
|
|
2006-08-16 22:08:49 -07:00
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
static void
|
|
|
|
moo_command_set_property (GObject *object,
|
|
|
|
guint property_id,
|
|
|
|
const GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
MooCommand *cmd = MOO_COMMAND (object);
|
|
|
|
|
|
|
|
switch (property_id)
|
|
|
|
{
|
2006-08-16 18:27:19 -07:00
|
|
|
case CMD_PROP_OPTIONS:
|
|
|
|
moo_command_set_options (cmd, g_value_get_flags (value));
|
2006-08-15 22:18:16 -07:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
moo_command_get_property (GObject *object,
|
|
|
|
guint property_id,
|
|
|
|
GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
MooCommand *cmd = MOO_COMMAND (object);
|
|
|
|
|
|
|
|
switch (property_id)
|
|
|
|
{
|
2006-08-16 18:27:19 -07:00
|
|
|
case CMD_PROP_OPTIONS:
|
|
|
|
g_value_set_flags (value, cmd->options);
|
2006-08-15 22:18:16 -07:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
moo_command_check_sensitive_real (MooCommand *cmd,
|
|
|
|
gpointer doc,
|
|
|
|
gpointer window)
|
|
|
|
{
|
2006-08-16 18:27:19 -07:00
|
|
|
if ((cmd->options & MOO_COMMAND_NEED_WINDOW) && !MOO_IS_EDIT_WINDOW (window))
|
2006-08-15 22:18:16 -07:00
|
|
|
return FALSE;
|
|
|
|
|
2006-08-16 18:27:19 -07:00
|
|
|
if ((cmd->options & MOO_COMMAND_NEED_DOC) && !doc)
|
2006-08-15 22:18:16 -07:00
|
|
|
return FALSE;
|
|
|
|
|
2006-08-16 18:27:19 -07:00
|
|
|
if ((cmd->options & MOO_COMMAND_NEED_FILE) && (!MOO_IS_EDIT (doc) || !moo_edit_get_filename (doc)))
|
2006-08-15 22:18:16 -07:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
moo_command_class_init (MooCommandClass *klass)
|
|
|
|
{
|
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
|
|
|
|
object_class->set_property = moo_command_set_property;
|
|
|
|
object_class->get_property = moo_command_get_property;
|
|
|
|
|
|
|
|
klass->check_sensitive = moo_command_check_sensitive_real;
|
|
|
|
|
2006-08-16 18:27:19 -07:00
|
|
|
g_object_class_install_property (object_class, CMD_PROP_OPTIONS,
|
|
|
|
g_param_spec_flags ("options", "options", "options",
|
|
|
|
MOO_TYPE_COMMAND_OPTIONS,
|
2006-08-15 22:18:16 -07:00
|
|
|
0,
|
|
|
|
G_PARAM_READWRITE));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
moo_command_init (G_GNUC_UNUSED MooCommand *cmd)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-08-16 18:27:19 -07:00
|
|
|
static MooCommandOptions
|
|
|
|
check_options (MooCommandOptions options)
|
2006-08-15 22:18:16 -07:00
|
|
|
{
|
2006-08-16 18:27:19 -07:00
|
|
|
MooCommandOptions checked = options;
|
2006-08-15 22:18:16 -07:00
|
|
|
|
2006-08-20 01:49:33 -07:00
|
|
|
if (options & MOO_COMMAND_NEED_SAVE_ALL)
|
|
|
|
checked |= MOO_COMMAND_NEED_SAVE;
|
2006-08-16 18:27:19 -07:00
|
|
|
if (options & MOO_COMMAND_NEED_FILE)
|
2006-08-15 22:18:16 -07:00
|
|
|
checked |= MOO_COMMAND_NEED_DOC;
|
2006-08-16 18:27:19 -07:00
|
|
|
if (options & MOO_COMMAND_NEED_SAVE)
|
2006-08-15 22:18:16 -07:00
|
|
|
checked |= MOO_COMMAND_NEED_DOC;
|
|
|
|
|
|
|
|
return checked;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-08-20 01:49:33 -07:00
|
|
|
static gboolean
|
|
|
|
save_one (MooEdit *doc)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (MOO_IS_EDIT (doc), FALSE);
|
|
|
|
|
|
|
|
if (MOO_EDIT_IS_MODIFIED (doc) && !moo_edit_save (doc, NULL))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
save_all (MooEdit *doc)
|
|
|
|
{
|
|
|
|
MooEditWindow *window;
|
|
|
|
GSList *list, *l;
|
|
|
|
gboolean result = TRUE;
|
|
|
|
|
|
|
|
g_return_val_if_fail (MOO_IS_EDIT (doc), FALSE);
|
|
|
|
|
|
|
|
window = moo_edit_get_window (doc);
|
|
|
|
g_return_val_if_fail (MOO_IS_EDIT_WINDOW (window), FALSE);
|
|
|
|
|
|
|
|
list = moo_edit_window_list_docs (window);
|
|
|
|
|
|
|
|
for (l = list; l != NULL; l = l->next)
|
|
|
|
{
|
|
|
|
if (!save_one (l->data))
|
|
|
|
{
|
|
|
|
result = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_slist_free (list);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
void
|
|
|
|
moo_command_run (MooCommand *cmd,
|
|
|
|
MooCommandContext *ctx)
|
|
|
|
{
|
|
|
|
gpointer doc, window;
|
|
|
|
|
|
|
|
g_return_if_fail (MOO_IS_COMMAND (cmd));
|
|
|
|
g_return_if_fail (MOO_IS_COMMAND_CONTEXT (ctx));
|
|
|
|
g_return_if_fail (MOO_COMMAND_GET_CLASS(cmd)->run != NULL);
|
|
|
|
|
|
|
|
doc = moo_command_context_get_doc (ctx);
|
|
|
|
window = moo_command_context_get_window (ctx);
|
|
|
|
|
2006-08-16 18:27:19 -07:00
|
|
|
if (cmd->options & MOO_COMMAND_NEED_WINDOW)
|
2006-08-15 22:18:16 -07:00
|
|
|
g_return_if_fail (MOO_IS_EDIT_WINDOW (window));
|
|
|
|
|
2006-08-16 18:27:19 -07:00
|
|
|
if (cmd->options & MOO_COMMAND_NEED_DOC)
|
2006-08-15 22:18:16 -07:00
|
|
|
g_return_if_fail (doc != NULL);
|
|
|
|
|
2006-08-16 18:27:19 -07:00
|
|
|
if (cmd->options & MOO_COMMAND_NEED_FILE)
|
2006-08-15 22:18:16 -07:00
|
|
|
g_return_if_fail (MOO_IS_EDIT (doc) && moo_edit_get_filename (doc) != NULL);
|
|
|
|
|
2006-08-16 18:27:19 -07:00
|
|
|
if (cmd->options & MOO_COMMAND_NEED_SAVE)
|
2006-08-20 01:49:33 -07:00
|
|
|
g_return_if_fail (MOO_IS_EDIT (doc));
|
|
|
|
|
|
|
|
if (cmd->options & MOO_COMMAND_NEED_SAVE_ALL)
|
2006-08-15 22:18:16 -07:00
|
|
|
{
|
2006-08-20 01:49:33 -07:00
|
|
|
if (!save_all (doc))
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (cmd->options & MOO_COMMAND_NEED_SAVE)
|
|
|
|
{
|
|
|
|
if (!save_one (doc))
|
2006-08-15 22:18:16 -07:00
|
|
|
return;
|
2006-09-02 00:30:43 -07:00
|
|
|
if (!moo_edit_get_filename (doc))
|
|
|
|
return;
|
2006-08-15 22:18:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
MOO_COMMAND_GET_CLASS(cmd)->run (cmd, ctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
moo_command_check_sensitive (MooCommand *cmd,
|
|
|
|
gpointer doc,
|
|
|
|
gpointer window)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (MOO_IS_COMMAND (cmd), FALSE);
|
|
|
|
g_return_val_if_fail (!doc || GTK_IS_TEXT_VIEW (doc), FALSE);
|
|
|
|
g_return_val_if_fail (!window || GTK_IS_WINDOW (window), FALSE);
|
|
|
|
g_return_val_if_fail (MOO_COMMAND_GET_CLASS(cmd)->check_sensitive != NULL, FALSE);
|
|
|
|
return MOO_COMMAND_GET_CLASS(cmd)->check_sensitive (cmd, doc, window);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2006-08-16 18:27:19 -07:00
|
|
|
moo_command_set_options (MooCommand *cmd,
|
|
|
|
MooCommandOptions options)
|
2006-08-15 22:18:16 -07:00
|
|
|
{
|
|
|
|
g_return_if_fail (MOO_IS_COMMAND (cmd));
|
|
|
|
|
2006-08-16 18:27:19 -07:00
|
|
|
options = check_options (options);
|
2006-08-15 22:18:16 -07:00
|
|
|
|
2006-08-16 18:27:19 -07:00
|
|
|
if (options != cmd->options)
|
2006-08-15 22:18:16 -07:00
|
|
|
{
|
2006-08-16 18:27:19 -07:00
|
|
|
cmd->options = options;
|
|
|
|
g_object_notify (G_OBJECT (cmd), "options");
|
2006-08-15 22:18:16 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-08-16 18:27:19 -07:00
|
|
|
MooCommandOptions
|
|
|
|
moo_command_get_options (MooCommand *cmd)
|
2006-08-15 22:18:16 -07:00
|
|
|
{
|
|
|
|
g_return_val_if_fail (MOO_IS_COMMAND (cmd), 0);
|
2006-08-16 18:27:19 -07:00
|
|
|
return cmd->options;
|
2006-08-15 22:18:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-08-16 18:27:19 -07:00
|
|
|
MooCommandOptions
|
|
|
|
moo_command_options_parse (const char *string)
|
2006-08-15 22:18:16 -07:00
|
|
|
{
|
2006-08-16 18:27:19 -07:00
|
|
|
MooCommandOptions options = 0;
|
2006-08-15 22:18:16 -07:00
|
|
|
char **pieces, **p;
|
|
|
|
|
|
|
|
if (!string)
|
|
|
|
return 0;
|
|
|
|
|
2006-08-20 01:49:33 -07:00
|
|
|
pieces = g_strsplit_set (string, " \t\r\n;,", 0);
|
2006-08-15 22:18:16 -07:00
|
|
|
|
|
|
|
if (!pieces || !pieces[0])
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
for (p = pieces; *p != NULL; ++p)
|
|
|
|
{
|
|
|
|
char *s = *p;
|
|
|
|
|
|
|
|
g_strdelimit (g_strstrip (s), "_", '-');
|
|
|
|
|
|
|
|
if (!*s)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!strcmp (s, "need-doc"))
|
2006-08-16 18:27:19 -07:00
|
|
|
options |= MOO_COMMAND_NEED_DOC;
|
2006-08-15 22:18:16 -07:00
|
|
|
else if (!strcmp (s, "need-file"))
|
2006-08-16 18:27:19 -07:00
|
|
|
options |= MOO_COMMAND_NEED_FILE;
|
2006-08-20 01:49:33 -07:00
|
|
|
else if (!strcmp (s, "need-save") || !strcmp (s, "save"))
|
2006-08-16 18:27:19 -07:00
|
|
|
options |= MOO_COMMAND_NEED_SAVE;
|
2006-08-20 01:49:33 -07:00
|
|
|
else if (!strcmp (s, "need-save-all") || !strcmp (s, "save-all"))
|
|
|
|
options |= MOO_COMMAND_NEED_SAVE_ALL;
|
2006-08-15 22:18:16 -07:00
|
|
|
else if (!strcmp (s, "need-window"))
|
2006-08-16 18:27:19 -07:00
|
|
|
options |= MOO_COMMAND_NEED_WINDOW;
|
2006-08-15 22:18:16 -07:00
|
|
|
else
|
|
|
|
g_warning ("unknown flag '%s'", s);
|
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
|
|
|
g_strfreev (pieces);
|
2006-08-16 18:27:19 -07:00
|
|
|
return options;
|
2006-08-15 22:18:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static Variable *
|
|
|
|
variable_new (const GValue *value)
|
|
|
|
{
|
|
|
|
Variable *var;
|
|
|
|
g_return_val_if_fail (G_IS_VALUE (value), NULL);
|
|
|
|
var = g_new0 (Variable, 1);
|
|
|
|
g_value_init (&var->value, G_VALUE_TYPE (value));
|
|
|
|
g_value_copy (value, &var->value);
|
|
|
|
return var;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
variable_free (Variable *var)
|
|
|
|
{
|
|
|
|
if (var)
|
|
|
|
{
|
|
|
|
g_value_unset (&var->value);
|
|
|
|
g_free (var);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
moo_command_context_set (MooCommandContext *ctx,
|
|
|
|
const char *name,
|
|
|
|
const GValue *value)
|
|
|
|
{
|
|
|
|
Variable *var;
|
|
|
|
|
|
|
|
g_return_if_fail (MOO_IS_COMMAND_CONTEXT (ctx));
|
|
|
|
g_return_if_fail (name != NULL);
|
|
|
|
g_return_if_fail (G_IS_VALUE (value));
|
|
|
|
|
|
|
|
var = variable_new (value);
|
|
|
|
g_hash_table_insert (ctx->priv->vars, g_strdup (name), var);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-08-18 22:21:29 -07:00
|
|
|
void
|
|
|
|
moo_command_context_set_string (MooCommandContext *ctx,
|
|
|
|
const char *name,
|
|
|
|
const char *value)
|
|
|
|
{
|
|
|
|
if (value)
|
|
|
|
{
|
|
|
|
GValue gval;
|
|
|
|
gval.g_type = 0;
|
|
|
|
g_value_init (&gval, G_TYPE_STRING);
|
|
|
|
g_value_set_string (&gval, value);
|
|
|
|
moo_command_context_set (ctx, name, &gval);
|
|
|
|
g_value_unset (&gval);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
moo_command_context_unset (ctx, name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
gboolean
|
|
|
|
moo_command_context_get (MooCommandContext *ctx,
|
|
|
|
const char *name,
|
|
|
|
GValue *value)
|
|
|
|
{
|
|
|
|
Variable *var;
|
|
|
|
|
|
|
|
g_return_val_if_fail (MOO_IS_COMMAND_CONTEXT (ctx), FALSE);
|
|
|
|
g_return_val_if_fail (name != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (value != NULL, FALSE);
|
2006-08-18 22:21:29 -07:00
|
|
|
g_return_val_if_fail (G_VALUE_TYPE (value) == 0, FALSE);
|
2006-08-15 22:18:16 -07:00
|
|
|
|
|
|
|
var = g_hash_table_lookup (ctx->priv->vars, name);
|
|
|
|
|
|
|
|
if (!var)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
g_value_init (value, G_VALUE_TYPE (&var->value));
|
|
|
|
g_value_copy (&var->value, value);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-08-18 22:21:29 -07:00
|
|
|
const char *
|
|
|
|
moo_command_context_get_string (MooCommandContext *ctx,
|
|
|
|
const char *name)
|
|
|
|
{
|
|
|
|
Variable *var;
|
|
|
|
|
|
|
|
g_return_val_if_fail (MOO_IS_COMMAND_CONTEXT (ctx), NULL);
|
|
|
|
g_return_val_if_fail (name != NULL, NULL);
|
|
|
|
|
|
|
|
var = g_hash_table_lookup (ctx->priv->vars, name);
|
|
|
|
|
|
|
|
if (!var)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
g_return_val_if_fail (G_VALUE_TYPE (&var->value) == G_TYPE_STRING, NULL);
|
|
|
|
return g_value_get_string (&var->value);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
void
|
|
|
|
moo_command_context_unset (MooCommandContext *ctx,
|
|
|
|
const char *name)
|
|
|
|
{
|
|
|
|
g_return_if_fail (MOO_IS_COMMAND_CONTEXT (ctx));
|
|
|
|
g_return_if_fail (name != NULL);
|
|
|
|
g_hash_table_remove (ctx->priv->vars, name);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
moo_command_context_dispose (GObject *object)
|
|
|
|
{
|
|
|
|
MooCommandContext *ctx = MOO_COMMAND_CONTEXT (object);
|
|
|
|
|
|
|
|
if (ctx->priv)
|
|
|
|
{
|
|
|
|
g_hash_table_destroy (ctx->priv->vars);
|
|
|
|
if (ctx->priv->window)
|
|
|
|
g_object_unref (ctx->priv->window);
|
|
|
|
if (ctx->priv->doc)
|
|
|
|
g_object_unref (ctx->priv->doc);
|
|
|
|
ctx->priv = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
G_OBJECT_CLASS (moo_command_context_parent_class)->dispose (object);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
moo_command_context_set_property (GObject *object,
|
|
|
|
guint property_id,
|
|
|
|
const GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
MooCommandContext *ctx = MOO_COMMAND_CONTEXT (object);
|
|
|
|
|
|
|
|
switch (property_id)
|
|
|
|
{
|
|
|
|
case CTX_PROP_DOC:
|
|
|
|
moo_command_context_set_doc (ctx, g_value_get_object (value));
|
|
|
|
break;
|
|
|
|
case CTX_PROP_WINDOW:
|
|
|
|
moo_command_context_set_window (ctx, g_value_get_object (value));
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
moo_command_context_get_property (GObject *object,
|
|
|
|
guint property_id,
|
|
|
|
GValue *value,
|
|
|
|
GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
MooCommandContext *ctx = MOO_COMMAND_CONTEXT (object);
|
|
|
|
|
|
|
|
switch (property_id)
|
|
|
|
{
|
|
|
|
case CTX_PROP_DOC:
|
|
|
|
g_value_set_object (value, ctx->priv->doc);
|
|
|
|
break;
|
|
|
|
case CTX_PROP_WINDOW:
|
|
|
|
g_value_set_object (value, ctx->priv->window);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
moo_command_context_class_init (MooCommandContextClass *klass)
|
|
|
|
{
|
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
|
|
|
|
object_class->dispose = moo_command_context_dispose;
|
|
|
|
object_class->set_property = moo_command_context_set_property;
|
|
|
|
object_class->get_property = moo_command_context_get_property;
|
|
|
|
|
2006-08-18 23:15:42 -07:00
|
|
|
g_type_class_add_private (klass, sizeof (MooCommandContextPrivate));
|
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
g_object_class_install_property (object_class, CTX_PROP_DOC,
|
|
|
|
g_param_spec_object ("doc", "doc", "doc",
|
|
|
|
GTK_TYPE_TEXT_VIEW,
|
|
|
|
G_PARAM_READWRITE));
|
|
|
|
|
|
|
|
g_object_class_install_property (object_class, CTX_PROP_WINDOW,
|
|
|
|
g_param_spec_object ("window", "window", "window",
|
|
|
|
GTK_TYPE_WINDOW,
|
|
|
|
G_PARAM_READWRITE));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
moo_command_context_init (MooCommandContext *ctx)
|
|
|
|
{
|
2006-08-18 23:15:42 -07:00
|
|
|
ctx->priv = G_TYPE_INSTANCE_GET_PRIVATE (ctx, MOO_TYPE_COMMAND_CONTEXT, MooCommandContextPrivate);
|
2006-08-15 22:18:16 -07:00
|
|
|
ctx->priv->vars = g_hash_table_new_full (g_str_hash,
|
|
|
|
g_str_equal,
|
|
|
|
g_free,
|
|
|
|
(GDestroyNotify) variable_free);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
ctx_foreach_func (const char *name,
|
|
|
|
Variable *var,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
struct {
|
|
|
|
MooCommandContextForeachFunc func;
|
|
|
|
gpointer data;
|
|
|
|
} *data = user_data;
|
|
|
|
|
|
|
|
data->func (name, &var->value, data->data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
moo_command_context_foreach (MooCommandContext *ctx,
|
|
|
|
MooCommandContextForeachFunc func,
|
|
|
|
gpointer func_data)
|
|
|
|
{
|
|
|
|
struct {
|
|
|
|
MooCommandContextForeachFunc func;
|
|
|
|
gpointer data;
|
|
|
|
} data;
|
|
|
|
|
|
|
|
g_return_if_fail (MOO_IS_COMMAND_CONTEXT (ctx));
|
|
|
|
g_return_if_fail (func != NULL);
|
|
|
|
|
|
|
|
data.func = func;
|
|
|
|
data.data = func_data;
|
|
|
|
g_hash_table_foreach (ctx->priv->vars, (GHFunc) ctx_foreach_func, &data);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MooCommandContext *
|
|
|
|
moo_command_context_new (gpointer doc,
|
|
|
|
gpointer window)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (!doc || GTK_IS_TEXT_VIEW (doc), NULL);
|
|
|
|
g_return_val_if_fail (!window || GTK_IS_WINDOW (window), NULL);
|
|
|
|
|
|
|
|
return g_object_new (MOO_TYPE_COMMAND_CONTEXT,
|
|
|
|
"doc", doc,
|
|
|
|
"window", window,
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
moo_command_context_set_doc (MooCommandContext *ctx,
|
|
|
|
gpointer doc)
|
|
|
|
{
|
|
|
|
g_return_if_fail (MOO_IS_COMMAND_CONTEXT (ctx));
|
|
|
|
g_return_if_fail (!doc || GTK_IS_TEXT_VIEW (doc));
|
|
|
|
|
|
|
|
if (ctx->priv->doc != doc)
|
|
|
|
{
|
|
|
|
if (ctx->priv->doc)
|
|
|
|
g_object_unref (ctx->priv->doc);
|
|
|
|
if (doc)
|
|
|
|
g_object_ref (doc);
|
|
|
|
ctx->priv->doc = doc;
|
|
|
|
g_object_notify (G_OBJECT (ctx), "doc");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
moo_command_context_set_window (MooCommandContext *ctx,
|
|
|
|
gpointer window)
|
|
|
|
{
|
|
|
|
g_return_if_fail (MOO_IS_COMMAND_CONTEXT (ctx));
|
|
|
|
g_return_if_fail (!window || GTK_IS_WINDOW (window));
|
|
|
|
|
|
|
|
if (ctx->priv->window != window)
|
|
|
|
{
|
|
|
|
if (ctx->priv->window)
|
|
|
|
g_object_unref (ctx->priv->window);
|
|
|
|
if (window)
|
|
|
|
g_object_ref (window);
|
|
|
|
ctx->priv->window = window;
|
|
|
|
g_object_notify (G_OBJECT (ctx), "window");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
gpointer
|
|
|
|
moo_command_context_get_doc (MooCommandContext *ctx)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (MOO_IS_COMMAND_CONTEXT (ctx), NULL);
|
|
|
|
return ctx->priv->doc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
gpointer
|
|
|
|
moo_command_context_get_window (MooCommandContext *ctx)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (MOO_IS_COMMAND_CONTEXT (ctx), NULL);
|
|
|
|
return ctx->priv->window;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-08-31 08:21:39 -07:00
|
|
|
static int
|
|
|
|
find_key (MooCommandType *type,
|
|
|
|
const char *key)
|
|
|
|
{
|
|
|
|
guint i;
|
|
|
|
|
|
|
|
for (i = 0; i < type->n_keys; ++i)
|
|
|
|
if (!strcmp (type->keys[i], key))
|
|
|
|
return i;
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
item_foreach_func (const char *key,
|
|
|
|
const char *val,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
int index;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
MooCommandType *type;
|
|
|
|
MooCommandData *cmd_data;
|
|
|
|
gboolean error;
|
|
|
|
const char *filename;
|
|
|
|
const char *name;
|
|
|
|
} *data = user_data;
|
|
|
|
|
|
|
|
if (data->error)
|
|
|
|
return;
|
|
|
|
|
|
|
|
index = find_key (data->type, key);
|
|
|
|
|
|
|
|
if (index < 0)
|
|
|
|
{
|
|
|
|
g_warning ("unknown key %s in item %s in file %s",
|
|
|
|
key, data->name, data->filename);
|
|
|
|
data->error = TRUE;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
moo_command_data_set (data->cmd_data, index, val);
|
|
|
|
}
|
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
MooCommandData *
|
2006-08-31 08:21:39 -07:00
|
|
|
_moo_command_parse_item (MooKeyFileItem *item,
|
|
|
|
const char *name,
|
|
|
|
const char *filename,
|
|
|
|
MooCommandType **type_p,
|
|
|
|
char **options_p)
|
2006-08-15 22:18:16 -07:00
|
|
|
{
|
|
|
|
MooCommandData *data;
|
2006-08-16 22:08:49 -07:00
|
|
|
MooCommandType *type;
|
2006-08-31 08:21:39 -07:00
|
|
|
char *type_name, *options;
|
|
|
|
struct {
|
2006-09-02 00:30:43 -07:00
|
|
|
MooCommandType *type;
|
2006-08-31 08:21:39 -07:00
|
|
|
MooCommandData *cmd_data;
|
|
|
|
gboolean error;
|
|
|
|
const char *filename;
|
|
|
|
const char *name;
|
|
|
|
} parse_data;
|
2006-08-15 22:18:16 -07:00
|
|
|
|
2006-08-31 08:21:39 -07:00
|
|
|
g_return_val_if_fail (item != NULL, NULL);
|
2006-08-15 22:18:16 -07:00
|
|
|
|
2006-08-31 08:21:39 -07:00
|
|
|
type_name = moo_key_file_item_steal (item, KEY_TYPE);
|
|
|
|
options = moo_key_file_item_steal (item, KEY_OPTIONS);
|
2006-08-15 22:18:16 -07:00
|
|
|
|
2006-08-16 22:08:49 -07:00
|
|
|
if (!type_name)
|
2006-08-15 22:18:16 -07:00
|
|
|
{
|
2006-08-31 08:21:39 -07:00
|
|
|
g_warning ("no type attribute in item %s in file %s", name, filename);
|
|
|
|
goto error;
|
2006-08-15 22:18:16 -07:00
|
|
|
}
|
|
|
|
|
2006-08-16 22:08:49 -07:00
|
|
|
type = moo_command_type_lookup (type_name);
|
|
|
|
|
|
|
|
if (!type)
|
2006-08-15 22:18:16 -07:00
|
|
|
{
|
2006-08-31 08:21:39 -07:00
|
|
|
g_warning ("unknown command type %s in item %s in file %s",
|
|
|
|
type_name, name, filename);
|
|
|
|
goto error;
|
2006-08-15 22:18:16 -07:00
|
|
|
}
|
|
|
|
|
2006-08-31 08:21:39 -07:00
|
|
|
data = moo_command_data_new (type->n_keys);
|
2006-08-15 22:18:16 -07:00
|
|
|
|
2006-09-02 00:30:43 -07:00
|
|
|
parse_data.type = type;
|
2006-08-31 08:21:39 -07:00
|
|
|
parse_data.cmd_data = data;
|
|
|
|
parse_data.error = FALSE;
|
|
|
|
parse_data.filename = filename;
|
|
|
|
parse_data.name = name;
|
2006-08-15 22:18:16 -07:00
|
|
|
|
2006-08-31 08:21:39 -07:00
|
|
|
moo_key_file_item_foreach (item, (GHFunc) item_foreach_func, &parse_data);
|
2006-08-15 22:18:16 -07:00
|
|
|
|
2006-08-31 08:21:39 -07:00
|
|
|
if (parse_data.error)
|
|
|
|
{
|
|
|
|
moo_command_data_unref (data);
|
|
|
|
goto error;
|
2006-08-15 22:18:16 -07:00
|
|
|
}
|
|
|
|
|
2006-08-31 08:21:39 -07:00
|
|
|
moo_command_data_take_code (data, moo_key_file_item_steal_content (item));
|
|
|
|
|
2006-08-16 18:27:19 -07:00
|
|
|
if (type_p)
|
2006-08-16 22:08:49 -07:00
|
|
|
*type_p = type;
|
2006-08-31 08:21:39 -07:00
|
|
|
|
2006-08-16 18:27:19 -07:00
|
|
|
if (options_p)
|
2006-08-31 08:21:39 -07:00
|
|
|
*options_p = options;
|
|
|
|
else
|
|
|
|
g_free (options);
|
2006-08-15 22:18:16 -07:00
|
|
|
|
2006-08-31 08:21:39 -07:00
|
|
|
g_free (type_name);
|
2006-08-16 18:27:19 -07:00
|
|
|
|
2006-08-31 08:21:39 -07:00
|
|
|
return data;
|
2006-08-16 18:27:19 -07:00
|
|
|
|
2006-08-31 08:21:39 -07:00
|
|
|
error:
|
|
|
|
g_free (type_name);
|
|
|
|
g_free (options);
|
|
|
|
return NULL;
|
2006-08-17 21:53:34 -07:00
|
|
|
}
|
|
|
|
|
2006-08-31 08:21:39 -07:00
|
|
|
|
2006-08-17 21:53:34 -07:00
|
|
|
void
|
2006-08-31 08:21:39 -07:00
|
|
|
_moo_command_format_item (MooKeyFileItem *item,
|
|
|
|
MooCommandData *data,
|
|
|
|
MooCommandType *type,
|
|
|
|
char *options)
|
2006-08-17 21:53:34 -07:00
|
|
|
{
|
2006-08-31 08:21:39 -07:00
|
|
|
g_return_if_fail (item != NULL);
|
2006-08-17 21:53:34 -07:00
|
|
|
g_return_if_fail (MOO_IS_COMMAND_TYPE (type));
|
|
|
|
|
2006-08-31 08:21:39 -07:00
|
|
|
moo_key_file_item_set (item, KEY_TYPE, type->name);
|
2006-08-17 21:53:34 -07:00
|
|
|
|
|
|
|
if (options && options[0])
|
2006-08-31 08:21:39 -07:00
|
|
|
moo_key_file_item_set (item, KEY_OPTIONS, options);
|
2006-08-17 21:53:34 -07:00
|
|
|
|
|
|
|
if (data)
|
|
|
|
{
|
2006-08-31 08:21:39 -07:00
|
|
|
guint i;
|
|
|
|
for (i = 0; i < type->n_keys; ++i)
|
|
|
|
moo_key_file_item_set (item, type->keys[i], moo_command_data_get (data, i));
|
|
|
|
moo_key_file_item_set_content (item, moo_command_data_get_code (data));
|
2006-08-17 21:53:34 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-08-16 18:27:19 -07:00
|
|
|
MooCommandData *
|
2006-08-31 08:21:39 -07:00
|
|
|
moo_command_data_new (guint len)
|
2006-08-16 18:27:19 -07:00
|
|
|
{
|
|
|
|
MooCommandData *data = g_new0 (MooCommandData, 1);
|
|
|
|
data->ref_count = 1;
|
2006-08-31 08:21:39 -07:00
|
|
|
data->data = len ? g_new0 (char*, len) : NULL;
|
|
|
|
data->len = len;
|
2006-08-16 18:27:19 -07:00
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
moo_command_data_clear (MooCommandData *data)
|
|
|
|
{
|
2006-08-31 08:21:39 -07:00
|
|
|
guint i;
|
|
|
|
|
2006-08-16 18:27:19 -07:00
|
|
|
g_return_if_fail (data != NULL);
|
2006-08-31 08:21:39 -07:00
|
|
|
|
|
|
|
for (i = 0; i < data->len; ++i)
|
|
|
|
{
|
|
|
|
g_free (data->data[i]);
|
|
|
|
data->data[i] = NULL;
|
|
|
|
}
|
2006-08-15 22:18:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MooCommandData *
|
|
|
|
moo_command_data_ref (MooCommandData *data)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (data != NULL, NULL);
|
|
|
|
data->ref_count++;
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
moo_command_data_unref (MooCommandData *data)
|
|
|
|
{
|
|
|
|
g_return_if_fail (data != NULL);
|
|
|
|
|
|
|
|
if (!--data->ref_count)
|
|
|
|
{
|
2006-08-31 08:21:39 -07:00
|
|
|
guint i;
|
|
|
|
for (i = 0; i < data->len; ++i)
|
|
|
|
g_free (data->data[i]);
|
|
|
|
g_free (data->data);
|
|
|
|
g_free (data->code);
|
2006-08-15 22:18:16 -07:00
|
|
|
g_free (data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
moo_command_data_set (MooCommandData *data,
|
2006-08-31 08:21:39 -07:00
|
|
|
guint index,
|
2006-08-15 22:18:16 -07:00
|
|
|
const char *value)
|
|
|
|
{
|
2006-08-31 08:21:39 -07:00
|
|
|
char *tmp;
|
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
g_return_if_fail (data != NULL);
|
2006-08-31 08:21:39 -07:00
|
|
|
g_return_if_fail (index < data->len);
|
2006-08-15 22:18:16 -07:00
|
|
|
|
2006-08-31 08:21:39 -07:00
|
|
|
tmp = data->data[index];
|
|
|
|
data->data[index] = g_strdup (value);
|
|
|
|
g_free (tmp);
|
2006-08-15 22:18:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const char *
|
|
|
|
moo_command_data_get (MooCommandData *data,
|
2006-08-31 08:21:39 -07:00
|
|
|
guint index)
|
2006-08-15 22:18:16 -07:00
|
|
|
{
|
|
|
|
g_return_val_if_fail (data != NULL, NULL);
|
2006-08-31 08:21:39 -07:00
|
|
|
g_return_val_if_fail (index < data->len, NULL);
|
|
|
|
return data->data[index];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
moo_command_data_take_code (MooCommandData *data,
|
|
|
|
char *code)
|
|
|
|
{
|
|
|
|
char *tmp;
|
|
|
|
|
|
|
|
g_return_if_fail (data != NULL);
|
2006-08-15 22:18:16 -07:00
|
|
|
|
2006-08-31 08:21:39 -07:00
|
|
|
tmp = data->code;
|
|
|
|
data->code = code;
|
|
|
|
g_free (tmp);
|
2006-08-15 22:18:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2006-08-31 08:21:39 -07:00
|
|
|
moo_command_data_set_code (MooCommandData *data,
|
|
|
|
const char *code)
|
2006-08-15 22:18:16 -07:00
|
|
|
{
|
2006-08-31 08:21:39 -07:00
|
|
|
moo_command_data_take_code (data, g_strdup (code));
|
|
|
|
}
|
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
|
2006-08-31 08:21:39 -07:00
|
|
|
const char *
|
|
|
|
moo_command_data_get_code (MooCommandData *data)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (data != NULL, NULL);
|
|
|
|
return data->code;
|
2006-08-15 22:18:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GType
|
|
|
|
moo_command_data_get_type (void)
|
|
|
|
{
|
|
|
|
static GType type;
|
|
|
|
|
|
|
|
if (!type)
|
|
|
|
type = g_boxed_type_register_static ("MooCommandData",
|
|
|
|
(GBoxedCopyFunc) moo_command_data_ref,
|
|
|
|
(GBoxedFreeFunc) moo_command_data_unref);
|
|
|
|
|
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
_moo_command_init (void)
|
|
|
|
{
|
|
|
|
static gboolean been_here = FALSE;
|
|
|
|
|
|
|
|
if (!been_here)
|
|
|
|
{
|
2006-08-20 01:49:33 -07:00
|
|
|
g_type_class_unref (g_type_class_ref (MOO_TYPE_COMMAND_SCRIPT));
|
2006-08-23 21:58:30 -07:00
|
|
|
#ifndef __WIN32__
|
2006-08-20 01:49:33 -07:00
|
|
|
g_type_class_unref (g_type_class_ref (MOO_TYPE_COMMAND_EXE));
|
2006-08-23 21:58:30 -07:00
|
|
|
#endif
|
2006-09-02 00:30:43 -07:00
|
|
|
_moo_command_filter_simple_load ();
|
2006-08-15 22:18:16 -07:00
|
|
|
been_here = TRUE;
|
|
|
|
}
|
|
|
|
}
|
2006-09-01 10:37:47 -07:00
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
filters_init (void)
|
|
|
|
{
|
|
|
|
if (!registered_filters)
|
|
|
|
registered_filters = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static FilterInfo *
|
|
|
|
filter_lookup (const char *id)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (id != NULL, NULL);
|
|
|
|
|
|
|
|
if (registered_filters)
|
|
|
|
return g_hash_table_lookup (registered_filters, id);
|
|
|
|
else
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
moo_command_filter_register (const char *id,
|
|
|
|
const char *name,
|
|
|
|
MooCommandFilterFactory factory_func,
|
|
|
|
gpointer data,
|
|
|
|
GDestroyNotify data_notify)
|
|
|
|
{
|
|
|
|
FilterInfo *info;
|
|
|
|
|
|
|
|
g_return_if_fail (id != NULL);
|
|
|
|
g_return_if_fail (name != NULL);
|
|
|
|
g_return_if_fail (factory_func != NULL);
|
|
|
|
|
|
|
|
filters_init ();
|
|
|
|
|
|
|
|
if (filter_lookup (id))
|
|
|
|
{
|
|
|
|
g_message ("reregistering filter '%s'", id);
|
|
|
|
moo_command_filter_unregister (id);
|
|
|
|
}
|
|
|
|
|
|
|
|
info = g_new0 (FilterInfo, 1);
|
|
|
|
info->name = g_strdup (name);
|
|
|
|
info->factory_func = factory_func;
|
|
|
|
info->data = data;
|
|
|
|
info->data_notify = data_notify;
|
|
|
|
|
|
|
|
g_hash_table_insert (registered_filters, g_strdup (id), info);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
moo_command_filter_unregister (const char *id)
|
|
|
|
{
|
|
|
|
FilterInfo *info;
|
|
|
|
|
|
|
|
g_return_if_fail (id != NULL);
|
|
|
|
|
|
|
|
info = filter_lookup (id);
|
|
|
|
|
|
|
|
if (!info)
|
|
|
|
{
|
|
|
|
g_warning ("filter '%s' not registered", id);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_hash_table_remove (registered_filters, id);
|
|
|
|
|
|
|
|
if (info->data_notify)
|
|
|
|
info->data_notify (info->data);
|
|
|
|
|
|
|
|
g_free (info->name);
|
|
|
|
g_free (info);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const char *
|
|
|
|
moo_command_filter_lookup (const char *id)
|
|
|
|
{
|
|
|
|
FilterInfo *info;
|
|
|
|
|
|
|
|
g_return_val_if_fail (id != NULL, 0);
|
|
|
|
|
|
|
|
info = filter_lookup (id);
|
|
|
|
|
|
|
|
return info ? info->name : NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
prepend_filter_id (const char *id,
|
|
|
|
G_GNUC_UNUSED gpointer info,
|
|
|
|
GSList **list)
|
|
|
|
{
|
|
|
|
*list = g_slist_prepend (*list, g_strdup (id));
|
|
|
|
}
|
|
|
|
|
|
|
|
GSList *
|
|
|
|
moo_command_filter_list (void)
|
|
|
|
{
|
|
|
|
GSList *list = NULL;
|
|
|
|
|
|
|
|
if (registered_filters)
|
|
|
|
g_hash_table_foreach (registered_filters, (GHFunc) prepend_filter_id, &list);
|
|
|
|
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MooOutputFilter *
|
|
|
|
moo_command_filter_create (const char *id)
|
|
|
|
{
|
|
|
|
FilterInfo *info;
|
|
|
|
|
|
|
|
g_return_val_if_fail (id != NULL, NULL);
|
|
|
|
|
|
|
|
info = filter_lookup (id);
|
|
|
|
g_return_val_if_fail (info != NULL, NULL);
|
|
|
|
|
|
|
|
return info->factory_func (id, info->data);
|
|
|
|
}
|