[gnome-calendar] Added undo notification system to event deletion.
- From: Erick PÃrez Castellanos <erickpc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-calendar] Added undo notification system to event deletion.
- Date: Wed, 11 Jul 2012 14:50:57 +0000 (UTC)
commit f83143050c67626fbffccdfdb8141298930a30c5
Author: Erick PÃrez Castellanos <erick red gmail com>
Date: Thu Jul 5 00:46:57 2012 -0400
Added undo notification system to event deletion.
Added GcalEventView::will-delete to let thw window knows about the change.
GcalWindow will handle the hiding of the event-widget till the notification goes
away or the user click "Undo".
Added method in GcalView interface to retrieve and event-widget by it's uuid.
Added some cosmetic changes in GcalMonthView as well.
data/gtk-styles.css | 2 +-
src/gcal-event-view.c | 32 ++++++-----
src/gcal-event-view.h | 2 +-
src/gcal-month-view.c | 131 +++++++++++++++++++++++++----------------
src/gcal-view.c | 9 +++
src/gcal-view.h | 18 ++++--
src/gcal-window.c | 153 +++++++++++++++++++++++++++++++++++++++++++++++--
src/gcal-window.h | 2 +
8 files changed, 270 insertions(+), 79 deletions(-)
---
diff --git a/data/gtk-styles.css b/data/gtk-styles.css
index bf496d6..085db3a 100644
--- a/data/gtk-styles.css
+++ b/data/gtk-styles.css
@@ -57,7 +57,7 @@
padding-right: 8px;
}
-GtkClutterOffscreen.sources {
+GtkClutterOffscreen.overlay {
background-color: transparent;
background-image: none;
}
diff --git a/src/gcal-event-view.c b/src/gcal-event-view.c
index 132f36f..8d21ba6 100644
--- a/src/gcal-event-view.c
+++ b/src/gcal-event-view.c
@@ -57,7 +57,7 @@ struct _GcalEventViewPrivate
enum
{
- DONE = 1,
+ WILL_DELETE = 1,
NUM_SIGNALS
};
@@ -86,14 +86,16 @@ gcal_event_view_class_init(GcalEventViewClass *klass)
object_class->constructed = gcal_event_view_constructed;
object_class->finalize = gcal_event_view_finalize;
- signals[DONE] = g_signal_new ("done",
- GCAL_TYPE_EVENT_VIEW,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GcalEventViewClass, done),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
+ signals[WILL_DELETE] = g_signal_new ("will-delete",
+ GCAL_TYPE_EVENT_VIEW,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GcalEventViewClass,
+ will_delete),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
g_type_class_add_private((gpointer)klass, sizeof(GcalEventViewPrivate));
}
@@ -337,17 +339,19 @@ gcal_event_view_delete_event (GtkWidget *button,
gpointer user_data)
{
GcalEventViewPrivate *priv;
+ gchar *event_uuid;
g_return_if_fail (GCAL_IS_EVENT_VIEW (user_data));
priv = GCAL_EVENT_VIEW (user_data)->priv;
- gcal_manager_remove_event (priv->manager,
- priv->source_uid,
- priv->event_uid);
-
+ event_uuid = g_strdup_printf ("%s:%s", priv->source_uid, priv->event_uid);
/* Reset the widget, and let the windows it work it's done */
gcal_event_view_load_new (GCAL_EVENT_VIEW (user_data));
- g_signal_emit (GCAL_EVENT_VIEW (user_data), signals[DONE], 0);
+ g_signal_emit (GCAL_EVENT_VIEW (user_data),
+ signals[WILL_DELETE],
+ 0,
+ event_uuid);
+ g_free (event_uuid);
}
/* Public API */
diff --git a/src/gcal-event-view.h b/src/gcal-event-view.h
index 395e48f..5f4a63e 100644
--- a/src/gcal-event-view.h
+++ b/src/gcal-event-view.h
@@ -49,7 +49,7 @@ struct _GcalEventViewClass
GtkGridClass parent_class;
/* Signals */
- void (*done) (GcalEventView *view);
+ void (*will_delete) (GcalEventView *view, const gchar* event_uuid);
};
GType gcal_event_view_get_type (void);
diff --git a/src/gcal-month-view.c b/src/gcal-month-view.c
index bd889fb..525ce5d 100644
--- a/src/gcal-month-view.c
+++ b/src/gcal-month-view.c
@@ -49,7 +49,7 @@ struct _GcalMonthViewPrivate
icaltimetype *date;
gint days_delay;
- gint header_font_size;
+ gint grid_header_size;
gdouble vertical_step;
gdouble horizontal_step;
};
@@ -66,63 +66,66 @@ const char* weekdays [] =
"Sat"
};
-static void gcal_view_interface_init (GcalViewIface *iface);
+static void gcal_view_interface_init (GcalViewIface *iface);
-static void gcal_month_view_constructed (GObject *object);
+static void gcal_month_view_constructed (GObject *object);
-static void gcal_month_view_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec);
+static void gcal_month_view_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
-static void gcal_month_view_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec);
+static void gcal_month_view_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
-static void gcal_month_view_finalize (GObject *object);
+static void gcal_month_view_finalize (GObject *object);
-static void gcal_month_view_realize (GtkWidget *widget);
+static void gcal_month_view_realize (GtkWidget *widget);
-static void gcal_month_view_unrealize (GtkWidget *widget);
+static void gcal_month_view_unrealize (GtkWidget *widget);
-static void gcal_month_view_map (GtkWidget *widget);
+static void gcal_month_view_map (GtkWidget *widget);
-static void gcal_month_view_unmap (GtkWidget *widget);
+static void gcal_month_view_unmap (GtkWidget *widget);
-static void gcal_month_view_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation);
+static void gcal_month_view_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
-static gboolean gcal_month_view_draw (GtkWidget *widget,
- cairo_t *cr);
+static gboolean gcal_month_view_draw (GtkWidget *widget,
+ cairo_t *cr);
-static gboolean gcal_month_view_button_press (GtkWidget *widget,
- GdkEventButton *event);
+static gboolean gcal_month_view_button_press (GtkWidget *widget,
+ GdkEventButton *event);
-static gboolean gcal_month_view_button_release (GtkWidget *widget,
- GdkEventButton *event);
+static gboolean gcal_month_view_button_release (GtkWidget *widget,
+ GdkEventButton *event);
-static void gcal_month_view_add (GtkContainer *constainer,
- GtkWidget *widget);
+static void gcal_month_view_add (GtkContainer *constainer,
+ GtkWidget *widget);
-static void gcal_month_view_remove (GtkContainer *constainer,
- GtkWidget *widget);
+static void gcal_month_view_remove (GtkContainer *constainer,
+ GtkWidget *widget);
-static void gcal_month_view_forall (GtkContainer *container,
- gboolean include_internals,
- GtkCallback callback,
- gpointer callback_data);
+static void gcal_month_view_forall (GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data);
-static void gcal_month_view_draw_month_grid (GcalMonthView *mont_view,
- cairo_t *cr,
- gint x,
- gint y);
+static void gcal_month_view_draw_month_grid (GcalMonthView *view,
+ cairo_t *cr,
+ gint x,
+ gint y);
-static gboolean gcal_month_view_is_in_range (GcalView *view,
- icaltimetype *date);
+static gboolean gcal_month_view_is_in_range (GcalView *view,
+ icaltimetype *date);
-static void gcal_month_view_remove_by_uuid (GcalView *view,
- const gchar *uuid);
+static void gcal_month_view_remove_by_uuid (GcalView *view,
+ const gchar *uuid);
+
+static GtkWidget* gcal_month_view_get_by_uuid (GcalView *view,
+ const gchar *uuid);
G_DEFINE_TYPE_WITH_CODE (GcalMonthView,
gcal_month_view,
@@ -195,6 +198,7 @@ gcal_view_interface_init (GcalViewIface *iface)
{
iface->is_in_range = gcal_month_view_is_in_range;
iface->remove_by_uuid = gcal_month_view_remove_by_uuid;
+ iface->get_by_uuid = gcal_month_view_get_by_uuid;
}
static void
@@ -386,11 +390,11 @@ gcal_month_view_size_allocate (GtkWidget *widget,
pango_layout_get_pixel_size (layout, NULL, &font_height);
/* init values */
- priv->header_font_size = 12;
+ priv->grid_header_size = 12;
priv->horizontal_step =
(allocation->width - (allocation->x + padding.left + padding.right)) / 7;
priv->vertical_step =
- (allocation->height - (allocation->y + padding.top + padding.bottom + priv->header_font_size)) / 5;
+ (allocation->height - (allocation->y + padding.top + padding.bottom + priv->grid_header_size)) / 5;
for (i = 0; i < 35; i++)
{
@@ -408,12 +412,14 @@ gcal_month_view_size_allocate (GtkWidget *widget,
pos_x = ( i % 7 ) * priv->horizontal_step;
pos_y = ( i / 7 ) * priv->vertical_step;
+ if (! gtk_widget_get_visible (GTK_WIDGET (l->data)))
+ continue;
gtk_widget_get_preferred_height (GTK_WIDGET (l->data),
&min_height,
&natural_height);
child_allocation.x = pos_x + allocation->x + padding.top;
child_allocation.y = pos_y + font_height + allocation->y
- + priv->header_font_size + padding.left;
+ + priv->grid_header_size + padding.left;
child_allocation.width = priv->horizontal_step;
child_allocation.height = MIN (natural_height, priv->vertical_step);
if (added_height + font_height + child_allocation.height
@@ -451,8 +457,8 @@ gcal_month_view_draw (GtkWidget *widget,
gtk_style_context_get_padding (context, state, &padding);
gtk_style_context_get_color (context, state, &color);
- /* header_font_size is found through pango_get_size_in_pixels */
- priv->header_font_size = 12;
+ /* grid_header_size is found through pango_get_size_in_pixels */
+ priv->grid_header_size = 12;
/* getting allocation, and so on */
gtk_widget_get_allocation (widget, &alloc);
@@ -461,7 +467,7 @@ gcal_month_view_draw (GtkWidget *widget,
GCAL_MONTH_VIEW (widget),
cr,
alloc.x + padding.left,
- alloc.y + padding.top + priv->header_font_size);
+ alloc.y + padding.top + priv->grid_header_size);
if (GTK_WIDGET_CLASS (gcal_month_view_parent_class)->draw != NULL)
GTK_WIDGET_CLASS (gcal_month_view_parent_class)->draw (widget, cr);
@@ -500,7 +506,7 @@ gcal_month_view_button_press (GtkWidget *widget,
}
x = x - padding.left;
- y = y - ( padding.top + priv->header_font_size );
+ y = y - ( padding.top + priv->grid_header_size );
priv->clicked_cell = 7 * ( (gint ) ( y / priv->vertical_step )) + ((gint) ( x / priv->horizontal_step ));
return TRUE;
@@ -537,7 +543,7 @@ static gboolean gcal_month_view_button_release (GtkWidget *widget,
}
x = x - padding.left;
- y = y - ( padding.top + priv->header_font_size );
+ y = y - ( padding.top + priv->grid_header_size );
released = 7 * ( (gint ) ( y / priv->vertical_step )) + ((gint) ( x / priv->horizontal_step ));
if (priv->clicked_cell == released)
@@ -624,7 +630,7 @@ gcal_month_view_forall (GtkContainer *container,
}
static void
-gcal_month_view_draw_month_grid (GcalMonthView *month_view,
+gcal_month_view_draw_month_grid (GcalMonthView *view,
cairo_t *cr,
gint x,
gint y)
@@ -645,8 +651,8 @@ gcal_month_view_draw_month_grid (GcalMonthView *month_view,
PangoLayout *layout;
gchar *day;
- priv = month_view->priv;
- widget = GTK_WIDGET (month_view);
+ priv = view->priv;
+ widget = GTK_WIDGET (view);
context = gtk_widget_get_style_context (widget);
state = gtk_widget_get_state_flags (widget);
@@ -753,6 +759,29 @@ gcal_month_view_remove_by_uuid (GcalView *view,
}
}
+static GtkWidget*
+gcal_month_view_get_by_uuid (GcalView *view,
+ const gchar *uuid)
+{
+ GcalMonthViewPrivate *priv;
+ gint i;
+ GList *l;
+
+ g_return_val_if_fail (GCAL_IS_MONTH_VIEW (view), NULL);
+ priv = GCAL_MONTH_VIEW (view)->priv;
+
+ for (i = 0; i < 35; i++)
+ {
+ for (l = priv->days[i]; l != NULL; l = l->next)
+ {
+ const gchar* widget_uuid = gcal_event_widget_peek_uuid (GCAL_EVENT_WIDGET (l->data));
+ if (g_strcmp0 (uuid, widget_uuid) == 0)
+ return GTK_WIDGET (l->data);
+ }
+ }
+ return NULL;
+}
+
/* Public API */
/**
* gcal_month_view_new:
diff --git a/src/gcal-view.c b/src/gcal-view.c
index 2ef8e11..44728a9 100644
--- a/src/gcal-view.c
+++ b/src/gcal-view.c
@@ -79,3 +79,12 @@ gcal_view_remove_by_uuid (GcalView *view,
GCAL_VIEW_GET_INTERFACE (view)->remove_by_uuid (view, uuid);
}
+
+GtkWidget*
+gcal_view_get_by_uuid (GcalView *view,
+ const gchar *uuid)
+{
+ g_return_val_if_fail (GCAL_IS_VIEW (view), NULL);
+
+ return GCAL_VIEW_GET_INTERFACE (view)->get_by_uuid (view, uuid);
+}
diff --git a/src/gcal-view.h b/src/gcal-view.h
index 6b0f006..de2d3ef 100644
--- a/src/gcal-view.h
+++ b/src/gcal-view.h
@@ -40,17 +40,21 @@ struct _GcalViewIface
{
GTypeInterface parent_iface;
- gboolean (*is_in_range) (GcalView *view, icaltimetype *date);
- void (*remove_by_uuid) (GcalView *view, const gchar *uuid);
+ gboolean (*is_in_range) (GcalView *view, icaltimetype *date);
+ void (*remove_by_uuid) (GcalView *view, const gchar *uuid);
+ GtkWidget* (*get_by_uuid) (GcalView *view, const gchar *uuid);
};
-GType gcal_view_get_type (void);
+GType gcal_view_get_type (void);
-gboolean gcal_view_is_in_range (GcalView *view,
- icaltimetype *date);
+gboolean gcal_view_is_in_range (GcalView *view,
+ icaltimetype *date);
-void gcal_view_remove_by_uuid (GcalView *view,
- const gchar *uuid);
+void gcal_view_remove_by_uuid (GcalView *view,
+ const gchar *uuid);
+
+GtkWidget* gcal_view_get_by_uuid (GcalView *view,
+ const gchar *uuid);
G_END_DECLS
diff --git a/src/gcal-window.c b/src/gcal-window.c
index 1322f59..46b095b 100644
--- a/src/gcal-window.c
+++ b/src/gcal-window.c
@@ -26,9 +26,11 @@
#include "gcal-event-widget.h"
#include "gcal-event-view.h"
#include "gcal-utils.h"
+#include "gtk-notification.h"
#include <clutter/clutter.h>
#include <clutter-gtk/clutter-gtk.h>
+#include <glib/gi18n.h>
#include <libedataserverui/e-cell-renderer-color.h>
@@ -48,6 +50,9 @@ struct _GcalWindowPrivate
GtkWidget *add_view;
GcalViewTypeEnum active_view;
+
+ /* temp to keep the will_delete event uuid */
+ gchar *event_to_delete;
};
static void gcal_window_constructed (GObject *object);
@@ -94,6 +99,16 @@ static void gcal_window_events_removed (GcalManager *manager
static void gcal_window_event_activated (GcalEventWidget *event_widget,
gpointer user_data);
+static void gcal_window_will_remove_event (GcalEventView *view,
+ gchar *event_uuid,
+ gpointer user_data);
+
+static void gcal_window_remove_event (GtkNotification *notification,
+ gpointer user_data);
+
+static void gcal_window_undo_remove_event (GtkButton *button,
+ gpointer user_data);
+
G_DEFINE_TYPE(GcalWindow, gcal_window, GTK_TYPE_APPLICATION_WINDOW)
static void
@@ -131,6 +146,10 @@ gcal_window_constructed (GObject *object)
priv = GCAL_WINDOW (object)->priv;
+ /* internal data init*/
+ priv->event_to_delete = NULL;
+
+ /* ui init */
embed = gtk_clutter_embed_new ();
gtk_container_add (GTK_CONTAINER (object), embed);
stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (embed));
@@ -240,8 +259,6 @@ gcal_window_constructed (GObject *object)
/* notifications manager */
priv->notification_actor = gtk_clutter_actor_new ();
- clutter_actor_set_opacity (priv->notification_actor, 0);
- clutter_actor_set_clip_to_allocation (priv->notification_actor, TRUE);
clutter_bin_layout_add (CLUTTER_BIN_LAYOUT (contents_layout_manager),
priv->notification_actor,
CLUTTER_BIN_ALIGNMENT_CENTER,
@@ -379,8 +396,8 @@ gcal_window_init_event_view (GcalWindow *window)
NULL);
g_signal_connect (priv->add_view,
- "done",
- G_CALLBACK (gcal_window_back_last_view),
+ "will-delete",
+ G_CALLBACK (gcal_window_will_remove_event),
window);
gtk_widget_show (priv->add_view);
@@ -669,8 +686,120 @@ gcal_window_event_activated (GcalEventWidget *event_widget,
GCAL_TOOLBAR_VIEW_EVENT);
}
-/* Public API */
+static void
+gcal_window_will_remove_event (GcalEventView *view,
+ gchar *event_uuid,
+ gpointer user_data)
+{
+ GcalWindowPrivate *priv;
+ gint activated_page;
+
+ GtkWidget *noty;
+ GtkWidget *grid;
+ GtkWidget *undo_button;
+
+ GtkWidget *event_widget;
+
+ priv = GCAL_WINDOW (user_data)->priv;
+
+ gcal_toolbar_set_mode (GCAL_TOOLBAR (priv->main_toolbar),
+ GCAL_TOOLBAR_OVERVIEW);
+
+ if ((activated_page = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook),
+ priv->views[priv->active_view]))
+ != -1)
+ {
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook),
+ activated_page);
+ }
+ else
+ {
+ //FIXME: there's something that needs to be done here.
+ g_warning ("Your app has gone crazy");
+ }
+
+ noty = gtk_notification_new ();
+ grid = gtk_grid_new ();
+ gtk_grid_set_column_spacing (GTK_GRID (grid), 12);
+ gtk_container_add (GTK_CONTAINER (grid), gtk_label_new (_("Event deleted")));
+
+ undo_button = gtk_button_new_from_stock (GTK_STOCK_UNDO);
+ gtk_container_add (GTK_CONTAINER (grid), undo_button);
+
+ gtk_container_add (GTK_CONTAINER (noty), grid);
+ gtk_widget_show_all (noty);
+ gcal_window_show_notification (GCAL_WINDOW (user_data), noty);
+
+ g_signal_connect (noty,
+ "dismissed",
+ G_CALLBACK (gcal_window_remove_event),
+ user_data);
+ g_signal_connect (undo_button,
+ "clicked",
+ G_CALLBACK (gcal_window_undo_remove_event),
+ user_data);
+
+ priv->event_to_delete = g_strdup (event_uuid);
+
+ /* hide widget of the event */
+ event_widget =
+ gcal_view_get_by_uuid (GCAL_VIEW (priv->views[priv->active_view]),
+ priv->event_to_delete);
+ gtk_widget_hide (event_widget);
+}
+
+static void
+gcal_window_remove_event (GtkNotification *notification,
+ gpointer user_data)
+{
+ GcalWindowPrivate *priv;
+ GcalManager *manager;
+ gchar **tokens;
+
+ g_return_if_fail (GCAL_IS_WINDOW (user_data));
+ priv = GCAL_WINDOW (user_data)->priv;
+
+ if (priv->event_to_delete != NULL)
+ {
+ manager = gcal_window_get_manager (GCAL_WINDOW (user_data));
+ tokens = g_strsplit (priv->event_to_delete, ":", -1);
+
+ gcal_manager_remove_event (manager, tokens[0], tokens[1]);
+
+ g_strfreev (tokens);
+ g_free (priv->event_to_delete);
+ priv->event_to_delete = NULL;
+ }
+
+ clutter_actor_hide (priv->notification_actor);
+}
+static void
+gcal_window_undo_remove_event (GtkButton *button,
+ gpointer user_data)
+{
+ GcalWindowPrivate *priv;
+ GtkWidget *event_widget;
+
+ g_return_if_fail (GCAL_IS_WINDOW (user_data));
+ priv = GCAL_WINDOW (user_data)->priv;
+
+ if (priv->event_to_delete != NULL)
+ {
+ event_widget = gcal_view_get_by_uuid (
+ GCAL_VIEW (priv->views[priv->active_view]),
+ priv->event_to_delete);
+ gtk_widget_show (event_widget);
+
+ g_free (priv->event_to_delete);
+ priv->event_to_delete = NULL;
+
+ gcal_window_hide_notification (GCAL_WINDOW (user_data));
+ }
+
+}
+
+/* Public API */
GtkWidget*
gcal_window_new (GcalApplication *app)
{
@@ -727,3 +856,17 @@ gcal_window_show_notification (GcalWindow *window,
gtk_widget_show_all (notification);
clutter_actor_show (priv->notification_actor);
}
+
+void
+gcal_window_hide_notification (GcalWindow *window)
+{
+ GcalWindowPrivate *priv;
+ GtkWidget *noty;
+
+ g_return_if_fail (GCAL_IS_WINDOW (window));
+ priv = window->priv;
+
+ noty = gtk_clutter_actor_get_contents (
+ GTK_CLUTTER_ACTOR (priv->notification_actor));
+ gtk_notification_dismiss (GTK_NOTIFICATION (noty));
+}
diff --git a/src/gcal-window.h b/src/gcal-window.h
index 0ac0de6..6a399fa 100644
--- a/src/gcal-window.h
+++ b/src/gcal-window.h
@@ -58,6 +58,8 @@ GtkWidget* gcal_window_new (GcalApplication *app);
void gcal_window_show_notification (GcalWindow *window,
GtkWidget *notification);
+void gcal_window_hide_notification (GcalWindow *window);
+
G_END_DECLS
#endif /* __GCAL_WINDOW_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]