clevic 0.13.0.b9 → 0.13.0.b10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. data/History.txt +3 -0
  2. data/lib/clevic/action_builder.rb +16 -16
  3. data/lib/clevic/ar_methods.rb +22 -22
  4. data/lib/clevic/attribute_list.rb +5 -5
  5. data/lib/clevic/cache_table.rb +18 -18
  6. data/lib/clevic/dataset_roller.rb +3 -3
  7. data/lib/clevic/default_view.rb +4 -4
  8. data/lib/clevic/delegate.rb +8 -8
  9. data/lib/clevic/delegates/combo_delegate.rb +22 -22
  10. data/lib/clevic/delegates/distinct_delegate.rb +5 -5
  11. data/lib/clevic/delegates/relational_delegate.rb +6 -6
  12. data/lib/clevic/delegates/set_delegate.rb +3 -3
  13. data/lib/clevic/dirty.rb +1 -1
  14. data/lib/clevic/emitter.rb +3 -3
  15. data/lib/clevic/extensions.rb +4 -4
  16. data/lib/clevic/field.rb +68 -68
  17. data/lib/clevic/field_valuer.rb +26 -26
  18. data/lib/clevic/filter_command.rb +6 -6
  19. data/lib/clevic/framework.rb +3 -3
  20. data/lib/clevic/generic_format.rb +2 -2
  21. data/lib/clevic/many_field.rb +3 -3
  22. data/lib/clevic/model_builder.rb +88 -84
  23. data/lib/clevic/model_column.rb +13 -13
  24. data/lib/clevic/ordered_dataset.rb +7 -7
  25. data/lib/clevic/qt/action_builder.rb +3 -3
  26. data/lib/clevic/qt/browser.rb +28 -28
  27. data/lib/clevic/qt/clipboard.rb +5 -5
  28. data/lib/clevic/qt/combo_delegate.rb +12 -12
  29. data/lib/clevic/qt/distinct_delegate.rb +1 -1
  30. data/lib/clevic/qt/extensions.rb +4 -4
  31. data/lib/clevic/qt/qt_combo_box.rb +7 -7
  32. data/lib/clevic/qt/relational_delegate.rb +5 -5
  33. data/lib/clevic/qt/search_dialog.rb +15 -15
  34. data/lib/clevic/qt/simplest_delegate.rb +2 -2
  35. data/lib/clevic/qt/table_model.rb +46 -46
  36. data/lib/clevic/qt/table_view.rb +48 -48
  37. data/lib/clevic/qt/text_delegate.rb +9 -9
  38. data/lib/clevic/rails_models_loaders.rb +3 -3
  39. data/lib/clevic/record.rb +8 -8
  40. data/lib/clevic/sampler.rb +6 -6
  41. data/lib/clevic/sequel_ar_adapter.rb +22 -22
  42. data/lib/clevic/sequel_clevic.rb +10 -10
  43. data/lib/clevic/sequel_meta.rb +5 -5
  44. data/lib/clevic/sequel_naked.rb +4 -4
  45. data/lib/clevic/swing/action.rb +20 -20
  46. data/lib/clevic/swing/action_builder.rb +2 -2
  47. data/lib/clevic/swing/boolean_delegate.rb +3 -3
  48. data/lib/clevic/swing/browser.rb +37 -37
  49. data/lib/clevic/swing/cell_editor.rb +13 -13
  50. data/lib/clevic/swing/cell_renderer.rb +7 -7
  51. data/lib/clevic/swing/clipboard.rb +19 -19
  52. data/lib/clevic/swing/combo_delegate.rb +26 -26
  53. data/lib/clevic/swing/confirm_dialog.rb +7 -7
  54. data/lib/clevic/swing/delegate.rb +4 -4
  55. data/lib/clevic/swing/extensions.rb +24 -24
  56. data/lib/clevic/swing/field.rb +1 -1
  57. data/lib/clevic/swing/relational_delegate.rb +2 -2
  58. data/lib/clevic/swing/row_header.rb +32 -32
  59. data/lib/clevic/swing/search_dialog.rb +31 -31
  60. data/lib/clevic/swing/selection_model.rb +12 -12
  61. data/lib/clevic/swing/swing_table_index.rb +6 -6
  62. data/lib/clevic/swing/table_model.rb +30 -30
  63. data/lib/clevic/swing/table_view.rb +54 -54
  64. data/lib/clevic/swing/table_view_focus.rb +4 -4
  65. data/lib/clevic/swing/tag_delegate.rb +14 -14
  66. data/lib/clevic/swing/tag_editor.rb +4 -4
  67. data/lib/clevic/swing/text_area_delegate.rb +6 -6
  68. data/lib/clevic/swing/text_delegate.rb +4 -4
  69. data/lib/clevic/table_index.rb +14 -14
  70. data/lib/clevic/table_model.rb +30 -30
  71. data/lib/clevic/table_searcher.rb +19 -19
  72. data/lib/clevic/table_view.rb +92 -92
  73. data/lib/clevic/table_view_paste.rb +19 -19
  74. data/lib/clevic/version.rb +1 -1
  75. data/lib/clevic/view.rb +22 -22
  76. data/models/accounts_models.rb +10 -10
  77. data/models/examples.rb +2 -2
  78. data/models/times_models.rb +32 -32
  79. data/models/values_models.rb +2 -2
  80. data/test/test_cache_table.rb +15 -15
  81. data/test/test_helper.rb +7 -7
  82. data/test/test_model_index_extensions.rb +6 -6
  83. data/test/test_table_model.rb +6 -6
  84. data/test/test_table_searcher.rb +25 -25
  85. metadata +33 -35
