glimmer-cs-gladiator 0.8.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -43,6 +43,7 @@ module Glimmer
43
43
  APP_ROOT = ::File.expand_path('../../../..', __FILE__)
44
44
  # TODO make sure COMMAND_KEY doesn't clash on Linux/Windows for CMD+CTRL shortcuts
45
45
  COMMAND_KEY = OS.mac? ? :command : :ctrl
46
+ CONTROL_KEY = OS.mac? ? :ctrl : :alt
46
47
  VERSION = ::File.read(::File.join(APP_ROOT, 'VERSION')).to_s.strip
47
48
  LICENSE = ::File.read(::File.join(APP_ROOT, 'LICENSE.txt')).to_s.strip
48
49
  ICON = ::File.expand_path(::File.join(APP_ROOT, 'images', 'glimmer-cs-gladiator-logo.png'))
@@ -106,7 +107,6 @@ module Glimmer
106
107
  display_about_dialog
107
108
  }
108
109
  on_quit {
109
- save_config
110
110
  project_dir.selected_child&.write_dirty_content
111
111
  display.swt_display.shells.each(&:close)
112
112
  }
@@ -115,7 +115,6 @@ module Glimmer
115
115
  focused_gladiator.handle_display_shortcut(key_event) if !focused_gladiator.nil? && key_event.widget.shell == focused_gladiator&.swt_widget
116
116
  }
117
117
  on_swt_Close {
118
- save_config
119
118
  project_dir.selected_child&.write_dirty_content
120
119
  }
121
120
  }
@@ -140,7 +139,7 @@ module Glimmer
140
139
  if Gladiator.drag && !@tab_folder2
141
140
  self.tab_folder1 = current_tab_folder
142
141
  @tab_folder_sash_form.content {
143
- self.current_tab_folder = self.tab_folder2 = tab_folder {}
142
+ self.current_tab_folder = self.tab_folder2 = text_editor_group_tab_folder
144
143
  @current_tab_folder.swt_widget.setData('proxy', @current_tab_folder)
145
144
  }
146
145
  body_root.pack_same_size
@@ -152,56 +151,61 @@ module Glimmer
152
151
  @current_tab_item = found_tab_item.getData('proxy')
153
152
  @current_text_editor = found_tab_item.getData('text_editor') unless found_tab_item.getData('text_editor').nil?
154
153
  @current_tab_folder.swt_widget.setData('selected_tab_item', @current_tab_item)
