[gtk/wip/otte/undo: 14/17] undo: Turn describe() vfunc into "title" property
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/undo: 14/17] undo: Turn describe() vfunc into "title" property
- Date: Mon, 18 Feb 2019 17:13:35 +0000 (UTC)
commit 716878cc90c65129fedf590e6ea75ccf70ea3e31
Author: Benjamin Otte <otte redhat com>
Date: Wed Aug 19 19:27:50 2015 +0200
undo: Turn describe() vfunc into "title" property
This way, applications can override the title to make it more useful.
gtk/gtkentryundocommand.c | 122 +++++++++++++++++++++++---------------------
gtk/gtkundocommand.c | 99 +++++++++++++++++++++++++++++------
gtk/gtkundocommandprivate.h | 6 +--
gtk/gtkundostack.c | 4 +-
gtk/gtkundoundocommand.c | 14 ++---
5 files changed, 155 insertions(+), 90 deletions(-)
---
diff --git a/gtk/gtkentryundocommand.c b/gtk/gtkentryundocommand.c
index eefc78ce22..c88570caa9 100644
--- a/gtk/gtkentryundocommand.c
+++ b/gtk/gtkentryundocommand.c
@@ -103,6 +103,64 @@ gtk_entry_undo_command_redo (GtkUndoCommand *command)
return gtk_entry_undo_command_run (priv->entry, &priv->after);
}
+static guint
+get_prefix_len (const char *str1,
+ const char *str2)
+{
+ guint i;
+
+ for (i = 0; str1[i] == str2[i] && str1[i] != 0; i++)
+ {
+ /* nothing to do here */
+ }
+
+ return i;
+}
+
+static guint
+get_suffix_len (const char *str1,
+ guint len1,
+ const char *str2,
+ guint len2)
+{
+ const char *cur1, *cur2;
+ guint i, max_len;
+
+ cur1 = str1 + len1 - 1;
+ cur2 = str2 + len2 - 1;
+ max_len = MIN (len1, len2);
+
+ for (i = 0; *cur1 == *cur2 && i < max_len; i++)
+ {
+ cur1--;
+ cur2--;
+ }
+
+ return i;
+}
+
+char *
+generate_title (const GtkEntrySnapshot *before,
+ const GtkEntrySnapshot *after)
+{
+ guint before_len, after_len, prefix_len, suffix_len;
+
+ before_len = strlen (before->text);
+ after_len = strlen (after->text);
+ prefix_len = get_prefix_len (before->text, after->text);
+ suffix_len = get_suffix_len (before->text, before_len,
+ after->text, after_len);
+
+ if (before_len == after_len && before_len == prefix_len)
+ return g_strdup (_("No changes")); /* huh? */
+ else if (prefix_len + suffix_len == before_len)
+ return g_strdup_printf (_("Entered `%.*s'"), after_len - prefix_len - suffix_len, after->text +
prefix_len);
+ else if (prefix_len + suffix_len == after_len)
+ return g_strdup_printf (_("Deleted `%.*s'"), before_len - prefix_len - suffix_len, before->text +
prefix_len);
+ else
+ return g_strdup (_("Text changed"));
+}
+
static GtkUndoCommand *
gtk_entry_undo_command_new_from_snapshots (GtkEntry *entry,
gint64 timestamp,
@@ -111,11 +169,16 @@ gtk_entry_undo_command_new_from_snapshots (GtkEntry *entry,
{
GtkEntryUndoCommand *command;
GtkEntryUndoCommandPrivate *priv;
+ char *title;
+
+ title = generate_title (before, after);
command = g_object_new (GTK_TYPE_ENTRY_UNDO_COMMAND,
"timestamp", timestamp,
+ "title", title,
NULL);
priv = gtk_entry_undo_command_get_instance_private (command);
+ g_free (title);
priv->entry = entry;
gtk_entry_snapshot_copy (&priv->before, before);
@@ -167,64 +230,6 @@ gtk_entry_undo_command_should_merge (GtkUndoCommand *command,
return TRUE;
}
-static guint
-get_prefix_len (const char *str1,
- const char *str2)
-{
- guint i;
-
- for (i = 0; str1[i] == str2[i] && str1[i] != 0; i++)
- {
- /* nothing to do here */
- }
-
- return i;
-}
-
-static guint
-get_suffix_len (const char *str1,
- guint len1,
- const char *str2,
- guint len2)
-{
- const char *cur1, *cur2;
- guint i, max_len;
-
- cur1 = str1 + len1 - 1;
- cur2 = str2 + len2 - 1;
- max_len = MIN (len1, len2);
-
- for (i = 0; *cur1 == *cur2 && i < max_len; i++)
- {
- cur1--;
- cur2--;
- }
-
- return i;
-}
-
-char *
-gtk_entry_undo_command_describe (GtkUndoCommand *command)
-{
- GtkEntryUndoCommandPrivate *priv = gtk_entry_undo_command_get_instance_private (GTK_ENTRY_UNDO_COMMAND
(command));
- guint before_len, after_len, prefix_len, suffix_len;
-
- before_len = strlen (priv->before.text);
- after_len = strlen (priv->after.text);
- prefix_len = get_prefix_len (priv->before.text, priv->after.text);
- suffix_len = get_suffix_len (priv->before.text, before_len,
- priv->after.text, after_len);
-
- if (before_len == after_len && before_len == prefix_len)
- return g_strdup (_("No changes")); /* huh? */
- else if (prefix_len + suffix_len == before_len)
- return g_strdup_printf (_("Entered `%.*s'"), after_len - prefix_len - suffix_len, priv->after.text +
prefix_len);
- else if (prefix_len + suffix_len == after_len)
- return g_strdup_printf (_("Deleted `%.*s'"), before_len - prefix_len - suffix_len, priv->before.text +
prefix_len);
- else
- return g_strdup (_("Text changed"));
-}
-
static void
gtk_entry_undo_command_finalize (GObject *object)
{
@@ -248,7 +253,6 @@ gtk_entry_undo_command_class_init (GtkEntryUndoCommandClass *klass)
undo_class->redo = gtk_entry_undo_command_redo;
undo_class->merge = gtk_entry_undo_command_merge;
undo_class->should_merge = gtk_entry_undo_command_should_merge;
- undo_class->describe = gtk_entry_undo_command_describe;
}
static void
diff --git a/gtk/gtkundocommand.c b/gtk/gtkundocommand.c
index bbc60efabf..b7fc36683d 100644
--- a/gtk/gtkundocommand.c
+++ b/gtk/gtkundocommand.c
@@ -26,11 +26,13 @@
typedef struct _GtkUndoCommandPrivate GtkUndoCommandPrivate;
struct _GtkUndoCommandPrivate {
gint64 timestamp;
+ char *title;
};
enum {
PROP_0,
PROP_TIMESTAMP,
+ PROP_TITLE,
/* add more */
NUM_PROPERTIES
};
@@ -54,6 +56,10 @@ gtk_undo_command_get_property (GObject *object,
g_value_set_int64 (value, priv->timestamp);
break;
+ case PROP_TITLE:
+ g_value_set_string (value, priv->title);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
@@ -65,7 +71,8 @@ gtk_undo_command_set_property (GObject *object,
const GValue *value,
GParamSpec *pspec)
{
- GtkUndoCommandPrivate *priv = gtk_undo_command_get_instance_private (GTK_UNDO_COMMAND (object));
+ GtkUndoCommand *command = GTK_UNDO_COMMAND (object);
+ GtkUndoCommandPrivate *priv = gtk_undo_command_get_instance_private (command);
switch (property_id)
{
@@ -75,11 +82,25 @@ gtk_undo_command_set_property (GObject *object,
priv->timestamp = g_get_real_time ();
break;
+ case PROP_TITLE:
+ gtk_undo_command_set_title (command, g_value_get_string (value));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
}
+static void
+gtk_undo_command_finalize (GObject *object)
+{
+ GtkUndoCommandPrivate *priv = gtk_undo_command_get_instance_private (GTK_UNDO_COMMAND (object));
+
+ g_free (priv->title);
+
+ G_OBJECT_CLASS (gtk_undo_command_parent_class)->finalize (object);
+}
+
static gboolean
gtk_undo_command_real_undo (GtkUndoCommand *command)
{
@@ -116,17 +137,6 @@ gtk_undo_command_real_should_merge (GtkUndoCommand *command,
return TRUE;
}
-char *
-gtk_undo_command_real_describe (GtkUndoCommand *command)
-{
- g_warning ("%s class failed to implement undo", G_OBJECT_TYPE_NAME (command));
-
- /* translators: This string is the fallback message that gets used
- * when undo commands are improperly implemented and don't have a
- * proper description. */
- return g_strdup (_("unknown undo command"));
-}
-
static void
gtk_undo_command_class_init (GtkUndoCommandClass *klass)
{
@@ -134,12 +144,12 @@ gtk_undo_command_class_init (GtkUndoCommandClass *klass)
object_class->set_property = gtk_undo_command_set_property;
object_class->get_property = gtk_undo_command_get_property;
+ object_class->finalize = gtk_undo_command_finalize;
klass->undo = gtk_undo_command_real_undo;
klass->redo = gtk_undo_command_real_redo;
klass->merge = gtk_undo_command_real_merge;
klass->should_merge = gtk_undo_command_real_should_merge;
- klass->describe = gtk_undo_command_real_describe;
/*
* GtkUndoCommand:timestamp:
@@ -153,6 +163,18 @@ gtk_undo_command_class_init (GtkUndoCommandClass *klass)
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+ /*
+ * GtkUndoCommand:title:
+ *
+ * Title of this command. See
+ * gtk_undo_command_get_title() for details.
+ */
+ properties[PROP_TITLE] = g_param_spec_string ("title", "Title",
+ "Title of this command",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
+ G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+
g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
}
@@ -209,12 +231,57 @@ gtk_undo_command_should_merge (GtkUndoCommand *command,
return GTK_UNDO_COMMAND_GET_CLASS (command)->should_merge (command, followup_command);
}
-char *
-gtk_undo_command_describe (GtkUndoCommand *command)
+/*
+ * gtk_undo_command_get_title:
+ * @command: The command
+ *
+ * Gets the title of the @command. The title is a translated string
+ * for presentation in a user interface, for example a list of actions
+ * to undo.
+ *
+ * Undo commands always have a title set, but that title is often generic.
+ * Applications may want to update titles via gtk_undo_command_set_title()
+ *
+ * Returns: The title for the command
+ */
+const char *
+gtk_undo_command_get_title (GtkUndoCommand *command)
{
+ GtkUndoCommandPrivate *priv = gtk_undo_command_get_instance_private (command);
+
g_return_val_if_fail (GTK_IS_UNDO_COMMAND (command), NULL);
- return GTK_UNDO_COMMAND_GET_CLASS (command)->describe (command);
+ return priv->title;
+}
+
+/*
+ * gtk_undo_command_set_title:
+ * @command: The command
+ * @title: The new title
+ *
+ * Updates the title for the given @command. This function should be called
+ * when applications can provide a better title for an action than the generic
+ * title provided upon creation of commands.
+ */
+void
+gtk_undo_command_set_title (GtkUndoCommand *command,
+ const char *title)
+{
+ GtkUndoCommandPrivate *priv = gtk_undo_command_get_instance_private (command);
+
+ g_return_if_fail (GTK_IS_UNDO_COMMAND (command));
+
+ if (title == NULL)
+ /* translators: This is the (hopefully never used) fallback string for undo commands without a name */
+ title = _("Unknown command");
+
+ if (g_strcmp0 (priv->title, title) == 0)
+ return;
+
+ g_free (priv->title);
+ priv->title = g_strdup (title);
+
+ g_object_notify_by_pspec (G_OBJECT (command), properties[PROP_TITLE]);
}
/*
diff --git a/gtk/gtkundocommandprivate.h b/gtk/gtkundocommandprivate.h
index bfe982e47a..f5d00002d2 100644
--- a/gtk/gtkundocommandprivate.h
+++ b/gtk/gtkundocommandprivate.h
@@ -53,13 +53,14 @@ struct _GtkUndoCommandClass
/* should the two commands be merged for user undo purposes? */
gboolean (* should_merge) (GtkUndoCommand *command,
GtkUndoCommand *followup_command);
- /* get a translated string describing the command */
- char * (* describe) (GtkUndoCommand *command);
};
GType gtk_undo_command_get_type (void) G_GNUC_CONST;
gint64 gtk_undo_command_get_timestamp (GtkUndoCommand *command);
+const char * gtk_undo_command_get_title (GtkUndoCommand *command);
+void gtk_undo_command_set_title (GtkUndoCommand *command,
+ const char *title);
gboolean gtk_undo_command_undo (GtkUndoCommand *command);
gboolean gtk_undo_command_redo (GtkUndoCommand *command);
@@ -67,7 +68,6 @@ GtkUndoCommand * gtk_undo_command_merge (GtkUndoCommand
GtkUndoCommand *followup_command);
gboolean gtk_undo_command_should_merge (GtkUndoCommand *command,
GtkUndoCommand *followup_command);
-char * gtk_undo_command_describe (GtkUndoCommand *command);
G_END_DECLS
diff --git a/gtk/gtkundostack.c b/gtk/gtkundostack.c
index d977b1799d..5dea553ab9 100644
--- a/gtk/gtkundostack.c
+++ b/gtk/gtkundostack.c
@@ -147,10 +147,8 @@ gtk_undo_stack_dump (GtkUndoStack *stack)
iter = g_sequence_iter_next (iter))
{
GtkUndoCommand *command = g_sequence_get (iter);
- char *desc;
- desc = gtk_undo_command_describe (command);
- g_print (" %s\n", desc);
+ g_print (" %s\n", gtk_undo_command_get_title (command));
}
}
diff --git a/gtk/gtkundoundocommand.c b/gtk/gtkundoundocommand.c
index 0c119c9d0b..17aa3907e6 100644
--- a/gtk/gtkundoundocommand.c
+++ b/gtk/gtkundoundocommand.c
@@ -77,14 +77,6 @@ gtk_undo_undo_command_merge (GtkUndoCommand *command,
return NULL;
}
-char *
-gtk_undo_undo_command_describe (GtkUndoCommand *command)
-{
- GtkUndoUndoCommandPrivate *priv = gtk_undo_undo_command_get_instance_private (GTK_UNDO_UNDO_COMMAND
(command));
-
- return g_strdup_printf (_("Undo last %u commands"), g_sequence_get_length (priv->commands));
-}
-
static void
gtk_undo_undo_command_finalize (GObject *object)
{
@@ -106,7 +98,6 @@ gtk_undo_undo_command_class_init (GtkUndoUndoCommandClass *klass)
undo_class->undo = gtk_undo_undo_command_undo;
undo_class->redo = gtk_undo_undo_command_redo;
undo_class->merge = gtk_undo_undo_command_merge;
- undo_class->describe = gtk_undo_undo_command_describe;
}
static void
@@ -124,6 +115,7 @@ gtk_undo_undo_command_new (GSequenceIter *begin_iter,
GtkUndoUndoCommand *result;
GtkUndoUndoCommandPrivate *priv;
GSequenceIter *iter;
+ char *title;
g_return_val_if_fail (begin_iter != NULL, NULL);
g_return_val_if_fail (end_iter != NULL, NULL);
@@ -136,6 +128,10 @@ gtk_undo_undo_command_new (GSequenceIter *begin_iter,
g_sequence_prepend (priv->commands, g_object_ref (g_sequence_get (iter)));
}
+ title = g_strdup_printf (_("Undo last %u commands"), g_sequence_get_length (priv->commands));
+ gtk_undo_command_set_title (GTK_UNDO_COMMAND (result), title);
+ g_free (title);
+
return GTK_UNDO_COMMAND (result);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]