medit/moo/mooedit/moousertools.c

895 lines
23 KiB
C
Raw Normal View History

/*
* moousertools.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 "mooedit/moousertools.h"
2006-08-15 22:18:16 -07:00
#include "mooedit/moocommand.h"
2006-08-17 21:53:34 -07:00
#include "mooedit/mooeditor.h"
#include "mooedit/mooeditaction.h"
#include "mooedit/mooeditaction-factory.h"
#include "mooutils/mooutils-misc.h"
#include "mooutils/mooaccel.h"
2006-08-15 22:18:16 -07:00
#include "mooutils/mooi18n.h"
#include "mooutils/mooaction-private.h"
#include <string.h>
2006-08-17 21:53:34 -07:00
#ifdef __WIN32__
#if MOO_USER_TOOL_THIS_OS != MOO_USER_TOOL_WIN32
#error "oops"
#endif
#else
#if MOO_USER_TOOL_THIS_OS != MOO_USER_TOOL_UNIX
#error "oops"
#endif
#endif
2006-08-15 22:18:16 -07:00
2006-08-17 21:53:34 -07:00
#define N_TOOLS 2
#define ELEMENT_TOOLS "tools"
#define ELEMENT_TOOL "tool"
#define ELEMENT_ACCEL "accel"
#define ELEMENT_MENU "menu"
#define ELEMENT_LANGS "langs"
#define ELEMENT_FILTER "filter"
#define ELEMENT_POSITION "position"
#define ELEMENT_COMMAND "command"
#define PROP_NAME "name"
#define PROP_ENABLED "enabled"
#define PROP_OS "os"
2006-04-20 01:57:05 -07:00
2006-08-15 22:18:16 -07:00
enum {
PROP_0,
PROP_COMMAND
};
typedef struct {
2006-08-15 22:18:16 -07:00
GSList *tools;
} ToolStore;
2006-08-17 21:53:34 -07:00
2006-08-15 22:18:16 -07:00
typedef struct {
char *id;
MooUIXML *xml;
guint merge_id;
2006-08-15 22:18:16 -07:00
} ToolInfo;
2006-08-15 22:18:16 -07:00
typedef struct {
MooEditAction parent;
MooCommand *cmd;
} MooToolAction;
2006-08-15 22:18:16 -07:00
typedef MooEditActionClass MooToolActionClass;
2006-08-15 22:18:16 -07:00
GType _moo_tool_action_get_type (void) G_GNUC_CONST;
G_DEFINE_TYPE (MooToolAction, _moo_tool_action, MOO_TYPE_EDIT_ACTION);
#define MOO_TYPE_TOOL_ACTION (_moo_tool_action_get_type())
#define MOO_IS_TOOL_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, MOO_TYPE_TOOL_ACTION))
#define MOO_TOOL_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, MOO_TYPE_TOOL_ACTION, MooToolAction))
2006-08-17 21:53:34 -07:00
static const char *FILENAMES[N_TOOLS] = {"menu.xml", "context.xml"};
2006-08-16 18:27:19 -07:00
static ToolStore *tools_stores[N_TOOLS];
2006-08-15 22:18:16 -07:00
static MooCommandContext *create_command_context (gpointer window,
gpointer doc);
static void
unload_user_tools (int type)
{
ToolStore *store = tools_stores[type];
GSList *list;
gpointer klass;
2006-08-17 21:53:34 -07:00
g_assert (type < N_TOOLS);
2006-08-15 22:18:16 -07:00
if (!store)
return;
2006-08-15 22:18:16 -07:00
list = store->tools;
store->tools = NULL;
2006-08-17 21:53:34 -07:00
if (type == MOO_USER_TOOL_MENU)
2006-08-15 22:18:16 -07:00
klass = g_type_class_peek (MOO_TYPE_EDIT_WINDOW);
else
klass = g_type_class_peek (MOO_TYPE_EDIT);
2006-08-15 22:18:16 -07:00
while (list)
{
2006-08-15 22:18:16 -07:00
ToolInfo *info = list->data;
if (info->xml)
{
moo_ui_xml_remove_ui (info->xml, info->merge_id);
g_object_unref (info->xml);
}
2006-08-17 21:53:34 -07:00
if (type == MOO_USER_TOOL_MENU)
2006-08-15 22:18:16 -07:00
moo_window_class_remove_action (klass, info->id);
else
moo_edit_class_remove_action (klass, info->id);
g_free (info->id);
g_free (info);
2006-08-17 21:53:34 -07:00
list = g_slist_delete_link (list, list);
}
2006-08-15 22:18:16 -07:00
g_free (store);
tools_stores[type] = NULL;
}
2006-08-17 21:53:34 -07:00
static ToolInfo *
tools_store_add (MooUserToolType type,
char *id)
{
ToolInfo *info;
g_assert (type < N_TOOLS);
info = g_new0 (ToolInfo, 1);
info->id = g_strdup (id);
info->xml = moo_editor_get_ui_xml (moo_editor_instance ());
if (info->xml)
{
g_object_ref (info->xml);
info->merge_id = moo_ui_xml_new_merge_id (info->xml);
}
if (!tools_stores[type])
tools_stores[type] = g_new0 (ToolStore, 1);
tools_stores[type]->tools = g_slist_prepend (tools_stores[type]->tools, info);
return info;
}
2006-08-15 22:18:16 -07:00
static char *
find_user_tools_file (int type)
2006-04-20 01:57:05 -07:00
{
2006-08-15 22:18:16 -07:00
char **files;
guint n_files;
char *filename = NULL;
int i;
2006-04-20 01:57:05 -07:00
2006-08-17 21:53:34 -07:00
files = moo_get_data_files (FILENAMES[type], MOO_DATA_SHARE, &n_files);
2006-04-20 01:57:05 -07:00
2006-08-15 22:18:16 -07:00
if (!n_files)
return NULL;
for (i = n_files - 1; i >= 0; --i)
{
if (g_file_test (files[i], G_FILE_TEST_EXISTS))
{
filename = g_strdup (files[i]);
break;
}
}
g_strfreev (files);
return filename;
2006-04-20 01:57:05 -07:00
}
2006-08-15 22:18:16 -07:00
static gboolean
check_sensitive_func (GtkAction *gtkaction,
MooEditWindow *window,
MooEdit *doc,
G_GNUC_UNUSED gpointer data)
{
2006-08-15 22:18:16 -07:00
MooToolAction *action;
2006-08-15 22:18:16 -07:00
g_return_val_if_fail (MOO_IS_TOOL_ACTION (gtkaction), FALSE);
action = MOO_TOOL_ACTION (gtkaction);
2006-08-15 22:18:16 -07:00
return moo_command_check_sensitive (action->cmd, doc, window);
}
2006-08-15 22:18:16 -07:00
static void
2006-08-17 21:53:34 -07:00
mangle_name (const char *label,
char **id,
char **name)
{
char *underscore;
*id = g_strdup (label);
g_strcanon (*id, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "_", '_');
*name = g_strdup (label);
underscore = strchr (*name, '_');
if (underscore)
memmove (underscore, underscore + 1, strlen (underscore + 1) + 1);
}
static gboolean
check_info (MooUserToolInfo *info,
MooUserToolType type)
{
if (!info->name || !info->name[0])
{
g_warning ("tool name missing in file %s", info->file);
return FALSE;
}
if (info->filter && type != MOO_USER_TOOL_CONTEXT)
g_warning ("filter specified in tool %s in file %s",
info->name, info->file);
if (info->position != MOO_USER_TOOL_POS_END &&
type != MOO_USER_TOOL_CONTEXT)
{
g_warning ("filter specified in tool %s in file %s",
info->name, info->file);
}
if (info->menu != NULL && type != MOO_USER_TOOL_MENU)
g_warning ("menu specified in tool %s in file %s",
info->name, info->file);
if (!info->cmd_data)
info->cmd_data = moo_command_data_new ();
if (!info->cmd_type)
{
g_warning ("command typ missing in tool '%s' in file %s",
info->name, info->file);
return FALSE;
}
return TRUE;
}
static void
2006-08-18 22:21:29 -07:00
load_tool (MooUserToolInfo *info)
{
2006-08-15 22:18:16 -07:00
ToolInfo *tool_info;
gpointer klass = NULL;
2006-08-16 18:27:19 -07:00
MooCommand *cmd;
2006-08-17 21:53:34 -07:00
char *id, *name;
2006-08-16 22:08:49 -07:00
g_return_if_fail (info != NULL);
2006-08-17 21:53:34 -07:00
g_return_if_fail (info->file != NULL);
if (!check_info (info, info->type))
return;
2006-08-16 22:08:49 -07:00
2006-08-16 18:27:19 -07:00
if (!info->enabled)
2006-05-01 01:35:41 -07:00
return;
2006-04-20 12:13:42 -07:00
#ifdef __WIN32__
2006-08-17 21:53:34 -07:00
if (info->os_type != MOO_USER_TOOL_WIN32)
2006-08-15 22:18:16 -07:00
return;
2006-08-16 18:27:19 -07:00
#else
2006-08-17 21:53:34 -07:00
if (info->os_type != MOO_USER_TOOL_UNIX)
2006-08-15 22:18:16 -07:00
return;
2006-08-16 18:27:19 -07:00
#endif
2006-08-16 22:08:49 -07:00
g_return_if_fail (MOO_IS_COMMAND_TYPE (info->cmd_type));
cmd = moo_command_create (info->cmd_type->name,
2006-08-16 18:27:19 -07:00
info->options,
info->cmd_data);
2006-08-15 22:18:16 -07:00
if (!cmd)
{
2006-08-16 18:27:19 -07:00
g_warning ("could not get command for tool '%s' in file %s",
2006-08-17 21:53:34 -07:00
info->name, info->file);
2006-08-15 22:18:16 -07:00
return;
}
2006-08-17 21:53:34 -07:00
mangle_name (info->name, &id, &name);
2006-08-16 18:27:19 -07:00
switch (info->type)
2006-04-20 01:57:05 -07:00
{
2006-08-17 21:53:34 -07:00
case MOO_USER_TOOL_MENU:
klass = g_type_class_peek (MOO_TYPE_EDIT_WINDOW);
2006-04-20 01:57:05 -07:00
2006-08-15 22:18:16 -07:00
if (!moo_window_class_find_group (klass, "Tools"))
moo_window_class_new_group (klass, "Tools", _("Tools"));
2006-08-17 21:53:34 -07:00
moo_window_class_new_action (klass, id, "Tools",
2006-08-15 22:18:16 -07:00
"action-type::", MOO_TYPE_TOOL_ACTION,
2006-08-17 21:53:34 -07:00
"display-name", name,
"label", info->name,
2006-08-16 18:27:19 -07:00
"accel", info->accel,
2006-08-15 22:18:16 -07:00
"command", cmd,
NULL);
2006-08-17 21:53:34 -07:00
moo_edit_window_set_action_check (id, MOO_ACTION_CHECK_SENSITIVE,
2006-08-15 22:18:16 -07:00
check_sensitive_func,
NULL, NULL);
2006-08-16 18:27:19 -07:00
if (info->langs)
2006-08-17 21:53:34 -07:00
moo_edit_window_set_action_langs (id, MOO_ACTION_CHECK_ACTIVE, info->langs);
2006-08-15 22:18:16 -07:00
2006-04-20 01:57:05 -07:00
break;
2006-08-17 21:53:34 -07:00
case MOO_USER_TOOL_CONTEXT:
klass = g_type_class_peek (MOO_TYPE_EDIT);
2006-08-17 21:53:34 -07:00
moo_edit_class_new_action (klass, id,
2006-08-15 22:18:16 -07:00
"action-type::", MOO_TYPE_TOOL_ACTION,
2006-08-17 21:53:34 -07:00
"display-name", name,
"label", info->name,
2006-08-16 18:27:19 -07:00
"accel", info->accel,
2006-08-15 22:18:16 -07:00
"command", cmd,
2006-08-16 18:27:19 -07:00
"langs", info->langs,
2006-08-15 22:18:16 -07:00
NULL);
2006-04-20 01:57:05 -07:00
break;
}
2006-08-17 21:53:34 -07:00
tool_info = tools_store_add (info->type, id);
2006-08-15 22:18:16 -07:00
2006-08-17 21:53:34 -07:00
if (tool_info->xml)
{
const char *ui_path;
char *freeme = NULL;
char *markup;
2006-08-17 21:53:34 -07:00
markup = g_markup_printf_escaped ("<item action=\"%s\"/>", id);
2006-04-20 01:57:05 -07:00
2006-08-17 21:53:34 -07:00
if (info->type == MOO_USER_TOOL_CONTEXT)
2006-04-20 01:57:05 -07:00
{
2006-08-16 18:27:19 -07:00
2006-08-17 21:53:34 -07:00
if (info->position == MOO_USER_TOOL_POS_START)
2006-08-16 18:27:19 -07:00
ui_path = "Editor/Popup/PopupStart";
else
ui_path = "Editor/Popup/PopupEnd";
}
else
{
freeme = g_strdup_printf ("Editor/Menubar/%s/UserMenu",
2006-08-16 18:27:19 -07:00
info->menu ? info->menu : "Tools");
ui_path = freeme;
2006-04-20 01:57:05 -07:00
}
2006-08-17 21:53:34 -07:00
moo_ui_xml_insert_markup (tool_info->xml,
tool_info->merge_id,
ui_path, -1, markup);
g_free (markup);
g_free (freeme);
}
2006-08-17 21:53:34 -07:00
g_free (id);
g_free (name);
2006-08-15 22:18:16 -07:00
g_object_unref (cmd);
}
2006-08-16 18:27:19 -07:00
void
2006-08-17 21:53:34 -07:00
_moo_edit_load_user_tools (MooUserToolType type)
2006-08-16 18:27:19 -07:00
{
2006-08-18 22:21:29 -07:00
GSList *list;
2006-08-16 18:27:19 -07:00
unload_user_tools (type);
2006-08-18 22:21:29 -07:00
list = _moo_edit_parse_user_tools (type);
while (list)
{
load_tool (list->data);
_moo_user_tool_info_unref (list->data);
list = g_slist_delete_link (list, list);
}
2006-08-16 18:27:19 -07:00
}
2006-08-18 22:21:29 -07:00
static MooUserToolInfo *
2006-08-16 18:27:19 -07:00
parse_element (MooMarkupNode *node,
2006-08-17 21:53:34 -07:00
MooUserToolType type,
2006-08-16 18:27:19 -07:00
const char *file)
{
const char *os;
const char *position = NULL;
MooMarkupNode *cmd_node, *child;
2006-08-17 21:53:34 -07:00
MooUserToolInfo *info;
2006-08-16 18:27:19 -07:00
2006-08-17 21:53:34 -07:00
if (strcmp (node->name, ELEMENT_TOOL))
2006-08-16 18:27:19 -07:00
{
g_warning ("invalid element %s in file %s", node->name, file);
2006-08-18 22:21:29 -07:00
return NULL;
2006-08-16 18:27:19 -07:00
}
2006-08-18 22:21:29 -07:00
info = _moo_user_tool_info_new ();
info->type = type;
info->file = g_strdup (file);
info->position = MOO_USER_TOOL_POS_END;
2006-08-17 21:53:34 -07:00
info->name = g_strdup (moo_markup_get_prop (node, PROP_NAME));
2006-08-16 18:27:19 -07:00
2006-08-17 21:53:34 -07:00
info->enabled = moo_markup_get_bool_prop (node, PROP_ENABLED, TRUE);
os = moo_markup_get_prop (node, PROP_OS);
2006-08-16 18:27:19 -07:00
#ifdef __WIN32__
2006-08-17 21:53:34 -07:00
info->os_type = (!os || !g_ascii_strncasecmp (os, "win", 3)) ? MOO_USER_TOOL_WIN32 : MOO_USER_TOOL_UNIX;
2006-08-16 18:27:19 -07:00
#else
2006-08-17 21:53:34 -07:00
info->os_type = (!os || !g_ascii_strcasecmp (os, "unix")) ? MOO_USER_TOOL_UNIX : MOO_USER_TOOL_WIN32;
2006-08-16 18:27:19 -07:00
#endif
for (child = node->children; child != NULL; child = child->next)
{
2006-08-17 21:53:34 -07:00
if (!MOO_MARKUP_IS_ELEMENT (child) || !strcmp (child->name, ELEMENT_COMMAND))
2006-08-16 18:27:19 -07:00
continue;
2006-08-17 21:53:34 -07:00
if (!strcmp (child->name, ELEMENT_FILTER))
{
if (info->filter)
{
g_warning ("duplicated element '%s' in tool %s in file %s",
child->name, info->name, file);
_moo_user_tool_info_unref (info);
2006-08-18 22:21:29 -07:00
return NULL;
2006-08-17 21:53:34 -07:00
}
info->filter = g_strdup (moo_markup_get_content (child));
}
else if (!strcmp (child->name, ELEMENT_ACCEL))
{
if (info->accel)
{
g_warning ("duplicated element '%s' in tool %s in file %s",
child->name, info->name, file);
_moo_user_tool_info_unref (info);
2006-08-18 22:21:29 -07:00
return NULL;
2006-08-17 21:53:34 -07:00
}
info->accel = g_strdup (moo_markup_get_content (child));
}
else if (!strcmp (child->name, ELEMENT_POSITION))
{
2006-08-16 18:27:19 -07:00
position = moo_markup_get_content (child);
2006-08-17 21:53:34 -07:00
}
else if (!strcmp (child->name, ELEMENT_MENU))
{
if (info->menu)
{
g_warning ("duplicated element '%s' in tool %s in file %s",
child->name, info->name, file);
_moo_user_tool_info_unref (info);
2006-08-18 22:21:29 -07:00
return NULL;
2006-08-17 21:53:34 -07:00
}
info->menu = g_strdup (moo_markup_get_content (child));
}
else if (!strcmp (child->name, ELEMENT_LANGS))
{
if (info->langs)
{
g_warning ("duplicated element '%s' in tool %s in file %s",
child->name, info->name, file);
_moo_user_tool_info_unref (info);
2006-08-18 22:21:29 -07:00
return NULL;
2006-08-17 21:53:34 -07:00
}
info->langs = g_strdup (moo_markup_get_content (child));
}
2006-08-16 18:27:19 -07:00
else
2006-08-17 21:53:34 -07:00
{
2006-08-16 18:27:19 -07:00
g_warning ("unknown element %s in tool %s in file %s",
2006-08-17 21:53:34 -07:00
child->name, info->name, file);
}
2006-08-16 18:27:19 -07:00
}
2006-08-17 21:53:34 -07:00
if (position)
2006-08-16 18:27:19 -07:00
{
if (!g_ascii_strcasecmp (position, "end"))
2006-08-17 21:53:34 -07:00
info->position = MOO_USER_TOOL_POS_END;
2006-08-16 18:27:19 -07:00
else if (!g_ascii_strcasecmp (position, "start"))
2006-08-17 21:53:34 -07:00
info->position = MOO_USER_TOOL_POS_START;
2006-08-16 18:27:19 -07:00
else
g_warning ("unknown position type '%s' for tool %s in file %s",
2006-08-17 21:53:34 -07:00
position, info->name, file);
2006-08-16 18:27:19 -07:00
}
2006-08-17 21:53:34 -07:00
cmd_node = moo_markup_get_element (node, ELEMENT_COMMAND);
2006-08-16 18:27:19 -07:00
if (!cmd_node)
{
2006-08-17 21:53:34 -07:00
g_warning ("command missing for tool '%s' in file %s", info->name, file);
_moo_user_tool_info_unref (info);
2006-08-18 22:21:29 -07:00
return NULL;
2006-08-16 18:27:19 -07:00
}
2006-08-17 21:53:34 -07:00
info->cmd_data = _moo_command_parse_markup (cmd_node, &info->cmd_type, &info->options);
2006-08-16 18:27:19 -07:00
2006-08-17 21:53:34 -07:00
if (!info->cmd_data)
2006-08-16 18:27:19 -07:00
{
2006-08-17 21:53:34 -07:00
g_warning ("could not get command data for tool '%s' in file %s", info->name, file);
_moo_user_tool_info_unref (info);
2006-08-18 22:21:29 -07:00
return NULL;
2006-08-16 18:27:19 -07:00
}
2006-08-18 22:21:29 -07:00
return info;
2006-08-16 18:27:19 -07:00
}
2006-08-18 22:21:29 -07:00
static GSList *
2006-08-16 18:27:19 -07:00
parse_doc (MooMarkupDoc *doc,
2006-08-18 22:21:29 -07:00
MooUserToolType type)
{
2006-08-15 22:18:16 -07:00
MooMarkupNode *root, *child;
2006-08-18 22:21:29 -07:00
GSList *list = NULL;
2006-08-17 21:53:34 -07:00
root = moo_markup_get_root_element (doc, ELEMENT_TOOLS);
2006-08-15 22:18:16 -07:00
if (!root)
2006-04-20 01:57:05 -07:00
{
2006-08-17 21:53:34 -07:00
g_warning ("no '" ELEMENT_TOOLS "' element in file '%s'", doc->name);
2006-08-18 22:21:29 -07:00
return NULL;
2006-04-20 01:57:05 -07:00
}
2006-08-15 22:18:16 -07:00
for (child = root->children; child != NULL; child = child->next)
{
2006-08-15 22:18:16 -07:00
if (MOO_MARKUP_IS_ELEMENT (child))
2006-08-18 22:21:29 -07:00
{
MooUserToolInfo *info = parse_element (child, type, doc->name);
if (info)
list = g_slist_prepend (list, info);
}
}
2006-08-18 22:21:29 -07:00
return g_slist_reverse (list);
}
2006-08-18 22:21:29 -07:00
GSList *
_moo_edit_parse_user_tools (MooUserToolType type)
2006-08-16 18:27:19 -07:00
{
char *file;
MooMarkupDoc *doc;
GError *error = NULL;
2006-08-18 22:21:29 -07:00
GSList *list = NULL;
2006-08-16 18:27:19 -07:00
2006-08-18 22:21:29 -07:00
g_return_val_if_fail (type < N_TOOLS, NULL);
2006-08-16 18:27:19 -07:00
_moo_command_init ();
file = find_user_tools_file (type);
if (!file)
2006-08-18 22:21:29 -07:00
return NULL;
2006-08-16 18:27:19 -07:00
doc = moo_markup_parse_file (file, &error);
if (doc)
{
2006-08-18 22:21:29 -07:00
list = parse_doc (doc, type);
2006-08-16 18:27:19 -07:00
moo_markup_doc_unref (doc);
}
else
{
g_warning ("could not load file '%s': %s", file, error->message);
g_error_free (error);
}
g_free (file);
2006-08-18 22:21:29 -07:00
return list;
2006-08-16 18:27:19 -07:00
}
2006-08-17 21:53:34 -07:00
void
_moo_edit_save_user_tools (MooUserToolType type,
const GSList *list)
{
MooMarkupDoc *doc;
MooMarkupNode *root;
GError *error = NULL;
char *string;
g_return_if_fail (type < N_TOOLS);
doc = moo_markup_doc_new ("tools");
root = moo_markup_create_root_element (doc, ELEMENT_TOOLS);
while (list)
{
MooMarkupNode *node;
const MooUserToolInfo *info = list->data;
node = moo_markup_create_element (root, ELEMENT_TOOL);
if (info->name && info->name[0])
moo_markup_set_prop (node, PROP_NAME, info->name);
if (info->accel && info->accel[0])
moo_markup_create_text_element (node, ELEMENT_ACCEL, info->accel);
if (info->menu && info->menu[0])
moo_markup_create_text_element (node, ELEMENT_MENU, info->menu);
if (info->langs && info->langs[0])
moo_markup_create_text_element (node, ELEMENT_LANGS, info->langs);
if (info->filter && info->filter[0])
moo_markup_create_text_element (node, ELEMENT_FILTER, info->filter);
if (!info->enabled)
moo_markup_set_bool_prop (node, PROP_ENABLED, info->enabled);
if (info->position != MOO_USER_TOOL_POS_END)
moo_markup_create_text_element (node, ELEMENT_POSITION, "start");
_moo_command_format_markup (node, info->cmd_data,
info->cmd_type, info->options);
list = list->next;
}
string = moo_markup_node_get_pretty_string (MOO_MARKUP_NODE (doc), 2);
g_message ("saving file %s", FILENAMES[type]);
if (!moo_save_user_data_file (FILENAMES[type], string, -1, &error))
{
g_critical ("could not save tools file: %s", error->message);
g_error_free (error);
}
g_message ("done");
g_free (string);
moo_markup_doc_unref (doc);
}
MooUserToolInfo *
_moo_user_tool_info_new (void)
{
MooUserToolInfo *info = g_new0 (MooUserToolInfo, 1);
info->ref_count = 1;
return info;
}
MooUserToolInfo *
_moo_user_tool_info_ref (MooUserToolInfo *info)
{
g_return_val_if_fail (info != NULL, NULL);
info->ref_count++;
return info;
}
void
_moo_user_tool_info_unref (MooUserToolInfo *info)
{
g_return_if_fail (info != NULL);
if (--info->ref_count)
return;
g_free (info->name);
g_free (info->accel);
g_free (info->menu);
g_free (info->langs);
g_free (info->options);
g_free (info->filter);
g_free (info->file);
if (info->cmd_data)
moo_command_data_unref (info->cmd_data);
g_free (info);
}
GType
_moo_user_tool_info_get_type (void)
{
static GType type = 0;
if (!type)
type = g_boxed_type_register_static ("MooUserToolInfo",
(GBoxedCopyFunc) _moo_user_tool_info_ref,
(GBoxedFreeFunc) _moo_user_tool_info_unref);
return type;
}
static void
2006-08-15 22:18:16 -07:00
moo_tool_action_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
2006-08-15 22:18:16 -07:00
MooToolAction *action = MOO_TOOL_ACTION (object);
2006-08-15 22:18:16 -07:00
switch (property_id)
{
2006-08-15 22:18:16 -07:00
case PROP_COMMAND:
if (action->cmd)
g_object_unref (action->cmd);
action->cmd = g_value_get_object (value);
if (action->cmd)
g_object_ref (action->cmd);
break;
2006-08-15 22:18:16 -07:00
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
2006-04-20 01:57:05 -07:00
static void
2006-08-15 22:18:16 -07:00
moo_tool_action_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
2006-04-20 01:57:05 -07:00
{
2006-08-15 22:18:16 -07:00
MooToolAction *action = MOO_TOOL_ACTION (object);
2006-04-20 01:57:05 -07:00
2006-08-15 22:18:16 -07:00
switch (property_id)
2006-04-20 01:57:05 -07:00
{
2006-08-15 22:18:16 -07:00
case PROP_COMMAND:
g_value_set_object (value, action->cmd);
break;
2006-04-20 01:57:05 -07:00
2006-08-15 22:18:16 -07:00
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
2006-04-20 01:57:05 -07:00
}
2006-08-15 22:18:16 -07:00
static void
moo_tool_action_finalize (GObject *object)
2006-04-16 20:06:13 -07:00
{
2006-08-15 22:18:16 -07:00
MooToolAction *action = MOO_TOOL_ACTION (object);
2006-04-16 20:06:13 -07:00
2006-08-15 22:18:16 -07:00
if (action->cmd)
g_object_unref (action->cmd);
2006-08-15 22:18:16 -07:00
G_OBJECT_CLASS (_moo_tool_action_parent_class)->finalize (object);
2006-04-16 20:06:13 -07:00
}
static void
2006-08-15 22:18:16 -07:00
moo_tool_action_activate (GtkAction *gtkaction)
{
2006-08-15 22:18:16 -07:00
MooEditWindow *window;
MooCommandContext *ctx = NULL;
MooEdit *doc;
2006-08-15 22:18:16 -07:00
MooToolAction *action = MOO_TOOL_ACTION (gtkaction);
MooEditAction *edit_action = MOO_EDIT_ACTION (gtkaction);
2006-08-15 22:18:16 -07:00
g_return_if_fail (action->cmd != NULL);
2006-04-16 20:06:13 -07:00
doc = moo_edit_action_get_doc (edit_action);
if (doc)
2006-08-15 22:18:16 -07:00
{
window = moo_edit_get_window (doc);
}
else
{
2006-08-15 22:18:16 -07:00
window = _moo_action_get_window (action);
g_return_if_fail (MOO_IS_EDIT_WINDOW (window));
doc = moo_edit_window_get_active_doc (window);
}
2006-08-15 22:18:16 -07:00
ctx = create_command_context (window, doc);
2006-04-16 20:06:13 -07:00
2006-08-15 22:18:16 -07:00
moo_command_run (action->cmd, ctx);
2006-08-15 22:18:16 -07:00
g_object_unref (ctx);
}
2006-08-15 22:18:16 -07:00
static void
2006-08-15 22:18:16 -07:00
moo_tool_action_check_state (MooEditAction *edit_action)
{
2006-08-15 22:18:16 -07:00
gboolean sensitive;
MooToolAction *action = MOO_TOOL_ACTION (edit_action);
MooEdit *doc;
2006-08-15 22:18:16 -07:00
g_return_if_fail (action->cmd != NULL);
2006-08-15 22:18:16 -07:00
MOO_EDIT_ACTION_CLASS (_moo_tool_action_parent_class)->check_state (edit_action);
2006-08-15 22:18:16 -07:00
if (!gtk_action_is_visible (GTK_ACTION (action)))
return;
doc = moo_edit_action_get_doc (edit_action);
sensitive = moo_command_check_sensitive (action->cmd, doc, moo_edit_get_window (doc));
2006-08-15 22:18:16 -07:00
g_object_set (action, "sensitive", sensitive, NULL);
}
2006-08-15 22:18:16 -07:00
static void
_moo_tool_action_init (G_GNUC_UNUSED MooToolAction *action)
2006-04-20 01:57:05 -07:00
{
}
static void
2006-08-15 22:18:16 -07:00
_moo_tool_action_class_init (MooToolActionClass *klass)
{
2006-08-15 22:18:16 -07:00
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkActionClass *gtkaction_class = GTK_ACTION_CLASS (klass);
MooEditActionClass *action_class = MOO_EDIT_ACTION_CLASS (klass);
object_class->set_property = moo_tool_action_set_property;
object_class->get_property = moo_tool_action_get_property;
object_class->finalize = moo_tool_action_finalize;
gtkaction_class->activate = moo_tool_action_activate;
action_class->check_state = moo_tool_action_check_state;
g_object_class_install_property (object_class, PROP_COMMAND,
g_param_spec_object ("command", "command", "command",
MOO_TYPE_COMMAND,
G_PARAM_READWRITE));
}
2006-08-18 22:21:29 -07:00
static void
get_extension (const char *string,
char **base,
char **ext)
{
char *dot;
g_return_if_fail (string != NULL);
dot = strrchr (string, '.');
if (dot)
{
*base = g_strndup (string, dot - string);
*ext = g_strdup (dot);
}
else
{
*base = g_strdup (string);
*ext = g_strdup ("");
}
}
2006-08-15 22:18:16 -07:00
static MooCommandContext *
create_command_context (gpointer window,
gpointer doc)
{
2006-08-15 22:18:16 -07:00
MooCommandContext *ctx;
2006-08-18 22:21:29 -07:00
char *user_dir;
2006-08-15 22:18:16 -07:00
ctx = moo_command_context_new (doc, window);
2006-08-18 22:21:29 -07:00
if (MOO_IS_EDIT (doc) && moo_edit_get_filename (doc))
{
const char *filename, *basename;
char *dirname, *base, *extension;
filename = moo_edit_get_filename (doc);
basename = moo_edit_get_basename (doc);
dirname = g_path_get_dirname (filename);
get_extension (basename, &base, &extension);
moo_command_context_set_string (ctx, "DOC", filename);
moo_command_context_set_string (ctx, "DOC_DIR", dirname);
moo_command_context_set_string (ctx, "DOC_BASE", base);
moo_command_context_set_string (ctx, "DOC_EXT", extension);
g_free (dirname);
g_free (base);
g_free (extension);
}
user_dir = moo_get_user_data_dir ();
moo_command_context_set_string (ctx, "DATA_DIR", user_dir);
moo_command_context_set_string (ctx, "APP_PID", _moo_get_pid_string ());
g_free (user_dir);
2006-08-15 22:18:16 -07:00
return ctx;
}