Class: Glimmer::SWT::TableProxy

Inherits:
WidgetProxy show all
Includes:
Glimmer
Defined in:
lib/glimmer/swt/table_proxy.rb

Defined Under Namespace

Modules: TableListenerEvent

Constant Summary

Constants inherited from WidgetProxy

WidgetProxy::DEFAULT_INITIALIZERS, WidgetProxy::DEFAULT_STYLES

Instance Attribute Summary collapse

Attributes inherited from WidgetProxy

#drag_source_proxy, #drag_source_style, #drag_source_transfer, #drop_target_proxy, #drop_target_transfer, #swt_widget

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Glimmer

included

Methods inherited from WidgetProxy

#add_observer, #async_exec, #can_add_observer?, #can_handle_drag_observation_request?, #can_handle_drop_observation_request?, #can_handle_observation_request?, #content, #dispose, #ensure_drag_source_proxy, #ensure_drop_target_proxy, #extract_args, #get_attribute, #handle_observation_request, #has_attribute?, #has_style?, #method_missing, #pack_same_size, #remove_observer, #respond_to?, #set_attribute, swt_widget_class_for, #sync_exec, widget_exists?

Methods included from Packages

included

Constructor Details

#initialize(underscored_widget_name, parent, args) ⇒ TableProxy

Returns a new instance of TableProxy.



96
97
98
99
100
101
102
# File 'lib/glimmer/swt/table_proxy.rb', line 96

def initialize(underscored_widget_name, parent, args)
  super
  @table_editor = TableEditor.new(swt_widget)
  @table_editor.horizontalAlignment = SWTProxy[:left]
  @table_editor.grabHorizontal = true
  @table_editor.minimumHeight = 20
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Glimmer::SWT::WidgetProxy

Instance Attribute Details

#additional_sort_propertiesObject

Returns the value of attribute additional_sort_properties.



93
94
95
# File 'lib/glimmer/swt/table_proxy.rb', line 93

def additional_sort_properties
  @additional_sort_properties
end

#column_propertiesObject

Returns the value of attribute column_properties.



94
95
96
# File 'lib/glimmer/swt/table_proxy.rb', line 94

def column_properties
  @column_properties
end

#editorObject

Returns the value of attribute editor.



93
94
95
# File 'lib/glimmer/swt/table_proxy.rb', line 93

def editor
  @editor
end

#sort_blockObject (readonly)

Returns the value of attribute sort_block.



93
94
95
# File 'lib/glimmer/swt/table_proxy.rb', line 93

def sort_block
  @sort_block
end

#sort_by_blockObject (readonly)

Returns the value of attribute sort_by_block.



93
94
95
# File 'lib/glimmer/swt/table_proxy.rb', line 93

def sort_by_block
  @sort_by_block
end

#sort_directionObject (readonly)

Returns the value of attribute sort_direction.



93
94
95
# File 'lib/glimmer/swt/table_proxy.rb', line 93

def sort_direction
  @sort_direction
end

#sort_propertyObject (readonly)

Returns the value of attribute sort_property.



93
94
95
# File 'lib/glimmer/swt/table_proxy.rb', line 93

def sort_property
  @sort_property
end

#sort_typeObject (readonly)

Returns the value of attribute sort_type.



93
94
95
# File 'lib/glimmer/swt/table_proxy.rb', line 93

def sort_type
  @sort_type
end

#table_editorObject (readonly)

Returns the value of attribute table_editor.



93
94
95
# File 'lib/glimmer/swt/table_proxy.rb', line 93

def table_editor
  @table_editor
end

#table_editor_widget_proxyObject (readonly)

Returns the value of attribute table_editor_widget_proxy.



93
94
95
# File 'lib/glimmer/swt/table_proxy.rb', line 93

def table_editor_widget_proxy
  @table_editor_widget_proxy
end

Class Method Details

.editorsObject



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/glimmer/swt/table_proxy.rb', line 37

def editors
  @editors ||= {
    text: {
      widget_value_property: :text,
      editor_gui: lambda do |args, model, property, table_proxy|
        table_proxy.table_editor.minimumHeight = 20
        table_editor_widget_proxy = text(*args) {
          text model.send(property)
          focus true
          on_focus_lost {
            table_proxy.finish_edit!
          }
          on_key_pressed { |key_event|
            if key_event.keyCode == swt(:cr)
              table_proxy.finish_edit!
            elsif key_event.keyCode == swt(:esc)
              table_proxy.cancel_edit!
            end
          }              
        }
        table_editor_widget_proxy.swt_widget.selectAll          
        table_editor_widget_proxy
      end,
    },
    combo: {
      widget_value_property: :text,
      editor_gui: lambda do |args, model, property, table_proxy|
        first_time = true
        table_proxy.table_editor.minimumHeight = 25
        table_editor_widget_proxy = combo(*args) {
          items model.send("#{property}_options")
          text model.send(property)
          focus true
          on_focus_lost {
            table_proxy.finish_edit!
          }
          on_key_pressed { |key_event|
            if key_event.keyCode == swt(:cr)
              table_proxy.finish_edit!
            elsif key_event.keyCode == swt(:esc)
              table_proxy.cancel_edit!
            end
          }
          on_widget_selected {
            if !OS.windows? || !first_time || first_time && model.send(property) != table_editor_widget_proxy.swt_widget.text
              table_proxy.finish_edit! 
            end 
          }
        }
        table_editor_widget_proxy
      end,
    }
  }      
