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