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
@@ -12,7 +12,7 @@ class TableView
12
12
  def paste
13
13
  busy_cursor do
14
14
  sanity_check_read_only
15
-
15
+
16
16
  # Try text/html then text/plain as tsv or csv
17
17
  # LATER maybe use the java-native-application at some point for
18
18
  # cut'n'paste internally?
@@ -28,14 +28,14 @@ class TableView
28
28
  rescue PasteError => e
29
29
  show_error e.message
30
30
  end
31
-
31
+
32
32
  # Paste suitable html to the selection
33
33
  # Check for presence of tr tags, and make sure there are no colspan or rowspan attributes
34
34
  # on td tags.
35
35
  def paste_html
36
36
  emit_status_text "Fetching data."
37
37
  html = clipboard.html
38
-
38
+
39
39
  # This should really be factored out somewhere and tested thoroughly
40
40
  emit_status_text "Analysing data."
41
41
  doc =
@@ -44,7 +44,7 @@ class TableView
44
44
  else
45
45
  Hpricot.parse( html )
46
46
  end
47
-
47
+
48
48
  # call the plain text paste if we don't have tabular data
49
49
  if doc.search( "//tr" ).size == 0
50
50
  paste_text
@@ -62,13 +62,13 @@ class TableView
62
62
  #{cell_list}
63
63
  EOF
64
64
  end
65
-
65
+
66
66
  # run through the tabular data and convert to simple array
67
67
  emit_status_text "Pasting data."
68
68
  ary = ( doc / :tr ).map do |row|
69
69
  ( row / :td ).map do |cell|
70
70
  # trim leading and trailing \r\n\t
71
-
71
+
72
72
  # check for br
73
73
  unless cell.search( '//br' ).empty?
74
74
  # treat br as separate lines
@@ -79,11 +79,11 @@ class TableView
79
79
  end.gsub( /^[\r\n\t]*/, '').gsub( /[\r\n\t]*$/, '')
80
80
  end
81
81
  end
82
-
82
+
83
83
  paste_array ary
84
84
  end
85
85
  end
86
-
86
+
87
87
  # LATER probably need a PasteParser or something, to figure
88
88
  # out if a file is tsv or csv
89
89
  # Try tsv first, because number formats often have embedded ','.
@@ -92,7 +92,7 @@ class TableView
92
92
  # TODO could also heuristically check paste selection area
93
93
  def paste_text
94
94
  text = clipboard.text
95
-
95
+
96
96
  case text
97
97
  when /\t/
98
98
  paste_array( CSV.parse( text, :col_sep => "\t" ) )
@@ -103,7 +103,7 @@ class TableView
103
103
  paste_value_to_selection( text )
104
104
  end
105
105
  end
106
-
106
+
107
107
  # Paste array to either a single selection or a matching multiple selection
108
108
  # TODO Check for rectangularness, ie csv_arr.map{|row| row.size}.uniq.size == 1
109
109
  def paste_array( arr )
@@ -124,21 +124,21 @@ class TableView
124
124
  if selection_model.ranges.size != 1
125
125
  raise PasteError, "Can't paste tabular data to multiple selection."
126
126
  end
127
-
127
+
128
128
  if selection_model.ranges.first.height != arr.size
129
129
  raise PasteError, "Height of paste area (#{selection_model.ranges.first.height}) doesn't match height of data (#{arr.size})."
130
130
  end
131
-
131
+
132
132
  if selection_model.ranges.first.width != arr.first.size
133
133
  raise PasteError, "Width of paste area (#{selection_model.ranges.first.width}) doesn't match width of data (#{arr.first.size})."
134
134
  end
135
-
135
+
136
136
  # size is the same, so do the paste
137
137
  paste_to_index( selected_index, arr )
138
138
  end
139
139
  end
140
140
  end
141
-
141
+
142
142
  # set all indexes in the selection to the value
143
143
  def paste_value_to_selection( value )
144
144
  selection_model.selected_indexes.each do |index|
@@ -146,7 +146,7 @@ class TableView
146
146
  # save records to db via view, so we get error messages
147
147
  save_row( index )
148
148
  end
149
-
149
+
150
150
  # notify of changed data
151
151
  model.data_changed do |change|
