Class: Rufio::FileOperationController

Inherits:
Object
  • Object
show all
Defined in:
lib/rufio/file_operation_controller.rb

Overview

ファイル操作専用コントローラKeybindHandler からファイル作成・削除・リネーム・移動・コピー系メソッドを分離し、単一責任原則に準拠

Constant Summary collapse

CONFIRMATION_DIALOG_WIDTH =

Dialog size constants

45
DIALOG_BORDER_HEIGHT =
4
FILESYSTEM_SYNC_DELAY =

10ms wait for filesystem sync

0.01

Instance Method Summary collapse

Constructor Details

#initialize(directory_listing, file_operations, dialog_renderer, nav_controller, selection_manager) ⇒ FileOperationController

Returns a new instance of FileOperationController.



16
17
18
19
20
21
22
23
# File 'lib/rufio/file_operation_controller.rb', line 16

def initialize(directory_listing, file_operations, dialog_renderer, nav_controller, selection_manager)
  @directory_listing = directory_listing
  @file_operations = file_operations
  @dialog_renderer = dialog_renderer
  @nav_controller = nav_controller
  @selection_manager = selection_manager
  @terminal_ui = nil
end

Instance Method Details

#copy_selected_to_currentObject



233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/rufio/file_operation_controller.rb', line 233

def copy_selected_to_current
  return false if @selection_manager.empty?

  current_path = @directory_listing&.current_path || Dir.pwd
  source_path = @selection_manager.source_directory || current_path

  if show_copy_confirmation(@selection_manager.count, source_path, current_path)
    @file_operations.copy(@selection_manager.selected_items, source_path, current_path)
    @selection_manager.clear
    @directory_listing.refresh if @directory_listing
    true
  else
    false
  end
end

#create_directoryObject



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/rufio/file_operation_controller.rb', line 61

def create_directory
  current_path = @directory_listing&.current_path || Dir.pwd

  dirname = @dialog_renderer.show_input_dialog("Create Directory", "Enter directory name:", {
    border_color: "\e[34m",
    title_color: "\e[1;34m",
    content_color: "\e[37m"
  })

  return false if dirname.nil? || dirname.empty?

  result = @file_operations.create_directory(current_path, dirname)

  if result.success
    @directory_listing.refresh
    entries = @directory_listing.list_entries
    new_dir_index = entries.find_index { |entry| entry[:name] == dirname }
    @nav_controller.select_index(new_dir_index) if new_dir_index
  end

  @terminal_ui&.refresh_display
  result.success
end

#create_fileObject

ファイル作成



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/rufio/file_operation_controller.rb', line 37

def create_file
  current_path = @directory_listing&.current_path || Dir.pwd

  filename = @dialog_renderer.show_input_dialog("Create File", "Enter file name:", {
    border_color: "\e[32m",
    title_color: "\e[1;32m",
    content_color: "\e[37m"
  })

  return false if filename.nil? || filename.empty?

  result = @file_operations.create_file(current_path, filename)

  if result.success
    @directory_listing.refresh
    entries = @directory_listing.list_entries
    new_file_index = entries.find_index { |entry| entry[:name] == filename }
    @nav_controller.select_index(new_file_index) if new_file_index
  end

  @terminal_ui&.refresh_display
  result.success
end

#delete_current_file_with_confirmation(entry, get_active_entries) ⇒ Object

Parameters:

  • entry (Hash)

    削除対象エントリ

  • get_active_entries (Proc)

    アクティブエントリ取得ラムダ



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/rufio/file_operation_controller.rb', line 123

