[gnome-calendar] Glue code for using those editable widgets.



commit 39ed044ca514f30f6ad4d8e86c2356d1a3d5626b
Author: Erick PÃrez Castellanos <erick red gmail com>
Date:   Thu Jun 21 08:21:57 2012 -0400

    Glue code for using those editable widgets.
    
    Added GcalEventWidget::activated signal.
    Fixed bug in GcalMonthView preventing to get button events.
    Added methods in GcalUtils from Evo for formatting time.
    ..and stuff

 src/gcal-event-widget.c |   43 ++++++++++-
 src/gcal-event-widget.h |   14 ++--
 src/gcal-month-view.c   |    4 +-
 src/gcal-utils.c        |  179 +++++++++++++++++++++++++++++++++++++++++++++++
 src/gcal-utils.h        |   29 ++++++--
 src/gcal-window.c       |   84 ++++++++++++++++------
 6 files changed, 313 insertions(+), 40 deletions(-)
---
diff --git a/src/gcal-event-widget.c b/src/gcal-event-widget.c
index dff9b9f..147aadc 100644
--- a/src/gcal-event-widget.c
+++ b/src/gcal-event-widget.c
@@ -43,6 +43,14 @@ enum
   PROP_DTSTART
 };
 
+enum
+{
+  ACTIVATED,
+  NUM_SIGNALS
+};
+
+static guint signals[NUM_SIGNALS] = { 0, };
+
 static void     gcal_event_widget_constructed          (GObject        *object);
 
 static void     gcal_event_widget_set_property         (GObject        *object,
@@ -77,6 +85,9 @@ static void     gcal_event_widget_size_allocate        (GtkWidget      *widget,
 static gboolean gcal_event_widget_draw                 (GtkWidget      *widget,
                                                         cairo_t        *cr);
 
+static gboolean gcal_event_widget_button_press_event   (GtkWidget      *widget,
+                                                        GdkEventButton *event);
+
 G_DEFINE_TYPE(GcalEventWidget, gcal_event_widget, GTK_TYPE_WIDGET)
 
 static void
@@ -99,6 +110,7 @@ gcal_event_widget_class_init(GcalEventWidgetClass *klass)
   widget_class->unmap = gcal_event_widget_unmap;
   widget_class->size_allocate = gcal_event_widget_size_allocate;
   widget_class->draw = gcal_event_widget_draw;
+  widget_class->button_press_event = gcal_event_widget_button_press_event;
 
   g_object_class_install_property (object_class,
                                    PROP_UUID,
@@ -136,6 +148,16 @@ gcal_event_widget_class_init(GcalEventWidgetClass *klass)
                                                        G_PARAM_CONSTRUCT |
                                                        G_PARAM_READWRITE));
 
+  signals[ACTIVATED] = g_signal_new ("activated",
+                                     GCAL_TYPE_EVENT_WIDGET,
+                                     G_SIGNAL_RUN_LAST,
+                                     G_STRUCT_OFFSET (GcalEventWidgetClass,
+                                                      activated),
+                                     NULL, NULL,
+                                     g_cclosure_marshal_VOID__VOID,
+                                     G_TYPE_NONE,
+                                     0);
+
   g_type_class_add_private((gpointer)klass, sizeof(GcalEventWidgetPrivate));
 }
 
@@ -343,10 +365,10 @@ gcal_event_widget_map (GtkWidget *widget)
   GcalEventWidgetPrivate *priv;
 
   priv = GCAL_EVENT_WIDGET (widget)->priv;
-  GTK_WIDGET_CLASS (gcal_event_widget_parent_class)->map (widget);
-
-  if (priv->event_window)
+  if (priv->event_window != NULL)
     gdk_window_show (priv->event_window);
+
+  GTK_WIDGET_CLASS (gcal_event_widget_parent_class)->map (widget);
 }
 
 static void
