Blender  V2.93
buttons_ops.c
Go to the documentation of this file.
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  * The Original Code is Copyright (C) 2009 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include "MEM_guardedalloc.h"
28 
29 #include "DNA_userdef_types.h"
30 
31 #include "BLI_fileops.h"
32 #include "BLI_path_util.h"
33 #include "BLI_string.h"
34 #include "BLI_utildefines.h"
35 
36 #include "BLT_translation.h"
37 
38 #include "BKE_context.h"
39 #include "BKE_main.h"
40 #include "BKE_report.h"
41 #include "BKE_screen.h"
42 
43 #include "WM_api.h"
44 #include "WM_types.h"
45 
46 #include "ED_screen.h"
47 #include "ED_undo.h"
48 
49 #include "RNA_access.h"
50 
51 #include "UI_interface.h"
52 #include "UI_resources.h"
53 
54 #include "buttons_intern.h" /* own include */
55 
56 /* -------------------------------------------------------------------- */
63 {
67 
68  ARegion *region_ctx = CTX_wm_region(C);
69  CTX_wm_region_set(C, region);
70  UI_textbutton_activate_rna(C, region, space, "search_filter");
71  CTX_wm_region_set(C, region_ctx);
72 
73  return OPERATOR_FINISHED;
74 }
75 
77 {
78  /* Identifiers. */
79  ot->name = "Filter";
80  ot->description = "Start entering filter text";
81  ot->idname = "BUTTONS_OT_start_filter";
82 
83  /* Callbacks. */
86 }
87 
89 {
91 
92  space->runtime->search_string[0] = '\0';
93 
97 
98  return OPERATOR_FINISHED;
99 }
100 
102 {
103  /* Identifiers. */
104  ot->name = "Clear Filter";
105  ot->description = "Clear the search filter";
106  ot->idname = "BUTTONS_OT_clear_filter";
107 
108  /* Callbacks. */
111 }
112 
115 /* -------------------------------------------------------------------- */
120 {
122 
123  sbuts->flag ^= SB_PIN_CONTEXT;
124 
125  /* Create the properties space pointer. */
126  PointerRNA sbuts_ptr;
127  bScreen *screen = CTX_wm_screen(C);
128  RNA_pointer_create(&screen->id, &RNA_SpaceProperties, sbuts, &sbuts_ptr);
129 
130  /* Create the new ID pointer and set the pin ID with RNA
131  * so we can use the property's RNA update functionality. */
132  ID *new_id = (sbuts->flag & SB_PIN_CONTEXT) ? buttons_context_id_path(C) : NULL;
133  PointerRNA new_id_ptr;
134  RNA_id_pointer_create(new_id, &new_id_ptr);
135  RNA_pointer_set(&sbuts_ptr, "pin_id", new_id_ptr);
136 
138 
139  return OPERATOR_FINISHED;
140 }
141 
143 {
144  /* Identifiers. */
145  ot->name = "Toggle Pin ID";
146  ot->description = "Keep the current data-block displayed";
147  ot->idname = "BUTTONS_OT_toggle_pin";
148 
149  /* Callbacks. */
152 }
153 
156 /* -------------------------------------------------------------------- */
160 static int context_menu_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
161 {
162  uiPopupMenu *pup = UI_popup_menu_begin(C, IFACE_("Context Menu"), ICON_NONE);
163  uiLayout *layout = UI_popup_menu_layout(pup);
164 
165  uiItemM(layout, "INFO_MT_area", NULL, ICON_NONE);
166  UI_popup_menu_end(C, pup);
167 
168  return OPERATOR_INTERFACE;
169 }
170 
172 {
173  /* Identifiers. */
174  ot->name = "Context Menu";
175  ot->description = "Display properties editor context_menu";
176  ot->idname = "BUTTONS_OT_context_menu";
177 
178  /* Callbacks. */
181 }
182 
185 /* -------------------------------------------------------------------- */
189 typedef struct FileBrowseOp {
192  bool is_undo;
195 
197 {
198  Main *bmain = CTX_data_main(C);
199  FileBrowseOp *fbo = op->customdata;
200  ID *id;
201  char *str, path[FILE_MAX];
202  const char *path_prop = RNA_struct_find_property(op->ptr, "directory") ? "directory" :
203  "filepath";
204 
205  if (RNA_struct_property_is_set(op->ptr, path_prop) == 0 || fbo == NULL) {
206  return OPERATOR_CANCELLED;
207  }
208 
209  str = RNA_string_get_alloc(op->ptr, path_prop, NULL, 0);
210 
211  /* Add slash for directories, important for some properties. */
212  if (RNA_property_subtype(fbo->prop) == PROP_DIRPATH) {
213  const bool is_relative = RNA_boolean_get(op->ptr, "relative_path");
214  id = fbo->ptr.owner_id;
215 
216  BLI_strncpy(path, str, FILE_MAX);
217  BLI_path_abs(path, id ? ID_BLEND_PATH(bmain, id) : BKE_main_blendfile_path(bmain));
218 
219  if (BLI_is_dir(path)) {
220  /* Do this first so '//' isn't converted to '//\' on windows. */
221  BLI_path_slash_ensure(path);
222  if (is_relative) {
223  BLI_strncpy(path, str, FILE_MAX);
225  str = MEM_reallocN(str, strlen(path) + 2);
226  BLI_strncpy(str, path, FILE_MAX);
227  }
228  else {
229  str = MEM_reallocN(str, strlen(str) + 2);
230  }
231  }
232  else {
233  char *const lslash = (char *)BLI_path_slash_rfind(str);
234  if (lslash) {
235  lslash[1] = '\0';
236  }
237  }
238  }
239 
240  RNA_property_string_set(&fbo->ptr, fbo->prop, str);
241  RNA_property_update(C, &fbo->ptr, fbo->prop);
242  MEM_freeN(str);
243 
244  if (fbo->is_undo) {
245  const char *undostr = RNA_property_identifier(fbo->prop);
246  ED_undo_push(C, undostr);
247  }
248 
249  /* Special annoying exception, filesel on redo panel T26618. */
250  {
251  wmOperator *redo_op = WM_operator_last_redo(C);
252  if (redo_op) {
253  if (fbo->ptr.data == redo_op->ptr->data) {
254  ED_undo_operator_repeat(C, redo_op);
255  }
256  }
257  }
258 
259  /* Tag user preferences as dirty. */
260  if (fbo->is_userdef) {
261  U.runtime.is_dirty = true;
262  }
263 
264  MEM_freeN(op->customdata);
265 
266  return OPERATOR_FINISHED;
267 }
268 
270 {
271  MEM_freeN(op->customdata);
272  op->customdata = NULL;
273 }
274 
275 static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event)
276 {
277  PointerRNA ptr;
278  PropertyRNA *prop;
279  bool is_undo;
280  bool is_userdef;
281  FileBrowseOp *fbo;
282  char *str;
283 
284  if (CTX_wm_space_file(C)) {
285  BKE_report(op->reports, RPT_ERROR, "Cannot activate a file selector, one already open");
286  return OPERATOR_CANCELLED;
287  }
288 
289  UI_context_active_but_prop_get_filebrowser(C, &ptr, &prop, &is_undo, &is_userdef);
290 
291  if (!prop) {
292  return OPERATOR_CANCELLED;
293  }
294 
296 
297  /* Useful yet irritating feature, Shift+Click to open the file
298  * Alt+Click to browse a folder in the OS's browser. */
299  if (event->shift || event->alt) {
300  wmOperatorType *ot = WM_operatortype_find("WM_OT_path_open", true);
301  PointerRNA props_ptr;
302 
303  if (event->alt) {
304  char *lslash = (char *)BLI_path_slash_rfind(str);
305  if (lslash) {
306  *lslash = '\0';
307  }
308  }
309 
311  RNA_string_set(&props_ptr, "filepath", str);
313  WM_operator_properties_free(&props_ptr);
314 
315  MEM_freeN(str);
316  return OPERATOR_CANCELLED;
317  }
318 
319  PropertyRNA *prop_relpath;
320  const char *path_prop = RNA_struct_find_property(op->ptr, "directory") ? "directory" :
321  "filepath";
322  fbo = MEM_callocN(sizeof(FileBrowseOp), "FileBrowseOp");
323  fbo->ptr = ptr;
324  fbo->prop = prop;
325  fbo->is_undo = is_undo;
326  fbo->is_userdef = is_userdef;
327  op->customdata = fbo;
328 
329  /* Normally ED_fileselect_get_params would handle this but we need to because of stupid
330  * user-prefs exception. - campbell */
331  if ((prop_relpath = RNA_struct_find_property(op->ptr, "relative_path"))) {
332  if (!RNA_property_is_set(op->ptr, prop_relpath)) {
333  bool is_relative = (U.flag & USER_RELPATHS) != 0;
334 
335  /* While we want to follow the defaults,
336  * we better not switch existing paths relative/absolute state. */
337  if (str[0]) {
338  is_relative = BLI_path_is_rel(str);
339  }
340 
341  if (UNLIKELY(ptr.data == &U || is_userdef)) {
342  is_relative = false;
343  }
344 
345  /* Annoying exception!, if we're dealing with the user prefs, default relative to be off. */
346  RNA_property_boolean_set(op->ptr, prop_relpath, is_relative);
347  }
348  }
349 
350  RNA_string_set(op->ptr, path_prop, str);
351  MEM_freeN(str);
352 
354 
355  return OPERATOR_RUNNING_MODAL;
356 }
357 
359 {
360  /* Identifiers. */
361  ot->name = "Accept";
362  ot->description =
363  "Open a file browser, hold Shift to open the file, Alt to browse containing directory";
364  ot->idname = "BUTTONS_OT_file_browse";
365 
366  /* Callbacks. */
370 
371  /* Conditional undo based on button flag. */
372  ot->flag = 0;
373 
374  /* Properties. */
376  0,
377  FILE_SPECIAL,
382 }
383 
384 /* Second operator, only difference from BUTTONS_OT_file_browse is WM_FILESEL_DIRECTORY. */
386 {
387  /* identifiers */
388  ot->name = "Accept";
389  ot->description =
390  "Open a directory browser, hold Shift to open the file, Alt to browse containing directory";
391  ot->idname = "BUTTONS_OT_directory_browse";
392 
393  /* api callbacks */
397 
398  /* conditional undo based on button flag */
399  ot->flag = 0;
400 
401  /* properties */
403  0,
404  FILE_SPECIAL,
409 }
410 
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:714
void CTX_wm_region_set(bContext *C, struct ARegion *region)
Definition: context.c:985
struct SpaceProperties * CTX_wm_space_properties(const bContext *C)
Definition: context.c:809
struct bScreen * CTX_wm_screen(const bContext *C)
Definition: context.c:709
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
struct SpaceFile * CTX_wm_space_file(const bContext *C)
Definition: context.c:818
const char * BKE_main_blendfile_path(const struct Main *bmain) ATTR_NONNULL()
void BKE_report(ReportList *reports, ReportType type, const char *message)
Definition: report.c:104
struct ARegion * BKE_area_find_region_type(const struct ScrArea *area, int type)
File and directory operations.
bool BLI_is_dir(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: storage.c:436
bool BLI_path_is_rel(const char *path) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
Definition: path_util.c:411
#define FILE_MAX
int BLI_path_slash_ensure(char *string) ATTR_NONNULL()
Definition: path_util.c:1981
void BLI_path_rel(char *file, const char *relfile) ATTR_NONNULL()
Definition: path_util.c:519
const char * BLI_path_slash_rfind(const char *string) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
Definition: path_util.c:1962
bool BLI_path_abs(char *path, const char *basepath) ATTR_NONNULL()
Definition: path_util.c:1016
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
#define UNUSED(x)
#define UNLIKELY(x)
#define IFACE_(msgid)
#define ID_BLEND_PATH(_bmain, _id)
Definition: DNA_ID.h:419
@ RGN_TYPE_HEADER
@ FILE_SORT_DEFAULT
@ FILE_SPECIAL
@ SB_PIN_CONTEXT
@ FILE_OPENFILE
@ FILE_DEFAULTDISPLAY
@ USER_RELPATHS
@ OPERATOR_CANCELLED
@ OPERATOR_INTERFACE
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
void ED_area_tag_redraw(ScrArea *area)
Definition: area.c:745
bool ED_operator_buttons_active(struct bContext *C)
Definition: screen_ops.c:287
void ED_region_search_filter_update(const struct ScrArea *area, struct ARegion *region)
int ED_undo_operator_repeat(struct bContext *C, struct wmOperator *op)
Definition: ed_undo.c:678
void ED_undo_push(struct bContext *C, const char *str)
Definition: ed_undo.c:117
Read Guarded memory(de)allocation.
#define MEM_reallocN(vmemh, len)
StructRNA RNA_SpaceProperties
@ PROP_DIRPATH
Definition: RNA_types.h:117
#define C
Definition: RandGen.cpp:39
struct uiLayout * UI_popup_menu_layout(uiPopupMenu *pup)
void UI_context_active_but_prop_get_filebrowser(const struct bContext *C, struct PointerRNA *r_ptr, struct PropertyRNA **r_prop, bool *r_is_undo, bool *r_is_userdef)
bool UI_textbutton_activate_rna(const struct bContext *C, struct ARegion *region, const void *rna_poin_data, const char *rna_prop_id)
void UI_popup_menu_end(struct bContext *C, struct uiPopupMenu *pup)
uiPopupMenu * UI_popup_menu_begin(struct bContext *C, const char *title, int icon) ATTR_NONNULL()
void uiItemM(uiLayout *layout, const char *menuname, const char *name, int icon)
#define WM_FILESEL_DIRECTORY
Definition: WM_api.h:535
#define WM_FILESEL_RELPATH
Definition: WM_api.h:533
#define WM_FILESEL_FILEPATH
Definition: WM_api.h:537
@ WM_OP_EXEC_DEFAULT
Definition: WM_types.h:204
unsigned int U
Definition: btGjkEpa3.h:78
ID * buttons_context_id_path(const bContext *C)
static int buttons_clear_filter_exec(bContext *C, wmOperator *UNUSED(op))
Definition: buttons_ops.c:88
static int toggle_pin_exec(bContext *C, wmOperator *UNUSED(op))
Definition: buttons_ops.c:119
static int buttons_start_filter_exec(bContext *C, wmOperator *UNUSED(op))
Definition: buttons_ops.c:62
static int context_menu_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
Definition: buttons_ops.c:160
void BUTTONS_OT_toggle_pin(wmOperatorType *ot)
Definition: buttons_ops.c:142
void BUTTONS_OT_context_menu(wmOperatorType *ot)
Definition: buttons_ops.c:171
void BUTTONS_OT_directory_browse(wmOperatorType *ot)
Definition: buttons_ops.c:385
static int file_browse_exec(bContext *C, wmOperator *op)
Definition: buttons_ops.c:196
static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: buttons_ops.c:275
void BUTTONS_OT_start_filter(struct wmOperatorType *ot)
Definition: buttons_ops.c:76
struct FileBrowseOp FileBrowseOp
void BUTTONS_OT_file_browse(wmOperatorType *ot)
Definition: buttons_ops.c:358
static void file_browse_cancel(bContext *UNUSED(C), wmOperator *op)
Definition: buttons_ops.c:269
void BUTTONS_OT_clear_filter(struct wmOperatorType *ot)
Definition: buttons_ops.c:101
#define str(s)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static void area(int d1, int d2, int e1, int e2, float weights[2])
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:146
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
Definition: rna_access.c:6550
void RNA_pointer_set(PointerRNA *ptr, const char *name, PointerRNA ptr_value)
Definition: rna_access.c:6574
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:122
const char * RNA_property_identifier(const PropertyRNA *prop)
Definition: rna_access.c:1145
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:6655
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:866
void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2317
char * RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen, int *r_len)
Definition: rna_access.c:3339
void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value)
Definition: rna_access.c:2358
PropertySubType RNA_property_subtype(PropertyRNA *prop)
Definition: rna_access.c:1160
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:6685
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
Definition: rna_access.c:3401
char * RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen)
Definition: rna_access.c:6527
PointerRNA ptr
Definition: buttons_ops.c:190
PropertyRNA * prop
Definition: buttons_ops.c:191
Definition: DNA_ID.h:273
Definition: BKE_main.h:116
void * data
Definition: RNA_types.h:52
struct ID * owner_id
Definition: RNA_types.h:50
char search_string[UI_MAX_NAME_STR]
struct SpaceProperties_Runtime * runtime
short shift
Definition: WM_types.h:618
short alt
Definition: WM_types.h:618
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
void(* cancel)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:760
const char * description
Definition: WM_types.h:726
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
struct ReportList * reports
struct PointerRNA * ptr
void WM_event_add_fileselect(bContext *C, wmOperator *op)
int WM_operator_name_call_ptr(bContext *C, wmOperatorType *ot, short context, PointerRNA *properties)
PointerRNA * ptr
Definition: wm_files.c:3157
wmOperatorType * ot
Definition: wm_files.c:3156
void WM_operator_properties_filesel(wmOperatorType *ot, int filter, short type, short action, short flag, short display, short sort)
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)
void WM_operator_properties_create_ptr(PointerRNA *ptr, wmOperatorType *ot)
Definition: wm_operators.c:584
void WM_operator_properties_free(PointerRNA *ptr)
Definition: wm_operators.c:711
wmOperator * WM_operator_last_redo(const bContext *C)