def delete_current_file_with_confirmation(entry, get_active_entries)
  return false if entry.nil?
  return false if entry[:name] == '..'

  current_path = @directory_listing&.current_path || Dir.pwd

  # 選択アイテムがある場合はそちらを優先
  unless @selection_manager.empty?
    source_path = @selection_manager.source_directory || current_path
    if show_delete_confirmation(@selection_manager.count, source_path)
      result = @file_operations.delete(@selection_manager.selected_items, source_path)
      @selection_manager.clear
      @directory_listing.refresh if @directory_listing
      @terminal_ui&.refresh_display
      return result.success
    else
      return false
    end
  end

  current_name = entry[:name]
  is_directory = entry[:type] == :directory

  type_text = is_directory ? 'directory' : 'file'
  content_lines = [
    '',
    "Delete this #{type_text}?",
    "  #{current_name}",
    '',
    '  [Y]es - Delete',
    '  [N]o  - Cancel',
    ''
  ]

  title = 'Confirm Delete'
  width = [50, current_name.length + 10].max
  height = content_lines.length + 4

  confirmed = false
  show_overlay_dialog(title, content_lines, {
    width: width,
    height: height,
    border_color: "\e[31m",
    title_color: "\e[1;31m",
    content_color: "\e[37m"
  }) do
    loop do
      input = STDIN.getch.downcase
      case input
      when 'y'
        confirmed = true
        break
      when 'n', "\e"
        confirmed = false
        break
      end
    end
    nil
  end

  return false unless confirmed

  result = @file_operations.delete([current_name], current_path)

  if result.success
    @directory_listing.refresh
    entries = get_active_entries.call
    idx = @nav_controller.current_index
    @nav_controller.select_index([[idx, 0].max, [entries.length - 1, 0].max].min)
  end

  @terminal_ui&.refresh_display
  result.success
end

#delete_selected_filesObject



198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/rufio/file_operation_controller.rb', line 198

def delete_selected_files
  return false if @selection_manager.empty?

  if show_delete_confirmation(@selection_manager.count)
    current_path = @directory_listing&.current_path || Dir.pwd
    result = @file_operations.delete(@selection_manager.selected_items, current_path)
    show_deletion_result(result.count, @selection_manager.count, result.errors)
    @selection_manager.clear
    @directory_listing.refresh if @directory_listing
    true
  else
    false
  end
end

#move_selected_to_currentObject

移動・コピー



217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/rufio/file_operation_controller.rb', line 217

def move_selected_to_current
  return false if @selection_manager.empty?

  current_path = @directory_listing&.current_path || Dir.pwd
  source_path = @selection_manager.source_directory || current_path

  if show_move_confirmation(@selection_manager.count, source_path, current_path)
    @file_operations.move(@selection_manager.selected_items, source_path, current_path)
    @selection_manager.clear
    @directory_listing.refresh if @directory_listing
    true
  else
    false
  end
end

#rename_current_file(entry) ⇒ Object

Parameters:

  • entry (Hash)

    対象エントリ(current_entry を呼び出し元で渡す)



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/rufio/file_operation_controller.rb', line 90

def rename_current_file(entry)
  return false unless entry

  current_name = entry[:name]
  current_path = @directory_listing&.current_path || Dir.pwd

  new_name = @dialog_renderer.show_input_dialog("Rename: #{current_name}", "Enter new name:", {
    border_color: "\e[33m",
    title_color: "\e[1;33m",
    content_color: "\e[37m"
  })

  return false if new_name.nil? || new_name.empty?

  result = @file_operations.rename(current_path, current_name, new_name)

  if result.success
    @directory_listing.refresh
    entries = @directory_listing.list_entries
    new_index = entries.find_index { |e| e[:name] == new_name }
    @nav_controller.select_index(new_index) if new_index
  end

  @terminal_ui&.refresh_display
  result.success
end

#set_directory_listing(directory_listing) ⇒ Object



29
30
31
# File 'lib/rufio/file_operation_controller.rb', line 29

def set_directory_listing(directory_listing)
  @directory_listing = directory_listing
end

#set_terminal_ui(terminal_ui) ⇒ Object



25
26
27
# File 'lib/rufio/file_operation_controller.rb', line 25

def set_terminal_ui(terminal_ui)
  @terminal_ui = terminal_ui
end

#show_exit_confirmationObject

終了確認



253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/rufio/file_operation_controller.rb', line 253

def show_exit_confirmation
  content_lines = [
    '',
    'Are you sure you want to exit?',
    '',
    '  [Y]es - Exit',
    '  [N]o  - Cancel',
    ''
  ]

  confirmed = false
  show_overlay_dialog('Exit Confirmation', content_lines, {
    width: CONFIRMATION_DIALOG_WIDTH,
    height: DIALOG_BORDER_HEIGHT + content_lines.length,
    border_color: "\e[33m",
    title_color: "\e[1;33m",
    content_color: "\e[37m"
  }) do
    loop do
      input = STDIN.getch.downcase
      case input
      when 'y'
        confirmed = true
        break
      when 'n', "\e", "\x03"
        confirmed = false
        break
      end
    end
    nil
  end

  confirmed
end