[gtk+/wip/csoriano/gtkpathbar_rework: 120/120] YAY file management working!



commit 2caeca509f270ecebfa6916a3df1c5b29134610c
Author: Carlos Soriano <csoriano gnome org>
Date:   Thu Mar 19 18:14:27 2015 +0100

    YAY file management working!

 gtk/gtkpathbar.c |  282 ++++++++++++++++++++++++++++++++++++++++++++++++------
 gtk/gtkpathbar.h |    5 +-
 2 files changed, 254 insertions(+), 33 deletions(-)
---
diff --git a/gtk/gtkpathbar.c b/gtk/gtkpathbar.c
index 5f68345..6f092d5 100644
--- a/gtk/gtkpathbar.c
+++ b/gtk/gtkpathbar.c
@@ -102,7 +102,7 @@ struct _ButtonData
   guint file_is_hidden : 1;
 };
 
-G_DEFINE_TYPE_WITH_PRIVATE (GtkPathBar, gtk_path_bar, GTK_TYPE_CONTAINER)
+G_DEFINE_TYPE_WITH_PRIVATE (GtkPathBar, gtk_path_bar, GTK_TYPE_BOX)
 
 static void gtk_path_bar_finalize                 (GObject          *object);
 static void gtk_path_bar_dispose                  (GObject          *object);
@@ -155,6 +155,15 @@ static void gtk_path_bar_on_file_changed (GFileMonitor      *monitor,
                                           GFile             *new_file,
                                           GFileMonitorEvent  event_type,
                                           gpointer          *user_data);
+static ButtonData * make_directory_button (GtkPathBar *path_bar,
+                                           const char *dir_name,
+                                           GFile      *file,
+                                           gboolean    current_dir,
+                                           gboolean    file_is_hidden);
+static void gtk_path_bar_get_info_callback (GObject      *source,
+                                            GAsyncResult *result,
+                                            gpointer      data);
+static void gtk_path_bar_create_buttons_parents_async (GTask *task);
 static void gtk_path_bar_update_path_async (GTask *task);
 
 static void
@@ -1601,12 +1610,44 @@ gtk_path_bar_button_data_monitor_file (ButtonData *button_data)
                                                                      button_data);
 }
 
+#if 0
 static void
-gtk_path_bar_remove_dangling_buttons (GtkPathBar *path_bar,
-                                      ButtonData *button_data,
-                                      GFile      *new_file)
+gtk_path_bar_add_required_buttons (GtkPathBar *path_bar,
+                                   ButtonData *button_data,
+                                   GFile      *new_file)
+{
+  GList *l;
+  GList *prev;
+  GFile *old_file;
+  GFile *old_parent;
+  GFile *current_evaluated_file;
+
+  l = g_list_find (path_bar->priv->button_list, button_data);
+  g_return_if_fail (l != NULL);
+  old_file = button_data->file;
+  old_parent = g_file_get_parent (old_file);
+  /* Start from the direct parent */
+  current_evaluated_file = g_file_get_parent (new_file);
+
+  while (current_evaluated_file != NULL &&
+         g_file_has_prefix (current_evaluated_file, old_parent))
+    {
+      g_print ("while add required %s, %s\n", g_file_get_uri (BUTTON_DATA (l->data)->file), g_file_get_uri 
(new_parent));
+      next = l->next;
+      g_print ("inside\n");
+      gtk_widget_destroy (BUTTON_DATA (l->data)->button);
+      path_bar->priv->button_list = g_list_remove (path_bar->priv->button_list, l->data);
+      l = next;
+    }
+
+  child_ordering_changed (path_bar);
+}
+
+static void
+gtk_path_bar_remove_dangling_buttons_above (GtkPathBar *path_bar,
+                                            ButtonData *button_data,
+                                            GFile      *new_file)
 {
-  GList *new_list;
   GList *l;
   GList *next;
   GFile *new_parent;
@@ -1624,19 +1665,203 @@ gtk_path_bar_remove_dangling_buttons (GtkPathBar *path_bar,
         {
           next = l->next;
           g_print ("inside\n");
-          new_list = g_list_remove (path_bar->priv->button_list, l->data);
+          gtk_widget_destroy (BUTTON_DATA (l->data)->button);
+          path_bar->priv->button_list = g_list_remove (path_bar->priv->button_list, l->data);
           l = next;
         }
       else
         {
-          child_ordering_changed (path_bar);
           break;
         }
     }
 
+  child_ordering_changed (path_bar);
   g_object_unref (new_parent);
 }
 
