From 35a25fc24fb27ac996a5115ee55fe6f485c6c07c Mon Sep 17 00:00:00 2001 From: Claudius Appel <151634114+Claudius-Appel@users.noreply.github.com> Date: Fri, 6 Dec 2024 14:54:54 +0100 Subject: [PATCH 1/6] `duflor_gui()`: cb's `input$save_state`: completely rework the root-selection and error-catching to no longer fail on NA roots --- R/app.R | 136 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 94 insertions(+), 42 deletions(-) diff --git a/R/app.R b/R/app.R index 972ad09..b556cf0 100644 --- a/R/app.R +++ b/R/app.R @@ -1430,48 +1430,43 @@ duflor_gui <- function() { observeEvent(input$save_state, { # Save directory selection input_mirror <- input ## mirror input so that the error-trycatch can pass it to save_state - shinyFileSave( - input, - "save_state", - roots = volumes, - session = getDefaultReactiveDomain(), - allowDirCreate = T - ) - savedir_path <- parseDirPath(roots = volumes, selection = input$save_state) - req(isFALSE(is.numeric(input$save_state[[1]]))) - req(dir.exists(savedir_path)) - tryCatch({ - showNotification( - ui = "State is being saved.", - id = "save_state.ongoing", - duration = NA, - type = "warning" - ) - # but first we must remove some values which are not to be saved to ensure filesize is minimal: - # - DATA$last_im (which caches the last-loaded image of the 'render_selected_mask'-subroutine) - saved_state_path <- save_state( - input = input, - DATA = DATA, - DEBUGKEYS = DEBUGKEYS, - FLAGS = FLAGS, - volumes = getVolumes() - ) - removeNotification(id = "save_state.ongoing") - if (file.exists(saved_state_path)) { - showNotification( - ui = str_c("State successfully saved to '",saved_state_path,"'."), - id = "save_state.done", - duration = DATA$notification_duration * 4, - type = "message" - ) - } else { - showNotification( - ui = str_c("State was not successfully saved to '",saved_state_path,"'."), - id = "save_state.error", - duration = DATA$notification_duration * 4, - type = "error" - ) + if (isFALSE(is.na(DATA$folder_path))) { + r <- dirname(DATA$folder_path) + showNotification(str_c("searching from ",DATA$folder_path)) + if (isFALSE(hasName(volumes,"reprex_location"))) { + reprex_location = DATA$folder_path + reprex_root <- volumes[which(str_count(r,volumes)==1)] + reprex_path <- fs::path_rel(path = reprex_location,start = reprex_root) + if (isTRUE(as.logical(str_count(reprex_location,volumes[which(stringr::str_count(r,volumes)==1)])))) { + shinyFileSave( + input, + "save_state", + roots = volumes, + defaultRoot = names(reprex_root), + defaultPath = reprex_path, + session = getDefaultReactiveDomain(), + allowDirCreate = T + ) + } else { + shinyFileSave( + input, + "save_state", + roots = volumes, + session = getDefaultReactiveDomain(), + allowDirCreate = T + ) + } } + } else { + shinyFileSave( + input, + "save_state", + roots = volumes, + session = getDefaultReactiveDomain(), + allowDirCreate = T + ) + } + tryCatch({ }, error = function(e) { DATA$stacktrace = traceback(1, 1) error_state_path <- save_error_state( @@ -1485,12 +1480,69 @@ duflor_gui <- function() { erroneous_callback = "save_state" ) showNotification( - ui = str_c("Error occured while saving state (during callback 'input$save_state'). The configuration which triggered this error was stored to '",error_state_path,"'."), + ui = str_c("Error occured during callback 'input$save_state'. The configuration which triggered this error was stored to '",error_state_path,"'."), id = "error_state_generated.done", duration = NULL, type = "error" ) }) + if (isFALSE(is.numeric(input$save_state[[1]]))) { + savedir_path <- parseDirPath(roots = volumes, selection = input$save_state) + + if (isTRUE(dir.exists(savedir_path))) { + tryCatch({ + showNotification( + ui = "State is being saved.", + id = "save_state.ongoing", + duration = NA, + type = "warning" + ) + # but first we must remove some values which are not to be saved to ensure filesize is minimal: + # - DATA$last_im (which caches the last-loaded image of the 'render_selected_mask'-subroutine) + saved_state_path <- save_state( + input = input, + DATA = DATA, + DEBUGKEYS = DEBUGKEYS, + FLAGS = FLAGS, + volumes = volumes + ) + removeNotification(id = "save_state.ongoing") + if (file.exists(saved_state_path)) { + showNotification( + ui = str_c("State successfully saved to '",saved_state_path,"'."), + id = "save_state.done", + duration = DATA$notification_duration * 4, + type = "message" + ) + } else { + showNotification( + ui = str_c("State was not successfully saved to '",saved_state_path,"'."), + id = "save_state.error", + duration = DATA$notification_duration * 4, + type = "error" + ) + } + }, error = function(e) { + DATA$stacktrace = traceback(1, 1) + error_state_path <- save_error_state( + input = input_mirror, + DATA = DATA, + DEBUGKEYS = DEBUGKEYS, + FLAGS = FLAGS, + volumes = getVolumes(), + error = e, + errordir_path = DATA$folder_path, + erroneous_callback = "save_state" + ) + showNotification( + ui = str_c("Error occured while saving state (during callback 'input$save_state'). The configuration which triggered this error was stored to '",error_state_path,"'."), + id = "error_state_generated.done", + duration = NULL, + type = "error" + ) + }) + } + } }) } #### LAUNCH APP #### From 2bcc2be9ef32fb12f4a65de866065308c3649ad7 Mon Sep 17 00:00:00 2001 From: Claudius Appel <151634114+Claudius-Appel@users.noreply.github.com> Date: Fri, 6 Dec 2024 14:56:37 +0100 Subject: [PATCH 2/6] `duflor_gui()`: cb's `input$folder`: fix buggy construction of `DATA$folder_path` and updating of `image_files_()` caused by shiny-dir shenanigans --- R/app.R | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/R/app.R b/R/app.R index b556cf0..a706490 100644 --- a/R/app.R +++ b/R/app.R @@ -406,10 +406,6 @@ duflor_gui <- function() { } else { shinyDirChoose(input = input, 'folder', roots=volumes) } - folder_path <- parseDirPath(roots = volumes,input$folder) # this is how you conver thte shinydirselection-objet to a valid path. cf: https://search.r-project.org/CRAN/refmans/shinyFiles/html/shinyFiles-parsers.html - req(dir.exists(folder_path)) - DATA$folder_path <- folder_path - image_files_() }, error = function(e) { DATA$stacktrace = traceback(1, 1) error_state_path <- save_error_state( @@ -423,12 +419,19 @@ duflor_gui <- function() { erroneous_callback = "folder" ) showNotification( - ui = str_c("Error occured during callback 'input$folder'. The configuration which triggered this error was stored to '",error_state_path,"'."), + ui = str_c("Error occured during callback 'input$folder' (1). The configuration which triggered this error was stored to '",error_state_path,"'."), id = "error_state_generated.done", duration = NULL, type = "error" ) }) + folder_path <- parseDirPath(roots = volumes,input$folder) # this is how you conver thte shinydirselection-objet to a valid path. cf: https://search.r-project.org/CRAN/refmans/shinyFiles/html/shinyFiles-parsers.html + if (length(folder_path)>0) { + if (dir.exists(folder_path)) { + DATA$folder_path <- folder_path + image_files_() + } + } }) #### REACTIVE - RESULTS_TABLE, FILTERED BY SPECTRUM #### filtered_results <- reactive({ From 89e72c504cdf2419cb8a18e645261d1aa6f062a1 Mon Sep 17 00:00:00 2001 From: Claudius Appel <151634114+Claudius-Appel@users.noreply.github.com> Date: Mon, 9 Dec 2024 15:25:33 +0100 Subject: [PATCH 3/6] `select_spectra_gui_comp()`: also implement restoration of the selected mask-checkboxes (save/save_highcontrast) for proper reprex --- R/app.R | 6 +++++- R/restore_state.R | 12 +++++++++++- R/select_spectra_gui_comp.R | 16 ++++++++++++++-- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/R/app.R b/R/app.R index a706490..d5743e8 100644 --- a/R/app.R +++ b/R/app.R @@ -234,7 +234,9 @@ duflor_gui <- function() { last_im = NA, folder_path = NA, search_root = NA, - selected_spectra = NA + selected_spectra = NA, + do_save_masks = NA, + do_save_high_contrast_masks = NA ) DEBUGKEYS <- reactiveValues( # if you want to have functionality blocked by the dev-console, add @@ -1392,6 +1394,8 @@ duflor_gui <- function() { DATA$spectrums <- state_unpack$spectrums DATA$folder_path <- state_unpack$loaded_path DATA$selected_spectra <- state_unpack$selected_spectra + DATA$do_save_masks <- state_unpack$do_save_masks + DATA$do_save_high_contrast_masks <- state_unpack$do_save_high_contrast_masks # once the loaded-path was updated, recompute the input-table image_files_() removeNotification(id = "restore_state.ongoing") diff --git a/R/restore_state.R b/R/restore_state.R index 423e303..a3994c7 100644 --- a/R/restore_state.R +++ b/R/restore_state.R @@ -36,6 +36,8 @@ restore_state <- function(input, output, DATA, FLAGS, DEBUGKEYS, session, volume } DATA$spectrums <- DATA_spectr selected_spectra <- input_state$input$selected_spectra + do_save_high_contrast_masks <- input_state$input$do_save_high_contrast_masks + do_save_masks <- input_state$input$do_save_masks DATA$r__tbl_dir_files <- input_state$DATA$r__tbl_dir_files DEBUGKEYS <- input_state$DEBUGKEYS FLAGS <- input_state$FLAGS @@ -185,5 +187,13 @@ restore_state <- function(input, output, DATA, FLAGS, DEBUGKEYS, session, volume value = input_state$input$identifier_area ) } - return(list(loaded_path=loaded_path,spectrums=DATA$spectrums,selected_spectra = selected_spectra)) + return( + list( + loaded_path = loaded_path, + spectrums = DATA$spectrums, + selected_spectra = selected_spectra, + do_save_masks = do_save_masks, + do_save_high_contrast_masks = do_save_high_contrast_masks + ) + ) } diff --git a/R/select_spectra_gui_comp.R b/R/select_spectra_gui_comp.R index ebebd9f..10ce423 100644 --- a/R/select_spectra_gui_comp.R +++ b/R/select_spectra_gui_comp.R @@ -27,13 +27,25 @@ select_spectra_gui_comp <- function(input, DATA, FLAGS) { all_choices <- unique(all_choices,DATA$selected_spectra) # DATA$selected_spectra <- NA # and finally, purge the field again so that the state is uniform } + do_save_masks_ <- FALSE + do_save_high_contrast_masks_ <- FALSE + if (isFALSE(is.na(DATA$do_save_masks))) { + if (isTRUE(as.logical(DATA$do_save_masks))) { + do_save_masks_ <- ifelse(isTRUE(as.logical(DATA$do_save_masks)),T,F) + if (isFALSE(is.na(DATA$do_save_high_contrast_masks))) { + if (isTRUE(as.logical(DATA$do_save_high_contrast_masks))) { + do_save_high_contrast_masks_ <- ifelse(isTRUE(as.logical(DATA$do_save_masks)),T,F) + } + } + } + } showModal(modalDialog( tags$h3('Choose which ranges to analyse'), # tags$h5('As a result, all images will be processed at full resolution. This is safer, but slower.'), footer=tagList( checkboxGroupInput("selected_spectra","Select spectra to analyse",choices = all_choices,selected = choices), - checkboxInput("do_save_masks","Save the spectrum-masks?"), - checkboxInput("do_save_high_contrast_masks","Save the high-contrast-masks instead?"), + checkboxInput("do_save_masks","Save the spectrum-masks?",value = do_save_masks_), + checkboxInput("do_save_high_contrast_masks","Save the high-contrast-masks instead?",value = do_save_high_contrast_masks_), actionButton('submit_selected_spectra', 'Submit choices'), modalButton('cancel') ) From c6c8125c9b1ea3e1d1d91395db3bdfb94d19ebac Mon Sep 17 00:00:00 2001 From: Claudius Appel <151634114+Claudius-Appel@users.noreply.github.com> Date: Mon, 9 Dec 2024 15:36:36 +0100 Subject: [PATCH 4/6] version bump, closes #92 --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 181ad16..3cbf98b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: duflor.gui Title: Frontend for duflor-package -Version: 1.0.11 +Version: 1.0.12 Author: Claudius Appel Authors@R: c( person("Claudius", "Appel", email = "claudius.appel@freenet.de" , role = c("aut", "cre")) From cd7aaa62f3ee01f25889bd3a090a709bbbf5e2c2 Mon Sep 17 00:00:00 2001 From: Claudius Appel <151634114+Claudius-Appel@users.noreply.github.com> Date: Mon, 9 Dec 2024 15:48:06 +0100 Subject: [PATCH 5/6] chore: update pkgdown site --- docs/404.html | 2 +- docs/LICENSE-text.html | 2 +- docs/LICENSE.html | 2 +- docs/articles/general-user-manual.html | 2 +- docs/articles/identifier-cropping.html | 2 +- docs/articles/image-cropping.html | 2 +- docs/articles/index.html | 2 +- docs/articles/modifying-hsv-bounds.html | 2 +- docs/articles/optimising-speed.html | 2 +- docs/articles/parallelisation.html | 2 +- docs/articles/raising-issues.html | 2 +- docs/articles/saving-and-restoring-application-states.html | 2 +- docs/authors.html | 6 +++--- docs/index.html | 2 +- docs/pkgdown.yml | 2 +- docs/reference/convert_pixels_to_area_gui.html | 2 +- docs/reference/correct_distortion.html | 2 +- docs/reference/dev_key_handler.html | 2 +- docs/reference/dot-main_args.html | 2 +- docs/reference/duflor_gui.html | 2 +- docs/reference/execute_analysis.html | 2 +- docs/reference/execute_multiple.html | 2 +- docs/reference/execute_single.html | 2 +- docs/reference/get_KPI_plot.html | 2 +- docs/reference/get_group.html | 2 +- docs/reference/get_image_dimensions.html | 2 +- docs/reference/index.html | 2 +- docs/reference/key_handle_cores.html | 2 +- docs/reference/limit_identifier_coordinates.html | 2 +- docs/reference/limit_to_range.html | 2 +- docs/reference/open_parallelPanel_event.html | 2 +- docs/reference/prepare_resultsObject.html | 2 +- docs/reference/render_selected_mask.html | 2 +- docs/reference/restore_state.html | 2 +- docs/reference/save_error_state.html | 2 +- docs/reference/save_state.html | 2 +- docs/reference/select_spectra_gui_comp.html | 2 +- docs/reference/setup_parallel.html | 2 +- .../show_infringing_spectrum_elements_gui_comp.html | 2 +- docs/reference/shutdown_parallel.html | 2 +- docs/reference/store_KPI_plot_to_file.html | 2 +- docs/reference/store_results_to_file.html | 2 +- docs/reference/update_resultsObject.html | 2 +- docs/reference/validate_custom_HSV_values.html | 2 +- docs/search.json | 2 +- 45 files changed, 47 insertions(+), 47 deletions(-) diff --git a/docs/404.html b/docs/404.html index 5124416..76402ea 100644 --- a/docs/404.html +++ b/docs/404.html @@ -20,7 +20,7 @@ duflor.gui - 1.0.11 + 1.0.12