152
152
  sorted = selection_model.selected_indexes.sort
@@ -154,7 +154,7 @@ class TableView
154
154
  change.bottom_right = sorted.last
155
155
  end
156
156
  end
157
-
157
+
158
158
  # Paste an array to the index, replacing whatever is at that index
159
159
  # and whatever is at other indices matching the size of the pasted
160
160
  # csv array. Create new rows if there aren't enough.
@@ -163,7 +163,7 @@ class TableView
163
163
  csv_arr.each_with_index do |row,row_index|
164
164
  # append row if we need one
165
165
  model.add_new_item if top_left_index.row + row_index >= model.row_count
166
-
166
+
167
167
  row.each_with_index do |field, field_index|
168
168
  unless top_left_index.column + field_index >= model.column_count
169
169
  # do paste
@@ -183,7 +183,7 @@ class TableView
183
183
  # save records to db via view, so we get error messages
184
184
  save_row( top_left_index.choppy {|i| i.row += row_index; i.column = 0 } )
185
185
  end
186
-
186
+
187
187
  # make the gui refresh
188
188
  model.data_changed do |change|
189
189
  change.top_left = top_left_index
@@ -193,7 +193,7 @@ class TableView
193
193
  end
194
194
  end
195
195
  end
196
-
196
+
197
197
  end
198
198
 
199
199
  end
@@ -3,7 +3,7 @@ module Clevic #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 13
5
5
  TINY = 0
6
- PRE = 'b9'
6
+ PRE = 'b10'
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
9
9
  end
data/lib/clevic/view.rb CHANGED
@@ -5,28 +5,28 @@ module Clevic
5
5
  # This contains the definition of a particular view of an entity.
6
6
  # See Clevic::ModelBuilder.
7
7
  class View
8
-
8
+
9
9
  class << self
10
10
  def define_ui_block( &block )
11
11
  @define_ui_block ||= block
12
12
  end
13
-
13
+
14
14
  def order
15
15
  @order ||= []
16
16
  end
17
-
17
+
18
18
  # sometimes order has duplicates. So this is all unique
19
19
  # defined views in order of definition, or as specified.
20
20
  def views
21
21
  order.uniq
22
22
  end
23
-
23
+
24
24
  def []( view_name )
25
25
  order.find do |view|
26
26
  view.name =~ /#{view_name.to_s}/i
27
27
  end
28
28
  end
29
-
29
+
30
30
  # Handle situations where the array passed to
31
31
  # Clevic::View.order has entity_class
32
32
  # objects in it. In other words, if there is one, pass back it's
@@ -40,7 +40,7 @@ module Clevic
40
40
  end
41
41
  end
42
42
  end
43
-
43
+
44
44
  def entity_class( *args )
45
45
  if args.size == 0
46
46
  @entity_class || raise( "entity_class not specified for #{name}" )
@@ -48,11 +48,11 @@ module Clevic
48
48
  self.entity_class = args.first
49
49
  end
50
50
  end
51
-
51
+
52
52
  def entity_class=( some_class )
53
53
  @entity_class = some_class
54
54
  end
55
-
55
+
56
56
  def widget_name( *args )
57
57
  if args.size == 0
58
58
  # the class name by default
@@ -62,7 +62,7 @@ module Clevic
62
62
  end
63
63
  end
64
64
  end
65
-
65
+
66
66
  # args can be anything that has a writer method. Often this
67
67
  # will be entity_class
68
68
  # block contains the ModelBuilder DSL
@@ -74,33 +74,33 @@ module Clevic
74
74
  end
75
75
  end
76
76
  end
77
-
77
+
78
78
  # use block from constructor, or class ui block from eg Clevic::Record
79
79
  def define_ui_block
80
80
  @define_ui_block || self.class.define_ui_block
81
81
  end
82
-
82
+
83
83
  # For descendants to override easily
84
84
  def entity_class
85
85
  @entity_class || self.class.entity_class
86
86
  end
87
87
  attr_writer :entity_class
88
-
88
+
89
89
  # The title to display, eg in a tab
90
90
  def title
91
91
  @title || self.class.name
92
92
  end
93
93
  attr_writer :title
94
-
94
+
95
95
  def fields
96
96
  @fields ||= define_ui.fields
97
97
  end
