[gnome-commander: 153/170] Use gio to find the default applicatin in the file popup menu




commit 8425ab264d96ea82c8f442b39ef05d4b504c116e
Author: Uwe Scholz <u scholz83 gmx de>
Date:   Sun Dec 20 17:05:15 2020 +0100

    Use gio to find the default applicatin in the file popup menu

 libgcmd/gnome-cmd-file-info.h |   2 +-
 libgcmd/libgcmd-deps.h        |   1 +
 src/dirlist.cc                |   2 +-
 src/gnome-cmd-app.cc          |  21 +++++-
 src/gnome-cmd-app.h           |   2 +
 src/gnome-cmd-file-popmenu.cc | 111 +++---------------------------
 src/gnome-cmd-file.cc         | 154 ++++++++++++++++++++++++++++++++++++++++++
 src/gnome-cmd-file.h          |   9 +++
 src/imageloader.cc            |  24 ++++++-
 src/imageloader.h             |   4 +-
 src/utils.cc                  |  31 ++++++++-
 src/utils.h                   |   4 +-
 12 files changed, 258 insertions(+), 107 deletions(-)
---
diff --git a/libgcmd/gnome-cmd-file-info.h b/libgcmd/gnome-cmd-file-info.h
index 20fe4a7c..310d07ff 100644
--- a/libgcmd/gnome-cmd-file-info.h
+++ b/libgcmd/gnome-cmd-file-info.h
@@ -1,4 +1,4 @@
-/** 
+/**
  * @file gnome-cmd-file-info.h
  * @copyright (C) 2001-2006 Marcus Bjurman\n
  * @copyright (C) 2007-2012 Piotr Eljasiak\n
diff --git a/libgcmd/libgcmd-deps.h b/libgcmd/libgcmd-deps.h
index 3705f81b..8af79d66 100644
--- a/libgcmd/libgcmd-deps.h
+++ b/libgcmd/libgcmd-deps.h
@@ -23,6 +23,7 @@
 
 #include <glib.h>
 #include <glib/gi18n.h>
+#include <gio/gio.h>
 #include <gdk/gdk.h>
 #include <gdk/gdkkeysyms.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
diff --git a/src/dirlist.cc b/src/dirlist.cc
index 02de745a..b41b0190 100644
--- a/src/dirlist.cc
+++ b/src/dirlist.cc
@@ -1,4 +1,4 @@
-/** 
+/**
  * @file dirlist.cc
  * @copyright (C) 2001-2006 Marcus Bjurman\n
  * @copyright (C) 2007-2012 Piotr Eljasiak\n
diff --git a/src/gnome-cmd-app.cc b/src/gnome-cmd-app.cc
index b8b72fa8..e8c51d52 100644
--- a/src/gnome-cmd-app.cc
+++ b/src/gnome-cmd-app.cc
@@ -23,6 +23,7 @@
 
 #include "gnome-cmd-includes.h"
 #include "gnome-cmd-app.h"
+#include "imageloader.h"
 
 using namespace std;
 
@@ -125,7 +126,7 @@ GnomeCmdApp *gnome_cmd_app_new_from_vfs_app (GnomeVFSMimeApplication *vfs_app)
 
     GtkIconTheme *theme = gtk_icon_theme_get_default ();
     char *icon = panel_find_icon (theme, gnome_vfs_mime_application_get_icon (vfs_app), 16);
-    
+
     GnomeCmdApp *rel_value = gnome_cmd_app_new_with_values (vfs_app->name,
                                           vfs_app->command,
                                           icon,
@@ -139,6 +140,24 @@ GnomeCmdApp *gnome_cmd_app_new_from_vfs_app (GnomeVFSMimeApplication *vfs_app)
 }
 
 
+GnomeCmdApp *gnome_cmd_app_new_from_app_info (GAppInfo *gAppInfo)
+{
+    g_return_val_if_fail (gAppInfo != nullptr, nullptr);
+
+    GtkIconTheme *theme = gtk_icon_theme_get_default ();
+
+    GnomeCmdApp *rel_value = gnome_cmd_app_new_with_values (g_app_info_get_name (gAppInfo),
+                                          g_app_info_get_commandline (gAppInfo),
+                                          get_default_application_icon_path(gAppInfo),
+                                          APP_TARGET_ALL_FILES,
+                                          nullptr,
+                                          g_app_info_supports_uris (gAppInfo),
+                                          true,
+                                          false);
+    return rel_value;
+}
+
+
 GnomeCmdApp *gnome_cmd_app_dup (GnomeCmdApp *app)
 {
     return gnome_cmd_app_new_with_values (app->name,
diff --git a/src/gnome-cmd-app.h b/src/gnome-cmd-app.h
index e5df1b1d..75a6d406 100644
--- a/src/gnome-cmd-app.h
+++ b/src/gnome-cmd-app.h
@@ -53,6 +53,8 @@ GnomeCmdApp *gnome_cmd_app_new ();
 
 GnomeCmdApp *gnome_cmd_app_new_from_vfs_app (GnomeVFSMimeApplication *vfs_app);
 
+GnomeCmdApp *gnome_cmd_app_new_from_app_info (GAppInfo *gAppInfo);
+
 GnomeCmdApp *gnome_cmd_app_new_with_values (const gchar *name,
                                             const gchar *cmd,
                                             const gchar *icon_path,
diff --git a/src/gnome-cmd-file-popmenu.cc b/src/gnome-cmd-file-popmenu.cc
index 5ed4f223..5162c90f 100644
--- a/src/gnome-cmd-file-popmenu.cc
+++ b/src/gnome-cmd-file-popmenu.cc
@@ -212,21 +212,19 @@ static void cb_exec_default (GtkMenuItem *menu_item, GList *files)
     for (; files; files = files->next)
     {
         auto file = static_cast<GnomeCmdFile*> (files->data);
-        auto vfs_app = file->get_default_application();
+        auto appInfo = file->GetAppInfoForContentType();
 
-        if (vfs_app)
+        if (g_app_info_get_commandline (appInfo))
         {
-            auto data = static_cast<OpenWithData*> (g_hash_table_lookup (gHashTable, vfs_app->id));
+            auto data = static_cast<OpenWithData*> (g_hash_table_lookup (gHashTable, 
g_app_info_get_id(appInfo)));
 
             if (!data)
             {
                 data = g_new0 (OpenWithData, 1);
-                data->app = gnome_cmd_app_new_from_vfs_app (vfs_app);
+                data->app = gnome_cmd_app_new_from_app_info (appInfo);
                 data->files = nullptr;
-                g_hash_table_insert (gHashTable, vfs_app->id, data);
+                g_hash_table_insert (gHashTable, (gpointer) g_app_info_get_id(appInfo), data);
             }
-
-            gnome_vfs_mime_application_free (vfs_app);
             data->files = g_list_append (data->files, file);
         }
         else
@@ -507,95 +505,6 @@ static void init (GnomeCmdFilePopmenu *menu)
 }
 
 
-inline gchar *string_double_underscores (const gchar *string)
-{
-    if (!string)
-        return nullptr;
-
-    int underscores = 0;
-
-    for (const gchar *p = string; *p; p++)
-        underscores += (*p == '_');
-
-    if (underscores == 0)
-        return g_strdup (string);
-
-    gchar *escaped = g_new (char, strlen (string) + underscores + 1);
-    gchar *q = escaped;
-
-    for (const gchar *p = string; *p; p++, q++)
-    {
-        /* Add an extra underscore. */
-        if (*p == '_')
-            *q++ = '_';
-        *q = *p;
-    }
-    *q = '\0';
-
-    return escaped;
-}
-
-
-inline GnomeVFSMimeApplication *get_default_gnome_vfs_app_for_mime_type(GnomeCmdFile *gnomeCmdFile)
-{
-    auto uri_str = gnomeCmdFile->get_uri_str();
-    auto *app = gnome_vfs_mime_get_default_application_for_uri (uri_str, gnomeCmdFile->info->mime_type);
-    g_free (uri_str);
-    return app;
-}
-
-
-inline gchar *get_default_application_action_name (GnomeCmdFile *gnomeCmdFile)
-{
-    auto app = get_default_gnome_vfs_app_for_mime_type(gnomeCmdFile);
-
-    if (!app)
-    {
-        return nullptr;
-    }
-
-    gchar *escaped_app_name = string_double_underscores (app->name);
-    gnome_vfs_mime_application_free (app);
-
-    return escaped_app_name;
-}
-
-
-inline gchar *get_default_application_icon_path (GnomeCmdFile *gnomeCmdFile)
-{
-    gchar* icon_path = nullptr;
-
-    auto app = get_default_gnome_vfs_app_for_mime_type(gnomeCmdFile);
-
-    if (app)
-    {
-        GnomeCmdApp *gapp = gnome_cmd_app_new_from_vfs_app (app);
-        if (gapp)
-        {
-            icon_path = g_strdup (gapp->icon_path);
-            gnome_cmd_app_free (gapp);
-        }
-        gnome_vfs_mime_application_free (app);
-    }
-
-    return icon_path;
-}
-
-
-inline gchar *get_default_application_action_label (GnomeCmdFile *gnomeCmdFile)
-{
-    gchar *escaped_app_name = get_default_application_action_name (gnomeCmdFile);
-    if (escaped_app_name == nullptr)
-    {
-        return g_strdup (_("_Open"));
-    }
-
-    gchar *retval = g_strdup_printf (_("_Open with ā€œ%sā€"), escaped_app_name);
-    g_free (escaped_app_name);
-
-    return retval;
-}
-
 inline GList *get_list_of_action_script_file_names(const gchar* scriptsDir)
 {
     DIR *dp = opendir (scriptsDir);
@@ -882,13 +791,14 @@ guint add_open_with_entries(GtkUIManager *ui_manager, GnomeCmdFileList *gnomeCmd
     gchar *openWithDefaultAppLabel = nullptr;
 
     // Only try to find a default application for the first file in the list of selected files
-    openWithDefaultAppName  = get_default_application_action_name(gnomeCmdFile);
-    defaultAppIconPath      = get_default_application_icon_path(gnomeCmdFile);
-    openWithDefaultAppLabel = get_default_application_action_label(gnomeCmdFile);
+    openWithDefaultAppName  = gnomeCmdFile->get_default_application_name_string();
+    auto appInfo = gnomeCmdFile->GetAppInfoForContentType();
+    openWithDefaultAppLabel = gnomeCmdFile->get_default_application_action_label(appInfo);
 
     if (openWithDefaultAppName != nullptr)
     {
         // Add the default "Open" menu entry at the top of the popup
+        defaultAppIconPath = g_strdup(get_default_application_icon_path(appInfo));
         appStockId = register_application_stock_icon(openWithDefaultAppName, defaultAppIconPath);
         dynAction = gtk_action_new ("Open", openWithDefaultAppLabel, nullptr, appStockId);
         g_signal_connect (dynAction, "activate", G_CALLBACK (cb_exec_default), files);
@@ -927,7 +837,8 @@ guint add_open_with_entries(GtkUIManager *ui_manager, GnomeCmdFileList *gnomeCmd
             gchar* openWithAppName  = g_strdup (gnome_cmd_app_get_name (data->app));
 
             // Only add the entry to the submenu if its name different from the default app
-            if (strcmp(openWithAppName, openWithDefaultAppName) == 0)
+            if (openWithDefaultAppName != nullptr
+                && strcmp(openWithAppName, openWithDefaultAppName) == 0)
             {
                 gnome_cmd_app_free(data->app);
                 g_free(data);
diff --git a/src/gnome-cmd-file.cc b/src/gnome-cmd-file.cc
index 3b72e97f..330c46ea 100644
--- a/src/gnome-cmd-file.cc
+++ b/src/gnome-cmd-file.cc
@@ -185,6 +185,44 @@ GnomeCmdFile *gnome_cmd_file_new_from_uri (GnomeVFSURI *uri)
     return gnome_cmd_file_new (info, dir);
 }
 
+#if 0
+static void add_file_callback(GObject *direnum,
+                GAsyncResult *result,
+                gpointer user_data){
+    GError *error = NULL;
+    GList *file_list = g_file_enumerator_next_files_finish(
+                    G_FILE_ENUMERATOR(direnum),
+                    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( file_list == NULL ){
+        /* Done listing */
+        g_object_unref(direnum);
+        return;
+    }else{
+
+        GList *node = file_list;
+        GFileInfo *info;
+        GtkTreeIter iter;
+        while(node){
+            info = node->data;
+            node = node->next;
+            ...add to store
+            g_object_unref(info);
+        }
+        g_file_enumerator_next_files_async(G_FILE_ENUMERATOR(direnum),
+                        BLOCK_SIZE,
+                        G_PRIORITY_LOW,
+                        NULL,
+                        add_file_callback,
+                        list);
+    }
+    g_list_free(file_list);
+}
+#endif
 
 void GnomeCmdFile::invalidate_metadata()
 {
@@ -226,6 +264,32 @@ void gnome_cmd_file_setup (GnomeCmdFile *f, GnomeVFSFileInfo *info, GnomeCmdDir
     }
 
     gnome_vfs_file_info_ref (f->info);
+
+    //auto fUriString = f->get_uri_str();
+    auto fUriString = f->get_path();
+
+    if (fUriString)
+    {
+        f->gFile = g_file_new_for_path(fUriString);
+        printf("g_file_path: %s\n", g_file_get_path(f->gFile));
+        g_free(fUriString);
+
+        GError *error;
+        error = nullptr;
+
+        f->gFileInfo = g_file_query_info(f->gFile,
+                           "standard::content-type",
+                           G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+                           nullptr,
+                           &error);
+
+        if (f->gFileInfo && error)
+        {
+            g_message ("retrieving file info failed: %s", error->message);
+            g_error_free (error);
+            exit (EXIT_FAILURE);
+        }
+    }
 }
 
 
@@ -415,6 +479,96 @@ gchar *GnomeCmdFile::get_unescaped_dirname()
 }
 
 
+GAppInfo *GnomeCmdFile::GetAppInfoForContentType()
+{
+    auto contentTypeString = this->GetGfileContentTypeString();
+    auto appInfo = g_app_info_get_default_for_type (contentTypeString, false);
+    g_free(contentTypeString);
+
+    return appInfo;
+}
+
+
+gchar *GnomeCmdFile::GetGfileContentTypeString()
+{
+    GError *error;
+    error = nullptr;
+    auto gcmdFileInfo = g_file_query_info(gFile,
+                                   "standard::content-type",
+                                   G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+                                   nullptr,
+                                   &error);
+    if (gcmdFileInfo && error)
+    {
+        g_message ("retrieving file info failed: %s", error->message);
+        g_error_free (error);
+        exit (EXIT_FAILURE);
+    }
+
+    auto gFileContentTypeString = g_strdup(g_file_info_get_attribute_string (gcmdFileInfo, 
"standard::content-type"));
+    g_object_unref(gcmdFileInfo);
+
+    return gFileContentTypeString;
+
+    //GList *files;
+    //g_list_append(files, gFile);
+
+    // Launch later with:
+    //g_app_info_launch (appInfo,
+    //           files,
+    //           nullptr,
+    //           &error);
+}
+
+
+gchar *GnomeCmdFile::get_default_application_name_string()
+{
+    gchar *contentType = nullptr;
+
+    contentType = g_file_info_get_attribute_as_string (gFileInfo, "standard::content-type");
+
+    auto appInfo = g_app_info_get_default_for_type (contentType, false);
+
+    g_free(contentType);
+    return g_strdup(g_app_info_get_name (appInfo));
+}
+
+
+gchar *GnomeCmdFile::get_default_application_action_label(GAppInfo *gAppInfo)
+{
+    gchar *escaped_app_name = get_default_application_action_name (gAppInfo);
+    if (escaped_app_name == nullptr)
+    {
+        return g_strdup (_("_Open"));
+    }
+
+    gchar *retval = g_strdup_printf (_("_Open with ā€œ%sā€"), escaped_app_name);
+    g_free (escaped_app_name);
+
+    return retval;
+}
+
+
+gchar *GnomeCmdFile::get_default_application_action_name(GAppInfo *gAppInfo)
+{
+    gchar *escaped_app_name = string_double_underscores (g_app_info_get_name (gAppInfo));
+
+    return escaped_app_name;
+}
+
+
+GnomeVFSMimeApplication *GnomeCmdFile::get_default_gnome_vfs_app_for_mime_type()
+{
+    g_return_val_if_fail (GNOME_CMD_IS_FILE (this), nullptr);
+
+    auto uri_str = this->get_uri_str();
+    auto *app = gnome_vfs_mime_get_default_application_for_uri (uri_str, this->info->mime_type);
+
+    g_free (uri_str);
+    return app;
+}
+
+
 GnomeVFSURI *GnomeCmdFile::get_uri(const gchar *name)
 {
     if (!has_parent_dir (this))
diff --git a/src/gnome-cmd-file.h b/src/gnome-cmd-file.h
index 39feb489..5a0169d7 100644
--- a/src/gnome-cmd-file.h
+++ b/src/gnome-cmd-file.h
@@ -46,6 +46,8 @@ struct GnomeCmdFile
     Private *priv;
 
     GnomeVFSFileInfo *info;
+    GFile *gFile;
+    GFileInfo *gFileInfo;
     gboolean is_dotdot;
     gchar *collate_key;                 // necessary for proper sorting of UTF-8 encoded file names
     GnomeCmdFileMetadata *metadata;
@@ -62,6 +64,7 @@ struct GnomeCmdFile
     gchar *get_quoted_real_path();
     gchar *get_dirname();
     gchar *get_unescaped_dirname();
+
     GnomeVFSURI *get_uri(const gchar *name=NULL);
     gchar *get_uri_str(GnomeVFSURIHideOptions hide_options=GNOME_VFS_URI_HIDE_PASSWORD);
 
@@ -102,6 +105,12 @@ struct GnomeCmdFile
     gboolean has_tree_size();
 
     GnomeVFSMimeApplication *get_default_application();
+    gchar *GetGfileContentTypeString();
+    gchar *get_default_application_name_string();
+    gchar *get_default_application_action_label(GAppInfo *gAppInfo);
+    gchar *get_default_application_action_name(GAppInfo *gAppInfo);
+    GAppInfo *GetAppInfoForContentType();
+    GnomeVFSMimeApplication *get_default_gnome_vfs_app_for_mime_type();
 };
 
 struct GnomeCmdFileClass
diff --git a/src/imageloader.cc b/src/imageloader.cc
index 39cf9f72..16d5d3e6 100644
--- a/src/imageloader.cc
+++ b/src/imageloader.cc
@@ -82,6 +82,7 @@ static CacheEntry file_type_pixmaps[NUM_FILE_TYPE_PIXMAPS];
 static GHashTable *mime_cache = nullptr;
 static GdkPixbuf *symlink_pixbuf = nullptr;
 
+static const gint ICON_SIZE = 16;
 
 static gboolean load_icon (const gchar *icon_path, GdkPixmap **pm, GdkBitmap **bm, GdkPixmap **lpm, 
GdkBitmap **lbm);
 
@@ -583,4 +584,25 @@ char* register_application_stock_icon(const char* applicationName, const char* d
     g_object_unref (icon_factory);
 
     return stockId;
-}
\ No newline at end of file
+}
+
+/**
+ * This method returns the path of the default application icon for a given GAppInfo object.
+ * The returned char must not be free'ed.
+ */
+const gchar* get_default_application_icon_path(GAppInfo* appInfo)
+{
+    g_return_val_if_fail (appInfo, nullptr);
+
+    auto appIconName = g_icon_to_string (g_app_info_get_icon(appInfo));
+    auto gtkIconInfo = gtk_icon_theme_lookup_icon (gtk_icon_theme_get_default(), appIconName, ICON_SIZE, 
GTK_ICON_LOOKUP_FORCE_SIZE);
+
+    g_free(appIconName);
+
+    if (gtkIconInfo == nullptr)
+    {
+        return nullptr;
+    }
+
+    return gtk_icon_info_get_filename(gtkIconInfo);
+}
diff --git a/src/imageloader.h b/src/imageloader.h
index 83a25528..75d9f50d 100644
--- a/src/imageloader.h
+++ b/src/imageloader.h
@@ -95,4 +95,6 @@ void IMAGE_clear_mime_cache ();
 
 void register_gnome_commander_stock_icons (void);
 
-char* register_application_stock_icon(const char* openWithDefaultLabel, const char* defaultAppIconPath);
\ No newline at end of file
+const gchar* get_default_application_icon_path(GAppInfo* appInfo);
+
+char* register_application_stock_icon(const char* openWithDefaultLabel, const char* defaultAppIconPath);
diff --git a/src/utils.cc b/src/utils.cc
index e4eb9fb3..69ea1627 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -1178,4 +1178,33 @@ gboolean move_old_to_new_location(const gchar* oldPath, const gchar* newPath)
 gchar* get_package_config_dir()
 {
     return g_build_filename (g_get_user_config_dir(), PACKAGE, NULL);
-}
\ No newline at end of file
+}
+
+
+gchar *string_double_underscores (const gchar *string)
+{
+    if (!string)
+        return nullptr;
+
+    int underscores = 0;
+
+    for (const gchar *p = string; *p; p++)
+        underscores += (*p == '_');
+
+    if (underscores == 0)
+        return g_strdup (string);
+
+    gchar *escaped = g_new (char, strlen (string) + underscores + 1);
+    gchar *q = escaped;
+
+    for (const gchar *p = string; *p; p++, q++)
+    {
+        /* Add an extra underscore. */
+        if (*p == '_')
+            *q++ = '_';
+        *q = *p;
+    }
+    *q = '\0';
+
+    return escaped;
+}
diff --git a/src/utils.h b/src/utils.h
index 7fd619f4..54bd5baf 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -404,4 +404,6 @@ gint get_string_pixel_size (const char *s, int len);
 
 gboolean move_old_to_new_location(const gchar* oldPath, const gchar* newPath);
 
-gchar* get_package_config_dir();
\ No newline at end of file
+gchar* get_package_config_dir();
+
+gchar *string_double_underscores (const gchar *string);
\ No newline at end of file


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