@@ -355,7 +377,7 @@ gcal_event_widget_unmap (GtkWidget *widget)
   GcalEventWidgetPrivate *priv;
 
   priv = GCAL_EVENT_WIDGET (widget)->priv;
-  if (priv->event_window)
+  if (priv->event_window != NULL)
     gdk_window_hide (priv->event_window);
 
   GTK_WIDGET_CLASS (gcal_event_widget_parent_class)->unmap (widget);
@@ -461,6 +483,19 @@ gcal_event_widget_draw (GtkWidget *widget,
   return FALSE;
 }
 
+static gboolean
+gcal_event_widget_button_press_event (GtkWidget      *widget,
+                                      GdkEventButton *event)
+{
+  g_debug ("button pressed over event: %s",
+           GCAL_EVENT_WIDGET (widget)->priv->uuid);
+
+  if (event->type == GDK_2BUTTON_PRESS)
+    g_signal_emit (widget, signals[ACTIVATED], 0);
+
+  return TRUE;
+}
+
 GtkWidget*
 gcal_event_widget_new (gchar *uuid)
 {
diff --git a/src/gcal-event-widget.h b/src/gcal-event-widget.h
index 88aed66..4e3f1bc 100644
--- a/src/gcal-event-widget.h
+++ b/src/gcal-event-widget.h
@@ -38,18 +38,20 @@ typedef struct _GcalEventWidget                   GcalEventWidget;
 typedef struct _GcalEventWidgetClass              GcalEventWidgetClass;
 typedef struct _GcalEventWidgetPrivate            GcalEventWidgetPrivate;
 
-struct _GcalEventWidget
+struct _GcalEventWidgetClass
 {
-  GtkWidget parent;
+  GtkWidgetClass parent_class;
 
-  GcalEventWidgetPrivate *priv;
+  /* signals */
+  void (*activated)  (GcalEventWidget *event_widget);
 };
 
-struct _GcalEventWidgetClass
+struct _GcalEventWidget
 {
-  GtkWidgetClass parent_class;
-};
+  GtkWidget parent;
 
+  GcalEventWidgetPrivate *priv;
+};
 
 GType         gcal_event_widget_get_type                   (void);
 
diff --git a/src/gcal-month-view.c b/src/gcal-month-view.c
index fd09c8d..104fe6f 100644
--- a/src/gcal-month-view.c
+++ b/src/gcal-month-view.c
@@ -327,10 +327,10 @@ gcal_month_view_map (GtkWidget *widget)
   GcalMonthViewPrivate *priv;
 
   priv = GCAL_MONTH_VIEW (widget)->priv;
-  GTK_WIDGET_CLASS (gcal_month_view_parent_class)->map (widget);
-
   if (priv->event_window)
     gdk_window_show (priv->event_window);
+
+  GTK_WIDGET_CLASS (gcal_month_view_parent_class)->map (widget);
 }
 
 static void
diff --git a/src/gcal-utils.c b/src/gcal-utils.c
index 93485f3..17391cd 100644
--- a/src/gcal-utils.c
+++ b/src/gcal-utils.c
@@ -22,6 +22,7 @@
 
 #include <string.h>
 
+#include <libedataserver/e-data-server-util.h>
 #include <libedataserverui/e-cell-renderer-color.h>
 
 G_DEFINE_BOXED_TYPE (icaltimetype, icaltime, gcal_dup_icaltime, g_free)
@@ -105,3 +106,181 @@ gcal_dup_icaltime (icaltimetype *date)
 
   return new_date;
 }