@@ -8,9 +8,9 @@ a hash instead of a class.
8
8
  class ModelColumn
9
9
  # these are from AR
10
10
  attr_accessor :primary, :scale, :sql_type, :name, :precision, :default, :type, :meta
11
-
11
+
12
12
  attr_writer :limit
13
-
13
+
14
14
  # if it's not here, it's probably from Sequel, so figure it out from
15
15
  # the db_type
16
16
  def limit
@@ -20,22 +20,22 @@ class ModelColumn
20
20
  end
21
21
  @limit
22
22
  end
23
-
23
+
24
24
  # these are from Sequel::Model.columns_hash
25
25
  attr_accessor :ruby_default, :primary_key, :allow_null, :db_type
26
-
26
+
27
27
  # sequel::Model.reflections
28
28
  attr_accessor :key, :eager_block, :type, :eager_grapher, :before_add, :model, :graph_join_type, :class_name, :before_remove, :eager_loader, :uses_composite_keys, :order_eager_graph, :dataset, :cartesian_product_number, :after_add, :cache, :keys, :after_remove, :extend, :graph_conditions, :name, :orig_opts, :after_load, :before_set, :after_set, :reciprocal, :reciprocal_type
29
-
29
+
30
30
  # for many_to_one targets
31
31
  attr_accessor :primary_keys
32
-
32
+
33
33
  # TODO not sure where these are from
34
34
  attr_accessor :order, :class, :conditions
35
-
35
+
36
36
  # a enw one in sequel 3.25.0
37
37
  attr_accessor :block
38
-
38
+
39
39
  # For Sequel many_to_many
40
40
  attr_accessor :left_key,
41
41
  :left_keys,
@@ -50,25 +50,25 @@ class ModelColumn
50
50
  :left_key_alias,
51
51
  :graph_join_table_conditions,
52
52
  :graph_join_table_join_type
53
-
53
+
54
54
  # added by us
55
55
  attr_accessor :association
56
56
  def association?; association; end
57
-
57
+
58
58
  def initialize( name, hash )
59
59
  @hash = hash
60
60
  @hash.each do |key,value|
61
61
  send( "#{key}=", value )
62
62
  end
63
-
63
+
64
64
  # must be after hash so it takes precedence
65
65
  @name = name
66
66
  end
67
-
67
+
68
68
  def name
69
69
  @name
70
70
  end
71
-
71
+
72
72
  def related_class
73
73
  @related_class ||= eval class_name
74
74
  end
@@ -1,11 +1,11 @@
1
1
  module Clevic
2
-
2
+
3
3
  # Provides a nice way of getting to Sequel::Dataset's
4
4
  # opts[:order] information
5
5
  #
6
6
  # Including class must call dataset= before calling order_attributes
7
7
  module OrderedDataset
8
-
8
+
9
9
  # returns a collection of [ attribute, (1|-1) ]
10
10
  # where 1 is forward/asc (>) and -1 is backward/desc (<)
11
11
  def order_attributes
@@ -15,10 +15,10 @@ module Clevic
15
15
  case order_expr
16
16
  when Symbol
17
17
  [ order_expr, 1 ]
18
-
18
+
19
19
  when Sequel::SQL::OrderedExpression
20
20
  [ order_expr.expression, order_expr.descending ? -1 : 1 ]
