2006-04-16 15:02:33 -07:00
|
|
|
/*
|
|
|
|
* 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"
|
2006-08-18 22:59:53 -07:00
|
|
|
#include "mooedit/mooeditaction.h"
|
|
|
|
#include "mooedit/mooeditaction-factory.h"
|
2006-04-16 15:02:33 -07:00
|
|
|
#include "mooutils/mooutils-misc.h"
|
2006-04-19 23:03:39 -07:00
|
|
|
#include "mooutils/mooaccel.h"
|
2006-08-15 22:18:16 -07:00
|
|
|
#include "mooutils/mooi18n.h"
|
2006-08-15 00:12:41 -07:00
|
|
|
#include "mooutils/mooaction-private.h"
|
2006-04-16 15:02:33 -07:00
|
|
|
#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_POSITION "position"
|
|
|
|
#define ELEMENT_COMMAND "command"
|
|
|
|
#define PROP_NAME "name"
|
|
|
|
#define PROP_ENABLED "enabled"
|
|
|
|
#define PROP_OS "os"
|
2006-08-22 21:22:32 -07:00
|
|
|
#define PROP_ID "id"
|
2006-08-23 00:41:56 -07:00
|
|
|
#define PROP_DELETED "deleted"
|
|
|
|
#define PROP_BUILTIN "builtin"
|
2006-04-20 01:57:05 -07:00
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
enum {
|
|
|
|
PROP_0,
|
|
|
|
PROP_COMMAND
|
|
|
|
};
|
2006-04-16 15:02:33 -07:00
|
|
|
|
|
|
|
typedef struct {
|
2006-08-15 22:18:16 -07:00
|
|
|
GSList *tools;
|
|
|
|
} ToolStore;
|
2006-04-16 15:02:33 -07:00
|
|
|
|
2006-08-17 21:53:34 -07:00
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
typedef struct {
|
|
|
|
char *id;
|
2006-04-16 15:02:33 -07:00
|
|
|
MooUIXML *xml;
|
|
|
|
guint merge_id;
|
2006-08-15 22:18:16 -07:00
|
|
|
} ToolInfo;
|
2006-04-16 15:02:33 -07:00
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
typedef struct {
|
|
|
|
MooEditAction parent;
|
|
|
|
MooCommand *cmd;
|
|
|
|
} MooToolAction;
|
2006-04-16 15:02:33 -07:00
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
typedef MooEditActionClass MooToolActionClass;
|
2006-04-16 15:02:33 -07:00
|
|
|
|
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-04-16 15:02:33 -07:00
|
|
|
|
|
|
|
|
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-04-16 15:02:33 -07:00
|
|
|
|
|
|
|
|
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-04-16 15:02:33 -07:00
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
list = store->tools;
|
|
|
|
store->tools = NULL;
|
2006-04-16 15:02:33 -07:00
|
|
|
|
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-04-16 15:02:33 -07:00
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
while (list)
|
2006-04-16 15:02:33 -07:00
|
|
|
{
|
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-04-16 15:02:33 -07:00
|
|
|
}
|
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
g_free (store);
|
|
|
|
tools_stores[type] = NULL;
|
2006-04-16 15:02:33 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
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-23 00:41:56 -07:00
|
|
|
static void
|
|
|
|
find_user_tools_file (int type,
|
|
|
|
char ***sys_files_p,
|
|
|
|
char **user_file_p)
|
2006-04-20 01:57:05 -07:00
|
|
|
{
|
2006-08-15 22:18:16 -07:00
|
|
|
char **files;
|
|
|
|
guint n_files;
|
|
|
|
int i;
|
2006-08-23 00:41:56 -07:00
|
|
|
GPtrArray *sys_files = NULL;
|
|
|
|
|
|
|
|
*sys_files_p = NULL;
|
|
|
|
*user_file_p = NULL;
|
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)
|
2006-08-23 00:41:56 -07:00
|
|
|
return;
|
2006-08-15 22:18:16 -07:00
|
|
|
|
2006-08-23 00:41:56 -07:00
|
|
|
if (g_file_test (files[n_files - 1], G_FILE_TEST_EXISTS))
|
|
|
|
*user_file_p = g_strdup (files[n_files - 1]);
|
|
|
|
|
|
|
|
for (i = 0; i < (int) n_files - 1; ++i)
|
2006-08-15 22:18:16 -07:00
|
|
|
{
|
|
|
|
if (g_file_test (files[i], G_FILE_TEST_EXISTS))
|
|
|
|
{
|
2006-08-23 00:41:56 -07:00
|
|
|
if (!sys_files)
|
|
|
|
sys_files = g_ptr_array_new ();
|
|
|
|
g_ptr_array_add (sys_files, g_strdup (files[i]));
|
2006-08-15 22:18:16 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-08-23 00:41:56 -07:00
|
|
|
if (sys_files)
|
|
|
|
{
|
|
|
|
g_ptr_array_add (sys_files, NULL);
|
|
|
|
*sys_files_p = (char**) g_ptr_array_free (sys_files, FALSE);
|
|
|
|
}
|
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
g_strfreev (files);
|
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-04-16 15:02:33 -07:00
|
|
|
{
|
2006-08-15 22:18:16 -07:00
|
|
|
MooToolAction *action;
|
2006-04-16 15:02:33 -07:00
|
|
|
|
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-04-16 15:02:33 -07:00
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
return moo_command_check_sensitive (action->cmd, doc, window);
|
2006-04-16 15:02:33 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-08-22 21:22:32 -07:00
|
|
|
static char *
|
|
|
|
get_name (const char *label)
|
2006-08-17 21:53:34 -07:00
|
|
|
{
|
2006-08-22 21:22:32 -07:00
|
|
|
char *underscore, *name;
|
2006-08-17 21:53:34 -07:00
|
|
|
|
2006-08-22 21:22:32 -07:00
|
|
|
name = g_strdup (label);
|
|
|
|
underscore = strchr (name, '_');
|
2006-08-17 21:53:34 -07:00
|
|
|
|
|
|
|
if (underscore)
|
|
|
|
memmove (underscore, underscore + 1, strlen (underscore + 1) + 1);
|
2006-08-22 21:22:32 -07:00
|
|
|
|
|
|
|
return name;
|
2006-08-17 21:53:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
check_info (MooUserToolInfo *info,
|
|
|
|
MooUserToolType type)
|
|
|
|
{
|
2006-08-22 21:22:32 -07:00
|
|
|
if (!info->id || !info->id[0])
|
|
|
|
{
|
|
|
|
g_warning ("tool id missing in file %s", info->file);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2006-08-17 21:53:34 -07:00
|
|
|
if (!info->name || !info->name[0])
|
|
|
|
{
|
|
|
|
g_warning ("tool name missing in file %s", info->file);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (info->position != MOO_USER_TOOL_POS_END &&
|
|
|
|
type != MOO_USER_TOOL_CONTEXT)
|
|
|
|
{
|
2006-08-20 01:49:33 -07:00
|
|
|
g_warning ("position specified in tool %s in file %s",
|
2006-08-17 21:53:34 -07:00
|
|
|
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-04-16 15:02:33 -07:00
|
|
|
{
|
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-22 21:22:32 -07:00
|
|
|
char *name;
|
2006-04-16 15:02:33 -07:00
|
|
|
|
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-04-16 15:02:33 -07:00
|
|
|
|
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-04-16 15:02:33 -07:00
|
|
|
|
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-04-16 15:02:33 -07:00
|
|
|
|
2006-08-22 21:22:32 -07:00
|
|
|
name = get_name (info->name);
|
2006-08-17 21:53:34 -07:00
|
|
|
|
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:
|
2006-05-01 10:26:45 -07:00
|
|
|
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-22 21:22:32 -07:00
|
|
|
moo_window_class_new_action (klass, info->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-22 21:22:32 -07:00
|
|
|
moo_edit_window_set_action_check (info->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-22 21:22:32 -07:00
|
|
|
moo_edit_window_set_action_langs (info->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:
|
2006-05-01 10:26:45 -07:00
|
|
|
klass = g_type_class_peek (MOO_TYPE_EDIT);
|
2006-08-22 21:22:32 -07:00
|
|
|
moo_edit_class_new_action (klass, info->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-04-16 15:02:33 -07:00
|
|
|
|
2006-08-22 21:22:32 -07:00
|
|
|
tool_info = tools_store_add (info->type, info->id);
|
2006-08-15 22:18:16 -07:00
|
|
|
|
2006-08-17 21:53:34 -07:00
|
|
|
if (tool_info->xml)
|
2006-04-16 15:02:33 -07:00
|
|
|
{
|
2006-05-01 10:26:45 -07:00
|
|
|
const char *ui_path;
|
|
|
|
char *freeme = NULL;
|
|
|
|
char *markup;
|
|
|
|
|
2006-08-22 21:22:32 -07:00
|
|
|
markup = g_markup_printf_escaped ("<item action=\"%s\"/>", info->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";
|
2006-05-01 10:26:45 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
freeme = g_strdup_printf ("Editor/Menubar/%s/UserMenu",
|
2006-08-16 18:27:19 -07:00
|
|
|
info->menu ? info->menu : "Tools");
|
2006-05-01 10:26:45 -07:00
|
|
|
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);
|
2006-05-01 10:26:45 -07:00
|
|
|
|
2006-04-16 15:02:33 -07:00
|
|
|
g_free (markup);
|
2006-05-01 10:26:45 -07:00
|
|
|
g_free (freeme);
|
2006-04-16 15:02:33 -07:00
|
|
|
}
|
|
|
|
|
2006-08-17 21:53:34 -07:00
|
|
|
g_free (name);
|
2006-08-15 22:18:16 -07:00
|
|
|
g_object_unref (cmd);
|
2006-04-16 15:02:33 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
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-22 21:22:32 -07:00
|
|
|
info->id = g_strdup (moo_markup_get_prop (node, PROP_ID));
|
2006-08-17 21:53:34 -07:00
|
|
|
info->name = g_strdup (moo_markup_get_prop (node, PROP_NAME));
|
|
|
|
info->enabled = moo_markup_get_bool_prop (node, PROP_ENABLED, TRUE);
|
2006-08-23 00:41:56 -07:00
|
|
|
info->deleted = moo_markup_get_bool_prop (node, PROP_DELETED, FALSE);
|
|
|
|
info->builtin = moo_markup_get_bool_prop (node, PROP_BUILTIN, FALSE);
|
|
|
|
|
|
|
|
if (!info->id)
|
|
|
|
{
|
|
|
|
g_warning ("tool id missing in file %s", file);
|
|
|
|
_moo_user_tool_info_unref (info);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (info->deleted || info->builtin)
|
|
|
|
return info;
|
|
|
|
|
2006-08-17 21:53:34 -07:00
|
|
|
os = moo_markup_get_prop (node, PROP_OS);
|
2006-08-16 18:27:19 -07:00
|
|
|
|
2006-08-23 00:41:56 -07:00
|
|
|
if (!os || !os[0])
|
|
|
|
info->os_type = MOO_USER_TOOL_THIS_OS;
|
|
|
|
else if (!g_ascii_strncasecmp (os, "win", 3))
|
|
|
|
info->os_type = MOO_USER_TOOL_WIN32;
|
|
|
|
else
|
|
|
|
info->os_type = MOO_USER_TOOL_UNIX;
|
2006-08-16 18:27:19 -07:00
|
|
|
|
|
|
|
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-20 01:49:33 -07:00
|
|
|
if (!strcmp (child->name, ELEMENT_ACCEL))
|
2006-08-17 21:53:34 -07:00
|
|
|
{
|
|
|
|
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-04-16 15:02:33 -07:00
|
|
|
{
|
2006-08-15 22:18:16 -07:00
|
|
|
MooMarkupNode *root, *child;
|
2006-08-18 22:21:29 -07:00
|
|
|
GSList *list = NULL;
|
2006-04-16 15:02:33 -07:00
|
|
|
|
2006-08-17 21:53:34 -07:00
|
|
|
root = moo_markup_get_root_element (doc, ELEMENT_TOOLS);
|
2006-04-16 15:02:33 -07:00
|
|
|
|
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-04-16 15:02:33 -07:00
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
for (child = root->children; child != NULL; child = child->next)
|
2006-04-16 15:02:33 -07:00
|
|
|
{
|
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-04-16 15:02:33 -07:00
|
|
|
}
|
2006-08-18 22:21:29 -07:00
|
|
|
|
|
|
|
return g_slist_reverse (list);
|
2006-04-16 15:02:33 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-08-23 00:41:56 -07:00
|
|
|
static GSList *
|
|
|
|
parse_file_simple (const char *filename,
|
|
|
|
MooUserToolType type)
|
2006-08-16 18:27:19 -07:00
|
|
|
{
|
|
|
|
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-23 00:41:56 -07:00
|
|
|
g_return_val_if_fail (filename != NULL, NULL);
|
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
|
|
|
|
2006-08-23 00:41:56 -07:00
|
|
|
doc = moo_markup_parse_file (filename, &error);
|
2006-08-16 18:27:19 -07:00
|
|
|
|
|
|
|
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
|
|
|
|
{
|
2006-08-23 00:41:56 -07:00
|
|
|
g_warning ("could not load file '%s': %s", filename, error->message);
|
2006-08-16 18:27:19 -07:00
|
|
|
g_error_free (error);
|
|
|
|
}
|
|
|
|
|
2006-08-18 22:21:29 -07:00
|
|
|
return list;
|
2006-08-16 18:27:19 -07:00
|
|
|
}
|
|
|
|
|
2006-08-23 00:41:56 -07:00
|
|
|
static void
|
|
|
|
parse_file (const char *filename,
|
|
|
|
MooUserToolType type,
|
|
|
|
GSList **list,
|
|
|
|
GHashTable *ids)
|
2006-08-22 21:22:32 -07:00
|
|
|
{
|
2006-08-23 00:41:56 -07:00
|
|
|
GSList *new_list;
|
2006-08-22 21:22:32 -07:00
|
|
|
|
2006-08-23 00:41:56 -07:00
|
|
|
new_list = parse_file_simple (filename, type);
|
|
|
|
|
|
|
|
if (!new_list)
|
|
|
|
return;
|
|
|
|
|
|
|
|
while (new_list)
|
2006-08-22 21:22:32 -07:00
|
|
|
{
|
2006-08-23 00:41:56 -07:00
|
|
|
MooUserToolInfo *info, *old_info;
|
|
|
|
GSList *old_link;
|
2006-08-22 21:22:32 -07:00
|
|
|
|
2006-08-23 00:41:56 -07:00
|
|
|
info = new_list->data;
|
|
|
|
g_return_if_fail (info->id != NULL);
|
2006-08-22 21:22:32 -07:00
|
|
|
|
2006-08-23 00:41:56 -07:00
|
|
|
old_link = g_hash_table_lookup (ids, info->id);
|
|
|
|
old_info = old_link ? old_link->data : NULL;
|
|
|
|
|
|
|
|
if (old_link)
|
|
|
|
{
|
|
|
|
*list = g_slist_delete_link (*list, old_link);
|
|
|
|
g_hash_table_remove (ids, info->id);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (info->deleted)
|
|
|
|
{
|
|
|
|
_moo_user_tool_info_unref (info);
|
|
|
|
info = NULL;
|
|
|
|
}
|
|
|
|
else if (info->builtin)
|
|
|
|
{
|
|
|
|
_moo_user_tool_info_unref (info);
|
|
|
|
info = old_info ? _moo_user_tool_info_ref (old_info) : NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (info)
|
|
|
|
{
|
|
|
|
*list = g_slist_prepend (*list, info);
|
|
|
|
g_hash_table_insert (ids, g_strdup (info->id), *list);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (old_info)
|
|
|
|
_moo_user_tool_info_unref (old_info);
|
|
|
|
|
|
|
|
new_list = g_slist_delete_link (new_list, new_list);
|
2006-08-22 21:22:32 -07:00
|
|
|
}
|
2006-08-23 00:41:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static GSList *
|
|
|
|
parse_user_tools (MooUserToolType type,
|
|
|
|
GHashTable **ids_p,
|
|
|
|
gboolean sys_only)
|
|
|
|
{
|
|
|
|
char **sys_files, *user_file;
|
|
|
|
GSList *list = NULL;
|
|
|
|
GHashTable *ids = NULL;
|
|
|
|
char **p;
|
|
|
|
|
|
|
|
g_return_val_if_fail (type < N_TOOLS, NULL);
|
|
|
|
|
|
|
|
_moo_command_init ();
|
|
|
|
|
|
|
|
find_user_tools_file (type, &sys_files, &user_file);
|
|
|
|
ids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
2006-08-22 21:22:32 -07:00
|
|
|
|
2006-08-23 00:41:56 -07:00
|
|
|
for (p = sys_files; p && *p; ++p)
|
|
|
|
parse_file (*p, type, &list, ids);
|
|
|
|
|
|
|
|
if (!sys_only && user_file)
|
|
|
|
parse_file (user_file, type, &list, ids);
|
|
|
|
|
|
|
|
if (ids_p)
|
|
|
|
*ids_p = ids;
|
|
|
|
else
|
|
|
|
g_hash_table_destroy (ids);
|
|
|
|
|
|
|
|
g_strfreev (sys_files);
|
|
|
|
g_free (user_file);
|
|
|
|
|
|
|
|
return g_slist_reverse (list);
|
2006-08-22 21:22:32 -07:00
|
|
|
}
|
|
|
|
|
2006-08-23 00:41:56 -07:00
|
|
|
GSList *
|
|
|
|
_moo_edit_parse_user_tools (MooUserToolType type)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (type < N_TOOLS, NULL);
|
|
|
|
return parse_user_tools (type, NULL, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
generate_id (MooUserToolInfo *info,
|
|
|
|
GHashTable *ids)
|
2006-08-22 21:22:32 -07:00
|
|
|
{
|
|
|
|
char *base, *name;
|
2006-08-23 00:41:56 -07:00
|
|
|
|
|
|
|
g_return_if_fail (info->id == NULL);
|
2006-08-22 21:22:32 -07:00
|
|
|
|
|
|
|
if (info->name)
|
|
|
|
name = get_name (info->name);
|
|
|
|
else
|
|
|
|
name = NULL;
|
|
|
|
|
|
|
|
base = g_strdup_printf ("MooUserTool_%s", name ? name : "");
|
|
|
|
g_strcanon (base, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "_", '_');
|
|
|
|
|
|
|
|
if (!g_hash_table_lookup (ids, base))
|
|
|
|
{
|
2006-08-23 00:41:56 -07:00
|
|
|
info->id = base;
|
2006-08-22 21:22:32 -07:00
|
|
|
base = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
guint i = 0;
|
|
|
|
|
|
|
|
while (TRUE)
|
|
|
|
{
|
|
|
|
char *tmp = g_strdup_printf ("%s_%d", base, i);
|
|
|
|
|
|
|
|
if (!g_hash_table_lookup (ids, tmp))
|
|
|
|
{
|
2006-08-23 00:41:56 -07:00
|
|
|
info->id = tmp;
|
2006-08-22 21:22:32 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (tmp);
|
|
|
|
|
|
|
|
i += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (name);
|
|
|
|
g_free (base);
|
2006-08-23 00:41:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
assign_missing_ids (GSList *list)
|
|
|
|
{
|
|
|
|
GSList *l;
|
|
|
|
GHashTable *ids;
|
|
|
|
|
|
|
|
ids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
|
|
|
|
|
|
|
for (l = list; l != NULL; l = l->next)
|
|
|
|
{
|
|
|
|
MooUserToolInfo *info = l->data;
|
|
|
|
|
|
|
|
if (info->id)
|
|
|
|
g_hash_table_insert (ids, g_strdup (info->id), l);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (l = list; l != NULL; l = l->next)
|
|
|
|
{
|
|
|
|
MooUserToolInfo *info = l->data;
|
|
|
|
|
|
|
|
if (!info->id)
|
|
|
|
{
|
|
|
|
generate_id (info, ids);
|
|
|
|
g_hash_table_insert (ids, g_strdup (info->id), l);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_hash_table_destroy (ids);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
add_deleted (const char *id,
|
|
|
|
GSList *link,
|
|
|
|
GSList **list)
|
|
|
|
{
|
|
|
|
MooUserToolInfo *info;
|
|
|
|
|
|
|
|
g_assert (!strcmp (((MooUserToolInfo*)link->data)->id, id));
|
|
|
|
|
|
|
|
info = _moo_user_tool_info_new ();
|
|
|
|
info->id = g_strdup (id);
|
|
|
|
info->deleted = TRUE;
|
|
|
|
|
|
|
|
*list = g_slist_prepend (*list, info);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
string_equal (const char *s1,
|
|
|
|
const char *s2)
|
|
|
|
{
|
|
|
|
return !strcmp (s1 ? s1 : "", s2 ? s2 : "");
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
info_equal (MooUserToolInfo *info1,
|
|
|
|
MooUserToolInfo *info2)
|
|
|
|
{
|
|
|
|
if (info1 == info2)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
if (info1->deleted)
|
|
|
|
return info2->deleted != 0;
|
|
|
|
if (info1->builtin)
|
|
|
|
return info2->builtin != 0;
|
|
|
|
|
|
|
|
if (!info1->enabled != !info2->enabled)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return info1->position == info2->position &&
|
|
|
|
info1->os_type == info2->os_type &&
|
|
|
|
info1->position == info2->position &&
|
|
|
|
info1->position == info2->position &&
|
|
|
|
info1->cmd_type == info2->cmd_type &&
|
|
|
|
string_equal (info1->name, info2->name) &&
|
|
|
|
string_equal (info1->accel, info2->accel) &&
|
|
|
|
string_equal (info1->menu, info2->menu) &&
|
|
|
|
string_equal (info1->langs, info2->langs) &&
|
|
|
|
string_equal (info1->options, info2->options) &&
|
|
|
|
_moo_command_type_data_equal (info1->cmd_type, info1->cmd_data, info2->cmd_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
static GSList *
|
|
|
|
generate_real_list (MooUserToolType type,
|
|
|
|
GSList *list)
|
|
|
|
{
|
|
|
|
GSList *real_list = NULL;
|
|
|
|
GSList *sys_list;
|
|
|
|
GHashTable *sys_ids;
|
|
|
|
|
|
|
|
sys_list = parse_user_tools (type, &sys_ids, TRUE);
|
|
|
|
assign_missing_ids (list);
|
|
|
|
|
|
|
|
while (list)
|
|
|
|
{
|
|
|
|
MooUserToolInfo *new_info = NULL;
|
|
|
|
MooUserToolInfo *info = list->data;
|
|
|
|
GSList *sys_link;
|
|
|
|
|
|
|
|
sys_link = g_hash_table_lookup (sys_ids, info->id);
|
|
|
|
|
|
|
|
if (sys_link)
|
|
|
|
{
|
|
|
|
MooUserToolInfo *sys_info = sys_link->data;
|
|
|
|
|
|
|
|
if (info_equal (sys_info, info))
|
|
|
|
{
|
|
|
|
new_info = _moo_user_tool_info_new ();
|
|
|
|
new_info->id = g_strdup (sys_info->id);
|
|
|
|
new_info->builtin = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
new_info = _moo_user_tool_info_ref (info);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_hash_table_remove (sys_ids, info->id);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
new_info = _moo_user_tool_info_ref (info);
|
|
|
|
}
|
|
|
|
|
|
|
|
real_list = g_slist_prepend (real_list, new_info);
|
|
|
|
list = list->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_hash_table_foreach (sys_ids, (GHFunc) add_deleted, &real_list);
|
|
|
|
|
|
|
|
g_hash_table_destroy (sys_ids);
|
|
|
|
g_slist_foreach (sys_list, (GFunc) _moo_user_tool_info_unref, NULL);
|
|
|
|
g_slist_free (sys_list);
|
|
|
|
|
|
|
|
return g_slist_reverse (real_list);
|
2006-08-22 21:22:32 -07:00
|
|
|
}
|
|
|
|
|
2006-08-17 21:53:34 -07:00
|
|
|
void
|
|
|
|
_moo_edit_save_user_tools (MooUserToolType type,
|
2006-08-23 00:41:56 -07:00
|
|
|
GSList *user_list)
|
2006-08-17 21:53:34 -07:00
|
|
|
{
|
|
|
|
MooMarkupDoc *doc;
|
|
|
|
MooMarkupNode *root;
|
|
|
|
GError *error = NULL;
|
|
|
|
char *string;
|
2006-08-23 00:41:56 -07:00
|
|
|
GSList *list;
|
2006-08-17 21:53:34 -07:00
|
|
|
|
|
|
|
g_return_if_fail (type < N_TOOLS);
|
|
|
|
|
|
|
|
doc = moo_markup_doc_new ("tools");
|
|
|
|
root = moo_markup_create_root_element (doc, ELEMENT_TOOLS);
|
2006-08-23 00:41:56 -07:00
|
|
|
list = generate_real_list (type, user_list);
|
2006-08-17 21:53:34 -07:00
|
|
|
|
|
|
|
while (list)
|
|
|
|
{
|
|
|
|
MooMarkupNode *node;
|
2006-08-23 00:41:56 -07:00
|
|
|
MooUserToolInfo *info = list->data;
|
2006-08-17 21:53:34 -07:00
|
|
|
|
|
|
|
node = moo_markup_create_element (root, ELEMENT_TOOL);
|
2006-08-23 00:41:56 -07:00
|
|
|
moo_markup_set_prop (node, PROP_ID, info->id);
|
2006-08-17 21:53:34 -07:00
|
|
|
|
2006-08-23 00:41:56 -07:00
|
|
|
if (info->deleted)
|
|
|
|
{
|
|
|
|
moo_markup_set_bool_prop (node, PROP_DELETED, TRUE);
|
|
|
|
}
|
|
|
|
else if (info->builtin)
|
|
|
|
{
|
|
|
|
moo_markup_set_bool_prop (node, PROP_BUILTIN, TRUE);
|
|
|
|
}
|
2006-08-22 21:22:32 -07:00
|
|
|
else
|
2006-08-23 00:41:56 -07:00
|
|
|
{
|
|
|
|
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->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);
|
|
|
|
}
|
2006-08-17 21:53:34 -07:00
|
|
|
|
2006-08-23 00:41:56 -07:00
|
|
|
_moo_user_tool_info_unref (info);
|
|
|
|
list = g_slist_delete_link (list, list);
|
2006-08-17 21:53:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2006-08-22 21:22:32 -07:00
|
|
|
g_free (info->id);
|
2006-08-17 21:53:34 -07:00
|
|
|
g_free (info->name);
|
|
|
|
g_free (info->accel);
|
|
|
|
g_free (info->menu);
|
|
|
|
g_free (info->langs);
|
|
|
|
g_free (info->options);
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-04-16 15:02:33 -07:00
|
|
|
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-04-16 15:02:33 -07:00
|
|
|
{
|
2006-08-15 22:18:16 -07:00
|
|
|
MooToolAction *action = MOO_TOOL_ACTION (object);
|
2006-04-16 15:02:33 -07:00
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
switch (property_id)
|
2006-04-16 15:02:33 -07:00
|
|
|
{
|
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-04-16 15:02:33 -07:00
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
|
|
}
|
2006-04-16 15:02:33 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
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-04-19 15:23:23 -07:00
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-04-16 15:02:33 -07:00
|
|
|
static void
|
2006-08-15 22:18:16 -07:00
|
|
|
moo_tool_action_activate (GtkAction *gtkaction)
|
2006-04-16 15:02:33 -07:00
|
|
|
{
|
2006-08-15 22:18:16 -07:00
|
|
|
MooEditWindow *window;
|
|
|
|
MooCommandContext *ctx = NULL;
|
2006-04-16 15:02:33 -07:00
|
|
|
MooEdit *doc;
|
2006-08-15 22:18:16 -07:00
|
|
|
MooToolAction *action = MOO_TOOL_ACTION (gtkaction);
|
|
|
|
MooEditAction *edit_action = MOO_EDIT_ACTION (gtkaction);
|
2006-04-16 15:02:33 -07:00
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
g_return_if_fail (action->cmd != NULL);
|
2006-04-16 20:06:13 -07:00
|
|
|
|
2006-08-18 22:59:53 -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-04-19 15:23:23 -07:00
|
|
|
{
|
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-04-19 15:23:23 -07:00
|
|
|
}
|
|
|
|
|
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-04-16 15:02:33 -07:00
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
g_object_unref (ctx);
|
2006-04-16 15:02:33 -07:00
|
|
|
}
|
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
|
2006-04-16 15:02:33 -07:00
|
|
|
static void
|
2006-08-15 22:18:16 -07:00
|
|
|
moo_tool_action_check_state (MooEditAction *edit_action)
|
2006-04-16 15:02:33 -07:00
|
|
|
{
|
2006-08-15 22:18:16 -07:00
|
|
|
gboolean sensitive;
|
|
|
|
MooToolAction *action = MOO_TOOL_ACTION (edit_action);
|
2006-08-18 22:59:53 -07:00
|
|
|
MooEdit *doc;
|
2006-04-16 15:02:33 -07:00
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
g_return_if_fail (action->cmd != NULL);
|
2006-04-16 15:02:33 -07:00
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
MOO_EDIT_ACTION_CLASS (_moo_tool_action_parent_class)->check_state (edit_action);
|
2006-04-16 15:02:33 -07:00
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
if (!gtk_action_is_visible (GTK_ACTION (action)))
|
|
|
|
return;
|
2006-04-16 15:02:33 -07:00
|
|
|
|
2006-08-18 22:59:53 -07:00
|
|
|
doc = moo_edit_action_get_doc (edit_action);
|
|
|
|
sensitive = moo_command_check_sensitive (action->cmd, doc, moo_edit_get_window (doc));
|
2006-04-16 15:02:33 -07:00
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
g_object_set (action, "sensitive", sensitive, NULL);
|
2006-04-16 15:02:33 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
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
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-04-16 15:02:33 -07:00
|
|
|
static void
|
2006-08-15 22:18:16 -07:00
|
|
|
_moo_tool_action_class_init (MooToolActionClass *klass)
|
2006-04-16 15:02:33 -07:00
|
|
|
{
|
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-04-16 15:02:33 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
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-04-16 15:02:33 -07:00
|
|
|
{
|
2006-08-15 22:18:16 -07:00
|
|
|
MooCommandContext *ctx;
|
2006-08-18 22:21:29 -07:00
|
|
|
char *user_dir;
|
2006-04-16 15:02:33 -07:00
|
|
|
|
2006-08-15 22:18:16 -07:00
|
|
|
ctx = moo_command_context_new (doc, window);
|
2006-04-16 15:02:33 -07:00
|
|
|
|
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);
|
|
|
|
|
2006-08-22 21:22:32 -07:00
|
|
|
moo_command_context_set_string (ctx, "DOC", basename);
|
2006-08-18 22:21:29 -07:00
|
|
|
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 ());
|
2006-08-22 21:22:32 -07:00
|
|
|
/* XXX */
|
|
|
|
moo_command_context_set_string (ctx, "MEDIT_PID", _moo_get_pid_string ());
|
2006-08-18 22:21:29 -07:00
|
|
|
|
|
|
|
g_free (user_dir);
|
2006-08-15 22:18:16 -07:00
|
|
|
return ctx;
|
2006-04-16 15:02:33 -07:00
|
|
|
}
|