end

Instance Method Details

#add_listener(underscored_listener_name, &block) ⇒ Object



307
308
309
310
311
312
313
# File 'lib/glimmer/swt/table_proxy.rb', line 307

def add_listener(underscored_listener_name, &block)
  enhanced_block = lambda do |event|
    event.extend(TableListenerEvent)
    block.call(event)
  end
  super(underscored_listener_name, &enhanced_block)
end

#all_table_itemsObject

Returns all table items including descendants



200
201
202
# File 'lib/glimmer/swt/table_proxy.rb', line 200

def all_table_items
  search
end

#cancel_edit!Object



229
230
231
# File 'lib/glimmer/swt/table_proxy.rb', line 229

def cancel_edit!
  @cancel_edit&.call if @edit_mode
end

#detect_sort_typeObject



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/glimmer/swt/table_proxy.rb', line 140

def detect_sort_type
  @sort_type = sort_property.size.times.map { String }
  array = model_binding.evaluate_property
  sort_property.each_with_index do |a_sort_property, i|
    values = array.map { |object| object.send(a_sort_property) }
    value_classes = values.map(&:class).uniq
    if value_classes.size == 1
      @sort_type[i] = value_classes.first
    elsif value_classes.include?(Integer)
      @sort_type[i] = Integer
    elsif value_classes.include?(Float)
      @sort_type[i] = Float
    end
  end
end

#edit_in_progress?Boolean

Indicates if table is editing a table item because the user hit ENTER or focused out after making a change in edit mode to a table item cell. It is set to false once change is saved to model

Returns:

  • (Boolean)


239
240
241
# File 'lib/glimmer/swt/table_proxy.rb', line 239

def edit_in_progress?
  !!@edit_in_progress
end

#edit_mode?Boolean

Indicates if table is in edit mode, thus displaying a text widget for a table item cell

Returns:

  • (Boolean)


225
226
227
# File 'lib/glimmer/swt/table_proxy.rb', line 225

def edit_mode?
  !!@edit_mode
end

#edit_selected_table_item(column_index, before_write: nil, after_write: nil, after_cancel: nil) ⇒ Object



243
244
245
# File 'lib/glimmer/swt/table_proxy.rb', line 243

def edit_selected_table_item(column_index, before_write: nil, after_write: nil, after_cancel: nil)
  edit_table_item(swt_widget.getSelection.first, column_index, before_write: before_write, after_write: after_write, after_cancel: after_cancel)
end

#edit_table_item(table_item, column_index, before_write: nil, after_write: nil, after_cancel: nil) ⇒ Object



247
248
249
250
251
252
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
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/glimmer/swt/table_proxy.rb', line 247

def edit_table_item(table_item, column_index, before_write: nil, after_write: nil, after_cancel: nil)
  return if table_item.nil?
  model = table_item.data
  property = column_properties[column_index]
  @cancel_edit&.call if @edit_mode
  action_taken = false
  @edit_mode = true
  
  editor_config = table_column_proxies[column_index].editor || editor
  editor_config = editor_config.to_a
  editor_widget_options = editor_config.last.is_a?(Hash) ? editor_config.last : {}
  editor_widget_arg_last_index = editor_config.last.is_a?(Hash) ? -2 : -1
  editor_widget = editor_config[0] || :text
  editor_widget_args = editor_config[1..editor_widget_arg_last_index]
  model_editing_property = editor_widget_options[:property] || property
  widget_value_property = TableProxy::editors[editor_widget][:widget_value_property]
  
  @cancel_edit = lambda do |event=nil|
    @cancel_in_progress = true
    @table_editor_widget_proxy&.swt_widget&.dispose
    @table_editor_widget_proxy = nil
    after_cancel&.call
    @edit_in_progress = false
    @cancel_in_progress = false
    @cancel_edit = nil
    @edit_mode = false
  end
  
  @finish_edit = lambda do |event=nil|
    new_value = @table_editor_widget_proxy&.swt_widget&.send(widget_value_property)
    if table_item.isDisposed
      @cancel_edit.call
    elsif new_value && !action_taken && !@edit_in_progress && !@cancel_in_progress
      action_taken = true
      @edit_in_progress = true
      if new_value == model.send(model_editing_property)
        @cancel_edit.call
      else
        before_write&.call
        model.send("#{model_editing_property}=", new_value) # makes table update itself, so must search for selected table item again
        # Table refresh happens here because of model update triggering observers, so must retrieve table item again
        edited_table_item = search { |ti| ti.getData == model }.first
        swt_widget.showItem(edited_table_item)
        @table_editor_widget_proxy&.swt_widget&.dispose
        @table_editor_widget_proxy = nil
        after_write&.call(edited_table_item)              
        @edit_in_progress = false
      end
    end
  end

  content { 
    @table_editor_widget_proxy = TableProxy::editors[editor_widget][:editor_gui].call(editor_widget_args, model, model_editing_property, self)
  }
  @table_editor.setEditor(@table_editor_widget_proxy.swt_widget, table_item, column_index)
