1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 */
16
17 /** \file
18 * \ingroup edinterface
19 *
20 * Search available operators by scanning all and checking their poll function.
21 * accessed via the #WM_OT_search_operator operator.
22 */
23
24 #include <string.h>
25
26 #include "DNA_gpencil_modifier_types.h"
27 #include "DNA_node_types.h"
28 #include "DNA_object_types.h"
29 #include "DNA_scene_types.h"
30 #include "DNA_shader_fx_types.h"
31 #include "DNA_texture_types.h"
32
33 #include "BLI_alloca.h"
34 #include "BLI_ghash.h"
35 #include "BLI_string.h"
36 #include "BLI_utildefines.h"
37
38 #include "BLT_translation.h"
39
40 #include "BKE_context.h"
41 #include "BKE_global.h"
42
43 #include "WM_api.h"
44 #include "WM_types.h"
45
46 #include "UI_interface.h"
47 #include "interface_intern.h"
48
49 /* -------------------------------------------------------------------- */
50 /** \name Operator Search Template Implementation
51 * \{ */
52
operator_search_exec_fn(bContext * C,void * UNUSED (arg1),void * arg2)53 static void operator_search_exec_fn(bContext *C, void *UNUSED(arg1), void *arg2)
54 {
55 wmOperatorType *ot = arg2;
56
57 if (ot) {
58 WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, NULL);
59 }
60 }
61
operator_search_update_fn(const bContext * C,void * UNUSED (arg),const char * str,uiSearchItems * items)62 static void operator_search_update_fn(const bContext *C,
63 void *UNUSED(arg),
64 const char *str,
65 uiSearchItems *items)
66 {
67 GHashIterator iter;
68
69 /* Prepare BLI_string_all_words_matched. */
70 const size_t str_len = strlen(str);
71 const int words_max = BLI_string_max_possible_word_count(str_len);
72 int(*words)[2] = BLI_array_alloca(words, words_max);
73 const int words_len = BLI_string_find_split_words(str, str_len, ' ', words, words_max);
74
75 for (WM_operatortype_iter(&iter); !BLI_ghashIterator_done(&iter);
76 BLI_ghashIterator_step(&iter)) {
77 wmOperatorType *ot = BLI_ghashIterator_getValue(&iter);
78 const char *ot_ui_name = CTX_IFACE_(ot->translation_context, ot->name);
79
80 if ((ot->flag & OPTYPE_INTERNAL) && (G.debug & G_DEBUG_WM) == 0) {
81 continue;
82 }
83
84 if (BLI_string_all_words_matched(ot_ui_name, str, words, words_len)) {
85 if (WM_operator_poll((bContext *)C, ot)) {
86 char name[256];
87 const int len = strlen(ot_ui_name);
88
89 /* display name for menu, can hold hotkey */
90 BLI_strncpy(name, ot_ui_name, sizeof(name));
91
92 /* check for hotkey */
93 if (len < sizeof(name) - 6) {
94 if (WM_key_event_operator_string(C,
95 ot->idname,
96 WM_OP_EXEC_DEFAULT,
97 NULL,
98 true,
99 &name[len + 1],
100 sizeof(name) - len - 1)) {
101 name[len] = UI_SEP_CHAR;
102 }
103 }
104
105 if (!UI_search_item_add(items, name, ot, ICON_NONE, 0, 0)) {
106 break;
107 }
108 }
109 }
110 }
111 }
112
113 /** \} */
114
115 /* -------------------------------------------------------------------- */
116 /** \name Operator Search Template API
117 * \{ */
118
UI_but_func_operator_search(uiBut * but)119 void UI_but_func_operator_search(uiBut *but)
120 {
121 UI_but_func_search_set(but,
122 ui_searchbox_create_operator,
123 operator_search_update_fn,
124 NULL,
125 false,
126 operator_search_exec_fn,
127 NULL);
128 }
129
uiTemplateOperatorSearch(uiLayout * layout)130 void uiTemplateOperatorSearch(uiLayout *layout)
131 {
132 uiBlock *block;
133 uiBut *but;
134 static char search[256] = "";
135
136 block = uiLayoutGetBlock(layout);
137 UI_block_layout_set_current(block, layout);
138
139 but = uiDefSearchBut(
140 block, search, 0, ICON_VIEWZOOM, sizeof(search), 0, 0, UI_UNIT_X * 6, UI_UNIT_Y, 0, 0, "");
141 UI_but_func_operator_search(but);
142 }
143
144 /** \} */
145