[glade] GladeCommand/GladeEditorProperty: Make the enabled state of a property undoable.



commit 8b98bc217b60f7f7fd39d2c3a4fa4cca7a01e626
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date:   Thu Apr 11 15:49:42 2013 +0900

    GladeCommand/GladeEditorProperty: Make the enabled state of a property undoable.
    
    Now that the enabled state of a property causes Glade's xml output to change,
    it must absolutely be undoable (enabled optional properties are saved regardless
    of default value).

 gladeui/glade-command.c         |  177 +++++++++++++++++++++++++++++++++++++++
 gladeui/glade-command.h         |   11 ++-
 gladeui/glade-editor-property.c |   19 ++--
 plugins/gtk+/glade-fixed.c      |    8 ++-
 4 files changed, 201 insertions(+), 14 deletions(-)
---
diff --git a/gladeui/glade-command.c b/gladeui/glade-command.c
index 387ea79..8920176 100644
--- a/gladeui/glade-command.c
+++ b/gladeui/glade-command.c
@@ -352,6 +352,183 @@ glade_command_check_group (GladeCommand *cmd)
     }
 }
 
+
+/****************************************************/
+/*******  GLADE_COMMAND_PROPERTY_ENABLED      *******/
+/****************************************************/
+typedef struct
+{
+  GladeCommand parent;
+  GladeProperty *property;
+  gboolean old_enabled;
+  gboolean new_enabled;
+} GladeCommandPropertyEnabled;
+
+/* standard macros */
+GLADE_MAKE_COMMAND (GladeCommandPropertyEnabled, glade_command_property_enabled);
+#define GLADE_COMMAND_PROPERTY_ENABLED_TYPE       (glade_command_property_enabled_get_type ())
+#define GLADE_COMMAND_PROPERTY_ENABLED(o)        (G_TYPE_CHECK_INSTANCE_CAST \
+                                                  ((o), GLADE_COMMAND_PROPERTY_ENABLED_TYPE, \
+                                                   GladeCommandPropertyEnabled))
+#define GLADE_COMMAND_PROPERTY_ENABLED_CLASS(k)          (G_TYPE_CHECK_CLASS_CAST \
+                                                  ((k), GLADE_COMMAND_PROPERTY_ENABLED_TYPE, \
+                                                   GladeCommandPropertyEnabledClass))
+#define GLADE_IS_COMMAND_PROPERTY_ENABLED(o)      (G_TYPE_CHECK_INSTANCE_TYPE ((o), 
GLADE_COMMAND_PROPERTY_ENABLED_TYPE))
+#define GLADE_IS_COMMAND_PROPERTY_ENABLED_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), 
GLADE_COMMAND_PROPERTY_ENABLED_TYPE))
+
+
+static gboolean
+glade_command_property_enabled_execute (GladeCommand *cmd)
+{
+  GladeCommandPropertyEnabled *me = GLADE_COMMAND_PROPERTY_ENABLED (cmd);
+
+  glade_property_set_enabled (me->property, me->new_enabled);
+
+  return TRUE;
+}
+
+static gboolean
+glade_command_property_enabled_undo (GladeCommand *cmd)
+{
+  GladeCommandPropertyEnabled *me = GLADE_COMMAND_PROPERTY_ENABLED (cmd);
+
+  glade_property_set_enabled (me->property, me->old_enabled);
+
+  return TRUE;
+}
+
+static void
+glade_command_property_enabled_finalize (GObject *obj)
+{
+  GladeCommandPropertyEnabled *me;
+
+  g_return_if_fail (GLADE_IS_COMMAND_PROPERTY_ENABLED (obj));
+
+  me = GLADE_COMMAND_PROPERTY_ENABLED (obj);
+
+  g_object_unref (me->property);
+  glade_command_finalize (obj);
+}
+
+static gboolean
+glade_command_property_enabled_unifies (GladeCommand *this_cmd, GladeCommand *other_cmd)
+{
+  GladeCommandPropertyEnabled *cmd1;
+  GladeCommandPropertyEnabled *cmd2;
+
+  if (!other_cmd)
+    {
+      if (GLADE_IS_COMMAND_PROPERTY_ENABLED (this_cmd))
+        {
+          cmd1 = (GladeCommandPropertyEnabled *) this_cmd;
+
+         return (cmd1->old_enabled == cmd1->new_enabled);
+        }
+      return FALSE;
+    }
+
+  if (GLADE_IS_COMMAND_PROPERTY_ENABLED (this_cmd) &&
+      GLADE_IS_COMMAND_PROPERTY_ENABLED (other_cmd))
+    {
+      cmd1 = GLADE_COMMAND_PROPERTY_ENABLED (this_cmd);
+      cmd2 = GLADE_COMMAND_PROPERTY_ENABLED (other_cmd);
+
+      return (cmd1->property == cmd2->property);
+    }
+
+  return FALSE;
+}
+
+static void
+glade_command_property_enabled_collapse (GladeCommand *this_cmd,
+                                        GladeCommand *other_cmd)
+{
+  GladeCommandPropertyEnabled *this = GLADE_COMMAND_PROPERTY_ENABLED (this_cmd);
+  GladeCommandPropertyEnabled *other = GLADE_COMMAND_PROPERTY_ENABLED (other_cmd);
+  GladeWidget *widget;
+  GladePropertyClass *pclass;
+
+  this->new_enabled = other->new_enabled;
+
+  widget = glade_property_get_widget (this->property);
+  pclass = glade_property_get_class (this->property);
+
+  g_free (this_cmd->priv->description);
+  if (this->new_enabled)
+    this_cmd->priv->description =
+      g_strdup_printf (_("Enabling property %s on widget %s"),
+                      glade_property_class_get_name (pclass),
+                      glade_widget_get_name (widget));
+  else
+    this_cmd->priv->description =
+      g_strdup_printf (_("Disabling property %s on widget %s"),
+                      glade_property_class_get_name (pclass),
+                      glade_widget_get_name (widget));
+}
+
+/**
+ * glade_command_set_property_enabled:
+ * @property: An optional #GladeProperty
+ * @enabled: Whether the property should be enabled
+ *
+ * Enables or disables @property.
+ *
+ * @property must be an optional property.
+ */
+void
+glade_command_set_property_enabled (GladeProperty *property,
+                                   gboolean       enabled)
+{
+  GladeCommandPropertyEnabled *me;
+  GladeCommand *cmd;
+  GladeWidget *widget;
+  GladePropertyClass *pclass;
+  gboolean old_enabled;
+
+  /* Sanity checks */
+  g_return_if_fail (GLADE_IS_PROPERTY (property));
+
+  widget = glade_property_get_widget (property);
+  g_return_if_fail (GLADE_IS_WIDGET (widget));
+
+  /* Only applies to optional properties */
+  pclass = glade_property_get_class (property);
+  g_return_if_fail (glade_property_class_optional (pclass));
+
+  /* Fetch current state */
+  old_enabled = glade_property_get_enabled (property);
+
+  /* Avoid useless command */
+  if (old_enabled == enabled)
+    return;
+
+  me = g_object_new (GLADE_COMMAND_PROPERTY_ENABLED_TYPE, NULL);
+  cmd = GLADE_COMMAND (me);
+  cmd->priv->project = glade_widget_get_project (widget);
+
+  me->property = g_object_ref (property);
+  me->new_enabled = enabled;
+  me->old_enabled = old_enabled;
+
+  if (enabled)
+    cmd->priv->description =
+      g_strdup_printf (_("Enabling property %s on widget %s"),
+                      glade_property_class_get_name (pclass),
+                      glade_widget_get_name (widget));
+  else
+    cmd->priv->description =
+      g_strdup_printf (_("Disabling property %s on widget %s"),
+                      glade_property_class_get_name (pclass),
+                      glade_widget_get_name (widget));
+
+  glade_command_check_group (GLADE_COMMAND (me));
+
+  if (glade_command_property_enabled_execute (GLADE_COMMAND (me)))
+    glade_project_push_undo (cmd->priv->project, cmd);
+  else
+    g_object_unref (G_OBJECT (me));
+}
+
 /**************************************************/
 /*******     GLADE_COMMAND_SET_PROPERTY     *******/
 /**************************************************/
