diff options
-rw-r--r-- | CMakeLists.txt | 7 | ||||
-rw-r--r-- | source/blender/editors/include/UI_interface.h | 5 | ||||
-rw-r--r-- | source/blender/editors/interface/interface.c | 19 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_handlers.c | 41 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_intern.h | 5 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_ops.c | 239 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 83 |
7 files changed, 271 insertions, 128 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 6e3247a7d2c..13be77e90eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -213,9 +213,6 @@ mark_as_advanced(WITH_CXX_GUARDEDALLOC) option(WITH_ASSERT_ABORT "Call abort() when raising an assertion through BLI_assert()" OFF) mark_as_advanced(WITH_ASSERT_ABORT) -option(WITH_PYTHON_UI_INFO "Allow navigating to UI source from the context menu" OFF) -mark_as_advanced(WITH_PYTHON_UI_INFO) - if(APPLE) if(NOT CMAKE_OSX_ARCHITECTURES) @@ -1330,10 +1327,6 @@ if(WITH_ASSERT_ABORT) add_definitions(-DWITH_ASSERT_ABORT) endif() -if(WITH_PYTHON_UI_INFO) - add_definitions(-DWITH_PYTHON_UI_INFO) -endif() - # message(STATUS "Using CFLAGS: ${CMAKE_C_FLAGS}") # message(STATUS "Using CXXFLAGS: ${CMAKE_CXX_FLAGS}") diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 43f6b36f5eb..5e9e7c65f83 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -787,6 +787,7 @@ void uiItemMenuEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propn void UI_buttons_operatortypes(void); /* Helpers for Operators */ +uiBut *uiContextActiveButton(const struct bContext *C); void uiContextActiveProperty(const struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA **prop, int *index); void uiContextActivePropertyHandle(struct bContext *C); void uiContextAnimUpdate(const struct bContext *C); @@ -817,5 +818,9 @@ const char *UI_translate_do_tooltip(const char *msgid); #define IFACE_(msgid) UI_translate_do_iface(msgid) #define TIP_(msgid) UI_translate_do_tooltip(msgid) +/* UI_OT_editsource helpers */ +int UI_editsource_enable_check(void); +void UI_editsource_active_but_test(uiBut *but); + #endif /* UI_INTERFACE_H */ diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index b7b572e7217..f9991079507 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -2562,23 +2562,10 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, if(block->curlayout) ui_layout_add_but(block->curlayout, but); -#ifdef WITH_PYTHON_UI_INFO - { - extern void PyC_FileAndNum_Safe(const char **filename, int *lineno); - - const char *fn; - int lineno= -1; - PyC_FileAndNum_Safe(&fn, &lineno); - if (lineno != -1) { - BLI_strncpy(but->py_dbg_fn, fn, sizeof(but->py_dbg_fn)); - but->py_dbg_ln= lineno; - } - else { - but->py_dbg_fn[0]= '\0'; - but->py_dbg_ln= -1; - } + /* if the 'UI_OT_editsource' is running, extract the source info from the button */ + if (UI_editsource_enable_check()) { + UI_editsource_active_but_test(but); } -#endif /* WITH_PYTHON_UI_INFO */ return but; } diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 32c4ec21e13..79080eb5f3b 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -4443,16 +4443,8 @@ static int ui_but_menu(bContext *C, uiBut *but) } } -#ifdef WITH_PYTHON_UI_INFO - if (but->py_dbg_ln != -1) { - PointerRNA ptr_props; - - WM_operator_properties_create(&ptr_props, "WM_OT_text_edit"); - RNA_string_set(&ptr_props, "filepath", but->py_dbg_fn); - RNA_int_set(&ptr_props, "line", but->py_dbg_ln); - uiItemFullO(layout, "WM_OT_text_edit", "Edit Source", ICON_NONE, ptr_props.data, WM_OP_EXEC_DEFAULT, 0); - } -#endif /* WITH_PYTHON_UI_INFO */ + /* perhaps we should move this into (G.f & G_DEBUG) - campbell */ + uiItemFullO(layout, "UI_OT_editsource", "Edit Source", ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0); uiPupMenuEnd(C, pup); @@ -5146,9 +5138,10 @@ void ui_button_active_free(const bContext *C, uiBut *but) } } -static uiBut *ui_context_rna_button_active(const bContext *C) +/* returns the active button with an optional checking function */ +static uiBut *ui_context_button_active(const bContext *C, int (*but_check_cb)(uiBut *)) { - uiBut *rnabut= NULL; + uiBut *but_found= NULL; ARegion *ar= CTX_wm_region(C); @@ -5166,26 +5159,40 @@ static uiBut *ui_context_rna_button_active(const bContext *C) } } - if(activebut && activebut->rnapoin.data) { + if(activebut && (but_check_cb == NULL || but_check_cb(activebut))) { uiHandleButtonData *data= activebut->active; - rnabut= activebut; + but_found= activebut; /* recurse into opened menu, like colorpicker case */ if(data && data->menu && (ar != data->menu->region)) { ar = data->menu->region; } else { - return rnabut; + return but_found; } } else { /* no active button */ - return rnabut; + return but_found; } } - return rnabut; + return but_found; +} + +static int ui_context_rna_button_active_test(uiBut *but) +{ + return (but->rnapoin.data != NULL); +} +static uiBut *ui_context_rna_button_active(const bContext *C) +{ + return ui_context_button_active(C, ui_context_rna_button_active_test); +} + +uiBut *uiContextActiveButton(const struct bContext *C) +{ + return ui_context_button_active(C, NULL); } /* helper function for insert keyframe, reset to default, etc operators */ diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index b7a2227f98a..9d0383c8812 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -252,11 +252,6 @@ struct uiBut { /* pointer back */ uiBlock *block; - -#ifdef WITH_PYTHON_UI_INFO - char py_dbg_fn[240]; - int py_dbg_ln; -#endif }; struct uiBlock { diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index 081b528d153..ebd6150cfd0 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -61,6 +61,10 @@ #include "WM_api.h" #include "WM_types.h" +/* only for UI_OT_editsource */ +#include "ED_screen.h" +#include "BKE_main.h" +#include "BLI_ghash.h" /* ********************************************************** */ @@ -474,6 +478,240 @@ static void UI_OT_reports_to_textblock(wmOperatorType *ot) ot->exec= reports_to_text_exec; } + +/* ------------------------------------------------------------------------- */ +/* EditSource Utility funcs and operator, + * note, this includes itility functions and button matching checks */ + +struct uiEditSourceStore { + uiBut but_orig; + GHash *hash; +} uiEditSourceStore; + +struct uiEditSourceButStore { + char py_dbg_fn[240]; + int py_dbg_ln; +} uiEditSourceButStore; + +/* should only ever be set while the edit source operator is running */ +struct uiEditSourceStore *ui_editsource_info= NULL; + +int UI_editsource_enable_check(void) +{ + return (ui_editsource_info != NULL); +} + +static void ui_editsource_active_but_set(uiBut *but) +{ + BLI_assert(ui_editsource_info == NULL); + + ui_editsource_info= MEM_callocN(sizeof(uiEditSourceStore), __func__); + memcpy(&ui_editsource_info->but_orig, but, sizeof(uiBut)); + + ui_editsource_info->hash = BLI_ghash_new(BLI_ghashutil_ptrhash, + BLI_ghashutil_ptrcmp, + __func__); +} + +static void ui_editsource_active_but_clear(void) +{ + BLI_ghash_free(ui_editsource_info->hash, NULL, (GHashValFreeFP)MEM_freeN); + MEM_freeN(ui_editsource_info); + ui_editsource_info= NULL; +} + +static int ui_editsource_uibut_match(uiBut *but_a, uiBut *but_b) +{ +#if 0 + printf("matching buttons: '%s' == '%s'\n", + but_a->drawstr, but_b->drawstr); +#endif + + /* this just needs to be a 'good-enough' comparison so we can know beyond + * reasonable doubt that these buttons are the same between redraws. + * if this fails it only means edit-source fails - campbell */ + if( (but_a->x1 == but_b->x1) && + (but_a->x2 == but_b->x2) && + (but_a->y1 == but_b->y1) && + (but_a->y2 == but_b->y2) && + (but_a->type == but_b->type) && + (but_a->rnaprop == but_b->rnaprop) && + (but_a->optype == but_b->optype) && + (but_a->unit_type == but_b->unit_type) && + strncmp(but_a->drawstr, but_b->drawstr, UI_MAX_DRAW_STR) == 0 + ) { + return TRUE; + } + else { + return FALSE; + } +} + +void UI_editsource_active_but_test(uiBut *but) +{ + extern void PyC_FileAndNum_Safe(const char **filename, int *lineno); + + struct uiEditSourceButStore *but_store= MEM_callocN(sizeof(uiEditSourceButStore), __func__); + + const char *fn; + int lineno= -1; + +#if 0 + printf("comparing buttons: '%s' == '%s'\n", + but->drawstr, ui_editsource_info->but_orig.drawstr); +#endif + + PyC_FileAndNum_Safe(&fn, &lineno); + + if (lineno != -1) { + BLI_strncpy(but_store->py_dbg_fn, fn, + sizeof(but_store->py_dbg_fn)); + but_store->py_dbg_ln= lineno; + } + else { + but_store->py_dbg_fn[0]= '\0'; + but_store->py_dbg_ln= -1; + } + + BLI_ghash_insert(ui_editsource_info->hash, but, but_store); +} + +/* editsource operator component */ + +static ScrArea *biggest_text_view(bContext *C) +{ + bScreen *sc= CTX_wm_screen(C); + ScrArea *sa, *big= NULL; + int size, maxsize= 0; + + for(sa= sc->areabase.first; sa; sa= sa->next) { + if(sa->spacetype==SPACE_TEXT) { + size= sa->winx * sa->winy; + if(size > maxsize) { + maxsize= size; + big= sa; + } + } + } + return big; +} + +static int editsource_text_edit(bContext *C, wmOperator *op, + char filepath[240], int line) +{ + struct Main *bmain= CTX_data_main(C); + Text *text; + + for (text=bmain->text.first; text; text=text->id.next) { + if (text->name && BLI_path_cmp(text->name, filepath) == 0) { + break; + } + } + + if (text == NULL) { + text= add_text(filepath, bmain->name); + } + + if (text == NULL) { + BKE_reportf(op->reports, RPT_WARNING, + "file: '%s' can't be opened", filepath); + return OPERATOR_CANCELLED; + } + else { + /* naughty!, find text area to set, not good behavior + * but since this is a dev tool lets allow it - campbell */ + ScrArea *sa= biggest_text_view(C); + if(sa) { + SpaceText *st= sa->spacedata.first; + st->text= text; + } + else { + BKE_reportf(op->reports, RPT_INFO, + "See '%s' in the text editor", text->id.name + 2); + } + + txt_move_toline(text, line - 1, FALSE); + WM_event_add_notifier(C, NC_TEXT|ND_CURSOR, text); + } + + return OPERATOR_FINISHED; +} + +static int editsource_exec(bContext *C, wmOperator *op) +{ + uiBut *but= uiContextActiveButton(C); + + if (but) { + GHashIterator ghi; + struct uiEditSourceButStore *but_store= NULL; + + ARegion *ar= CTX_wm_region(C); + int ret; + + uiFreeActiveButtons(C, CTX_wm_screen(C)); + + // printf("%s: begin\n", __func__); + + ui_editsource_active_but_set(but); + + /* redraw and get active button python info */ + ED_region_do_draw(C, ar); + + for(BLI_ghashIterator_init(&ghi, ui_editsource_info->hash); + !BLI_ghashIterator_isDone(&ghi); + BLI_ghashIterator_step(&ghi)) + { + uiBut *but= BLI_ghashIterator_getKey(&ghi); + if (but && ui_editsource_uibut_match(&ui_editsource_info->but_orig, but)) { + but_store= BLI_ghashIterator_getValue(&ghi); + break; + } + + } + + if (but_store) { + if (but_store->py_dbg_ln != -1) { + ret= editsource_text_edit(C, op, + but_store->py_dbg_fn, + but_store->py_dbg_ln); + } + else { + BKE_report(op->reports, RPT_ERROR, + "Active button isn't from a script, cant edit source."); + ret= OPERATOR_CANCELLED; + } + } + else { + BKE_report(op->reports, RPT_ERROR, + "Active button match can't be found."); + ret= OPERATOR_CANCELLED; + } + + + ui_editsource_active_but_clear(); + + // printf("%s: end\n", __func__); + + return ret; + } + else { + BKE_report(op->reports, RPT_ERROR, "Active button not found"); + return OPERATOR_CANCELLED; + } +} + +static void UI_OT_editsource(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Reports to Text Block"; + ot->idname= "UI_OT_editsource"; + ot->description= "Edit source code for a button"; + + /* callbacks */ + ot->exec= editsource_exec; +} + + /* ********************************************************* */ /* Registration */ @@ -485,5 +723,6 @@ void UI_buttons_operatortypes(void) WM_operatortype_append(UI_OT_reset_default_button); WM_operatortype_append(UI_OT_copy_to_selected_button); WM_operatortype_append(UI_OT_reports_to_textblock); // XXX: temp? + WM_operatortype_append(UI_OT_editsource); } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 5fee5fb2a57..49bb3132204 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -104,11 +104,6 @@ static GHash *global_ops_hash= NULL; -#ifdef WITH_PYTHON_UI_INFO -# include "DNA_text_types.h" -# include "BKE_text.h" -#endif - /* ************ operator API, exported ********** */ @@ -3509,79 +3504,6 @@ static void operatortype_ghash_free_cb(wmOperatorType *ot) MEM_freeN(ot); } -#ifdef WITH_PYTHON_UI_INFO - -static ScrArea *biggest_text_view(bContext *C) -{ - bScreen *sc= CTX_wm_screen(C); - ScrArea *sa, *big= NULL; - int size, maxsize= 0; - - for(sa= sc->areabase.first; sa; sa= sa->next) { - if(sa->spacetype==SPACE_TEXT) { - size= sa->winx * sa->winy; - if(size > maxsize) { - maxsize= size; - big= sa; - } - } - } - return big; -} - -static int wm_text_edit_exec(bContext *C, wmOperator *op) -{ - Main *bmain= CTX_data_main(C); - Text *text; - - char filepath[240]; - int line= RNA_int_get(op->ptr, "line"); - RNA_string_get(op->ptr, "filepath", filepath); - - for (text=bmain->text.first; text; text=text->id.next) { - if (text->name && BLI_path_cmp(text->name, filepath) == 0) { - break; - } - } - - if (text == NULL) { - text= add_text(filepath, bmain->name); - } - - if (text == NULL) { - BKE_reportf(op->reports, RPT_WARNING, "file: '%s' can't be opened", filepath); - return OPERATOR_CANCELLED; - } - else { - /* naughty!, find text area to set, not good behavior - * but since this is a dev tool lets allow it - campbell */ - ScrArea *sa= biggest_text_view(C); - if(sa) { - SpaceText *st= sa->spacedata.first; - st->text= text; - } - - txt_move_toline(text, line - 1, FALSE); - WM_event_add_notifier(C, NC_TEXT|ND_CURSOR, text); - } - - return OPERATOR_FINISHED; -} - -static void WM_OT_text_edit(wmOperatorType *ot) -{ - ot->name= "Edit Text File"; - ot->idname= "WM_OT_text_edit"; - - ot->exec= wm_text_edit_exec; - - RNA_def_string_file_path(ot->srna, "filepath", "", FILE_MAX, "Path", ""); - RNA_def_int(ot->srna, "line", 0, INT_MIN, INT_MAX, "Line", "", 0, INT_MAX); -} - -#endif /* WITH_PYTHON_UI_INFO */ - - /* ******************************************************* */ /* called on initialize WM_exit() */ void wm_operatortype_free(void) @@ -3624,11 +3546,6 @@ void wm_operatortype_init(void) WM_operatortype_append(WM_OT_collada_export); WM_operatortype_append(WM_OT_collada_import); #endif - -#ifdef WITH_PYTHON_UI_INFO - WM_operatortype_append(WM_OT_text_edit); -#endif - } /* circleselect-like modal operators */ |