window: implement removing and undoing the removal of a calendar
We're still facing the bug where the just-added calendar segfaults when removed.
This commit is contained in:
committed by
Erick Pérez Castellanos
parent
9d222e47fc
commit
9df8b8077d
@@ -100,6 +100,7 @@
|
|||||||
<property name="receives_default">True</property>
|
<property name="receives_default">True</property>
|
||||||
<property name="halign">end</property>
|
<property name="halign">end</property>
|
||||||
<property name="margin_top">6</property>
|
<property name="margin_top">6</property>
|
||||||
|
<signal name="clicked" handler="action_widget_activated" object="GcalSourceDialog" swapped="no"/>
|
||||||
<style>
|
<style>
|
||||||
<class name="destructive-action"/>
|
<class name="destructive-action"/>
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
+1
-4
@@ -145,10 +145,7 @@
|
|||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="receives_default">True</property>
|
||||||
<property name="no_show_all">True</property>
|
<property name="no_show_all">True</property>
|
||||||
<signal name="clicked" handler="undo_remove_event" object="GcalWindow" swapped="no"/>
|
<signal name="clicked" handler="undo_remove_action" object="GcalWindow" swapped="no"/>
|
||||||
<style>
|
|
||||||
<class name="text-button"/>
|
|
||||||
</style>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">1</property>
|
<property name="left_attach">1</property>
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ typedef struct
|
|||||||
GtkWidget *headerbar;
|
GtkWidget *headerbar;
|
||||||
GtkWidget *name_entry;
|
GtkWidget *name_entry;
|
||||||
GtkWidget *notebook;
|
GtkWidget *notebook;
|
||||||
|
GtkWidget *remove_button;
|
||||||
GtkWidget *select_file_button;
|
GtkWidget *select_file_button;
|
||||||
GtkWidget *stack;
|
GtkWidget *stack;
|
||||||
|
|
||||||
@@ -382,6 +383,7 @@ gcal_source_dialog_constructed (GObject *object)
|
|||||||
|
|
||||||
g_object_set_data (G_OBJECT (priv->add_button), "response", GINT_TO_POINTER (GTK_RESPONSE_APPLY));
|
g_object_set_data (G_OBJECT (priv->add_button), "response", GINT_TO_POINTER (GTK_RESPONSE_APPLY));
|
||||||
g_object_set_data (G_OBJECT (priv->cancel_button), "response", GINT_TO_POINTER (GTK_RESPONSE_CANCEL));
|
g_object_set_data (G_OBJECT (priv->cancel_button), "response", GINT_TO_POINTER (GTK_RESPONSE_CANCEL));
|
||||||
|
g_object_set_data (G_OBJECT (priv->remove_button), "response", GINT_TO_POINTER (GCAL_RESPONSE_REMOVE_SOURCE));
|
||||||
|
|
||||||
/* setup titlebar */
|
/* setup titlebar */
|
||||||
gtk_window_set_titlebar (GTK_WINDOW (object), priv->headerbar);
|
gtk_window_set_titlebar (GTK_WINDOW (object), priv->headerbar);
|
||||||
@@ -450,6 +452,7 @@ gcal_source_dialog_class_init (GcalSourceDialogClass *klass)
|
|||||||
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, name_entry);
|
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, name_entry);
|
||||||
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, notebook);
|
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, notebook);
|
||||||
|
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, remove_button);
|
||||||
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, select_file_button);
|
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, select_file_button);
|
||||||
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, stack);
|
gtk_widget_class_bind_template_child_private (widget_class, GcalSourceDialog, stack);
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,8 @@
|
|||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define GCAL_RESPONSE_REMOVE_SOURCE 2
|
||||||
|
|
||||||
#define GCAL_TYPE_SOURCE_DIALOG (gcal_source_dialog_get_type())
|
#define GCAL_TYPE_SOURCE_DIALOG (gcal_source_dialog_get_type())
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE (GcalSourceDialog, gcal_source_dialog, GCAL, SOURCE_DIALOG, GtkDialog)
|
G_DECLARE_FINAL_TYPE (GcalSourceDialog, gcal_source_dialog, GCAL, SOURCE_DIALOG, GtkDialog)
|
||||||
|
|||||||
+86
-12
@@ -115,6 +115,8 @@ typedef struct
|
|||||||
gint refresh_timeout;
|
gint refresh_timeout;
|
||||||
gint refresh_timeout_id;
|
gint refresh_timeout_id;
|
||||||
|
|
||||||
|
ESource *removed_source;
|
||||||
|
|
||||||
GHashTable *calendar_source_to_row;
|
GHashTable *calendar_source_to_row;
|
||||||
|
|
||||||
/* temp to keep event_creation */
|
/* temp to keep event_creation */
|
||||||
@@ -250,7 +252,7 @@ static void remove_event (GtkWidget *n
|
|||||||
GParamSpec *spec,
|
GParamSpec *spec,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
static void undo_remove_event (GtkButton *button,
|
static void undo_remove_action (GtkButton *button,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
static void gcal_window_constructed (GObject *object);
|
static void gcal_window_constructed (GObject *object);
|
||||||
@@ -923,9 +925,11 @@ source_row_activated (GtkListBox *listbox,
|
|||||||
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;
|
GtkWidget *new_row;
|
||||||
ESource *source;
|
ESource *source;
|
||||||
|
gint response;
|
||||||
GList *l, *aux;
|
GList *l, *aux;
|
||||||
|
|
||||||
l = g_hash_table_get_keys (priv->calendar_source_to_row);
|
l = g_hash_table_get_keys (priv->calendar_source_to_row);
|
||||||
|
source = NULL;
|
||||||
|
|
||||||
for (aux = l; aux != NULL; aux = aux->next)
|
for (aux = l; aux != NULL; aux = aux->next)
|
||||||
{
|
{
|
||||||
@@ -941,21 +945,44 @@ source_row_activated (GtkListBox *listbox,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* double check the source */
|
||||||
|
if (source == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
gcal_source_dialog_set_mode (GCAL_SOURCE_DIALOG (priv->source_dialog), GCAL_SOURCE_DIALOG_MODE_EDIT);
|
gcal_source_dialog_set_mode (GCAL_SOURCE_DIALOG (priv->source_dialog), GCAL_SOURCE_DIALOG_MODE_EDIT);
|
||||||
gcal_source_dialog_set_source (GCAL_SOURCE_DIALOG (priv->source_dialog), source);
|
gcal_source_dialog_set_source (GCAL_SOURCE_DIALOG (priv->source_dialog), source);
|
||||||
|
|
||||||
gtk_widget_hide (priv->calendar_popover);
|
gtk_widget_hide (priv->calendar_popover);
|
||||||
|
|
||||||
gtk_dialog_run (GTK_DIALOG (priv->source_dialog));
|
response = gtk_dialog_run (GTK_DIALOG (priv->source_dialog));
|
||||||
|
|
||||||
gtk_widget_hide (priv->source_dialog);
|
gtk_widget_hide (priv->source_dialog);
|
||||||
|
|
||||||
/* update the source */
|
/* update the source */
|
||||||
new_row = make_row_for_source (GCAL_WINDOW (user_data), source);
|
|
||||||
|
|
||||||
g_hash_table_remove (priv->calendar_source_to_row, source);
|
g_hash_table_remove (priv->calendar_source_to_row, source);
|
||||||
g_hash_table_insert (priv->calendar_source_to_row, source, new_row);
|
|
||||||
|
|
||||||
gtk_container_add (GTK_CONTAINER (priv->calendar_listbox), new_row);
|
if (response == GCAL_RESPONSE_REMOVE_SOURCE)
|
||||||
|
{
|
||||||
|
gchar *str;
|
||||||
|
|
||||||
|
str = g_strdup_printf (_("Calendar '%s' 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_for_source (GCAL_WINDOW (user_data), source);
|
||||||
|
|
||||||
|
g_hash_table_insert (priv->calendar_source_to_row, source, new_row);
|
||||||
|
|
||||||
|
gtk_container_add (GTK_CONTAINER (priv->calendar_listbox), new_row);
|
||||||
|
}
|
||||||
|
|
||||||
g_list_free (l);
|
g_list_free (l);
|
||||||
}
|
}
|
||||||
@@ -1283,11 +1310,39 @@ 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
|
||||||
undo_remove_event (GtkButton *button,
|
undo_remove_action (GtkButton *button,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GcalWindowPrivate *priv;
|
GcalWindowPrivate *priv;
|
||||||
gchar *uuid;
|
gchar *uuid;
|
||||||
@@ -1305,11 +1360,30 @@ undo_remove_event (GtkButton *button,
|
|||||||
g_clear_pointer (&(priv->event_to_delete), g_free);
|
g_clear_pointer (&(priv->event_to_delete), g_free);
|
||||||
g_list_free (widgets);
|
g_list_free (widgets);
|
||||||
g_free (uuid);
|
g_free (uuid);
|
||||||
|
|
||||||
g_source_remove (priv->notification_timeout);
|
|
||||||
hide_notification (GCAL_WINDOW (user_data), NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_revealer_set_reveal_child (GTK_REVEALER (priv->notification), FALSE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -1433,7 +1507,7 @@ gcal_window_class_init(GcalWindowClass *klass)
|
|||||||
/* Event removal related */
|
/* Event removal related */
|
||||||
gtk_widget_class_bind_template_callback (widget_class, hide_notification);
|
gtk_widget_class_bind_template_callback (widget_class, hide_notification);
|
||||||
gtk_widget_class_bind_template_callback (widget_class, remove_event);
|
gtk_widget_class_bind_template_callback (widget_class, remove_event);
|
||||||
gtk_widget_class_bind_template_callback (widget_class, undo_remove_event);
|
gtk_widget_class_bind_template_callback (widget_class, undo_remove_action);
|
||||||
|
|
||||||
/* Event creation related */
|
/* Event creation related */
|
||||||
gtk_widget_class_bind_template_callback (widget_class, create_event);
|
gtk_widget_class_bind_template_callback (widget_class, create_event);
|
||||||
|
|||||||
Reference in New Issue
Block a user