98
-
98
+
99
99
  # used by the framework-specific code to name widgets
100
100
  def widget_name
101
101
  @widget_name || self.class.widget_name
102
102
  end
103
-
103
+
104
104
  def model_builder( value = nil, &block )
105
105
  if value.nil?
106
106
  @model_builder ||= ModelBuilder.new( self )
@@ -110,7 +110,7 @@ module Clevic
110
110
  end
111
111
  end
112
112
  attr_writer :model_builder
113
-
113
+
114
114
  # return a default UI constructed from model metadata
115
115
  def define_ui
116
116
  if define_ui_block.nil?
@@ -123,23 +123,23 @@ module Clevic
123
123
  model_builder( &define_ui_block )
124
124
  end
125
125
  end
126
-
126
+
127
127
  # callback for view/model specific actions
128
128
  def define_actions( table_view, action_builder )
129
129
  end
130
-
130
+
131
131
  # callback for notify
132
132
  def notify_field( table_view, model_index )
133
133
  ndc = model_index.field.notify_data_changed
134
134
  case ndc
135
135
  when Proc
136
136
  ndc.call( self, table_view, model_index )
137
-
137
+
138
138
  when Symbol
139
139
  send( ndc, table_view, model_index )
140
140
  end
141
141
  end
142
-
142
+
143
143
  # Define data changed events. Default is to call notify_data_changed
144
144
  # for each field in the rectangular area defined by top_left and bottom_right
145
145
  # (which are include Clevic::TableIndex)
@@ -157,10 +157,10 @@ module Clevic
157
157
  end
158
158
  end
159
159
  end
160
-
160
+
161
161
  # callback for key presses
162
162
  def notify_key_press( table_view, key_press_event, current_model_index )
163
163
  end
164
-
164
+
165
165
  end
166
166
  end
@@ -16,9 +16,9 @@ db.test_connection
16
16
  class Entry < Sequel::Model
17
17
  many_to_one :debit, :class_name => 'Account', :key => :debit_id
18
18
  many_to_one :credit, :class_name => 'Account', :key => :credit_id
19
-
19
+
20
20
  include Clevic::Record
21
-
21
+
22
22
  define_ui do
23
23
  plain :date, :sample => '88-WWW-99'
24
24
  distinct :supplier do |f|
@@ -28,7 +28,7 @@ class Entry < Sequel::Model
28
28
  f.notify_data_changed = lambda do |entity_view, table_view, model_index|
29
29
  if model_index.entity.credit.nil? && model_index.entity.debit.nil?
30
30
  entity_view.update_from_description( model_index )
31
-
31
+
32
32
  # move edit cursor to amount field
33
33
  table_view.selection_model.clear
34
34
  table_view.override_next_index( model_index.choppy( :column => :amount ) )
@@ -43,10 +43,10 @@ class Entry < Sequel::Model
43
43
  plain :cheque_number
44
44
  plain :active, :sample => 'WW'
45
45
  plain :vat, :label => 'VAT', :sample => 'WW', :tooltip => 'Does this include VAT?'
46
-
46
+
47
47
  dataset.order( :date, :id )
48
48
  end
49
-
49
+
50
50
  # Copy the values for the credit and debit fields
51
51
  # from the previous similar entry with a similar description
52
52
  def self.update_from_description( current_index )
@@ -56,13 +56,13 @@ class Entry < Sequel::Model
56
56
  filter( current_index.attribute.to_sym => current_index.attribute_value ). \
57
57
  order( :date.desc ). \
58
58
  first
59
-
59
+
60
60
  if similar != nil
61
61
  # set the values
62
62
  current_index.entity.debit = similar.debit
63
63
  current_index.entity.credit = similar.credit
64
64
  current_index.entity.category = similar.category
65
-
65
+
66
66
  # emit signal to that whole row has changed
67
67
  current_index.model.data_changed do |change|
68
68
  change.top_left = current_index.choppy( :column => 0 )
@@ -75,9 +75,9 @@ end
75
75
  class Account < Sequel::Model
76
76
  one_to_many :debits, :class_name => 'Entry', :key => :debit_id, :order => :date
77
77
  one_to_many :credits, :class_name => 'Entry', :key => :credit_id, :order => :date
