Added MooCommand, object which knows how to "perform an action"

master
Yevgen Muntyan 2006-04-09 02:29:08 -05:00
parent b9a8ab9844
commit 14631f4c40
10 changed files with 673 additions and 80 deletions

View File

@ -119,8 +119,9 @@ static void moo_app_exec_cmd_real (MooApp *app,
char cmd, char cmd,
const char *data, const char *data,
guint len); guint len);
static MSContext *moo_app_get_context_real (MooApp *app, static void moo_app_cmd_setup_real (MooApp *app,
MooWindow *window); MooCommand *cmd,
GtkWindow *window);
static GtkWidget *moo_app_create_prefs_dialog (MooApp *app); static GtkWidget *moo_app_create_prefs_dialog (MooApp *app);
static void moo_app_set_name (MooApp *app, static void moo_app_set_name (MooApp *app,
@ -186,7 +187,7 @@ enum {
TRY_QUIT, TRY_QUIT,
PREFS_DIALOG, PREFS_DIALOG,
EXEC_CMD, EXEC_CMD,
GET_CONTEXT, CMD_SETUP,
LAST_SIGNAL LAST_SIGNAL
}; };
@ -214,7 +215,7 @@ moo_app_class_init (MooAppClass *klass)
klass->try_quit = moo_app_try_quit_real; klass->try_quit = moo_app_try_quit_real;
klass->prefs_dialog = moo_app_create_prefs_dialog; klass->prefs_dialog = moo_app_create_prefs_dialog;
klass->exec_cmd = moo_app_exec_cmd_real; klass->exec_cmd = moo_app_exec_cmd_real;
klass->get_context = moo_app_get_context_real; klass->cmd_setup = moo_app_cmd_setup_real;
g_object_class_install_property (gobject_class, g_object_class_install_property (gobject_class,
PROP_ARGV, PROP_ARGV,
@ -367,15 +368,16 @@ moo_app_class_init (MooAppClass *klass)
G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE, G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE,
G_TYPE_UINT); G_TYPE_UINT);
signals[GET_CONTEXT] = signals[CMD_SETUP] =
g_signal_new ("get-context", g_signal_new ("cmd-setup",
G_OBJECT_CLASS_TYPE (klass), G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_ACTION | G_SIGNAL_RUN_LAST, G_SIGNAL_ACTION | G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (MooAppClass, get_context), G_STRUCT_OFFSET (MooAppClass, cmd_setup),
NULL, NULL, NULL, NULL,
_moo_marshal_OBJECT__OBJECT, _moo_marshal_VOID__OBJECT_OBJECT,
MS_TYPE_CONTEXT, 1, G_TYPE_NONE, 2,
MOO_TYPE_WINDOW); MOO_TYPE_COMMAND,
GTK_TYPE_WINDOW);
} }
@ -754,18 +756,13 @@ moo_app_get_info (MooApp *app)
} }
static MSContext * static void
moo_app_get_context (MooWindow *window) moo_app_cmd_setup (MooCommand *cmd,
MooWindow *window)
{ {
MSContext *ctx; MooApp *app = moo_app_get_instance ();
MooApp *app; g_return_if_fail (app != NULL);
g_signal_emit (app, signals[CMD_SETUP], 0, cmd, window);
app = moo_app_get_instance ();
g_return_val_if_fail (app != NULL, NULL);
g_signal_emit (app, signals[GET_CONTEXT], 0, window, &ctx);
return ctx;
} }
static void static void
@ -782,7 +779,7 @@ moo_app_load_user_actions (void)
char *file = g_build_filename (dirs[i], MOO_ACTIONS_FILE, NULL); char *file = g_build_filename (dirs[i], MOO_ACTIONS_FILE, NULL);
if (g_file_test (file, G_FILE_TEST_EXISTS)) if (g_file_test (file, G_FILE_TEST_EXISTS))
moo_parse_user_actions (file, moo_app_get_context); moo_parse_user_actions (file, moo_app_cmd_setup);
g_free (file); g_free (file);
} }
@ -1593,14 +1590,13 @@ moo_app_tempnam (MooApp *app)
} }
static MSContext * static void
moo_app_get_context_real (G_GNUC_UNUSED MooApp *app, moo_app_cmd_setup_real (MooApp *app,
MooWindow *window) MooCommand *cmd,
GtkWindow *window)
{ {
if (MOO_IS_EDIT_WINDOW (window)) if (MOO_IS_EDIT_WINDOW (window))
return moo_edit_context_new (MOO_EDIT_WINDOW (window)); return moo_edit_setup_command (cmd, MOO_EDIT_WINDOW (window));
else
return ms_context_new (window);
} }

