]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkactivatable.c
filechooserbutton: Don't duplicate tests for GTK_RESPONSE_DELETE_EVENT
[~andy/gtk] / gtk / gtkactivatable.c
index 5f7252d2b55e60d801433b492f9b40b601db0186..46ffa1bd2f2384eca82a1cc538dd18246f1be10a 100644 (file)
  * Library General Public License for more details.
  *
  * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  */
 
 /**
- * SECTION:gtk-activatable
- * @Short_Description: An interface for activatable widgets.
+ * SECTION:gtkactivatable
+ * @Short_Description: An interface for activatable widgets
+ * @Title: GtkActivatable
  *
  * Activatable widgets can be connected to a #GtkAction and reflects
- * the state of its action - a #GtkActivatable can also provide feedback
- * through its action, as they are responsible for activating their 
+ * the state of its action. A #GtkActivatable can also provide feedback
+ * through its action, as they are responsible for activating their
  * related actions.
  *
  * <refsect2>
  * <title>Implementing GtkActivatable</title>
  * <para>
  * When extending a class that is already #GtkActivatable; it is only
- * necessary to implement the #GtkActivatable->reset() and #GtkActivatable->update()
- * methods and chain up to the parent implementation, however when introducing
+ * necessary to implement the #GtkActivatable->sync_action_properties()
+ * and #GtkActivatable->update() methods and chain up to the parent
+ * implementation, however when introducing
  * a new #GtkActivatable class; the #GtkActivatable:related-action and
  * #GtkActivatable:use-action-appearance properties need to be handled by
- * the implementor. Handling these properties is mostly a matter of installing 
- * the action pointer and boolean flag on your instance, and calling 
- * gtk_activatable_do_set_related_action() and gtk_activatable_reset() at the
- * appropriate times.
+ * the implementor. Handling these properties is mostly a matter of installing
+ * the action pointer and boolean flag on your instance, and calling
+ * gtk_activatable_do_set_related_action() and
+ * gtk_activatable_sync_action_properties() at the appropriate times.
  * </para>
  * <example>
  * <title>A class fragment implementing #GtkActivatable</title>
@@ -45,7 +45,7 @@
  *
  * enum {
  * ...
- * 
+ *
  * PROP_ACTIVATABLE_RELATED_ACTION,
  * PROP_ACTIVATABLE_USE_ACTION_APPEARANCE
  * }
  * 
  * ...
  * 
- * static void foo_bar_activatable_interface_init (GtkActivatableIface  *iface);
- * static void foo_bar_activatable_update         (GtkActivatable       *activatable,
- *                                                GtkAction            *action,
- *                                                const gchar          *property_name);
- * static void foo_bar_activatable_reset          (GtkActivatable       *activatable,
- *                                                GtkAction            *action);
+ * static void foo_bar_activatable_interface_init         (GtkActivatableIface  *iface);
+ * static void foo_bar_activatable_update                 (GtkActivatable       *activatable,
+ *                                                        GtkAction            *action,
+ *                                                        const gchar          *property_name);
+ * static void foo_bar_activatable_sync_action_properties (GtkActivatable       *activatable,
+ *                                                        GtkAction            *action);
  * ...
- * 
- * 
+ *
+ *
  * static void
  * foo_bar_class_init (FooBarClass *klass)
  * {
- * 
+ *
  *   ...
- * 
+ *
  *   g_object_class_override_property (gobject_class, PROP_ACTIVATABLE_RELATED_ACTION, "related-action");
  *   g_object_class_override_property (gobject_class, PROP_ACTIVATABLE_USE_ACTION_APPEARANCE, "use-action-appearance");
- * 
+ *
  *   ...
  * }
- * 
- * 
- * static void 
+ *
+ *
+ * static void
  * foo_bar_activatable_interface_init (GtkActivatableIface  *iface)
  * {
  *   iface->update = foo_bar_activatable_update;
- *   iface->reset = foo_bar_activatable_reset;
+ *   iface->sync_action_properties = foo_bar_activatable_sync_action_properties;
  * }
  * 
  * ... Break the reference using gtk_activatable_do_set_related_action()...
  *     {
  *       priv->use_action_appearance = use_appearance;
  *       
- *       gtk_activatable_reset (GTK_ACTIVATABLE (bar), priv->action);
+ *       gtk_activatable_sync_action_properties (GTK_ACTIVATABLE (bar), priv->action);
  *     }
  * }
  * 
  * }
  * 
  * ... Selectively reset and update activatable depending on the use-action-appearance property ...
- * static void 
- * gtk_button_activatable_reset (GtkActivatable       *activatable,
- *                              GtkAction            *action)
+ * static void
+ * gtk_button_activatable_sync_action_properties (GtkActivatable       *activatable,
+ *                                               GtkAction            *action)
  * {
  *   GtkButtonPrivate *priv = GTK_BUTTON_GET_PRIVATE (activatable);
  * 
  * 
  * static void 
  * foo_bar_activatable_update (GtkActivatable       *activatable,
- *                         GtkAction            *action,
- *                         const gchar          *property_name)
+ *                            GtkAction            *action,
+ *                            const gchar          *property_name)
  * {
  *   FooBarPrivate *priv = FOO_BAR_GET_PRIVATE (activatable);
  * 
  *   ...
  * }]]></programlisting>
  * </example>
- * 
+ * </refsect2>
  */
 
 #include "config.h"
 #include "gtkactivatable.h"
 #include "gtkactiongroup.h"