155
- elsif selected_file
156
- @current_tab_folder.content {
157
- @current_tab_item = tab_item { |the_tab_item|
158
- text selected_file.name
159
- fill_layout(:horizontal) {
160
- margin_width 0
161
- margin_height 0
162
- }
163
- tab_folder = nil
164
- the_text_editor = nil
165
- the_tab_item.content {
166
- @current_text_editor = the_text_editor = text_editor(project_dir: project_dir, file: selected_file) {
167
- layout_data :fill, :fill, true, true
154
+ else
155
+ begin
156
+ @current_tab_folder.content {
157
+ @current_tab_item = tab_item { |the_tab_item|
158
+ text selected_file.name
159
+ fill_layout(:horizontal) {
160
+ margin_width 0
161
+ margin_height 0
168
162
  }
169
- @current_tab_folder.swt_widget.setData('selected_tab_item', @current_tab_item)
170
- the_tab_item.swt_tab_item.setData('text_editor', @current_text_editor)
171
- @current_text_editor.text_proxy.content {
172
- on_focus_gained {
173
- tab_folder = the_text_editor.swt_widget.getParent.getParent
174
- self.current_tab_folder = tab_folder.getData('proxy')
175
- @current_tab_item = the_tab_item
176
- @current_text_editor = the_text_editor
177
- @current_tab_folder.swt_widget.setData('selected_tab_item', @current_tab_item)
178
- @current_tab_folder.swt_widget.setSelection(@current_tab_item.swt_tab_item)
179
- project_dir.selected_child = @current_tab_item.swt_tab_item.getData('file')
163
+ tab_folder = nil
164
+ the_text_editor = nil
165
+ the_tab_item.content {
166
+ @current_text_editor = the_text_editor = text_editor(project_dir: project_dir, file: selected_file) {
167
+ layout_data :fill, :fill, true, true
168
+ }
169
+ @current_tab_folder.swt_widget.setData('selected_tab_item', @current_tab_item)
170
+ the_tab_item.swt_tab_item.setData('text_editor', @current_text_editor)
171
+ @current_text_editor.text_proxy.content {
172
+ on_focus_gained {
173
+ tab_folder = the_text_editor.swt_widget.getParent.getParent
174
+ self.current_tab_folder = tab_folder.getData('proxy')
175
+ @current_tab_item = the_tab_item
176
+ @current_text_editor = the_text_editor
177
+ @current_tab_folder.swt_widget.setData('selected_tab_item', @current_tab_item)
178
+ @current_tab_folder.swt_widget.setSelection(@current_tab_item.swt_tab_item)
179
+ project_dir.selected_child = @current_tab_item.swt_tab_item.getData('file')
180
+ }
180
181
  }
181
182
  }
183
+ on_swt_show {
184
+ @current_tab_item = the_tab_item
185
+ @current_text_editor = the_text_editor
186
+ self.current_tab_folder = @current_tab_item.swt_widget.getParent.getData('proxy')
187
+ @current_tab_folder.swt_widget.setData('selected_tab_item', @current_tab_item)
188
+ @current_tab_folder.swt_widget.setSelection(@current_tab_item.swt_tab_item)
189
+ project_dir.selected_child = selected_file
190
+ @current_text_editor&.load_content
191
+ @current_text_editor&.text_widget&.setFocus
192
+ save_config unless selected_file.nil?
193
+ }
194
+ on_widget_disposed {
195
+ project_dir.selected_child&.write_dirty_content
196
+ tab_item_file = the_tab_item.swt_tab_item.get_data('file')
197
+ tab_item_file.close unless [@tab_folder1, @tab_folder2].compact.map(&:items).flatten(1).detect {|ti| ti.get_data('file') == tab_item_file}
198
+ }
182
199
  }
183
-
184
- on_swt_show {
185
- @current_tab_item = the_tab_item
186
- @current_text_editor = the_text_editor
187
- self.current_tab_folder = @current_tab_item.swt_widget.getParent.getData('proxy')
188
- @current_tab_folder.swt_widget.setData('selected_tab_item', @current_tab_item)
189
- @current_tab_folder.swt_widget.setSelection(@current_tab_item.swt_tab_item)
190
- project_dir.selected_child = selected_file
191
- @current_text_editor&.text_widget&.setFocus
192
- }
193
- on_widget_disposed {
194
- project_dir.selected_child&.write_dirty_content
195
- tab_item_file = the_tab_item.swt_tab_item.get_data('file')
196
- tab_item_file.close unless [@tab_folder1, @tab_folder2].compact.map(&:items).flatten(1).detect {|ti| ti.get_data('file') == tab_item_file}
197
- }
200
+ @current_tab_item.swt_tab_item.setData('file_path', selected_file.path)
201
+ @current_tab_item.swt_tab_item.setData('file', selected_file)
202
+ @current_tab_item.swt_tab_item.setData('proxy', @current_tab_item)
198
203
  }
199
- @current_tab_item.swt_tab_item.setData('file_path', selected_file.path)
200
- @current_tab_item.swt_tab_item.setData('file', selected_file)
201
- @current_tab_item.swt_tab_item.setData('proxy', @current_tab_item)
202
- }
203
- @current_tab_folder.swt_widget.setSelection(@current_tab_item.swt_tab_item)
204
- body_root.pack_same_size
204
+ @current_tab_folder.swt_widget.setSelection(@current_tab_item.swt_tab_item)
205
+ body_root.pack_same_size
206
+ rescue => e
207
+ puts e.full_message
208
+ end
205
209
  end
206
210
  @current_text_editor&.text_widget&.setFocus
207
211
  end
@@ -266,7 +270,6 @@ module Glimmer
266
270
  }
267
271
 
268
272
  on_shell_closed {
269
- save_config
270
273
  project_dir.selected_child&.write_dirty_content
271
274
  if @tab_folder2
272
275
  current_tab_folder.swt_widget.getItems.each do |tab_item|
@@ -644,28 +647,44 @@ module Glimmer
644
647
  minimum_height 176
645
648
  }
646
649
  orientation bind(self, :split_orientation) {|value| async_exec { body_root.pack_same_size}; value}
647
- self.current_tab_folder = self.tab_folder1 = tab_folder {
648
- drag_source(DND::DROP_COPY) {
649
- transfer [TextTransfer.getInstance].to_java(Transfer)
650
- event_data = nil
651
- on_drag_start {|event|
652
- Gladiator.drag = true
653
- tab_folder = event.widget.getControl
654
- tab_item = tab_folder.getItem(Point.new(event.x, event.y))
655
- event_data = tab_item.getData('file_path')
656
- }
657
- on_drag_set_data { |event|
658
- event.data = event_data
659
- }
660
- }
661
- }
662
- @current_tab_folder.swt_widget.setData('proxy', @current_tab_folder)
650
+ self.current_tab_folder = self.tab_folder1 = text_editor_group_tab_folder
651
+ @current_tab_folder.swt_widget.setData('proxy', @current_tab_folder) # TODO see if we could get rid of this as it seems redundant
663
652
  }
664
653
  }
665
654
  } # end of sash form
666
655
  }