+#endif
+
+typedef struct _SetFileInfo
+{
+  GFile *file;
+  GFile *parent_file;
+  GtkPathBar *path_bar;
+  GList *new_buttons;
+  gboolean first_directory;
+} SetFileInfo;
+
+typedef struct  _CreateButtonsParentsData {
+  GFile *current_file;
+  ButtonData *first_not_changed_button;
+} CreateButtonsParentsData;
+
+static void
+create_buttons_parents_data_free (CreateButtonsParentsData *data)
+{
+  /* Doesn't free the button data, since that's managed
+   * by the GtkPathBar */
+  g_object_unref (data->current_file);
+  g_slice_free (CreateButtonsParentsData, data);
+}
+
+static void
+gtk_path_bar_create_buttons_parents_on_get_info (GObject      *object,
+                                                 GAsyncResult *result,
+                                                 gpointer      user_data)
+{
+  const gchar *display_name;
+  ButtonData *button_data;
+  CreateButtonsParentsData *task_data;
+  CreateButtonsParentsData *new_task_data;
+  gboolean is_hidden;
+  GTask *task;
+  GtkPathBar *path_bar;
+  GFileInfo *info;
+  GFile *file;
+  GFile *parent_file;
+
+
+  task = (GTask*) user_data;
+  task_data = (CreateButtonsParentsData *) g_task_get_task_data (task);
+  file = task_data->current_file;
+  info = g_file_query_info_finish (file, result, NULL);
+  path_bar = GTK_PATH_BAR (g_task_get_source_object (task));
+
+  g_return_if_fail (info != NULL);
+  g_return_if_fail (path_bar != NULL);
+
+  display_name = g_file_info_get_display_name (info);
+  is_hidden = g_file_info_get_is_hidden (info) || g_file_info_get_is_backup (info);
+  button_data =  make_directory_button (path_bar, display_name, file, FALSE, is_hidden);
+  path_bar->priv->button_list = g_list_append (path_bar->priv->button_list, button_data);
+  gtk_box_pack_start (GTK_BOX (path_bar), button_data->button, TRUE, TRUE, 0);
+
+  /* Update recursively if there is parent */
+  parent_file = g_file_get_parent (file);
+  g_print ("child data ok\n");
+  if (parent_file != NULL && !button_data->is_root)
+    {
+      /* Set the children button data for operating on the next button */
+      new_task_data = g_slice_new (CreateButtonsParentsData);
+      new_task_data->current_file = g_object_ref (parent_file);
+      new_task_data->first_not_changed_button = task_data->first_not_changed_button;
+      g_task_set_task_data (task, new_task_data,
+                            (GDestroyNotify) create_buttons_parents_data_free);
+
+      gtk_path_bar_create_buttons_parents_async (task);
+    }
+  else
+    {
+      g_print ("null ended\n");
+      /* No more button, we finished */
+      g_task_return_pointer (task, NULL, NULL);
+    }
+
+  g_object_unref (info);
+}
+
+static void
+gtk_path_bar_create_buttons_parents_async (GTask *task)
+{
+  GtkPathBar *path_bar;
+  CreateButtonsParentsData *task_data;
+
+  path_bar = GTK_PATH_BAR (g_task_get_source_object (task));
+  task_data = (CreateButtonsParentsData *) g_task_get_task_data (task);
+
+  g_print ("creating parents info for %s\n", g_file_get_uri (task_data->current_file));
+
+  g_file_query_info_async (task_data->current_file,
+                           "standard::display-name,standard::is-hidden,standard::is-backup",
+                           G_FILE_QUERY_INFO_NONE,
+                           G_PRIORITY_DEFAULT,
+                           path_bar->priv->get_info_cancellable,
+                           gtk_path_bar_create_buttons_parents_on_get_info,
+                           task);
+}
+
+static void
+gtk_path_bar_create_buttons_parents (GtkPathBar          *path_bar,
+                                     ButtonData          *first_not_changed_button,
+                                     GFile               *new_file,
+                                     GAsyncReadyCallback  callback)
+{
+  SetFileInfo *info;
+  CreateButtonsParentsData *task_data;
+
+  info = g_new0 (SetFileInfo, 1);
+  info->file = g_object_ref (new_file);
+  info->path_bar = path_bar;
+  info->first_directory = FALSE;
+  info->parent_file = g_file_get_parent (info->file);
+
+  if (path_bar->priv->get_info_cancellable)
+    {
+      g_cancellable_cancel (path_bar->priv->get_info_cancellable);
+      g_object_unref (path_bar->priv->get_info_cancellable);
+    }
+
+  path_bar->priv->get_info_cancellable = g_cancellable_new ();
+
+
+  GTask *task;
+
+  task = g_task_new (path_bar, NULL, callback, new_file);
+  task_data = g_slice_new (CreateButtonsParentsData);
+  task_data ->current_file = g_file_get_parent (new_file);
+  task_data->first_not_changed_button = first_not_changed_button;
+  g_task_set_task_data (task, task_data, (GDestroyNotify) create_buttons_parents_data_free);
+
+  gtk_path_bar_create_buttons_parents_async (task);
+
+}
+
+static void
+gtk_path_bar_remove_buttons_parents (GtkPathBar *path_bar,
+                                     ButtonData *button_data)
+{
+
+  GList *l;
+  GList *next;
+
+  l = g_list_find (path_bar->priv->button_list, button_data);
+  g_return_if_fail (l != NULL);
+
+  l = l->next;
+  while (l != NULL)
+    {
+      next = l->next;
+      g_print ("remove parents %s\n", g_file_get_uri (BUTTON_DATA (l->data)->file));
+      gtk_widget_destroy (BUTTON_DATA (l->data)->button);
+      path_bar->priv->button_list = g_list_remove (path_bar->priv->button_list, l->data);
+      l = next;
+    }
+
+  child_ordering_changed (path_bar);
+}
+
+static void
+gtk_path_bar_remove_buttons_children (GtkPathBar *path_bar,
+                                      ButtonData *button_data)
+{
+  GList *l;
+  GList *prev;
+
+  l = g_list_find (path_bar->priv->button_list, button_data);
+  g_return_if_fail (l != NULL);
+
+  while (l != NULL)
+    {
+      prev = l->prev;
+      g_print ("inside %s\n", g_file_get_uri (BUTTON_DATA (l->data)->file));
+      gtk_widget_destroy (BUTTON_DATA (l->data)->button);
+      path_bar->priv->button_list = g_list_remove (path_bar->priv->button_list, l->data);
+      l = prev;
+    }
+
+  child_ordering_changed (path_bar);
+}
+
 typedef struct  _UpdatePathData {
   GFile *updated_file;
   ButtonData *button_data;
@@ -1652,9 +1877,9 @@ update_path_data_free (UpdatePathData *update_path_data)
 }
 
 static void
