Remove hildon-banner-private.h
[hildon] / hildon / hildon-banner.c
index 7e9f417..11b8ca8 100644 (file)
@@ -23,8 +23,8 @@
  */
 
 /**
- * SECTION:hildon-banner 
- * @short_description: A widget used to display timed notifications. 
+ * SECTION:hildon-banner
+ * @short_description: A widget used to display timed notifications.
  *
  * #HildonBanner is a small, pop-up window that can be used to display
  * a short, timed notification or information to the user. It can
  * hildon_banner_show_information(), hildon_banner_show_informationf()
  * or hildon_banner_show_information_with_markup().
  *
+ * If the application window has set the _HILDON_DO_NOT_DISTURB flag (using
+ * hildon_gtk_window_set_do_not_disturb() for example), the banner will not
+ * be shown. If you need to override this flag for important information,
+ * you can use the method hildon_banner_show_information_override_dnd().
+ * Please, take into account that this is only for important information.
+ *
+ *
  * Two more kinds of banners are maintained for backward compatibility
  * but are no longer recommended in Hildon 2.2. These are the animated
  * banner (created with hildon_banner_show_animation()) and the
  * hildon_gtk_window_set_progress_indicator() for the preferred way of
  * showing progress notifications in Hildon 2.2.
  *
- * Information banners dissapear automatically after a certain
+ * Information banners are automatically destroyed after a certain
  * period. This is stored in the #HildonBanner:timeout property (in
  * miliseconds), and can be changed using hildon_banner_set_timeout().
  *
  * Note that #HildonBanner<!-- -->s should only be used to display
  * non-critical pieces of information.
+ *
+ * <example>
+ * <title>Using the HildonBanner widget</title>
+ * <programlisting>
+ * void show_info_banner (GtkWidget *parent)
+ * {
+ *   GtkWidget *banner;
+ * <!-- -->
+ *   banner = hildon_banner_show_information (widget, NULL, "Information banner");
+ *   hildon_banner_set_timeout (HILDON_BANNER (banner), 9000);
+ * <!-- -->
+ *   return;
+ * }
+ * </programlisting>
+ * </example>
  */
 
 #ifdef                                          HAVE_CONFIG_H
@@ -62,8 +84,8 @@
 #undef                                          HILDON_DISABLE_DEPRECATED
 
 #include                                        "hildon-banner.h"
-#include                                        "hildon-banner-private.h"
 #include                                        "hildon-defines.h"
+#include                                        "hildon-gtk.h"
 
 /* position relative to the screen */
 
@@ -73,8 +95,6 @@
 
 /* max widths */
 
-#define                                         HILDON_BANNER_PROGRESS_WIDTH 104
-
 #define                                         HILDON_BANNER_LABEL_MAX_TIMED \
                                                 (gdk_screen_width() - ((HILDON_MARGIN_TRIPLE) * 2))
 
@@ -186,8 +206,38 @@ static HildonBanner*
 hildon_banner_get_instance_for_widget           (GtkWidget *widget, 
                                                  gboolean timed);
 
+static void
+hildon_banner_set_override_flag                 (HildonBanner *banner);
+
+static GtkWidget*
+hildon_banner_real_show_information             (GtkWidget *widget,
+                                                 const gchar *text,
+                                                 gboolean override_dnd);
+
 G_DEFINE_TYPE (HildonBanner, hildon_banner, GTK_TYPE_WINDOW)
 
+typedef struct                                  _HildonBannerPrivate HildonBannerPrivate;
+
+#define                                         HILDON_BANNER_GET_PRIVATE(obj) \
+                                                (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+                                                HILDON_TYPE_BANNER, HildonBannerPrivate));
+
+struct                                          _HildonBannerPrivate
+{
+    GtkWidget *main_item;
+    GtkWidget *alignment;
+    GtkWidget *label;
+    GtkWidget *layout;
+    GtkWindow *parent;
+    guint      timeout;
+    guint      timeout_id;
+    guint      is_timed             : 1;
+    guint      has_been_wrapped     : 1;
+    guint      has_been_truncated   : 1;
+    guint      require_override_dnd : 1;
+    guint      overrides_dnd        : 1;
+};
+
 static GQuark 
 hildon_banner_timed_quark                       (void)
 {
@@ -388,6 +438,10 @@ hildon_banner_destroy                           (GtkObject *object)
         g_object_set_qdata (parent_window, hildon_banner_timed_quark (), NULL);
     }
 