667
656
  end
668
657
  }
658
+
659
+ def text_editor_group_tab_folder
660
+ tab_folder { |tab_folder_proxy|
661
+ on_widget_selected {
662
+ self.current_tab_folder = tab_folder_proxy
663
+ selected_file = @current_tab_item&.swt_tab_item&.getData('file')
664
+ if selected_file
665
+ project_dir.selected_child = selected_file
666
+ @current_tab_item = @current_tab_folder.swt_widget.getSelection.first.getData('proxy')
667
+ @current_tab_folder.swt_widget.setData('selected_tab_item', @current_tab_item) #TODO see if we can get rid of this as it seems redundant
668
+ @current_text_editor = @current_tab_item.swt_tab_item.getData('text_editor')
669
+ @current_text_editor&.load_content
670
+ @current_text_editor&.text_widget&.setFocus
671
+ end
672
+ }
673
+ drag_source(DND::DROP_COPY) {
674
+ transfer [TextTransfer.getInstance].to_java(Transfer)
675
+ event_data = nil
676
+ on_drag_start {|event|
677
+ Gladiator.drag = true
678
+ tab_folder = event.widget.getControl
679
+ tab_item = tab_folder.getItem(Point.new(event.x, event.y))
680
+ event_data = tab_item.getData('file_path')
681
+ }
682
+ on_drag_set_data { |event|
683
+ event.data = event_data
684
+ }
685
+ }
686
+ }
687
+ end
669
688
 
670
689
  def load_config_ignore_paths
671
690
  # TODO eliminate duplication with load_config
@@ -759,11 +778,11 @@ module Glimmer
759
778
  return if child.nil?
760
779
  tab_folder1 = @tab_folder1 || @current_tab_folder
761
780
  tab_folder2 = @tab_folder2
