Issue #5601: Command Search (/) Results to show Menu Path.

This commit is contained in:
Jehan 2023-04-07 17:32:43 +02:00
parent 32f93c49de
commit 7d1155af4a
7 changed files with 117 additions and 12 deletions

View file

@ -34,6 +34,7 @@
#include "widgets/gimpactionfactory.h"
#include "widgets/gimpdashboard.h"
#include "widgets/gimpmenufactory.h"
#include "widgets/gimpuimanager.h"
#include "dockable-menu.h"
#include "image-menu.h"
@ -523,8 +524,11 @@ menus_get_image_manager_singleton (Gimp *gimp)
static GimpUIManager *image_ui_manager = NULL;
if (image_ui_manager == NULL)
image_ui_manager = gimp_menu_factory_get_manager (menus_get_global_menu_factory (gimp),
"<Image>", gimp);
{
image_ui_manager = gimp_menu_factory_get_manager (menus_get_global_menu_factory (gimp),
"<Image>", gimp);
image_ui_manager->store_action_paths = TRUE;
}
return image_ui_manager;
}

View file

@ -73,6 +73,8 @@ struct _GimpActionPrivate
gchar **accels;
gchar **default_accels;
gchar *menu_path;
GimpRGB *color;
GimpViewable *viewable;
PangoEllipsizeMode ellipsize;
@ -213,6 +215,7 @@ gimp_action_init (GimpAction *action)
priv->icon = NULL;
priv->accels = NULL;
priv->default_accels = NULL;
priv->menu_path = NULL;
priv->ellipsize = PANGO_ELLIPSIZE_NONE;
priv->max_width_chars = -1;
priv->proxies = NULL;
@ -644,6 +647,14 @@ gimp_action_use_default_accels (GimpAction *action)
return TRUE;
}
const gchar *
gimp_action_get_menu_path (GimpAction *action)
{
g_return_val_if_fail (GIMP_IS_ACTION (action), NULL);
return GET_PRIVATE (action)->menu_path;
}
void
gimp_action_activate (GimpAction *action)
{
@ -1133,6 +1144,32 @@ gimp_action_set_default_accels (GimpAction *action,
g_signal_emit (action, action_signals[ACCELS_CHANGED], 0, accels);
}
/* This function is only meant to be run by the GimpMenuModel class. */
void
gimp_action_set_menu_path (GimpAction *action,
const gchar *menu_path)
{
GimpActionPrivate *priv = GET_PRIVATE (action);
gchar **paths;
g_return_if_fail (GIMP_IS_ACTION (action));
if (priv->menu_path != NULL)
/* There are cases where we put some actions in 2 menu paths, for instance:
* - filters-color-to-alpha in both /Layer/Transparency and /Colors
* - dialogs-histogram in both /Colors/Info and /Windows/Dockable Dialogs
*
* Anyway this is not an error, it's just how it is. Let's simply skip such
* cases silently and keep the first path as reference to show in helper
* widgets.
*/
return;
paths = gimp_utils_break_menu_path (menu_path);
/* The 4 raw bytes are the "rightwards triangle arrowhead" unicode character. */
priv->menu_path = g_strjoinv (" \xF0\x9F\xA2\x92 ", paths);
g_strfreev (paths);
}
/* Private functions */
@ -1176,6 +1213,8 @@ gimp_action_private_finalize (GimpActionPrivate *priv)
g_strfreev (priv->accels);
g_strfreev (priv->default_accels);
g_free (priv->menu_path);
for (GList *iter = priv->proxies; iter; iter = iter->next)
{
/* TODO GAction: if an action associated to a proxy menu item disappears,

View file

@ -115,6 +115,8 @@ const gchar ** gimp_action_get_accels (GimpAction *action);
gchar ** gimp_action_get_display_accels (GimpAction *action);
gboolean gimp_action_use_default_accels (GimpAction *action);
const gchar * gimp_action_get_menu_path (GimpAction *action);
void gimp_action_activate (GimpAction *action);
gint gimp_action_name_compare (GimpAction *action1,
@ -148,6 +150,8 @@ void gimp_action_set_group (GimpAction *action,
GimpActionGroup *group);
void gimp_action_set_default_accels (GimpAction *action,
const gchar **accels);
void gimp_action_set_menu_path (GimpAction *action,
const gchar *menu_path);
#endif /* __GIMP_ACTION_H__ */

View file

@ -653,6 +653,12 @@ gimp_menu_model_initialize (GimpMenuModel *model,
action = gimp_ui_manager_find_action (model->priv->manager, NULL, action_name);
if (model->priv->manager->store_action_paths)
/* Special-case the main menu manager when constructing it as
* this is the only one which should set the menu path.
*/
gimp_action_set_menu_path (action, gimp_menu_model_get_path (model));
g_signal_connect_object (action,
"notify::visible",
G_CALLBACK (gimp_menu_model_action_notify_visible),
@ -851,6 +857,9 @@ gimp_menu_model_ui_added (GimpUIManager *manager,
/* TODO: add also G_MENU_ATTRIBUTE_ICON attribute? */
g_free (detailed_action_name);
if (model->priv->manager->store_action_paths)
gimp_action_set_menu_path (GIMP_ACTION (action), gimp_menu_model_get_path (model));
if (placeholder_key)
{
GList *placeholder = NULL;

View file

@ -233,8 +233,9 @@ gimp_search_popup_add_result (GimpSearchPopup *popup,
gchar *label;
gchar *escaped_label = NULL;
const gchar *icon_name;
gchar *escaped_accel = NULL;
gboolean has_shortcut = FALSE;
gchar *shortcut_helper = NULL;
const gchar *menu_path;
gchar *menu_path_helper = NULL;
const gchar *tooltip;
gchar *escaped_tooltip = NULL;
gboolean has_tooltip = FALSE;
@ -267,11 +268,46 @@ gimp_search_popup_add_result (GimpSearchPopup *popup,
accels = gimp_action_get_display_accels (action);
if (accels && accels[0])
{
escaped_accel = g_markup_escape_text (accels[0], -1);
has_shortcut = TRUE;
gchar *formatted_label;
gchar *formatted_value;
/* TRANSLATORS: a helper label indicating the shortcut for an action,
* it will be used within the generic "%s: %s" (also localized) string.
* e.g.: "shortcut: Ctrl+Alt+O"
*/
formatted_label = g_markup_printf_escaped ("<u>%s</u>", _("shortcut"));
formatted_value = g_markup_escape_text (accels[0], -1);
/* TRANSLATORS: generic "title: value" label which will be used in various ways. */
shortcut_helper = g_strdup_printf (_("%s: %s"), formatted_label, formatted_value);
g_free (formatted_label);
g_free (formatted_value);
}
g_strfreev (accels);
if ((menu_path = gimp_action_get_menu_path (action)) != NULL)
{
if (strlen (menu_path) > 0)
{
gchar *formatted_label;
gchar *formatted_value;
/* TRANSLATORS: a helper label indicating the menu path for an action,
* it will be used within the generic "%s: %s" (also localized) string.
* e.g.: "Menu: Filters > Generic"
*/
formatted_label = g_markup_printf_escaped ("<u>%s</u>", _("menu"));
formatted_value = g_markup_escape_text (menu_path, -1);
/* TRANSLATORS: generic "title: value" label which will be used in various ways. */
menu_path_helper = g_strdup_printf (_("%s: %s"), formatted_label, formatted_value);
g_free (formatted_label);
g_free (formatted_value);
}
}
tooltip = gimp_action_get_tooltip (action);
if (tooltip != NULL)
{
@ -287,12 +323,18 @@ gimp_search_popup_add_result (GimpSearchPopup *popup,
markup = g_strdup_printf ("%s" /* Label */
"<small>%s%s" /* Shortcut */
"%s%s" /* Menu path */
"%s<span weight='light'>%s</span>" /* Tooltip */
"%s<i><span weight='ultralight'>%s</span></i>" /* Inactive reason */
"</small>",
escaped_label,
has_shortcut ? " | " : "",
has_shortcut ? escaped_accel : "",
shortcut_helper ? " | " : "",
shortcut_helper ? shortcut_helper : "",
menu_path_helper ? " | " : "",
menu_path_helper ? menu_path_helper : "",
has_tooltip ? "\n" : "",
has_tooltip ? escaped_tooltip : "",
escaped_reason ? "\n" : "",
@ -339,10 +381,11 @@ gimp_search_popup_add_result (GimpSearchPopup *popup,
g_free (markup);
g_free (action_name);
g_free (label);
g_free (escaped_accel);
g_free (escaped_label);
g_free (escaped_tooltip);
g_free (escaped_reason);
g_free (menu_path_helper);
g_free (shortcut_helper);
}
/************ Private Functions ****************/

View file

@ -199,9 +199,10 @@ gimp_ui_manager_class_init (GimpUIManagerClass *klass)
static void
gimp_ui_manager_init (GimpUIManager *manager)
{
manager->name = NULL;
manager->gimp = NULL;
manager->action_groups = NULL;
manager->name = NULL;
manager->gimp = NULL;
manager->action_groups = NULL;
manager->store_action_paths = FALSE;
}
static void

View file

@ -69,6 +69,11 @@ struct _GimpUIManager
GList *ui_items;
GList *action_groups;
/* Special property which should be set to TRUE only for the singleton UI
* manager of the top menu bar.
*/
gboolean store_action_paths;
};
struct _GimpUIManagerClass