View File

@ -15,7 +15,7 @@
#define __MOO_APP_H__ #define __MOO_APP_H__
#include <mooedit/mooeditor.h> #include <mooedit/mooeditor.h>
#include <mooscript/mooscript-context.h> #include <mooutils/moocommand.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -68,8 +68,9 @@ struct _MooAppClass
char cmd, char cmd,
const char *data, const char *data,
guint len); guint len);
MSContext* (*get_context) (MooApp *app, void (*cmd_setup) (MooApp *app,
MooWindow *window); MooCommand *cmd,
GtkWindow *window);
}; };

View File

@ -153,6 +153,22 @@ moo_edit_context_new (MooEditWindow *window)
} }
void
moo_edit_setup_command (MooCommand *cmd,
MooEditWindow *window)
{
MSContext *ctx;
g_return_if_fail (MOO_IS_COMMAND (cmd));
g_return_if_fail (!window || MOO_IS_EDIT_WINDOW (window));
ctx = moo_edit_context_new (window);
moo_command_set_context (cmd, ctx);
moo_command_set_py_dict (cmd, ctx->py_dict);
g_object_unref (ctx);
}
/******************************************************************/ /******************************************************************/
/* API /* API
*/ */

View File

@ -14,6 +14,7 @@
#ifndef __MOO_EDIT_SCRIPT_H__ #ifndef __MOO_EDIT_SCRIPT_H__
#define __MOO_EDIT_SCRIPT_H__ #define __MOO_EDIT_SCRIPT_H__
#include <mooutils/moocommand.h>
#include <mooscript/mooscript-context.h> #include <mooscript/mooscript-context.h>
#include <mooedit/mooeditor.h> #include <mooedit/mooeditor.h>
@ -44,10 +45,12 @@ struct _MooEditContextClass {
GType moo_edit_context_get_type (void) G_GNUC_CONST; GType moo_edit_context_get_type (void) G_GNUC_CONST;
MSContext *moo_edit_context_new (MooEditWindow *window); MSContext *moo_edit_context_new (MooEditWindow *window);
void moo_edit_context_set_doc (MooEditContext *ctx, void moo_edit_context_set_doc (MooEditContext *ctx,
MooEdit *doc); MooEdit *doc);
void moo_edit_setup_command (MooCommand *cmd,
MooEditWindow *window);
G_END_DECLS G_END_DECLS

View File

@ -16,6 +16,7 @@ mooutils_include_headers = \
$(mooutils)/mooclosure.h \ $(mooutils)/mooclosure.h \
$(mooutils)/moocmd.h \ $(mooutils)/moocmd.h \
$(mooutils)/moocombo.h \ $(mooutils)/moocombo.h \
$(mooutils)/moocommand.h \
$(mooutils)/mooconfig.h \ $(mooutils)/mooconfig.h \
$(mooutils)/mooentry.h \ $(mooutils)/mooentry.h \
$(mooutils)/moofiltermgr.h \ $(mooutils)/moofiltermgr.h \
@ -58,6 +59,7 @@ mooutils_sources = \
$(mooutils)/moocombo.c \ $(mooutils)/moocombo.c \
$(mooutils)/moocompat.c \ $(mooutils)/moocompat.c \
$(mooutils)/moocompat.h \ $(mooutils)/moocompat.h \
$(mooutils)/moocommand.c \
$(mooutils)/mooconfig.c \ $(mooutils)/mooconfig.c \
$(mooutils)/moodialogs.c \ $(mooutils)/moodialogs.c \
$(mooutils)/moodialogs.h \ $(mooutils)/moodialogs.h \

471
moo/mooutils/moocommand.c Normal file
View File

@ -0,0 +1,471 @@
/*
* 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.
*/
#include "mooutils/moocommand.h"
#include "mooutils/moomarshals.h"
#include "mooscript/mooscript-context.h"
#include "mooscript/mooscript-parser.h"
#include <gtk/gtk.h>
static void moo_command_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static void moo_command_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void moo_command_finalize (GObject *object);
static void moo_command_cleanup (MooCommand *cmd);
static void moo_command_run_real (MooCommand *cmd);
static void moo_command_run_script (MooCommand *cmd);
static void moo_command_run_python (MooCommand *cmd);
static void moo_command_run_shell (MooCommand *cmd);
G_DEFINE_TYPE(MooCommand, moo_command, G_TYPE_OBJECT)
enum {
PROP_0,
PROP_CONTEXT,
PROP_PY_DICT,
PROP_SHELL_ENV,
PROP_WINDOW,
PROP_SCRIPT,
PROP_PYTHON_SCRIPT,
PROP_SHELL_COMMAND
};
enum {
RUN,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL];
static void
moo_command_class_init (MooCommandClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = moo_command_finalize;
gobject_class->set_property = moo_command_set_property;
gobject_class->get_property = moo_command_get_property;
klass->run = moo_command_run_real;
g_object_class_install_property (gobject_class,
PROP_CONTEXT,
g_param_spec_object ("context",
"context",
"context",
MS_TYPE_CONTEXT,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_PY_DICT,
g_param_spec_pointer ("py-dict",
"py-dict",
"py-dict",
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_SHELL_ENV,
g_param_spec_boxed ("shell-env",
"shell-env",
"shell-env",
G_TYPE_STRV,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_WINDOW,
g_param_spec_object ("window",
"window",
"window",
GTK_TYPE_WINDOW,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_SCRIPT,
g_param_spec_string ("script",
"script",
"script",
NULL,
G_PARAM_WRITABLE));
g_object_class_install_property (gobject_class,
PROP_PYTHON_SCRIPT,
g_param_spec_string ("python-script",
"python-script",
"python-script",
NULL,
G_PARAM_WRITABLE));
g_object_class_install_property (gobject_class,
PROP_SHELL_COMMAND,
g_param_spec_string ("shell-command",
"shell-command",
"shell-command",
NULL,
G_PARAM_WRITABLE));
signals[RUN] = g_signal_new ("run",
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (MooCommandClass, run),
NULL, NULL,
_moo_marshal_VOID__VOID,
G_TYPE_NONE, 0);
}
static void
moo_command_init (G_GNUC_UNUSED MooCommand *cmd)
{
}
static void
moo_command_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
MooCommand *cmd = MOO_COMMAND (object);
switch (prop_id)
{
case PROP_CONTEXT:
moo_command_set_context (cmd, g_value_get_object (value));
break;
case PROP_PY_DICT:
moo_command_set_py_dict (cmd, g_value_get_pointer (value));
break;
case PROP_SHELL_ENV:
moo_command_set_shell_env (cmd, g_value_get_boxed (value));
break;
case PROP_WINDOW:
moo_command_set_window (cmd, g_value_get_object (value));
break;
case PROP_SCRIPT:
moo_command_set_script (cmd, g_value_get_string (value));
break;
case PROP_PYTHON_SCRIPT:
moo_command_set_python (cmd, g_value_get_string (value));
break;
case PROP_SHELL_COMMAND:
moo_command_set_shell (cmd, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
moo_command_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
MooCommand *cmd = MOO_COMMAND (object);
switch (prop_id)
{
case PROP_CONTEXT:
g_value_set_object (value, cmd->context);
break;
case PROP_PY_DICT:
g_value_set_pointer (value, cmd->py_dict);
break;
case PROP_SHELL_ENV:
g_value_set_boxed (value, cmd->shell_env);
break;
case PROP_WINDOW:
g_value_set_object (value, cmd->window);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
moo_command_finalize (GObject *object)
{
MooCommand *cmd = MOO_COMMAND (object);
moo_command_cleanup (cmd);
if (cmd->context)
g_object_unref (cmd->context);
if (cmd->py_dict)
moo_Py_DECREF (cmd->py_dict);
g_strfreev (cmd->shell_env);
G_OBJECT_CLASS(moo_command_parent_class)->finalize (object);
}
void
moo_command_run (MooCommand *cmd)
{
g_return_if_fail (MOO_IS_COMMAND (cmd));
g_signal_emit (cmd, signals[RUN], 0);
}
static void
moo_command_run_real (MooCommand *cmd)
{
if (!cmd->type)
{
g_message ("%s: no command", G_STRLOC);
return;
}
switch (cmd->type)
{
case MOO_COMMAND_SCRIPT:
return moo_command_run_script (cmd);
case MOO_COMMAND_PYTHON:
return moo_command_run_python (cmd);
case MOO_COMMAND_SHELL:
return moo_command_run_shell (cmd);
}
g_return_if_reached ();
}
static void
moo_command_run_script (MooCommand *cmd)
{
MSValue *val;
g_return_if_fail (cmd->script != NULL);
g_return_if_fail (cmd->context != NULL);
val = ms_top_node_eval (cmd->script,
cmd->context);
if (!val)
{
g_warning ("%s: %s", G_STRLOC,
ms_context_get_error_msg (cmd->context));
ms_context_clear_error (cmd->context);
}
ms_value_unref (val);
}
static void
moo_command_run_python (MooCommand *cmd)
{
MooPyObject *result;
g_return_if_fail (moo_python_running ());
g_return_if_fail (cmd->string != NULL);
if (!cmd->py_dict)
cmd->py_dict = moo_py_get_script_dict ("__moo_script__");
result = moo_python_run_string (cmd->string,
cmd->py_dict,
cmd->py_dict);
if (!result)
moo_PyErr_Print ();
moo_Py_DECREF (result);
}
static void
moo_command_run_shell (MooCommand *cmd)
{
g_return_if_fail (cmd->string);
g_critical ("%s: implement me", G_STRLOC);
}
void
moo_command_set_window (MooCommand *cmd,
gpointer window)
{
g_return_if_fail (MOO_IS_COMMAND (cmd));
g_return_if_fail (!window || GTK_IS_WINDOW (window));
cmd->window = window;
if (cmd->context && cmd->window)
g_object_set (cmd->context, "window", cmd->window, NULL);
g_object_notify (G_OBJECT (cmd), "window");
}
void
moo_command_set_context (MooCommand *cmd,
MSContext *ctx)
{
g_return_if_fail (MOO_IS_COMMAND (cmd));
g_return_if_fail (!ctx || MS_IS_CONTEXT (ctx));
if (cmd->context != ctx)
{
if (cmd->context)
g_object_unref (cmd->context);
cmd->context = ctx;
if (cmd->context)
g_object_ref (cmd->context);
if (cmd->context && cmd->window)
g_object_set (cmd->context, "window", cmd->window, NULL);
g_object_notify (G_OBJECT (cmd), "context");
}
}
void
moo_command_set_py_dict (MooCommand *cmd,
gpointer dict)
{
g_return_if_fail (MOO_IS_COMMAND (cmd));
g_return_if_fail (moo_python_running ());
if (cmd->py_dict != dict)
{
if (cmd->py_dict)
moo_Py_DECREF (cmd->py_dict);
cmd->py_dict = dict;
if (cmd->py_dict)
moo_Py_INCREF (cmd->py_dict);
g_object_notify (G_OBJECT (cmd), "py-dict");
}
}
void
moo_command_set_shell_env (MooCommand *cmd,
char **env)
{
g_return_if_fail (MOO_IS_COMMAND (cmd));
if (cmd->shell_env != env)
{
g_strfreev (cmd->shell_env);
cmd->shell_env = g_strdupv (env);
g_object_notify (G_OBJECT (cmd), "shell-env");
}
}
void
moo_command_set_script (MooCommand *cmd,
const char *string)
{
g_return_if_fail (MOO_IS_COMMAND (cmd));
moo_command_cleanup (cmd);
cmd->type = MOO_COMMAND_SCRIPT;
if (string)
cmd->script = ms_script_parse (string);
}
void
moo_command_set_python (MooCommand *cmd,
const char *string)
{
g_return_if_fail (MOO_IS_COMMAND (cmd));
if (cmd->type == MOO_COMMAND_PYTHON && cmd->string == string)
return;
moo_command_cleanup (cmd);
cmd->type = MOO_COMMAND_PYTHON;
cmd->string = g_strdup (string);
}
void
moo_command_set_shell (MooCommand *cmd,
const char *string)
{
g_return_if_fail (MOO_IS_COMMAND (cmd));
if (cmd->type == MOO_COMMAND_SHELL && cmd->string == string)
return;
moo_command_cleanup (cmd);
cmd->type = MOO_COMMAND_SHELL;
cmd->string = g_strdup (string);
}
static void
moo_command_cleanup (MooCommand *cmd)
{
g_free (cmd->string);
ms_node_unref (cmd->script);
cmd->string = NULL;
cmd->script = NULL;
}
MooCommand *
moo_command_new (MooCommandType type)
{
MooCommand *cmd;
if (!type)
return g_object_new (MOO_TYPE_COMMAND, NULL);
switch (type)
{
case MOO_COMMAND_SCRIPT:
case MOO_COMMAND_PYTHON:
case MOO_COMMAND_SHELL:
cmd = g_object_new (MOO_TYPE_COMMAND, NULL);
cmd->type = type;
return cmd;
}
g_return_val_if_reached (NULL);
}

85
moo/mooutils/moocommand.h Normal file
View File

@ -0,0 +1,85 @@
/*
* moocommand.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 __MOO_COMMAND_H__
#define __MOO_COMMAND_H__
#include <mooscript/mooscript-node.h>
G_BEGIN_DECLS
#define MOO_TYPE_COMMAND (moo_command_get_type ())
#define MOO_COMMAND(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), MOO_TYPE_COMMAND, MooCommand))
#define MOO_COMMAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MOO_TYPE_COMMAND, MooCommandClass))
#define MOO_IS_COMMAND(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), MOO_TYPE_COMMAND))
#define MOO_IS_COMMAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MOO_TYPE_COMMAND))
#define MOO_COMMAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MOO_TYPE_COMMAND, MooCommandClass))
typedef struct _MooCommand MooCommand;
typedef struct _MooCommandClass MooCommandClass;
typedef enum {
MOO_COMMAND_SCRIPT = 1,
MOO_COMMAND_PYTHON,
MOO_COMMAND_SHELL
} MooCommandType;
struct _MooCommand {
GObject object;
MooCommandType type;
gpointer window;
MSContext *context;
gpointer py_dict; /* PyObject* */
char **shell_env;
GHashTable *dict; /* string variables */
char *string;
MSNode *script;
};
struct _MooCommandClass {
GObjectClass object_class;
void (*run) (MooCommand *cmd);
};
GType moo_command_get_type (void) G_GNUC_CONST;
MooCommand *moo_command_new (MooCommandType type);
void moo_command_set_context (MooCommand *cmd,
MSContext *ctx);
void moo_command_set_py_dict (MooCommand *cmd,
gpointer dict);
void moo_command_set_shell_env (MooCommand *cmd,
char **env);
void moo_command_set_window (MooCommand *cmd,
gpointer window);
void moo_command_set_script (MooCommand *cmd,
const char *script);
void moo_command_set_python (MooCommand *cmd,
const char *script);
void moo_command_set_shell (MooCommand *cmd,
const char *cmd_line);
void moo_command_run (MooCommand *cmd);
G_END_DECLS
#endif /* __MOO_COMMAND_H__ */

View File

@ -408,6 +408,7 @@ ms_context_get_error_msg (MSContext *ctx)
g_return_val_if_fail (MS_IS_CONTEXT (ctx), NULL); g_return_val_if_fail (MS_IS_CONTEXT (ctx), NULL);
g_return_val_if_fail (ctx->error < MS_ERROR_LAST, NULL); g_return_val_if_fail (ctx->error < MS_ERROR_LAST, NULL);
g_return_val_if_fail (ctx->error != MS_ERROR_NONE, "ERROR");
if (ctx->error_msg) if (ctx->error_msg)
return ctx->error_msg; return ctx->error_msg;

View File

@ -17,21 +17,21 @@
#include "mooutils/mooconfig.h" #include "mooutils/mooconfig.h"
#include <string.h> #include <string.h>
typedef MooUserActionCtxFunc CtxFunc; typedef MooUserActionSetup SetupFunc;
typedef struct { typedef struct {
char *name; char *name;
char *label; char *label;
char *accel; char *accel;
MSNode *script; MooCommand *cmd;
CtxFunc ctx_func; SetupFunc setup;
} Action; } Action;
typedef struct { typedef struct {
MooAction base; MooAction base;
MooWindow *window; MooWindow *window;
MSNode *script; MooCommand *cmd;
CtxFunc ctx_func; SetupFunc setup;
} MooUserAction; } MooUserAction;
typedef struct { typedef struct {
@ -39,7 +39,7 @@ typedef struct {
} MooUserActionClass; } MooUserActionClass;
GType _moo_user_action_get_type (void) G_GNUC_CONST; GType _moo_user_action_get_type (void) G_GNUC_CONST;
G_DEFINE_TYPE (MooUserAction, _moo_user_action, MOO_TYPE_ACTION) G_DEFINE_TYPE (MooUserAction, _moo_user_action, MOO_TYPE_ACTION)
@ -53,7 +53,8 @@ action_free (Action *action)
g_free (action->name); g_free (action->name);
g_free (action->label); g_free (action->label);
g_free (action->accel); g_free (action->accel);
ms_node_unref (action->script); if (action->cmd)
g_object_unref (action->cmd);
g_free (action); g_free (action);
} }
} }
@ -69,40 +70,41 @@ parse_accel (const char *string)
} }
static MSNode *
parse_code (const char *code)
{
g_return_val_if_fail (code != NULL, NULL);
return ms_script_parse (code);
}
static Action * static Action *
action_new (const char *name, action_new (const char *name,
const char *label, const char *label,
const char *accel, const char *accel,
MooCommandType cmd_type,
const char *code, const char *code,
CtxFunc ctx_func) MooUserActionSetup setup)
{ {
Action *action; Action *action;
MSNode *script; MooCommand *cmd = NULL;
g_return_val_if_fail (name != NULL, NULL); g_return_val_if_fail (name != NULL, NULL);
g_return_val_if_fail (code != NULL, NULL);
script = parse_code (code); cmd = moo_command_new (cmd_type);
g_return_val_if_fail (cmd != NULL, NULL);
if (!script) switch (cmd_type)
{ {
g_warning ("could not parse script\n%s\n", code); case MOO_COMMAND_SCRIPT:
return NULL; moo_command_set_script (cmd, code);
break;
case MOO_COMMAND_PYTHON:
moo_command_set_python (cmd, code);
break;
case MOO_COMMAND_SHELL:
moo_command_set_shell (cmd, code);
break;
} }
action = g_new0 (Action, 1); action = g_new0 (Action, 1);
action->name = g_strdup (name); action->name = g_strdup (name);
action->label = label ? g_strdup (label) : g_strdup (name); action->label = label ? g_strdup (label) : g_strdup (name);
action->accel = parse_accel (accel); action->accel = parse_accel (accel);
action->script = script; action->cmd = cmd;
action->ctx_func = ctx_func; action->setup = setup;
return action; return action;
} }
@ -123,23 +125,22 @@ create_action (MooWindow *window,
NULL); NULL);
action->window = window; action->window = window;
action->script = ms_node_ref (data->script); action->cmd = g_object_ref (data->cmd);
action->ctx_func = data->ctx_func; action->setup = data->setup;
return MOO_ACTION (action); return MOO_ACTION (action);
} }
void void
moo_parse_user_actions (const char *filename, moo_parse_user_actions (const char *filename,
MooUserActionCtxFunc ctx_func) MooUserActionSetup setup)
{ {
guint n_items, i; guint n_items, i;
MooConfig *config; MooConfig *config;
MooWindowClass *klass; MooWindowClass *klass;
g_return_if_fail (filename != NULL); g_return_if_fail (filename != NULL);
g_return_if_fail (ctx_func != NULL);
config = moo_config_parse_file (filename); config = moo_config_parse_file (filename);
@ -152,12 +153,14 @@ moo_parse_user_actions (const char *filename,
for (i = 0; i < n_items; ++i) for (i = 0; i < n_items; ++i)
{ {
Action *action; Action *action;
const char *name, *label, *accel, *code; const char *name, *label, *accel, *code, *type;
MooCommandType cmd_type = 0;
MooConfigItem *item = moo_config_nth_item (config, i); MooConfigItem *item = moo_config_nth_item (config, i);
name = moo_config_item_get_value (item, "action"); name = moo_config_item_get_value (item, "action");
label = moo_config_item_get_value (item, "label"); label = moo_config_item_get_value (item, "label");
accel = moo_config_item_get_value (item, "accel"); accel = moo_config_item_get_value (item, "accel");
type = moo_config_item_get_value (item, "command");
code = moo_config_item_get_content (item); code = moo_config_item_get_content (item);
if (!name) if (!name)
@ -169,13 +172,26 @@ moo_parse_user_actions (const char *filename,
if (!label) if (!label)
label = name; label = name;
if (!code) if (code)
{ {
g_warning ("%s: code missing", G_STRLOC); if (!type || !g_ascii_strcasecmp (type, "script"))
continue; cmd_type = MOO_COMMAND_SCRIPT;
else if (!g_ascii_strcasecmp (type, "shell") ||
!g_ascii_strcasecmp (type, "bat") ||
!g_ascii_strcasecmp (type, "exe"))
cmd_type = MOO_COMMAND_SHELL;
else if (!g_ascii_strcasecmp (type, "python"))
cmd_type = MOO_COMMAND_PYTHON;
if (!cmd_type)
{
g_warning ("%s: unknown command type '%s'", G_STRLOC, type);
continue;
}
} }
action = action_new (name, label, accel, code, ctx_func); action = action_new (name, label, accel,
cmd_type, code, setup);
if (action) if (action)
moo_window_class_new_action_custom (klass, action->name, moo_window_class_new_action_custom (klass, action->name,
@ -197,7 +213,7 @@ static void
moo_user_action_finalize (GObject *object) moo_user_action_finalize (GObject *object)
{ {
MooUserAction *action = (MooUserAction*) object; MooUserAction *action = (MooUserAction*) object;
ms_node_unref (action->script); g_object_unref (action->cmd);
G_OBJECT_CLASS(_moo_user_action_parent_class)->finalize (object); G_OBJECT_CLASS(_moo_user_action_parent_class)->finalize (object);
} }
@ -205,19 +221,21 @@ moo_user_action_finalize (GObject *object)
static void static void
moo_user_action_activate (MooAction *_action) moo_user_action_activate (MooAction *_action)
{ {
MSContext *ctx;
MSValue *value;
MooUserAction *action = (MooUserAction*) _action; MooUserAction *action = (MooUserAction*) _action;
ctx = action->ctx_func (action->window); g_return_if_fail (action->cmd != NULL);
value = ms_top_node_eval (action->script, ctx);
if (!value) moo_command_set_window (action->cmd, action->window);
g_warning ("%s: %s", G_STRLOC, ms_context_get_error_msg (ctx));
else
ms_value_unref (value);
g_object_unref (ctx); if (action->setup)
action->setup (action->cmd, action->window);
moo_command_run (action->cmd);
moo_command_set_context (action->cmd, NULL);
moo_command_set_py_dict (action->cmd, NULL);
moo_command_set_shell_env (action->cmd, NULL);
moo_command_set_window (action->cmd, NULL);
} }

View File

@ -14,17 +14,17 @@
#ifndef __MOO_USER_ACTIONS_H__ #ifndef __MOO_USER_ACTIONS_H__
#define __MOO_USER_ACTIONS_H__ #define __MOO_USER_ACTIONS_H__
#include <mooscript/mooscript-context.h> #include <mooutils/moocommand.h>
#include <mooutils/moowindow.h> #include <mooutils/moowindow.h>
G_BEGIN_DECLS G_BEGIN_DECLS
typedef MSContext* (*MooUserActionCtxFunc) (MooWindow *window); typedef void (*MooUserActionSetup) (MooCommand *command,
MooWindow *window);
void moo_parse_user_actions (const char *file,
void moo_parse_user_actions (const char *file, MooUserActionSetup setup);
MooUserActionCtxFunc ctx_func);
G_END_DECLS G_END_DECLS