Fix some more export bugs
This commit is contained in:
		| @ -152,15 +152,9 @@ static enum { | ||||
| } export_confirm_action(ExportScreen *screen, | ||||
|                         SensorState *state, | ||||
|                         const char *fmt, ...) { | ||||
|     int done_status = EXPORT_CONFIRM_CONTINUE; | ||||
|     if (screen->current_op && export_check_bg_task(screen)) { | ||||
|         // background task done | ||||
|         done_status = EXPORT_CONFIRM_CONTINUE; | ||||
|         goto confirm_done; | ||||
|     } | ||||
|     int done_status; | ||||
|     if (state->back_down || (state->sel_down && !screen->confirm_state)) { | ||||
|         done_status = EXPORT_CONFIRM_NO; | ||||
|         screen->need_redraw = true; | ||||
|         goto confirm_done; | ||||
|     } | ||||
|     if (state->sel_down) { | ||||
| @ -193,6 +187,7 @@ static enum { | ||||
|     lcd_display_control(state->lcd, LCD_CURSOR_NO_BLINK, LCD_CURSOR_OFF, | ||||
|                         LCD_DISPLAY_ON); | ||||
|     screen->confirm_state = false; | ||||
|     screen->need_redraw = true; | ||||
|     return done_status; | ||||
| } | ||||
|  | ||||
| @ -225,12 +220,14 @@ static const char BACKGROUND_CHARS[] = { | ||||
|  * True if done, false otherwise | ||||
|  */ | ||||
| static bool export_do_background_action(ExportScreen *screen, SensorState *state) { | ||||
|     if (state->down_down || state->up_down || state->back_down || | ||||
|         state->sel_down) { | ||||
|         screen->last_cancel_stage = screen->stage; | ||||
|         screen->stage = EXPORT_SCREEN_CONFIRM_CANCEL; | ||||
|     if (!screen->show_cancel_screen && (state->down_down || state->up_down || | ||||
|                                         state->back_down || state->sel_down)) { | ||||
|         screen->show_cancel_screen = true; | ||||
|         screen->need_redraw = true; | ||||
|         return false; | ||||
|         // we need to make sure that the confirm action screen ignores actions | ||||
|         // for this iteration of the UI loop | ||||
|         state->back_down = state->up_down = | ||||
|             state->sel_down = state->down_down = false; | ||||
|     } | ||||
|     if (!screen->current_op) { | ||||
|         screen->stage = EXPORT_SCREEN_FAILED; | ||||
| @ -240,16 +237,32 @@ static bool export_do_background_action(ExportScreen *screen, SensorState *state | ||||
|     if (export_check_bg_task(screen)) { | ||||
|         return true; | ||||
|     } | ||||
|     time_t now = time(NULL); | ||||
|     if (screen->need_redraw || now != screen->last_char_change) { | ||||
|         lcd_display_control(state->lcd, LCD_CURSOR_NO_BLINK, LCD_CURSOR_OFF, | ||||
|                             LCD_DISPLAY_ON); | ||||
|         screen->last_char_change = now; | ||||
|         screen->need_redraw = false; | ||||
|         lcd_clear(state->lcd); | ||||
|         lcd_move_to(state->lcd, 0, 0); | ||||
|         lcd_write_string(state->lcd, "Working"); | ||||
|         lcd_write_char(state->lcd, BACKGROUND_CHARS[screen->working_char++ % NBACKGROUND_CHAR]); | ||||
|     if (screen->show_cancel_screen) { | ||||
|         int confirm_status = export_confirm_action(screen, state, "Really cancel?"); | ||||
|         if (confirm_status == EXPORT_CONFIRM_YES) { | ||||
|             async_operation_free(screen->current_op); | ||||
|             screen->current_op = NULL; | ||||
|             AsyncOperation *op = drive_unmount(&screen->drives[screen->cur_drive], true); | ||||
|             async_operation_poll(op, true); | ||||
|             async_operation_free(op); | ||||
|             screen->stage = EXPORT_SCREEN_CANCELED; | ||||
|             screen->need_redraw = true; | ||||
|         } else if (confirm_status == EXPORT_CONFIRM_NO) { | ||||
|             screen->need_redraw = true; | ||||
|             screen->show_cancel_screen = false; | ||||
|         } | ||||
|     } else { | ||||
|         time_t now = time(NULL); | ||||
|         if (screen->need_redraw || now != screen->last_char_change) { | ||||
|             lcd_display_control(state->lcd, LCD_CURSOR_NO_BLINK, LCD_CURSOR_OFF, | ||||
|                                 LCD_DISPLAY_ON); | ||||
|             screen->last_char_change = now; | ||||
|             screen->need_redraw = false; | ||||
|             lcd_clear(state->lcd); | ||||
|             lcd_move_to(state->lcd, 0, 0); | ||||
|             lcd_write_string(state->lcd, "Working"); | ||||
|             lcd_write_char(state->lcd, BACKGROUND_CHARS[screen->working_char++ % NBACKGROUND_CHAR]); | ||||
|         } | ||||
|     } | ||||
|     return false; | ||||
| } | ||||
| @ -291,6 +304,7 @@ static void export_handle_write(ExportScreen *screen, SensorState *state) { | ||||
|         return; | ||||
|     } | ||||
|     // if we have no current op, start a new one | ||||
|     screen->show_cancel_screen = false; | ||||
|     pid_t pid = fork(); | ||||
|     if (pid < 0) { | ||||
|         warn("failed to start write background task"); | ||||
| @ -344,6 +358,7 @@ static bool export_screen_dispatch(ExportScreen *screen, | ||||
|     case EXPORT_SCREEN_WRITE_NEWFS: | ||||
|         if (!screen->current_op) { | ||||
|             screen->current_op = drive_newfs_msdos(cur_drive); | ||||
|             screen->show_cancel_screen = false; | ||||
|         } | ||||
|         if (export_do_background_action(screen, state)) { | ||||
|             screen->stage = EXPORT_SCREEN_MOUNTING; | ||||
| @ -353,6 +368,7 @@ static bool export_screen_dispatch(ExportScreen *screen, | ||||
|     case EXPORT_SCREEN_MOUNTING: | ||||
|         if (!screen->current_op) { | ||||
|             screen->current_op = drive_mount(cur_drive); | ||||
|             screen->show_cancel_screen = false; | ||||
|         } | ||||
|         if (export_do_background_action(screen, state)) { | ||||
|             char *path = export_build_cur_path(screen); | ||||
| @ -387,27 +403,13 @@ static bool export_screen_dispatch(ExportScreen *screen, | ||||
|     case EXPORT_SCREEN_UNMOUNT: | ||||
|         if (!screen->current_op) { | ||||
|             screen->current_op = drive_unmount(cur_drive, false); | ||||
|             screen->show_cancel_screen = false; | ||||
|         } | ||||
|         if (export_do_background_action(screen, state)) { | ||||
|             screen->stage = EXPORT_SCREEN_DONE; | ||||
|             screen->need_redraw = true; | ||||
|         } | ||||
|         break; | ||||
|     case EXPORT_SCREEN_CONFIRM_CANCEL: | ||||
|         confirm_status = export_confirm_action(screen, state, "Really cancel?"); | ||||
|         if (confirm_status == EXPORT_CONFIRM_YES) { | ||||
|             async_operation_free(screen->current_op); | ||||
|             screen->current_op = NULL; | ||||
|             AsyncOperation *op = drive_unmount(cur_drive, true); | ||||
|             async_operation_poll(op, true); | ||||
|             async_operation_free(op); | ||||
|             screen->stage = EXPORT_SCREEN_CANCELED; | ||||
|             screen->need_redraw = true; | ||||
|         } else if (confirm_status == EXPORT_CONFIRM_NO) { | ||||
|             screen->stage = screen->last_cancel_stage; | ||||
|             screen->need_redraw = true; | ||||
|         } | ||||
|         break; | ||||
|     case EXPORT_SCREEN_CANCELED: | ||||
|         return export_show_message(screen, state, "Cancelled!"); | ||||
|     case EXPORT_SCREEN_FAILED: | ||||
|  | ||||
| @ -30,7 +30,6 @@ typedef struct { | ||||
|         EXPORT_SCREEN_WRITING, | ||||
|         EXPORT_SCREEN_UNMOUNT, | ||||
|         EXPORT_SCREEN_DONE, | ||||
|         EXPORT_SCREEN_CONFIRM_CANCEL, | ||||
|         EXPORT_SCREEN_CANCELED, | ||||
|         EXPORT_SCREEN_FAILED, | ||||
|         EXPORT_SCREEN_NO_DRIVES, | ||||
| @ -54,6 +53,7 @@ typedef struct { | ||||
|     sqlite3 *db_cache; | ||||
|     int last_cancel_stage; | ||||
|     AsyncOperation *current_op; | ||||
|     bool show_cancel_screen; | ||||
| } ExportScreen; | ||||
|  | ||||
| ExportScreen *export_screen_new(void); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user