21
-
21
+
22
22
  else
23
23
  raise "unknown order_expr: #{order_expr.inspect}"
24
24
  end
@@ -26,9 +26,9 @@ module Clevic
26
26
  end
27
27
  @order_attributes
28
28
  end
29
-
29
+
30
30
  attr_reader :dataset
31
-
31
+
32
32
  # Set default dataset ordering to primary key if it doesn't
33
33
  # already have an order.
34
34
  def dataset=( other )
@@ -39,7 +39,7 @@ module Clevic
39
39
  other
40
40
  end
41
41
  end
42
-
42
+
43
43
  end
44
44
 
45
45
  end
@@ -9,11 +9,11 @@ module ActionBuilder
9
9
  collect_actions << action
10
10
  end
11
11
  end
12
-
12
+
13
13
  def create_action( &block )
14
14
  Qt::Action.new( parent, &block )
15
15
  end
16
-
16
+
17
17
  # TODO move this into Action, like the swing adapter
18
18
  def create_key_sequence( sequence )
19
19
  Qt::KeySequence.new( sequence )
@@ -22,7 +22,7 @@ module ActionBuilder
22
22
  # set up the code to be executed when an action is triggered,
23
23
  def action_method_or_block( qt_action, options, &block )
24
24
  signal_name = "triggered(#{options.has_key?( :checkable ) ? 'bool' : ''})"
25
-
25
+
26
26
  # connect the action to some code
27
27
  if options.has_key?( :method )
28
28
  qt_action.connect SIGNAL( signal_name ) do |active|
@@ -12,29 +12,29 @@ added.
12
12
  =end
13
13
  class Browser < Qt::Widget
14
14
  slots *%w{dump() refresh_table() filter_by_current(bool) next_tab() previous_tab() current_changed(int)}
15
-
15
+
16
16
  attr_reader :tables_tab
17
-
17
+
18
18
  def initialize( main_window )
19
19
  super( main_window )
20
-
20
+
21
21
  # do menus and widgets
22
22
  @layout = Ui::Browser.new
23
23
  @layout.setup_ui( main_window )
24
-
24
+
25
25
  # set icon. MUST come after call to setup_ui
26
26
  icon_path = Pathname.new( __FILE__ ).parent + "../icons/icon.png"
27
27
  Kernel::raise "icon.png not found" unless icon_path.file?
28
28
  main_window.window_icon = Qt::Icon.new( icon_path.realpath.to_s )
29
-
29
+
30
30
  # add the tables tab
31
31
  @tables_tab = Qt::TabWidget.new( @layout.main_widget )
32
32
  @layout.main_widget.layout.add_widget @tables_tab
33
33
  @tables_tab.tab_bar.focus_policy = Qt::NoFocus
34
-
34
+
35
35
  # hide the file menu, for now
36
36
  @layout.menubar.remove_action( @layout.menu_file.menu_action )
37
-
37
+
38
38
  # tab navigation
39
39
  @layout.action_next.connect SIGNAL( 'triggered()' ), &method( :next_tab )
40
40
  @layout.action_previous.connect SIGNAL( 'triggered()' ), &method( :previous_tab )
@@ -42,51 +42,51 @@ class Browser < Qt::Widget
42
42
  # dump model for current tab
43
43
  @layout.action_dump.visible = $options[:debug]
44
44
  @layout.action_dump.connect SIGNAL( 'triggered()' ), &method( :dump )
45
-
45
+
46
46
  tables_tab.connect SIGNAL( 'currentChanged(int)' ), &method( :current_changed )
47
-
47
+
48
48
  load_views
49
49
  update_menus
50
50
  main_window.window_title = [database_name, 'Clevic'].compact.join ' '
51
51
  end
52
-
52
+
53
53
  # Set the main window title to the name of the database, if we can find it.
54
54
  def database_name
55
55
  table_view.model.entity_class.db.url rescue ''
56
56
  end
57
-
57
+
58
58
  def update_menus
59
59
  # update edit menu
60
60
  @layout.menu_edit.clear
61
-
61
+
62
62
  # do the model-specific menu items first
63
63
  table_view.model_actions.each do |action|
64
64
  @layout.menu_edit.add_action( action )
65
65
  end
66
-
66
+
67
67
  # now do the generic edit items
68
68
  table_view.edit_actions.each do |action|
69
69
  @layout.menu_edit.add_action( action )
70
70
  end
71
-
71
+
72
72
  # update search menu
73
73
  @layout.menu_search.clear
