[gnome-commander] WIP: Remove the call of gnome_vfs_directory_list_load()



commit bcd73728b1462959cdb9efaec7d5361dd96afc8d
Author: Uwe Scholz <u scholz83 gmx de>
Date:   Tue May 11 21:18:51 2021 +0200

    WIP: Remove the call of gnome_vfs_directory_list_load()
    
    For doing that I had to change and migrate many methods as we are moving away from
    using GnomeVFSFileInfo, instead we are using GFileInfo now. But the transition is
    not finished yet and the commit here is only preliminary work.
    
    For example, Gnome Commander can be started at the moment, but the file names in
    the left and right panes are not shown. This and more has to be fixed later on.
    
    When jumping to the upper directory, the programm crashes.

 src/dirlist.cc                 |  83 +++++++++++++++++++++++-
 src/gnome-cmd-con.cc           |   5 ++
 src/gnome-cmd-dir.cc           | 142 +++++++++++++++++++++++++++++++----------
 src/gnome-cmd-dir.h            |  42 ++++++++----
 src/gnome-cmd-file-list.cc     |   8 +--
 src/gnome-cmd-file-selector.cc |   2 +-
 src/gnome-cmd-file.cc          | 114 ++++++++++++++++++++++++++++++---
 src/gnome-cmd-file.h           |   5 ++
 src/utils.cc                   |  48 ++++++++++++++
 src/utils.h                    |   4 ++
 10 files changed, 393 insertions(+), 60 deletions(-)
---
diff --git a/src/dirlist.cc b/src/dirlist.cc
index f531b0db..f60ad5c6 100644
--- a/src/dirlist.cc
+++ b/src/dirlist.cc
@@ -112,21 +112,98 @@ void async_list (GnomeCmdDir *dir)
     g_timeout_add (gnome_cmd_data.gui_update_rate, (GSourceFunc) update_list_progress, dir);
 }
 
+static void enumerate_children_callback(GObject *direnum, GAsyncResult *result, gpointer user_data);
 
 void sync_list (GnomeCmdDir *dir)
 {
-    GnomeVFSFileInfoOptions infoOpts = (GnomeVFSFileInfoOptions) (GNOME_VFS_FILE_INFO_FOLLOW_LINKS | 
GNOME_VFS_FILE_INFO_GET_MIME_TYPE);
+    GError *error = nullptr;
+    //GnomeVFSFileInfoOptions infoOpts = (GnomeVFSFileInfoOptions) (GNOME_VFS_FILE_INFO_FOLLOW_LINKS | 
GNOME_VFS_FILE_INFO_GET_MIME_TYPE);
 
     gchar *uri_str = GNOME_CMD_FILE (dir)->get_uri_str();
     DEBUG('l', "sync_list: %s\n", uri_str);
 
     dir->infolist = NULL;
-    dir->list_result = gnome_vfs_directory_list_load (&dir->infolist, uri_str, infoOpts);
+    //dir->list_result = gnome_vfs_directory_list_load (&dir->infolist, uri_str, infoOpts);
+
+    auto gFile = GNOME_CMD_FILE (dir)->gFile;
+
+    auto gFileEnumerator = g_file_enumerate_children (gFile,
+                            "*",
+                            G_FILE_QUERY_INFO_NONE,
+                            nullptr,
+                            &error);
+    if( error )
+    {
+        g_critical("Unable to enumerate children, error: %s", error->message);
+        g_error_free(error);
+        return;
+    }
+
+    //GList *gFileInfoList = nullptr;
+    g_file_enumerator_next_files_async(gFileEnumerator,
+                    2,
+                    G_PRIORITY_LOW,
+                    nullptr,
+                    enumerate_children_callback,
+                    dir);
+
+    //enumerate_children_callback(G_OBJECT(gFileEnumerator), nullptr, dir);
+    g_object_unref(gFileEnumerator);
 
     g_free (uri_str);
 
     dir->state = dir->list_result==GNOME_VFS_OK ? GnomeCmdDir::STATE_LISTED : GnomeCmdDir::STATE_EMPTY;
