UI: errors in buttons now show in info report
Mistakes in button expressions were previously only printed to the console.
This commit is contained in:
parent
3ed009af96
commit
29aae4db38
|
@ -2315,6 +2315,7 @@ bool ui_but_string_set(bContext *C, uiBut *but, const char *str)
|
|||
double value;
|
||||
|
||||
if (ui_but_string_set_eval_num(C, but, str, &value) == false) {
|
||||
WM_report_banner_show(C);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -478,6 +478,34 @@ error_cleanup:
|
|||
}
|
||||
#endif
|
||||
|
||||
PyObject *PyC_ExceptionBuffer_Simple(void)
|
||||
{
|
||||
PyObject *string_io_buf;
|
||||
|
||||
PyObject *error_type, *error_value, *error_traceback;
|
||||
|
||||
if (!PyErr_Occurred())
|
||||
return NULL;
|
||||
|
||||
PyErr_Fetch(&error_type, &error_value, &error_traceback);
|
||||
|
||||
if (error_value == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
string_io_buf = PyObject_Str(error_value);
|
||||
/* Python does this too */
|
||||
if (UNLIKELY(string_io_buf == NULL)) {
|
||||
string_io_buf = PyUnicode_FromFormat(
|
||||
"<unprintable %s object>", Py_TYPE(error_value)->tp_name);
|
||||
}
|
||||
|
||||
PyErr_Restore(error_type, error_value, error_traceback);
|
||||
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
return string_io_buf;
|
||||
}
|
||||
|
||||
/* string conversion, escape non-unicode chars, coerce must be set to NULL */
|
||||
const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
|
||||
|
|
|
@ -32,6 +32,7 @@ void PyC_ObSpit(const char *name, PyObject *var);
|
|||
void PyC_LineSpit(void);
|
||||
void PyC_StackSpit(void);
|
||||
PyObject * PyC_ExceptionBuffer(void);
|
||||
PyObject * PyC_ExceptionBuffer_Simple(void);
|
||||
PyObject * PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...);
|
||||
PyObject * PyC_FrozenSetFromStrings(const char **strings);
|
||||
PyObject * PyC_Err_Format_Prefix(PyObject *exception_type_prefix, const char *format, ...);
|
||||
|
|
|
@ -595,7 +595,7 @@ int BPY_button_exec(bContext *C, const char *expr, double *value, const bool ver
|
|||
|
||||
if (error_ret) {
|
||||
if (verbose) {
|
||||
BPy_errors_to_report(CTX_wm_reports(C));
|
||||
BPy_errors_to_report_ex(CTX_wm_reports(C), false, false);
|
||||
}
|
||||
else {
|
||||
PyErr_Clear();
|
||||
|
|
|
@ -82,10 +82,9 @@ short BPy_reports_to_error(ReportList *reports, PyObject *exception, const bool
|
|||
}
|
||||
|
||||
|
||||
short BPy_errors_to_report(ReportList *reports)
|
||||
bool BPy_errors_to_report_ex(ReportList *reports, const bool use_full, const bool use_location)
|
||||
{
|
||||
PyObject *pystring;
|
||||
PyObject *pystring_format = NULL; /* workaround, see below */
|
||||
const char *cstring;
|
||||
|
||||
const char *filename;
|
||||
|
@ -101,31 +100,49 @@ short BPy_errors_to_report(ReportList *reports)
|
|||
return 1;
|
||||
}
|
||||
|
||||
pystring = PyC_ExceptionBuffer();
|
||||
if (use_full) {
|
||||
pystring = PyC_ExceptionBuffer();
|
||||
}
|
||||
else {
|
||||
pystring = PyC_ExceptionBuffer_Simple();
|
||||
}
|
||||
|
||||
if (pystring == NULL) {
|
||||
BKE_report(reports, RPT_ERROR, "Unknown py-exception, could not convert");
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyC_FileAndNum(&filename, &lineno);
|
||||
if (filename == NULL)
|
||||
filename = "<unknown location>";
|
||||
|
||||
|
||||
cstring = _PyUnicode_AsString(pystring);
|
||||
|
||||
if (use_location) {
|
||||
PyObject *pystring_format; /* workaround, see below */
|
||||
|
||||
PyC_FileAndNum(&filename, &lineno);
|
||||
if (filename == NULL) {
|
||||
filename = "<unknown location>";
|
||||
}
|
||||
|
||||
#if 0 /* ARG!. workaround for a bug in blenders use of vsnprintf */
|
||||
BKE_reportf(reports, RPT_ERROR, "%s\nlocation: %s:%d\n", cstring, filename, lineno);
|
||||
BKE_reportf(reports, RPT_ERROR, "%s\nlocation: %s:%d\n", cstring, filename, lineno);
|
||||
#else
|
||||
pystring_format = PyUnicode_FromFormat(TIP_("%s\nlocation: %s:%d\n"), cstring, filename, lineno);
|
||||
cstring = _PyUnicode_AsString(pystring_format);
|
||||
BKE_report(reports, RPT_ERROR, cstring);
|
||||
pystring_format = PyUnicode_FromFormat(TIP_("%s\nlocation: %s:%d\n"), cstring, filename, lineno);
|
||||
cstring = _PyUnicode_AsString(pystring_format);
|
||||
BKE_report(reports, RPT_ERROR, cstring);
|
||||
Py_DECREF(pystring_format); /* workaround */
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
BKE_report(reports, RPT_ERROR, cstring);
|
||||
}
|
||||
|
||||
/* not exactly needed. just for testing */
|
||||
fprintf(stderr, TIP_("%s\nlocation: %s:%d\n"), cstring, filename, lineno);
|
||||
|
||||
Py_DECREF(pystring);
|
||||
Py_DECREF(pystring_format); /* workaround */
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool BPy_errors_to_report(ReportList *reports)
|
||||
{
|
||||
return BPy_errors_to_report_ex(reports, true, true);
|
||||
}
|
|
@ -40,7 +40,8 @@ char *BPy_enum_as_string(struct EnumPropertyItem *item);
|
|||
|
||||
/* error reporting */
|
||||
short BPy_reports_to_error(struct ReportList *reports, PyObject *exception, const bool clear);
|
||||
short BPy_errors_to_report(struct ReportList *reports);
|
||||
bool BPy_errors_to_report_ex(struct ReportList *reports, const bool use_full, const bool use_location);
|
||||
bool BPy_errors_to_report(struct ReportList *reports);
|
||||
|
||||
/* TODO - find a better solution! */
|
||||
struct bContext *BPy_GetContext(void);
|
||||
|
|
|
@ -178,6 +178,7 @@ void WM_main_remove_notifier_reference(const void *reference);
|
|||
void WM_main_remove_editor_id_reference(const struct ID *id);
|
||||
|
||||
/* reports */
|
||||
void WM_report_banner_show(const struct bContext *C);
|
||||
void WM_report(const struct bContext *C, ReportType type, const char *message);
|
||||
void WM_reportf(const struct bContext *C, ReportType type, const char *format, ...) ATTR_PRINTF_FORMAT(3, 4);
|
||||
|
||||
|
|
|
@ -587,26 +587,35 @@ void WM_event_print(const wmEvent *event)
|
|||
|
||||
#endif /* NDEBUG */
|
||||
|
||||
/**
|
||||
* Show the report in the info header.
|
||||
*/
|
||||
void WM_report_banner_show(const bContext *C)
|
||||
{
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
ReportList *wm_reports = CTX_wm_reports(C);
|
||||
ReportTimerInfo *rti;
|
||||
|
||||
/* After adding reports to the global list, reset the report timer. */
|
||||
WM_event_remove_timer(wm, NULL, wm_reports->reporttimer);
|
||||
|
||||
/* Records time since last report was added */
|
||||
wm_reports->reporttimer = WM_event_add_timer(wm, CTX_wm_window(C), TIMERREPORT, 0.05);
|
||||
|
||||
rti = MEM_callocN(sizeof(ReportTimerInfo), "ReportTimerInfo");
|
||||
wm_reports->reporttimer->customdata = rti;
|
||||
}
|
||||
|
||||
static void wm_add_reports(const bContext *C, ReportList *reports)
|
||||
{
|
||||
/* if the caller owns them, handle this */
|
||||
if (reports->list.first && (reports->flag & RPT_OP_HOLD) == 0) {
|
||||
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
ReportList *wm_reports = CTX_wm_reports(C);
|
||||
ReportTimerInfo *rti;
|
||||
|
||||
/* add reports to the global list, otherwise they are not seen */
|
||||
BLI_movelisttolist(&wm_reports->list, &reports->list);
|
||||
|
||||
/* After adding reports to the global list, reset the report timer. */
|
||||
WM_event_remove_timer(wm, NULL, wm_reports->reporttimer);
|
||||
|
||||
/* Records time since last report was added */
|
||||
wm_reports->reporttimer = WM_event_add_timer(wm, CTX_wm_window(C), TIMERREPORT, 0.05);
|
||||
|
||||
rti = MEM_callocN(sizeof(ReportTimerInfo), "ReportTimerInfo");
|
||||
wm_reports->reporttimer->customdata = rti;
|
||||
|
||||
WM_report_banner_show(C);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue