From 07ac070f08b36855dd2070296f9b88c7b6faa514 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erick=20P=C3=A9rez=20Castellanos?= Date: Tue, 3 Jul 2012 14:55:10 -0400 Subject: [PATCH] First approach of Event view ended. For now the view, works only for viewing, and not for editing. The delete button works, though. It's needed yet a notification for an event deletion. --- src/gcal-application.c | 2 +- src/gcal-event-view.c | 67 +++++++++++++++++++- src/gcal-event-view.h | 3 + src/gcal-event-widget.c | 3 - src/gcal-manager.c | 136 +++++++++++++++++++++++++++++++++++++--- src/gcal-manager.h | 4 ++ src/gcal-month-view.c | 29 ++++++++- src/gcal-view.c | 9 +++ src/gcal-view.h | 12 ++-- src/gcal-window.c | 59 ++++++++++++++--- 10 files changed, 296 insertions(+), 28 deletions(-) diff --git a/src/gcal-application.c b/src/gcal-application.c index 6cceed4d..b3fed3c3 100644 --- a/src/gcal-application.c +++ b/src/gcal-application.c @@ -118,7 +118,7 @@ gcal_application_startup (GApplication *app) error = NULL; gtk_css_provider_load_from_path (priv->provider, CSS_FILE, &error); if (error != NULL) - g_warning ("Not loading stylesheet from file %s", CSS_FILE); + g_warning ("Error loading stylesheet from file %s. %s", CSS_FILE, error->message); } priv->manager = gcal_manager_new (); diff --git a/src/gcal-event-view.c b/src/gcal-event-view.c index 4913bc22..d79c2370 100644 --- a/src/gcal-event-view.c +++ b/src/gcal-event-view.c @@ -55,6 +55,15 @@ struct _GcalEventViewPrivate GcalManager *manager; }; +enum +{ + DONE = 1, + + NUM_SIGNALS +}; + +static guint signals[NUM_SIGNALS] = { 0, }; + static void gcal_event_view_constructed (GObject *object); static void gcal_event_view_finalize (GObject *object); @@ -63,6 +72,9 @@ static void gcal_event_view_set_combo_box (GcalEventView *view); static void gcal_event_view_update (GcalEventView *view); +static void gcal_event_view_delete_event (GtkWidget *button, + gpointer user_data); + G_DEFINE_TYPE(GcalEventView, gcal_event_view, GTK_TYPE_GRID) static void @@ -74,6 +86,15 @@ 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); + g_type_class_add_private((gpointer)klass, sizeof(GcalEventViewPrivate)); } @@ -120,7 +141,6 @@ gcal_event_view_constructed (GObject *object) priv->e_where = gcal_editable_entry_new (); priv->e_widgets = g_slist_append (priv->e_widgets, priv->e_where); - /* FIXME: turn me into a GcalEditable Widget */ priv->cb_cal = gcal_editable_combo_new (); priv->e_widgets = g_slist_append (priv->e_widgets, priv->cb_cal); gtk_widget_set_halign (priv->cb_cal, GTK_ALIGN_START); @@ -197,6 +217,12 @@ gcal_event_view_constructed (GObject *object) gtk_widget_show_all (GTK_WIDGET (object)); gtk_widget_hide (priv->delete_button); + + /* Signals */ + g_signal_connect (priv->delete_button, + "clicked", + G_CALLBACK (gcal_event_view_delete_event), + object); } static void @@ -304,6 +330,24 @@ gcal_event_view_update (GcalEventView *view) } } +static void +gcal_event_view_delete_event (GtkWidget *button, + gpointer user_data) +{ + GcalEventViewPrivate *priv; + + 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); + + /* 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); +} + /* Public API */ /** @@ -336,6 +380,24 @@ gcal_event_view_new_with_manager (GcalManager *manager) void gcal_event_view_load_new (GcalEventView *view) { + GcalEventViewPrivate *priv; + + g_return_if_fail (GCAL_IS_EVENT_VIEW (view)); + priv = view->priv; + + if (priv->source_uid != NULL) + g_free (priv->source_uid); + if (priv->event_uid != NULL) + g_free (priv->event_uid); + + priv->source_uid = NULL; + priv->event_uid = NULL; + + /* Setting the widget to blank state to load a new event */ + g_slist_foreach (priv->e_widgets, (GFunc) gcal_editable_clear, NULL); + + gcal_event_view_update (view); + gcal_event_view_enter_edit_mode (view); } /** @@ -398,7 +460,8 @@ gcal_event_view_enter_edit_mode (GcalEventView *view) NULL); /* showing delete button */ - gtk_widget_show (priv->delete_button); + if (priv->event_uid != NULL) + gtk_widget_show (priv->delete_button); } /** diff --git a/src/gcal-event-view.h b/src/gcal-event-view.h index d1a658b7..395e48fd 100644 --- a/src/gcal-event-view.h +++ b/src/gcal-event-view.h @@ -47,6 +47,9 @@ struct _GcalEventView struct _GcalEventViewClass { GtkGridClass parent_class; + + /* Signals */ + void (*done) (GcalEventView *view); }; GType gcal_event_view_get_type (void); diff --git a/src/gcal-event-widget.c b/src/gcal-event-widget.c index 147aadc0..411ad8c4 100644 --- a/src/gcal-event-widget.c +++ b/src/gcal-event-widget.c @@ -487,9 +487,6 @@ 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); diff --git a/src/gcal-manager.c b/src/gcal-manager.c index d0ef9a10..dcb60959 100644 --- a/src/gcal-manager.c +++ b/src/gcal-manager.c @@ -63,6 +63,15 @@ struct _GcalManagerUnit typedef struct _GcalManagerUnit GcalManagerUnit; +struct _DeleteEventData +{ + gchar *event_uid; + GcalManagerUnit *unit; + GcalManager *manager; +}; + +typedef struct _DeleteEventData DeleteEventData; + struct _GcalManagerPrivate { /** @@ -87,7 +96,7 @@ struct _GcalManagerPrivate /* The active query */ gchar *query; - GCancellable *loading_clients; + GCancellable *async_ops; }; /* Signal IDs */ @@ -143,6 +152,10 @@ static void gcal_manager_on_sources_row_changed (GtkTreeModel *stor GtkTreeIter *iter, gpointer user_data); +static void gcal_manager_on_event_removed (GObject *source_object, + GAsyncResult *result, + gpointer user_data); + G_DEFINE_TYPE(GcalManager, gcal_manager, G_TYPE_OBJECT) static void @@ -172,7 +185,7 @@ gcal_manager_class_init (GcalManagerClass *klass) G_TYPE_NONE, 1, G_TYPE_POINTER); - signals[EVENTS_REMOVED] = g_signal_new ("evens-removed", + signals[EVENTS_REMOVED] = g_signal_new ("events-removed", GCAL_TYPE_MANAGER, G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GcalManagerClass, @@ -328,7 +341,7 @@ gcal_manager_on_client_opened (GObject *source_object, rod = g_new0 (RetryOpenData, 1); rod->client = g_object_ref (client); rod->manager = user_data; - rod->cancellable = g_object_ref (priv->loading_clients); + rod->cancellable = g_object_ref (priv->async_ops); /* postpone for 1/2 of a second, backend is busy now */ g_timeout_add_full (G_PRIORITY_DEFAULT, @@ -357,7 +370,7 @@ gcal_manager_on_client_opened (GObject *source_object, // /* to have them ready for later use */ // e_client_retrieve_capabilities ( -// E_CLIENT (client), manager->priv->loading_clients, +// E_CLIENT (client), manager->priv->async_ops, // cal_model_retrieve_capabilies_cb, model); } @@ -437,9 +450,17 @@ gcal_manager_load_source (GcalManager *manager, g_free, g_object_unref); - g_hash_table_insert (priv->clients, - g_strdup (e_source_peek_uid (source)), - unit); + if (g_hash_table_lookup (priv->clients, e_source_peek_uid (source)) == NULL) + { + g_hash_table_insert (priv->clients, + g_strdup (e_source_peek_uid (source)), + unit); + } + else + { + g_warning ("Reinserting source: %s in priv->clients", + e_source_peek_uid (source)); + } /* filling store */ gdk_color_parse (e_source_peek_color_spec (source), &gdk_color); @@ -453,7 +474,7 @@ gcal_manager_load_source (GcalManager *manager, e_client_open (E_CLIENT (unit->client), TRUE, - priv->loading_clients, + priv->async_ops, gcal_manager_on_client_opened, manager); } @@ -489,7 +510,9 @@ gcal_manager_reload_events (GcalManager *manager) g_hash_table_iter_init (&iter, priv->clients); while (g_hash_table_iter_next (&iter, &key, &value)) { - gcal_manager_reload_view (manager, (GcalManagerUnit*) value); + GcalManagerUnit *unit = (GcalManagerUnit*) value; + if (e_client_is_opened (E_CLIENT (unit->client))) + gcal_manager_reload_view (manager, unit); } } @@ -511,7 +534,7 @@ gcal_manager_reload_view (GcalManager *manager, if (e_cal_client_get_view_sync (unit->client, priv->query, &(unit->view), - priv->loading_clients, + priv->async_ops, &error)) { /*hooking signals */ @@ -622,6 +645,34 @@ gcal_manager_on_view_objects_removed (ECalClientView *view, gpointer objects, gpointer user_data) { + GSList *l; + GSList *events_data; + + ECalClient *client; + const gchar *source_uid; + + events_data = NULL; + client = e_cal_client_view_get_client (view); + source_uid = e_source_peek_uid (e_client_get_source (E_CLIENT (client))); + + for (l = objects; l != NULL; l = l->next) + { + gchar *removed_event_uuid = + g_strdup_printf ("%s:%s", + source_uid, + ((ECalComponentId*)(l->data))->uid); + events_data = g_slist_append (events_data, removed_event_uuid); + } + + if (events_data != NULL) + { + g_signal_emit (GCAL_MANAGER (user_data), + signals[EVENTS_REMOVED], + 0, + events_data); + + g_slist_free_full (events_data, g_free); + } } /** @@ -635,6 +686,7 @@ gcal_manager_on_view_objects_modified (ECalClientView *view, gpointer objects, gpointer user_data) { + g_debug ("Objects modified"); } static void @@ -662,6 +714,36 @@ gcal_manager_on_sources_row_changed (GtkTreeModel *store, g_free (source_uid); } +static void +gcal_manager_on_event_removed (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + ECalClient *client; + DeleteEventData *data; + GError *error; + + client = E_CAL_CLIENT (source_object); + data = (DeleteEventData*) user_data; + + error = NULL; + if (e_cal_client_remove_object_finish (client, result, &error)) + { + /* removing events from hash */ + if (g_hash_table_remove (data->unit->events, data->event_uid)) + g_debug ("Found and removed: %s", data->event_uid); + } + else + { + //FIXME: do something when there was some error + ; + } + + g_free (data->event_uid); + g_free (data); +} + +/* Public API */ /** * gcal_manager_new: * @@ -1185,3 +1267,37 @@ gcal_manager_get_event_reminders (GcalManager *manager, reminders = g_list_reverse (reminders); return reminders; } + +void +gcal_manager_remove_event (GcalManager *manager, + const gchar *source_uid, + const gchar *event_uid) +{ + GcalManagerPrivate *priv; + GcalManagerUnit *unit; + ECalComponent *event; + + g_return_if_fail (GCAL_IS_MANAGER (manager)); + priv = manager->priv; + + unit = g_hash_table_lookup (priv->clients, source_uid); + event = g_hash_table_lookup (unit->events, event_uid); + if (event != NULL) + { + //FIXME: here sends notifications to everyone. + //FIXME: reload the events in all the views, etc, etc, etc + DeleteEventData *data; + + data = g_new0 (DeleteEventData, 1); + data->event_uid = g_strdup (event_uid); + data->unit = unit; + data->manager = manager; + e_cal_client_remove_object (unit->client, + event_uid, + NULL, + CALOBJ_MOD_ALL, + priv->async_ops, + gcal_manager_on_event_removed, + data); + } +} diff --git a/src/gcal-manager.h b/src/gcal-manager.h index 658f2a75..7b736831 100644 --- a/src/gcal-manager.h +++ b/src/gcal-manager.h @@ -112,6 +112,10 @@ GList* gcal_manager_get_event_reminders (GcalManager *manager const gchar *source_uid, const gchar *event_uid); +void gcal_manager_remove_event (GcalManager *manager, + const gchar *source_uid, + const gchar *event_uid); + G_END_DECLS #endif /* __GCAL_MANAGER_H__ */ diff --git a/src/gcal-month-view.c b/src/gcal-month-view.c index 104fe6f7..bd889fb9 100644 --- a/src/gcal-month-view.c +++ b/src/gcal-month-view.c @@ -121,6 +121,8 @@ static void gcal_month_view_draw_month_grid (GcalMonthView *mont_vi 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); G_DEFINE_TYPE_WITH_CODE (GcalMonthView, gcal_month_view, @@ -192,6 +194,7 @@ static void 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; } static void @@ -723,10 +726,34 @@ static gboolean gcal_month_view_is_in_range (GcalView *view, icaltimetype *date) { - g_debug ("Implementation of is_in_range called"); + //FIXME: Add implementation here. + // as it should return TRUE all the time. return TRUE; } +static void +gcal_month_view_remove_by_uuid (GcalView *view, + const gchar *uuid) +{ + GcalMonthViewPrivate *priv; + gint i; + GList *l; + + g_return_if_fail (GCAL_IS_MONTH_VIEW (view)); + 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) + gtk_widget_destroy (GTK_WIDGET (l->data)); + } + } +} + +/* Public API */ /** * gcal_month_view_new: * @date: diff --git a/src/gcal-view.c b/src/gcal-view.c index 8fc772bf..2ef8e11d 100644 --- a/src/gcal-view.c +++ b/src/gcal-view.c @@ -70,3 +70,12 @@ gcal_view_is_in_range (GcalView *view, return GCAL_VIEW_GET_INTERFACE (view)->is_in_range (view, date); } + +void +gcal_view_remove_by_uuid (GcalView *view, + const gchar *uuid) +{ + g_return_if_fail (GCAL_IS_VIEW (view)); + + GCAL_VIEW_GET_INTERFACE (view)->remove_by_uuid (view, uuid); +} diff --git a/src/gcal-view.h b/src/gcal-view.h index 1b1c9ef3..6b0f006b 100644 --- a/src/gcal-view.h +++ b/src/gcal-view.h @@ -40,13 +40,17 @@ struct _GcalViewIface { GTypeInterface parent_iface; - gboolean (*is_in_range) (GcalView *view, icaltimetype *date); + gboolean (*is_in_range) (GcalView *view, icaltimetype *date); + void (*remove_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); G_END_DECLS diff --git a/src/gcal-window.c b/src/gcal-window.c index f7aaee11..1322f598 100644 --- a/src/gcal-window.c +++ b/src/gcal-window.c @@ -40,6 +40,7 @@ struct _GcalWindowPrivate ClutterActor *contents_actor; ClutterActor *notebook_actor; ClutterActor *sources_actor; + ClutterActor *notification_actor; GtkWidget *notebook; GtkWidget *sources_view; @@ -68,7 +69,7 @@ static void gcal_window_sources_shown (GcalToolbar *main_to static void gcal_window_add_event (GcalToolbar *main_toolbar, gpointer user_data); -static void gcal_window_back_last_view (GcalToolbar *main_toolbar, +static void gcal_window_back_last_view (GtkWidget *widget, gpointer user_data); static void gcal_window_edit_event (GcalToolbar *main_toolbar, @@ -86,6 +87,10 @@ static void gcal_window_events_added (GcalManager *manager gpointer events_list, gpointer user_data); +static void gcal_window_events_removed (GcalManager *manager, + gpointer events_list, + gpointer user_data); + static void gcal_window_event_activated (GcalEventWidget *event_widget, gpointer user_data); @@ -373,6 +378,11 @@ gcal_window_init_event_view (GcalWindow *window) "margin-right", 20, NULL); + g_signal_connect (priv->add_view, + "done", + G_CALLBACK (gcal_window_back_last_view), + window); + gtk_widget_show (priv->add_view); gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), priv->add_view, @@ -401,6 +411,9 @@ gcal_window_view_changed (GcalToolbar *main_toolbar, { //TODO create view g_debug ("GcalViewTypeEnum in GcalWindow %d", priv->active_view); + if (priv->active_view == GCAL_VIEW_TYPE_LIST) + { + } } } @@ -444,6 +457,11 @@ gcal_window_add_event (GcalToolbar *main_toolbar, gtk_notebook_set_current_page ( GTK_NOTEBOOK (priv->notebook), gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), priv->add_view)); + + gcal_toolbar_set_mode (GCAL_TOOLBAR (priv->main_toolbar), + GCAL_TOOLBAR_VIEW_EVENT); + + gcal_event_view_load_new (GCAL_EVENT_VIEW (priv->add_view)); } /* @@ -451,7 +469,7 @@ gcal_window_add_event (GcalToolbar *main_toolbar, * need to advice the user and offers him to save/discard the changes */ static void -gcal_window_back_last_view (GcalToolbar *main_toolbar, +gcal_window_back_last_view (GtkWidget *widget, gpointer user_data) { GcalWindowPrivate *priv; @@ -471,8 +489,8 @@ gcal_window_back_last_view (GcalToolbar *main_toolbar, } else { - //TODO create view - g_debug ("GcalViewTypeEnum in GcalWindow %d", priv->active_view); + //FIXME: there's something that needs to be done here. + g_warning ("Your app has gone crazy"); } } @@ -555,8 +573,6 @@ gcal_window_events_added (GcalManager *manager, for (l = events_list; l != NULL; l = l->next) { - g_debug ("Adding events in GcalWindow %d", priv->active_view); - tokens = g_strsplit ((gchar*) l->data, ":", -1); source_uid = tokens[0]; event_uid = tokens[1]; @@ -605,6 +621,31 @@ gcal_window_events_added (GcalManager *manager, } } +static void +gcal_window_events_removed (GcalManager *manager, + gpointer events_list, + gpointer user_data) +{ + GcalWindowPrivate *priv; + GSList *l; + + g_return_if_fail (GCAL_IS_WINDOW (user_data)); + priv = GCAL_WINDOW (user_data)->priv; + + for (l = events_list; l != NULL; l = l->next) + { + gint i; + //FIXME: call destroy widget representing this event in every view. + g_debug ("Removed event: %s", (gchar*) l->data); + for (i = 0; i < 5; i++) + { + if (priv->views[i] != NULL) + gcal_view_remove_by_uuid (GCAL_VIEW (priv->views[i]), + (gchar*) l->data); + } + } +} + static void gcal_window_event_activated (GcalEventWidget *event_widget, gpointer user_data) @@ -614,7 +655,6 @@ gcal_window_event_activated (GcalEventWidget *event_widget, 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)); @@ -650,6 +690,11 @@ gcal_window_new (GcalApplication *app) G_CALLBACK (gcal_window_events_added), win); + g_signal_connect (manager, + "events-removed", + G_CALLBACK (gcal_window_events_removed), + win); + /* FIXME: demo code */ GcalWindowPrivate *priv; icaltimetype *first_day;