+    if (!priv->is_timed && priv->parent) {
+        hildon_gtk_window_set_progress_indicator (priv->parent, 0);
+    }
+
     (void) hildon_banner_clear_timeout (self);
 
     if (GTK_OBJECT_CLASS (hildon_banner_parent_class)->destroy)
@@ -653,9 +707,18 @@ hildon_banner_check_position                    (GtkWidget *widget)
 }
 
 static void
+screen_size_changed                            (GdkScreen *screen,
+                                                GtkWindow *banner)
+
+{
+    gtk_window_reshow_with_initial_size (banner);
+}
+
+static void
 hildon_banner_realize                           (GtkWidget *widget)
 {
     GdkWindow *gdkwin;
+    GdkScreen *screen;
     GdkAtom atom;
     guint32 portrait = 1;
     const gchar *notification_type = "_HILDON_NOTIFICATION_TYPE_BANNER";
@@ -683,6 +746,24 @@ hildon_banner_realize                           (GtkWidget *widget)
     atom = gdk_atom_intern ("_HILDON_PORTRAIT_MODE_SUPPORT", FALSE);
     gdk_property_change (gdkwin, atom, gdk_x11_xatom_to_atom (XA_CARDINAL), 32,
                          GDK_PROP_MODE_REPLACE, (gpointer) &portrait, 1);
+
+    /* Manage override flag */
+    if ((priv->require_override_dnd)&&(!priv->overrides_dnd)) {
+      hildon_banner_set_override_flag (HILDON_BANNER (widget));
+        priv->overrides_dnd = TRUE;
+    }
+
+    screen = gtk_widget_get_screen (widget);
+    g_signal_connect (screen, "size-changed", G_CALLBACK (screen_size_changed), widget);
+}
+
+static void
+hildon_banner_unrealize                         (GtkWidget *widget)
+{
+    GdkScreen *screen = gtk_widget_get_screen (widget);
+    g_signal_handlers_disconnect_by_func (screen, G_CALLBACK (screen_size_changed), widget);
+
+    GTK_WIDGET_CLASS (hildon_banner_parent_class)->unrealize (widget);
 }
 
 static void 
@@ -706,6 +787,7 @@ hildon_banner_class_init                        (HildonBannerClass *klass)
     GTK_OBJECT_CLASS (klass)->destroy = hildon_banner_destroy;
     widget_class->map_event = hildon_banner_map_event;
     widget_class->realize = hildon_banner_realize;
+    widget_class->unrealize = hildon_banner_unrealize;
     widget_class->button_press_event = hildon_banner_button_press_event;
 #if defined(MAEMO_GTK)
     widget_class->map = hildon_banner_map;
@@ -742,7 +824,7 @@ hildon_banner_class_init                        (HildonBannerClass *klass)
     /**
      * HildonBanner:timeout:
      *
-     * The time before making the banner banner go away. This needs 
+     * The time before destroying the banner. This needs
      * to be adjusted before the banner is mapped to the screen.
      *                      
      */
@@ -763,8 +845,11 @@ hildon_banner_init                              (HildonBanner *self)
     g_assert (priv);
 
     priv->parent = NULL;
+    priv->overrides_dnd = FALSE;
+    priv->require_override_dnd = FALSE;
 
     /* Initialize the common layout inside banner */
+    priv->alignment = gtk_alignment_new (0.5, 0.5, 0, 0);
     priv->layout = gtk_hbox_new (FALSE, HILDON_MARGIN_DEFAULT);
 
     priv->label = g_object_new (GTK_TYPE_LABEL, NULL);
@@ -772,8 +857,9 @@ hildon_banner_init                              (HildonBanner *self)
     gtk_label_set_line_wrap_mode (GTK_LABEL (priv->label), PANGO_WRAP_WORD_CHAR);
 
     gtk_container_set_border_width (GTK_CONTAINER (priv->layout), HILDON_MARGIN_DEFAULT);
-    gtk_container_add (GTK_CONTAINER (self), priv->layout);
-    gtk_box_pack_start (GTK_BOX (priv->layout), priv->label, TRUE, TRUE, 0);
+    gtk_container_add (GTK_CONTAINER (self), priv->alignment);
+    gtk_container_add (GTK_CONTAINER (priv->alignment), priv->layout);
+    gtk_box_pack_start (GTK_BOX (priv->layout), priv->label, FALSE, FALSE, 0);
 
     gtk_window_set_accept_focus (GTK_WINDOW (self), FALSE);
 
