[gtk/wip/matthiasc/context-menu: 29/33] appchooser: Redo context menus



commit ff07d4dc8b2fb5962f40bfb652ba858bf3836d19
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Jan 29 19:12:32 2019 -0500

    appchooser: Redo context menus
    
    This following the same pattern applied in editable
    widgets before.

 gtk/gtkappchooserdialog.c | 62 ++++++++++++++++++++-------------
 gtk/gtkappchooserwidget.c | 89 ++++++-----------------------------------------
 2 files changed, 48 insertions(+), 103 deletions(-)
---
diff --git a/gtk/gtkappchooserdialog.c b/gtk/gtkappchooserdialog.c
index ec5ced63b2..bda1c50f85 100644
--- a/gtk/gtkappchooserdialog.c
+++ b/gtk/gtkappchooserdialog.c
@@ -80,6 +80,8 @@ struct _GtkAppChooserDialogPrivate {
 
   GtkSizeGroup *buttons;
 
+  GActionMap *context_actions;
+
   gboolean show_more_clicked;
   gboolean dismissed;
 };
@@ -141,6 +143,13 @@ widget_application_selected_cb (GtkAppChooserWidget *widget,
                                 gpointer             user_data)
 {
   GtkDialog *self = user_data;
+  gboolean can_remove;
+  GAction *action;
+
+  can_remove = g_app_info_can_remove_supports_type (app_info);
+
+  action = g_action_map_lookup_action (GTK_APP_CHOOSER_DIALOG (self)->priv->context_actions, 
"forget-association");
+  g_simple_action_set_enabled (G_SIMPLE_ACTION (action), can_remove);  
 
   gtk_dialog_set_response_sensitive (self, GTK_RESPONSE_OK, TRUE);
 }
@@ -281,8 +290,9 @@ widget_notify_for_button_cb (GObject    *source,
 }
 
 static void
-forget_menu_item_activate_cb (GtkMenuItem *item,
-                              gpointer     user_data)
+forget_association (GSimpleAction *action,
+                    GVariant      *parameter,
+                    gpointer     user_data)
 {
   GtkAppChooserDialog *self = user_data;
   GAppInfo *info;
@@ -299,34 +309,35 @@ forget_menu_item_activate_cb (GtkMenuItem *item,
     }
 }
 
-static GtkWidget *
-build_forget_menu_item (GtkAppChooserDialog *self)
+static void
+gtk_app_chooser_dialog_add_context_actions (GtkAppChooserDialog *self)
 {
-  GtkWidget *retval;
+    GActionEntry entries[] = {
+    { "forget-association", forget_association, NULL, NULL, NULL },
+  };
 
-  retval = gtk_menu_item_new_with_label (_("Forget association"));
-  gtk_widget_show (retval);
+  GSimpleActionGroup *actions = g_simple_action_group_new ();
+  GAction *action;
 
-  g_signal_connect (retval, "activate",
-                    G_CALLBACK (forget_menu_item_activate_cb), self);
+  self->priv->context_actions = G_ACTION_MAP (actions);
 
-  return retval;
+  g_action_map_add_action_entries (G_ACTION_MAP (actions), entries, G_N_ELEMENTS (entries), self);
+
+  action = g_action_map_lookup_action (G_ACTION_MAP (actions), "forget-association");
+  g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
+
+  gtk_widget_insert_action_group (GTK_WIDGET (self), "context", G_ACTION_GROUP (actions));
 }
 
 static void
-widget_populate_popup_cb (GtkAppChooserWidget *widget,
-                          GtkMenu             *menu,
-                          GAppInfo            *info,
-                          gpointer             user_data)
+setup_context_menu (GtkWidget *widget)
 {
-  GtkAppChooserDialog *self = user_data;
-  GtkWidget *menu_item;
+  GMenu *menu;
 
-  if (g_app_info_can_remove_supports_type (info))
-    {
-      menu_item = build_forget_menu_item (self);
-      gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
-    }
+  menu = g_menu_new ();
+  g_menu_append (menu, _("Forget association"), "context.forget-association");
+  gtk_widget_set_context_menu (widget, G_MENU_MODEL (menu));
+  g_object_unref (menu);
 }
 
 static void
@@ -339,15 +350,14 @@ construct_appchooser_widget (GtkAppChooserDialog *self)
   gtk_widget_set_vexpand (self->priv->app_chooser_widget, TRUE);
   gtk_container_add (GTK_CONTAINER (self->priv->inner_box), self->priv->app_chooser_widget);
 
-
   g_signal_connect (self->priv->app_chooser_widget, "application-selected",
                     G_CALLBACK (widget_application_selected_cb), self);
   g_signal_connect (self->priv->app_chooser_widget, "application-activated",
                     G_CALLBACK (widget_application_activated_cb), self);
   g_signal_connect (self->priv->app_chooser_widget, "notify::show-other",
                     G_CALLBACK (widget_notify_for_button_cb), self);
-  g_signal_connect (self->priv->app_chooser_widget, "populate-popup",
-                    G_CALLBACK (widget_populate_popup_cb), self);
+
+  setup_context_menu (self->priv->app_chooser_widget);
 
   /* Add the custom button to the new appchooser */
   gtk_container_add (GTK_CONTAINER (self->priv->inner_box),
@@ -533,6 +543,8 @@ gtk_app_chooser_dialog_finalize (GObject *object)
   g_free (self->priv->content_type);
   g_free (self->priv->heading);
 
+  g_object_unref (self->priv->context_actions);
+
   G_OBJECT_CLASS (gtk_app_chooser_dialog_parent_class)->finalize (object);
 }
 