78
-
78
+
79
79
  include Clevic::Record
80
-
80
+
81
81
  # define how fields are displayed
82
82
  define_ui do
83
83
  plain :name
@@ -86,7 +86,7 @@ class Account < Sequel::Model
86
86
  plain :pastel_number, :alignment => :right, :label => 'Pastel'
87
87
  plain :fringe, :format => "%.1f"
88
88
  plain :active
89
-
89
+
90
90
  dataset.order( :name, :account_type )
91
91
  end
92
92
  end
data/models/examples.rb CHANGED
@@ -31,10 +31,10 @@ See also Clevic::ModelBuilder and Clevic::Field
31
31
 
32
32
  == Work hours database using Sqlite
33
33
  :include:models/times_sqlite_models.rb
34
-
34
+
35
35
  == Work hours database using Postgres
36
36
  :include:models/times_psql_models.rb
37
-
37
+
38
38
  == Work hours database using ActiveRecord style models
39
39
  :include:models/times_ar_style_models.rb
40
40
 
@@ -11,7 +11,7 @@ class Entry < Sequel::Model
11
11
  many_to_one :invoice
12
12
  many_to_one :activity
13
13
  many_to_one :project
14
-
14
+
15
15
  # spans of time more than 8 ours are coloured violet
16
16
  # because they're often the result of typos.
17
17
  def time_color
@@ -19,21 +19,21 @@ class Entry < Sequel::Model
19
19
  # 8 hours
20
20
  'darkviolet' if self.end - start > 8.hours
21
21
  end
22
-
22
+
23
23
  # tooltip for spans of time > 8 hours
24
24
  def time_tooltip
25
25
  return if self.end.nil? || start.nil?
26
26
  'Time interval greater than 8 hours' if self.end - start > 8.hours
27
27
  end
28
-
28
+
29
29
  define_ui do
30
30
  plain :date, :sample => '28-WWW-08'
31
-
31
+
32
32
  # The project field
33
33
  relational :project do |field|
34
34
  field.display = :project
35
35
  field.dataset.filter( :active => true ).order{ lower(project) }
36
-
36
+
37
37
  # handle data changed events. In this case,
38
38
  # auto-fill-in the invoice field.
39
39
  field.notify_data_changed do |entity_view, table_view, model_index|
@@ -45,31 +45,31 @@ class Entry < Sequel::Model
45
45
  end
46
46
  end
47
47
  end
48
-
48
+
49
49
  relational :invoice do |f|
50
50
  f.display 'invoice_number'
51
51
  f.dataset.filter( :status => 'not sent' ).order( :invoice_number )
52
52
  end
53
-
53
+
54
54
  # call time_color method for foreground color value
55
55
  plain :start, :foreground => :time_color, :tooltip => :time_tooltip
56
-
56
+
57
57
  # another way to call time_color method for foreground color value
58
58
  plain :end, :foreground => lambda{|x| x.time_color}, :tooltip => :time_tooltip
59
-
59
+
60
60
  # multiline text
61
61
  text :description, :sample => 'This is a long string designed to hold lots of data and description'
62
-
62
+
63
63
  relational :activity do |f|
64
64
  f.display 'activity'
65
65
  f.sample 'Troubleshooting'
66
66
  f.dataset.filter( :active => true ).order{ lower(activity) }
67
67
  end
68
-
68
+
69
69
  distinct :module, :tooltip => 'Module or sub-project'
70
70
  plain :charge, :tooltip => 'Is this time billable?'
71
71
  distinct :person, :default => 'John', :tooltip => 'The person who did the work'
72
-
72
+
73
73
  dataset.order( :date, :start, :id )
74
74
  end
75
75
 
@@ -77,11 +77,11 @@ class Entry < Sequel::Model
77
77
  action_builder.action :smart_copy, 'Smart Copy', :shortcut => 'Ctrl+"' do
78
78
  smart_copy( view )
79
79
  end
80
-
80
+
81
81
  action_builder.action :invoice_from_project, 'Invoice from Project', :shortcut => 'Ctrl+Shift+I' do
82
82
  invoice_from_project( view, view.current_index ) do
83
83
  # execute the block if the invoice is changed
84
-
84
+
85
85
  # save this before selection model is cleared
