ver 1.2
Browse files
app.R
CHANGED
@@ -70,6 +70,8 @@ ui <- fluidPage(
|
|
70 |
} else {
|
71 |
Shiny.setInputValue('clicked_caption', caption, {priority: 'event'});
|
72 |
}
|
|
|
|
|
73 |
} else {
|
74 |
copyToClipboard(caption);
|
75 |
}
|
@@ -80,6 +82,7 @@ ui <- fluidPage(
|
|
80 |
# ユーザー入力を受け付ける部分
|
81 |
sidebarLayout(
|
82 |
sidebarPanel(
|
|
|
83 |
uiOutput("operation_mode_UI"),
|
84 |
|
85 |
# ディレクトリパスを入力するテキストボックス
|
@@ -102,7 +105,7 @@ ui <- fluidPage(
|
|
102 |
tags$br(),
|
103 |
tags$br(),
|
104 |
|
105 |
-
# Direct Remover
|
106 |
actionButton("direct_remover", "Direct Remover"),
|
107 |
conditionalPanel(
|
108 |
condition = "output.operation_mode_UI === 'direct remove'",
|
@@ -110,12 +113,32 @@ ui <- fluidPage(
|
|
110 |
),
|
111 |
tags$br(),
|
112 |
tags$br(),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
conditionalPanel(
|
114 |
-
condition = "output.operation_mode_UI !== 'direct remove'",
|
115 |
-
|
116 |
-
|
117 |
-
actionButton("shuffle_single", "Shuffle Order for Current Image"),
|
118 |
-
actionButton("shuffle_all", "Shuffle Order for All Images"),
|
119 |
tags$br(),
|
120 |
tags$br(),
|
121 |
numericInput("frequency_threshold", "Frequency Threshold:", value = 5, min = 1),
|
@@ -123,18 +146,18 @@ ui <- fluidPage(
|
|
123 |
tags$br(),
|
124 |
tags$br(),
|
125 |
textInput("edit_caption", "Caption to Edit:", ""),
|
126 |
-
actionButton("remove_single", "Remove
|
127 |
-
actionButton("remove_from_all", "Remove
|
128 |
# actionButton("edit_interactively", "Edit Interactively"),
|
129 |
tags$br(),
|
130 |
-
actionButton("add_single", "Add
|
131 |
-
actionButton("add_to_all", "Add
|
132 |
tags$br(),
|
133 |
-
actionButton("move_caption", "Move
|
134 |
-
actionButton("move_caption_all", "Move
|
135 |
tags$br(),
|
136 |
-
actionButton("remove_related_single", "Remove Related
|
137 |
-
actionButton("remove_related_all", "Remove Related
|
138 |
orderInputPanel(),
|
139 |
textInputPanel(), # ここで関数を呼び出しています
|
140 |
tags$br(),
|
@@ -160,8 +183,9 @@ ui <- fluidPage(
|
|
160 |
actionButton("search_button", "Search"),
|
161 |
actionButton("clear_search", "Clear"),
|
162 |
fluidRow(
|
163 |
-
column(
|
164 |
-
column(
|
|
|
165 |
)
|
166 |
)
|
167 |
)
|
@@ -176,7 +200,7 @@ server <- function(input, output, session) {
|
|
176 |
directory_path <- reactiveVal()
|
177 |
captions_data <- reactiveVal()
|
178 |
caption_frequency <- reactiveVal()
|
179 |
-
operation_mode <- reactiveVal("
|
180 |
log_text <- reactiveVal("Log:\n")
|
181 |
|
182 |
## ログ表示用
|
@@ -268,20 +292,159 @@ server <- function(input, output, session) {
|
|
268 |
}
|
269 |
})
|
270 |
|
271 |
-
# Direct Remover
|
272 |
observeEvent(input$direct_remover, {
|
273 |
operation_mode("direct remove")
|
274 |
update_log("DIRECT REMOVER MODE.")
|
275 |
})
|
276 |
|
277 |
observeEvent(input$exit_direct_remover, {
|
278 |
-
operation_mode("
|
279 |
update_log("Exited Direct Remover mode.")
|
280 |
})
|
281 |
|
282 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
283 |
observeEvent(input$shuffle_single, {
|
284 |
-
if (operation_mode() != "
|
285 |
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error")
|
286 |
return()
|
287 |
}
|
@@ -303,7 +466,7 @@ server <- function(input, output, session) {
|
|
303 |
|
304 |
# Shuffle Order for All Images
|
305 |
observeEvent(input$shuffle_all, {
|
306 |
-
if (operation_mode() != "
|
307 |
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error")
|
308 |
return()
|
309 |
}
|
@@ -324,7 +487,7 @@ server <- function(input, output, session) {
|
|
324 |
|
325 |
# remove_low_freqボタンが押されたときの処理
|
326 |
observeEvent(input$remove_low_freq, {
|
327 |
-
if (operation_mode() != "
|
328 |
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error")
|
329 |
return()
|
330 |
}
|
@@ -335,7 +498,7 @@ server <- function(input, output, session) {
|
|
335 |
captions_data(updated_data)
|
336 |
|
337 |
# キャプションの頻度を更新
|
338 |
-
updated_caption_frequency <- get_caption_frequency(
|
339 |
caption_frequency(updated_caption_frequency)
|
340 |
}
|
341 |
|
@@ -344,7 +507,7 @@ server <- function(input, output, session) {
|
|
344 |
|
345 |
# Remove Captions from All Images
|
346 |
observeEvent(input$remove_from_all, {
|
347 |
-
if (operation_mode() != "
|
348 |
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error")
|
349 |
return()
|
350 |
}
|
@@ -359,7 +522,7 @@ server <- function(input, output, session) {
|
|
359 |
captions_data(updated_data)
|
360 |
|
361 |
# キャプションの頻度を更新
|
362 |
-
updated_caption_frequency <- get_caption_frequency(
|
363 |
caption_frequency(updated_caption_frequency)
|
364 |
|
365 |
update_log("Caption removed from all images.")
|
@@ -370,7 +533,7 @@ server <- function(input, output, session) {
|
|
370 |
showTextInput <- reactiveVal(FALSE)
|
371 |
|
372 |
observeEvent(input$remove_single, {
|
373 |
-
if (operation_mode() != "
|
374 |
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error")
|
375 |
return()
|
376 |
}
|
@@ -385,7 +548,7 @@ server <- function(input, output, session) {
|
|
385 |
})
|
386 |
|
387 |
observeEvent(input$add_single, {
|
388 |
-
if (operation_mode() != "
|
389 |
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error")
|
390 |
return()
|
391 |
}
|
@@ -395,7 +558,7 @@ server <- function(input, output, session) {
|
|
395 |
})
|
396 |
|
397 |
observeEvent(input$add_to_all, {
|
398 |
-
if (operation_mode() != "
|
399 |
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error")
|
400 |
return()
|
401 |
}
|
@@ -405,7 +568,7 @@ server <- function(input, output, session) {
|
|
405 |
})
|
406 |
|
407 |
observeEvent(input$move_caption, {
|
408 |
-
if (operation_mode() != "
|
409 |
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error")
|
410 |
return()
|
411 |
}
|
@@ -420,7 +583,7 @@ server <- function(input, output, session) {
|
|
420 |
})
|
421 |
|
422 |
observeEvent(input$move_caption_all, {
|
423 |
-
if (operation_mode() != "
|
424 |
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error")
|
425 |
return()
|
426 |
}
|
@@ -430,7 +593,7 @@ server <- function(input, output, session) {
|
|
430 |
})
|
431 |
|
432 |
observeEvent(input$remove_related_single, {
|
433 |
-
if (operation_mode() != "
|
434 |
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error")
|
435 |
return()
|
436 |
}
|
@@ -450,7 +613,7 @@ server <- function(input, output, session) {
|
|
450 |
})
|
451 |
|
452 |
observeEvent(input$remove_related_all, {
|
453 |
-
if (operation_mode() != "
|
454 |
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error")
|
455 |
return()
|
456 |
}
|
@@ -503,9 +666,9 @@ server <- function(input, output, session) {
|
|
503 |
)
|
504 |
|
505 |
# キャプションの頻度を更新
|
506 |
-
updated_caption_frequency <- get_caption_frequency(
|
507 |
caption_frequency(updated_caption_frequency)
|
508 |
-
operation_mode("
|
509 |
showOrderInput(FALSE)
|
510 |
})
|
511 |
|
@@ -542,21 +705,21 @@ server <- function(input, output, session) {
|
|
542 |
)
|
543 |
|
544 |
# キャプションの頻度を更新
|
545 |
-
updated_caption_frequency <- get_caption_frequency(
|
546 |
caption_frequency(updated_caption_frequency)
|
547 |
-
operation_mode("
|
548 |
showTextInput(FALSE)
|
549 |
})
|
550 |
|
551 |
|
552 |
observeEvent(input$cancel_order, {
|
553 |
-
operation_mode("
|
554 |
showOrderInput(FALSE)
|
555 |
update_log("Operation was canceled.")
|
556 |
})
|
557 |
|
558 |
observeEvent(input$cancel_text, {
|
559 |
-
operation_mode("
|
560 |
showTextInput(FALSE)
|
561 |
update_log("Operation was canceled.")
|
562 |
})
|
@@ -582,7 +745,7 @@ server <- function(input, output, session) {
|
|
582 |
captions_data(updated_data)
|
583 |
|
584 |
# キャプションの頻度を更新
|
585 |
-
updated_caption_frequency <- get_caption_frequency(
|
586 |
caption_frequency(updated_caption_frequency)
|
587 |
|
588 |
update_log("Caption removed from this image.")
|
@@ -600,32 +763,12 @@ server <- function(input, output, session) {
|
|
600 |
captions_data(updated_data)
|
601 |
|
602 |
# キャプションの頻度を更新
|
603 |
-
updated_caption_frequency <- get_caption_frequency(
|
604 |
caption_frequency(updated_caption_frequency)
|
605 |
|
606 |
update_log("Caption removed from all images.")
|
607 |
})
|
608 |
|
609 |
-
## Restore Captions
|
610 |
-
# 3. 「Restore captions」ボタンがクリックされたときの処理
|
611 |
-
# observeEvent(input$restore_captions, {
|
612 |
-
# # 確認のダイアログを表示
|
613 |
-
# if (modalDialog(
|
614 |
-
# title = "Confirmation",
|
615 |
-
# "Are you sure you want to restore the captions?",
|
616 |
-
# footer = tagList(
|
617 |
-
# modalButton("Cancel"),
|
618 |
-
# actionButton("proceed_restore", "Yes, Restore")
|
619 |
-
# )
|
620 |
-
# )) {
|
621 |
-
# # 復元処理
|
622 |
-
# observeEvent(input$proceed_restore, {
|
623 |
-
# captions_data(temp_captions_data())
|
624 |
-
# removeModal()
|
625 |
-
# })
|
626 |
-
# }
|
627 |
-
# })
|
628 |
-
|
629 |
# yes/no選択dialog
|
630 |
show_confirmation_dialog <- function() {
|
631 |
showModal(
|
@@ -655,6 +798,9 @@ server <- function(input, output, session) {
|
|
655 |
observeEvent(user_choice(), {
|
656 |
if (user_choice() == "Yes") {
|
657 |
captions_data(temp_captions_data())
|
|
|
|
|
|
|
658 |
}
|
659 |
# リアクティブな変数をリセット
|
660 |
user_choice(NULL)
|
@@ -701,22 +847,6 @@ server <- function(input, output, session) {
|
|
701 |
list(src = file.path(input$selected_image), alt = "Selected Image", width = "80%")
|
702 |
}, deleteFile = FALSE)
|
703 |
|
704 |
-
# output$image_captions <- renderUI({
|
705 |
-
# if (!is.null(captions_data())) {
|
706 |
-
# selected_image_path <- input$selected_image
|
707 |
-
# captions <- filter(captions_data(), image_path == selected_image_path) %>%
|
708 |
-
# arrange(caption_order) %>%
|
709 |
-
# pull(caption)
|
710 |
-
#
|
711 |
-
# # キャプションをリンク付きのHTMLに変換
|
712 |
-
# linked_captions <- lapply(captions, function(caption) {
|
713 |
-
# sprintf("<a href='javascript:void(0);' onclick='handleCaptionClick(\"%s\", \"image\");'>%s</a>", caption, caption)
|
714 |
-
# })
|
715 |
-
#
|
716 |
-
# HTML(paste(linked_captions, collapse = ", "))
|
717 |
-
# }
|
718 |
-
# })
|
719 |
-
#
|
720 |
output$image_captions <- renderUI({
|
721 |
if (!is.null(captions_data())) {
|
722 |
selected_image_path <- input$selected_image
|
@@ -770,34 +900,11 @@ server <- function(input, output, session) {
|
|
770 |
|
771 |
return(sorted_freq_data)
|
772 |
}
|
773 |
-
}, sanitize.text.function = function(x) x
|
774 |
-
|
775 |
-
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
# output$selected_image_captions <- renderTable({
|
780 |
-
# if (!is.null(captions_data())) {
|
781 |
-
# selected_image_path <- input$selected_image
|
782 |
-
# selected_captions <- filter(captions_data(), image_path == selected_image_path) %>%
|
783 |
-
# select(caption, caption_order) %>%
|
784 |
-
# arrange(caption_order)
|
785 |
-
#
|
786 |
-
# # caption列の各エントリにリンクを追加
|
787 |
-
# selected_captions$caption <- sprintf("<a href='javascript:void(0);' onclick='handleCaptionClick(\"%s\", \"image\");'>%s</a>", selected_captions$caption, selected_captions$caption)
|
788 |
-
#
|
789 |
-
# return(selected_captions)
|
790 |
-
# }
|
791 |
-
# }, sanitize.text.function = function(x) x) # HTMLをエスケープしないようにする
|
792 |
-
#
|
793 |
-
# output$caption_frequency_table_with_links <- renderTable({
|
794 |
-
# if (!is.null(caption_frequency())) {
|
795 |
-
# freq_data <- caption_frequency()
|
796 |
-
# freq_data$caption <- sprintf("<a href='javascript:void(0);' onclick='handleCaptionClick(\"%s\", \"frequency\");'>%s</a>", freq_data$caption, freq_data$caption)
|
797 |
-
# freq_data
|
798 |
-
# }
|
799 |
-
# }, sanitize.text.function = function(x) x, rownames = TRUE)
|
800 |
|
|
|
|
|
|
|
801 |
}
|
802 |
|
803 |
# アプリを実行
|
|
|
70 |
} else {
|
71 |
Shiny.setInputValue('clicked_caption', caption, {priority: 'event'});
|
72 |
}
|
73 |
+
} else if (operationModeElement && operationModeElement.innerText === 'Database Making') {
|
74 |
+
Shiny.setInputValue('clicked_caption_RDB', caption, {priority: 'event'});
|
75 |
} else {
|
76 |
copyToClipboard(caption);
|
77 |
}
|
|
|
82 |
# ユーザー入力を受け付ける部分
|
83 |
sidebarLayout(
|
84 |
sidebarPanel(
|
85 |
+
width = 3,
|
86 |
uiOutput("operation_mode_UI"),
|
87 |
|
88 |
# ディレクトリパスを入力するテキストボックス
|
|
|
105 |
tags$br(),
|
106 |
tags$br(),
|
107 |
|
108 |
+
# Direct Removerモード
|
109 |
actionButton("direct_remover", "Direct Remover"),
|
110 |
conditionalPanel(
|
111 |
condition = "output.operation_mode_UI === 'direct remove'",
|
|
|
113 |
),
|
114 |
tags$br(),
|
115 |
tags$br(),
|
116 |
+
|
117 |
+
# Database Makingモード
|
118 |
+
actionButton("enter_database_mode", "Enter Database Making Mode"),
|
119 |
+
conditionalPanel(
|
120 |
+
condition = "output.operation_mode_UI === 'Database Making'",
|
121 |
+
actionButton("exit_database_mode", "Exit Database Making Mode"),
|
122 |
+
tags$br(),
|
123 |
+
tags$br(),
|
124 |
+
textInput("parent_caption_input", "Parent Caption:"),
|
125 |
+
textInput("child_caption_input", "Child Caption:"),
|
126 |
+
actionButton("add_to_RDB", "Add to Database"),
|
127 |
+
actionButton("clear_inputs_RDB", "Clear"),
|
128 |
+
tags$br(),
|
129 |
+
tags$br(),
|
130 |
+
fileInput("load_relation_database", "Load Relation DB", accept = ".csv"),
|
131 |
+
downloadButton("save_relation_database", "Save Relation DB"),
|
132 |
+
tags$br(),
|
133 |
+
tags$br(),
|
134 |
+
actionButton("aggregate_single", "Aggregation Single"),
|
135 |
+
actionButton("aggregate_all", "Aggregation All")
|
136 |
+
),
|
137 |
+
|
138 |
conditionalPanel(
|
139 |
+
condition = "output.operation_mode_UI !== 'direct remove' && output.operation_mode_UI !== 'Database Making'",
|
140 |
+
actionButton("shuffle_single", "Shuffle Single"),
|
141 |
+
actionButton("shuffle_all", "Shuffle All"),
|
|
|
|
|
142 |
tags$br(),
|
143 |
tags$br(),
|
144 |
numericInput("frequency_threshold", "Frequency Threshold:", value = 5, min = 1),
|
|
|
146 |
tags$br(),
|
147 |
tags$br(),
|
148 |
textInput("edit_caption", "Caption to Edit:", ""),
|
149 |
+
actionButton("remove_single", "Remove Single"),
|
150 |
+
actionButton("remove_from_all", "Remove All"),
|
151 |
# actionButton("edit_interactively", "Edit Interactively"),
|
152 |
tags$br(),
|
153 |
+
actionButton("add_single", "Add Single"),
|
154 |
+
actionButton("add_to_all", "Add All"),
|
155 |
tags$br(),
|
156 |
+
actionButton("move_caption", "Move Single"),
|
157 |
+
actionButton("move_caption_all", "Move All"),
|
158 |
tags$br(),
|
159 |
+
actionButton("remove_related_single", "Remove Related Single"),
|
160 |
+
actionButton("remove_related_all", "Remove Related All"),
|
161 |
orderInputPanel(),
|
162 |
textInputPanel(), # ここで関数を呼び出しています
|
163 |
tags$br(),
|
|
|
183 |
actionButton("search_button", "Search"),
|
184 |
actionButton("clear_search", "Clear"),
|
185 |
fluidRow(
|
186 |
+
column(4, tableOutput("selected_image_captions")),
|
187 |
+
column(4, tableOutput("caption_frequency_table_with_links")),
|
188 |
+
column(4, tableOutput("relation_database_table"))
|
189 |
)
|
190 |
)
|
191 |
)
|
|
|
200 |
directory_path <- reactiveVal()
|
201 |
captions_data <- reactiveVal()
|
202 |
caption_frequency <- reactiveVal()
|
203 |
+
operation_mode <- reactiveVal("Normal")
|
204 |
log_text <- reactiveVal("Log:\n")
|
205 |
|
206 |
## ログ表示用
|
|
|
292 |
}
|
293 |
})
|
294 |
|
295 |
+
# Direct Removerモード
|
296 |
observeEvent(input$direct_remover, {
|
297 |
operation_mode("direct remove")
|
298 |
update_log("DIRECT REMOVER MODE.")
|
299 |
})
|
300 |
|
301 |
observeEvent(input$exit_direct_remover, {
|
302 |
+
operation_mode("Normal")
|
303 |
update_log("Exited Direct Remover mode.")
|
304 |
})
|
305 |
|
306 |
+
## Relation Databaseモード
|
307 |
+
relation_database <- reactiveVal(data.frame(parent_caption = character(0), child_caption = character(0), stringsAsFactors = FALSE))
|
308 |
+
|
309 |
+
observeEvent(input$enter_database_mode, {
|
310 |
+
operation_mode("Database Making")
|
311 |
+
update_log("DATABASE MAKING MODE.")
|
312 |
+
})
|
313 |
+
|
314 |
+
observeEvent(input$exit_database_mode, {
|
315 |
+
operation_mode("Normal")
|
316 |
+
update_log("Exited Database Making mode.")
|
317 |
+
})
|
318 |
+
|
319 |
+
observeEvent(input$clicked_caption_RDB, {
|
320 |
+
if (input$parent_caption_input == "") {
|
321 |
+
updateTextInput(session, "parent_caption_input", value = input$clicked_caption_RDB)
|
322 |
+
} else {
|
323 |
+
updateTextInput(session, "child_caption_input", value = input$clicked_caption_RDB)
|
324 |
+
}
|
325 |
+
})
|
326 |
+
|
327 |
+
observeEvent(input$add_to_RDB, {
|
328 |
+
# 親キャプションまたは子キャプションが空欄の場合、または親キャプションと子キャプションが同じ場合、エラーログを出力
|
329 |
+
if (input$parent_caption_input == "" || input$child_caption_input == "" || input$parent_caption_input == input$child_caption_input) {
|
330 |
+
showNotification("Error: Invalid parent or child caption.", type = "error")
|
331 |
+
return()
|
332 |
+
}
|
333 |
+
|
334 |
+
# 同じ組み合わせがrelation_databaseに存在するかチェック
|
335 |
+
existing_relation <- with(relation_database(), parent_caption == input$parent_caption_input &
|
336 |
+
child_caption == input$child_caption_input)
|
337 |
+
if (any(existing_relation)) {
|
338 |
+
showNotification("Error: This relation already exists in the database.", type = "error")
|
339 |
+
return() # このobserveEventの処理を終了
|
340 |
+
}
|
341 |
+
|
342 |
+
# relation_databaseに関係を追加するコード
|
343 |
+
new_relation <- data.frame(parent_caption = input$parent_caption_input,
|
344 |
+
child_caption = input$child_caption_input)
|
345 |
+
updated_database <- rbind(relation_database(), new_relation)
|
346 |
+
relation_database(updated_database)
|
347 |
+
update_log("Relation added to database.")
|
348 |
+
})
|
349 |
+
|
350 |
+
observeEvent(input$clear_inputs_RDB, {
|
351 |
+
updateTextInput(session, "parent_caption_input", value = "")
|
352 |
+
updateTextInput(session, "child_caption_input", value = "")
|
353 |
+
})
|
354 |
+
|
355 |
+
observeEvent(input$aggregate_single, {
|
356 |
+
updated_data <- captions_data()
|
357 |
+
# 選択されている画像のcaptionを別変数に保存
|
358 |
+
captions_for_selected_image <- updated_data$caption[updated_data$image_path == input$selected_image]
|
359 |
+
|
360 |
+
for (i in 1:nrow(relation_database())) {
|
361 |
+
parent <- relation_database()$parent_caption[i]
|
362 |
+
child <- relation_database()$child_caption[i]
|
363 |
+
|
364 |
+
# parent_captionの存在確認を行い、存在する場合remove_caption_and_adjust_orderを実行
|
365 |
+
if (parent %in% captions_for_selected_image) {
|
366 |
+
updated_data <- remove_caption_and_adjust_order(updated_data, input$selected_image, child)
|
367 |
+
}
|
368 |
+
}
|
369 |
+
|
370 |
+
captions_data(updated_data)
|
371 |
+
|
372 |
+
# キャプションの頻度を更新
|
373 |
+
updated_caption_frequency <- get_caption_frequency(captions_data())
|
374 |
+
caption_frequency(updated_caption_frequency)
|
375 |
+
|
376 |
+
update_log("Captions aggregated for this image.")
|
377 |
+
})
|
378 |
+
|
379 |
+
observeEvent(input$aggregate_all, {
|
380 |
+
updated_data <- captions_data()
|
381 |
+
|
382 |
+
for (image_path in unique(updated_data$image_path)) {
|
383 |
+
# 各画像のcaptionを別変数に保存
|
384 |
+
captions_for_image <- updated_data$caption[updated_data$image_path == image_path]
|
385 |
+
|
386 |
+
for (i in 1:nrow(relation_database())) {
|
387 |
+
parent <- relation_database()$parent_caption[i]
|
388 |
+
child <- relation_database()$child_caption[i]
|
389 |
+
|
390 |
+
# parent_captionの存在確認を行い、存在する場合remove_caption_and_adjust_orderを実行
|
391 |
+
if (parent %in% captions_for_image) {
|
392 |
+
updated_data <- remove_caption_and_adjust_order(updated_data, image_path, child)
|
393 |
+
}
|
394 |
+
}
|
395 |
+
}
|
396 |
+
|
397 |
+
captions_data(updated_data)
|
398 |
+
|
399 |
+
# キャプションの頻度を更新
|
400 |
+
updated_caption_frequency <- get_caption_frequency(captions_data())
|
401 |
+
caption_frequency(updated_caption_frequency)
|
402 |
+
|
403 |
+
update_log("Captions aggregated for all images.")
|
404 |
+
})
|
405 |
+
|
406 |
+
# Relation Databaseをセーブ
|
407 |
+
output$save_relation_database <- downloadHandler(
|
408 |
+
filename = function() {
|
409 |
+
paste("relation_database_", Sys.Date(), ".csv", sep="")
|
410 |
+
},
|
411 |
+
content = function(file) {
|
412 |
+
write.csv(relation_database(), file, row.names = FALSE)
|
413 |
+
},
|
414 |
+
contentType = "text/csv"
|
415 |
+
)
|
416 |
+
|
417 |
+
observeEvent(input$load_relation_database, {
|
418 |
+
# ファイルが選択された場合のみ処理を実行
|
419 |
+
if (!is.null(input$load_relation_database$datapath)) {
|
420 |
+
# CSV���ァイルを読み込む
|
421 |
+
new_data <- read.csv(input$load_relation_database$datapath, stringsAsFactors = FALSE)
|
422 |
+
|
423 |
+
# データの整合性チェック
|
424 |
+
if (!all(c("parent_caption", "child_caption") %in% names(new_data))) {
|
425 |
+
showNotification("Error: The file does not have the required columns (parent_caption and child_caption).", type = "error")
|
426 |
+
return()
|
427 |
+
}
|
428 |
+
|
429 |
+
if (any(is.na(new_data$parent_caption)) || any(is.na(new_data$child_caption))) {
|
430 |
+
showNotification("Error: The file contains missing values in parent_caption or child_caption.", type = "error")
|
431 |
+
return()
|
432 |
+
}
|
433 |
+
|
434 |
+
if (any(nchar(new_data$parent_caption) == 0) || any(nchar(new_data$child_caption) == 0)) {
|
435 |
+
showNotification("Error: The file contains empty strings in parent_caption or child_caption.", type = "error")
|
436 |
+
return()
|
437 |
+
}
|
438 |
+
|
439 |
+
# relation_database()に新しいデータを格納
|
440 |
+
relation_database(new_data)
|
441 |
+
update_log("Relation database loaded.")
|
442 |
+
}
|
443 |
+
})
|
444 |
+
|
445 |
+
## Shuffle Order for Current Image
|
446 |
observeEvent(input$shuffle_single, {
|
447 |
+
if (operation_mode() != "Normal") {
|
448 |
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error")
|
449 |
return()
|
450 |
}
|
|
|
466 |
|
467 |
# Shuffle Order for All Images
|
468 |
observeEvent(input$shuffle_all, {
|
469 |
+
if (operation_mode() != "Normal") {
|
470 |
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error")
|
471 |
return()
|
472 |
}
|
|
|
487 |
|
488 |
# remove_low_freqボタンが押されたときの処理
|
489 |
observeEvent(input$remove_low_freq, {
|
490 |
+
if (operation_mode() != "Normal") {
|
491 |
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error")
|
492 |
return()
|
493 |
}
|
|
|
498 |
captions_data(updated_data)
|
499 |
|
500 |
# キャプションの頻度を更新
|
501 |
+
updated_caption_frequency <- get_caption_frequency(captions_data())
|
502 |
caption_frequency(updated_caption_frequency)
|
503 |
}
|
504 |
|
|
|
507 |
|
508 |
# Remove Captions from All Images
|
509 |
observeEvent(input$remove_from_all, {
|
510 |
+
if (operation_mode() != "Normal") {
|
511 |
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error")
|
512 |
return()
|
513 |
}
|
|
|
522 |
captions_data(updated_data)
|
523 |
|
524 |
# キャプションの頻度を更新
|
525 |
+
updated_caption_frequency <- get_caption_frequency(captions_data())
|
526 |
caption_frequency(updated_caption_frequency)
|
527 |
|
528 |
update_log("Caption removed from all images.")
|
|
|
533 |
showTextInput <- reactiveVal(FALSE)
|
534 |
|
535 |
observeEvent(input$remove_single, {
|
536 |
+
if (operation_mode() != "Normal") {
|
537 |
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error")
|
538 |
return()
|
539 |
}
|
|
|
548 |
})
|
549 |
|
550 |
observeEvent(input$add_single, {
|
551 |
+
if (operation_mode() != "Normal") {
|
552 |
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error")
|
553 |
return()
|
554 |
}
|
|
|
558 |
})
|
559 |
|
560 |
observeEvent(input$add_to_all, {
|
561 |
+
if (operation_mode() != "Normal") {
|
562 |
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error")
|
563 |
return()
|
564 |
}
|
|
|
568 |
})
|
569 |
|
570 |
observeEvent(input$move_caption, {
|
571 |
+
if (operation_mode() != "Normal") {
|
572 |
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error")
|
573 |
return()
|
574 |
}
|
|
|
583 |
})
|
584 |
|
585 |
observeEvent(input$move_caption_all, {
|
586 |
+
if (operation_mode() != "Normal") {
|
587 |
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error")
|
588 |
return()
|
589 |
}
|
|
|
593 |
})
|
594 |
|
595 |
observeEvent(input$remove_related_single, {
|
596 |
+
if (operation_mode() != "Normal") {
|
597 |
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error")
|
598 |
return()
|
599 |
}
|
|
|
613 |
})
|
614 |
|
615 |
observeEvent(input$remove_related_all, {
|
616 |
+
if (operation_mode() != "Normal") {
|
617 |
showNotification("Another operation is in progress. Please finish or cancel it first.", type = "error")
|
618 |
return()
|
619 |
}
|
|
|
666 |
)
|
667 |
|
668 |
# キャプションの頻度を更新
|
669 |
+
updated_caption_frequency <- get_caption_frequency(captions_data())
|
670 |
caption_frequency(updated_caption_frequency)
|
671 |
+
operation_mode("Normal")
|
672 |
showOrderInput(FALSE)
|
673 |
})
|
674 |
|
|
|
705 |
)
|
706 |
|
707 |
# キャプションの頻度を更新
|
708 |
+
updated_caption_frequency <- get_caption_frequency(captions_data())
|
709 |
caption_frequency(updated_caption_frequency)
|
710 |
+
operation_mode("Normal")
|
711 |
showTextInput(FALSE)
|
712 |
})
|
713 |
|
714 |
|
715 |
observeEvent(input$cancel_order, {
|
716 |
+
operation_mode("Normal")
|
717 |
showOrderInput(FALSE)
|
718 |
update_log("Operation was canceled.")
|
719 |
})
|
720 |
|
721 |
observeEvent(input$cancel_text, {
|
722 |
+
operation_mode("Normal")
|
723 |
showTextInput(FALSE)
|
724 |
update_log("Operation was canceled.")
|
725 |
})
|
|
|
745 |
captions_data(updated_data)
|
746 |
|
747 |
# キャプションの頻度を更新
|
748 |
+
updated_caption_frequency <- get_caption_frequency(captions_data())
|
749 |
caption_frequency(updated_caption_frequency)
|
750 |
|
751 |
update_log("Caption removed from this image.")
|
|
|
763 |
captions_data(updated_data)
|
764 |
|
765 |
# キャプションの頻度を更新
|
766 |
+
updated_caption_frequency <- get_caption_frequency(captions_data())
|
767 |
caption_frequency(updated_caption_frequency)
|
768 |
|
769 |
update_log("Caption removed from all images.")
|
770 |
})
|
771 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
772 |
# yes/no選択dialog
|
773 |
show_confirmation_dialog <- function() {
|
774 |
showModal(
|
|
|
798 |
observeEvent(user_choice(), {
|
799 |
if (user_choice() == "Yes") {
|
800 |
captions_data(temp_captions_data())
|
801 |
+
# キャプションの頻度を更新
|
802 |
+
updated_caption_frequency <- get_caption_frequency(captions_data())
|
803 |
+
caption_frequency(updated_caption_frequency)
|
804 |
}
|
805 |
# リアクティブな変数をリセット
|
806 |
user_choice(NULL)
|
|
|
847 |
list(src = file.path(input$selected_image), alt = "Selected Image", width = "80%")
|
848 |
}, deleteFile = FALSE)
|
849 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
850 |
output$image_captions <- renderUI({
|
851 |
if (!is.null(captions_data())) {
|
852 |
selected_image_path <- input$selected_image
|
|
|
900 |
|
901 |
return(sorted_freq_data)
|
902 |
}
|
903 |
+
}, sanitize.text.function = function(x) x)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
904 |
|
905 |
+
output$relation_database_table <- renderTable({
|
906 |
+
relation_database()
|
907 |
+
}, sanitize.text.function = function(x) x)
|
908 |
}
|
909 |
|
910 |
# アプリを実行
|