clevic 0.12.0 → 0.13.0.b1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. data/History.txt +10 -0
  2. data/Manifest.txt +209 -30
  3. data/README.txt +16 -20
  4. data/Rakefile +8 -8
  5. data/TODO +6 -7
  6. data/bin/clevic +12 -73
  7. data/lib/clevic/action_builder.rb +168 -0
  8. data/lib/clevic/ar_methods.rb +120 -0
  9. data/lib/clevic/attribute_list.rb +56 -0
  10. data/lib/clevic/cache_table.rb +60 -37
  11. data/lib/clevic/default_view.rb +3 -16
  12. data/lib/clevic/delegate.rb +46 -0
  13. data/lib/clevic/emitter.rb +38 -0
  14. data/lib/clevic/extensions.rb +61 -114
  15. data/lib/clevic/field.rb +159 -228
  16. data/lib/clevic/field_valuer.rb +165 -0
  17. data/lib/clevic/filter_command.rb +2 -6
  18. data/lib/clevic/generic_format.rb +52 -0
  19. data/lib/clevic/{ui → icons}/icon.png +0 -0
  20. data/lib/clevic/many_field.rb +7 -0
  21. data/lib/clevic/model_builder.rb +234 -146
  22. data/lib/clevic/model_column.rb +61 -13
  23. data/lib/clevic/order_attribute.rb +10 -0
  24. data/lib/clevic/qt.rb +35 -0
  25. data/lib/clevic/qt/action_builder.rb +47 -0
  26. data/lib/clevic/qt/boolean_delegate.rb +8 -0
  27. data/lib/clevic/{browser.rb → qt/browser.rb} +35 -14
  28. data/lib/clevic/qt/clipboard.rb +35 -0
  29. data/lib/clevic/qt/combo_delegate.rb +198 -0
  30. data/lib/clevic/qt/delegates.rb +1 -0
  31. data/lib/clevic/qt/distinct_delegate.rb +35 -0
  32. data/lib/clevic/qt/extensions.rb +52 -0
  33. data/lib/clevic/qt/field.rb +18 -0
  34. data/lib/clevic/{item_delegate.rb → qt/item_delegate.rb} +8 -4
  35. data/lib/clevic/qt/relational_delegate.rb +87 -0
  36. data/lib/clevic/{search_dialog.rb → qt/search_dialog.rb} +1 -11
  37. data/lib/clevic/qt/set_delegate.rb +44 -0
  38. data/lib/clevic/qt/table_model.rb +331 -0
  39. data/lib/clevic/qt/table_view.rb +344 -0
  40. data/lib/clevic/qt/text_area_delegate.rb +8 -0
  41. data/lib/clevic/{text_delegate.rb → qt/text_delegate.rb} +6 -4
  42. data/lib/clevic/{ui → qt/ui}/.gitignore +0 -0
  43. data/lib/clevic/{ui → qt/ui}/browser.ui +0 -0
  44. data/lib/clevic/{ui → qt/ui}/search_dialog.ui +0 -0
  45. data/lib/clevic/rails_models_loaders.rb +56 -0
  46. data/lib/clevic/record.rb +2 -17
  47. data/lib/clevic/sampler.rb +81 -0
  48. data/lib/clevic/sequel_ar_adapter.rb +215 -0
  49. data/lib/clevic/sequel_length_validation.rb +23 -0
  50. data/lib/clevic/sequel_meta.rb +65 -0
  51. data/lib/clevic/sequel_naked.rb +30 -0
  52. data/lib/clevic/swing.rb +38 -0
  53. data/lib/clevic/swing/action.rb +125 -0
  54. data/lib/clevic/swing/action_builder.rb +47 -0
  55. data/lib/clevic/swing/boolean_delegate.rb +26 -0
  56. data/lib/clevic/swing/browser.rb +282 -0
  57. data/lib/clevic/swing/cell_editor.rb +95 -0
  58. data/lib/clevic/swing/cell_renderer.rb +44 -0
  59. data/lib/clevic/swing/clipboard.rb +135 -0
  60. data/lib/clevic/swing/combo_delegate.rb +336 -0
  61. data/lib/clevic/swing/confirm_dialog.rb +57 -0
  62. data/lib/clevic/swing/delegate.rb +40 -0
  63. data/lib/clevic/swing/distinct_delegate.rb +30 -0
  64. data/lib/clevic/swing/extensions.rb +274 -0
  65. data/lib/clevic/swing/field.rb +35 -0
  66. data/lib/clevic/swing/relational_delegate.rb +48 -0
  67. data/lib/clevic/swing/row_header.rb +210 -0
  68. data/lib/clevic/swing/search_dialog.rb +230 -0
  69. data/lib/clevic/swing/selection_model.rb +90 -0
  70. data/lib/clevic/swing/set_delegate.rb +41 -0
  71. data/lib/clevic/swing/swing_table_index.rb +43 -0
  72. data/lib/clevic/swing/table_model.rb +200 -0
  73. data/lib/clevic/swing/table_view.rb +385 -0
  74. data/lib/clevic/swing/table_view_focus.rb +47 -0
  75. data/lib/clevic/swing/tag_delegate.rb +127 -0
  76. data/lib/clevic/swing/tag_editor.rb +101 -0
  77. data/lib/clevic/swing/text_area_delegate.rb +46 -0
  78. data/lib/clevic/swing/text_delegate.rb +31 -0
  79. data/lib/clevic/swing/ui/build.xml +74 -0
  80. data/lib/clevic/swing/ui/dist/README.TXT +33 -0
  81. data/lib/clevic/swing/ui/dist/lib/swing-layout-1.0.3.jar +0 -0
  82. data/lib/clevic/swing/ui/manifest.mf +3 -0
  83. data/lib/clevic/swing/ui/nbproject/build-impl.xml +731 -0
  84. data/lib/clevic/swing/ui/nbproject/genfiles.properties +8 -0
  85. data/lib/clevic/swing/ui/nbproject/private/config.properties +0 -0
  86. data/lib/clevic/swing/ui/nbproject/private/private.properties +6 -0
  87. data/lib/clevic/swing/ui/nbproject/private/private.xml +4 -0
  88. data/lib/clevic/swing/ui/nbproject/project.properties +70 -0
  89. data/lib/clevic/swing/ui/nbproject/project.xml +14 -0
  90. data/lib/clevic/swing/ui/src/SearchDialog.form +158 -0
  91. data/lib/clevic/swing/ui/src/SearchDialog.java +163 -0
  92. data/lib/clevic/swing/ui/src/TagEditor.form +106 -0
  93. data/lib/clevic/swing/ui/src/TagEditor.java +108 -0
  94. data/lib/clevic/swing/ui/src/resources/SearchDialog.properties +0 -0
  95. data/lib/clevic/table_index.rb +100 -0
  96. data/lib/clevic/table_model.rb +54 -425
  97. data/lib/clevic/table_searcher.rb +113 -116
  98. data/lib/clevic/table_view.rb +171 -399
  99. data/lib/clevic/table_view_paste.rb +199 -0
  100. data/lib/clevic/version.rb +3 -2
  101. data/lib/clevic/view.rb +94 -43
  102. data/models/accounts_models.rb +13 -13
  103. data/models/minimal_models.rb +5 -9
  104. data/models/times_models.rb +19 -14
  105. data/models/times_psql_models.rb +10 -0
  106. data/models/times_sqlite_models.rb +1 -8
  107. data/models/values_models.rb +2 -8
  108. data/tasks/clevic.rake +1 -1
  109. data/tasks/rdoc.rake +1 -5
  110. data/tasks/website.rake +1 -1
  111. data/test/test_cache_table.rb +15 -29
  112. data/test/test_helper.rb +14 -83
  113. data/test/test_order_attribute.rb +1 -1
  114. data/test/test_table_model.rb +0 -21
  115. data/test/test_table_searcher.rb +67 -61
  116. metadata +262 -78
  117. data/lib/clevic.rb +0 -4
  118. data/lib/clevic/db_options.rb +0 -112
  119. data/lib/clevic/delegates.rb +0 -386