-gtk_path_bar_on_file_finished (GObject      *object,
-                               GAsyncResult *result,
-                               gpointer      user_data)
+gtk_path_bar_on_update_path_finished (GObject      *object,
+                                      GAsyncResult *result,
+                                      gpointer      user_data)
 {
   g_print ("callback called!\n");
   GtkPathBar *path_bar;
@@ -1838,7 +2063,7 @@ gtk_path_bar_on_file_changed (GFileMonitor      *monitor,
           renamed_button_data = gtk_path_bar_find_button_from_file (path_bar, file);
           g_return_if_fail (renamed_button_data != NULL);
           gtk_path_bar_update_path (path_bar, renamed_button_data, new_file,
-                                   (GAsyncReadyCallback) gtk_path_bar_on_file_finished);
+                                   (GAsyncReadyCallback) gtk_path_bar_on_update_path_finished);
         }
       else
         {
@@ -1850,6 +2075,10 @@ gtk_path_bar_on_file_changed (GFileMonitor      *monitor,
                * 1- Remove the dangling buttons, those are the buttons that are
                * below the one that is moved */
               g_print ("moved inside current path\n");
+              ButtonData *renamed_button_data;
+
+              renamed_button_data = gtk_path_bar_find_button_from_file (path_bar, file);
+              gtk_path_bar_remove_buttons_children (path_bar, renamed_button_data);
             }
           else
             {
@@ -1857,18 +2086,17 @@ gtk_path_bar_on_file_changed (GFileMonitor      *monitor,
                * 1- Remove the dangling buttons, those are the buttons that are
                * parents of the old file and are no longer children of the old file
                * parent.
-               * 2- Rename buttons from the modified one to the innermost button */
+               * 2- Create necesary buttons if we moved to a longer path.
+               * 3- Rename buttons from the modified one to the innermost button */
               ButtonData *renamed_button_data;
 
+              g_print ("moved outside current path\n");
               renamed_button_data = gtk_path_bar_find_button_from_file (path_bar, file);
               g_assert (renamed_button_data != NULL);
-              gtk_path_bar_remove_dangling_buttons (path_bar, renamed_button_data, new_file);
+              gtk_path_bar_remove_buttons_parents (path_bar, renamed_button_data);
+              gtk_path_bar_create_buttons_parents (path_bar, renamed_button_data, new_file, NULL);
               gtk_path_bar_update_path (path_bar, renamed_button_data, new_file,
-                                        (GAsyncReadyCallback) gtk_path_bar_on_file_finished);
-              //g_object_unref (path_bar->priv->current_path);
-              //path_bar->priv->current_path = g_object_ref (new_file);
-              //_gtk_path_bar_set_file (path_bar, current_path, FALSE);
-              g_print ("moved outside current path\n");
+                                        (GAsyncReadyCallback) gtk_path_bar_on_update_path_finished);
             }
 
           return;
@@ -2024,17 +2252,8 @@ gtk_path_bar_check_parent_path (GtkPathBar         *path_bar,
 }
 
 
-struct SetFileInfo
-{
-  GFile *file;
-  GFile *parent_file;
-  GtkPathBar *path_bar;
-  GList *new_buttons;
-  gboolean first_directory;
-};
-
 static void
-gtk_path_bar_set_file_finish (struct SetFileInfo *info,
+gtk_path_bar_set_file_finish (SetFileInfo *info,
                               gboolean            result)
 {
   if (result)
@@ -2158,12 +2377,13 @@ gtk_path_bar_get_info_callback (GObject      *source,
   GFile *file = G_FILE (source);
   GFileInfo *info;
   GError *error;
-  struct SetFileInfo *file_info = data;
+  SetFileInfo *file_info = data;
   ButtonData *button_data;
   const gchar *display_name;
   gboolean is_hidden;
 
   info = g_file_query_info_finish (file, result, &error);
+  g_print ("get info callback %s\n", g_file_get_uri (file));
 
   if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) || !info)
     {
@@ -2216,7 +2436,7 @@ _gtk_path_bar_set_file (GtkPathBar *path_bar,
                         GFile      *file,
                         gboolean    keep_trail)
 {
-  struct SetFileInfo *info;
+  SetFileInfo *info;
 
   g_return_if_fail (GTK_IS_PATH_BAR (path_bar));
   g_return_if_fail (G_IS_FILE (file));
@@ -2234,7 +2454,7 @@ _gtk_path_bar_set_file (GtkPathBar *path_bar,
   if (keep_trail && gtk_path_bar_check_parent_path (path_bar, file))
     return;
 
-  info = g_new0 (struct SetFileInfo, 1);
+  info = g_new0 (SetFileInfo, 1);
   info->file = g_object_ref (file);
   info->path_bar = path_bar;
   info->first_directory = TRUE;
diff --git a/gtk/gtkpathbar.h b/gtk/gtkpathbar.h
index 8b96b70..9b1e45b 100644
--- a/gtk/gtkpathbar.h
+++ b/gtk/gtkpathbar.h
@@ -19,6 +19,7 @@
 #define __GTK_PATH_BAR_H__
 
 #include "gtkcontainer.h"
+#include "gtkbox.h"
 #include "gtkfilesystem.h"
 
 G_BEGIN_DECLS
@@ -37,14 +38,14 @@ typedef struct _GtkPathBarPrivate GtkPathBarPrivate;
 
 struct _GtkPathBar
 {
-  GtkContainer parent;
+  GtkBox parent;
 
   GtkPathBarPrivate *priv;
 };
 
 struct _GtkPathBarClass
 {
-  GtkContainerClass parent_class;
+  GtkBoxClass parent_class;
 
   void (* path_clicked) (GtkPathBar  *path_bar,
                         GFile       *file,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]