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:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
/***/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user