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:
committed by
Erick Pérez Castellanos
parent
c7341d77f0
commit
72eb5dd20b
+705
-616
File diff suppressed because it is too large
Load Diff
+195
-1
@@ -38,6 +38,17 @@ typedef struct
|
|||||||
GtkWidget *remove_button;
|
GtkWidget *remove_button;
|
||||||
GtkWidget *stack;
|
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 */
|
/* new source details */
|
||||||
GtkWidget *author_label;
|
GtkWidget *author_label;
|
||||||
GtkWidget *calendar_address_entry;
|
GtkWidget *calendar_address_entry;
|
||||||
@@ -48,8 +59,9 @@ typedef struct
|
|||||||
GtkWidget *web_sources_listbox;
|
GtkWidget *web_sources_listbox;
|
||||||
GtkWidget *web_sources_revealer;
|
GtkWidget *web_sources_revealer;
|
||||||
|
|
||||||
gint validate_url_resource_id;
|
|
||||||
gint calendar_address_id;
|
gint calendar_address_id;
|
||||||
|
gint validate_url_resource_id;
|
||||||
|
gint notification_timeout_id;
|
||||||
|
|
||||||
/* overview widgets */
|
/* overview widgets */
|
||||||
GtkWidget *add_calendar_menu_button;
|
GtkWidget *add_calendar_menu_button;
|
||||||
@@ -60,6 +72,7 @@ typedef struct
|
|||||||
GcalSourceDialogMode mode;
|
GcalSourceDialogMode mode;
|
||||||
ESource *source;
|
ESource *source;
|
||||||
ESource *remote_source;
|
ESource *remote_source;
|
||||||
|
ESource *removed_source;
|
||||||
ESource *old_default_source;
|
ESource *old_default_source;
|
||||||
GBinding *title_bind;
|
GBinding *title_bind;
|
||||||
gboolean *prompt_password;
|
gboolean *prompt_password;
|
||||||
@@ -1314,6 +1327,177 @@ remove_source (GcalManager *manager,
|
|||||||
g_list_free (children);
|
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 *
|
GcalSourceDialog *
|
||||||
gcal_source_dialog_new (void)
|
gcal_source_dialog_new (void)
|
||||||
{
|
{
|
||||||
@@ -1377,18 +1561,24 @@ gcal_source_dialog_class_init (GcalSourceDialogClass *klass)
|
|||||||
/* bind things for/from the template class */
|
/* 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_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_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, 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, 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_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_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, 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, calendars_listbox);
|
||||||
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, cancel_button);
|
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, default_check);
|
||||||
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, edit_grid);
|
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, 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, 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, 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, remove_button);
|
||||||
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, stack);
|
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, color_set);
|
||||||
gtk_widget_class_bind_template_callback (widget_class, default_check_toggled);
|
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, 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, 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, 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, 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, response_signal);
|
||||||
gtk_widget_class_bind_template_callback (widget_class, stack_visible_child_name_changed);
|
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);
|
gtk_widget_class_bind_template_callback (widget_class, url_entry_text_changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-87
@@ -115,8 +115,6 @@ typedef struct
|
|||||||
gint refresh_timeout;
|
gint refresh_timeout;
|
||||||
gint refresh_timeout_id;
|
gint refresh_timeout_id;
|
||||||
|
|
||||||
ESource *removed_source;
|
|
||||||
|
|
||||||
/* temp to keep event_creation */
|
/* temp to keep event_creation */
|
||||||
gboolean open_edit_dialog;
|
gboolean open_edit_dialog;
|
||||||
} GcalWindowPrivate;
|
} GcalWindowPrivate;
|
||||||
@@ -908,9 +906,7 @@ source_row_activated (GtkListBox *listbox,
|
|||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GcalWindowPrivate *priv = gcal_window_get_instance_private (GCAL_WINDOW (user_data));
|
GcalWindowPrivate *priv = gcal_window_get_instance_private (GCAL_WINDOW (user_data));
|
||||||
GtkWidget *new_row;
|
|
||||||
ESource *source;
|
ESource *source;
|
||||||
gint response;
|
|
||||||
|
|
||||||
source = g_object_get_data (G_OBJECT (row), "source");
|
source = g_object_get_data (G_OBJECT (row), "source");
|
||||||
|
|
||||||
@@ -922,34 +918,9 @@ source_row_activated (GtkListBox *listbox,
|
|||||||
|
|
||||||
gtk_widget_hide (priv->calendar_popover);
|
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);
|
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
|
static void
|
||||||
@@ -1264,36 +1235,6 @@ remove_event (GtkWidget *notification,
|
|||||||
|
|
||||||
g_clear_pointer (&(priv->event_to_delete), g_free);
|
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
|
static void
|
||||||
@@ -1317,33 +1258,6 @@ undo_remove_action (GtkButton *button,
|
|||||||
g_list_free (widgets);
|
g_list_free (widgets);
|
||||||
g_free (uuid);
|
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
|
static gboolean
|
||||||
|
|||||||
Reference in New Issue
Block a user