|
rm(list=ls()) |
|
|
|
|
|
library(shiny) |
|
|
|
|
|
source("./script.R") |
|
|
|
|
|
orderInputPanel <- function() { |
|
conditionalPanel( |
|
condition = "output.showOrderInput", |
|
numericInput("target_order", "Target Order:", value = 1, min = 1), |
|
actionButton("confirm_order", "Confirm Order"), |
|
actionButton("cancel_order", "Cancel") |
|
) |
|
} |
|
|
|
|
|
sort_captions_by_search <- function(data, search_term) { |
|
if (is.null(search_term) || search_term == "") { |
|
return(data) |
|
} |
|
|
|
|
|
scores <- as.integer(grepl(search_term, data$caption, ignore.case = TRUE)) |
|
|
|
|
|
return(data[order(-scores), ]) |
|
} |
|
|
|
|
|
ui <- fluidPage( |
|
|
|
titlePanel("SDtagEditoR"), |
|
|
|
|
|
tags$style(type = "text/css", |
|
"#image_captions { white-space: pre-wrap; }", |
|
".shiny-action-button { margin-bottom: 50px; }" |
|
), |
|
|
|
|
|
tags$head(tags$script(HTML(" |
|
function copyToClipboard(text) { |
|
var dummy = document.createElement('textarea'); |
|
document.body.appendChild(dummy); |
|
dummy.value = text; |
|
dummy.select(); |
|
document.execCommand('copy'); |
|
document.body.removeChild(dummy); |
|
} |
|
"))), |
|
|
|
tags$script(HTML(" |
|
function handleCaptionClick(caption, source) { |
|
var operationModeElement = document.getElementById('operation_mode_UI'); |
|
if (source === 'remove_RDB') { |
|
Shiny.setInputValue('remove_relation_index', caption, {priority: 'event'}); |
|
} else if (operationModeElement && operationModeElement.innerText === 'direct remove') { |
|
if (source === 'frequency') { |
|
Shiny.setInputValue('clicked_caption_frequency', caption, {priority: 'event'}); |
|
} else { |
|
Shiny.setInputValue('clicked_caption', caption, {priority: 'event'}); |
|
} |
|
} else if (operationModeElement && operationModeElement.innerText === 'Database Making') { |
|
Shiny.setInputValue('clicked_caption_RDB', caption, {priority: 'event'}); |
|
} else { |
|
copyToClipboard(caption); |
|
} |
|
} |
|
")), |
|
|
|
|
|
|
|
sidebarLayout( |
|
sidebarPanel( |
|
width = 3, |
|
uiOutput("operation_mode_UI"), |
|
|
|
|
|
textInput("directory_path", "Enter the directory path:", value = ""), |
|
|
|
|
|
actionButton("load_data", "Load Captions Data"), |
|
tags$br(), |
|
tags$br(), |
|
|
|
conditionalPanel( |
|
condition = "output.dataLoaded", |
|
|
|
|
|
selectInput("selected_image", "Choose an image:", choices = NULL), |
|
|
|
|
|
actionButton("prev_image", "Prev"), |
|
actionButton("next_image", "Next"), |
|
tags$br(), |
|
tags$br(), |
|
|
|
|
|
actionButton("direct_remover", "Enter Direct Remover Mode"), |
|
conditionalPanel( |
|
condition = "output.operation_mode_UI === 'direct remove'", |
|
actionButton("exit_direct_remover", "Exit Direct Remover") |
|
), |
|
tags$br(), |
|
tags$br(), |
|
|
|
|
|
actionButton("enter_database_mode", "Enter Database Making Mode"), |
|
conditionalPanel( |
|
condition = "output.operation_mode_UI === 'Database Making'", |
|
actionButton("exit_database_mode", "Exit Database Making Mode"), |
|
tags$br(), |
|
tags$br(), |
|
textInput("parent_caption_input", "Parent Caption:"), |
|
textInput("child_caption_input", "Child Caption:"), |
|
actionButton("add_to_RDB", "Add to Database"), |
|
actionButton("clear_inputs_RDB", "Clear"), |
|
tags$br(), |
|
tags$br(), |
|
fileInput("load_relation_database", "Load Relation DB", accept = ".csv"), |
|
downloadButton("save_relation_database", "Save Relation DB"), |
|
tags$br(), |
|
tags$br(), |
|
actionButton("aggregate_single", "Aggregation Single"), |
|
actionButton("aggregate_all", "Aggregation All") |
|
), |
|
tags$br(), |
|
tags$br(), |
|
|
|
conditionalPanel( |
|
condition = "output.operation_mode_UI !== 'direct remove' && output.operation_mode_UI !== 'Database Making'", |
|
actionButton("shuffle_single", "Shuffle Single"), |
|
actionButton("shuffle_all", "Shuffle All"), |
|
tags$br(), |
|
tags$br(), |
|
numericInput("frequency_threshold", "Frequency Threshold:", value = 5, min = 1), |
|
actionButton("remove_low_freq", "Remove Low Frequency Captions"), |
|
tags$br(), |
|
tags$br(), |
|
textInput("edit_caption", "Caption to Edit:", ""), |
|
actionButton("remove_single", "Remove Single"), |
|
actionButton("remove_from_all", "Remove All"), |
|
|
|
tags$br(), |
|
actionButton("add_single", "Add Single"), |
|
actionButton("add_to_all", "Add All"), |
|
tags$br(), |
|
actionButton("move_caption", "Move Single"), |
|
actionButton("move_caption_all", "Move All"), |
|
tags$br(), |
|
|
|
|
|
orderInputPanel(), |
|
|
|
tags$br(), |
|
), |
|
tags$br(), |
|
tags$br(), |
|
actionButton("restore_captions", "Restore captions"), |
|
tags$br(), |
|
actionButton("output_captions", "Output Edited Captions") |
|
) |
|
), |
|
|
|
mainPanel( |
|
fluidRow( |
|
column(6, |
|
imageOutput("image_display", width = "100%", height = "50%"), |
|
tags$br(), |
|
uiOutput("image_captions") |
|
), |
|
column(6, |
|
verbatimTextOutput("log_output"), |
|
textInput("search_caption", "Search Caption:", ""), |
|
actionButton("search_button", "Search"), |
|
actionButton("clear_search", "Clear"), |
|
tags$br(), |
|
tags$br(), |
|
fluidRow( |
|
column(4, tableOutput("selected_image_captions")), |
|
column(4, tableOutput("caption_frequency_table_with_links")), |
|
column(4, tableOutput("relation_database_display")) |
|
) |
|
) |
|
) |
|
) |
|
) |
|
) |
|
|
|
|
|
|
|
server <- function(input, output, session) { |
|
|
|
directory_path <- reactiveVal() |
|
captions_data <- reactiveVal() |
|
caption_frequency <- reactiveVal() |
|
operation_mode <- reactiveVal("Normal") |
|
log_text <- reactiveVal("Log:\n") |
|
|
|
|
|
|
|
add_log <- function(message) { |
|
current_log <- log_text() |
|
new_log <- paste(current_log, message, "\n") |
|
log_text(new_log) |
|
} |
|
|
|
|
|
update_log <- function(message) { |
|
log_text(message) |
|
} |
|
|
|
|
|
|
|
output$dataLoaded <- reactive({ |
|
!is.null(captions_data()) |
|
}) |
|
outputOptions(output, "dataLoaded", suspendWhenHidden=FALSE) |
|
|
|
|
|
output$operation_mode_UI <- renderText({ |
|
return(operation_mode()) |
|
}) |
|
outputOptions(output, "operation_mode_UI", suspendWhenHidden=FALSE) |
|
|
|
|
|
|
|
temp_captions_data <- reactiveVal() |
|
|
|
|
|
observeEvent(input$selected_image, { |
|
temp_captions_data(captions_data()) |
|
}, ignoreNULL = TRUE) |
|
|
|
|
|
searched_caption <- reactiveVal(NULL) |
|
|
|
observeEvent(input$search_button, { |
|
searched_caption(input$search_caption) |
|
}) |
|
|
|
observeEvent(input$clear_search, { |
|
searched_caption(NULL) |
|
updateTextInput(session, "search_caption", value = "") |
|
}) |
|
|
|
|
|
observeEvent(input$load_data, { |
|
|
|
|
|
temp_directory_path <- isolate(input$directory_path) |
|
temp_captions_data <- read_captions_from_directory(temp_directory_path) |
|
|
|
|
|
if (is.null(temp_captions_data)) { |
|
showNotification("Error in read_captions_from_directory: No .txt files found in the specified directory.", type = "error") |
|
return() |
|
} |
|
|
|
temp_caption_frequency <- get_caption_frequency(temp_captions_data) |
|
|
|
|
|
directory_path(temp_directory_path) |
|
captions_data(temp_captions_data) |
|
caption_frequency(temp_caption_frequency) |
|
|
|
|
|
unique_images <- unique(captions_data()$image_path) |
|
updateSelectInput(session, "selected_image", choices = unique_images, selected = unique_images[1]) |
|
|
|
update_log("Captions data loaded.") |
|
}) |
|
|
|
|
|
observeEvent(input$prev_image, { |
|
current_index <- which(unique(captions_data()$image_path) == input$selected_image) |
|
if (current_index > 1) { |
|
updateSelectInput(session, "selected_image", selected = unique(captions_data()$image_path)[current_index - 1]) |
|
} |
|
}) |
|
|
|
observeEvent(input$next_image, { |
|
current_index <- which(unique(captions_data()$image_path) == input$selected_image) |
|
if (current_index < length(unique(captions_data()$image_path))) { |
|
updateSelectInput(session, "selected_image", selected = unique(captions_data()$image_path)[current_index + 1]) |
|
} |
|
}) |
|
|
|
|
|
observeEvent(input$direct_remover, { |
|
operation_mode("direct remove") |
|
update_log("DIRECT REMOVER MODE.") |
|
}) |
|
|
|
observeEvent(input$exit_direct_remover, { |
|
operation_mode("Normal") |
|
update_log("Exited Direct Remover mode.") |
|
}) |
|
|
|
|
|
relation_database <- reactiveVal(data.frame(parent_caption = character(0), child_caption = character(0), stringsAsFactors = FALSE)) |
|
|
|
observeEvent(input$enter_database_mode, { |
|
operation_mode("Database Making") |
|
update_log("DATABASE MAKING MODE.") |
|
}) |
|
|
|
observeEvent(input$exit_database_mode, { |
|
operation_mode("Normal") |
|
update_log("Exited Database Making mode.") |
|
}) |
|
|
|
observeEvent(input$clicked_caption_RDB, { |
|
if (input$parent_caption_input == "") { |
|
updateTextInput(session, "parent_caption_input", value = input$clicked_caption_RDB) |
|
} else { |
|
updateTextInput(session, "child_caption_input", value = input$clicked_caption_RDB) |
|
} |
|
}) |
|
|
|
observeEvent(input$add_to_RDB, { |
|
|
|
if (input$parent_caption_input == "" || input$child_caption_input == "" || input$parent_caption_input == input$child_caption_input) { |
|
showNotification("Error: Invalid parent or child caption.", type = "error") |
|
return() |
|
} |
|
|
|
|
|
existing_relation <- with(relation_database(), parent_caption == input$parent_caption_input & |
|
child_caption == input$child_caption_input) |
|
if (any(existing_relation)) { |
|
showNotification("Error: This relation already exists in the database.", type = "error") |
|
return() |
|
} |
|
|
|
|
|
new_relation <- data.frame(parent_caption = input$parent_caption_input, |
|
child_caption = input$child_caption_input) |
|
updated_database <- rbind(relation_database(), new_relation) |
|
relation_database(updated_database) |
|
update_log("Relation added to database.") |
|
}) |
|
|
|
observeEvent(input$clear_inputs_RDB, { |
|
updateTextInput(session, "parent_caption_input", value = "") |
|
updateTextInput(session, "child_caption_input", value = "") |
|
}) |
|
|
|
observeEvent(input$aggregate_single, { |
|
updated_data <- captions_data() |
|
|
|
captions_for_selected_image <- updated_data$caption[updated_data$image_path == input$selected_image] |
|
|
|
if (nrow(relation_database()) > 0) { |
|
for (i in 1:nrow(relation_database())) { |
|
parent <- relation_database()$parent_caption[i] |
|
child <- relation_database()$child_caption[i] |
|
|
|
|
|
if (parent %in% captions_for_selected_image) { |
|
updated_data <- remove_caption_and_adjust_order(updated_data, input$selected_image, child) |
|
} |
|
} |
|
} |
|
|
|
captions_data(updated_data) |
|
|
|
|
|
updated_caption_frequency <- get_caption_frequency(captions_data()) |
|
caption_frequency(updated_caption_frequency) |
|
|
|
update_log("Captions aggregated for this image.") |
|
}) |
|
|
|
observeEvent(input$aggregate_all, { |
|
updated_data <- captions_data() |
|
|
|
if (nrow(relation_database()) > 0) { |
|
for (image_path in unique(updated_data$image_path)) { |
|
|
|
captions_for_image <- updated_data$caption[updated_data$image_path == image_path] |
|
|
|
for (i in 1:nrow(relation_database())) { |
|
parent <- relation_database()$parent_caption[i] |
|
child <- relation_database()$child_caption[i] |
|
|
|
|
|
if (parent %in% captions_for_image) { |
|
updated_data <- remove_caption_and_adjust_order(updated_data, image_path, child) |
|
} |
|
} |
|
} |
|
} |
|
|
|
captions_data(updated_data) |
|
|
|
|
|
updated_caption_frequency <- get_caption_frequency(captions_data()) |
|
caption_frequency(updated_caption_frequency) |
|
|
|
update_log("Captions aggregated for all images.") |
|
}) |
|
|
|
observeEvent(input$remove_relation_index, { |
|
index_to_remove <- as.numeric(input$remove_relation_index) |
|
|
|
|
|
parent_to_remove <- relation_database()$parent_caption[index_to_remove] |
|
child_to_remove <- relation_database()$child_caption[index_to_remove] |
|
|
|
|
|
relation_database(relation_database()[-index_to_remove, ]) |
|
|
|
|
|
update_log(paste("Removed relation:", parent_to_remove, "->", child_to_remove)) |
|
}) |
|
|
|
|
|
output$save_relation_database <- downloadHandler( |
|
filename = function() { |
|
paste("relation_database_", Sys.Date(), ".csv", sep="") |
|
}, |
|
content = function(file) { |
|
write.csv(relation_database(), file, row.names = FALSE) |
|
}, |
|
contentType = "text/csv" |
|
) |
|
|
|
observeEvent(input$load_relation_database, { |
|
|
|
if (!is.null(input$load_relation_database$datapath)) { |
|
|
|
new_data <- read.csv(input$load_relation_database$datapath, stringsAsFactors = FALSE) |
|
|
|
|
|
if (!all(c("parent_caption", "child_caption") %in% names(new_data))) { |
|
showNotification("Error: The file does not have the required columns (parent_caption and child_caption).", type = "error") |
|
return() |
|
} |
|
|
|
if (any(is.na(new_data$parent_caption)) || any(is.na(new_data$child_caption))) { |
|
showNotification("Error: The file contains missing values in parent_caption or child_caption.", type = "error") |
|
return() |
|
} |
|
|
|
if (any(nchar(new_data$parent_caption) == 0) || any(nchar(new_data$child_caption) == 0)) { |
|
showNotification("Error: The file contains empty strings in parent_caption or child_caption.", type = "error") |
|
return() |
|
} |
|
|
|
|
|
relation_database(new_data) |
|
update_log("Relation database loaded.") |
|
} |
|
}) |
|
|
|
|
|
observeEvent(input$shuffle_single, { |
|
if (operation_mode() != "Normal") { |
|
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error") |
|
return() |
|
} |
|
|
|
current_image <- input$selected_image |
|
updated_data <- captions_data() |
|
captions_for_current_image <- filter(updated_data, image_path == current_image) |
|
|
|
|
|
new_order <- sample(1:nrow(captions_for_current_image), nrow(captions_for_current_image)) |
|
captions_for_current_image$caption_order <- new_order |
|
|
|
|
|
updated_data[updated_data$image_path == current_image, ] <- captions_for_current_image |
|
captions_data(updated_data) |
|
|
|
update_log("captions of this image was shauffled.") |
|
}) |
|
|
|
|
|
observeEvent(input$shuffle_all, { |
|
if (operation_mode() != "Normal") { |
|
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error") |
|
return() |
|
} |
|
|
|
updated_data <- captions_data() |
|
unique_images <- unique(updated_data$image_path) |
|
|
|
for (image in unique_images) { |
|
captions_for_image <- filter(updated_data, image_path == image) |
|
new_order <- sample(1:nrow(captions_for_image), nrow(captions_for_image)) |
|
captions_for_image$caption_order <- new_order |
|
updated_data[updated_data$image_path == image, ] <- captions_for_image |
|
} |
|
|
|
captions_data(updated_data) |
|
update_log("captions of all images was shauffled.") |
|
}) |
|
|
|
|
|
observeEvent(input$remove_low_freq, { |
|
if (operation_mode() != "Normal") { |
|
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error") |
|
return() |
|
} |
|
|
|
if (!is.null(captions_data())) { |
|
threshold <- input$frequency_threshold |
|
updated_data <- remove_low_frequency_captions(captions_data(), threshold) |
|
captions_data(updated_data) |
|
|
|
|
|
updated_caption_frequency <- get_caption_frequency(captions_data()) |
|
caption_frequency(updated_caption_frequency) |
|
} |
|
|
|
update_log("Low frequency captions removed.") |
|
}) |
|
|
|
|
|
observeEvent(input$remove_from_all, { |
|
if (operation_mode() != "Normal") { |
|
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error") |
|
return() |
|
} |
|
|
|
|
|
target_caption <- input$edit_caption |
|
updated_data <- captions_data() |
|
unique_images <- unique(updated_data$image_path[updated_data$caption == target_caption]) |
|
for (image in unique_images) { |
|
updated_data <- remove_caption_and_adjust_order(updated_data, image, target_caption) |
|
} |
|
captions_data(updated_data) |
|
|
|
|
|
updated_caption_frequency <- get_caption_frequency(captions_data()) |
|
caption_frequency(updated_caption_frequency) |
|
|
|
update_log("Caption removed from all images.") |
|
}) |
|
|
|
|
|
showOrderInput <- reactiveVal(FALSE) |
|
showTextInput <- reactiveVal(FALSE) |
|
|
|
observeEvent(input$remove_single, { |
|
if (operation_mode() != "Normal") { |
|
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error") |
|
return() |
|
} |
|
target_caption <- input$edit_caption |
|
if (target_caption %in% captions_data()$caption[captions_data()$image_path == input$selected_image]) { |
|
updated_data <- remove_caption_and_adjust_order(captions_data(), input$selected_image, target_caption) |
|
captions_data(updated_data) |
|
update_log("Caption removed from this image.") |
|
} else { |
|
showNotification("Error: Caption not found in the selected image.", type = "error") |
|
} |
|
}) |
|
|
|
observeEvent(input$add_single, { |
|
if (operation_mode() != "Normal") { |
|
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error") |
|
return() |
|
} |
|
operation_mode("add_single") |
|
showOrderInput(TRUE) |
|
update_log("ADD SINGLE MODE.") |
|
}) |
|
|
|
observeEvent(input$add_to_all, { |
|
if (operation_mode() != "Normal") { |
|
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error") |
|
return() |
|
} |
|
operation_mode("add_all") |
|
showOrderInput(TRUE) |
|
update_log("ADD ALL MODE.") |
|
}) |
|
|
|
observeEvent(input$move_caption, { |
|
if (operation_mode() != "Normal") { |
|
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error") |
|
return() |
|
} |
|
target_caption <- input$edit_caption |
|
if (target_caption %in% captions_data()$caption[captions_data()$image_path == input$selected_image]) { |
|
operation_mode("move_caption") |
|
showOrderInput(TRUE) |
|
update_log("MOVE CAPTION SINGLE MODE.") |
|
} else { |
|
showNotification("Error: Caption not found in the selected image.", type = "error") |
|
} |
|
}) |
|
|
|
observeEvent(input$move_caption_all, { |
|
if (operation_mode() != "Normal") { |
|
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error") |
|
return() |
|
} |
|
operation_mode("move_caption_all") |
|
showOrderInput(TRUE) |
|
update_log("MOVE CAPTION ALL MODE.") |
|
}) |
|
|
|
observeEvent(input$confirm_order, { |
|
switch(operation_mode(), |
|
"add_single" = { |
|
|
|
target_caption <- input$edit_caption |
|
target_order <- max(1, floor(input$target_order)) |
|
updated_data <- add_caption_at_order(captions_data(), input$selected_image, target_caption, target_order) |
|
captions_data(updated_data) |
|
update_log("Caption added to target order.") |
|
}, |
|
"add_all" = { |
|
target_caption <- input$edit_caption |
|
target_order <- target_order <- max(1, floor(input$target_order)) |
|
updated_data <- captions_data() |
|
unique_images <- unique(updated_data$image_path) |
|
for (image in unique_images) { |
|
updated_data <- add_caption_at_order(updated_data, image, target_caption, target_order) |
|
} |
|
captions_data(updated_data) |
|
update_log("Caption added to all images.") |
|
}, |
|
"move_caption" = { |
|
|
|
target_caption <- input$edit_caption |
|
target_order <- target_order <- max(1, floor(input$target_order)) |
|
updated_data <- move_caption_order(captions_data(), input$selected_image, target_caption, target_order) |
|
captions_data(updated_data) |
|
update_log("Caption moved to target order.") |
|
}, |
|
"move_caption_all" = { |
|
|
|
target_caption <- input$edit_caption |
|
target_order <- target_order <- max(1, floor(input$target_order)) |
|
updated_data <- captions_data() |
|
unique_images <- unique(updated_data$image_path[updated_data$caption == target_caption]) |
|
for (image in unique_images) { |
|
updated_data <- move_caption_order(updated_data, image, target_caption, target_order) |
|
} |
|
captions_data(updated_data) |
|
update_log("Caption moved to target order from all images.") |
|
} |
|
) |
|
|
|
|
|
updated_caption_frequency <- get_caption_frequency(captions_data()) |
|
caption_frequency(updated_caption_frequency) |
|
operation_mode("Normal") |
|
showOrderInput(FALSE) |
|
}) |
|
|
|
observeEvent(input$cancel_order, { |
|
operation_mode("Normal") |
|
showOrderInput(FALSE) |
|
update_log("Operation was canceled.") |
|
}) |
|
|
|
observeEvent(input$cancel_text, { |
|
operation_mode("Normal") |
|
showTextInput(FALSE) |
|
update_log("Operation was canceled.") |
|
}) |
|
|
|
output$showOrderInput <- reactive({ |
|
showOrderInput() |
|
}) |
|
|
|
outputOptions(output, "showOrderInput", suspendWhenHidden=FALSE) |
|
|
|
output$showTextInput <- reactive({ |
|
showTextInput() |
|
}) |
|
|
|
outputOptions(output, "showTextInput", suspendWhenHidden=FALSE) |
|
|
|
|
|
observeEvent(input$clicked_caption, { |
|
target_caption <- input$clicked_caption |
|
|
|
|
|
updated_data <- remove_caption_and_adjust_order(captions_data(), input$selected_image, target_caption) |
|
captions_data(updated_data) |
|
|
|
|
|
updated_caption_frequency <- get_caption_frequency(captions_data()) |
|
caption_frequency(updated_caption_frequency) |
|
|
|
update_log("Caption removed from this image.") |
|
}) |
|
|
|
observeEvent(input$clicked_caption_frequency, { |
|
target_caption <- input$clicked_caption_frequency |
|
|
|
|
|
updated_data <- captions_data() |
|
unique_images <- unique(updated_data$image_path[updated_data$caption == target_caption]) |
|
for (image in unique_images) { |
|
updated_data <- remove_caption_and_adjust_order(updated_data, image, target_caption) |
|
} |
|
captions_data(updated_data) |
|
|
|
|
|
updated_caption_frequency <- get_caption_frequency(captions_data()) |
|
caption_frequency(updated_caption_frequency) |
|
|
|
update_log("Caption removed from all images.") |
|
}) |
|
|
|
|
|
show_confirmation_dialog <- function() { |
|
showModal( |
|
modalDialog( |
|
title = "Confirmation", |
|
"Are you sure?", |
|
footer = tagList( |
|
modalButton("No"), |
|
actionButton("yes_button", "Yes") |
|
) |
|
) |
|
) |
|
} |
|
|
|
|
|
user_choice <- reactiveVal(NULL) |
|
|
|
|
|
observeEvent(input$yes_button, { |
|
user_choice("Yes") |
|
removeModal() |
|
}) |
|
|
|
|
|
observeEvent(input$restore_captions, { |
|
show_confirmation_dialog() |
|
observeEvent(user_choice(), { |
|
if (user_choice() == "Yes") { |
|
captions_data(temp_captions_data()) |
|
|
|
updated_caption_frequency <- get_caption_frequency(captions_data()) |
|
caption_frequency(updated_caption_frequency) |
|
} |
|
|
|
user_choice(NULL) |
|
}, ignoreNULL = TRUE) |
|
}) |
|
|
|
|
|
observeEvent(input$output_captions, { |
|
show_confirmation_dialog() |
|
|
|
observeEvent(user_choice(), { |
|
if (user_choice() == "Yes") { |
|
|
|
|
|
if (!dir.exists("./output")) { |
|
dir.create("./output") |
|
} |
|
|
|
|
|
unique_images <- unique(captions_data()$image_path) |
|
for (image_path in unique_images) { |
|
|
|
image_name <- basename(image_path) |
|
output_filename <- paste0("./output/", tools::file_path_sans_ext(image_name), ".txt") |
|
|
|
|
|
csv_captions <- capture.output(print_image_captions_as_csv(captions_data(), image_path)) |
|
|
|
|
|
writeLines(csv_captions, con = output_filename) |
|
} |
|
|
|
|
|
update_log("Captions data written to ./output/ directory.") |
|
|
|
} |
|
|
|
user_choice(NULL) |
|
}, ignoreNULL = TRUE) |
|
}) |
|
|
|
|
|
output$image_display <- renderImage({ |
|
list(src = file.path(input$selected_image), alt = "Selected Image", width = "80%") |
|
}, deleteFile = FALSE) |
|
|
|
output$image_captions <- renderUI({ |
|
if (!is.null(captions_data())) { |
|
selected_image_path <- input$selected_image |
|
captions <- filter(captions_data(), image_path == selected_image_path) %>% |
|
arrange(caption_order) %>% |
|
pull(caption) |
|
|
|
|
|
linked_captions <- lapply(captions, function(caption) { |
|
if (!is.null(searched_caption()) && grepl(searched_caption(), caption)) { |
|
sprintf("<a href='javascript:void(0);' onclick='handleCaptionClick(\"%s\");' style='background-color: yellow;'>%s</a>", caption, caption) |
|
} else { |
|
sprintf("<a href='javascript:void(0);' onclick='handleCaptionClick(\"%s\");'>%s</a>", caption, caption) |
|
} |
|
}) |
|
|
|
HTML(paste(linked_captions, collapse = ", ")) |
|
} |
|
}) |
|
|
|
output$log_output <- renderText({ |
|
log_text() |
|
}) |
|
|
|
output$selected_image_captions <- renderTable({ |
|
if (!is.null(captions_data())) { |
|
selected_image_path <- input$selected_image |
|
selected_captions <- filter(captions_data(), image_path == selected_image_path) %>% |
|
select(caption, caption_order) %>% |
|
arrange(caption_order) |
|
|
|
|
|
sorted_captions <- sort_captions_by_search(selected_captions, searched_caption()) |
|
|
|
|
|
sorted_captions$caption <- sprintf("<a href='javascript:void(0);' onclick='handleCaptionClick(\"%s\", \"image\");'>%s</a>", sorted_captions$caption, sorted_captions$caption) |
|
|
|
return(sorted_captions) |
|
} |
|
}, sanitize.text.function = function(x) x) |
|
|
|
output$caption_frequency_table_with_links <- renderTable({ |
|
if (!is.null(caption_frequency())) { |
|
freq_data <- caption_frequency() |
|
|
|
|
|
sorted_freq_data <- sort_captions_by_search(freq_data, searched_caption()) |
|
|
|
|
|
sorted_freq_data$caption <- sprintf("<a href='javascript:void(0);' onclick='handleCaptionClick(\"%s\", \"frequency\");'>%s</a>", sorted_freq_data$caption, sorted_freq_data$caption) |
|
|
|
return(sorted_freq_data) |
|
} |
|
}, sanitize.text.function = function(x) x) |
|
|
|
output$relation_database_display <- renderTable({ |
|
db <- relation_database() |
|
|
|
|
|
if (nrow(db) > 0) { |
|
db$remove <- sprintf("<a href='javascript:void(0);' onclick='handleCaptionClick(\"%s\", \"remove_RDB\");'>Remove</a>", 1:nrow(db)) |
|
} |
|
|
|
db |
|
}, sanitize.text.function = function(x) x) |
|
|
|
} |
|
|
|
|
|
shinyApp(ui = ui, server = server) |
|
|
|
|