rescue => e
  Glimmer::Config.logger.error {e.full_message}
  raise e
end

#finish_edit!Object



233
234
235
# File 'lib/glimmer/swt/table_proxy.rb', line 233

def finish_edit!
  @finish_edit&.call if @edit_mode
end

#model_bindingObject



104
105
106
# File 'lib/glimmer/swt/table_proxy.rb', line 104

def model_binding
  swt_widget.data
end

#post_initialize_child(table_column_proxy) ⇒ Object



216
217
218
# File 'lib/glimmer/swt/table_proxy.rb', line 216

def post_initialize_child(table_column_proxy)
  table_column_proxies << table_column_proxy
end

#search(&condition) ⇒ Object

Performs a search for table items matching block condition If no condition block is passed, returns all table items Returns a Java TableItem array to easily set as selection on org.eclipse.swt.Table if needed



195
196
197
# File 'lib/glimmer/swt/table_proxy.rb', line 195

def search(&condition)
  swt_widget.getItems.select {|item| condition.nil? || condition.call(item)}.to_java(TableItem)
end

#sortObject



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
# File 'lib/glimmer/swt/table_proxy.rb', line 164

def sort
  return unless sort_property && (sort_type || sort_block || sort_by_block)
  array = model_binding.evaluate_property
  # Converting value to_s first to handle nil cases. Should work with numeric, boolean, and date fields
  if sort_block
    sorted_array = array.sort(&sort_block)
  elsif sort_by_block
    sorted_array = array.sort_by(&sort_by_block)          
  else
    sorted_array = array.sort_by do |object|
      sort_property.each_with_index.map do |a_sort_property, i|
        value = object.send(a_sort_property)
        # handle nil and difficult to compare types gracefully
        if sort_type[i] == Integer
          value = value.to_i
        elsif sort_type[i] == Float
          value = value.to_f
        elsif sort_type[i] == String
          value = value.to_s
        end
        value
      end
    end
  end
  sorted_array = sorted_array.reverse if sort_direction == :descending
  model_binding.call(sorted_array)
end

#sort_by_column(table_column_proxy) ⇒ Object



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/glimmer/swt/table_proxy.rb', line 108

def sort_by_column(table_column_proxy)
  index = swt_widget.columns.to_a.index(table_column_proxy.swt_widget)
  new_sort_property = table_column_proxy.sort_property || [column_properties[index]]
  if new_sort_property.size == 1 && !additional_sort_properties.to_a.empty?
    selected_additional_sort_properties = additional_sort_properties.clone
    if selected_additional_sort_properties.include?(new_sort_property.first)
      selected_additional_sort_properties.delete(new_sort_property.first)
      new_sort_property += selected_additional_sort_properties
    else
      new_sort_property += additional_sort_properties
    end
  end
  
  @sort_direction = @sort_direction.nil? || @sort_property != new_sort_property || @sort_direction == :descending ? :ascending : :descending        
  swt_widget.sort_direction = @sort_direction == :ascending ? SWTProxy[:up] : SWTProxy[:down]
  
  @sort_property = new_sort_property
  swt_widget.sort_column = table_column_proxy.swt_widget
  
  @sort_by_block = nil
  @sort_block = nil
  @sort_type = nil
  if table_column_proxy.sort_by_block
    @sort_by_block = table_column_proxy.sort_by_block
  elsif table_column_proxy.sort_block
    @sort_block = table_column_proxy.sort_block
  else
    detect_sort_type        
  end
  sort
end

#table_column_proxiesObject



220
221
222
# File 'lib/glimmer/swt/table_proxy.rb', line 220

def table_column_proxies
  @table_column_proxies ||= []
end

#widget_property_listener_installersObject



204
205
206
207
208
209
210
211
212
213
214
# File 'lib/glimmer/swt/table_proxy.rb', line 204

def widget_property_listener_installers
  super.merge({
    Java::OrgEclipseSwtWidgets::Table => {
      selection: lambda do |observer|
        on_widget_selected { |selection_event|
          observer.call(@swt_widget.getSelection)
        }
      end
    },        
  })
end