-    dir->done_func (dir, dir->infolist, dir->list_result);
+    //dir->done_func (dir, dir->infolist, dir->list_result);
+    //dir->done_func (dir, dir->gFileInfoList, dir->list_result);
+}
+
+static void enumerate_children_callback(GObject *direnum, GAsyncResult *result, gpointer user_data)
+{
+    auto gFileEnumerator = G_FILE_ENUMERATOR(direnum);
+    auto dir = GNOME_CMD_DIR(user_data);
+    GError *error = nullptr;
+
+    GList *gFileInfosList = g_file_enumerator_next_files_finish( gFileEnumerator,
+                    result, &error);
+    if( error )
+    {
+        g_critical("Unable to add files to list, error: %s", error->message);
+        g_object_unref(direnum);
+        g_error_free(error);
+        return;
+    }
+    else if( gFileInfosList == nullptr )
+    {
+        /* DONE */
+        dir->state = dir->list_result==GNOME_VFS_OK ? GnomeCmdDir::STATE_LISTED : GnomeCmdDir::STATE_EMPTY;
+        dir->done_func (dir, dir->gFileInfoList, dir->list_result);
+        g_object_unref(direnum);
+        return;
+    }
+    else
+    {
+        dir->gFileInfoList = g_list_concat (dir->gFileInfoList, g_list_copy (gFileInfosList));
+        //g_list_foreach (list, (GFunc) gnome_vfs_file_info_ref, NULL);
+        //dir->list_counter += entries_read;
+        //DEBUG ('l', "files listed: %d\n", dir->list_counter);
+
+        //GList *node = gFileInfosList;
+        //GFileInfo *info;
+        //while(node)
+        //{
+        //    info = (GFileInfo *) node->data;
+        //    node = node->next;
+        //    g_object_unref(info);
+        //}
+
+        g_file_enumerator_next_files_async(G_FILE_ENUMERATOR(direnum),
+                        20,
+                        G_PRIORITY_LOW,
+                        nullptr,
+                        enumerate_children_callback,
+                        dir);
+    }
+    g_list_free(gFileInfosList);
 }
 
 
diff --git a/src/gnome-cmd-con.cc b/src/gnome-cmd-con.cc
index 87e639c8..f8b7f66e 100644
--- a/src/gnome-cmd-con.cc
+++ b/src/gnome-cmd-con.cc
@@ -483,6 +483,11 @@ void gnome_cmd_con_add_to_cache (GnomeCmdCon *con, GnomeCmdDir *dir)
 
     gchar *uri_str = GNOME_CMD_FILE (dir)->get_uri_str();
 
+    if (uri_str == nullptr)
+    {
+        return;
+    }
+
     if (!con->priv->all_dirs_map)
         con->priv->all_dirs_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, nullptr);
 
diff --git a/src/gnome-cmd-dir.cc b/src/gnome-cmd-dir.cc
index b1af50d6..dbc13000 100644
--- a/src/gnome-cmd-dir.cc
+++ b/src/gnome-cmd-dir.cc
@@ -270,6 +270,47 @@ GnomeCmdDir *gnome_cmd_dir_new_from_info (GnomeVFSFileInfo *info, GnomeCmdDir *p
 }
 
 