@@ -816,7 +902,7 @@ hildon_banner_ensure_child                      (HildonBanner *self,
         /* Use user provided widget or create a new one */
         priv->main_item = widget = user_widget ? 
             user_widget : GTK_WIDGET (g_object_new_valist(type, first_property, args));
-        gtk_box_pack_start (GTK_BOX (priv->layout), widget, TRUE, TRUE, 0);
+        gtk_box_pack_start (GTK_BOX (priv->layout), widget, FALSE, FALSE, 0);
     }
 
     /* We make sure that the widget exists in desired position. Different
@@ -884,11 +970,12 @@ hildon_banner_create_animation (void)
  * any value that you pass will be ignored
  * @text: Text to display
  *
- * This function creates and displays an information banner that
- * automatically goes away after certain time period. For each window
- * in your application there can only be one timed banner, so if you
- * spawn a new banner before the earlier one has timed out, the
- * previous one will be replaced.
+ * This function creates and displays an information banner that is
+ * automatically destroyed after a certain time period (see
+ * hildon_banner_set_timeout()). For each window in your application
+ * there can only be one timed banner, so if you spawn a new banner
+ * before the earlier one has timed out, the previous one will be
+ * replaced.
  *
  * Returns: The newly created banner
  *
@@ -898,20 +985,70 @@ hildon_banner_show_information                  (GtkWidget *widget,
                                                  const gchar *icon_name,
                                                  const gchar *text)
 {
+    return hildon_banner_real_show_information (widget, text, FALSE);
+}
+
+/**
+ * hildon_banner_show_information_override_dnd:
+ * @widget: the #GtkWidget that is the owner of the banner
+ * @text: Text to display
+ *
+ * Equivalent to hildon_banner_show_information(), but overriding the
+ * "do not disturb" flag.
+ *
+ * Returns: The newly created banner
+ *
+ * Since: 2.2
+ *
+ */
+GtkWidget*
+hildon_banner_show_information_override_dnd     (GtkWidget *widget,
+                                                 const gchar *text)
+{
+    return hildon_banner_real_show_information (widget, text, TRUE);
+}
+
+static void
+hildon_banner_set_override_flag                 (HildonBanner *banner)
+{
+    guint32 state = 1;
+
+    gdk_property_change (GTK_WIDGET (banner)->window,
+                         gdk_atom_intern_static_string ("_HILDON_DO_NOT_DISTURB_OVERRIDE"),
+                         gdk_x11_xatom_to_atom (XA_INTEGER),
+                         32,
+                         GDK_PROP_MODE_REPLACE,
+                         (const guchar*) &state,
+                         1);
+}
+
+
+static GtkWidget*
+hildon_banner_real_show_information             (GtkWidget *widget,
+                                                 const gchar *text,
+                                                 gboolean override_dnd)
+{
     HildonBanner *banner;
+    HildonBannerPrivate *priv = NULL;
 
     g_return_val_if_fail (text != NULL, NULL);
 
     /* Prepare banner */
     banner = hildon_banner_get_instance_for_widget (widget, TRUE);
+    priv = HILDON_BANNER_GET_PRIVATE (banner);
 
     hildon_banner_set_text (banner, text);
     hildon_banner_bind_style (banner, "information");
 
+    if (override_dnd) {
+      /* so on the realize it will set the property */
+      priv->require_override_dnd = TRUE;
+    }
+
     /* Show the banner, since caller cannot do that */
     gtk_widget_show_all (GTK_WIDGET (banner));
 
-    return (GtkWidget *) banner;
+    return GTK_WIDGET (banner);
 }
 
 /**
@@ -922,7 +1059,7 @@ hildon_banner_show_information                  (GtkWidget *widget,
  * @format: a printf-like format string
  * @Varargs: arguments for the format string
  *
- * A helper function for #hildon_banner_show_information with
+ * A helper function for hildon_banner_show_information() with
  * string formatting.
  *
  * Returns: the newly created banner
@@ -957,11 +1094,12 @@ hildon_banner_show_informationf                 (GtkWidget *widget,
  * any value that you pass will be ignored
  * @markup: a markup string to display (see <link linkend="PangoMarkupFormat">Pango markup format</link>)
  *
- * This function creates and displays an information banner that
- * automatically goes away after certain time period. For each window
- * in your application there can only be one timed banner, so if you
- * spawn a new banner before the earlier one has timed out, the
- * previous one will be replaced.
+ * This function creates and displays an information banner that is
+ * automatically destroyed after certain time period (see
+ * hildon_banner_set_timeout()). For each window in your application
+ * there can only be one timed banner, so if you spawn a new banner
+ * before the earlier one has timed out, the previous one will be
+ * replaced.
  *
  * Returns: the newly created banner
  *
@@ -1002,15 +1140,20 @@ hildon_banner_show_information_with_markup      (GtkWidget *widget,
  * notifications with timed banners. In this case the banners are
  * located so that you can somehow see both.
  *
- * Please note that banners are destroyed automatically once the
+ * Unlike information banners (created with
+ * hildon_banner_show_information()), animation banners are not
+ * destroyed automatically using a timeout. You have to destroy them
+ * yourself.
+ *
+ * Please note also that these banners are destroyed automatically if the
  * window they are attached to is closed. The pointer that you receive
  * with this function does not contain additional references, so it
  * can become invalid without warning (this is true for all toplevel
  * windows in gtk). To make sure that the banner does not disappear
  * automatically, you can separately ref the return value (this
  * doesn't prevent the banner from disappearing, just the object from
- * being finalized). In this case you have to call both
- * gtk_widget_destroy() followed by g_object_unref() (in this order).
+ * being finalized). In this case you have to call
+ * gtk_widget_destroy() followed by g_object_unref().
  *
  * Returns: a #HildonBanner widget. You must call gtk_widget_destroy()
  *          once you are done with the banner.
@@ -1047,11 +1190,11 @@ hildon_banner_show_animation                    (GtkWidget *widget,
 /**
  * hildon_banner_show_progress:
  * @widget: the #GtkWidget that wants to display banner
- * @bar: Progressbar to use. You usually can just pass %NULL, unless
- *       you want somehow customized progress bar.
+ * @bar: since Hildon 2.2 this parameter is not used anymore and
+ * any value that you pass will be ignored
  * @text: text to display.
  *
- * Shows progress notification. See #hildon_banner_show_animation
+ * Shows progress notification. See hildon_banner_show_animation()
  * for more information.
  * 
  * Returns: a #HildonBanner widget. You must call #gtk_widget_destroy
@@ -1067,22 +1210,19 @@ hildon_banner_show_progress                     (GtkWidget *widget,
     HildonBanner *banner;
     HildonBannerPrivate *priv;
 
-    g_return_val_if_fail (bar == NULL || GTK_IS_PROGRESS_BAR (bar), NULL);
     g_return_val_if_fail (text != NULL, NULL);
 
-
     /* Prepare banner */
     banner = hildon_banner_get_instance_for_widget (widget, FALSE);
     priv = HILDON_BANNER_GET_PRIVATE (banner);
     g_assert (priv);
