MooUndoOps for MooTextView and MooEntry

master
Yevgen Muntyan 2008-05-07 14:46:08 -05:00
parent 8c65b775fa
commit b456e3324c
3 changed files with 109 additions and 21 deletions

View File

@ -24,6 +24,7 @@
#include "marshals.h"
#include "mooutils/mooutils-misc.h"
#include "mooutils/mooundo.h"
#include "mooutils/mooeditops.h"
#include "mooutils/mooentry.h"
#include "mooutils/mooi18n.h"
#include <gtk/gtk.h>
@ -52,6 +53,7 @@ static const GtkTargetEntry text_view_target_table[] = {
static GdkAtom moo_text_view_atom;
static void undo_ops_iface_init (MooUndoOpsIface *iface);
static GObject *moo_text_view_constructor (GType type,
guint n_construct_properties,
GObjectConstructParam *construct_param);
@ -110,6 +112,8 @@ static void cursor_moved (MooTextView *view,
GtkTextIter *where);
static void proxy_prop_notify (MooTextView *view,
GParamSpec *pspec);
static void proxy_notify_can_undo_redo (MooTextView *view,
GParamSpec *pspec);
static void find_word_at_cursor (MooTextView *view,
gboolean forward);
@ -242,7 +246,8 @@ enum {
/* MOO_TYPE_TEXT_VIEW */
G_DEFINE_TYPE (MooTextView, moo_text_view, GTK_TYPE_TEXT_VIEW)
G_DEFINE_TYPE_WITH_CODE (MooTextView, moo_text_view, GTK_TYPE_TEXT_VIEW,
G_IMPLEMENT_INTERFACE (MOO_TYPE_UNDO_OPS, undo_ops_iface_init))
static void moo_text_view_class_init (MooTextViewClass *klass)
@ -740,9 +745,9 @@ moo_text_view_constructor (GType type,
undo_stack = _moo_text_buffer_get_undo_stack (get_moo_buffer (view));
g_signal_connect_swapped (undo_stack, "notify::can-undo",
G_CALLBACK (proxy_prop_notify), view);
G_CALLBACK (proxy_notify_can_undo_redo), view);
g_signal_connect_swapped (undo_stack, "notify::can-redo",
G_CALLBACK (proxy_prop_notify), view);
G_CALLBACK (proxy_notify_can_undo_redo), view);
g_signal_connect_data (get_buffer (view), "insert-text",
G_CALLBACK (insert_text_cb), view,
@ -1412,6 +1417,54 @@ proxy_prop_notify (MooTextView *view,
}
static void
undo_ops_undo (MooUndoOps *obj)
{
gboolean retval;
g_signal_emit_by_name (obj, "undo", &retval);
}
static void
undo_ops_redo (MooUndoOps *obj)
{
gboolean retval;
g_signal_emit_by_name (obj, "redo", &retval);
}
static gboolean
undo_ops_can_undo (MooUndoOps *obj)
{
return moo_text_view_can_undo (MOO_TEXT_VIEW (obj));
}
static gboolean
undo_ops_can_redo (MooUndoOps *obj)
{
return moo_text_view_can_redo (MOO_TEXT_VIEW (obj));
}
static void
undo_ops_iface_init (MooUndoOpsIface *iface)
{
iface->undo = undo_ops_undo;
iface->redo = undo_ops_redo;
iface->can_undo = undo_ops_can_undo;
iface->can_redo = undo_ops_can_redo;
}
static void
proxy_notify_can_undo_redo (MooTextView *view,
GParamSpec *pspec)
{
if (strcmp (pspec->name, "can-undo") == 0)
moo_undo_ops_can_undo_changed (G_OBJECT (view));
else
moo_undo_ops_can_redo_changed (G_OBJECT (view));
g_object_notify (G_OBJECT (view), pspec->name);
}
MooIndenter*
moo_text_view_get_indenter (MooTextView *view)
{

View File

@ -337,13 +337,13 @@ static void
moo_undo_ops_class_init (G_GNUC_UNUSED MooUndoOpsIface *iface)
{
g_signal_new ("moo-undo-ops-can-undo-changed",
MOO_TYPE_EDIT_OPS,
MOO_TYPE_UNDO_OPS,
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
_moo_marshal_VOID__VOID,
G_TYPE_NONE, 0);
g_signal_new ("moo-undo-ops-can-redo-changed",
MOO_TYPE_EDIT_OPS,
MOO_TYPE_UNDO_OPS,
G_SIGNAL_RUN_LAST,
0, NULL, NULL,
_moo_marshal_VOID__VOID,
@ -358,7 +358,7 @@ moo_undo_ops_get_type (void)
if (G_UNLIKELY (!type))
{
GTypeInfo type_info = {
sizeof (MooEditOpsIface), NULL, NULL,
sizeof (MooUndoOpsIface), NULL, NULL,
(GClassInitFunc) moo_undo_ops_class_init,
NULL
};
@ -376,13 +376,13 @@ moo_undo_ops_get_type (void)
void
moo_undo_ops_can_undo_changed (GObject *obj)
{
g_signal_emit_by_name (obj, "moo-edit-ops-can-undo-changed");
g_signal_emit_by_name (obj, "moo-undo-ops-can-undo-changed");
}
void
moo_undo_ops_can_redo_changed (GObject *obj)
{
g_signal_emit_by_name (obj, "moo-edit-ops-can-redo-changed");
g_signal_emit_by_name (obj, "moo-undo-ops-can-redo-changed");
}

View File

@ -15,6 +15,7 @@
#include "mooutils/mooentry.h"
#include "mooutils/mooundo.h"
#include "mooutils/mooutils-gobject.h"
#include "mooutils/mooeditops.h"
#include <gtk/gtkbindings.h>
#include <gtk/gtkimagemenuitem.h>
#include <gtk/gtkseparatormenuitem.h>
@ -40,6 +41,7 @@ static guint DELETE_ACTION_TYPE;
static void moo_entry_class_init (MooEntryClass *klass);
static void moo_entry_editable_init (GtkEditableClass *klass);
static void moo_entry_undo_ops_init (MooUndoOpsIface *iface);
static void moo_entry_init (MooEntry *entry);
static void moo_entry_finalize (GObject *object);
@ -112,15 +114,17 @@ moo_entry_get_type (void)
NULL
};
static const GInterfaceInfo editable_info =
{
(GInterfaceInitFunc) moo_entry_editable_init,
NULL,
NULL
static const GInterfaceInfo editable_info = {
(GInterfaceInitFunc) moo_entry_editable_init, NULL, NULL
};
static const GInterfaceInfo undo_ops_info = {
(GInterfaceInitFunc) moo_entry_undo_ops_init, NULL, NULL
};
type = g_type_register_static (GTK_TYPE_ENTRY, "MooEntry", &info, 0);
g_type_add_interface_static (type, GTK_TYPE_EDITABLE, &editable_info);
g_type_add_interface_static (type, MOO_TYPE_UNDO_OPS, &undo_ops_info);
}
return type;
@ -388,22 +392,28 @@ moo_entry_changed (GtkEditable *editable)
void
moo_entry_undo (MooEntry *entry)
moo_entry_undo (MooEntry *entry)
{
g_return_if_fail (MOO_IS_ENTRY (entry));
if (entry->priv->enable_undo && moo_undo_stack_can_undo (entry->priv->undo_stack))
moo_undo_stack_undo (entry->priv->undo_stack);
}
moo_undo_ops_can_undo_changed (G_OBJECT (entry));
moo_undo_ops_can_redo_changed (G_OBJECT (entry));
}
void
moo_entry_redo (MooEntry *entry)
moo_entry_redo (MooEntry *entry)
{
g_return_if_fail (MOO_IS_ENTRY (entry));
if (entry->priv->enable_undo && moo_undo_stack_can_redo (entry->priv->undo_stack))
moo_undo_stack_redo (entry->priv->undo_stack);
}
moo_undo_ops_can_undo_changed (G_OBJECT (entry));
moo_undo_ops_can_redo_changed (G_OBJECT (entry));
}
void
moo_entry_begin_undo_group (MooEntry *entry)
@ -412,7 +422,6 @@ moo_entry_begin_undo_group (MooEntry *entry)
moo_undo_stack_start_group (entry->priv->undo_stack);
}
void
moo_entry_end_undo_group (MooEntry *entry)
{
@ -420,7 +429,6 @@ moo_entry_end_undo_group (MooEntry *entry)
moo_undo_stack_end_group (entry->priv->undo_stack);
}
void
moo_entry_clear_undo (MooEntry *entry)
{
@ -428,6 +436,31 @@ moo_entry_clear_undo (MooEntry *entry)
moo_undo_stack_clear (entry->priv->undo_stack);
}
static gboolean
undo_ops_can_undo (MooUndoOps *obj)
{
MooEntry *entry = MOO_ENTRY (obj);
return entry->priv->enable_undo &&
moo_undo_stack_can_undo (entry->priv->undo_stack);
}
static gboolean
undo_ops_can_redo (MooUndoOps *obj)
{
MooEntry *entry = MOO_ENTRY (obj);
return entry->priv->enable_undo &&
moo_undo_stack_can_redo (entry->priv->undo_stack);
}
static void
moo_entry_undo_ops_init (MooUndoOpsIface *iface)
{
iface->undo = (void(*)(MooUndoOps*)) moo_entry_undo;
iface->redo = (void(*)(MooUndoOps*)) moo_entry_redo;
iface->can_undo = undo_ops_can_undo;
iface->can_redo = undo_ops_can_redo;
}
GtkWidget*
moo_entry_new (void)
@ -599,6 +632,7 @@ moo_entry_do_insert_text (GtkEditable *editable,
INSERT_ACTION_TYPE,
insert_action_new (editable, text, length, position));
parent_editable_iface->do_insert_text (editable, text, length, position);
moo_undo_ops_can_undo_changed (G_OBJECT (editable));
}
}
@ -626,9 +660,10 @@ moo_entry_do_delete_text (GtkEditable *editable,
if (start_pos < end_pos)
{
moo_undo_stack_add_action (MOO_ENTRY(editable)->priv->undo_stack,
DELETE_ACTION_TYPE,
delete_action_new (editable, start_pos, end_pos));
DELETE_ACTION_TYPE,
delete_action_new (editable, start_pos, end_pos));
parent_editable_iface->do_delete_text (editable, start_pos, end_pos);
moo_undo_ops_can_undo_changed (G_OBJECT (editable));
}
}