diff --git a/gladeui/glade-command.h b/gladeui/glade-command.h
index ddae77b..8fb6705 100644
--- a/gladeui/glade-command.h
+++ b/gladeui/glade-command.h
@@ -93,14 +93,17 @@ void           glade_command_set_project_template(GladeProject *project,
 
 /************************** properties *********************************/
 
-void           glade_command_set_property        (GladeProperty *property,     
+void           glade_command_set_property_enabled(GladeProperty *property,
+                                                 gboolean       enabled);
+
+void           glade_command_set_property        (GladeProperty *property,
                                                  ...);
 
-void           glade_command_set_property_value  (GladeProperty *property,     
+void           glade_command_set_property_value  (GladeProperty *property,
                                                  const GValue  *value);
 
-void           glade_command_set_properties      (GladeProperty *property, 
-                                                 const GValue  *old_value, 
+void           glade_command_set_properties      (GladeProperty *property,
+                                                 const GValue  *old_value,
                                                  const GValue  *new_value,
                                                  ...);
 
diff --git a/gladeui/glade-editor-property.c b/gladeui/glade-editor-property.c
index b362a4b..5956ecb 100644
--- a/gladeui/glade-editor-property.c
+++ b/gladeui/glade-editor-property.c
@@ -271,6 +271,14 @@ glade_editor_property_state_cb (GladeProperty *property,
 }
 
 static void
+glade_editor_property_enabled_toggled_cb (GtkWidget *check,
+                                          GladeEditorProperty *eprop)
+{
+  glade_command_set_property_enabled (eprop->priv->property,
+                                     gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check)));
+}
+
+static void
 glade_editor_property_enabled_cb (GladeProperty *property,
                                   GParamSpec *pspec,
                                   GladeEditorProperty *eprop)
@@ -289,19 +297,12 @@ glade_editor_property_enabled_cb (GladeProperty *property,
                (glade_property_get_state (property) & GLADE_STATE_SUPPORT_DISABLED) != 0)
         gtk_widget_set_sensitive (eprop->priv->input, TRUE);
 
+      g_signal_handlers_block_by_func (eprop->priv->check, glade_editor_property_enabled_toggled_cb, eprop);
       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (eprop->priv->check), enabled);
+      g_signal_handlers_unblock_by_func (eprop->priv->check, glade_editor_property_enabled_toggled_cb, 
eprop);
     }
 }
 
