2.5: Error reporting

* Added a report list to operator, to which they can report errors and
  warnings. When the operator ends, it will display them with a popup. For
  python these should become exceptions when calling operators.
* Added a function to make a popup menu from a report list.
* Also added a utility function to prepend a string before the reports to
  indicate what they relates to. Also made the report functions used
  BLI_dynstr to simplify the code.
* Made file reading and writing report errors to the user again using this
  system, also replacing the left over uncommented bad level error() calls.
This commit is contained in:
2008-12-29 13:38:08 +00:00
parent d51bc24384
commit 0a8a00cd10
23 changed files with 340 additions and 227 deletions

View File

@@ -34,9 +34,10 @@
#include "BKE_blender.h"
#include "BKE_context.h"
#include "BKE_idprop.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_idprop.h"
#include "BKE_report.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -65,6 +66,11 @@ void WM_operator_free(wmOperator *op)
if(op->ptr)
MEM_freeN(op->ptr);
if(op->reports) {
BKE_reports_clear(op->reports);
MEM_freeN(op->reports);
}
MEM_freeN(op);
}

View File

@@ -44,6 +44,7 @@
#include "BKE_context.h"
#include "BKE_idprop.h"
#include "BKE_global.h"
#include "BKE_report.h"
#include "BKE_utildefines.h"
#include "ED_screen.h"
@@ -52,6 +53,8 @@
#include "RNA_access.h"
#include "UI_interface.h"
#include "WM_api.h"
#include "WM_types.h"
#include "wm.h"
@@ -336,6 +339,10 @@ int WM_operator_call(bContext *C, wmOperator *op)
if(op->type->exec)
retval= op->type->exec(C, op);
if(!(retval & OPERATOR_RUNNING_MODAL))
if(op->reports->list.first)
uiPupmenuReports(C, op->reports);
if((retval & OPERATOR_FINISHED) && (op->type->flag & OPTYPE_REGISTER)) {
wm_operator_register(CTX_wm_manager(C), op);
@@ -364,6 +371,9 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, I
op->ptr= MEM_callocN(sizeof(PointerRNA), "wmOperatorPtrRNA");
RNA_pointer_create(&RNA_WindowManager, &wm->id, ot->srna, &op->properties, op->ptr);
op->reports= MEM_callocN(sizeof(ReportList), "wmOperatorReportList");
BKE_reports_init(op->reports, RPT_STORE);
if(op->type->invoke && event)
retval= (*op->type->invoke)(C, op, event);
else if(op->type->exec)
@@ -374,6 +384,10 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, I
if(G.f & G_DEBUG)
WM_operator_print(op);
if(!(retval & OPERATOR_RUNNING_MODAL))
if(op->reports->list.first)
uiPupmenuReports(C, op->reports);
if((retval & OPERATOR_FINISHED) && (ot->flag & OPTYPE_REGISTER)) {
wm_operator_register(wm, op);
}
@@ -588,6 +602,10 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
CTX_wm_area_set(C, NULL);
CTX_wm_region_set(C, NULL);
}
if(!(retval & OPERATOR_RUNNING_MODAL))
if(op->reports->list.first)
uiPupmenuReports(C, op->reports);
if((retval & OPERATOR_FINISHED) && (ot->flag & OPTYPE_REGISTER)) {
wm_operator_register(CTX_wm_manager(C), op);

View File

@@ -481,7 +481,7 @@ static void verse_unsub(void)
}
#endif
void WM_read_file(bContext *C, char *name)
void WM_read_file(bContext *C, char *name, ReportList *reports)
{
int retval;
@@ -501,7 +501,7 @@ void WM_read_file(bContext *C, char *name)
/* put aside screens to match with persistant windows later */
wm_window_match_init(C, &wmbase);
retval= BKE_read_file(C, name, NULL);
retval= BKE_read_file(C, name, NULL, reports);
/* match the read WM with current WM */
wm_window_match_do(C, &wmbase);
@@ -524,8 +524,10 @@ void WM_read_file(bContext *C, char *name)
}
// else if(retval==1)
// XXX BIF_undo_push("Import file");
else if(retval == -1)
WM_error(C, "Cannot read file");
else if(retval == -1) {
if(reports && reports->list.first == NULL)
BKE_report(reports, RPT_ERROR, "Cannot read file.");
}
}
static void outliner_242_patch(void)
@@ -573,9 +575,9 @@ int WM_read_homefile(bContext *C, int from_memory)
wm_window_match_init(C, &wmbase);
if (!from_memory && BLI_exists(tstr)) {
success = BKE_read_file(C, tstr, NULL);
success = BKE_read_file(C, tstr, NULL, NULL);
} else {
success = BKE_read_file_from_memory(C, datatoc_B_blend, datatoc_B_blend_size, NULL);
success = BKE_read_file_from_memory(C, datatoc_B_blend, datatoc_B_blend_size, NULL, NULL);
/* outliner patch for 2.42 .b.blend */
outliner_242_patch();
}
@@ -643,7 +645,7 @@ void WM_read_autosavefile(bContext *C)
get_autosave_location(tstr);
save_over = G.save_over;
BKE_read_file(C, tstr, NULL);
BKE_read_file(C, tstr, NULL, NULL);
G.save_over = save_over;
BLI_strncpy(G.sce, scestr, FILE_MAX);
}
@@ -781,7 +783,7 @@ static void writeBlog(void)
}
}
static void do_history(char *name)
static void do_history(char *name, ReportList *reports)
{
char tempname1[FILE_MAXDIR+FILE_MAXFILE], tempname2[FILE_MAXDIR+FILE_MAXFILE];
int hisnr= U.versions;
@@ -789,12 +791,12 @@ static void do_history(char *name)
if(U.versions==0) return;
if(strlen(name)<2) return;
while( hisnr > 1) {
while(hisnr > 1) {
sprintf(tempname1, "%s%d", name, hisnr-1);
sprintf(tempname2, "%s%d", name, hisnr);
// if(BLI_rename(tempname1, tempname2))
// XXX error("Unable to make version backup");
if(BLI_rename(tempname1, tempname2))
BKE_report(reports, RPT_ERROR, "Unable to make version backup");
hisnr--;
}
@@ -802,22 +804,21 @@ static void do_history(char *name)
/* is needed when hisnr==1 */
sprintf(tempname1, "%s%d", name, hisnr);
// if(BLI_rename(name, tempname1))
// XXX error("Unable to make version backup");
if(BLI_rename(name, tempname1))
BKE_report(reports, RPT_ERROR, "Unable to make version backup");
}
void WM_write_file(bContext *C, char *target)
void WM_write_file(bContext *C, char *target, ReportList *reports)
{
Library *li;
int writeflags, len;
char di[FILE_MAX];
ReportList reports;
len = strlen(target);
if (len == 0) return;
if (len >= FILE_MAX) {
// XXX error("Path too long, cannot save");
BKE_report(reports, RPT_ERROR, "Path too long, cannot save");
return;
}
@@ -826,7 +827,7 @@ void WM_write_file(bContext *C, char *target)
for (li= G.main->library.first; li; li= li->id.next) {
if (BLI_streq(li->name, target)) {
// XXX error("Cannot overwrite used library");
BKE_report(reports, RPT_ERROR, "Cannot overwrite used library");
return;
}
}
@@ -851,16 +852,14 @@ void WM_write_file(bContext *C, char *target)
// XXX waitcursor(1); // exit_editmode sets cursor too
do_history(di);
do_history(di, reports);
/* we use the UserDef to define compression flag */
writeflags= G.fileflags & ~G_FILE_COMPRESS;
if(U.flag & USER_FILECOMPRESS)
writeflags |= G_FILE_COMPRESS;
BKE_reports_init(&reports, RPT_STORE);
if (BLO_write_file(CTX_data_main(C), di, writeflags, &reports)) {
if (BLO_write_file(CTX_data_main(C), di, writeflags, reports)) {
strcpy(G.sce, di);
G.relbase_valid = 1;
strcpy(G.main->name, di); /* is guaranteed current file */
@@ -870,38 +869,29 @@ void WM_write_file(bContext *C, char *target)
G.save_over = 1;
writeBlog();
} else {
// XXX error("%s", err);
}
BKE_reports_clear(&reports);
// XXX waitcursor(0);
}
/* operator entry */
int WM_write_homefile(bContext *C, wmOperator *op)
{
ReportList reports;
char tstr[FILE_MAXDIR+FILE_MAXFILE];
int write_flags;
BLI_make_file_string("/", tstr, BLI_gethome(), ".B.blend");
BLI_make_file_string("/", tstr, "/", ".B.blend");
/* force save as regular blend file */
write_flags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN);
// XXX error reporting to the user
BKE_reports_init(&reports, RPT_PRINT);
BLO_write_file(CTX_data_main(C), tstr, write_flags, &reports);
BKE_reports_clear(&reports);
BLO_write_file(CTX_data_main(C), tstr, write_flags, op->reports);
return OPERATOR_FINISHED;
}
void WM_write_autosave(bContext *C)
{
ReportList reports;
char tstr[FILE_MAXDIR+FILE_MAXFILE];
int write_flags;
@@ -910,9 +900,8 @@ void WM_write_autosave(bContext *C)
/* force save as regular blend file */
write_flags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN);
BKE_reports_init(&reports, RPT_PRINT);
BLO_write_file(CTX_data_main(C), tstr, write_flags, &reports);
BKE_reports_clear(&reports);
/* error reporting to console */
BLO_write_file(CTX_data_main(C), tstr, write_flags, NULL);
}
/* if global undo; remove tempsave, otherwise rename */
@@ -933,7 +922,3 @@ void delete_autosave(void)
/***/

View File

@@ -195,17 +195,6 @@ int WM_menu_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_CANCELLED;
}
/* call anywhere */
void WM_error(bContext *C, char *str)
{
char buf[148], testbuf[128];
BLI_strncpy(testbuf, str, 128);
sprintf(buf, "Error %%i%d%%t|%s", ICON_ERROR, testbuf);
uiPupmenu(C, 0, NULL, NULL, buf);
}
/* op->invoke */
int WM_operator_confirm(bContext *C, wmOperator *op, wmEvent *event)
{
@@ -276,11 +265,11 @@ static int recentfile_exec(bContext *C, wmOperator *op)
if(event>0) {
if (G.sce[0] && (event==1))
WM_read_file(C, G.sce);
WM_read_file(C, G.sce, op->reports);
else {
struct RecentFile *recent = BLI_findlink(&(G.recent_files), event-2);
if(recent) {
WM_read_file(C, recent->filename);
WM_read_file(C, recent->filename, op->reports);
}
}
}