+
+/*
+ * gcal_get_source_name:
+ *
+ * This method assume it receive only the model inside GcalManager
+ * */
+gchar*
+gcal_get_source_name (GtkTreeModel *model,
+                      const gchar  *uid)
+{
+  GtkTreeIter iter;
+  gboolean valid;
+  gchar *name;
+
+  name = NULL;
+  valid = gtk_tree_model_get_iter_first (model, &iter);
+  while (valid)
+    {
+      gchar *name_data;
+      gchar *uid_data;
+
+      gtk_tree_model_get (model, &iter,
+                          0, &uid_data,
+                          1, &name_data,
+                          -1);
+
+      if (g_strcmp0 (uid_data, uid) == 0)
+        {
+          name = g_strdup (name_data);
+
+          g_free (name_data);
+          g_free (uid_data);
+          break;
+        }
+
+      g_free (name_data);
+      g_free (uid_data);
+
+      valid = gtk_tree_model_iter_next (model, &iter);
+    }
+  return name;
+}
+
+gchar*
+gcal_get_source_uid (GtkTreeModel *model,
+                     const gchar  *name)
+{
+  GtkTreeIter iter;
+  gboolean valid;
+  gchar *uid;
+
+  uid = NULL;
+  valid = gtk_tree_model_get_iter_first (model, &iter);
+  while (valid)
+    {
+      gchar *name_data;
+      gchar *uid_data;
+
+      gtk_tree_model_get (model, &iter,
+                          0, &uid_data,
+                          1, &name_data,
+                          -1);
+
+      if (g_strcmp0 (name_data, name) == 0)
+        {
+          uid = g_strdup (uid_data);
+
+          g_free (name_data);
+          g_free (uid_data);
+          break;
+        }
+
+      g_free (name_data);
+      g_free (uid_data);
+
+      valid = gtk_tree_model_iter_next (model, &iter);
+    }
+  return uid;
+}
+
+/* Function to do a last minute fixup of the AM/PM stuff if the locale
+ * and gettext haven't done it right. Most English speaking countries
+ * except the USA use the 24 hour clock (UK, Australia etc). However
+ * since they are English nobody bothers to write a language
+ * translation (gettext) file. So the locale turns off the AM/PM, but
+ * gettext does not turn on the 24 hour clock. Leaving a mess.
+ *
+ * This routine checks if AM/PM are defined in the locale, if not it
+ * forces the use of the 24 hour clock.
+ *
+ * The function itself is a front end on strftime and takes exactly
+ * the same arguments.
+ *
+ * TODO: Actually remove the '%p' from the fixed up string so that
+ * there isn't a stray space.
+ */
+
+gsize
+e_strftime_fix_am_pm (gchar *str,
+                      gsize max,
+                      const gchar *fmt,
+                      const struct tm *tm)
+{
+  gchar buf[10];
+  gchar *sp;
+  gchar *ffmt;
+  gsize ret;
+
+  if (strstr(fmt, "%p")==NULL && strstr(fmt, "%P")==NULL) {
+    /* No AM/PM involved - can use the fmt string directly */
+    ret = e_strftime (str, max, fmt, tm);
+  } else {
+    /* Get the AM/PM symbol from the locale */
+    e_strftime (buf, 10, "%p", tm);
+
+    if (buf[0]) {
+      /* AM/PM have been defined in the locale
+       * so we can use the fmt string directly. */
+      ret = e_strftime (str, max, fmt, tm);
+    } else {
+      /* No AM/PM defined by locale
+       * must change to 24 hour clock. */
+      ffmt = g_strdup (fmt);
+      for (sp=ffmt; (sp=strstr(sp, "%l")); sp++) {
+        /* Maybe this should be 'k', but I have never
+         * seen a 24 clock actually use that format. */
+        sp[1]='H';
+      }
+      for (sp=ffmt; (sp=strstr(sp, "%I")); sp++) {
+        sp[1]='H';
+      }
+      ret = e_strftime (str, max, ffmt, tm);
+      g_free (ffmt);
+    }
+  }
+
+  return (ret);
+}
+
+gsize
+e_utf8_strftime_fix_am_pm (gchar *str,
+                           gsize max,
+                           const gchar *fmt,
+                           const struct tm *tm)
+{
+  gsize sz, ret;
+  gchar *locale_fmt, *buf;
+
+  locale_fmt = g_locale_from_utf8 (fmt, -1, NULL, &sz, NULL);
+  if (!locale_fmt)
+    return 0;
+
+  ret = e_strftime_fix_am_pm (str, max, locale_fmt, tm);
+  if (!ret) {
+    g_free (locale_fmt);
+    return 0;
+  }
+
+  buf = g_locale_to_utf8 (str, ret, NULL, &sz, NULL);
+  if (!buf) {
+    g_free (locale_fmt);
+    return 0;
+  }
+
+  if (sz >= max) {
+    gchar *tmp = buf + max - 1;
+    tmp = g_utf8_find_prev_char (buf, tmp);
+    if (tmp)
+      sz = tmp - buf;
+    else
+      sz = 0;
+  }
+  memcpy (str, buf, sz);
+  str[sz] = '\0';
+  g_free (locale_fmt);
+  g_free (buf);
+  return sz;
+}
diff --git a/src/gcal-utils.h b/src/gcal-utils.h
index b49b8fc..877a49c 100644
--- a/src/gcal-utils.h
+++ b/src/gcal-utils.h
@@ -47,16 +47,33 @@ typedef enum
 } GcalEditableMode;
 
 typedef
-const gchar*  (*GcalTranslateFunc)                             (GtkWidget      *source_widget);
+const gchar*  (*GcalTranslateFunc)                              (GtkWidget       *source_widget);
 
-GType           icaltime_get_type                               (void)           G_GNUC_CONST;
+GType           icaltime_get_type                               (void)            G_GNUC_CONST;
 
-void            gcal_gtk_tree_view_set_activate_on_single_click (GtkTreeView    *tree_view,
-                                                                 gboolean       should_activate);
+void            gcal_gtk_tree_view_set_activate_on_single_click (GtkTreeView     *tree_view,
+                                                                 gboolean         should_activate);
 
 
-const gchar*    gcal_get_group_name                             (const gchar    *base_uri);
+const gchar*    gcal_get_group_name                             (const gchar     *base_uri);
 
-icaltimetype*   gcal_dup_icaltime                               (icaltimetype   *date);
+icaltimetype*   gcal_dup_icaltime                               (icaltimetype    *date);
+
+gchar*          gcal_get_source_name                            (GtkTreeModel    *model,
+                                                                 const gchar     *uid);
+
+gchar*          gcal_get_source_uid                             (GtkTreeModel    *model,
+                                                                 const gchar     *name);
+
+/* code brought from evolution */
+gsize           e_strftime_fix_am_pm                            (gchar           *str,
+                                                                 gsize            max,
+                                                                 const gchar     *fmt,
+                                                                 const struct tm *tm);
+gsize           e_utf8_strftime_fix_am_pm                       (gchar           *str,
+
+                                                                 gsize            max,
+                                                                 const gchar     *fmt,
+                                                                 const struct tm *tm);
 
 #endif // __GCAL_UTILS_H__
diff --git a/src/gcal-window.c b/src/gcal-window.c
index c1723bc..76e6716 100644
--- a/src/gcal-window.c
+++ b/src/gcal-window.c
@@ -55,6 +55,8 @@ GcalManager*      gcal_window_get_manager            (GcalWindow        *window)
 
 static void       gcal_window_set_sources_view       (GcalWindow        *window);
 
+static void       gcal_window_init_event_view        (GcalWindow        *window);
+
 static void       gcal_window_view_changed           (GcalToolbar       *main_toolbar,
                                                       GcalViewTypeEnum   view_type,
                                                       gpointer           user_data);
@@ -75,6 +77,9 @@ static void       gcal_window_events_added           (GcalManager       *manager
                                                       gpointer           events_list,
                                                       gpointer           user_data);
 
+static void       gcal_window_event_activated        (GcalEventWidget   *event_widget,
+                                                      gpointer           user_data);
+
 G_DEFINE_TYPE(GcalWindow, gcal_window, GTK_TYPE_APPLICATION_WINDOW)
 
 static void