-static void
-glade_editor_property_enabled_toggled_cb (GtkWidget *check,
-                                          GladeEditorProperty *eprop)
-{
-  glade_property_set_enabled (eprop->priv->property,
-                              gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
-                                                            (check)));
-}
-
 static gboolean
 glade_editor_property_button_pressed (GtkWidget *widget,
                                       GdkEventButton *event,
diff --git a/plugins/gtk+/glade-fixed.c b/plugins/gtk+/glade-fixed.c
index 03a6742..e38a596 100644
--- a/plugins/gtk+/glade-fixed.c
+++ b/plugins/gtk+/glade-fixed.c
@@ -562,7 +562,13 @@ glade_fixed_configure_child_impl (GladeFixed *fixed,
                                   GladeWidget *child,
                                   GdkRectangle *rect)
 {
-  /* Make sure we can modify these properties */
+  /* Make sure we can modify these properties
+   *
+   * FIXME: This is inappropriate how that enabled state of properties
+   * is undoable... instead there should be some adaptor hooks to allow
+   * adding commands to the command group which adds a child to
+   * the given widget... where we can undoably override this.
+   */
   glade_widget_pack_property_set_enabled (child, fixed->x_prop, TRUE);
   glade_widget_pack_property_set_enabled (child, fixed->y_prop, TRUE);
   glade_widget_property_set_enabled (child, fixed->width_prop, TRUE);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]