762
- open_file_paths1 = tab_folder1&.swt_widget&.items.to_a.map {|i| i.get_data('file_path')}
763
- open_file_paths2 = tab_folder2&.swt_widget&.items.to_a.map {|i| i.get_data('file_path')}
781
+ open_file_paths1 = tab_folder1&.swt_widget&.items.to_a.map {|i| i.get_data('file_path')}.reject {|path| path.to_s.strip.empty?}
782
+ open_file_paths2 = tab_folder2&.swt_widget&.items.to_a.map {|i| i.get_data('file_path')}.reject {|path| path.to_s.strip.empty?}
764
783
  split_orientation_value = split_orientation == swt(:horizontal) ? 'horizontal' : (split_orientation == swt(:vertical) ? 'vertical' : nil)
765
784
  @config = {
766
- selected_child_path: child.path,
785
+ selected_child_path: child.nil? ? open_file_paths1&.first&.path : child.path,
767
786
  split_orientation: split_orientation_value,
768
787
  caret_position: child.caret_position,
769
788
  top_pixel: child.top_pixel,
@@ -966,16 +985,18 @@ module Glimmer
966
985
  # async_exec { current_text_editor&.text_widget&.setFocus }
967
986
  end
968
987
  end
969
- elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == ']'
988
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == ']' || Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :ctrl) && key_event.keyCode == swt(:page_down)
970
989
  current_tab_folder.swt_widget.setSelection((current_tab_folder.swt_widget.getSelectionIndex() + 1) % current_tab_folder.swt_widget.getItemCount) if current_tab_folder.swt_widget.getItemCount > 0
971
990
  current_text_editor&.text_widget&.setFocus
972
- elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == '['
991
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == '[' || Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :ctrl) && key_event.keyCode == swt(:page_up)
973
992
  current_tab_folder.swt_widget.setSelection((current_tab_folder.swt_widget.getSelectionIndex() - 1) % current_tab_folder.swt_widget.getItemCount) if current_tab_folder.swt_widget.getItemCount > 0
974
993
  current_text_editor&.text_widget&.setFocus
975
- elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :ctrl) && extract_char(key_event) == ']'
994
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, CONTROL_KEY) && extract_char(key_event) == ']'
976
995
  navigate_to_next_tab_folder
977
- elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :ctrl) && extract_char(key_event) == '['
996
+ key_event.doit = false
997
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, CONTROL_KEY) && extract_char(key_event) == '['
978
998
  navigate_to_previous_tab_folder
999
+ key_event.doit = false
979
1000
  elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '1'
980
1001
  current_tab_folder.swt_widget.setSelection(0) if current_tab_folder.swt_widget.getItemCount >= 1
981
1002
  current_text_editor&.text_widget&.setFocus
