diff --git a/app/config/gimpguiconfig.c b/app/config/gimpguiconfig.c index 436d0701da..5c9f147a71 100644 --- a/app/config/gimpguiconfig.c +++ b/app/config/gimpguiconfig.c @@ -78,7 +78,6 @@ enum PROP_SHOW_HELP_BUTTON, PROP_HELP_LOCALES, PROP_HELP_BROWSER, - PROP_SEARCH_SHOW_UNAVAILABLE_ACTIONS, PROP_ACTION_HISTORY_SIZE, PROP_USER_MANUAL_ONLINE, PROP_USER_MANUAL_ONLINE_URI, @@ -377,13 +376,6 @@ gimp_gui_config_class_init (GimpGuiConfigClass *klass) DEFAULT_USER_MANUAL_ONLINE_URI, GIMP_PARAM_STATIC_STRINGS); - GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SEARCH_SHOW_UNAVAILABLE_ACTIONS, - "search-show-unavailable-actions", - "Show unavailable actions", - SEARCH_SHOW_UNAVAILABLE_BLURB, - FALSE, - GIMP_PARAM_STATIC_STRINGS); - GIMP_CONFIG_PROP_INT (object_class, PROP_ACTION_HISTORY_SIZE, "action-history-size", "Action history size", @@ -675,9 +667,6 @@ gimp_gui_config_set_property (GObject *object, g_free (gui_config->user_manual_online_uri); gui_config->user_manual_online_uri = g_value_dup_string (value); break; - case PROP_SEARCH_SHOW_UNAVAILABLE_ACTIONS: - gui_config->search_show_unavailable = g_value_get_boolean (value); - break; case PROP_ACTION_HISTORY_SIZE: gui_config->action_history_size = g_value_get_int (value); break; @@ -841,9 +830,6 @@ gimp_gui_config_get_property (GObject *object, case PROP_USER_MANUAL_ONLINE_URI: g_value_set_string (value, gui_config->user_manual_online_uri); break; - case PROP_SEARCH_SHOW_UNAVAILABLE_ACTIONS: - g_value_set_boolean (value, gui_config->search_show_unavailable); - break; case PROP_ACTION_HISTORY_SIZE: g_value_set_int (value, gui_config->action_history_size); break; diff --git a/app/config/gimpguiconfig.h b/app/config/gimpguiconfig.h index b757d93bde..ac1c6b59df 100644 --- a/app/config/gimpguiconfig.h +++ b/app/config/gimpguiconfig.h @@ -75,7 +75,6 @@ struct _GimpGuiConfig GimpHelpBrowserType help_browser; gboolean user_manual_online; gchar *user_manual_online_uri; - gboolean search_show_unavailable; gint action_history_size; GimpWindowHint dock_window_hint; GimpHandedness cursor_handedness; diff --git a/app/dialogs/action-search-dialog.c b/app/dialogs/action-search-dialog.c index 7b1d4346e4..79b4f5e96d 100644 --- a/app/dialogs/action-search-dialog.c +++ b/app/dialogs/action-search-dialog.c @@ -46,6 +46,7 @@ #include "gimp-intl.h" +#define ACTION_SECTION_INACTIVE 7 static void action_search_history_and_actions (GimpSearchPopup *popup, const gchar *keyword, @@ -95,13 +96,12 @@ action_search_history_and_actions (GimpSearchPopup *popup, action_search_match_keyword, keyword); - /* First put on top of the list any matching action of user history. */ + /* 0. Top result: matching action in run history. */ for (list = history_actions; list; list = g_list_next (list)) - { - gimp_search_popup_add_result (popup, list->data, 0); - } + gimp_search_popup_add_result (popup, list->data, + gimp_action_is_sensitive (list->data) ? 0 : ACTION_SECTION_INACTIVE); - /* Now check other actions. */ + /* 1. Then other matching actions. */ for (list = gimp_ui_manager_get_action_groups (manager); list; list = g_list_next (list)) @@ -130,9 +130,7 @@ action_search_history_and_actions (GimpSearchPopup *popup, if (gimp_action_history_is_blacklisted_action (name)) continue; - if (! gimp_action_is_visible (action) || - (! gimp_action_is_sensitive (action) && - ! GIMP_GUI_CONFIG (gimp->config)->search_show_unavailable)) + if (! gimp_action_is_visible (action)) continue; if (action_search_match_keyword (action, keyword, §ion, gimp)) @@ -165,6 +163,44 @@ action_search_history_and_actions (GimpSearchPopup *popup, g_list_free_full (history_actions, (GDestroyNotify) g_object_unref); } +/** + * action_search_match_keyword: + * @action: a #GimpAction to be matched. + * @keyword: free text keyword to match with @action. + * @section: relative section telling "how well" @keyword matched + * @action. The smaller the @section, the better the match. In + * particular this value can be used in the call to + * gimp_search_popup_add_result() to show best matches at the + * top of the list. + * @gimp: the #Gimp object. This matters because we will tokenize + * keywords, labels and tooltip by language. + * + * This function will check if some freely typed text @keyword matches + * @action's label or tooltip, using a few algorithms to determine the + * best matches (order of words, start of match, and so on). + * All text (the user-provided @keyword as well as @actions labels and + * tooltips) are unicoded normalized, tokenized and case-folded before + * being compared. Comparisons with ASCII alternatives are also + * performed, providing even better matches, depending on the user + * languages (accounting for variant orthography in natural languages). + * + * @section will be set to: + * - 0 for any @action if @keyword is %NULL (match all). + * - 1 for a full initialism. + * - 4 for a partial initialism. + * - 1 if key tokens are found in the same order in the label and match + * the start of the label. + * - 2 if key tokens are found in the label order but don't match the + * start of the label. + * - 3 if key tokens are found with a different order from label. + * - 5 if @keyword matches the tooltip. + * - 6 if @keyword is a mix-match on tooltip and label. + * In the end, @section is incremented by %ACTION_SECTION_INACTIVE if + * the action is non-sensitive. + * + * Returns: %TRUE is a match was successful (in which case, @section + * will be set as well). + */ static gboolean action_search_match_keyword (GimpAction *action, const gchar *keyword, @@ -183,9 +219,8 @@ action_search_match_keyword (GimpAction *action, * matches. */ if (section) - { - *section = 0; - } + *section = gimp_action_is_sensitive (action) ? 0 : ACTION_SECTION_INACTIVE; + return TRUE; } @@ -338,11 +373,11 @@ one_tooltip_matched: } if (matched && section) { - /* Matching the tooltip is section 4. We don't go looking + /* Matching the tooltip is section 5. We don't go looking * for start of string or token order for tooltip match. * But if the match is mixed on tooltip and label (there are * no match for *only* label or *only* tooltip), this is - * section 5. */ + * section 6. */ *section = mixed_match ? 6 : 5; } } @@ -354,5 +389,8 @@ one_tooltip_matched: g_strfreev (label_tokens); g_strfreev (label_alternates); + if (matched && section && ! gimp_action_is_sensitive (action)) + *section += ACTION_SECTION_INACTIVE; + return matched; } diff --git a/app/dialogs/preferences-dialog.c b/app/dialogs/preferences-dialog.c index fc2c811b5b..2aafa0a26c 100644 --- a/app/dialogs/preferences-dialog.c +++ b/app/dialogs/preferences-dialog.c @@ -2632,9 +2632,6 @@ prefs_dialog_new (Gimp *gimp, vbox2 = prefs_frame_new (_("Action Search"), GTK_CONTAINER (vbox), FALSE); grid = prefs_grid_new (GTK_CONTAINER (vbox2)); - prefs_check_button_add (object, "search-show-unavailable-actions", - _("Show _unavailable actions"), - GTK_BOX (vbox2)); prefs_spin_button_add (object, "action-history-size", 1.0, 10.0, 0, _("_Maximum History Size:"), GTK_GRID (grid), 0, size_group); diff --git a/app/widgets/gimpaction-history.c b/app/widgets/gimpaction-history.c index 5bfefd1cce..2a766221a2 100644 --- a/app/widgets/gimpaction-history.c +++ b/app/widgets/gimpaction-history.c @@ -260,11 +260,19 @@ gimp_action_history_clear (Gimp *gimp) gimp_action_history_item_free (item); } -/* Search all history actions which match "keyword" with function - * match_func(action, keyword). +/** + * gimp_action_history_search: + * @gimp: + * @match_func: + * @keyword: * - * @return a list of GtkAction*, to free with: - * g_list_free_full (result, (GDestroyNotify) g_object_unref); + * Search all history #GimpAction which match @keyword with function + * @match_func(action, keyword). + * It will also return inactive actions, but will discard non-visible + * actions. + * + * returns: a #GList of #GimpAction, which must be freed with + * g_list_free_full (result, (GDestroyNotify) g_object_unref) */ GList * gimp_action_history_search (Gimp *gimp, @@ -294,9 +302,7 @@ gimp_action_history_search (Gimp *gimp, if (action == NULL) continue; - if (! gimp_action_is_visible (action) || - (! gimp_action_is_sensitive (action) && - ! config->search_show_unavailable)) + if (! gimp_action_is_visible (action)) continue; if (match_func (action, keyword, NULL, gimp))