Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2011-10-23 08:13:56 +0400
committerCampbell Barton <ideasman42@gmail.com>2011-10-23 08:13:56 +0400
commit8e2bc6cdbcb47c5f2e4714241fde0ac970f6f58e (patch)
tree6c588cd22b7c40e31d3715eecc96a699d7343334 /source/blender/editors/interface/interface_ops.c
parent29417887d7e78f31cbefc5d86c156237484e837a (diff)
Context menu 'Edit Source' operator no longer needs to be enabled as a build option, improved this so the python file:line lookups are only done when the operator runs (previously this was done for every button, every draw when the build option was enabled).
Perhaps this should be hidden when not running with --debug, easy to change.
Diffstat (limited to 'source/blender/editors/interface/interface_ops.c')
-rw-r--r--source/blender/editors/interface/interface_ops.c239
1 files changed, 239 insertions, 0 deletions
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);
}