@@ -671,6 +683,8 @@ gtk_app_chooser_dialog_init (GtkAppChooserDialog *self)
    */
   g_signal_connect (self, "response",
                     G_CALLBACK (gtk_app_chooser_dialog_response), NULL);
+
+  gtk_app_chooser_dialog_add_context_actions (self);
 }
 
 static void
diff --git a/gtk/gtkappchooserwidget.c b/gtk/gtkappchooserwidget.c
index 9ff532dc2f..a0bb3681d4 100644
--- a/gtk/gtkappchooserwidget.c
+++ b/gtk/gtkappchooserwidget.c
@@ -129,7 +129,6 @@ enum {
 enum {
   SIGNAL_APPLICATION_SELECTED,
   SIGNAL_APPLICATION_ACTIVATED,
-  SIGNAL_POPULATE_POPUP,
   N_SIGNALS
 };
 
@@ -178,43 +177,6 @@ refresh_and_emit_app_selected (GtkAppChooserWidget *self,
                    self->priv->selected_app_info);
 }
 
-static GAppInfo *
-get_app_info_for_coords (GtkAppChooserWidget *self,
-                         double               x,
-                         double               y)
-{
-  GtkTreePath *path = NULL;
-  GtkTreeIter iter;
-  GtkTreeModel *model;
-  GAppInfo *info;
-  gboolean recommended;
-
-  if (!gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (self->priv->program_list),
-                                      x, y,
-                                      &path,
-                                      NULL, NULL, NULL))
-    return NULL;
-
-  model = gtk_tree_view_get_model (GTK_TREE_VIEW (self->priv->program_list));
-
-  if (!gtk_tree_model_get_iter (model, &iter, path))
-    {
-      gtk_tree_path_free (path);
-      return NULL;
-    }
-
-  /* we only allow interaction with recommended applications */
-  gtk_tree_model_get (model, &iter,
-                      COLUMN_APP_INFO, &info,
-                      COLUMN_RECOMMENDED, &recommended,
-                      -1);
-
-  if (!recommended)
-    g_clear_object (&info);
-
-  return info;
-}
-
 static void
 popup_menu_detach (GtkWidget *attach_widget,
                    GtkMenu   *menu)
@@ -232,34 +194,24 @@ gtk_app_chooser_row_pressed_cb (GtkGesture *gesture,
                                 gpointer    user_data)
 {
   GtkAppChooserWidget *self = user_data;
-  GAppInfo *info;
   GtkWidget *menu;
-  GList *children;
-  gint n_children;
+  GMenuModel *model;
 
-  info = get_app_info_for_coords (self, x, y);
+  if (self->priv->popup_menu)
+    {
+      gtk_widget_destroy (self->priv->popup_menu);
+      self->priv->popup_menu = NULL;
+    }
 
-  if (info == NULL)
+  model = gtk_widget_get_context_menu (GTK_WIDGET (self));
+  if (model == NULL)
     return;
 
-  if (self->priv->popup_menu)
-    gtk_widget_destroy (self->priv->popup_menu);
-
-  self->priv->popup_menu = menu = gtk_menu_new ();
+  self->priv->popup_menu = menu = gtk_menu_new_from_model (model);
   gtk_menu_attach_to_widget (GTK_MENU (menu), GTK_WIDGET (self), popup_menu_detach);
 
-  g_signal_emit (self, signals[SIGNAL_POPULATE_POPUP], 0, menu, info);
-
-  g_object_unref (info);
-
-  /* see if clients added menu items to this container */
-  children = gtk_container_get_children (GTK_CONTAINER (menu));
-  n_children = g_list_length (children);
-
-  if (n_children > 0) /* actually popup the menu */
+  if (g_menu_model_get_n_items (model) > 0) /* actually popup the menu */
     gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL);
-
-  g_list_free (children);
 }
 
 static gboolean
@@ -1098,27 +1050,6 @@ gtk_app_chooser_widget_class_init (GtkAppChooserWidgetClass *klass)
                   G_TYPE_NONE,
                   1, G_TYPE_APP_INFO);
 
-  /**
-   * GtkAppChooserWidget::populate-popup:
-   * @self: the object which received the signal
-   * @menu: the #GtkMenu to populate
-   * @application: the current #GAppInfo
-   *
-   * Emitted when a context menu is about to popup over an application item.
-   * Clients can insert menu items into the provided #GtkMenu object in the
-   * callback of this signal; the context menu will be shown over the item
-   * if at least one item has been added to the menu.
-   */
-  signals[SIGNAL_POPULATE_POPUP] =
-    g_signal_new (I_("populate-popup"),
-                  GTK_TYPE_APP_CHOOSER_WIDGET,
-                  G_SIGNAL_RUN_FIRST,
-                  G_STRUCT_OFFSET (GtkAppChooserWidgetClass, populate_popup),
-                  NULL, NULL,
-                  _gtk_marshal_VOID__OBJECT_OBJECT,
-                  G_TYPE_NONE,
-                  2, GTK_TYPE_MENU, G_TYPE_APP_INFO);
-
   /* Bind class to template
    */
   gtk_widget_class_set_template_from_resource (widget_class,


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