-    hildon_banner_ensure_child (banner, (GtkWidget *) bar, -1, GTK_TYPE_PROGRESS_BAR, NULL);
-
-    gtk_widget_set_size_request (priv->main_item,
-            HILDON_BANNER_PROGRESS_WIDTH, -1);
 
     hildon_banner_set_text (banner, text);
     hildon_banner_bind_style (banner, "progress");
 
+    if (priv->parent)
+        hildon_gtk_window_set_progress_indicator (priv->parent, 1);
+
     /* Show the banner */
     gtk_widget_show_all (GTK_WIDGET (banner));
 
@@ -1163,19 +1303,13 @@ hildon_banner_set_markup                        (HildonBanner *self,
  * Note that this method only has effect if @self was created with
  * hildon_banner_show_progress()
  *
+ * Deprecated: This function does nothing. As of Hildon 2.2, hildon
+ * banners don't have progress bars.
  */
 void 
 hildon_banner_set_fraction                      (HildonBanner *self, 
                                                  gdouble fraction)
 {
-    HildonBannerPrivate *priv;
-
-    g_return_if_fail (HILDON_IS_BANNER (self));
-    priv = HILDON_BANNER_GET_PRIVATE (self);
-    g_assert (priv);
-
-    g_return_if_fail (GTK_IS_PROGRESS_BAR (priv->main_item));
-    gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (priv->main_item), fraction);
 }
 
 /**
@@ -1184,8 +1318,8 @@ hildon_banner_set_fraction                      (HildonBanner *self,
  * @timeout: timeout to set in miliseconds.
  *
  * Sets the timeout on the banner. After the given amount of miliseconds
- * has elapsed the banner will go away. Note that settings this only makes
- * sense on the banners that are timed and that have not been yet displayed
+ * has elapsed the banner will be destroyed. Setting this only makes
+ * sense on banners that are timed and that have not been yet displayed
  * on the screen.
  *
  * Note that this method only has effect if @self is an information