@@ -307,6 +312,28 @@ gcal_window_set_sources_view (GcalWindow *window)
 }
 
 static void
+gcal_window_init_event_view (GcalWindow *window)
+{
+  GcalWindowPrivate *priv;
+
+  g_return_if_fail (GCAL_IS_WINDOW (window));
+  priv = window->priv;
+
+  priv->add_view = gcal_event_view_new_with_manager (
+      gcal_window_get_manager (window));
+  gtk_widget_set_hexpand (priv->add_view, TRUE);
+  gtk_widget_set_vexpand (priv->add_view, TRUE);
+  gtk_widget_set_margin_top (priv->add_view, 10);
+  gtk_widget_set_margin_left (priv->add_view, 20);
+  gtk_widget_set_margin_right (priv->add_view, 20);
+
+  gtk_widget_show (priv->add_view);
+  gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook),
+                            priv->add_view,
+                            NULL);
+}
+
+static void
 gcal_window_view_changed (GcalToolbar      *main_toolbar,
                            GcalViewTypeEnum  view_type,
                            gpointer          user_data)
@@ -365,28 +392,12 @@ gcal_window_add_event (GcalToolbar *main_toolbar,
 
   priv = GCAL_WINDOW (user_data)->priv;
   if (priv->add_view == NULL)
-    {
-      priv->add_view = gcal_event_view_new_with_manager (
-          gcal_window_get_manager (GCAL_WINDOW (user_data)));
-      gtk_widget_set_hexpand (priv->add_view, TRUE);
-      gtk_widget_set_vexpand (priv->add_view, TRUE);
-      gtk_widget_set_margin_top (priv->add_view, 10);
-      gtk_widget_set_margin_left (priv->add_view, 20);
-      gtk_widget_set_margin_right (priv->add_view, 20);
-
-      gtk_widget_show (priv->add_view);
-      gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook),
-                                priv->add_view,
-                                NULL);
-      gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), -1);
-    }
-  else
-    {
-      //TODO: Reload/clean/reinitialize status
-      gtk_notebook_set_current_page (
-          GTK_NOTEBOOK (priv->notebook),
-          gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), priv->add_view));
-    }
+      gcal_window_init_event_view (GCAL_WINDOW (user_data));
+
+  //TODO: Reload/clean/reinitialize status
+  gtk_notebook_set_current_page (
+      GTK_NOTEBOOK (priv->notebook),
+      gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), priv->add_view));
 }
 
 static void
@@ -471,6 +482,12 @@ gcal_window_events_added (GcalManager *manager,
               event);
           gtk_style_context_add_class (gtk_widget_get_style_context (event),
                                        "event");
+
+          g_signal_connect (event,
+                            "activated",
+                            G_CALLBACK (gcal_window_event_activated),
+                            user_data);
+
           g_free (summary);
           gdk_rgba_free (color);
         }
@@ -484,6 +501,29 @@ gcal_window_events_added (GcalManager *manager,
     }
 }
 
+static void
+gcal_window_event_activated (GcalEventWidget *event_widget,
+                             gpointer         user_data)
+{
+  GcalWindowPrivate *priv;
+
+  g_return_if_fail (GCAL_IS_WINDOW (user_data));
+  priv = GCAL_WINDOW (user_data)->priv;
+
+  g_debug ("event_activated: %s", gcal_event_widget_peek_uuid (event_widget));
+  if (priv->add_view == NULL)
+    gcal_window_init_event_view (GCAL_WINDOW (user_data));
+
+  gtk_notebook_set_current_page (
+    GTK_NOTEBOOK (priv->notebook),
+    gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), priv->add_view));
+
+  gcal_event_view_load_event (GCAL_EVENT_VIEW (priv->add_view),
+                              gcal_event_widget_peek_uuid (event_widget));
+}
+
+/* Public API */
+
 GtkWidget*
 gcal_window_new (GcalApplication *app)
 {



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