cella110n commited on
Commit
6d01677
1 Parent(s): 310d0b1
Files changed (1) hide show
  1. app.R +211 -104
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 from Single"),
127
- actionButton("remove_from_all", "Remove from All"),
128
  # actionButton("edit_interactively", "Edit Interactively"),
129
  tags$br(),
130
- actionButton("add_single", "Add to Single"),
131
- actionButton("add_to_all", "Add to All"),
132
  tags$br(),
133
- actionButton("move_caption", "Move Caption"),
134
- actionButton("move_caption_all", "Move Caption of All"),
135
  tags$br(),
136
- actionButton("remove_related_single", "Remove Related from Single"),
137
- actionButton("remove_related_all", "Remove Related from all"),
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(6, tableOutput("selected_image_captions")),
164
- column(6, tableOutput("caption_frequency_table_with_links"))
 
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("normal")
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("normal")
279
  update_log("Exited Direct Remover mode.")
280
  })
281
 
282
- # Shuffle Order for Current Image
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
283
  observeEvent(input$shuffle_single, {
284
- if (operation_mode() != "normal") {
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() != "normal") {
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() != "normal") {
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(updated_data)
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() != "normal") {
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(updated_data)
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() != "normal") {
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() != "normal") {
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() != "normal") {
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() != "normal") {
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() != "normal") {
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() != "normal") {
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() != "normal") {
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(updated_data)
507
  caption_frequency(updated_caption_frequency)
508
- operation_mode("normal")
509
  showOrderInput(FALSE)
510
  })
511
 
@@ -542,21 +705,21 @@ server <- function(input, output, session) {
542
  )
543
 
544
  # キャプションの頻度を更新
545
- updated_caption_frequency <- get_caption_frequency(updated_data)
546
  caption_frequency(updated_caption_frequency)
547
- operation_mode("normal")
548
  showTextInput(FALSE)
549
  })
550
 
551
 
552
  observeEvent(input$cancel_order, {
553
- operation_mode("normal")
554
  showOrderInput(FALSE)
555
  update_log("Operation was canceled.")
556
  })
557
 
558
  observeEvent(input$cancel_text, {
559
- operation_mode("normal")
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(updated_data)
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(updated_data)
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, rownames = TRUE)
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
  # アプリを実行