@@ -0,0 +1,57 @@
1
+ module Clevic
2
+ # keeps a list of names => results mappings
3
+ # and returns
4
+ class ConfirmDialog
5
+ def initialize
6
+ @names = []
7
+ @results = []
8
+ yield self if block_given?
9
+ end
10
+
11
+ attr_accessor :names, :results, :question, :title, :dialog_result, :parent
12
+
13
+ def to_java( arg )
14
+ @options.keys.to_java( arg )
15
+ end
16
+
17
+ def canonical_results
18
+ @canonical_results ||= [:accept, :reject]
19
+ end
20
+
21
+ # To create a an Ok button that has the focus, and causes
22
+ # the class to return true from accepted?
23
+ # dialog['Ok'] = :accept, true
24
+ #
25
+ # To create a Cancel button that returns true from rejected?
26
+ # dialog['Cancel'] = :reject
27
+ def []=( name, *args )
28
+ result, default = *args.flatten
29
+ raise "Result is not in #{@canonical_results.inspect}" unless canonical_results.include?( result.to_sym )
30
+ names << name.to_s
31
+ results << result.to_sym
32
+ @default = name.to_s if default
33
+ end
34
+
35
+ def accepted?
36
+ results[dialog_result] == :accept
37
+ end
38
+
39
+ def rejected?
40
+ results[dialog_result] == :reject
41
+ end
42
+
43
+ def show
44
+ self.dialog_result = javax.swing.JOptionPane.showOptionDialog(
45
+ parent,
46
+ question,
47
+ title,
48
+ javax.swing.JOptionPane::DEFAULT_OPTION,
49
+ javax.swing.JOptionPane::QUESTION_MESSAGE,
50
+ nil, # icon. Not used here
51
+ names.to_java( :object ),
52
+ @default
53
+ )
54
+ self
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,40 @@
1
+ require 'clevic/delegate'
2
+
3
+ module Clevic
4
+
5
+ class Delegate
6
+ def initialize( field )
7
+ @field = field
8
+ @message_receivers = Set.new
9
+ end
10
+
11
+ def show_message( msg, &block )
12
+ if block_given?
13
+ @message_receivers << block
14
+ else
15
+ @message_receivers.each do |receiver|
16
+ receiver.call( msg )
17
+ end
18
+ end
19
+ end
20
+
21
+ # workaround for broken JTable editing starts
22
+ def needs_pre_selection?
23
+ false
24
+ end
25
+
26
+ # Return something useful if this should use the default GUI framework
27
+ # mechanism for table editing. Default is false, so native framework
28
+ # won't be used. For Java/Swing, this would return the a class object
29
+ # indicating the type of data, eg java.lang.Boolean, or java.lang.String
30
+ # or something from JTable.setDefaultEditor
31
+ def native
32
+ false
33
+ end
34
+
35
+ def inspect
36
+ "<#{self.class.name} native=#{native} needs_pre_selection=#{needs_pre_selection?}>"
37
+ end
38
+ end
39
+
40
+ end
@@ -0,0 +1,30 @@
1
+ require 'clevic/swing/combo_delegate'
2
+
3
+ module Clevic
4
+
5
+ # Provide a list of all values in this field,
6
+ # and allow new values to be entered.
7
+ # :frequency can be set as an option. Boolean. If it's true
8
+ # the options are sorted in order of most frequently used first.
9
+ class DistinctDelegate < ComboDelegate
10
+ def needs_combo?
11
+ # works except when there is a '' in the column
12
+ entity_class.adaptor.count( attribute.to_s, find_options ) > 0
13
+ end
14
+
15
+ # strings are stored in the model
16
+ def display_for( model_value )
17
+ model_value
18
+ end
19
+
20
+ def population
21
+ # we only use the first column, so use the second
22
+ # column to sort by, since SQL requires the order by clause
23
+ # to be in the select list where distinct is involved
24
+ entity_class.adaptor.attribute_list( attribute, attribute_value, field.description, field.frequency, find_options ) do |row|
25
+ row[attribute]
26
+ end
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,274 @@
1
+ # these two are from
2
+ # http://kofno.wordpress.com/2007/05/05/jruby-swingutilitiesinvoke_block_later/
3
+ class BlockRunner < java.lang.Thread
4
+ def initialize(&proc)
5
+ @p = proc
6
+ end
7
+
8
+ def run
9
+ @p.call
10
+ end
11
+ end
12
+
13
+ unless defined? SwingUtilities
14
+ SwingUtilities = javax.swing.SwingUtilities
15
+
16
+ def SwingUtilities.invoke_block_later(&proc)
17
+ r = BlockRunner.new &proc
18
+ invoke_later r
19
+ end
20
+ end
21
+
22
+ module Kernel
23
+ def invoke_later( &block )
24
+ javax.swing.SwingUtilities.invoke_block_later( &block )
25
+ end
26
+ end
27
+
28
+ unless defined? AbstractButton
29
+ AbstractButton = javax.swing.AbstractButton
30
+ class AbstractButton
31
+ def mnemonic=( arg )
32
+ case arg
33
+ when String
34
+ self.setMnemonic( arg.to_char )
35
+ else
36
+ self.setMnemonic( arg )
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ unless defined? CaretEvent
43
+ CaretEvent = javax.swing.event.CaretEvent
44
+ class CaretEvent
45
+ def inspect
46
+ "<CaretEvent dot=#{dot} mark=#{mark} source=#{source}>"
47
+ end
48
+ end
49
+ end
50
+
51
+ unless defined? Component
52
+ Component = java.awt.Component
53
+ class Component
54
+ def <<( obj )
55
+ case obj
56
+ when Clevic::Separator
57
+ add_separator
58
+
59
+ when Clevic::Action
60
+ add obj.menu_item
61
+
62
+ when String
63
+ add obj.to_java_string
64
+
65
+ else
66
+ add obj
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ unless defined? EventObject
73
+ EventObject = java.util.EventObject
74
+ class EventObject
75
+ def inspect
76
+ if respond_to?( :paramString )
77
+ "<#{self.class.name} #{param_string}>"
78
+ else
79
+ "<#{self.class.name} #{toString}>"
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+ unless defined? JComboBox
86
+ JComboBox = javax.swing.JComboBox
87
+ class JComboBox
88
+ def << ( value )
89
+ model.addElement( value )
90
+ end
91
+
92
+ def each
93
+ (0...model.size).each do |i|
94
+ yield model.getElementAt( i )
95
+ end
96
+ end
97
+
98
+ include Enumerable
99
+ end
100
+ end
101
+
102
+ unless defined? JTabbedPane
103
+ JTabbedPane = javax.swing.JTabbedPane
104
+ class JTabbedPane
105
+ include Enumerable
106
+
107
+ def each
108
+ (0...count).each do |index|
109
+ yield getComponentAt( index )
110
+ end
111
+ end
112
+
113
+ def count
114
+ getTabCount
115
+ end
116
+
117
+ def current=( component )
118
+ self.selected_component = component
119
+ end
120
+ end
121
+ end
122
+
123
+ unless defined? JObject
124
+ JObject = java.lang.Object
125
+ class JObject
126
+ # filter_block returns true if the event is to be constantified, false otherwise.
127
+ # the name of the constant will be passed to the block
128
+ def const_lookup( integer, *filter_block )
129
+ self.class.constants.select do |constant_name|
130
+ if eval( "self.class::#{constant_name}" ) == integer
131
+ if block_given?
132
+ yield constant_name
133
+ else
134
+ true
135
+ end
136
+ else
137
+ false
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+ unless defined? KeyEvent
145
+ KeyEvent = java.awt.event.KeyEvent
146
+ class KeyEvent
147
+ def alt?
148
+ modifiers & self.class::ALT_MASK != 0
149
+ end
150
+
151
+ def ctrl?
152
+ modifiers & self.class::CTRL_MASK != 0
153
+ end
154
+
155
+ def meta?
156
+ modifiers & self.class::META_MASK != 0
157
+ end
158
+
159
+ def self.function_keys
160
+ @function_keys ||= (1..24).map{|i| eval( "VK_F#{i}" ) }
161
+ end
162
+
163
+ def fx?
164
+ self.class.function_keys.include?( key_code )
165
+ end
166
+
167
+ def del?
168
+ key_code == VK_DELETE
169
+ end
170
+
171
+ def shift?
172
+ modifiers & self.class::SHIFT_MASK != 0
173
+ end
174
+
175
+ def plain?
176
+ modifiers == 0
177
+ end
178
+
179
+ def esc?
180
+ key_code == VK_ESCAPE
181
+ end
182
+
183
+ # a KEY_TYPED event
184
+ def typed?
185
+ getID == self.class::KEY_TYPED
186
+ end
187
+
188
+ def inspect
189
+ "<KeyEvent id=#{getID} #{self.class.getKeyText(key_code)} '#{key_char}'>"
190
+ end
191
+ end
192
+ end
193
+
194
+ unless defined? KeyStroke
195
+ KeyStroke = javax.swing.KeyStroke
196
+ class KeyStroke
197
+ def inspect
198
+ toString
199
+ end
200
+ end
201
+ end
202
+
203
+ unless defined? MouseEvent
204
+ MouseEvent = java.awt.event.MouseEvent
205
+ class MouseEvent
206
+ def pressed?
207
+ getID == MOUSE_PRESSED
208
+ end
209
+
210
+ def released?
211
+ getID == MOUSE_RELEASED
212
+ end
213
+
214
+ def clicked?
215
+ getID == MOUSE_CLICKED
216
+ end
217
+
218
+ #~ def inspect
219
+ #~ <<EOF
220
+
221
+ #~ button: #{const_lookup(button) {|b| b =~ /BUTTON/} }
222
+ #~ click_count: #{click_count.inspect}
223
+ #~ modifiers_ex_text: #{self.class.getModifiersExText(modifiers)}
224
+ #~ component: #{component.inspect}
225
+ #~ EOF
226
+ #~ end
227
+ end
228
+ end
229
+
230
+ unless defined? TableModelEvent
231
+ TableModelEvent = javax.swing.event.TableModelEvent
232
+ class TableModelEvent
233
+ def inspect
234
+ "#<#{first_row..last_row}, #{column}, #{const_lookup( type )} >"
235
+ end
236
+
237
+ def updated?
238
+ type == self.class::UPDATE
239
+ end
240
+
241
+ def deleted?
242
+ type == self.class::DELETE
243
+ end
244
+
245
+ def inserted?
246
+ type == self.class::INSERT
247
+ end
248
+
249
+ # returns true if this is a notification to update all
250
+ # rows, ie a fireTableDataChanged() was called
251
+ def all_rows?
252
+ first_row == 0 && last_row == java.lang.Integer::MAX_VALUE
253
+ end
254
+ end
255
+ end
256
+
257
+ unless defined? DocumentEvent
258
+ DocumentEvent = javax.swing.event.DocumentEvent
259
+ module DocumentEvent
260
+ def inspect
261
+ "<DocumentEvent type=#{type} offset=#{offset} length=#{length}>"
262
+ end
263
+ end
264
+ end
265
+
266
+
267
+ unless defined? ItemEvent
268
+ ItemEvent = java.awt.event.ItemEvent
269
+ class ItemEvent
270
+ def inspect
271
+ "<ItemEvent state=#{const_lookup state_change} ps=#{param_string}>"
272
+ end
273
+ end
274
+ end
@@ -0,0 +1,35 @@
1
+ module Clevic
2
+
3
+ class Field
4
+ # Convert a color name understood by java.awt.Color,
5
+ # or a 0xddccee style string to a java.awt.Color
6
+ def string_or_color( s_or_c )
7
+ case s_or_c
8
+ when NilClass
9
+ nil
10
+ when java.awt.Color
11
+ s_or_c
12
+ else
13
+ color_string = s_or_c.to_s
14
+ if java.awt.Color.constants.include?( color_string.upcase )
15
+ eval( "java.awt.Color::#{color_string.upcase}" )
16
+ elsif
17
+ color_string[0..1] == "0x"
18
+ java.awt.Color.decode( color_string )
19
+ else
20
+ nil
21
+ end
22
+ end
23
+ end
24
+
25
+ def swing_alignment
26
+ case alignment
27
+ when :left; javax.swing.SwingConstants::LEFT
28
+ when :right; javax.swing.SwingConstants::RIGHT
29
+ when :centre, :center; javax.swing.SwingConstants::CENTER
30
+ else javax.swing.SwingConstants::LEADING
31
+ end
32
+ end
33
+ end
34
+
35
+ end
@@ -0,0 +1,48 @@
1
+ require 'clevic/swing/combo_delegate'
2
+
3
+ module Clevic
4
+
5
+ # Edit a relation from an id and display a list of relevant entries.
6
+ #
7
+ # attribute is the method to call on the row entity to retrieve the related object.
8
+ #
9
+ # The ids of the model objects are stored in the item data
10
+ # and the item text is fetched from them using attribute_path.
11
+ class RelationalDelegate < ComboDelegate
12
+ def initialize( field )
13
+ super
14
+ unless find_options[:conditions].nil?
15
+ find_options[:conditions].gsub!( /true/, field.related_class.adaptor.quoted_true )
16
+ find_options[:conditions].gsub!( /false/, field.related_class.adaptor.quoted_false )
17
+ end
18
+ end
19
+
20
+ # use the Clevic::ComboBox class because JCombobox is remarkably stupid
21
+ # about far too many things.
22
+ def combo_class
23
+ ComboBox
24
+ end
25
+
26
+ def needs_combo?
27
+ field.related_class.adaptor.count( :conditions => find_options[:conditions] ) > 0
28
+ end
29
+
30
+ def empty_set_message
31
+ "There must be records in #{field.related_class.name.humanize} for this field to be editable."
32
+ end
33
+
34
+ def population
35
+ # add set of all possible related entities,
36
+ # including the currently selected entity
37
+ ary = field.related_class.adaptor.find( :all, find_options )
38
+ ary << attribute_value unless ary.include?( attribute_value )
39
+ ary
40
+ end
41
+
42
+ # don't allow new values
43
+ def restricted?
44
+ true
45
+ end
46
+ end
47
+
48
+ end