From 11070f1d1725019fe68fd1b2cf28aecc87411cf4 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 16 Feb 2016 13:32:35 -0200 Subject: [PATCH] quick-add-popover: new class to handle new events Instead of throwing it all for GcalWindow to handle, add a new class called GcalQuickAddPopover that handles event creation. Events are always all day when created from the quick add popover, unless the user wants to change it and click 'Edit Details' button. In the future, we'll look forward adding natural language support, so the user can type the times directly from the entry (like e.g. "soccer at park from 10am to 11:30am"). --- data/Makefile.am | 1 + data/calendar.gresource.xml | 1 + data/ui/quick-add-popover.ui | 244 ++++++++++++ src/Makefile.am | 2 + src/gcal-quick-add-popover.c | 746 +++++++++++++++++++++++++++++++++++ src/gcal-quick-add-popover.h | 51 +++ 6 files changed, 1045 insertions(+) create mode 100644 data/ui/quick-add-popover.ui create mode 100644 src/gcal-quick-add-popover.c create mode 100644 src/gcal-quick-add-popover.h diff --git a/data/Makefile.am b/data/Makefile.am index 577c312a..48c28373 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -53,6 +53,7 @@ EXTRA_DIST= \ ui/date-selector.ui \ ui/edit-dialog.ui \ ui/menus.ui \ + ui/quick-add-popover.ui \ ui/search-view.ui \ ui/source-dialog.ui \ ui/time-selector.ui \ diff --git a/data/calendar.gresource.xml b/data/calendar.gresource.xml index 7a150e21..70a5116b 100644 --- a/data/calendar.gresource.xml +++ b/data/calendar.gresource.xml @@ -6,6 +6,7 @@ ui/edit-dialog.ui ui/menus.ui ui/online-account-row.ui + ui/quick-add-popover.ui ui/search-view.ui ui/source-dialog.ui ui/time-selector.ui diff --git a/data/ui/quick-add-popover.ui b/data/ui/quick-add-popover.ui new file mode 100644 index 00000000..f52a6598 --- /dev/null +++ b/data/ui/quick-add-popover.ui @@ -0,0 +1,244 @@ + + + + + + + + + + + diff --git a/src/Makefile.am b/src/Makefile.am index d465ece4..597184de 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,6 +42,8 @@ gnome_calendar_SOURCES = \ gcal-manager.h \ gcal-month-view.c \ gcal-month-view.h \ + gcal-quick-add-popover.c \ + gcal-quick-add-popover.h \ gcal-search-view.h \ gcal-search-view.c \ gcal-shell-search-provider.h \ diff --git a/src/gcal-quick-add-popover.c b/src/gcal-quick-add-popover.c new file mode 100644 index 00000000..7f9aad27 --- /dev/null +++ b/src/gcal-quick-add-popover.c @@ -0,0 +1,746 @@ +/* gcal-quick-add-popover.c + * + * Copyright (C) 2016 Georges Basile Stavracas Neto + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "gcal-quick-add-popover.h" +#include "gcal-utils.h" + +struct _GcalQuickAddPopover +{ + GtkPopover parent; + + GtkWidget *add_button; + GtkWidget *calendars_listbox; + GtkWidget *calendar_name_label; + GtkWidget *color_image; + GtkWidget *stack; + GtkWidget *summary_entry; + GtkWidget *title_label; + + /* Internal data */ + GDateTime *date_start; + GDateTime *date_end; + + GtkWidget *selected_row; + + GcalManager *manager; +}; + +G_DEFINE_TYPE (GcalQuickAddPopover, gcal_quick_add_popover, GTK_TYPE_POPOVER) + +enum { + PROP_0, + PROP_DATE_START, + PROP_DATE_END, + PROP_MANAGER, + N_PROPS +}; + +enum +{ + EDIT_EVENT, + NUM_SIGNALS +}; + +static guint signals[NUM_SIGNALS] = { 0, }; + +/* + * Utility functions + */ + +static GtkWidget* +create_row_for_source (GcalManager *manager, + ESource *source, + gboolean writable) +{ + GtkWidget *row, *box, *icon, *label, *selected_icon; + GdkPixbuf *circle_pixbuf; + GdkRGBA color; + gchar *tooltip, *parent_name; + + /* The main box */ + box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); + gtk_widget_set_margin_start (box, 6); + gtk_widget_set_margin_end (box, 6); + gtk_widget_set_margin_top (box, 3); + gtk_widget_set_margin_bottom (box, 3); + + /* The icon with the source color */ + get_color_name_from_source (source, &color); + circle_pixbuf = get_circle_pixbuf_from_color (&color, 16); + icon = gtk_image_new_from_pixbuf (circle_pixbuf); + + gtk_container_add (GTK_CONTAINER (box), icon); + + /* Source name label */ + label = gtk_label_new (e_source_get_display_name (source)); + gtk_widget_set_margin_end (label, 12); + + gtk_container_add (GTK_CONTAINER (box), label); + + /* Selected icon */ + selected_icon = gtk_image_new_from_icon_name ("emblem-ok-symbolic", GTK_ICON_SIZE_BUTTON); + gtk_container_add (GTK_CONTAINER (box), selected_icon); + + /* The row itself */ + row = gtk_list_box_row_new (); + gtk_widget_set_sensitive (row, writable); + + gtk_container_add (GTK_CONTAINER (row), box); + + /* Setup also a cool tooltip */ + get_source_parent_name_color (manager, source, &parent_name, NULL); + + if (writable) + tooltip = g_strdup (parent_name); + else + tooltip = g_strdup_printf (_("%s (this calendar is read-only)"), parent_name); + + gtk_widget_set_tooltip_text (row, tooltip); + + /* + * Setup the row data. A reference for the source is + * taken to make sure it is not destroyed before this + * row. + */ + g_object_set_data_full (G_OBJECT (row), "source", g_object_ref (source), g_object_unref); + g_object_set_data (G_OBJECT (row), "selected-icon", selected_icon); + g_object_set_data (G_OBJECT (row), "color-icon", icon); + g_object_set_data (G_OBJECT (row), "name-label", label); + + gtk_widget_show (label); + gtk_widget_show (icon); + gtk_widget_show (box); + gtk_widget_show (row); + + g_clear_object (&circle_pixbuf); + g_free (parent_name); + g_free (tooltip); + + return row; +} + +/* + * Retrieves the corresponding row for the given + * ESource from the listbox. + */ +static GtkWidget* +get_row_for_source (GcalQuickAddPopover *self, + ESource *source) +{ + GList *children, *l; + GtkWidget *row; + + row = NULL; + children = gtk_container_get_children (GTK_CONTAINER (self->calendars_listbox)); + + for (l = children; l != NULL; l = g_list_next (l)) + { + ESource *row_source = g_object_get_data (l->data, "source"); + + if (row_source == source) + { + row = l->data; + break; + } + } + + g_list_free (children); + + return row; +} + +static void +select_row (GcalQuickAddPopover *self, + GtkListBoxRow *row) +{ + GtkWidget *icon; + GdkPixbuf *circle_pixbuf; + ESource *source; + GdkRGBA color; + + /* First, unselect the previous row */ + if (self->selected_row) + { + icon = g_object_get_data (G_OBJECT (self->selected_row), "selected-icon"); + gtk_widget_set_visible (icon, FALSE); + } + + /* Now, select and save the new row */ + icon = g_object_get_data (G_OBJECT (row), "selected-icon"); + gtk_widget_set_visible (icon, TRUE); + + self->selected_row = GTK_WIDGET (row); + + /* Setup the event page's source name and color */ + source = g_object_get_data (G_OBJECT (row), "source"); + + gtk_label_set_label (GTK_LABEL (self->calendar_name_label), e_source_get_display_name (source)); + + get_color_name_from_source (source, &color); + circle_pixbuf = get_circle_pixbuf_from_color (&color, 16); + gtk_image_set_from_pixbuf (GTK_IMAGE (self->color_image), circle_pixbuf); + + /* Return to the events page */ + gtk_stack_set_visible_child_name (GTK_STACK (self->stack), "events"); + + g_clear_object (&circle_pixbuf); +} + +static void +update_header (GcalQuickAddPopover *self) +{ + icaltimetype *dtstart; + struct tm stm_date, etm_date; + gboolean all_day; + gchar start[64], end[64]; + gchar *title_date; + + all_day = datetime_is_date (self->date_start) && (self->date_end ? datetime_is_date (self->date_end) : TRUE); + dtstart = datetime_to_icaltime (self->date_start); + + /* Translators: + * this is the format string for representing a date consisting of a month name + * and a date of month. + */ + stm_date = icaltimetype_to_tm (dtstart); + e_utf8_strftime_fix_am_pm (start, 64, C_("event date format", "%B %d"), &stm_date); + + if (self->date_end && + (!all_day || + (all_day && g_date_time_difference (self->date_end, self->date_start) / G_TIME_SPAN_DAY > 1))) + { + icaltimetype *dtend; + + dtend = datetime_to_icaltime (self->date_end); + + if (dtend->is_date) + dtend->day--; + + /* Translators: + * this is the format string for representing a date consisting of a month name + * and a date of month. + */ + etm_date = icaltimetype_to_tm (dtend); + e_utf8_strftime_fix_am_pm (end, 64, C_("event date format", "%B %d"), &etm_date); + + title_date = g_strdup_printf (_("New Event from %s to %s"), start, end); + + g_free (dtend); + } + else + { + title_date = g_strdup_printf (_("New Event on %s"), start); + } + + gtk_label_set_label (GTK_LABEL (self->title_label), title_date); + + g_free (title_date); + g_free (dtstart); +} + +/* + * Callbacks + */ + +static void +on_source_added (GcalManager *manager, + ESource *source, + gboolean enabled, + GcalQuickAddPopover *self) +{ + ESource *default_source; + GtkWidget *row; + + default_source = gcal_manager_get_default_source (manager); + row = create_row_for_source (manager, source, gcal_manager_is_client_writable (manager, source)); + + gtk_container_add (GTK_CONTAINER (self->calendars_listbox), row); + + /* Select the default source whe first adding events */ + if (source == default_source && !self->selected_row) + select_row (self, GTK_LIST_BOX_ROW (row)); + + g_clear_object (&default_source); +} + +static void +on_source_changed (GcalManager *manager, + ESource *source, + GcalQuickAddPopover *self) +{ + GtkWidget *row, *color_icon, *name_label; + GdkPixbuf *circle_pixbuf; + GdkRGBA color; + + row = get_row_for_source (self, source); + color_icon = g_object_get_data (G_OBJECT (row), "color-icon"); + name_label = g_object_get_data (G_OBJECT (row), "name-label"); + + /* If the source is writable now (or not), update sensitivity */ + gtk_widget_set_sensitive (row, gcal_manager_is_client_writable (manager, source)); + + /* Setup the source color, in case it changed */ + get_color_name_from_source (source, &color); + circle_pixbuf = get_circle_pixbuf_from_color (&color, 16); + gtk_image_set_from_pixbuf (GTK_IMAGE (color_icon), circle_pixbuf); + + g_clear_object (&circle_pixbuf); + + /* Also setup the row name, in case we just changed the source name */ + gtk_label_set_text (GTK_LABEL (name_label), e_source_get_display_name (source)); + + gtk_list_box_invalidate_sort (GTK_LIST_BOX (self->calendars_listbox)); + + /* + * If the row is the selected one, make a fake selection so the + * icon & name of the source is updated at the events' page. + */ + if (row == self->selected_row) + select_row (self, GTK_LIST_BOX_ROW (row)); +} + +static void +on_source_removed (GcalManager *manager, + ESource *source, + GcalQuickAddPopover *self) +{ + GtkWidget *row; + + row = get_row_for_source (self, source); + + gtk_container_remove (GTK_CONTAINER (self->calendars_listbox), row); +} + +/* Sort the calendars by their display name */ +static gint +sort_func (GtkListBoxRow *row1, + GtkListBoxRow *row2, + gpointer user_data) +{ + ESource *source1, *source2; + gchar *name1, *name2; + gint retval; + + source1 = g_object_get_data (G_OBJECT (row1), "source"); + source2 = g_object_get_data (G_OBJECT (row2), "source"); + + name1 = g_utf8_casefold (e_source_get_display_name (source1), -1); + name2 = g_utf8_casefold (e_source_get_display_name (source2), -1); + + retval = g_strcmp0 (name1, name2); + + g_free (name1); + g_free (name2); + + return retval; +} + +static void +select_calendar_button_clicked (GcalQuickAddPopover *self) +{ + gtk_stack_set_visible_child_name (GTK_STACK (self->stack), "calendars"); +} + +static void +back_button_clicked (GcalQuickAddPopover *self) +{ + gtk_stack_set_visible_child_name (GTK_STACK (self->stack), "events"); +} + +static void +edit_or_create_event (GcalQuickAddPopover *self, + GtkWidget *button) +{ + ECalComponent *component; + GDateTime *date_start, *date_end; + GcalEvent *event; + ESource *source; + const gchar *summary; + + if (!self->selected_row) + return; + + source = g_object_get_data (G_OBJECT (self->selected_row), "source"); + + /* Gather start date */ + date_start = g_date_time_new_local (g_date_time_get_year (self->date_start), + g_date_time_get_month (self->date_start), + g_date_time_get_day_of_month (self->date_start), + 0, 0, 0); + + /* Gather date end */ + if (self->date_end) + { + date_end = g_date_time_new_local (g_date_time_get_year (self->date_end), + g_date_time_get_month (self->date_end), + g_date_time_get_day_of_month (self->date_end), + 0, 0, 0); + } + else + { + date_end = g_date_time_add_days (date_start, 1); + } + + /* Gather the summary */ + if (gtk_entry_get_text_length (GTK_ENTRY (self->summary_entry)) > 0) + summary = gtk_entry_get_text (GTK_ENTRY (self->summary_entry)); + else + summary = _("Unnamed event"); + + /* Create an ECalComponent from the data above */ + component = build_component_from_details (summary, date_start, date_end); + event = gcal_event_new (source, component); + + /* If we clicked edit button, send a signal; otherwise, create the event */ + if (button == self->add_button) + gcal_manager_create_event (self->manager, event); + else + g_signal_emit (self, signals[EDIT_EVENT], 0, event); + + gtk_widget_hide (GTK_WIDGET (self)); + + g_clear_pointer (&date_start, g_date_time_unref); + g_clear_pointer (&date_end, g_date_time_unref); + g_clear_object (&event); +} + +static void +summary_entry_text_changed (GtkEntry *entry, + GParamSpec *pspec, + GcalQuickAddPopover *self) +{ + gtk_widget_set_sensitive (self->add_button, gtk_entry_get_text_length (entry) > 0); +} + +static void +summary_entry_activated (GtkEntry *entry, + GcalQuickAddPopover *self) +{ + if (gtk_entry_get_text_length (entry) > 0) + edit_or_create_event (self, self->add_button); +} + + +/* + * Overrides + */ + +static void +gcal_quick_add_popover_finalize (GObject *object) +{ + GcalQuickAddPopover *self = (GcalQuickAddPopover *)object; + + g_clear_object (&self->manager); + + G_OBJECT_CLASS (gcal_quick_add_popover_parent_class)->finalize (object); +} + +static void +gcal_quick_add_popover_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GcalQuickAddPopover *self = GCAL_QUICK_ADD_POPOVER (object); + + switch (prop_id) + { + case PROP_DATE_END: + g_value_set_boxed (value, self->date_end); + break; + + case PROP_DATE_START: + g_value_set_boxed (value, self->date_start); + break; + + case PROP_MANAGER: + g_value_set_object (value, self->manager); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gcal_quick_add_popover_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GcalQuickAddPopover *self = GCAL_QUICK_ADD_POPOVER (object); + + switch (prop_id) + { + case PROP_DATE_END: + gcal_quick_add_popover_set_date_end (self, g_value_get_boxed (value)); + break; + + case PROP_DATE_START: + gcal_quick_add_popover_set_date_start (self, g_value_get_boxed (value)); + break; + + case PROP_MANAGER: + gcal_quick_add_popover_set_manager (self, g_value_get_object (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gcal_quick_add_popover_closed (GtkPopover *popover) +{ + GcalQuickAddPopover *self; + GtkWidget *default_row; + ESource *default_source; + + self = GCAL_QUICK_ADD_POPOVER (popover); + default_source = gcal_manager_get_default_source (self->manager); + + /* Clear text */ + gtk_entry_set_text (GTK_ENTRY (self->summary_entry), ""); + + /* Select the default row again */ + default_row = get_row_for_source (self, default_source); + select_row (self, GTK_LIST_BOX_ROW (default_row)); + + g_clear_pointer (&self->date_start, g_date_time_unref); + g_clear_pointer (&self->date_end, g_date_time_unref); + g_clear_object (&default_source); +} + +static void +gcal_quick_add_popover_class_init (GcalQuickAddPopoverClass *klass) +{ + GtkPopoverClass *popover_class = GTK_POPOVER_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + popover_class->closed = gcal_quick_add_popover_closed; + + object_class->finalize = gcal_quick_add_popover_finalize; + object_class->get_property = gcal_quick_add_popover_get_property; + object_class->set_property = gcal_quick_add_popover_set_property; + + /** + * GcalQuickAddPopover::edit-event: + * @self: a #GcalQuickAddPopover + * @event: the new #GcalEvent + * + * Emited when the user clicks 'Edit event' button. + */ + signals[EDIT_EVENT] = g_signal_new ("edit-event", + GCAL_TYPE_QUICK_ADD_POPOVER, + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, + 1, + GCAL_TYPE_EVENT); + + /** + * GcalQuickAddPopover::date-end: + * + * The end date of the new event. + */ + g_object_class_install_property (object_class, + PROP_DATE_END, + g_param_spec_boxed ("date-end", + "End date of the event", + "The end date of the new event", + G_TYPE_DATE_TIME, + G_PARAM_READWRITE)); + + /** + * GcalQuickAddPopover::date-start: + * + * The start date of the new event. + */ + g_object_class_install_property (object_class, + PROP_DATE_START, + g_param_spec_boxed ("date-start", + "Start date of the event", + "The start date of the new event", + G_TYPE_DATE_TIME, + G_PARAM_READWRITE)); + + /** + * GcalQuickAddPopover::manager: + * + * The manager of the application. + */ + g_object_class_install_property (object_class, + PROP_MANAGER, + g_param_spec_object ("manager", + "Manager of the application", + "The singleton manager of the application", + GCAL_TYPE_MANAGER, + G_PARAM_READWRITE)); + + gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/calendar/quick-add-popover.ui"); + + gtk_widget_class_bind_template_child (widget_class, GcalQuickAddPopover, add_button); + gtk_widget_class_bind_template_child (widget_class, GcalQuickAddPopover, calendars_listbox); + gtk_widget_class_bind_template_child (widget_class, GcalQuickAddPopover, calendar_name_label); + gtk_widget_class_bind_template_child (widget_class, GcalQuickAddPopover, color_image); + gtk_widget_class_bind_template_child (widget_class, GcalQuickAddPopover, stack); + gtk_widget_class_bind_template_child (widget_class, GcalQuickAddPopover, summary_entry); + gtk_widget_class_bind_template_child (widget_class, GcalQuickAddPopover, title_label); + + gtk_widget_class_bind_template_callback (widget_class, back_button_clicked); + gtk_widget_class_bind_template_callback (widget_class, edit_or_create_event); + gtk_widget_class_bind_template_callback (widget_class, select_calendar_button_clicked); + gtk_widget_class_bind_template_callback (widget_class, select_row); + gtk_widget_class_bind_template_callback (widget_class, summary_entry_activated); + gtk_widget_class_bind_template_callback (widget_class, summary_entry_text_changed); +} + +static void +gcal_quick_add_popover_init (GcalQuickAddPopover *self) +{ + gtk_widget_init_template (GTK_WIDGET (self)); + + gtk_list_box_set_sort_func (GTK_LIST_BOX (self->calendars_listbox), sort_func, NULL, NULL); +} + +GtkWidget* +gcal_quick_add_popover_new (void) +{ + return g_object_new (GCAL_TYPE_QUICK_ADD_POPOVER, NULL); +} + +/** + * gcal_quick_add_popover_set_manager: + * @self: a #GcalQuickAddPopover + * @manager: a #GcalManager + * + * Sets the manager of the popover. + */ +void +gcal_quick_add_popover_set_manager (GcalQuickAddPopover *self, + GcalManager *manager) +{ + g_return_if_fail (GCAL_IS_QUICK_ADD_POPOVER (self)); + + if (g_set_object (&self->manager, manager)) + { + GList *sources, *l; + + /* Add currently leaded sources */ + sources = gcal_manager_get_sources_connected (manager); + + for (l = sources; l != NULL; l = g_list_next (l)) + on_source_added (manager, l->data, gcal_manager_is_client_writable (manager, l->data), self); + + g_list_free (sources); + + /* Connect to the manager signals and keep the list updates */ + g_signal_connect (manager, "source-added", G_CALLBACK (on_source_added), self); + g_signal_connect (manager, "source-changed", G_CALLBACK (on_source_changed), self); + g_signal_connect (manager, "source-removed", G_CALLBACK (on_source_removed), self); + + g_object_notify (G_OBJECT (self), "manager"); + } +} + +/** + * gcal_quick_add_popover_get_date_start: + * @self: a #GcalQuickAddPopover + * + * Retrieves the start date of @self. + * + * Returns: (transfer none): a #GDateTime + */ +GDateTime* +gcal_quick_add_popover_get_date_start (GcalQuickAddPopover *self) +{ + g_return_val_if_fail (GCAL_IS_QUICK_ADD_POPOVER (self), NULL); + + return self->date_start; +} + +/** + * gcal_quick_add_popover_set_date_start: + * @self: a #GcalQuickAddPopover + * @dt: a #GDateTime + * + * Sets the start date of the to-be-created event. + */ +void +gcal_quick_add_popover_set_date_start (GcalQuickAddPopover *self, + GDateTime *dt) +{ + g_return_if_fail (GCAL_IS_QUICK_ADD_POPOVER (self)); + + if (self->date_start != dt && + (!self->date_start || !dt || + (self->date_start && dt && !g_date_time_equal (self->date_start, dt)))) + { + g_clear_pointer (&self->date_start, g_date_time_unref); + self->date_start = g_date_time_ref (dt); + + update_header (self); + + g_object_notify (G_OBJECT (self), "date-start"); + } +} + +/** + * gcal_quick_add_popover_get_date_end: + * @self: a #GcalQuickAddPopover + * + * Retrieves the end date of @self. + * + * Returns: (transfer none): a #GDateTime + */ +GDateTime* +gcal_quick_add_popover_get_date_end (GcalQuickAddPopover *self) +{ + g_return_val_if_fail (GCAL_IS_QUICK_ADD_POPOVER (self), NULL); + + return self->date_end; +} + +/** + * gcal_quick_add_popover_set_date_end: + * @self: a #GcalQuickAddPopover + * @dt: a #GDateTime + * + * Sets the end date of the to-be-created event. + */ +void +gcal_quick_add_popover_set_date_end (GcalQuickAddPopover *self, + GDateTime *dt) +{ + g_return_if_fail (GCAL_IS_QUICK_ADD_POPOVER (self)); + + if (self->date_end != dt && + (!self->date_end || !dt || + (self->date_end && dt && !g_date_time_equal (self->date_end, dt)))) + { + g_clear_pointer (&self->date_end, g_date_time_unref); + self->date_end = g_date_time_ref (dt); + + update_header (self); + + g_object_notify (G_OBJECT (self), "date-end"); + } +} diff --git a/src/gcal-quick-add-popover.h b/src/gcal-quick-add-popover.h new file mode 100644 index 00000000..b2b31800 --- /dev/null +++ b/src/gcal-quick-add-popover.h @@ -0,0 +1,51 @@ +/* gcal-quick-add-popover.h + * + * Copyright (C) 2016 Georges Basile Stavracas Neto + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef GCAL_QUICK_ADD_POPOVER_H +#define GCAL_QUICK_ADD_POPOVER_H + +#include "gcal-event.h" +#include "gcal-manager.h" + +#include +#include + +G_BEGIN_DECLS + +#define GCAL_TYPE_QUICK_ADD_POPOVER (gcal_quick_add_popover_get_type()) + +G_DECLARE_FINAL_TYPE (GcalQuickAddPopover, gcal_quick_add_popover, GCAL, QUICK_ADD_POPOVER, GtkPopover) + +GtkWidget* gcal_quick_add_popover_new (void); + +void gcal_quick_add_popover_set_manager (GcalQuickAddPopover *self, + GcalManager *manager); + +GDateTime* gcal_quick_add_popover_get_date_start (GcalQuickAddPopover *self); + +void gcal_quick_add_popover_set_date_start (GcalQuickAddPopover *self, + GDateTime *dt); + +GDateTime* gcal_quick_add_popover_get_date_end (GcalQuickAddPopover *self); + +void gcal_quick_add_popover_set_date_end (GcalQuickAddPopover *self, + GDateTime *dt); + +G_END_DECLS + +#endif /* GCAL_QUICK_ADD_POPOVER_H */