74
74
  table_view.search_actions.each do |action|
75
75
  @layout.menu_search.add_action( action )
76
76
  end
77
77
  end
78
-
78
+
79
79
  # activated by Ctrl-Shift-D for debugging
80
80
  def dump
81
81
  puts "table_view.model: #{table_view.model.inspect}"
82
82
  puts "table_view.model.entity_class: #{table_view.model.entity_class.inspect}"
83
83
  end
84
-
84
+
85
85
  # return the Clevic::TableView object in the currently displayed tab
86
86
  def table_view
87
87
  tables_tab.current_widget
88
88
  end
89
-
89
+
90
90
  # slot to handle Ctrl-Tab and move to next tab, or wrap around
91
91
  def next_tab
92
92
  tables_tab.current_index =
@@ -106,14 +106,14 @@ class Browser < Qt::Widget
106
106
  tables_tab.current_index - 1
107
107
  end
108
108
  end
109
-
109
+
110
110
  # slot to handle the currentChanged signal from tables_tab, and
111
111
  # set focus on the grid
112
112
  def current_changed( current_tab_index )
113
113
  update_menus
114
114
  tables_tab.current_widget.set_focus
115
115
  end
116
-
116
+
117
117
  # shortcut for the Qt translate call
118
118
  def translate( st )
119
119
  Qt::Application.translate("Browser", st, nil, Qt::Application::UnicodeUTF8)
@@ -124,26 +124,26 @@ class Browser < Qt::Widget
124
124
  def load_views
125
125
  views = Clevic::View.order.uniq
126
126
  Kernel.raise "no views to display" if views.empty?
127
-
127
+
128
128
  # Add all existing model objects as tabs, one each
129
129
  views.each do |view_class|
130
130
  begin
131
131
  view = view_class.new
132
-
132
+
133
133
  # This will raise an exception if we can't talk to the
134
134
  # table. Returns nil if there is an empty table, which is
135
135
  # also fine.
136
136
  view.entity_class.first
137
-
137
+
138
138
  # create the the table_view and the table_model for the entity_class
139
139
  tab = Clevic::TableView.new( view )
140
-
140
+
141
141
  # show status messages
142
142
  tab.connect( SIGNAL( 'status_text_signal(QString)' ) ) { |msg| @layout.statusbar.show_message( msg, 10000 ) }
143
-
143
+
144
144
  # add a new tab
145
145
  tables_tab.add_tab( tab, translate( tab.title ) )
146
-
146
+
147
147
  # add the table to the Table menu
148
148
  action = Qt::Action.new( @layout.menu_model )
149
149
  action.text = translate( tab.title )
@@ -151,7 +151,7 @@ class Browser < Qt::Widget
151
151
  tables_tab.current_widget = tab
152
152
  end
153
153
  @layout.menu_model.add_action( action )
154
-
154
+
155
155
  # handle filter status changed, so we can provide a visual indication
156
156
  tab.connect SIGNAL( 'filter_status_signal(bool)' ) do |status|
157
157
  # update the tab, so there's a visual indication of filtering
@@ -166,12 +166,12 @@ class Browser < Qt::Widget
166
166
  end
167
167
  end
168
168
  end
169
-
169
+
170
170
  # make sure all outstanding records are saved
171
171
  def save_all
172
172
  tables_tab.tabs.each {|x| x.save_row( x.current_index ) }
173
173
  end
174
-
174
+
175
175
  def self.run( args )
176
176
  # load model files
177
177
  raise "no model definition file specified" if args.empty?
@@ -7,23 +7,23 @@ module Clevic
7
7
  def system
8
8
  Qt::Application::clipboard
9
9
  end
10
-
10
+
11
11
  def text=( value )
12
12
  system.text = value
13
13
  end
14
-
14
+
15
15
  def text
16
16
  system.text
17
17
  end
18
-
18
+
19
19
  def text?
20
20
  system.mime_data.has_text
21
21
  end
22
-
22
+
23
23
  def html?
24
24
  system.mime_data.has_html
25
25
  end
26
-
26
+
27
27
  # TODO figure out why Qt never has anything other than text.
28
28
  # Could be because the event loop isn't running when testing
29
29
  # from irb.
@@ -19,7 +19,7 @@ class ComboDelegate < Clevic::Delegate
19
19
  end
20
20
  hs
21
21
  end
22
-
22
+
23
23
  def dump_editor_state( editor )
24
24
  if $options[:debug]
25
25
  puts "#{self.class.name}"
