clevic 0.13.0.b9 → 0.13.0.b10

Sign up to get free protection for your applications and to get access to all the features.
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