From c9271fcc7a3c2e7a04ae8682c4625afee428c8d6 Mon Sep 17 00:00:00 2001
From: Kevin Lopez <kevin@kevlopez.com>
Date: Sun, 5 Mar 2017 23:18:25 +0100
Subject: [PATCH] Todo.txt: segfaults when selecting empty file.

Using g_free to the source_file member of GTD_PROVIDER_TODO_TXT
struct, causes a segfault.

Since source_file is a GFile and derives from GObject, we have to use
g_clear_object ().

Also when we close the plugin dialog, instead of destroy it we hide
it, so when we open another time the plugin dialog, it shows the last
panel that was visible when we closed the dialog. The correct behavoir
should be that when we click show extensions in the menu, always
should appear the list of extensions.

https://bugzilla.gnome.org/show_bug.cgi?id=778588
---
 data/ui/plugin-dialog.ui                 |  3 +--
 plugins/todo-txt/gtd-provider-todo-txt.c | 16 +++++++++++++++-
 src/gtd-plugin-dialog.c                  | 16 ++++++++++++++++
 3 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/data/ui/plugin-dialog.ui b/data/ui/plugin-dialog.ui
index eadf71b..f9a577e 100644
--- a/data/ui/plugin-dialog.ui
+++ b/data/ui/plugin-dialog.ui
@@ -9,7 +9,7 @@
     <property name="width_request">600</property>
     <property name="height_request">450</property>
     <property name="border_width">0</property>
-    <signal name="delete-event" handler="gtk_widget_hide_on_delete" object="GtdPluginDialog" swapped="yes" />
+    <signal name="delete-event" handler="delete_widget" object="GtdPluginDialog"/>
     <child internal-child="vbox">
       <object class="GtkBox" id="dialog-vbox1">
         <property name="can_focus">False</property>
@@ -21,7 +21,6 @@
             <property name="can_focus">False</property>
             <property name="hexpand">True</property>
             <property name="vexpand">True</property>
-            <property name="transition_type">slide-left-right</property>
             <property name="interpolate_size">True</property>
             <child>
               <object class="GtkScrolledWindow">
diff --git a/plugins/todo-txt/gtd-provider-todo-txt.c b/plugins/todo-txt/gtd-provider-todo-txt.c
index 5fdb320..c08c123 100644
--- a/plugins/todo-txt/gtd-provider-todo-txt.c
+++ b/plugins/todo-txt/gtd-provider-todo-txt.c
@@ -346,6 +346,20 @@ gtd_provider_todo_txt_load_source (GtdProviderTodoTxt *self)
       g_list_free_full (tokens, g_free);
       g_free (line_read);
     }
+
+  if (self->no_of_lines == 0) 
+    {
+      gchar *msg; 
+      gchar *name;
+
+      name = g_file_get_basename (self->source_file);
+      msg = g_strdup_printf (_("%s file is empty, please select a non empty file."), name);
+      gtd_manager_emit_error_message (gtd_manager_get_default (),
+                                      _("The selected Todo.txt file is empty"),
+                                      msg);
+      g_free (msg);
+      g_free (name);
+    }
 }
 
 static void
@@ -1044,7 +1058,7 @@ gtd_provider_todo_txt_finalize (GObject *object)
   g_clear_pointer (&self->lists, g_hash_table_destroy);
   g_clear_pointer (&self->root_tasks, g_hash_table_destroy);
   g_clear_pointer (&self->tasklists, g_clear_object);
-  g_clear_pointer (&self->source_file, g_free);
+  g_clear_object (&self->source_file);
   g_clear_object (&self->icon);
 
   G_OBJECT_CLASS (gtd_provider_todo_txt_parent_class)->finalize (object);
diff --git a/src/gtd-plugin-dialog.c b/src/gtd-plugin-dialog.c
index d9a21b0..b117f58 100644
--- a/src/gtd-plugin-dialog.c
+++ b/src/gtd-plugin-dialog.c
@@ -42,10 +42,24 @@ static void
 back_button_clicked (GtkWidget       *button,
                      GtdPluginDialog *self)
 {
+  gtk_stack_set_transition_type (GTK_STACK (self->stack), GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT);
   gtk_stack_set_visible_child_name (GTK_STACK (self->stack), "list");
   gtk_widget_hide (button);
 }
 
+static gboolean
+delete_widget (GtkWidget *dialog,
+               GdkEvent  *event,
+               gpointer   data)
+{
+  gtk_stack_set_transition_type (GTK_STACK (GTD_PLUGIN_DIALOG(dialog)->stack), GTK_STACK_TRANSITION_TYPE_NONE);
+  gtk_stack_set_visible_child_name (GTK_STACK (GTD_PLUGIN_DIALOG(dialog)->stack), "list");
+  gtk_widget_hide (GTD_PLUGIN_DIALOG(dialog)->back_button);
+  gtk_widget_hide (dialog);
+
+  return TRUE;
+}
+
 static void
 show_preferences_cb (GtdPluginDialogRow *row,
                      PeasPluginInfo     *info,
@@ -76,6 +90,7 @@ show_preferences_cb (GtdPluginDialogRow *row,
     }
 
   /* Last, go to the preferences page */
+  gtk_stack_set_transition_type (GTK_STACK (self->stack), GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT);
   gtk_stack_set_visible_child_name (GTK_STACK (self->stack), "config");
   gtk_widget_show (self->back_button);
 }
@@ -187,6 +202,7 @@ gtd_plugin_dialog_class_init (GtdPluginDialogClass *klass)
   gtk_widget_class_bind_template_child (widget_class, GtdPluginDialog, stack);
 
   gtk_widget_class_bind_template_callback (widget_class, back_button_clicked);
+  gtk_widget_class_bind_template_callback (widget_class, delete_widget);
 }
 
 static void
-- 
2.12.0

