Continuing user tools thing

master
Yevgen Muntyan 2006-08-16 20:27:19 -05:00
parent 200ee0a8bb
commit ead05d78f3
18 changed files with 2121 additions and 487 deletions

View File

@ -53,3 +53,4 @@ moo/mooterm/termhelper_res\.rc$
^po/.*\.pot$
^po/notexist$
-old\..*$
^po/ru\.po$

View File

@ -25,6 +25,7 @@
#include "mooedit/mooplugin.h"
#include "mooedit/mooedit-script.h"
#include "mooedit/moousertools.h"
#include "mooedit/moousertools-prefs.h"
#include "mooedit/plugins/mooeditplugins.h"
#include "mooutils/mooprefsdialog.h"
#include "mooutils/moopython.h"
@ -783,8 +784,8 @@ moo_app_init_editor (MooApp *app)
moo_plugin_read_dirs ();
moo_edit_load_user_tools (NULL, moo_app_get_ui_xml (app));
moo_edit_load_user_menu (NULL, moo_app_get_ui_xml (app));
_moo_edit_load_user_tools (MOO_TOOL_FILE_TOOLS, moo_app_get_ui_xml (app));
_moo_edit_load_user_tools (MOO_TOOL_FILE_MENU, moo_app_get_ui_xml (app));
}
#endif /* MOO_BUILD_EDIT */
@ -1644,6 +1645,7 @@ moo_app_create_prefs_dialog (MooApp *app)
#ifdef MOO_BUILD_EDIT
moo_prefs_dialog_append_page (dialog, moo_edit_prefs_page_new (moo_app_get_editor (app)));
moo_prefs_dialog_append_page (dialog, moo_user_tools_prefs_page_new ());
_moo_plugin_attach_prefs (GTK_WIDGET (dialog));
#endif

View File

@ -38,8 +38,7 @@ mooedit_include_headers = \
mootextsearch.h \
mootextstyle.h \
mootextstylescheme.h \
mootextview.h \
moousertools.h
mootextview.h
mooedit_noinst_headers = \
gtksourceiter.h \
@ -68,6 +67,9 @@ mooedit_noinst_headers = \
mootextgotoline-glade.h \
mootextsearch-private.h \
mootextview-private.h \
moousertools.h \
moousertools-prefs.h \
mooedittools-glade.h \
quicksearch-glade.h \
statusbar-glade.h
@ -110,7 +112,8 @@ mooedit_sources = \
mootextstyle.c \
mootextstylescheme.c \
mootextview.c \
moousertools.c
moousertools.c \
moousertools-prefs.c
mooedit_printing_sources = \
mootextprint.c \
@ -125,7 +128,8 @@ BUILT_SOURCES = \
mooprint-glade.h \
mooeditprefs-glade.h \
mooeditprogress-glade.h \
mooeditsavemultiple-glade.h
mooeditsavemultiple-glade.h \
mooedittools-glade.h
XML2H = $(srcdir)/../mooutils/xml2h.sh
@ -156,6 +160,9 @@ statusbar-glade.h: $(srcdir)/glade/statusbar.glade $(XML2H)
mooprint-glade.h: $(srcdir)/glade/mooprint.glade $(XML2H)
$(SHELL) $(XML2H) MOO_PRINT_GLADE_XML $(srcdir)/glade/mooprint.glade \
> mooprint-glade.h
mooedittools-glade.h: $(srcdir)/glade/mooedittools.glade $(XML2H)
$(SHELL) $(XML2H) MOO_EDIT_TOOLS_GLADE_XML $(srcdir)/glade/mooedittools.glade \
> mooedittools-glade.h
EXTRA_DIST = \
glade/statusbar.glade \

View File

@ -0,0 +1,663 @@
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
<glade-interface>
<widget class="GtkWindow" id="window1">
<property name="visible">True</property>
<property name="title">window1</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="decorated">True</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
<property name="urgency_hint">False</property>
<child>
<widget class="GtkVBox" id="page">
<property name="border_width">6</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkVBox" id="vbox2">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<widget class="GtkTreeView" id="treeview">
<property name="border_width">3</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="headers_visible">False</property>
<property name="rules_hint">False</property>
<property name="reorderable">False</property>
<property name="enable_search">True</property>
<property name="fixed_height_mode">False</property>
<property name="hover_selection">False</property>
<property name="hover_expand">False</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox2">
<property name="border_width">3</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkButton" id="new">
<property name="visible">True</property>
<property name="tooltip">New item</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">False</property>
<child>
<widget class="GtkImage" id="image3">
<property name="visible">True</property>
<property name="stock">gtk-new</property>
<property name="icon_size">4</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="delete">
<property name="visible">True</property>
<property name="tooltip">Delete item</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">False</property>
<child>
<widget class="GtkImage" id="image4">
<property name="visible">True</property>
<property name="stock">gtk-delete</property>
<property name="icon_size">4</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">3</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="down">
<property name="visible">True</property>
<property name="tooltip">Move item down</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">False</property>
<child>
<widget class="GtkImage" id="image2">
<property name="visible">True</property>
<property name="stock">gtk-go-down</property>
<property name="icon_size">4</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="up">
<property name="visible">True</property>
<property name="tooltip">Move item up</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">False</property>
<child>
<widget class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="stock">gtk-go-up</property>
<property name="icon_size">4</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="tool_vbox">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkTable" id="table">
<property name="visible">True</property>
<property name="n_rows">5</property>
<property name="n_columns">2</property>
<property name="homogeneous">False</property>
<property name="row_spacing">0</property>
<property name="column_spacing">0</property>
<child>
<widget class="GtkCheckButton" id="enabled">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Enabled</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">False</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">2</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="label" translatable="yes">Name:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">1</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="name">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label7">
<property name="visible">True</property>
<property name="label" translatable="yes">Label:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">1</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="label">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label8">
<property name="visible">True</property>
<property name="label" translatable="yes">Files:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">1</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="langs">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label9">
<property name="visible">True</property>
<property name="label" translatable="yes">Options:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">1</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="options">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="y_options"></property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkFrame" id="frame1">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="label_yalign">0.5</property>
<property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
<child>
<widget class="GtkAlignment" id="alignment1">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xscale">1</property>
<property name="yscale">1</property>
<property name="top_padding">0</property>
<property name="bottom_padding">0</property>
<property name="left_padding">0</property>
<property name="right_padding">0</property>
<child>
<widget class="GtkNotebook" id="notebook">
<property name="visible">True</property>
<property name="show_tabs">False</property>
<property name="show_border">False</property>
<property name="tab_pos">GTK_POS_TOP</property>
<property name="scrollable">False</property>
<property name="enable_popup">False</property>
<child>
<placeholder/>
</child>
<child>
<widget class="GtkLabel" id="label10">
<property name="visible">True</property>
<property name="label" translatable="yes"></property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="type">tab</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<widget class="GtkLabel" id="label11">
<property name="visible">True</property>
<property name="label" translatable="yes"></property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="type">tab</property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkHBox" id="hbox3">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkLabel" id="label5">
<property name="visible">True</property>
<property name="label" translatable="yes">Command type:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">3</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkComboBox" id="type_combo">
<property name="visible">True</property>
<property name="items" translatable="yes"></property>
<property name="add_tearoffs">False</property>
<property name="focus_on_click">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
<widget class="GtkWindow" id="window2">
<property name="visible">True</property>
<property name="title" translatable="yes">window2</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="decorated">True</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
<property name="urgency_hint">False</property>
<child>
<widget class="GtkVBox" id="moo_script_page">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<widget class="GtkTextView" id="textview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="overwrite">False</property>
<property name="accepts_tab">True</property>
<property name="justification">GTK_JUSTIFY_LEFT</property>
<property name="wrap_mode">GTK_WRAP_NONE</property>
<property name="cursor_visible">True</property>
<property name="pixels_above_lines">0</property>
<property name="pixels_below_lines">0</property>
<property name="pixels_inside_wrap">0</property>
<property name="left_margin">0</property>
<property name="right_margin">0</property>
<property name="indent">0</property>
<property name="text" translatable="yes"></property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>

View File

@ -3,8 +3,7 @@
<_name>Switch Header And Implementation</_name>
<_label>_Switch Header And Implementation</_label>
<langs>C, GAP</langs>
<command type="MooScript">
<flags>need-file</flags>
<command type="MooScript" options="need-file">
<code>extensions = [[['.h', '.hh', '.hpp', '.hxx', '.H'], ['.c', '.cc', '.cpp', '.cxx', '.C']],
[['.gd'], ['.gi']]];
new = none;

View File