86
86
  current_index = view.current_index
87
87
  view.selection_model.clear
@@ -89,35 +89,35 @@ class Entry < Sequel::Model
89
89
  end
90
90
  end
91
91
  end
92
-
92
+
93
93
  # do a smart copy from the previous line
94
94
  def self.smart_copy( view )
95
95
  view.sanity_check_read_only
96
96
  view.sanity_check_ditto
97
-
97
+
98
98
  # need a reference to current_index here, because selection_model.clear will
99
99
  # invalidate view.current_index. And anyway, its shorter and easier to read.
100
100
  current_index = view.current_index
101
101
  if current_index.row >= 1
102
102
  # fetch previous item
103
103
  previous_item = view.model.collection[current_index.row - 1]
104
-
104
+
105
105
  # copy the relevant fields
106
106
  current_index.entity.date = previous_item.date if current_index.entity.date.nil?
107
107
  # depends on previous line
108
108
  current_index.entity.start = previous_item.end if current_index.entity.date == previous_item.date
109
-
109
+
110
110
  # copy rest of fields
111
111
  [:project, :invoice, :activity, :module, :charge, :person].each do |attr|
112
112
  current_index.entity.send( "#{attr.to_s}=", previous_item.send( attr ) )
113
113
  end
114
-
114
+
115
115
  # tell view to update
116
116
  view.model.data_changed do |change|
117
117
  change.top_left = current_index.choppy( :column => 0 )
118
118
  change.bottom_right = current_index.choppy( :column => view.model.fields.size - 1 )
119
119
  end
120
-
120
+
121
121
  # move to the first empty time field
122
122
  next_field =
123
123
  if current_index.entity.start.nil?
@@ -125,7 +125,7 @@ class Entry < Sequel::Model
125
125
  else
126
126
  :end
127
127
  end
128
-
128
+
129
129
  # next cursor location
130
130
  view.selection_model.clear
131
131
  view.current_index = current_index.choppy( :column => next_field )
@@ -142,10 +142,10 @@ class Entry < Sequel::Model
142
142
  unless invoice.nil?
143
143
  # make a reference to the invoice
144
144
  current_index.entity.invoice = invoice
145
-
145
+
146
146
  # update view from top_left to bottom_right
147
147
  table_view.model.data_changed( current_index.choppy( :column => :invoice ) )
148
-
148
+
149
149
  unless block.nil?
150
150
  if block.arity == 1
151
151
  block.call( invoice )
@@ -156,14 +156,14 @@ class Entry < Sequel::Model
156
156
  end
157
157
  end
158
158
  end
159
-
159
+
160
160
  end
161
161
 
162
162
  class Invoice < Sequel::Model
163
163
  include Clevic::Record
164
-
164
+
165
165
  one_to_many :entries
166
-
166
+
167
167
  define_ui do
168
168
  plain :date
169
169
  distinct :client
@@ -173,7 +173,7 @@ class Invoice < Sequel::Model
173
173
  plain :quote_date, :format => '%d-%b-%y', :edit_format => '%d-%b-%Y', :tooltip => 'the date and time when the quote was supplied', :default => lambda{|x| DateTime.now}
174
174
  plain :quote_amount
175
175
  plain :description
176
-
176
+
177
177
  dataset.order( :invoice_number )
178
178
  end
179
179
  end
@@ -182,17 +182,17 @@ class Project < Sequel::Model
182
182
  one_to_many :entries
183
183
 
184
184
  include Clevic::Record
185
-
185
+
186
186
  define_ui do
187
187
  plain :project
188
188
  plain :description
189
189
  distinct :client
190
190
  plain :rate
191
191
  plain :active
192
-
192
+
193
193
  dataset.order( :project )
194
194
  end
195
-
195
+
196
196
  # Return the latest invoice for this project
197
197
  # Not part of the UI.
198
198
  def latest_invoice
@@ -207,12 +207,12 @@ class Activity < Sequel::Model
207
207
  one_to_many :entries
208
208
 
209
209
  include Clevic::Record
210
-
210
+
211
211
  # define how fields are displayed
212
212
  define_ui do
213
213
  plain :activity
214
214
  plain :active
215
-
215
+
216
216
  dataset.order( :activity )
217
217
  end
218
218
  end