+GnomeCmdDir *gnome_cmd_dir_new_from_gfileinfo (GFileInfo *gFileInfo, GnomeCmdDir *parent)
+{
+    g_return_val_if_fail (gFileInfo != nullptr, nullptr);
+    g_return_val_if_fail (GNOME_CMD_IS_DIR (parent), nullptr);
+
+    GnomeCmdCon *con = gnome_cmd_dir_get_connection (parent);
+    auto basename = g_file_info_get_display_name(gFileInfo);
+    GnomeCmdPath *path = gnome_cmd_dir_get_path (parent)->get_child(basename);
+    if (!path)
+    {
+        return nullptr;
+    }
+
+    GnomeVFSURI *uri = gnome_cmd_con_create_uri (con, path);
+    gchar *uri_str = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_PASSWORD);
+
+    // ToDo: Do it with gFile!
+    GnomeCmdDir *dir = gnome_cmd_con_cache_lookup (gnome_cmd_dir_get_connection (parent), uri_str);
+    g_free (uri_str);
+    gnome_vfs_uri_unref (uri);
+
+    if (dir)
+    {
+        delete path;
+        GNOME_CMD_FILE (dir)->update_gFileInfo(gFileInfo);
+        return dir;
+    }
+
+    dir = static_cast<GnomeCmdDir*> (g_object_new (GNOME_CMD_TYPE_DIR, nullptr));
+    gnome_cmd_file_setup (GNOME_CMD_FILE (dir), gFileInfo, parent);
+
+    dir->priv->con = con;
+    gnome_cmd_dir_set_path (dir, path);
+    dir->priv->needs_mtime_update = FALSE;
+
+    gnome_cmd_con_add_to_cache (gnome_cmd_dir_get_connection (parent), dir);
+
+    return dir;
+}
+
+
 GnomeCmdDir *gnome_cmd_dir_new_with_con (GnomeCmdCon *con)
 {
     g_return_val_if_fail (GNOME_CMD_IS_CON (con), nullptr);
@@ -320,13 +361,19 @@ GnomeCmdDir *gnome_cmd_dir_new (GnomeCmdCon *con, GnomeCmdPath *path, gboolean i
     auto infoOpts = (GnomeVFSFileInfoOptions) (GNOME_VFS_FILE_INFO_FOLLOW_LINKS | 
GNOME_VFS_FILE_INFO_GET_MIME_TYPE | GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE);
     auto gnomeVFSFileInfo = gnome_vfs_file_info_new ();
     auto gnomeVFSResult = gnome_vfs_get_file_info_uri (gnomeVFSUri, gnomeVFSFileInfo, infoOpts);
+
+    //ToDo. Verallgemeinere das mit _from_uri()!
+    auto gFileTmp = g_file_new_for_path(path->get_path());
+    auto gFileInfo = g_file_query_info(gFileTmp, "*", G_FILE_QUERY_INFO_NONE, nullptr, nullptr);
+    g_object_unref(gFileTmp);
+
     gnome_vfs_uri_unref (gnomeVFSUri);
 
     if (gnomeVFSResult == GNOME_VFS_OK)
     {
         dir = static_cast<GnomeCmdDir*> (g_object_new (GNOME_CMD_TYPE_DIR, nullptr));
         gnome_cmd_dir_set_path (dir, path);
-        gnome_cmd_file_setup (GNOME_CMD_FILE (dir), gnomeVFSFileInfo, nullptr);
+        gnome_cmd_file_setup (GNOME_CMD_FILE (dir), gFileInfo, nullptr);
 
         dir->priv->con = con;
         dir->priv->needs_mtime_update = FALSE;
@@ -396,7 +443,56 @@ GList *gnome_cmd_dir_get_files (GnomeCmdDir *dir)
 }
 
 
-static GList *create_file_list (GnomeCmdDir *dir, GList *info_list)
+//static GList *create_file_list (GnomeCmdDir *dir, GList *info_list)
+//{
+//    GList *file_list = nullptr;
+//
+//    // create a new list with GnomeCmdFile objects
+//
+//    for (GList *i = info_list; i; i = i->next)
+//    {
+//        GnomeVFSFileInfo *info = (GnomeVFSFileInfo *) i->data;
+//
+//        if (info && info->name)
+//        {
+//            if (strcmp (info->name, ".") == 0 || strcmp (info->name, "..") == 0)
+//            {
+//                gnome_vfs_file_info_unref (info);
+//                continue;
+//            }
+//
+//#ifdef HAVE_SAMBA
+//            GnomeCmdCon *con = gnome_cmd_dir_get_connection (dir);
+//            if (GNOME_CMD_IS_CON_SMB (con)
+//                && info->mime_type
+//                && (strcmp (info->mime_type, "application/x-gnome-app-info") == 0 ||
+//                    strcmp (info->mime_type, "application/x-desktop") == 0)
+//                && strcmp (info->name, ".directory"))
+//            {
+//                // This is a hack to make samba workgroups etc
+//                // look like normal directories
+//                info->type = GNOME_VFS_FILE_TYPE_DIRECTORY;
+//                // Determining smb MIME type: workgroup or server
+//                gchar *uri_str = GNOME_CMD_FILE (dir)->get_uri_str();
+//
+//                info->mime_type = strcmp (uri_str, "smb:///") == 0 ? g_strdup 
("x-directory/smb-workgroup") :
+//                                                                     g_strdup ("x-directory/smb-server");
+//            }
+//#endif
+//
+//            GnomeCmdFile *f = info->type == GNOME_VFS_FILE_TYPE_DIRECTORY ? GNOME_CMD_FILE 
(gnome_cmd_dir_new_from_info (info, dir)) :
+//                                                                            gnome_cmd_file_new (info, dir);
+//
+//            gnome_cmd_file_ref (f);
+//            file_list = g_list_append (file_list, f);
+//        }
+//    }
+//
+//    return file_list;
+//}
+
+
+static GList *create_gnome_cmd_file_list_from_gfileinfo_list (GnomeCmdDir *dir, GList *info_list)
 {
     GList *file_list = nullptr;
 
@@ -404,43 +500,24 @@ static GList *create_file_list (GnomeCmdDir *dir, GList *info_list)
 
     for (GList *i = info_list; i; i = i->next)
     {
-        GnomeVFSFileInfo *info = (GnomeVFSFileInfo *) i->data;
+        GFileInfo *gFileInfo = (GFileInfo *) i->data;
 
-        if (info && info->name)
+        auto basename = g_file_info_get_attribute_string (gFileInfo, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME);
+        if (strcmp (basename, ".") == 0 || strcmp (basename, "..") == 0)
         {
-            if (strcmp (info->name, ".") == 0 || strcmp (info->name, "..") == 0)
-            {
-                gnome_vfs_file_info_unref (info);
-                continue;
-            }
-
-#ifdef HAVE_SAMBA
-            GnomeCmdCon *con = gnome_cmd_dir_get_connection (dir);
-            if (GNOME_CMD_IS_CON_SMB (con)
-                && info->mime_type
-                && (strcmp (info->mime_type, "application/x-gnome-app-info") == 0 ||
-                    strcmp (info->mime_type, "application/x-desktop") == 0)
-                && strcmp (info->name, ".directory"))
-            {
-                // This is a hack to make samba workgroups etc
-                // look like normal directories
-                info->type = GNOME_VFS_FILE_TYPE_DIRECTORY;
-                // Determining smb MIME type: workgroup or server
-                gchar *uri_str = GNOME_CMD_FILE (dir)->get_uri_str();
-
-                info->mime_type = strcmp (uri_str, "smb:///") == 0 ? g_strdup ("x-directory/smb-workgroup") :
-                                                                     g_strdup ("x-directory/smb-server");
-            }
-#endif
+            continue;
+        }
 
-            GnomeCmdFile *f = info->type == GNOME_VFS_FILE_TYPE_DIRECTORY ? GNOME_CMD_FILE 
(gnome_cmd_dir_new_from_info (info, dir)) :
-                                                                            gnome_cmd_file_new (info, dir);
+        GnomeCmdFile *f = g_file_info_get_attribute_uint32 (gFileInfo, G_FILE_ATTRIBUTE_STANDARD_TYPE) == 
G_FILE_TYPE_DIRECTORY
+            ? GNOME_CMD_FILE (gnome_cmd_dir_new_from_gfileinfo (gFileInfo, dir))
+            : gnome_cmd_file_new (gFileInfo, dir);
 
+        if (f)
+        {
             gnome_cmd_file_ref (f);
             file_list = g_list_append (file_list, f);
         }
     }
-
     return file_list;
 }
 
@@ -454,7 +531,8 @@ static void on_list_done (GnomeCmdDir *dir, GList *infolist, GnomeVFSResult resu
         if (!dir->priv->file_collection->empty())
             dir->priv->file_collection->clear();
 
-        dir->priv->files = create_file_list (dir, infolist);
+        //dir->priv->files = create_file_list (dir, infolist);
+        dir->priv->files = create_gnome_cmd_file_list_from_gfileinfo_list (dir, infolist);
         dir->priv->file_collection->add(dir->priv->files);
         g_list_free (infolist);
 
diff --git a/src/gnome-cmd-dir.h b/src/gnome-cmd-dir.h
index 4dbdea9e..f0ea5e79 100644
--- a/src/gnome-cmd-dir.h
+++ b/src/gnome-cmd-dir.h
@@ -59,6 +59,7 @@ struct GnomeCmdDir
 
     gint voffset;
     GList *infolist;
+    GList *gFileInfoList;
     GnomeVFSAsyncHandle *list_handle;
     GnomeVFSResult list_result;
     gint list_counter;
@@ -86,6 +87,7 @@ struct GnomeCmdDirClass
 struct GnomeCmdCon;
 
 GnomeCmdDir *gnome_cmd_dir_new_from_info (GnomeVFSFileInfo *info, GnomeCmdDir *parent);
+GnomeCmdDir *gnome_cmd_dir_new_from_gfileinfo (GFileInfo *gFileInfo, GnomeCmdDir *parent);
 GnomeCmdDir *gnome_cmd_dir_new_with_con (GnomeCmdCon *con);
 GnomeCmdDir *gnome_cmd_dir_new (GnomeCmdCon *con, GnomeCmdPath *path, gboolean isStartup = false);
 GnomeCmdDir *gnome_cmd_dir_get_parent (GnomeCmdDir *dir);
@@ -93,19 +95,37 @@ GnomeCmdDir *gnome_cmd_dir_get_child (GnomeCmdDir *dir, const gchar *child);
 GnomeCmdCon *gnome_cmd_dir_get_connection (GnomeCmdDir *dir);
 Handle *gnome_cmd_dir_get_handle (GnomeCmdDir *dir);
 
+//inline GnomeCmdFile *gnome_cmd_dir_new_parent_dir_file (GnomeCmdDir *dir)
+//{
+//    GnomeVFSFileInfo *info = gnome_vfs_file_info_new ();
+//
+//    memset (info, '\0', sizeof (GnomeVFSFileInfo));
+//    info->name = g_strdup ("..");
+//    info->type = GNOME_VFS_FILE_TYPE_DIRECTORY;
+//    info->mime_type = g_strdup ("x-directory/normal");
+//    info->size = 0;
+//    info->refcount = 1;
+//    info->valid_fields = (GnomeVFSFileInfoFields) (GNOME_VFS_FILE_INFO_FIELDS_TYPE |
+//                                                   GNOME_VFS_FILE_INFO_FIELDS_SIZE |
+//                                                   GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE);
+//
+//    return gnome_cmd_file_new (info, dir);
+//}
+//
 inline GnomeCmdFile *gnome_cmd_dir_new_parent_dir_file (GnomeCmdDir *dir)
 {
-    GnomeVFSFileInfo *info = gnome_vfs_file_info_new ();
-
-    memset (info, '\0', sizeof (GnomeVFSFileInfo));
-    info->name = g_strdup ("..");
-    info->type = GNOME_VFS_FILE_TYPE_DIRECTORY;
-    info->mime_type = g_strdup ("x-directory/normal");
-    info->size = 0;
-    info->refcount = 1;
-    info->valid_fields = (GnomeVFSFileInfoFields) (GNOME_VFS_FILE_INFO_FIELDS_TYPE |
-                                                   GNOME_VFS_FILE_INFO_FIELDS_SIZE |
-                                                   GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE);
+    auto info = g_file_info_new ();
+
+    //memset (info, '\0', sizeof (GFileInfo));
+    g_file_info_set_name(info, "..");
+    g_file_info_set_display_name(info, "..");
+    g_file_info_set_file_type(info, G_FILE_TYPE_DIRECTORY);
+    //info->mime_type = g_strdup ("x-directory/normal");
+    g_file_info_set_size(info, 0);
+    //info->refcount = 1;
+    //info->valid_fields = (GnomeVFSFileInfoFields) (GNOME_VFS_FILE_INFO_FIELDS_TYPE |
+    //                                               GNOME_VFS_FILE_INFO_FIELDS_SIZE |
+    //                                               GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE);
 
     return gnome_cmd_file_new (info, dir);
 }
diff --git a/src/gnome-cmd-file-list.cc b/src/gnome-cmd-file-list.cc
index ce1a8b4b..da984c52 100644
--- a/src/gnome-cmd-file-list.cc
+++ b/src/gnome-cmd-file-list.cc
@@ -916,10 +916,10 @@ static gint sort_by_name (GnomeCmdFile *f1, GnomeCmdFile *f2, GnomeCmdFileList *
     if (f2->is_dotdot)
         return 1;
 
-    if (f1->info->type > f2->info->type)
+    if(g_file_info_get_file_type(f1->gFileInfo) > g_file_info_get_file_type(f2->gFileInfo))
         return -1;
 
-    if (f1->info->type < f2->info->type)
+    if (g_file_info_get_file_type(f1->gFileInfo) < g_file_info_get_file_type(f2->gFileInfo))
         return 1;
 
     gboolean raising = fl->priv->sort_raising[fl->priv->current_col];
@@ -936,10 +936,10 @@ static gint sort_by_ext (GnomeCmdFile *f1, GnomeCmdFile *f2, GnomeCmdFileList *f
     if (f2->is_dotdot)
         return 1;
 
-    if (f1->info->type > f2->info->type)
+    if(g_file_info_get_file_type(f1->gFileInfo) > g_file_info_get_file_type(f2->gFileInfo))
         return -1;
 
-    if (f1->info->type < f2->info->type)
+    if (g_file_info_get_file_type(f1->gFileInfo) < g_file_info_get_file_type(f2->gFileInfo))
         return 1;
 
     gboolean raising = fl->priv->sort_raising[fl->priv->current_col];
diff --git a/src/gnome-cmd-file-selector.cc b/src/gnome-cmd-file-selector.cc
index 11e0b84f..0adabb00 100644
--- a/src/gnome-cmd-file-selector.cc
+++ b/src/gnome-cmd-file-selector.cc
@@ -130,7 +130,7 @@ inline void GnomeCmdFileSelector::update_selected_files_label()
 
             case G_FILE_TYPE_REGULAR:
                 num_files++;
-                total_bytes += f->info->size;
+                total_bytes += g_file_info_get_size(f->gFileInfo);
                 break;
 
             default:
diff --git a/src/gnome-cmd-file.cc b/src/gnome-cmd-file.cc
index 53912f56..e5fadcb7 100644
--- a/src/gnome-cmd-file.cc
+++ b/src/gnome-cmd-file.cc
@@ -104,11 +104,12 @@ static void gnome_cmd_file_finalize (GObject *object)
 
     delete f->metadata;
 
-    if (f->info->name[0] != '.')
+    if (f->info && f->info->name[0] != '.')
         DEBUG ('f', "file destroying 0x%p %s\n", f, f->info->name);
 
     g_free (f->collate_key);
     gnome_vfs_file_info_unref (f->info);
+    g_object_unref(f->gFileInfo);
     if (f->priv->dir_handle)
         handle_unref (f->priv->dir_handle);
 
@@ -171,6 +172,22 @@ GnomeCmdFile *gnome_cmd_file_new (GnomeVFSFileInfo *info, GnomeCmdDir *dir)
 }
 
 
+GnomeCmdFile *gnome_cmd_file_new (GFileInfo *gFileInfo, GnomeCmdDir *dir)
+{
+    auto gnomeCmdFile = static_cast<GnomeCmdFile*> (g_object_new (GNOME_CMD_TYPE_FILE, nullptr));
+
+    gnome_cmd_file_setup (gnomeCmdFile, gFileInfo, dir);
+
+    if(!gnomeCmdFile->gFile)
+    {
+        g_object_unref(gnomeCmdFile);
+        return nullptr;
+    }
+
+    return gnomeCmdFile;
+}
+
+
 GnomeCmdFile *gnome_cmd_file_new_from_uri (GnomeVFSURI *uri)
 {
     g_return_val_if_fail (uri != nullptr, nullptr);
@@ -288,6 +305,56 @@ void gnome_cmd_file_setup (GnomeCmdFile *gnomeCmdFile, GnomeVFSFileInfo *info, G
 }
 
 
+void gnome_cmd_file_setup (GnomeCmdFile *gnomeCmdFile, GFileInfo *gFileInfo, GnomeCmdDir *dir)
+{
+    g_return_if_fail (gnomeCmdFile != nullptr);
+    g_return_if_fail (gFileInfo != nullptr);
+
+    gnomeCmdFile->gFileInfo = gFileInfo;
+
+    auto filename = g_file_info_get_attribute_string (gFileInfo, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME);
+
+    // check if file is '..'
+    gnomeCmdFile->is_dotdot = g_file_info_get_attribute_uint32 (gFileInfo, G_FILE_ATTRIBUTE_STANDARD_TYPE) 
== G_FILE_TYPE_DIRECTORY
+                              && g_strcmp0(filename, "..") == 0;
+
+    gchar *utf8_name;
+
+    if (!gnome_cmd_data.options.case_sens_sort)
+    {
+        utf8_name = g_utf8_casefold (filename, -1);
+    }
+    else
+        utf8_name = g_strdup(filename);
+
+    gnomeCmdFile->collate_key = g_utf8_collate_key_for_filename (utf8_name, -1);
+    g_free (utf8_name);
+
+    if (dir)
+    {
+        gnomeCmdFile->priv->dir_handle = gnome_cmd_dir_get_handle (dir);
+        handle_ref (gnomeCmdFile->priv->dir_handle);
+    }
+
+    auto path = gnomeCmdFile->get_path();
+    //auto path = g_file_info_get
+
+    if (path)
+    {
+        GNOME_CMD_FILE_BASE (gnomeCmdFile)->gFile = g_file_new_for_path(path);
+        gnomeCmdFile->gFile = GNOME_CMD_FILE_BASE (gnomeCmdFile)->gFile;
+        g_free(path);
+    }
+    // EVERY GnomeCmdFile instance must have a gFile reference
+    if (!gnomeCmdFile->gFile)
+    {
+        gnome_vfs_file_info_unref(gnomeCmdFile->info);
+        g_object_unref(gnomeCmdFile->gFileInfo);
+        return;
+    }
+}
+
+
 GnomeCmdFile *GnomeCmdFile::ref()
 {
     priv->ref_cnt++;
@@ -297,7 +364,7 @@ GnomeCmdFile *GnomeCmdFile::ref()
 
     char c = GNOME_CMD_IS_DIR (this) ? 'd' : 'f';
 
-    DEBUG (c, "refing: 0x%p %s to %d\n", this, info->name, priv->ref_cnt);
+    DEBUG (c, "refing: 0x%p %s to %d\n", this, g_file_info_get_display_name(gFileInfo), priv->ref_cnt);
 
     return this;
 }
@@ -309,7 +376,7 @@ void GnomeCmdFile::unref()
 
     char c = GNOME_CMD_IS_DIR (this) ? 'd' : 'f';
 
-    DEBUG (c, "un-refing: 0x%p %s to %d\n", this, info->name, priv->ref_cnt);
+    DEBUG (c, "un-refing: 0x%p %s to %d\n", this, g_file_info_get_display_name(gFileInfo), priv->ref_cnt);
     if (priv->ref_cnt < 1)
         g_object_unref (this);
 }
@@ -414,10 +481,13 @@ gchar *GnomeCmdFile::get_quoted_name()
 
 gchar *GnomeCmdFile::get_path()
 {
-    g_return_val_if_fail (info != nullptr, nullptr);
+    //g_return_val_if_fail (gFile != nullptr, nullptr);
+
+    //auto filename = GetGfileAttributeString (G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME);
+    auto filename = g_file_info_get_name (this->gFileInfo);
 
-    if (strcmp (info->name, G_DIR_SEPARATOR_S) == 0)
-        return g_strdup (G_DIR_SEPARATOR_S);
+    if (strcmp (filename, G_DIR_SEPARATOR_S) == 0)
+        return g_strdup(filename);
 
     GnomeCmdPath *path;
     gchar *path_str;
@@ -432,7 +502,7 @@ gchar *GnomeCmdFile::get_path()
         g_assert ("Non directory file without owning directory");
     }
 
-    path = gnome_cmd_dir_get_path (::get_parent_dir (this))->get_child(info->name);
+    path = gnome_cmd_dir_get_path (::get_parent_dir (this))->get_child(filename);
     if (!path)
     {
         return nullptr;
@@ -500,6 +570,8 @@ GAppInfo *GnomeCmdFile::GetAppInfoForContentType()
 
 gchar *GnomeCmdFile::GetGfileAttributeString(const char *attribute)
 {
+    g_return_val_if_fail (gFile != nullptr, nullptr);
+
     GError *error;
     error = nullptr;
     auto gcmdFileInfo = g_file_query_info(this->gFile,
@@ -650,7 +722,7 @@ const gchar *GnomeCmdFile::get_extension()
     if (GetGfileAttributeUInt32(G_FILE_ATTRIBUTE_STANDARD_TYPE) == G_FILE_TYPE_DIRECTORY)
         return nullptr;
 
-    const char *s = strrchr (info->name, '.');        // does NOT work on UTF-8 strings, should be (MUCH 
SLOWER):
+    const char *s = strrchr (g_file_info_get_name(this->gFileInfo), '.');        // does NOT work on UTF-8 
strings, should be (MUCH SLOWER):
     // const char *s = g_utf8_strrchr (info->name, -1, '.');
 
     return s ? s+1 : nullptr;
@@ -726,7 +798,7 @@ const gchar *GnomeCmdFile::get_size()
 guint64 GnomeCmdFile::get_tree_size()
 {
     if (GetGfileAttributeUInt32(G_FILE_ATTRIBUTE_STANDARD_TYPE) != G_FILE_TYPE_DIRECTORY)
-        return info->size;
+        return g_file_info_get_attribute_uint64 (gFileInfo, G_FILE_ATTRIBUTE_STANDARD_SIZE);
 
     if (is_dotdot)
         return 0;
@@ -981,6 +1053,30 @@ void GnomeCmdFile::update_info(GnomeVFSFileInfo *file_info)
 }
 
 
+void GnomeCmdFile::update_gFileInfo(GFileInfo *gFileInfo_new)
+{
+    g_return_if_fail (gFileInfo_new != nullptr);
+
+    g_free (collate_key);
+    g_object_unref (this->gFileInfo);
+    g_object_ref (gFileInfo_new);
+    this->gFileInfo = gFileInfo_new;
+
+    gchar *filename;
+
+    if (!gnome_cmd_data.options.case_sens_sort)
+    {
+        auto filenameWithCase = g_file_info_get_display_name(gFileInfo_new);
+        filename = g_utf8_casefold (filenameWithCase, -1);
+    }
+    else
+        filename = g_strdup(g_file_info_get_display_name(gFileInfo_new));
+
+    collate_key = g_utf8_collate_key_for_filename (filename, -1);
+    g_free(filename);
+}
+
+
 gboolean GnomeCmdFile::is_local()
 {
     return gnome_cmd_dir_is_local (::get_parent_dir (this));
diff --git a/src/gnome-cmd-file.h b/src/gnome-cmd-file.h
index 58c522e4..e97f8c4c 100644
--- a/src/gnome-cmd-file.h
+++ b/src/gnome-cmd-file.h
@@ -47,6 +47,7 @@ struct GnomeCmdFile
 
     GnomeVFSFileInfo *info;
     GFile *gFile;
+    GFileInfo *gFileInfo;
     gboolean is_dotdot;
     gchar *collate_key;                 // necessary for proper sorting of UTF-8 encoded file names
     GnomeCmdFileMetadata *metadata;
@@ -92,6 +93,7 @@ struct GnomeCmdFile
     GnomeVFSResult rename(const gchar *new_name);
 
     void update_info(GnomeVFSFileInfo *info);
+    void update_gFileInfo(GFileInfo *gFileInfo);
     gboolean is_local();
     gboolean is_executable();
     void is_deleted();
@@ -127,7 +129,10 @@ inline gchar *GnomeCmdFile::get_name()
 GnomeCmdFile *gnome_cmd_file_new_from_uri (GnomeVFSURI *uri);
 GnomeCmdFile *gnome_cmd_file_new (const gchar *local_full_path);
 GnomeCmdFile *gnome_cmd_file_new (GnomeVFSFileInfo *info, GnomeCmdDir *dir);
+GnomeCmdFile *gnome_cmd_file_new (GFileInfo *gFileInfo, GnomeCmdDir *dir);
 void gnome_cmd_file_setup (GnomeCmdFile *gnomeCmdFile, GnomeVFSFileInfo *info, GnomeCmdDir *dir);
+void gnome_cmd_file_setup (GnomeCmdFile *gnomeCmdFile, GFileInfo *gFileInfo, GnomeCmdDir *dir);
+
 
 inline GnomeCmdFile *gnome_cmd_file_ref (GnomeCmdFile *f)
 {
diff --git a/src/utils.cc b/src/utils.cc
index fdef4e94..bdf9f3a7 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -1157,3 +1157,51 @@ gchar *string_double_underscores (const gchar *string)
 
     return escaped;
 }
+
+guint32 GetGfileAttributeUInt32(GFile *gFile, const char *attribute)
+{
+    GError *error;
+    error = nullptr;
+    guint32 gFileAttributeUInt32 = 0;
+
+    auto gcmdFileInfo = g_file_query_info(gFile,
+                                   attribute,
+                                   G_FILE_QUERY_INFO_NONE,
+                                   nullptr,
+                                   &error);
+    if (error)
+    {
+        g_message ("retrieving file info failed: %s", error->message);
+        g_error_free (error);
+    }
+    else
+    {
+        gFileAttributeUInt32 = g_file_info_get_attribute_uint32 (gcmdFileInfo, attribute);
+        g_object_unref(gcmdFileInfo);
+    }
+
+    return gFileAttributeUInt32;
+}
+
+
+gchar *GetGfileAttributeString(GFile *gFile, const char *attribute)
+{
+    GError *error;
+    error = nullptr;
+    auto gcmdFileInfo = g_file_query_info(gFile,
+                                   attribute,
+                                   G_FILE_QUERY_INFO_NONE,
+                                   nullptr,
+                                   &error);
+    if (gcmdFileInfo && error)
+    {
+        g_message ("retrieving file info failed: %s", error->message);
+        g_error_free (error);
+        return nullptr;
+    }
+
+    auto gFileAttributeString = g_strdup(g_file_info_get_attribute_string (gcmdFileInfo, attribute));
+    g_object_unref(gcmdFileInfo);
+
+    return gFileAttributeString;
+}
diff --git a/src/utils.h b/src/utils.h
index 9dab26b3..365b461d 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -412,3 +412,7 @@ gboolean move_old_to_new_location(const gchar* oldPath, const gchar* newPath);
 gchar* get_package_config_dir();
 
 gchar *string_double_underscores (const gchar *string);
+
+guint32 GetGfileAttributeUInt32(GFile *gFile, const char *attribute);
+
+gchar *GetGfileAttributeString(GFile *gFile, const char *attribute);


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