@@ -33,23 +33,23 @@ class ComboDelegate < Clevic::Delegate
33
33
  puts
34
34
  end
35
35
  end
36
-
36
+
37
37
  # open the combo box, just like if f4 was pressed
38
38
  def full_edit
39
39
  editor.show_popup if is_combo?( editor )
40
40
  end
41
-
41
+
42
42
  def is_combo?( editor )
43
43
  editor.is_a?( Qt::ComboBox )
44
44
  end
45
-
45
+
46
46
  def create_combo_box( *args )
47
47
  Qt::ComboBox.new( parent ).tap do |combo|
48
48
  # all combos are editable so that prefix matching will work
49
49
  combo.editable = true
50
50
  end
51
51
  end
52
-
52
+
53
53
  # Override the Qt method. Create a ComboBox widget and fill it with the possible values.
54
54
  def createEditor( parent_widget, style_option_view_item, model_index )
55
55
  self.parent = parent_widget
@@ -62,7 +62,7 @@ class ComboDelegate < Clevic::Delegate
62
62
  def line_editor( edit_value )
63
63
  @line_editor ||= Qt::LineEdit.new( edit_value, parent )
64
64
  end
65
-
65
+
66
66
  def framework_setup( *args )
67
67
  # don't need to do anything here
68
68
  # might need to once prefix-matching is implemented
@@ -71,7 +71,7 @@ class ComboDelegate < Clevic::Delegate
71
71
  # Override the Qt::ItemDelegate method.
72
72
  def updateEditorGeometry( editor, style_option_view_item, model_index )
73
73
  rect = style_option_view_item.rect
74
-
74
+
75
75
  # ask the editor for how much space it wants, and set the editor
76
76
  # to that size when it displays in the table
77
77
  rect.set_width( [editor.size_hint.width,rect.width].max ) if is_combo?( editor )
@@ -87,19 +87,19 @@ class ComboDelegate < Clevic::Delegate
87
87
  editor.text = model_index.edit_value
88
88
  end
89
89
  end
90
-
90
+
91
91
  # This translates the text from the editor into something that is
92
92
  # stored in an underlying model. Intended to be overridden by subclasses.
93
93
  def translate_from_editor_text( editor, text )
94
94
  index = editor.find_text( text )
95
-
95
+
96
96
  if index == -1
97
97
  text unless restricted?
98
98
  else
99
99
  editor.item_data( index ).value
100
100
  end
101
101
  end
102
-
102
+
103
103
  # Send the data from the editor to the model. The data will
104
104
  # be translated by translate_from_editor_text,
105
105
  def setModelData( editor, abstract_item_model, model_index )
@@ -116,11 +116,11 @@ class ComboDelegate < Clevic::Delegate
116
116
  # there is a matching completion, so use it
117
117
  editor.completer.current_completion
118
118
  end
119
-
119
+
120
120
  if value != nil
121
121
  model_index.attribute_value = translate_from_editor_text( editor, value )
122
122
  end
123
-
123
+
124
124
  else
125
125
  model_index.attribute_value = editor.text
126
126
  end
@@ -5,7 +5,7 @@ module Clevic
5
5
 
6
6
  class DistinctDelegate < ComboDelegate
7
7
  include SimplestDelegate
8
-
8
+
9
9
  # This might be unnecessary.
10
10
  def translate_from_editor_text( editor, text )
11
11
  text
@@ -7,7 +7,7 @@ require 'clevic/qt/accept_reject'
7
7
  # convenience methods
8
8
  module Qt
9
9
  PasteRole = UserRole + 1 unless defined?( PasteRole )
10
-
10
+
11
11
  class AbstractItemDelegate
12
12
  # overridden in EntryDelegate subclasses
13
13
  def full_edit
@@ -26,7 +26,7 @@ module Qt
26
26
  class ModelIndex
27
27
  include Clevic::TableIndex
28
28
  end
29
-
29
+
30
30
  class ItemSelectionModel
31
31
  # return an array of integer indexes for currently selected rows
32
32
  def row_indexes
@@ -40,12 +40,12 @@ module Qt
40
40
  def ranges
41
41
  selection
42
42
  end
43
-
43
+
44
44
  def single_cell?
45
45
  ranges.size == 1 && ranges.first.single_cell?
46
46
  end
47
47
  end
48
-
48
+
49
49
  # implement accepted? and rejected? for TableView#confirm_dialog and friends
50
50
  class MessageBox
51
51
  include Clevic::AcceptReject