@@ -1,244 +1,244 @@
1
- # Copyright (c) 2020-2021 Andy Maleh
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining
4
- # a copy of this software and associated documentation files (the
5
- # "Software"), to deal in the Software without restriction, including
6
- # without limitation the rights to use, copy, modify, merge, publish,
7
- # distribute, sublicense, and/or sell copies of the Software, and to
8
- # permit persons to whom the Software is furnished to do so, subject to
9
- # the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be
12
- # included in all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
-
22
- module Glimmer
23
- class Gladiator
24
- class FileExplorerTree
25
- include Glimmer::UI::CustomWidget
26
-
27
- options :gladiator, :foreground_color
28
-
29
- body {
30
- tree {
31
- #visible bind(self, 'project_dir.filter') {|f| !f}
32
- items bind(self, :project_dir), tree_properties(children: :children, text: :name)
33
- foreground foreground_color
34
- drag_source(:drop_copy) {
35
- transfer :text
36
- on_drag_set_data { |event|
37
- Gladiator.drag = true
38
- tree = event.widget.getControl
39
- tree_item = tree.getSelection.first
40
- event.data = tree_item.getData.path
41
- }
42
- }
43
-
44
- menu {
45
- @open_menu_item = menu_item {
46
- text 'Open'
47
- on_widget_selected {
48
- project_dir.selected_child_path = extract_tree_item_path(swt_widget.getSelection.first)
49
- }
50
- }
51
- menu_item(:separator)
52
- menu_item {
53
- text 'Delete'
54
- on_widget_selected {
55
- tree_item = swt_widget.getSelection.first
56
- delete_tree_item(tree_item)
57
- }
58
- }
59
- menu_item {
60
- text 'Refresh'
61
- on_widget_selected {
62
- project_dir.refresh
63
- }
64
- }
65
- menu_item {
66
- text 'Rename'
67
- on_widget_selected {
68
- rename_selected_tree_item
69
- }
70
- }
71
- menu_item {
72
- text 'New Directory'
73
- on_widget_selected {
74
- add_new_directory_to_selected_tree_item
75
- }
76
- }
77
- menu_item {
78
- text 'New File'
79
- on_widget_selected {
80
- add_new_file_to_selected_tree_item
81
- }
82
- }
83
- }
84
-
85
- on_swt_menudetect { |event|
86
- path = extract_tree_item_path(swt_widget.getSelection.first)
87
- @open_menu_item.swt_widget.setEnabled(!::Dir.exist?(path)) if path
88
- }
89
- on_mouse_up {
90
- if Gladiator.drag_and_drop
91
- Gladiator.drag_and_drop = false
92
- else
93
- project_dir.selected_child_path = extract_tree_item_path(swt_widget.getSelection&.first)
94
- gladiator.current_text_editor&.text_widget&.setFocus
95
- end
96
- }
97
- on_key_pressed { |key_event|
98
- if Glimmer::SWT::SWTProxy.include?(key_event.keyCode, :cr)
99
- project_dir.selected_child_path = extract_tree_item_path(swt_widget.getSelection&.first)
100
- gladiator.current_text_editor&.text_widget&.setFocus
101
- end
102
- }
103
- on_paint_control {
104
- root_item = swt_widget.getItems.first
105
- if root_item && !root_item.getExpanded
106
- root_item.setExpanded(true)
107
- end
108
- }
109
-
110
- }
111
- }
112
-
113
- def project_dir
114
- gladiator.project_dir
115
- end
116
-
117
- def current_text_editor
118
- gladiator.current_text_editor
119
- end
120
-
121
- def extract_tree_item_path(tree_item)
122
- return if tree_item.nil?
123
- if tree_item.getParentItem
124
- ::File.join(extract_tree_item_path(tree_item.getParentItem), tree_item.getText)
125
- else
126
- project_dir.path
127
- end
128
- end
129
-
130
- def select_tree_item
131
- return unless project_dir.selected_child&.name
132
- tree_items_to_select = body_root.depth_first_search { |ti| ti.getData.path == project_dir.selected_child.path }
133
- swt_widget.setSelection(tree_items_to_select)
134
- end
135
-
136
- def delete_tree_item(tree_item)
137
- return if tree_item.nil?
138
- file = tree_item.getData
139
- parent_path = ::File.dirname(file.path)
140
- if file.is_a?(Gladiator::Dir)
141
- file_paths = file.all_children.select {|f| f.is_a?(Gladiator::File)}.map(&:path)
142
- file.remove_all_observers
143
- else
144
- file_paths = [file.path]
145
- end
146
- file_paths.each do |file_path|
147
- found_tab_item = gladiator.find_tab_item(file_path)
148
- if found_tab_item
149
- project_dir.selected_child_path_history.delete(found_tab_item.getData('file_path'))
150
- found_tab_item.getData('proxy')&.dispose
151
- end
152
- end
153
- file.delete! # TODO consider supporting command undo/redo
154
- project_dir.refresh(async: false)
155
- parent_tree_item = body_root.depth_first_search {|ti| ti.getData.path == parent_path}.first
156
- swt_widget.showItem(parent_tree_item)
157
- parent_tree_item.setExpanded(true)
158
- rescue => e
159
- puts e.full_message
160
- end
161
-
162
- def add_new_directory_to_selected_tree_item
163
- project_dir.pause_refresh
164
- tree_item = swt_widget.getSelection.first
165
- directory_path = extract_tree_item_path(tree_item)
166
- return if directory_path.nil?
167
- if !::Dir.exist?(directory_path)
168
- tree_item = tree_item.getParentItem
169
- directory_path = ::File.dirname(directory_path)
170
- end
171
- new_directory_path = ::File.expand_path(::File.join(directory_path, 'new_directory'))
172
- FileUtils.mkdir_p(new_directory_path)
173
- project_dir.refresh(async: false, force: true)
174
- new_tree_item = body_root.depth_first_search {|ti| ti.getData.path == new_directory_path}.first
175
- swt_widget.showItem(new_tree_item)
176
- rename_tree_item(new_tree_item)
177
- end
178
-
179
- def add_new_file_to_selected_tree_item
180
- project_dir.pause_refresh
181
- tree_item = swt_widget.getSelection.first
182
- directory_path = extract_tree_item_path(tree_item)
183
- if !::Dir.exist?(directory_path)
184
- tree_item = tree_item.getParentItem
185
- directory_path = ::File.dirname(directory_path)
186
- end
187
- new_file_path = ::File.expand_path(::File.join(directory_path, 'new_file'))
188
- FileUtils.touch(new_file_path)
189
- # TODO look into refreshing only the parent directory to avoid slowdown
190
- project_dir.refresh(async: false, force: true)
191
- new_tree_item = body_root.depth_first_search {|ti| ti.getData.path == new_file_path}.first
192
- swt_widget.showItem(new_tree_item)
193
- rename_tree_item(new_tree_item, true)
194
- end
195
-
196
- def rename_selected_tree_item
197
- project_dir.pause_refresh
198
- tree_item = swt_widget.getSelection.first
199
- rename_tree_item(tree_item)
200
- end
201
-
202
- def rename_tree_item(tree_item, new_file = false)
203
- original_file = tree_item.getData
204
- current_file = project_dir.selected_child_path == original_file.path
205
- found_tab_item = gladiator.find_tab_item(original_file.path)
206
- found_text_editor = found_tab_item&.getData('text_editor')
207
- body_root.edit_tree_item(
208
- tree_item,
209
- after_write: -> (edited_tree_item) {
210
- file = edited_tree_item.getData
211
- file_path = file.path
212
- file.name
213
- if ::File.file?(file_path)
214
- if new_file
215
- project_dir.selected_child_path = file_path
216
- else
217
- found_text_editor&.file = file
218
- found_tab_item&.setData('file', file)
219
- found_tab_item&.setData('file_path', file.path)
220
- found_tab_item&.setText(file.name)
221
- body_root.pack_same_size
222
- if current_file
223
- project_dir.selected_child_path = file_path
224
- else
225
- selected_tab_item&.getData('text_editor')&.text_widget&.setFocus
226
- end
227
- async_exec {
228
- swt_widget.showItem(edited_tree_item)
229
- }
230
- end
231
- end
232
- project_dir.resume_refresh
233
- },
234
- after_cancel: -> {
235
- project_dir.resume_refresh
236
- }
237
- )
238
- end
239
-
240
- end
241
-
242
- end
243
-
244
- end
1
+ # Copyright (c) 2020-2021 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ module Glimmer
23
+ class Gladiator
24
+ class FileExplorerTree
25
+ include Glimmer::UI::CustomWidget
26
+
27
+ options :gladiator, :foreground_color
28
+
29
+ body {
30
+ tree {
31
+ #visible bind(self, 'project_dir.filter') {|f| !f}
32
+ items bind(self, :project_dir), tree_properties(children: :children, text: :name)
33
+ foreground foreground_color
34
+ drag_source(:drop_copy) {
35
+ transfer :text
36
+ on_drag_set_data { |event|
37
+ Gladiator.drag = true
38
+ tree = event.widget.getControl
39
+ tree_item = tree.getSelection.first
40
+ event.data = tree_item.getData.path
41
+ }
42
+ }
43
+
44
+ menu {
45
+ @open_menu_item = menu_item {
46
+ text 'Open'
47
+ on_widget_selected {
48
+ project_dir.selected_child_path = extract_tree_item_path(swt_widget.getSelection.first)
49
+ }
50
+ }
51
+ menu_item(:separator)
52
+ menu_item {
53
+ text 'Delete'
54
+ on_widget_selected {
55
+ tree_item = swt_widget.getSelection.first
56
+ delete_tree_item(tree_item)
57
+ }
58
+ }
59
+ menu_item {
60
+ text 'Refresh'
61
+ on_widget_selected {
62
+ project_dir.refresh
63
+ }
64
+ }
65
+ menu_item {
66
+ text 'Rename'
67
+ on_widget_selected {
68
+ rename_selected_tree_item
69
+ }
70
+ }
71
+ menu_item {
72
+ text 'New Directory'
73
+ on_widget_selected {
74
+ add_new_directory_to_selected_tree_item
75
+ }
76
+ }
77
+ menu_item {
78
+ text 'New File'
79
+ on_widget_selected {
80
+ add_new_file_to_selected_tree_item
81
+ }
82
+ }
83
+ }
84
+
85
+ on_swt_menudetect { |event|
86
+ path = extract_tree_item_path(swt_widget.getSelection.first)
87
+ @open_menu_item.swt_widget.setEnabled(!::Dir.exist?(path)) if path
88
+ }
89
+ on_mouse_up {
90
+ if Gladiator.drag_and_drop
91
+ Gladiator.drag_and_drop = false
92
+ else
93
+ project_dir.selected_child_path = extract_tree_item_path(swt_widget.getSelection&.first)
94
+ gladiator.current_text_editor&.text_widget&.setFocus
95
+ end
96
+ }
97
+ on_key_pressed { |key_event|
98
+ if Glimmer::SWT::SWTProxy.include?(key_event.keyCode, :cr)
99
+ project_dir.selected_child_path = extract_tree_item_path(swt_widget.getSelection&.first)
100
+ gladiator.current_text_editor&.text_widget&.setFocus
101
+ end
102
+ }
103
+ on_paint_control {
104
+ root_item = swt_widget.getItems.first
105
+ if root_item && !root_item.getExpanded
106
+ root_item.setExpanded(true)
107
+ end
108
+ }
109
+
110
+ }
111
+ }
112
+
113
+ def project_dir
114
+ gladiator.project_dir
115
+ end
116
+
117
+ def current_text_editor
118
+ gladiator.current_text_editor
119
+ end
120
+
121
+ def extract_tree_item_path(tree_item)
122
+ return if tree_item.nil?
123
+ if tree_item.getParentItem
124
+ ::File.join(extract_tree_item_path(tree_item.getParentItem), tree_item.getText)
125
+ else
126
+ project_dir.path
127
+ end
128
+ end
129
+
130
+ def select_tree_item
131
+ return unless project_dir.selected_child&.name
132
+ tree_items_to_select = body_root.depth_first_search { |ti| ti.getData.path == project_dir.selected_child.path }
133
+ swt_widget.setSelection(tree_items_to_select)
134
+ end
135
+
136
+ def delete_tree_item(tree_item)
137
+ return if tree_item.nil?
138
+ file = tree_item.getData
139
+ parent_path = ::File.dirname(file.path)
140
+ if file.is_a?(Gladiator::Dir)
141
+ file_paths = file.all_children.select {|f| f.is_a?(Gladiator::File)}.map(&:path)
142
+ file.remove_all_observers
143
+ else
144
+ file_paths = [file.path]
145
+ end
146
+ file_paths.each do |file_path|
147
+ found_tab_item = gladiator.find_tab_item(file_path)
148
+ if found_tab_item
149
+ project_dir.selected_child_path_history.delete(found_tab_item.getData('file_path'))
150
+ found_tab_item.getData('proxy')&.dispose
151
+ end
152
+ end
153
+ file.delete! # TODO consider supporting command undo/redo
154
+ project_dir.refresh(async: false)
155
+ parent_tree_item = body_root.depth_first_search {|ti| ti.getData.path == parent_path}.first
156
+ swt_widget.showItem(parent_tree_item)
157
+ parent_tree_item.setExpanded(true)
158
+ rescue => e
159
+ puts e.full_message
160
+ end
161
+
162
+ def add_new_directory_to_selected_tree_item
163
+ project_dir.pause_refresh
164
+ tree_item = swt_widget.getSelection.first
165
+ directory_path = extract_tree_item_path(tree_item)
166
+ return if directory_path.nil?
167
+ if !::Dir.exist?(directory_path)
168
+ tree_item = tree_item.getParentItem
169
+ directory_path = ::File.dirname(directory_path)
170
+ end
171
+ new_directory_path = ::File.expand_path(::File.join(directory_path, 'new_directory'))
172
+ FileUtils.mkdir_p(new_directory_path)
173
+ project_dir.refresh(async: false, force: true)
174
+ new_tree_item = body_root.depth_first_search {|ti| ti.getData.path == new_directory_path}.first
175
+ swt_widget.showItem(new_tree_item)
176
+ rename_tree_item(new_tree_item)
177
+ end
178
+
179
+ def add_new_file_to_selected_tree_item
180
+ project_dir.pause_refresh
181
+ tree_item = swt_widget.getSelection.first
182
+ directory_path = extract_tree_item_path(tree_item)
183
+ if !::Dir.exist?(directory_path)
184
+ tree_item = tree_item.getParentItem
185
+ directory_path = ::File.dirname(directory_path)
186
+ end
187
+ new_file_path = ::File.expand_path(::File.join(directory_path, 'new_file'))
188
+ FileUtils.touch(new_file_path)
189
+ # TODO look into refreshing only the parent directory to avoid slowdown
190
+ project_dir.refresh(async: false, force: true)
191
+ new_tree_item = body_root.depth_first_search {|ti| ti.getData.path == new_file_path}.first
192
+ swt_widget.showItem(new_tree_item)
193
+ rename_tree_item(new_tree_item, true)
194
+ end
195
+
196
+ def rename_selected_tree_item
197
+ project_dir.pause_refresh
198
+ tree_item = swt_widget.getSelection.first
199
+ rename_tree_item(tree_item)
200
+ end
201
+
202
+ def rename_tree_item(tree_item, new_file = false)
203
+ original_file = tree_item.getData
204
+ current_file = project_dir.selected_child_path == original_file.path
205
+ found_tab_item = gladiator.find_tab_item(original_file.path)
206
+ found_text_editor = found_tab_item&.getData('text_editor')
207
+ body_root.edit_tree_item(
208
+ tree_item,
209
+ after_write: -> (edited_tree_item) {
210
+ file = edited_tree_item.getData
211
+ file_path = file.path
212
+ file.name
213
+ if ::File.file?(file_path)
214
+ if new_file
215
+ project_dir.selected_child_path = file_path
216
+ else
217
+ found_text_editor&.file = file
218
+ found_tab_item&.setData('file', file)
219
+ found_tab_item&.setData('file_path', file.path)
220
+ found_tab_item&.setText(file.name)
221
+ body_root.pack_same_size
222
+ if current_file
223
+ project_dir.selected_child_path = file_path
224
+ else
225
+ selected_tab_item&.getData('text_editor')&.text_widget&.setFocus
226
+ end
227
+ async_exec {
228
+ swt_widget.showItem(edited_tree_item)
229
+ }
230
+ end
231
+ end
232
+ project_dir.resume_refresh
233
+ },
234
+ after_cancel: -> {
235
+ project_dir.resume_refresh
236
+ }
237
+ )
238
+ end
239
+
240
+ end
241
+
242
+ end
243
+
244
+ end