pidgin: a060cc83: Smiley insertions can be undone with thi...
sadrul at pidgin.im
sadrul at pidgin.im
Sun Apr 20 11:40:50 EDT 2008
-----------------------------------------------------------------
Revision: a060cc8315a6500f42289837501a738d109ce642
Ancestor: 35556576c8b9b3c77f9674eb5de05f1a325e2851
Author: sadrul at pidgin.im
Date: 2008-04-20T15:35:16
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/a060cc8315a6500f42289837501a738d109ce642
Modified files:
pidgin/gtkimhtml.c pidgin/gtksourceundomanager.c
ChangeLog:
Smiley insertions can be undone with this fix. References #5577. But redo
doesn't work yet.
-------------- next part --------------
============================================================
--- pidgin/gtkimhtml.c 68bfbe6c83a614dbd6f0c70f846849571c7dae1b
+++ pidgin/gtkimhtml.c 1917ef0ea282673f5f17685055709d13ea7195f1
@@ -1201,16 +1201,20 @@ static void
}
static void
-gtk_imhtml_undo(GtkIMHtml *imhtml) {
+gtk_imhtml_undo(GtkIMHtml *imhtml)
+{
g_return_if_fail(GTK_IS_IMHTML(imhtml));
- if (imhtml->editable)
+ if (imhtml->editable &&
+ gtk_source_undo_manager_can_undo(imhtml->undo_manager))
gtk_source_undo_manager_undo(imhtml->undo_manager);
}
static void
-gtk_imhtml_redo(GtkIMHtml *imhtml) {
+gtk_imhtml_redo(GtkIMHtml *imhtml)
+{
g_return_if_fail(GTK_IS_IMHTML(imhtml));
- if (imhtml->editable)
+ if (imhtml->editable &&
+ gtk_source_undo_manager_can_redo(imhtml->undo_manager))
gtk_source_undo_manager_redo(imhtml->undo_manager);
}
@@ -2425,6 +2429,7 @@ void gtk_imhtml_insert_html_at_iter(GtkI
ws = g_malloc(len + 1);
ws[0] = 0;
+ gtk_text_buffer_begin_user_action(imhtml->text_buffer);
while (pos < len) {
if (*c == '<' && gtk_imhtml_is_tag (c + 1, &tag, &tlen, &type)) {
c++;
@@ -3153,6 +3158,7 @@ void gtk_imhtml_insert_html_at_iter(GtkI
g_signal_emit(object, signals[UPDATE_FORMAT], 0);
g_object_unref(object);
+ gtk_text_buffer_end_user_action(imhtml->text_buffer);
}
void gtk_imhtml_remove_smileys(GtkIMHtml *imhtml)
============================================================
--- pidgin/gtksourceundomanager.c d884207163126f125bd060de5b2e00d133a44d95
+++ pidgin/gtksourceundomanager.c 69772385ac890e4914040019da83eedc6f4835d8
@@ -41,10 +41,12 @@ typedef struct _GtkSourceUndoDeleteActio
typedef struct _GtkSourceUndoAction GtkSourceUndoAction;
typedef struct _GtkSourceUndoInsertAction GtkSourceUndoInsertAction;
typedef struct _GtkSourceUndoDeleteAction GtkSourceUndoDeleteAction;
+typedef struct _GtkSourceUndoInsertAnchorAction GtkSourceUndoInsertAnchorAction;
typedef enum {
GTK_SOURCE_UNDO_ACTION_INSERT,
- GTK_SOURCE_UNDO_ACTION_DELETE
+ GTK_SOURCE_UNDO_ACTION_DELETE,
+ GTK_SOURCE_UNDO_ACTION_INSERT_ANCHOR,
} GtkSourceUndoActionType;
/*
@@ -68,6 +70,12 @@ struct _GtkSourceUndoDeleteAction
gboolean forward;
};
+struct _GtkSourceUndoInsertAnchorAction
+{
+ gint pos;
+ GtkTextChildAnchor *anchor;
+};
+
struct _GtkSourceUndoAction
{
GtkSourceUndoActionType action_type;
@@ -75,6 +83,7 @@ struct _GtkSourceUndoAction
union {
GtkSourceUndoInsertAction insert;
GtkSourceUndoDeleteAction delete;
+ GtkSourceUndoInsertAnchorAction insert_anchor;
} action;
gint order_in_group;
@@ -139,6 +148,10 @@ static void gtk_source_undo_manager_inse
const gchar *text,
gint length,
GtkSourceUndoManager *um);
+static void gtk_source_undo_manager_insert_anchor_handler (GtkTextBuffer *buffer,
+ GtkTextIter *pos,
+ GtkTextChildAnchor *anchor,
+ GtkSourceUndoManager *um);
static void gtk_source_undo_manager_delete_range_handler (GtkTextBuffer *buffer,
GtkTextIter *start,
GtkTextIter *end,
@@ -275,6 +288,10 @@ gtk_source_undo_manager_finalize (GObjec
um);
g_signal_handlers_disconnect_by_func (G_OBJECT (um->priv->document),
+ G_CALLBACK (gtk_source_undo_manager_insert_anchor_handler),
+ um);
+
+ g_signal_handlers_disconnect_by_func (G_OBJECT (um->priv->document),
G_CALLBACK (gtk_source_undo_manager_begin_user_action_handler),
um);
@@ -297,6 +314,10 @@ gtk_source_undo_manager_new (GtkTextBuff
G_CALLBACK (gtk_source_undo_manager_insert_text_handler),
um);
+ g_signal_connect (G_OBJECT (buffer), "insert_child_anchor",
+ G_CALLBACK (gtk_source_undo_manager_insert_anchor_handler),
+ um);
+
g_signal_connect (G_OBJECT (buffer), "delete_range",
G_CALLBACK (gtk_source_undo_manager_delete_range_handler),
um);
@@ -403,6 +424,15 @@ static void
}
static void
+insert_anchor (GtkTextBuffer *buffer, gint pos, GtkTextChildAnchor *anchor)
+{
+ GtkTextIter iter;
+
+ gtk_text_buffer_get_iter_at_offset (buffer, &iter, pos);
+ gtk_text_buffer_insert_child_anchor (buffer, &iter, anchor);
+}
+
+static void
delete_text (GtkTextBuffer *buffer, gint start, gint end)
{
GtkTextIter start_iter;
@@ -497,6 +527,13 @@ gtk_source_undo_manager_undo (GtkSourceU
undo_action->action.insert.pos);
break;
+ case GTK_SOURCE_UNDO_ACTION_INSERT_ANCHOR:
+ delete_text (
+ um->priv->document,
+ undo_action->action.insert_anchor.pos,
+ undo_action->action.insert_anchor.pos + 1);
+ undo_action->action.insert_anchor.anchor->segment = NULL; /* XXX: This may be a bug in GTK+ */
+ break;
default:
/* Unknown action type. */
g_return_if_reached ();
@@ -588,6 +625,17 @@ gtk_source_undo_manager_redo (GtkSourceU
break;
+ case GTK_SOURCE_UNDO_ACTION_INSERT_ANCHOR:
+ set_cursor (
+ um->priv->document,
+ undo_action->action.insert_anchor.pos);
+
+ insert_anchor (
+ um->priv->document,
+ undo_action->action.insert_anchor.pos,
+ undo_action->action.insert_anchor.anchor);
+ break;
+
default:
/* Unknown action type */
++um->priv->next_redo;
@@ -633,6 +681,8 @@ gtk_source_undo_action_free (GtkSourceUn
g_free (action->action.insert.text);
else if (action->action_type == GTK_SOURCE_UNDO_ACTION_DELETE)
g_free (action->action.delete.text);
+ else if (action->action_type == GTK_SOURCE_UNDO_ACTION_INSERT_ANCHOR)
+ g_object_unref(action->action.insert_anchor.anchor);
else
g_return_if_reached ();
@@ -695,6 +745,27 @@ gtk_source_undo_manager_insert_text_hand
gtk_source_undo_manager_add_action (um, &undo_action);
}
+static void gtk_source_undo_manager_insert_anchor_handler (GtkTextBuffer *buffer,
+ GtkTextIter *pos,
+ GtkTextChildAnchor *anchor,
+ GtkSourceUndoManager *um)
+{
+ GtkSourceUndoAction undo_action;
+
+ if (um->priv->running_not_undoable_actions > 0)
+ return;
+
+ undo_action.action_type = GTK_SOURCE_UNDO_ACTION_INSERT_ANCHOR;
+
+ undo_action.action.insert_anchor.pos = gtk_text_iter_get_offset (pos);
+ undo_action.action.insert_anchor.anchor = g_object_ref (anchor);
+
+ undo_action.mergeable = FALSE;
+ undo_action.modified = FALSE;
+
+ gtk_source_undo_manager_add_action (um, &undo_action);
+}
+
static void
gtk_source_undo_manager_delete_range_handler (GtkTextBuffer *buffer,
GtkTextIter *start,
@@ -775,6 +846,10 @@ gtk_source_undo_manager_add_action (GtkS
action->action.insert.text = g_strndup (undo_action->action.insert.text, undo_action->action.insert.length);
else if (action->action_type == GTK_SOURCE_UNDO_ACTION_DELETE)
action->action.delete.text = g_strdup (undo_action->action.delete.text);
+ else if (action->action_type == GTK_SOURCE_UNDO_ACTION_INSERT_ANCHOR)
+ {
+ /* Nothing needs to be done */
+ }
else
{
g_free (action);
@@ -998,6 +1073,10 @@ gtk_source_undo_manager_merge_action (Gt
last_action->action.insert.chars += undo_action->action.insert.chars;
}
+ else if (undo_action->action_type == GTK_SOURCE_UNDO_ACTION_INSERT_ANCHOR)
+ {
+ /* Nothing needs to be done */
+ }
else
/* Unknown action inside undo merge encountered */
g_return_val_if_reached (TRUE);
More information about the Commits
mailing list