@ -13,7 +13,12 @@
#include "mooedit/moocommand-script.h"
#include "mooedit/mooedit-script.h"
#include "mooedit/mooedittools-glade.h"
#include "mooedit/mootextview.h"
#include "mooscript/mooscript-parser.h"
#include "mooutils/mooi18n.h"
#include "mooutils/mooglade.h"
#include <string.h>
struct _MooCommandScriptPrivate {
@ -87,6 +92,7 @@ moo_command_script_dispose (GObject *object)
static MooCommand *
factory_func (MooCommandData *data,
const char *options,
G_GNUC_UNUSED gpointer user_data)
{
MooCommand *cmd;
@ -96,22 +102,90 @@ factory_func (MooCommandData *data,
g_return_val_if_fail (code && *code, NULL);
cmd = moo_command_script_new (code);
cmd = moo_command_script_new (code, moo_command_options_parse (options));
g_return_val_if_fail (cmd != NULL, NULL);
moo_command_load_data (cmd, data);
return cmd;
}
static GtkWidget *
create_widget (G_GNUC_UNUSED gpointer data)
{
GtkWidget *page;
MooGladeXML *xml;
xml = moo_glade_xml_new_empty (GETTEXT_PACKAGE);
moo_glade_xml_parse_memory (xml, MOO_EDIT_TOOLS_GLADE_XML, -1, "moo_script_page", NULL);
page = moo_glade_xml_get_widget (xml, "moo_script_page");
g_return_val_if_fail (page != NULL, NULL);
g_object_set_data_full (G_OBJECT (page), "moo-glade-xml", xml, g_object_unref);
return page;
}
static void
load_data (GtkWidget *page,
MooCommandData *data,
G_GNUC_UNUSED gpointer user_data)
{
MooGladeXML *xml;
GtkTextView *textview;
GtkTextBuffer *buffer;
const char *code;
xml = g_object_get_data (G_OBJECT (page), "moo-glade-xml");
textview = moo_glade_xml_get_widget (xml, "textview");
buffer = gtk_text_view_get_buffer (textview);
code = moo_command_data_get (data, "code");
gtk_text_buffer_set_text (buffer, code ? code : "", -1);
}
static gboolean
save_data (GtkWidget *page,
MooCommandData *data,
G_GNUC_UNUSED gpointer user_data)
{
MooGladeXML *xml;
GtkTextView *textview;
const char *code;
char *new_code;
gboolean changed = FALSE;
xml = g_object_get_data (G_OBJECT (page), "moo-glade-xml");
textview = moo_glade_xml_get_widget (xml, "textview");
g_assert (GTK_IS_TEXT_VIEW (textview));
new_code = moo_text_view_get_text (textview);
code = moo_command_data_get (data, "code");
code = code ? code : "";
if (strcmp (code, new_code) != 0)
{
moo_command_data_set (data, "code", new_code);
changed = TRUE;
}
g_free (new_code);
return changed;
}
static void
moo_command_script_class_init (MooCommandScriptClass *klass)
{
G_OBJECT_CLASS(klass)->dispose = moo_command_script_dispose;
MOO_COMMAND_CLASS(klass)->run = moo_command_script_run;
moo_command_register ("MooScript", factory_func, NULL, NULL);
moo_command_type_register ("MooScript", _("MooScript"),
factory_func,
create_widget,
load_data,
save_data,
NULL, NULL);
}
@ -123,7 +197,8 @@ moo_command_script_init (MooCommandScript *cmd)
MooCommand *
moo_command_script_new (const char *script)
moo_command_script_new (const char *script,
MooCommandOptions options)
{
MooCommandScript *cmd;
MSNode *node;
@ -133,7 +208,7 @@ moo_command_script_new (const char *script)
node = ms_script_parse (script);
g_return_val_if_fail (node != NULL, NULL);
cmd = g_object_new (MOO_TYPE_COMMAND_SCRIPT, NULL);
cmd = g_object_new (MOO_TYPE_COMMAND_SCRIPT, "options", options, NULL);
cmd->priv->script = node;
return MOO_COMMAND (cmd);

View File

@ -42,7 +42,8 @@ struct _MooCommandScriptClass {
GType moo_command_script_get_type (void) G_GNUC_CONST;
MooCommand *moo_command_script_new (const char *script);
MooCommand *moo_command_script_new (const char *script,
MooCommandOptions options);
G_END_DECLS

View File

@ -30,7 +30,7 @@ enum {
enum {
CMD_PROP_0,
CMD_PROP_FLAGS
CMD_PROP_OPTIONS
};
typedef struct {
@ -44,8 +44,7 @@ struct _MooCommandContextPrivate {
};
typedef struct {
MooCommandFactoryFunc func;
gpointer data;
MooCommandTypeInfo info;
GDestroyNotify notify;
} CommandType;
@ -64,6 +63,7 @@ static void variable_free (Variable *var);
MooCommand *
moo_command_create (const char *name,
const char *options,
MooCommandData *data)
{
CommandType *type;
@ -79,7 +79,7 @@ moo_command_create (const char *name,
type = g_hash_table_lookup (registered_types, name);
g_return_val_if_fail (type != NULL, NULL);
cmd = type->func (data, type->data);
cmd = type->info.factory (data, options, type->info.data);
moo_command_data_unref (data);
return cmd;
@ -87,15 +87,22 @@ moo_command_create (const char *name,
void
moo_command_register (const char *name,
MooCommandFactoryFunc func,
gpointer user_data,
GDestroyNotify notify)
moo_command_type_register (const char *id,
const char *name,
MooCommandFactoryFunc factory,
MooCommandCreateWidgetFunc create_widget,
MooCommandLoadDataFunc load_data,
MooCommandSaveDataFunc save_data,
gpointer data,
GDestroyNotify notify)
{
CommandType *type;
g_return_if_fail (name != NULL);
g_return_if_fail (func != NULL);
g_return_if_fail (id != NULL && name != NULL);
g_return_if_fail (factory != NULL);
g_return_if_fail (create_widget != NULL);
g_return_if_fail (load_data != NULL);
g_return_if_fail (save_data != NULL);
if (registered_types != NULL)
{
@ -104,8 +111,12 @@ moo_command_register (const char *name,
if (old != NULL)
{
g_warning ("reregistering command type '%s'", name);
if (old->notify)
old->notify (old->data);
old->notify (old->info.data);
g_free ((char*) old->info.id);
g_free ((char*) old->info.name);
g_free (old);
}
}
@ -114,20 +125,50 @@ moo_command_register (const char *name,
registered_types = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
type = g_new0 (CommandType, 1);
type->func = func;
type->data = user_data;
type->info.id = g_strdup (id);
type->info.name = g_strdup (name);
type->info.factory = factory;
type->info.create_widget = create_widget;
type->info.load_data = load_data;
type->info.save_data = save_data;
type->info.data = data;
type->notify = notify;
g_hash_table_insert (registered_types, g_strdup (name), type);
}
gboolean
moo_command_registered (const char *name)
MooCommandTypeInfo *
moo_command_type_lookup (const char *name)
{
CommandType *type = NULL;
g_return_val_if_fail (name != NULL, FALSE);
return registered_types != NULL &&
g_hash_table_lookup (registered_types, name) != NULL;
if (registered_types != NULL)
type = g_hash_table_lookup (registered_types, name);
return type ? &type->info : NULL;
}
static void
add_type_hash_cb (const char *type,
G_GNUC_UNUSED gpointer whatever,
GSList **list)
{
*list = g_slist_prepend (*list, g_strdup (type));
}
GSList *
moo_command_list_types (void)
{
GSList *list = NULL;
if (registered_types)
g_hash_table_foreach (registered_types, (GHFunc) add_type_hash_cb, &list);
return g_slist_reverse (list);
}
@ -141,8 +182,8 @@ moo_command_set_property (GObject *object,
switch (property_id)
{
case CMD_PROP_FLAGS:
moo_command_set_flags (cmd, g_value_get_flags (value));
case CMD_PROP_OPTIONS:
moo_command_set_options (cmd, g_value_get_flags (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@ -160,8 +201,8 @@ moo_command_get_property (GObject *object,
switch (property_id)
{
case CMD_PROP_FLAGS:
g_value_set_flags (value, cmd->flags);
case CMD_PROP_OPTIONS:
g_value_set_flags (value, cmd->options);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@ -174,13 +215,13 @@ moo_command_check_sensitive_real (MooCommand *cmd,
gpointer doc,
gpointer window)
{
if ((cmd->flags & MOO_COMMAND_NEED_WINDOW) && !MOO_IS_EDIT_WINDOW (window))
if ((cmd->options & MOO_COMMAND_NEED_WINDOW) && !MOO_IS_EDIT_WINDOW (window))
return FALSE;
if ((cmd->flags & MOO_COMMAND_NEED_DOC) && !doc)
if ((cmd->options & MOO_COMMAND_NEED_DOC) && !doc)
return FALSE;
if ((cmd->flags & MOO_COMMAND_NEED_FILE) && (!MOO_IS_EDIT (doc) || !moo_edit_get_filename (doc)))
if ((cmd->options & MOO_COMMAND_NEED_FILE) && (!MOO_IS_EDIT (doc) || !moo_edit_get_filename (doc)))
return FALSE;
return TRUE;
@ -209,9 +250,9 @@ moo_command_class_init (MooCommandClass *klass)
klass->check_context = moo_command_check_context_real;
klass->check_sensitive = moo_command_check_sensitive_real;
g_object_class_install_property (object_class, CMD_PROP_FLAGS,
g_param_spec_flags ("flags", "flags", "flags",
MOO_TYPE_COMMAND_FLAGS,
g_object_class_install_property (object_class, CMD_PROP_OPTIONS,
g_param_spec_flags ("options", "options", "options",
MOO_TYPE_COMMAND_OPTIONS,
0,
G_PARAM_READWRITE));
}
@ -223,14 +264,14 @@ moo_command_init (G_GNUC_UNUSED MooCommand *cmd)
}
static MooCommandFlags
check_flags (MooCommandFlags flags)
static MooCommandOptions
check_options (MooCommandOptions options)
{
MooCommandFlags checked = flags;
MooCommandOptions checked = options;
if (flags & MOO_COMMAND_NEED_FILE)
if (options & MOO_COMMAND_NEED_FILE)
checked |= MOO_COMMAND_NEED_DOC;
if (flags & MOO_COMMAND_NEED_SAVE)
if (options & MOO_COMMAND_NEED_SAVE)
checked |= MOO_COMMAND_NEED_DOC;
return checked;
@ -250,16 +291,16 @@ moo_command_run (MooCommand *cmd,
doc = moo_command_context_get_doc (ctx);
window = moo_command_context_get_window (ctx);
if (cmd->flags & MOO_COMMAND_NEED_WINDOW)
if (cmd->options & MOO_COMMAND_NEED_WINDOW)
g_return_if_fail (MOO_IS_EDIT_WINDOW (window));
if (cmd->flags & MOO_COMMAND_NEED_DOC)
if (cmd->options & MOO_COMMAND_NEED_DOC)
g_return_if_fail (doc != NULL);
if (cmd->flags & MOO_COMMAND_NEED_FILE)
if (cmd->options & MOO_COMMAND_NEED_FILE)
g_return_if_fail (MOO_IS_EDIT (doc) && moo_edit_get_filename (doc) != NULL);
if (cmd->flags & MOO_COMMAND_NEED_SAVE)
if (cmd->options & MOO_COMMAND_NEED_SAVE)
{
if (MOO_EDIT_IS_MODIFIED (doc) && !moo_edit_save (doc, NULL))
return;
@ -295,31 +336,31 @@ moo_command_check_sensitive (MooCommand *cmd,
void
moo_command_set_flags (MooCommand *cmd,
MooCommandFlags flags)
moo_command_set_options (MooCommand *cmd,
MooCommandOptions options)
{
g_return_if_fail (MOO_IS_COMMAND (cmd));
flags = check_flags (flags);
options = check_options (options);
if (flags != cmd->flags)
if (options != cmd->options)
{
cmd->flags = flags;
g_object_notify (G_OBJECT (cmd), "flags");
cmd->options = options;
g_object_notify (G_OBJECT (cmd), "options");
}
}
MooCommandFlags
moo_command_get_flags (MooCommand *cmd)
MooCommandOptions
moo_command_get_options (MooCommand *cmd)
{
g_return_val_if_fail (MOO_IS_COMMAND (cmd), 0);
return cmd->flags;
return cmd->options;
}
GType
moo_command_flags_get_type (void)
moo_command_options_get_type (void)
{
static GType type;
@ -333,17 +374,17 @@ moo_command_flags_get_type (void)
{ 0, NULL, NULL }
};
type = g_flags_register_static ("MooCommandFlags", values);
type = g_flags_register_static ("MooCommandOptions", values);
}
return type;
}
MooCommandFlags
moo_command_flags_parse (const char *string)
MooCommandOptions
moo_command_options_parse (const char *string)
{
MooCommandFlags flags = 0;
MooCommandOptions options = 0;
char **pieces, **p;
if (!string)
@ -364,34 +405,20 @@ moo_command_flags_parse (const char *string)
continue;
if (!strcmp (s, "need-doc"))
flags |= MOO_COMMAND_NEED_DOC;
options |= MOO_COMMAND_NEED_DOC;
else if (!strcmp (s, "need-file"))
flags |= MOO_COMMAND_NEED_FILE;
options |= MOO_COMMAND_NEED_FILE;
else if (!strcmp (s, "need-save"))
flags |= MOO_COMMAND_NEED_SAVE;
options |= MOO_COMMAND_NEED_SAVE;
else if (!strcmp (s, "need-window"))
flags |= MOO_COMMAND_NEED_WINDOW;
options |= MOO_COMMAND_NEED_WINDOW;
else
g_warning ("unknown flag '%s'", s);
}
out:
g_strfreev (pieces);
return flags;
}
void
moo_command_load_data (MooCommand *cmd,
MooCommandData *data)
{
const char *flags;
g_return_if_fail (MOO_IS_COMMAND (cmd));
g_return_if_fail (data != NULL);
flags = moo_command_data_get (data, "flags");
moo_command_set_flags (cmd, moo_command_flags_parse (flags));
return options;
}
@ -663,27 +690,19 @@ moo_command_context_get_window (MooCommandContext *ctx)
MooCommandData *
moo_command_data_new (void)
_moo_command_parse_markup (MooMarkupNode *node,
char **type_p,
char **options_p)
{
MooCommandData *data = g_new0 (MooCommandData, 1);
data->ref_count = 1;
data->hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
return data;
}
MooCommand *
_moo_command_parse_markup (MooMarkupNode *node)
{
MooCommand *cmd;
MooCommandData *data;
MooMarkupNode *child;
const char *type;
const char *type, *options;
g_return_val_if_fail (MOO_MARKUP_IS_ELEMENT (node), NULL);
g_return_val_if_fail (!strcmp (node->name, "command"), NULL);
type = moo_markup_get_prop (node, "type");
options = moo_markup_get_prop (node, "options");
if (!type)
{
@ -691,7 +710,7 @@ _moo_command_parse_markup (MooMarkupNode *node)
return NULL;
}
if (!moo_command_registered (type))
if (!moo_command_type_lookup (type))
{
g_warning ("unknown command type %s", type);
return NULL;
@ -714,10 +733,31 @@ _moo_command_parse_markup (MooMarkupNode *node)
moo_command_data_set (data, child->name, moo_markup_get_content (child));
}
cmd = moo_command_create (type, data);
if (type_p)
*type_p = g_strdup (type);
if (options_p)
*options_p = g_strdup (options);
moo_command_data_unref (data);
return cmd;
return data;
}
MooCommandData *
moo_command_data_new (void)
{
MooCommandData *data = g_new0 (MooCommandData, 1);
data->ref_count = 1;
data->hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
return data;
}
void
moo_command_data_clear (MooCommandData *data)
{
g_return_if_fail (data != NULL);
g_hash_table_destroy (data->hash);
data->hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
}

View File

@ -15,6 +15,7 @@
#define __MOO_COMMAND_H__
#include <mooutils/moomarkup.h>
#include <gtk/gtkwidget.h>
G_BEGIN_DECLS
@ -34,7 +35,7 @@ G_BEGIN_DECLS
#define MOO_COMMAND_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MOO_TYPE_COMMAND_CONTEXT, MooCommandContextClass))
#define MOO_TYPE_COMMAND_DATA (moo_command_data_get_type ())
#define MOO_TYPE_COMMAND_FLAGS (moo_command_flags_get_type ())
#define MOO_TYPE_COMMAND_OPTIONS (moo_command_options_get_type ())
typedef struct _MooCommand MooCommand;
typedef struct _MooCommandClass MooCommandClass;
@ -42,13 +43,14 @@ typedef struct _MooCommandContext MooCommandContext;
typedef struct _MooCommandContextPrivate MooCommandContextPrivate;
typedef struct _MooCommandContextClass MooCommandContextClass;
typedef struct _MooCommandData MooCommandData;
typedef struct _MooCommandTypeInfo MooCommandTypeInfo;
typedef enum {
MOO_COMMAND_NEED_DOC = 1 << 0,
MOO_COMMAND_NEED_FILE = 1 << 1,
MOO_COMMAND_NEED_SAVE = 1 << 2,
MOO_COMMAND_NEED_WINDOW = 1 << 3
} MooCommandFlags;
} MooCommandOptions;
struct _MooCommandContext {
GObject base;
@ -62,7 +64,7 @@ struct _MooCommandContextClass {
struct _MooCommand {
GObject base;
/* read-only */
MooCommandFlags flags;
MooCommandOptions options;
};
struct _MooCommandClass {
@ -78,19 +80,36 @@ struct _MooCommandClass {
};
typedef MooCommand *(*MooCommandFactoryFunc) (MooCommandData *data,
const char *options,
gpointer user_data);
typedef GtkWidget *(*MooCommandCreateWidgetFunc)(gpointer user_data);
typedef void (*MooCommandLoadDataFunc) (GtkWidget *widget,
MooCommandData *data,
gpointer user_data);
typedef gboolean (*MooCommandSaveDataFunc) (GtkWidget *widget,
MooCommandData *data,
gpointer user_data);
struct _MooCommandTypeInfo {
const char *id;
const char *name;
MooCommandFactoryFunc factory;
MooCommandCreateWidgetFunc create_widget;
MooCommandLoadDataFunc load_data;
MooCommandSaveDataFunc save_data;
gpointer data;
};
GType moo_command_get_type (void) G_GNUC_CONST;
GType moo_command_context_get_type(void) G_GNUC_CONST;
GType moo_command_data_get_type (void) G_GNUC_CONST;
GType moo_command_flags_get_type (void) G_GNUC_CONST;
GType moo_command_options_get_type(void) G_GNUC_CONST;
MooCommand *moo_command_create (const char *type,
const char *options,
MooCommandData *data);
void moo_command_load_data (MooCommand *cmd,
MooCommandData *data);
void moo_command_run (MooCommand *cmd,
MooCommandContext *ctx);
gboolean moo_command_check_context (MooCommand *cmd,
@ -99,17 +118,23 @@ gboolean moo_command_check_sensitive (MooCommand *cmd,
gpointer doc,
gpointer window);
void moo_command_set_flags (MooCommand *cmd,
MooCommandFlags flags);
MooCommandFlags moo_command_get_flags (MooCommand *cmd);
void moo_command_set_options (MooCommand *cmd,
MooCommandOptions options);
MooCommandOptions moo_command_get_options (MooCommand *cmd);
MooCommandFlags moo_command_flags_parse (const char *string);
MooCommandOptions moo_command_options_parse (const char *string);
void moo_command_register (const char *type,
MooCommandFactoryFunc func,
gpointer user_data,
void moo_command_type_register (const char *type,
const char *name,
MooCommandFactoryFunc factory,
MooCommandCreateWidgetFunc create_widget,
MooCommandLoadDataFunc load_data,
MooCommandSaveDataFunc save_data,
gpointer data,
GDestroyNotify notify);
gboolean moo_command_registered (const char *type);
MooCommandTypeInfo *moo_command_type_lookup (const char *type);
/* free return value and its contents */
GSList *moo_command_list_types (void);
MooCommandData *moo_command_data_new (void);
@ -123,6 +148,7 @@ const char *moo_command_data_get (MooCommandData *data,
const char *key);
void moo_command_data_unset (MooCommandData *data,
const char *key);
void moo_command_data_clear (MooCommandData *data);
MooCommandContext *moo_command_context_new (gpointer doc,
@ -152,7 +178,13 @@ void moo_command_context_foreach (MooCommandContext *ctx,
gpointer data);
void _moo_command_init (void);
MooCommand *_moo_command_parse_markup (MooMarkupNode *node);
MooCommandData *_moo_command_parse_markup (MooMarkupNode *node,
char **type,
char **options);
void _moo_command_format_markup (MooMarkupNode *parent,
MooCommandData *data,
char *type,
char *options);
G_END_DECLS

View File

@ -0,0 +1,538 @@
/*
* moousertools-prefs.c
*
* Copyright (C) 2004-2006 by Yevgen Muntyan <muntyan@math.tamu.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* See COPYING file that comes with this distribution.
*/
#include "mooedit/moousertools-prefs.h"
#include "mooedit/moousertools.h"
#include "mooedit/mooedittools-glade.h"
#include "mooedit/moocommand.h"
#include "mooutils/mooprefsdialogpage.h"
#include "mooutils/mooi18n.h"
#include "mooutils/mooutils-treeview.h"
#include <string.h>
#define GET_WID(name) (moo_glade_xml_get_widget (page->xml, (name)))
enum {
COLUMN_ENABLED,
COLUMN_ID,
COLUMN_NAME,
COLUMN_LABEL,
COLUMN_LANGS,
COLUMN_OPTIONS,
COLUMN_COMMAND_TYPE,
COLUMN_COMMAND,
N_COLUMNS
};
enum {
COMBO_COLUMN_NAME,
COMBO_COLUMN_TYPE
};
static void combo_changed (MooPrefsDialogPage *page,
GtkComboBox *combo);
static void block_combo (MooPrefsDialogPage *page);
static void unblock_combo (MooPrefsDialogPage *page);
static gboolean get_changed (MooPrefsDialogPage *page);
static void set_changed (MooPrefsDialogPage *page,
gboolean changed);
static gboolean
get_changed (MooPrefsDialogPage *page)
{
return g_object_get_data (G_OBJECT (page), "moo-changed") != NULL;
}
static void
set_changed (MooPrefsDialogPage *page,
gboolean changed)
{
g_object_set_data (G_OBJECT (page), "moo-changed",
GINT_TO_POINTER (changed));
}
static void
init_type_combo (MooPrefsDialogPage *page)
{
GtkListStore *store;
GSList *types;
GtkCellRenderer *cell;
GtkComboBox *combo;
combo = GET_WID ("type_combo");
cell = gtk_cell_renderer_text_new ();
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), cell,
"text", COMBO_COLUMN_NAME, NULL);
store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_POINTER);
gtk_combo_box_set_model (combo, GTK_TREE_MODEL (store));
types = moo_command_list_types ();
while (types)
{
GtkTreeIter iter;
char *type;
MooCommandTypeInfo *info;
GtkWidget *widget;
type = types->data;
info = moo_command_type_lookup (type);
g_return_if_fail (info != NULL);
widget = info->create_widget (info->data);
g_return_if_fail (widget != NULL);
gtk_widget_show (widget);
gtk_notebook_append_page (GET_WID ("notebook"), widget, NULL);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
COMBO_COLUMN_NAME, info->name,
COMBO_COLUMN_TYPE, info,
-1);
g_free (type);
types = g_slist_delete_link (types, types);
}
g_signal_connect_swapped (combo, "changed", G_CALLBACK (combo_changed), page);
g_object_unref (store);
}
static void
combo_set_type (MooPrefsDialogPage *page,
const char *type)
{
GtkComboBox *combo = GET_WID ("type_combo");
GtkTreeModel *model = gtk_combo_box_get_model (combo);
if (type)
{
gboolean found = FALSE;
int active;
int index = 0;
MooCommandTypeInfo *info;
GtkTreeIter iter;
if (gtk_tree_model_get_iter_first (model, &iter))
{
do
{
gtk_tree_model_get (model, &iter, COMBO_COLUMN_TYPE, &info, -1);
if (!strcmp (info->id, type))
{
found = TRUE;
break;
}
++index;
}
while (gtk_tree_model_iter_next (model, &iter));
}
g_return_if_fail (found);
active = gtk_combo_box_get_active (combo);
if (active < 0 || active != index)
{
block_combo (page);
gtk_combo_box_set_active (combo, index);
gtk_notebook_set_current_page (GET_WID ("notebook"), index);
gtk_widget_show (GET_WID ("notebook"));
unblock_combo (page);
}
}
else
{
block_combo (page);
gtk_combo_box_set_active (combo, -1);
gtk_widget_hide (GET_WID ("notebook"));
unblock_combo (page);
}
}
static void
block_combo (MooPrefsDialogPage *page)
{
g_signal_handlers_block_by_func (GET_WID ("type_combo"),
(gpointer) combo_changed,
page);
}
static void
unblock_combo (MooPrefsDialogPage *page)
{
g_signal_handlers_unblock_by_func (GET_WID ("type_combo"),
(gpointer) combo_changed,
page);
}
static void
combo_get_type (MooPrefsDialogPage *page,
const char **type_p,
MooCommandTypeInfo **info_p,
GtkWidget **widget_p)
{
GtkTreeIter iter;
GtkComboBox *combo = GET_WID ("type_combo");
GtkTreeModel *model = gtk_combo_box_get_model (combo);
int index = 0;
MooCommandTypeInfo *info;
index = gtk_combo_box_get_active (combo);
if (index >= 0)
{
gtk_tree_model_iter_nth_child (model, &iter, NULL, index);
gtk_tree_model_get (model, &iter, COMBO_COLUMN_TYPE, &info, -1);
if (type_p)
*type_p = info->id;
if (info_p)
*info_p = info;
if (widget_p)
*widget_p = gtk_notebook_get_nth_page (GET_WID ("notebook"), index);
}
else
{
if (type_p)
*type_p = NULL;
if (info_p)
*info_p = NULL;
if (widget_p)
*widget_p = NULL;
}
}
static void
combo_changed (MooPrefsDialogPage *page,
GtkComboBox *combo)
{
GtkTreeView *treeview;
GtkTreeSelection *selection;
GtkTreeModel *model, *combo_model;
GtkTreeIter iter;
MooCommandTypeInfo *info = NULL;
MooCommandData *data;
GtkWidget *widget;
treeview = GET_WID ("treeview");
selection = gtk_tree_view_get_selection (treeview);
combo_model = gtk_combo_box_get_model (combo);
if (!gtk_tree_selection_get_selected (selection, &model, &iter))
g_return_if_reached ();
combo_get_type (page, NULL, &info, &widget);
g_return_if_fail (info != NULL);
set_changed (page, TRUE);
gtk_tree_model_get (model, &iter, COLUMN_COMMAND, &data, -1);
moo_command_data_clear (data);
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
COLUMN_COMMAND_TYPE, info->id, -1);
info->load_data (widget, data, info->data);
moo_command_data_unref (data);
}
static void
tool_parse_func (MooToolLoadInfo *info,
gpointer data)
{
GtkTreeIter iter;
GtkListStore *store = data;
#ifdef __WIN32__
if (info->os_type != MOO_TOOL_WINDOWS)
return;
#else
if (info->os_type != MOO_TOOL_UNIX)
return;
#endif
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
COLUMN_ENABLED, info->enabled,
COLUMN_ID, info->id,
COLUMN_NAME, info->name,
COLUMN_LABEL, info->label,
COLUMN_LANGS, info->langs,
COLUMN_OPTIONS, info->options,
COLUMN_COMMAND_TYPE, info->cmd_type,
COLUMN_COMMAND, info->cmd_data,
-1);
}
static void
populate_store (GtkListStore *store)
{
_moo_edit_parse_user_tools (MOO_TOOL_FILE_TOOLS,
tool_parse_func,
store);
}
static gboolean
new_row (MooPrefsDialogPage *page,
GtkTreeModel *model,
GtkTreePath *path)
{
GtkTreeIter iter;
MooCommandData *cmd_data;
cmd_data = moo_command_data_new ();
set_changed (page, TRUE);
gtk_list_store_insert (GTK_LIST_STORE (model), &iter,
gtk_tree_path_get_indices(path)[0]);
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
COLUMN_ENABLED, TRUE,
COLUMN_ID, "New Tool",
COLUMN_NAME, "New Tool",
COLUMN_LABEL, "New Tool",
COLUMN_COMMAND_TYPE, "MooScript",
COLUMN_COMMAND, cmd_data,
-1);
moo_command_data_unref (cmd_data);
return TRUE;
}
static void
update_widgets (MooPrefsDialogPage *page,
GtkTreeModel *model,
GtkTreePath *path,
GtkTreeIter *iter)
{
gboolean enabled;
char *name, *label, *type, *langs, *options;
gboolean sensitive;
MooCommandData *cmd_data;
MooCommandTypeInfo *info;
GtkWidget *widget;
if (path)
{
gtk_tree_model_get (model, iter,
COLUMN_ENABLED, &enabled,
COLUMN_NAME, &name,
COLUMN_LABEL, &label,
COLUMN_LANGS, &langs,
COLUMN_OPTIONS, &options,
COLUMN_COMMAND_TYPE, &type,
COLUMN_COMMAND, &cmd_data,
-1);
sensitive = TRUE;
}
else
{
enabled = FALSE;
name = label = type = langs = options = NULL;
sensitive = FALSE;
cmd_data = NULL;
}
combo_set_type (page, type);
if (type)
{
combo_get_type (page, NULL, &info, &widget);
g_return_if_fail (info != NULL);
info->load_data (widget, cmd_data, info->data);
}
gtk_toggle_button_set_active (GET_WID ("enabled"), enabled);
gtk_entry_set_text (GET_WID ("name"), name ? name : "");
gtk_entry_set_text (GET_WID ("label"), label ? label : "");
gtk_entry_set_text (GET_WID ("langs"), langs ? langs : "");
gtk_entry_set_text (GET_WID ("options"), options ? options : "");
gtk_widget_set_sensitive (GET_WID ("tool_vbox"), sensitive);
g_free (name);
g_free (label);
g_free (type);
g_free (langs);
g_free (options);
if (cmd_data)
moo_command_data_unref (cmd_data);
}
static gboolean
string_equal (const char *s1,
const char *s2)
{
return !strcmp (s1 ? s1 : "", s2 ? s2 : "");
}
static void
update_model (MooPrefsDialogPage *page,
GtkTreeModel *model,
G_GNUC_UNUSED GtkTreePath *path,
GtkTreeIter *iter)
{
gboolean old_enabled;
char *old_name, *old_label, *old_type, *old_langs, *old_options;
gboolean enabled;
const char *name, *label, *type, *langs, *options;
MooCommandData *data;
MooCommandTypeInfo *info = NULL;
GtkWidget *widget;
enabled = gtk_toggle_button_get_active (GET_WID ("enabled"));
name = gtk_entry_get_text (GET_WID ("name"));
label = gtk_entry_get_text (GET_WID ("label"));
langs = gtk_entry_get_text (GET_WID ("langs"));
options = gtk_entry_get_text (GET_WID ("options"));
combo_get_type (page, &type, &info, &widget);
g_return_if_fail (info != NULL);
gtk_tree_model_get (model, iter, COLUMN_COMMAND, &data, -1);
if (info->save_data (widget, data, info->data))
set_changed (page, TRUE);
gtk_tree_model_get (model, iter,
COLUMN_ENABLED, &old_enabled,
COLUMN_NAME, &old_name,
COLUMN_LABEL, &old_label,
COLUMN_LANGS, &old_langs,
COLUMN_OPTIONS, &old_options,
COLUMN_COMMAND_TYPE, &old_type,
-1);
if (enabled != old_enabled ||
!string_equal (old_name, name) ||
!string_equal (old_label, label) ||
!string_equal (old_langs, langs) ||
!string_equal (old_options, options) ||
!string_equal (old_type, type))
{
gtk_list_store_set (GTK_LIST_STORE (model), iter,
COLUMN_ENABLED, enabled,
COLUMN_NAME, name,
COLUMN_LABEL, label,
COLUMN_LANGS, langs,
COLUMN_OPTIONS, options,
COLUMN_COMMAND_TYPE, type,
-1);
set_changed (page, TRUE);
}
g_free (old_name);
g_free (old_label);
g_free (old_langs);
g_free (old_options);
g_free (old_type);
moo_command_data_unref (data);
}
static void
page_init (MooPrefsDialogPage *page)
{
GtkTreeView *treeview;
GtkListStore *store;
GtkTreeViewColumn *column;
GtkCellRenderer *cell;
MooTreeHelper *helper;
init_type_combo (page);
treeview = moo_glade_xml_get_widget (page->xml, "treeview");
store = gtk_list_store_new (N_COLUMNS, G_TYPE_BOOLEAN,
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
MOO_TYPE_COMMAND_DATA);
gtk_tree_view_set_model (treeview, GTK_TREE_MODEL (store));
cell = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("id", cell, "text", COLUMN_ID, NULL);
gtk_tree_view_append_column (treeview, column);
populate_store (store);
_moo_tree_view_select_first (treeview);
helper = _moo_tree_helper_new (GTK_WIDGET (treeview),
moo_glade_xml_get_widget (page->xml, "new"),
moo_glade_xml_get_widget (page->xml, "delete"),
moo_glade_xml_get_widget (page->xml, "up"),
moo_glade_xml_get_widget (page->xml, "down"));
g_object_set_data_full (G_OBJECT (page), "moo-tree-helper", helper, g_object_unref);
g_signal_connect_swapped (page, "destroy", G_CALLBACK (gtk_object_destroy), helper);
g_signal_connect_swapped (helper, "new-row", G_CALLBACK (new_row), page);
g_signal_connect_swapped (helper, "update-widgets", G_CALLBACK (update_widgets), page);
g_signal_connect_swapped (helper, "update-model", G_CALLBACK (update_model), page);
_moo_tree_helper_update_widgets (helper);
g_object_unref (store);
}
static void
page_apply (MooPrefsDialogPage *page)
{
MooTreeHelper *helper;
helper = g_object_get_data (G_OBJECT (page), "moo-tree-helper");
_moo_tree_helper_update_model (helper, NULL, NULL);
if (!get_changed (page))
return;
g_print ("apply\n");
set_changed (page, FALSE);
}
GtkWidget *
moo_user_tools_prefs_page_new (void)
{
MooPrefsDialogPage *page;
MooGladeXML *xml;
xml = moo_glade_xml_new_empty (GETTEXT_PACKAGE);
page = moo_prefs_dialog_page_new_from_xml (_("Tools"), GTK_STOCK_EXECUTE,
xml, MOO_EDIT_TOOLS_GLADE_XML, -1,
"page", NULL);
g_signal_connect (page, "init", G_CALLBACK (page_init), NULL);
g_signal_connect (page, "apply", G_CALLBACK (page_apply), NULL);
g_object_unref (xml);
return GTK_WIDGET (page);
}

View File

@ -0,0 +1,27 @@
/*
* moousertools-prefs.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_USER_TOOLS_PREFS_H__
#define __MOO_USER_TOOLS_PREFS_H__
#include <gtk/gtkwidget.h>
G_BEGIN_DECLS
GtkWidget *moo_user_tools_prefs_page_new (void);
G_END_DECLS
#endif /* __MOO_USER_TOOLS_PREFS_H__ */

View File

@ -25,11 +25,7 @@
#define TOOLS_FILE "tools.xml"
#define MENU_FILE "menu.xml"
enum {
FILE_TOOLS,
FILE_MENU,
N_FILES
};
#define N_TOOLS 2
enum {
PROP_0,
@ -60,12 +56,9 @@ G_DEFINE_TYPE (MooToolAction, _moo_tool_action, MOO_TYPE_EDIT_ACTION);
#define MOO_TOOL_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, MOO_TYPE_TOOL_ACTION, MooToolAction))
static ToolStore *tools_stores[N_FILES];
static ToolStore *tools_stores[N_TOOLS];
static void parse_user_tools (MooMarkupDoc *doc,
MooUIXML *xml,
int type);
static MooCommandContext *create_command_context (gpointer window,
gpointer doc);
@ -83,7 +76,7 @@ unload_user_tools (int type)
list = store->tools;
store->tools = NULL;
if (type == FILE_MENU)
if (type == MOO_TOOL_FILE_MENU)
klass = g_type_class_peek (MOO_TYPE_EDIT_WINDOW);
else
klass = g_type_class_peek (MOO_TYPE_EDIT);
@ -100,7 +93,7 @@ unload_user_tools (int type)
g_object_unref (info->xml);
}
if (type == FILE_MENU)
if (type == MOO_TOOL_FILE_MENU)
moo_window_class_remove_action (klass, info->id);
else
moo_edit_class_remove_action (klass, info->id);
@ -122,7 +115,7 @@ find_user_tools_file (int type)
char *filename = NULL;
int i;
files = moo_get_data_files (type == FILE_TOOLS ? TOOLS_FILE : MENU_FILE,
files = moo_get_data_files (type == MOO_TOOL_FILE_TOOLS ? TOOLS_FILE : MENU_FILE,
MOO_DATA_SHARE, &n_files);
if (!n_files)
@ -142,60 +135,26 @@ find_user_tools_file (int type)
}
static void
load_user_tools (const char *file,
MooUIXML *xml,
int type)
void
_moo_edit_save_user_tools (MooToolFileType type,
MooMarkupDoc *doc)
{
MooMarkupDoc *doc;
char *contents;
GError *error = NULL;
char *freeme = NULL;
g_return_if_fail (!xml || MOO_IS_UI_XML (xml));
g_return_if_fail (type < N_FILES);
g_return_if_fail (type < N_TOOLS);
g_return_if_fail (doc != NULL);
unload_user_tools (type);
_moo_command_init ();
contents = moo_markup_node_get_pretty_string (MOO_MARKUP_NODE (doc), 2);
if (!file)
if (!moo_save_user_data_file (type == MOO_TOOL_FILE_TOOLS ? TOOLS_FILE : MENU_FILE,
contents, -1, &error))
{
freeme = find_user_tools_file (type);
file = freeme;
}
if (!file)
return;
doc = moo_markup_parse_file (file, &error);
if (doc)
{
parse_user_tools (doc, xml, type);
moo_markup_doc_unref (doc);
}
else
{
g_warning ("could not load file '%s': %s", file, error->message);
g_critical ("could not save tools file: %s", error->message);
g_error_free (error);
}
g_free (freeme);
}
void
moo_edit_load_user_tools (const char *file,
MooUIXML *xml)
{
return load_user_tools (file, xml, FILE_TOOLS);
}
void
moo_edit_load_user_menu (const char *file,
MooUIXML *xml)
{
return load_user_tools (file, xml, FILE_MENU);
g_free (contents);
}
@ -215,146 +174,79 @@ check_sensitive_func (GtkAction *gtkaction,
static void
parse_element (MooMarkupNode *node,
MooUIXML *xml,
int type,
const char *file)
load_tool_func (MooToolLoadInfo *info,
gpointer user_data)
{
const char *os, *id;
const char *position = NULL, *name = NULL, *label = NULL;
const char *accel = NULL, *menu = NULL, *langs = NULL;
MooMarkupNode *cmd_node, *child;
MooCommand *cmd;
gboolean enabled;
ToolStore **store;
ToolInfo *tool_info;
gpointer klass = NULL;
MooCommand *cmd;
MooUIXML *xml = user_data;
if (strcmp (node->name, "tool"))
{
g_warning ("invalid element %s in file %s", node->name, file);
return;
}
id = moo_markup_get_prop (node, "id");
if (!id || !id[0])
{
g_warning ("tool id attribute missing in file %s", file);
return;
}
enabled = moo_markup_get_bool_prop (node, "enabled", TRUE);
os = moo_markup_get_prop (node, "os");
position = moo_markup_get_prop (node, "position");
if (!enabled)
if (!info->enabled)
return;
if (os)
{
#ifdef __WIN32__
if (g_ascii_strncasecmp (os, "win", 3);
return;
if (info->os_type != MOO_TOOL_WINDOWS)
return;
#else
if (g_ascii_strcasecmp (os, "unix"))
return;
if (info->os_type != MOO_TOOL_UNIX)
return;
#endif
}
for (child = node->children; child != NULL; child = child->next)
{
if (!MOO_MARKUP_IS_ELEMENT (child) || !strcmp (child->name, "command"))
continue;
if (!strcmp (child->name, "name"))
name = moo_markup_get_content (child);
else if (!strcmp (child->name, "_name"))
name = _(moo_markup_get_content (child));
else if (!strcmp (child->name, "label"))
label = moo_markup_get_content (child);
else if (!strcmp (child->name, "_label"))
label = _(moo_markup_get_content (child));
else if (!strcmp (child->name, "accel"))
accel = moo_markup_get_content (child);
else if (!strcmp (child->name, "position"))
position = moo_markup_get_content (child);
else if (!strcmp (child->name, "menu"))
menu = moo_markup_get_content (child);
else if (!strcmp (child->name, "langs"))
langs = moo_markup_get_content (child);
else
g_warning ("unknown element %s in tool %s in file %s",
child->name, id, file);
}
if (!name)
{
g_warning ("name missing for tool '%s' in file %s", id, file);
return;
}
if (!label)
label = name;
cmd_node = moo_markup_get_element (node, "command");
if (!cmd_node)
{
g_warning ("command missing for tool '%s' in file %s", id, file);
return;
}
cmd = _moo_command_parse_markup (cmd_node);
cmd = moo_command_create (info->cmd_type,
info->options,
info->cmd_data);
if (!cmd)
{
g_warning ("could not get command for tool '%s' in file %s", id, file);
g_warning ("could not get command for tool '%s' in file %s",
info->id, info->file);
return;
}
switch (type)
switch (info->type)
{
case FILE_TOOLS:
case MOO_TOOL_FILE_TOOLS:
klass = g_type_class_peek (MOO_TYPE_EDIT_WINDOW);
if (!moo_window_class_find_group (klass, "Tools"))
moo_window_class_new_group (klass, "Tools", _("Tools"));
moo_window_class_new_action (klass, id, "Tools",
moo_window_class_new_action (klass, info->id, "Tools",
"action-type::", MOO_TYPE_TOOL_ACTION,
"display-name", name,
"label", label,
"accel", accel,
"display-name", info->name,
"label", info->label,
"accel", info->accel,
"command", cmd,
NULL);
moo_edit_window_set_action_check (id, MOO_ACTION_CHECK_SENSITIVE,
moo_edit_window_set_action_check (info->id, MOO_ACTION_CHECK_SENSITIVE,
check_sensitive_func,
NULL, NULL);
if (langs)
moo_edit_window_set_action_langs (id, MOO_ACTION_CHECK_ACTIVE, langs);
if (info->langs)
moo_edit_window_set_action_langs (info->id, MOO_ACTION_CHECK_ACTIVE, info->langs);
break;
case FILE_MENU:
case MOO_TOOL_FILE_MENU:
klass = g_type_class_peek (MOO_TYPE_EDIT);
moo_edit_class_new_action (klass, id,
moo_edit_class_new_action (klass, info->id,
"action-type::", MOO_TYPE_TOOL_ACTION,
"display-name", name,
"label", label,
"accel", accel,
"display-name", info->name,
"label", info->label,
"accel", info->accel,
"command", cmd,
"langs", langs,
"langs", info->langs,
NULL);
break;
}
tool_info = g_new0 (ToolInfo, 1);
tool_info->id = g_strdup (id);
tool_info->id = g_strdup (info->id);
store = &tools_stores[type];
store = &tools_stores[info->type];
if (!*store)
*store = g_new (ToolStore, 1);
@ -367,29 +259,22 @@ parse_element (MooMarkupNode *node,
char *freeme = NULL;
char *markup;
markup = g_markup_printf_escaped ("<item action=\"%s\"/>", id);
markup = g_markup_printf_escaped ("<item action=\"%s\"/>", info->id);
tool_info->xml = g_object_ref (xml);
tool_info->merge_id = moo_ui_xml_new_merge_id (xml);
if (type == FILE_MENU)
if (info->type == MOO_TOOL_FILE_MENU)
{
ui_path = "Editor/Popup/PopupEnd";
if (position)
{
if (!g_ascii_strcasecmp (position, "end"))
ui_path = "Editor/Popup/PopupEnd";
else if (!g_ascii_strcasecmp (position, "start"))
ui_path = "Editor/Popup/PopupStart";
else
g_warning ("unknown position type '%s' for tool %s in file %s",
position, id, file);
}
if (info->position == MOO_TOOL_POS_START)
ui_path = "Editor/Popup/PopupStart";
else
ui_path = "Editor/Popup/PopupEnd";
}
else
{
freeme = g_strdup_printf ("Editor/Menubar/%s/UserMenu",
menu ? menu : "Tools");
info->menu ? info->menu : "Tools");
ui_path = freeme;
}
@ -403,10 +288,138 @@ parse_element (MooMarkupNode *node,
}
void
_moo_edit_load_user_tools (MooToolFileType type,
MooUIXML *xml)
{
unload_user_tools (type);
_moo_edit_parse_user_tools (type, load_tool_func, xml);
}
static void
parse_user_tools (MooMarkupDoc *doc,
MooUIXML *xml,
int type)
parse_element (MooMarkupNode *node,
MooToolFileType type,
MooToolFileParseFunc func,
gpointer data,
const char *file)
{
const char *os;
const char *position = NULL;
MooMarkupNode *cmd_node, *child;
MooCommandData *cmd_data;
MooToolLoadInfo info;
memset (&info, 0, sizeof (info));
info.type = type;
info.file = file;
info.position = MOO_TOOL_POS_END;
if (strcmp (node->name, "tool"))
{
g_warning ("invalid element %s in file %s", node->name, file);
return;
}
info.id = moo_markup_get_prop (node, "id");
if (!info.id || !info.id[0])
{
g_warning ("tool id missing in file %s", file);
return;
}
info.enabled = moo_markup_get_bool_prop (node, "enabled", TRUE);
os = moo_markup_get_prop (node, "os");
#ifdef __WIN32__
info.os_type = (!os || !g_ascii_strncasecmp (os, "win", 3)) ? MOO_TOOL_WINDOWS : MOO_TOOL_UNIX;
#else
info.os_type = (!os || !g_ascii_strcasecmp (os, "unix")) ? MOO_TOOL_UNIX : MOO_TOOL_WINDOWS;
#endif
for (child = node->children; child != NULL; child = child->next)
{
if (!MOO_MARKUP_IS_ELEMENT (child) || !strcmp (child->name, "command"))
continue;
if (!strcmp (child->name, "name"))
info.name = moo_markup_get_content (child);
else if (!strcmp (child->name, "_name"))
info.name = _(moo_markup_get_content (child));
else if (!strcmp (child->name, "label"))
info.label = moo_markup_get_content (child);
else if (!strcmp (child->name, "_label"))
info.label = _(moo_markup_get_content (child));
else if (!strcmp (child->name, "accel"))
info.accel = moo_markup_get_content (child);
else if (!strcmp (child->name, "position"))
position = moo_markup_get_content (child);
else if (!strcmp (child->name, "menu"))
info.menu = moo_markup_get_content (child);
else if (!strcmp (child->name, "langs"))
info.langs = moo_markup_get_content (child);
else
g_warning ("unknown element %s in tool %s in file %s",
child->name, info.id, file);
}
if (!info.name)
{
g_warning ("name missing for tool '%s' in file %s", info.id, file);
return;
}
if (position && type != MOO_TOOL_FILE_MENU)
{
g_warning ("invalid element 'position' in tool '%s' in file %s", info.id, file);
return;
}
else if (position)
{
if (!g_ascii_strcasecmp (position, "end"))
info.position = MOO_TOOL_POS_END;
else if (!g_ascii_strcasecmp (position, "start"))
info.position = MOO_TOOL_POS_START;
else
g_warning ("unknown position type '%s' for tool %s in file %s",
position, info.id, file);
}
if (!info.label)
info.label = info.name;
cmd_node = moo_markup_get_element (node, "command");
if (!cmd_node)
{
g_warning ("command missing for tool '%s' in file %s", info.id, file);
return;
}
info.cmd_data = _moo_command_parse_markup (cmd_node,
(char**) &info.cmd_type,
(char**) &info.options);
if (!info.cmd_data)
{
g_warning ("could not get command data for tool '%s' in file %s", info.id, file);
return;
}
func (&info, data);
moo_command_data_unref (cmd_data);
g_free ((char*) info.cmd_type);
g_free ((char*) info.options);
}
static void
parse_doc (MooMarkupDoc *doc,
MooToolFileType type,
MooToolFileParseFunc func,
gpointer data)
{
MooMarkupNode *root, *child;
@ -421,11 +434,46 @@ parse_user_tools (MooMarkupDoc *doc,
for (child = root->children; child != NULL; child = child->next)
{
if (MOO_MARKUP_IS_ELEMENT (child))
parse_element (child, xml, type, doc->name);
parse_element (child, type, func, data, doc->name);
}
}
void
_moo_edit_parse_user_tools (MooToolFileType type,
MooToolFileParseFunc func,
gpointer data)
{
char *file;
MooMarkupDoc *doc;
GError *error = NULL;
g_return_if_fail (type < N_TOOLS);
g_return_if_fail (func != NULL);
_moo_command_init ();
file = find_user_tools_file (type);
if (!file)
return;
doc = moo_markup_parse_file (file, &error);
if (doc)
{
parse_doc (doc, type, func, data);
moo_markup_doc_unref (doc);
}
else
{
g_warning ("could not load file '%s': %s", file, error->message);
g_error_free (error);
}
g_free (file);
}
static void
moo_tool_action_set_property (GObject *object,
guint property_id,

View File

@ -15,15 +15,54 @@
#define __MOO_USER_TOOLS_H__
#include <mooutils/moouixml.h>
#include <mooedit/moocommand.h>
G_BEGIN_DECLS
/* file == NULL means find one in data dirs */
void moo_edit_load_user_tools (const char *file,
MooUIXML *xml);
void moo_edit_load_user_menu (const char *file,
MooUIXML *xml);
typedef enum {
MOO_TOOL_FILE_TOOLS,
MOO_TOOL_FILE_MENU
} MooToolFileType;
typedef enum {
MOO_TOOL_POS_START,
MOO_TOOL_POS_END
} MooToolPosition;
typedef enum {
MOO_TOOL_UNIX,
MOO_TOOL_WINDOWS
} MooToolOSType;
typedef struct {
const char *id;
const char *name;
const char *label;
const char *accel;
const char *menu;
const char *langs;
const char *options;
MooToolPosition position;
gboolean enabled;
MooToolOSType os_type;
const char *cmd_type;
MooCommandData *cmd_data;
MooToolFileType type;
const char *file;
} MooToolLoadInfo;
void _moo_edit_load_user_tools (MooToolFileType type,
MooUIXML *xml);
typedef void (*MooToolFileParseFunc) (MooToolLoadInfo *info,
gpointer data);
void _moo_edit_parse_user_tools (MooToolFileType type,
MooToolFileParseFunc func,
gpointer data);
void _moo_edit_save_user_tools (MooToolFileType type,
MooMarkupDoc *doc);
G_END_DECLS

View File

@ -55,7 +55,7 @@ static void helper_update_model (MooGladeXML *xml,
GtkWidget *
_moo_file_selector_prefs_page (MooPlugin *plugin)
{
GtkWidget *page;
MooPrefsDialogPage *page;
MooGladeXML *xml;
GtkWidget *treeview;
GtkTreeViewColumn *column;
@ -102,7 +102,7 @@ _moo_file_selector_prefs_page (MooPlugin *plugin)
g_object_set_data (G_OBJECT (xml), "moo-file-selector-plugin", plugin);
g_object_unref (xml);
return page;
return GTK_WIDGET (page);
}

View File

@ -36,9 +36,10 @@
<property name="enable_popup">False</property>
<child>
<widget class="GtkHPaned" id="hpaned1">
<widget class="GtkHBox" id="hbox3">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="homogeneous">False</property>
<property name="spacing">6</property>
<child>
<widget class="GtkVBox" id="vbox2">
@ -202,8 +203,9 @@
</child>
</widget>
<packing>
<property name="shrink">False</property>
<property name="resize">False</property>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
@ -222,154 +224,6 @@
<property name="row_spacing">0</property>
<property name="column_spacing">0</property>
<child>
<widget class="GtkEventBox" id="eventbox4">
<property name="visible">True</property>
<property name="tooltip">Semicolon-separated list of mime types, e.g. 'text/*;application/x-glade'</property>
<property name="visible_window">True</property>
<property name="above_child">False</property>
<child>
<widget class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="label" translatable="yes">Mime types:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">1</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
</child>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEventBox" id="eventbox3">
<property name="visible">True</property>
<property name="tooltip">Semicolon-separated list of file globs, e.g. '*.txt;foo.*;*bar*'</property>
<property name="visible_window">True</property>
<property name="above_child">False</property>
<child>
<widget class="GtkLabel" id="label5">
<property name="visible">True</property>
<property name="label" translatable="yes">Extensions:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">1</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
</child>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEventBox" id="eventbox2">
<property name="visible">True</property>
<property name="tooltip">Shell command to open the file: '%f' is replaced with file path, e.g. 'foobar %f'</property>
<property name="visible_window">True</property>
<property name="above_child">False</property>
<child>
<widget class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="label">Command:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">1</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
</child>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEventBox" id="eventbox1">
<property name="visible">True</property>
<property name="tooltip">Menu item label</property>
<property name="visible_window">True</property>
<property name="above_child">False</property>
<child>
<widget class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="label">Label:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">1</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
</child>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="mimetypes">
<property name="visible">True</property>
@ -457,6 +311,154 @@
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEventBox" id="eventbox1">
<property name="visible">True</property>
<property name="tooltip">Menu item label</property>
<property name="visible_window">True</property>
<property name="above_child">False</property>
<child>
<widget class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="label">Label:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">1</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
</child>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEventBox" id="eventbox2">
<property name="visible">True</property>
<property name="tooltip">Shell command to open the file: '%f' is replaced with file path, e.g. 'foobar %f'</property>
<property name="visible_window">True</property>
<property name="above_child">False</property>
<child>
<widget class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="label">Command:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">1</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
</child>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEventBox" id="eventbox3">
<property name="visible">True</property>
<property name="tooltip">Semicolon-separated list of file globs, e.g. '*.txt;foo.*;*bar*'</property>
<property name="visible_window">True</property>
<property name="above_child">False</property>
<child>
<widget class="GtkLabel" id="label5">
<property name="visible">True</property>
<property name="label" translatable="yes">Extensions:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">1</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
</child>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEventBox" id="eventbox4">
<property name="visible">True</property>
<property name="tooltip">Semicolon-separated list of mime types, e.g. 'text/*;application/x-glade'</property>
<property name="visible_window">True</property>
<property name="above_child">False</property>
<child>
<widget class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="label" translatable="yes">Mime types:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">1</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
</child>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
@ -466,8 +468,9 @@
</child>
</widget>
<packing>
<property name="shrink">False</property>
<property name="resize">False</property>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>

View File

@ -2,8 +2,7 @@
<tool id="ShellCommand" os="unix">
<_name>Shell Command</_name>
<_label>_Shell Command</_label>
<command type="MooScript">
<flags>need-doc</flags>
<command type="MooScript" options="need-doc">
<code>cmd = HistoryEntry("", "ShellCommand");
if cmd then
Insert(Exec(cmd), "\n");

View File

@ -13,7 +13,7 @@
(c-name "MooCommand")
(gtype-id "MOO_TYPE_COMMAND")
(fields
'("MooCommandFlags" "flags")
'("MooCommandOptions" "options")
)
)
@ -23,24 +23,33 @@
(gtype-id "MOO_TYPE_COMMAND_DATA")
)
(define-flags CommandFlags
(define-flags CommandOptions
(in-module "Moo")
(c-name "MooCommandFlags")
(gtype-id "MOO_TYPE_COMMAND_FLAGS")
(c-name "MooCommandOptions")
(gtype-id "MOO_TYPE_COMMAND_OPTIONS")
)
(define-function parse_command_options
(c-name "moo_command_options_parse")
(return-type "MooCommandOptions")
(parameters
'("const-char*" "string" (null-ok))
)
)
(define-function command_create
(c-name "moo_command_create")
(return-type "MooCommand*")
(parameters
'("const-char*" "type")
'("const-char*" "options")
'("MooCommandData*" "data")
)
)
(define-function command_register
(c-name "moo_command_register")
(define-function command_type_register
(c-name "moo_command_type_register")
(return-type "none")
(parameters
'("const-char*" "type")
@ -49,8 +58,8 @@
)
)
(define-function command_registered
(c-name "moo_command_registered")
(define-function command_type_registered
(c-name "moo_command_type_registered")
(return-type "gboolean")
(parameters
'("const-char*" "type")
@ -75,19 +84,19 @@
)
)
(define-method set_flags
(define-method set_options
(of-object "MooCommand")
(c-name "moo_command_set_flags")
(c-name "moo_command_set_options")
(return-type "none")
(parameters
'("MooCommandFlags" "flags")
'("MooCommandOptions" "options")
)
)
(define-method get_flags
(define-method get_options
(of-object "MooCommand")
(c-name "moo_command_get_flags")
(return-type "MooCommandFlags")
(c-name "moo_command_get_options")
(return-type "MooCommandOptions")
)

View File

@ -624,29 +624,37 @@ _wrap_moo_command_context_foreach (PyGObject *self, PyObject *args)
return_None;
}
%%
override moo_command_register kwargs
override moo_command_type_register kwargs
typedef struct {
PyObject *func;
PyObject *factory_func;
PyObject *create_widget_func;
PyObject *load_data_func;
PyObject *save_data_func;
PyObject *data;
} CommandFactoryData;
} CommandTypeData;
static MooCommand *
command_factory_func (MooCommandData *data,
const char *flags,
gpointer user_data)
{
MooCommand *cmd;
PyObject *py_cmd, *py_data;
CommandFactoryData *factory_data = user_data;
PyObject *py_cmd, *py_data, *py_flags;
CommandTypeData *type_data = user_data;
py_data = pyg_boxed_new (MOO_TYPE_COMMAND_DATA, data, TRUE, TRUE);
py_flags = PyString_FromString (flags);
if (factory_data->data)
py_cmd = PyObject_CallFunction (factory_data->func, (char*) "OO", py_data, factory_data->data);
if (type_data->data)
py_cmd = PyObject_CallFunction (type_data->factory_func, (char*) "OOO",
py_data, py_flags, type_data->data);
else
py_cmd = PyObject_CallFunction (factory_data->func, (char*) "O", py_data);
py_cmd = PyObject_CallFunction (type_data->factory_func, (char*) "OO",
py_data, py_flags);
Py_DECREF (py_data);
Py_DECREF (py_flags);
if (!py_cmd)
{
@ -673,42 +681,185 @@ command_factory_func (MooCommandData *data,
return cmd;
}
static GtkWidget *
command_create_widget (gpointer user_data)
{
PyObject *py_widget;
GtkWidget *widget;
CommandTypeData *type_data = user_data;
if (type_data->data)
py_widget = PyObject_CallFunction (type_data->create_widget_func, (char*) "O", type_data->data);
else
py_widget = PyObject_CallFunction (type_data->create_widget_func, (char*) "");
if (!py_widget)
{
PyErr_Print ();
return NULL;
}
if (py_widget == Py_None)
{
Py_DECREF (py_widget);
return NULL;
}
if (!pygobject_check (py_widget, &PyGtkWidget_Type))
{
g_warning ("return value must be a GtkWidget");
Py_DECREF (py_widget);
return NULL;
}
widget = g_object_ref (pygobject_get (py_widget));
Py_DECREF (py_widget);
return widget;
}
static void
command_factory_data_free (CommandFactoryData *data)
command_load_data (GtkWidget *widget,
MooCommandData *data,
gpointer user_data)
{
PyObject *py_widget, *py_data;
CommandTypeData *type_data = user_data;
PyObject *py_ret;
py_data = pyg_boxed_new (MOO_TYPE_COMMAND_DATA, data, TRUE, TRUE);
py_widget = pygobject_new (G_OBJECT (widget));
if (type_data->data)
py_ret = PyObject_CallFunction (type_data->load_data_func, (char*) "OOO",
py_widget, py_data, type_data->data);
else
py_ret = PyObject_CallFunction (type_data->load_data_func, (char*) "OO",
py_widget, py_data);
if (!py_ret)
{
PyErr_Print ();
}
else
{
Py_DECREF (py_ret);
}
}
static gboolean
command_save_data (GtkWidget *widget,
MooCommandData *data,
gpointer user_data)
{
PyObject *py_widget, *py_data;
CommandTypeData *type_data = user_data;
PyObject *py_ret;
gboolean ret = FALSE;
py_data = pyg_boxed_new (MOO_TYPE_COMMAND_DATA, data, TRUE, TRUE);
py_widget = pygobject_new (G_OBJECT (widget));
if (type_data->data)
py_ret = PyObject_CallFunction (type_data->save_data_func, (char*) "OOO",
py_widget, py_data, type_data->data);
else
py_ret = PyObject_CallFunction (type_data->save_data_func, (char*) "OO",
py_widget, py_data);
if (!py_ret)
{
PyErr_Print ();
}
else
{
ret = PyObject_IsTrue (py_ret);
Py_DECREF (py_ret);
}
return ret;
}
static void
command_type_data_free (CommandTypeData *data)
{
if (data)
{
Py_XDECREF (data->func);
Py_XDECREF (data->factory_func);
Py_XDECREF (data->create_widget_func);
Py_XDECREF (data->load_data_func);
Py_XDECREF (data->save_data_func);
Py_XDECREF (data->data);
g_free (data);
}
}
static PyObject *
_wrap_moo_command_register (G_GNUC_UNUSED PyGObject *self, PyObject *args, PyObject *kwargs)
_wrap_moo_command_type_register (G_GNUC_UNUSED PyGObject *self, PyObject *args, PyObject *kwargs)
{
static char *kwlist[] = {(char*) "type", (char*) "factory_func", (char*) "factory_data", NULL};
char *type;
PyObject *factory_func;
static char *kwlist[] = {(char*) "id",
(char*) "name",
(char*) "factory_func",
(char*) "create_widget_func",
(char*) "load_data_func",
(char*) "save_data_func",
(char*) "data",
NULL};
char *type, *name;
PyObject *factory_func, *create_widget_func, *load_data_func, *save_data_func;
PyObject *factory_data = NULL;
CommandFactoryData *data;
CommandTypeData *data;
if (!PyArg_ParseTupleAndKeywords (args, kwargs, (char*) "sO|O:command_register",
kwlist, &type, &factory_func, &factory_data))
if (!PyArg_ParseTupleAndKeywords (args, kwargs, (char*) "ssOOOO|O:command_type_register",
kwlist, &type, &name,
&factory_func, &factory_data))
return NULL;
if (!PyCallable_Check (factory_func))
return_TypeError ("command_register: factory_func must be callable");
if (!PyCallable_Check (create_widget_func))
return_TypeError ("command_register: create_widget_func must be callable");
if (!PyCallable_Check (load_data_func))
return_TypeError ("command_register: load_data_func must be callable");
if (!PyCallable_Check (save_data_func))
return_TypeError ("command_register: save_data_func must be callable");
Py_INCREF (factory_func);
Py_INCREF (create_widget_func);
Py_INCREF (load_data_func);
Py_INCREF (save_data_func);
Py_XINCREF (factory_data);
data = g_new0 (CommandFactoryData, 1);
data->func = factory_func;
data = g_new0 (CommandTypeData, 1);
data->factory_func = factory_func;
data->create_widget_func = create_widget_func;
data->load_data_func = load_data_func;
data->save_data_func = save_data_func;
data->data = factory_data;
moo_command_register (type, command_factory_func, data,
(GDestroyNotify) command_factory_data_free);
moo_command_type_register (type, name,
command_factory_func,
command_create_widget,
command_load_data,
command_save_data,
data,
(GDestroyNotify) command_type_data_free);
return_None;
}
%%
override moo_command_type_registered kwargs
static PyObject *
_wrap_moo_command_type_registered (G_GNUC_UNUSED PyObject *self, PyObject *args, PyObject *kwargs)
{
static char *kwlist[] = { (char*) "type", NULL };
char *type;
int ret;
if (!PyArg_ParseTupleAndKeywords (args, kwargs,(char*) "s:command_type_registered", kwlist, &type))
return NULL;
ret = moo_command_type_lookup (type) != NULL;
return PyBool_FromLong (ret);
}