-#include "gtktypeutils.h"
 #include "gtkprivate.h"
 #include "gtkintl.h"
-#include "gtkalias.h"
-
-
-static void gtk_activatable_class_init (gpointer g_iface);
-
-GType
-gtk_activatable_get_type (void)
-{
-  static GType activatable_type = 0;
 
-  if (!activatable_type)
-    activatable_type =
-      g_type_register_static_simple (G_TYPE_INTERFACE, I_("GtkActivatable"),
-                                    sizeof (GtkActivatableIface),
-                                    (GClassInitFunc) gtk_activatable_class_init,
-                                    0, NULL, 0);
 
-  return activatable_type;
-}
+typedef GtkActivatableIface GtkActivatableInterface;
+G_DEFINE_INTERFACE (GtkActivatable, gtk_activatable, G_TYPE_OBJECT)
 
 static void
-gtk_activatable_class_init (gpointer g_iface)
+gtk_activatable_default_init (GtkActivatableInterface *iface)
 {
   /**
    * GtkActivatable:related-action:
@@ -298,7 +282,7 @@ gtk_activatable_class_init (gpointer g_iface)
    *
    * Since: 2.16
    */
-  g_object_interface_install_property (g_iface,
+  g_object_interface_install_property (iface,
                                       g_param_spec_object ("related-action",
                                                            P_("Related Action"),
                                                            P_("The action this activatable will activate and receive updates from"),
@@ -316,11 +300,12 @@ gtk_activatable_class_init (gpointer g_iface)
    * should be ignored by the #GtkActivatable when this property is %FALSE.
    *
    * <note><para>#GtkActivatable implementors need to handle this property
-   * and call gtk_activatable_reset() on the activatable widget when it changes.</para></note>
+   * and call gtk_activatable_sync_action_properties() on the activatable
+   * widget when it changes.</para></note>
    *
    * Since: 2.16
    */
-  g_object_interface_install_property (g_iface,
+  g_object_interface_install_property (iface,
                                       g_param_spec_boolean ("use-action-appearance",
                                                             P_("Use Action Appearance"),
                                                             P_("Whether to use the related actions appearance properties"),
@@ -348,29 +333,30 @@ gtk_activatable_update (GtkActivatable *activatable,
 }
 
 /**
- * gtk_activatable_reset:
+ * gtk_activatable_sync_action_properties:
  * @activatable: a #GtkActivatable
- * @action: the related #GtkAction or %NULL
+ * @action: (allow-none): the related #GtkAction or %NULL
  *
- * This is called to update the activatable completely, this is called internally when 
- * the #GtkActivatable::related-action property is set or unset and by the implementing 
- * class when #GtkActivatable::use-action-appearance changes.
+ * This is called to update the activatable completely, this is called
+ * internally when the #GtkActivatable:related-action property is set
+ * or unset and by the implementing class when
+ * #GtkActivatable:use-action-appearance changes.
  *
  * Since: 2.16
  **/
 void
-gtk_activatable_reset (GtkActivatable *activatable,
-                      GtkAction      *action)
+gtk_activatable_sync_action_properties (GtkActivatable *activatable,
+                                       GtkAction      *action)
 {
   GtkActivatableIface *iface;
 
   g_return_if_fail (GTK_IS_ACTIVATABLE (activatable));
 
   iface = GTK_ACTIVATABLE_GET_IFACE (activatable);
-  if (iface->reset)
-    iface->reset (activatable, action);
+  if (iface->sync_action_properties)
+    iface->sync_action_properties (activatable, action);
   else
-    g_critical ("GtkActivatable->reset() unimplemented for type %s", 
+    g_critical ("GtkActivatable->sync_action_properties() unimplemented for type %s", 
                g_type_name (G_OBJECT_TYPE (activatable)));
 }
 
@@ -423,7 +409,10 @@ gtk_activatable_action_notify (GtkAction      *action,
  *
  * <note><para>Be careful to call this before setting the local
  * copy of the #GtkAction property, since this function uses 
- * gtk_activatable_get_action() to retrieve the previous action</para></note>
+ * gtk_activatable_get_related_action() to retrieve the
+ * previous action</para></note>
+ *
+ * Since: 2.16
  */
 void
 gtk_activatable_do_set_related_action (GtkActivatable *activatable,
@@ -439,31 +428,44 @@ gtk_activatable_do_set_related_action (GtkActivatable *activatable,
        {
          g_signal_handlers_disconnect_by_func (prev_action, gtk_activatable_action_notify, activatable);
          
-         _gtk_action_remove_from_proxy_list (prev_action, GTK_WIDGET (activatable));
+          /* Check the type so that actions can be activatable too. */
+          if (GTK_IS_WIDGET (activatable))
+            _gtk_action_remove_from_proxy_list (prev_action, GTK_WIDGET (activatable));
          
-         g_object_unref (prev_action);
-
           /* Some apps are using the object data directly...
            * so continue to set it for a bit longer
            */
-          g_object_set_data (activatable, "gtk-action", NULL);
+          g_object_set_data (G_OBJECT (activatable), "gtk-action", NULL);
+
+          /*
+           * We don't want prev_action to be activated
+           * during the sync_action_properties() call when syncing "active".
+           */ 
+          gtk_action_block_activate (prev_action);
        }
       
       /* Some applications rely on their proxy UI to be set up
        * before they receive the ::connect-proxy signal, so we
-       * need to call reset() before add_to_proxy_list().
+       * need to call sync_action_properties() before add_to_proxy_list().
        */
-      gtk_activatable_reset (activatable, action);
+      gtk_activatable_sync_action_properties (activatable, action);
+
+      if (prev_action)
+        {
+          gtk_action_unblock_activate (prev_action);
+         g_object_unref (prev_action);
+        }
 
       if (action)
        {
          g_object_ref (action);
-         
+
          g_signal_connect (G_OBJECT (action), "notify", G_CALLBACK (gtk_activatable_action_notify), activatable);
-         
-         _gtk_action_add_to_proxy_list (action, GTK_WIDGET (activatable));
 
-          g_object_set_data (activatable, "gtk-action", action);
+          if (GTK_IS_WIDGET (activatable))
+            _gtk_action_add_to_proxy_list (action, GTK_WIDGET (activatable));
+
+          g_object_set_data (G_OBJECT (activatable), "gtk-action", action);
        }
     }
 }
@@ -474,7 +476,7 @@ gtk_activatable_do_set_related_action (GtkActivatable *activatable,
  *
  * Gets the related #GtkAction for @activatable.
  *
- * Returns: the related #GtkAction if one is set.
+ * Returns: (transfer none): the related #GtkAction if one is set.
  *
  * Since: 2.16
  **/
@@ -499,17 +501,19 @@ gtk_activatable_get_related_action (GtkActivatable *activatable)
  * @activatable: a #GtkActivatable
  * @use_appearance: whether to use the actions appearance
  *
- * Sets whether this activatable should reset its layout and appearance 
- * when setting the related action or when the action changes appearance 
+ * Sets whether this activatable should reset its layout and appearance
+ * when setting the related action or when the action changes appearance
  *
- * <note><para>#GtkActivatable implementors need to handle the #GtkActivatable:use-action-appearance
- * property and call gtk_activatable_reset() to update @activatable if needed.</para></note>
+ * <note><para>#GtkActivatable implementors need to handle the
+ * #GtkActivatable:use-action-appearance property and call
+ * gtk_activatable_sync_action_properties() to update @activatable
+ * if needed.</para></note>
  *
  * Since: 2.16
  **/
 void
-gtk_activatable_set_use_action_appearance  (GtkActivatable *activatable,
-                                           gboolean        use_appearance)
+gtk_activatable_set_use_action_appearance (GtkActivatable *activatable,
+                                          gboolean        use_appearance)
 {
   g_object_set (activatable, "use-action-appearance", use_appearance, NULL);
 }
@@ -535,6 +539,3 @@ gtk_activatable_get_use_action_appearance  (GtkActivatable *activatable)
 
   return use_appearance;
 }
-
-#define __GTK_ACTIVATABLE_C__
-#include "gtkaliasdef.c"