[gnome-builder/wip/tree-menu] tree: load relevant content-type handling applications into menu



commit 70a8c52f9b34fb574542349a871caf156c6c6bec
Author: Christian Hergert <christian hergert me>
Date:   Wed Apr 8 16:51:57 2015 -0700

    tree: load relevant content-type handling applications into menu
    
    This provides a GAction that can be used to load a file with a specific
    application. It also populates the list of available applications for
    a given IdeProjectFile based on the discovered mimetype.

 src/editor/gb-project-tree-actions.c |   61 ++++++++++++++++++++++++++++++++++
 src/tree/gb-project-tree-builder.c   |   59 ++++++++++++++++++++++++++++++++
 2 files changed, 120 insertions(+), 0 deletions(-)
---
diff --git a/src/editor/gb-project-tree-actions.c b/src/editor/gb-project-tree-actions.c
index 21978ac..133f473 100644
--- a/src/editor/gb-project-tree-actions.c
+++ b/src/editor/gb-project-tree-actions.c
@@ -17,6 +17,7 @@
  */
 
 #include <glib/gi18n.h>
+#include <gio/gdesktopappinfo.h>
 
 #include "gb-editor-workspace.h"
 #include "gb-editor-workspace-private.h"
@@ -164,6 +165,65 @@ gb_project_tree_actions_open (GSimpleAction *action,
 }
 
 static void
+gb_project_tree_actions_open_with (GSimpleAction *action,
+                                   GVariant      *variant,
+                                   gpointer       user_data)
+{
+  GDesktopAppInfo *app_info = NULL;
+  GbEditorWorkspace *editor = user_data;
+  GbTreeNode *selected;
+  GbWorkbench *workbench;
+  GdkAppLaunchContext *launch_context;
+  GdkDisplay *display;
+  GFileInfo *file_info;
+  GFile *file;
+  const gchar *app_id;
+  GObject *item;
+  GList *files;
+
+  g_assert (GB_IS_EDITOR_WORKSPACE (editor));
+  g_assert (g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING));
+
+  workbench = gb_widget_get_workbench (GTK_WIDGET (editor));
+  if (workbench == NULL)
+    return;
+
+  selected = gb_tree_get_selected (editor->project_tree);
+  if (selected == NULL)
+    return;
+
+  item = gb_tree_node_get_item (selected);
+  if (item == NULL || !IDE_IS_PROJECT_FILE (item))
+    return;
+
+  app_id = g_variant_get_string (variant, NULL);
+  if (app_id == NULL)
+    return;
+
+  app_info = g_desktop_app_info_new (app_id);
+  if (app_info == NULL)
+    return;
+
+  file_info = ide_project_file_get_file_info (IDE_PROJECT_FILE (item));
+  if (file_info == NULL)
+    return;
+
+  file = ide_project_file_get_file (IDE_PROJECT_FILE (item));
+  if (file == NULL)
+    return;
+
+  display = gtk_widget_get_display (GTK_WIDGET (editor));
+  launch_context = gdk_display_get_app_launch_context (display);
+  files = g_list_append (NULL, file);
+
+  g_app_info_launch (G_APP_INFO (app_info), files, G_APP_LAUNCH_CONTEXT (launch_context), NULL);
+
+  g_list_free (files);
+  g_object_unref (launch_context);
+  g_object_unref (app_info);
+}
+
+static void
 gb_project_tree_actions_open_with_editor (GSimpleAction *action,
                                           GVariant      *variant,
                                           gpointer       user_data)
@@ -248,6 +308,7 @@ static GActionEntry GbProjectTreeActions[] = {
   { "collapse-all-nodes",     gb_project_tree_actions_collapse_all_nodes },
   { "open",                   gb_project_tree_actions_open },
   { "open-containing-folder", gb_project_tree_actions_open_containing_folder },
+  { "open-with",              gb_project_tree_actions_open_with, "s" },
   { "open-with-editor",       gb_project_tree_actions_open_with_editor },
   { "refresh",                gb_project_tree_actions_refresh },
   { "show-icons",             NULL, NULL, "false", gb_project_tree_actions_show_icons },
diff --git a/src/tree/gb-project-tree-builder.c b/src/tree/gb-project-tree-builder.c
index c52d30b..cdaa1b6 100644
--- a/src/tree/gb-project-tree-builder.c
+++ b/src/tree/gb-project-tree-builder.c
@@ -273,6 +273,62 @@ gb_project_tree_builder_build_node (GbTreeBuilder *builder,
     build_files (self, node);
 }
 
+static gchar *
+get_content_type (GFile *file)
+{
+  g_autofree gchar *name = NULL;
+
+  g_assert (G_IS_FILE (file));
+
+  name = g_file_get_basename (file);
+
+  return g_content_type_guess (name, NULL, 0, NULL);
+}
+
+static void
+populate_mime_handlers (GMenu          *menu,
+                        IdeProjectFile *project_file)
+{
+  g_autofree gchar *content_type = NULL;
+  GList *list;
+  GList *iter;
+  GFile *file;
+
+  g_assert (G_IS_MENU (menu));
+  g_assert (IDE_IS_PROJECT_FILE (project_file));
+
+  g_menu_remove_all (menu);
+
+  file = ide_project_file_get_file (project_file);
+  if (file == NULL)
+    return;
+
+  content_type = get_content_type (file);
+  if (content_type == NULL)
+    return;
+
+  list = g_app_info_get_all_for_type (content_type);
+
+  for (iter = list; iter; iter = iter->next)
+    {
+      g_autoptr(GMenuItem) menu_item = NULL;
+      g_autofree gchar *detailed_action = NULL;
+      GAppInfo *app_info = iter->data;
+      const gchar *display_name;
+      const gchar *app_id;
+
+      display_name = g_app_info_get_display_name (app_info);
+      app_id = g_app_info_get_id (app_info);
+
+      detailed_action = g_strdup_printf ("project-tree.open-with('%s')", app_id);
+      menu_item = g_menu_item_new (display_name, detailed_action);
+
+      g_menu_append_item (menu, menu_item);
+    }
+
+  g_list_free_full (list, g_object_unref);
+}
+
 static void
 gb_project_tree_builder_node_popup (GbTreeBuilder *builder,
                                     GbTreeNode    *node,
@@ -303,6 +359,9 @@ gb_project_tree_builder_node_popup (GbTreeBuilder *builder,
 
       submenu = gtk_application_get_menu_by_id (app, "project-tree-open");
       g_menu_prepend_section (menu, NULL, G_MENU_MODEL (submenu));
+
+      submenu = gtk_application_get_menu_by_id (app, "open-by-mime-section");
+      populate_mime_handlers (submenu, IDE_PROJECT_FILE (item));
     }
 
 }


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