source-dialog: make remove action local to the dialog

Instead of delegating it to GcalWindow, take
the responsability to manage the source removal
logic.

This commit expose a problem we were trying to
avoid: make our widgets sensitive to source
modifications.
This commit is contained in:
Georges Basile Stavracas Neto
2015-05-25 12:35:33 -04:00
committed by Erick Pérez Castellanos
parent c7341d77f0
commit 72eb5dd20b
3 changed files with 901 additions and 704 deletions
+705 -616
View File
File diff suppressed because it is too large Load Diff
+195 -1
View File
@@ -38,6 +38,17 @@ typedef struct
GtkWidget *remove_button;
GtkWidget *stack;
/* notification */
GtkWidget *notification;
GtkWidget *notification_label;
/* edit page widgets */
GtkWidget *account_box;
GtkWidget *account_label;
GtkWidget *account_dim_label;
GtkWidget *calendar_url_button;
GtkWidget *location_dim_label;
/* new source details */
GtkWidget *author_label;
GtkWidget *calendar_address_entry;
@@ -48,8 +59,9 @@ typedef struct
GtkWidget *web_sources_listbox;
GtkWidget *web_sources_revealer;
gint validate_url_resource_id;
gint calendar_address_id;
gint validate_url_resource_id;
gint notification_timeout_id;
/* overview widgets */
GtkWidget *add_calendar_menu_button;
@@ -60,6 +72,7 @@ typedef struct
GcalSourceDialogMode mode;
ESource *source;
ESource *remote_source;
ESource *removed_source;
ESource *old_default_source;
GBinding *title_bind;
gboolean *prompt_password;
@@ -1314,6 +1327,177 @@ remove_source (GcalManager *manager,
g_list_free (children);
}
/**
* notification_child_revealed_changed:
*
* Remove the source after the notification
* is hidden.
*
* Returns:
*/
static void
notification_child_revealed_changed (GtkWidget *notification,
GParamSpec *spec,
gpointer user_data)
{
GcalSourceDialogPrivate *priv = GCAL_SOURCE_DIALOG (user_data)->priv;
if (gtk_revealer_get_child_revealed (GTK_REVEALER (notification)))
return;
/* If we have any removed source, delete it */
if (priv->removed_source != NULL)
{
GError *error = NULL;
/* We don't really want to remove non-removable sources */
if (!e_source_get_removable (priv->removed_source))
return;
// Enable the source again to remove it's name from disabled list
gcal_manager_enable_source (priv->manager, priv->removed_source);
e_source_remove_sync (priv->removed_source, NULL, &error);
/**
* If something goes wrong, throw
* an alert and add the source back.
*/
if (error != NULL)
{
g_warning ("[source-dialog] Error removing source: %s", error->message);
add_source (priv->manager, priv->removed_source,
gcal_manager_source_enabled (priv->manager, priv->removed_source), user_data);
gcal_manager_enable_source (priv->manager, priv->removed_source);
g_error_free (error);
}
}
}
/**
* undo_remove_action:
*
* Readd the removed source.
*
* Returns:
*/
static void
undo_remove_action (GtkButton *button,
gpointer user_data)
{
GcalSourceDialogPrivate *priv = GCAL_SOURCE_DIALOG (user_data)->priv;
/* if there's any set source, unremove it */
if (priv->removed_source != NULL)
{
// Enable the source before adding it again
gcal_manager_enable_source (priv->manager, priv->removed_source);
add_source (priv->manager, priv->removed_source,
gcal_manager_source_enabled (priv->manager, priv->removed_source), user_data);
/*
* Don't clear the pointer, since we don't
* want to erase the source at all.
*/
priv->removed_source = NULL;
// Hide notification
gtk_revealer_set_reveal_child (GTK_REVEALER (priv->notification), FALSE);
}
}
/**
* hide_notification:
*
* Helper function that hides the
* notification, causing the removal
* of the source (when valid).
*
* Returns:
*/
static void
hide_notification (GcalSourceDialog *dialog,
GtkWidget *button)
{
GcalSourceDialogPrivate *priv = dialog->priv;
gtk_revealer_set_reveal_child (GTK_REVEALER (priv->notification), FALSE);
priv->notification_timeout_id = 0;
}
/**
* hide_notification_scheduled:
*
* Limit the ammount of time that
* the notification is shown.
*
* Returns: %FALSE
*/
static gboolean
hide_notification_scheduled (gpointer dialog)
{
hide_notification (GCAL_SOURCE_DIALOG (dialog), NULL);
return FALSE;
}
/**
* remove_button_clicked:
*
* Trigger the source removal
* logic.
*
* Returns:
*/
static void
remove_button_clicked (GtkWidget *button,
gpointer user_data)
{
GcalSourceDialogPrivate *priv = GCAL_SOURCE_DIALOG (user_data)->priv;
if (priv->source != NULL)
{
GList *children, *l;
gchar *str;
priv->removed_source = priv->source;
priv->source = NULL;
children = gtk_container_get_children (GTK_CONTAINER (priv->calendars_listbox));
gtk_revealer_set_reveal_child (GTK_REVEALER (priv->notification), TRUE);
// Remove the listbox entry (if any)
for (l = children; l != NULL; l = l->next)
{
if (g_object_get_data (l->data, "source") == priv->removed_source)
{
gtk_widget_destroy (l->data);
break;
}
}
// Update notification label
str = g_strdup_printf (_("Calendar <b>%s</b> removed"), e_source_get_display_name (priv->removed_source));
gtk_label_set_markup (GTK_LABEL (priv->notification_label), str);
// Remove old notifications
if (priv->notification_timeout_id != 0)
g_source_remove (priv->notification_timeout_id);
priv->notification_timeout_id = g_timeout_add_seconds (5, hide_notification_scheduled, user_data);
// Disable the source, so it gets hidden
gcal_manager_disable_source (priv->manager, priv->removed_source);
g_list_free (children);
g_free (str);
}
gcal_source_dialog_set_mode (GCAL_SOURCE_DIALOG (user_data), GCAL_SOURCE_DIALOG_MODE_NORMAL);
}
GcalSourceDialog *
gcal_source_dialog_new (void)
{
@@ -1377,18 +1561,24 @@ gcal_source_dialog_class_init (GcalSourceDialogClass *klass)
/* bind things for/from the template class */
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass), "/org/gnome/calendar/source-dialog.ui");
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, account_box);
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, account_label);
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, add_button);
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, add_calendar_menu_button);
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, back_button);
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, calendar_address_entry);
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, calendar_color_button);
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, calendar_url_button);
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, calendar_visible_check);
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, calendars_listbox);
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, cancel_button);
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, default_check);
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, edit_grid);
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, headerbar);
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, location_dim_label);
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, name_entry);
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, notification);
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, notification_label);
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, online_accounts_listbox);
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, remove_button);
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, stack);
@@ -1408,11 +1598,15 @@ gcal_source_dialog_class_init (GcalSourceDialogClass *klass)
gtk_widget_class_bind_template_callback (widget_class, color_set);
gtk_widget_class_bind_template_callback (widget_class, default_check_toggled);
gtk_widget_class_bind_template_callback (widget_class, description_label_link_activated);
gtk_widget_class_bind_template_callback (widget_class, hide_notification);
gtk_widget_class_bind_template_callback (widget_class, name_entry_text_changed);
gtk_widget_class_bind_template_callback (widget_class, new_name_entry_text_changed);
gtk_widget_class_bind_template_callback (widget_class, notification_child_revealed_changed);
gtk_widget_class_bind_template_callback (widget_class, online_accounts_settings_button_clicked);
gtk_widget_class_bind_template_callback (widget_class, remove_button_clicked);
gtk_widget_class_bind_template_callback (widget_class, response_signal);
gtk_widget_class_bind_template_callback (widget_class, stack_visible_child_name_changed);
gtk_widget_class_bind_template_callback (widget_class, undo_remove_action);
gtk_widget_class_bind_template_callback (widget_class, url_entry_text_changed);
}
+1 -87
View File
@@ -115,8 +115,6 @@ typedef struct
gint refresh_timeout;
gint refresh_timeout_id;
ESource *removed_source;
/* temp to keep event_creation */
gboolean open_edit_dialog;
} GcalWindowPrivate;
@@ -908,9 +906,7 @@ source_row_activated (GtkListBox *listbox,
gpointer user_data)
{
GcalWindowPrivate *priv = gcal_window_get_instance_private (GCAL_WINDOW (user_data));
GtkWidget *new_row;
ESource *source;
gint response;
source = g_object_get_data (G_OBJECT (row), "source");
@@ -922,34 +918,9 @@ source_row_activated (GtkListBox *listbox,
gtk_widget_hide (priv->calendar_popover);
response = gtk_dialog_run (GTK_DIALOG (priv->source_dialog));
gtk_dialog_run (GTK_DIALOG (priv->source_dialog));
gtk_widget_hide (priv->source_dialog);
/* remove the row */
gtk_widget_destroy (GTK_WIDGET (row));
if (response == GCAL_RESPONSE_REMOVE_SOURCE)
{
gchar *str;
str = g_strdup_printf (_("Calendar <b>%s</b> removed"), e_source_get_display_name (source));
priv->removed_source = source;
create_notification (GCAL_WINDOW (user_data), str, _("Undo"));
gtk_revealer_set_reveal_child (GTK_REVEALER (priv->notification), TRUE);
gcal_manager_disable_source (priv->manager, source);
g_free (str);
}
else
{
new_row = make_row_from_source (GCAL_WINDOW (user_data), source);
g_object_set_data (G_OBJECT (new_row), "source", source);
gtk_container_add (GTK_CONTAINER (priv->calendar_listbox), new_row);
}
}
static void
@@ -1264,36 +1235,6 @@ remove_event (GtkWidget *notification,
g_clear_pointer (&(priv->event_to_delete), g_free);
}
/* If we have any removed source, finally delete it */
if (priv->removed_source != NULL)
{
GError *error = NULL;
/* We don't really want to remove non-removable sources */
if (!e_source_get_removable (priv->removed_source))
return;
e_source_remove_sync (priv->removed_source, NULL, &error);
/**
* If something goes wrong, throw
* an alert and add the source back.
*/
if (error != NULL)
{
g_warning ("Error removing source: %s", error->message);
add_source (priv->manager, priv->removed_source,
gcal_manager_source_enabled (priv->manager, priv->removed_source), user_data);
gcal_manager_enable_source (priv->manager, priv->removed_source);
g_error_free (error);
}
}
}
static void
@@ -1317,33 +1258,6 @@ undo_remove_action (GtkButton *button,
g_list_free (widgets);
g_free (uuid);
}
/* if there's any set source, unremove it */
if (priv->removed_source != NULL)
{
/**
* Enable the source before adding it again to
* avoid an enabled source with unchecked check
* button.
*/
gcal_manager_enable_source (priv->manager, priv->removed_source);
add_source (priv->manager, priv->removed_source,
gcal_manager_source_enabled (priv->manager, priv->removed_source), user_data);
/**
* Don't clear the pointer, since we don't
* want to erase the source at all.
*/
priv->removed_source = NULL;
}
if (priv->event_to_delete != NULL || priv->removed_source != NULL)
{
g_source_remove (priv->notification_timeout);
hide_notification (GCAL_WINDOW (user_data), NULL);
}
}
static gboolean