clevic 0.8.0 → 0.11.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/History.txt +9 -0
  2. data/Manifest.txt +13 -10
  3. data/README.txt +6 -9
  4. data/Rakefile +35 -24
  5. data/TODO +29 -17
  6. data/bin/clevic +84 -37
  7. data/config/hoe.rb +7 -3
  8. data/lib/clevic.rb +2 -4
  9. data/lib/clevic/browser.rb +37 -49
  10. data/lib/clevic/cache_table.rb +55 -165
  11. data/lib/clevic/db_options.rb +32 -21
  12. data/lib/clevic/default_view.rb +66 -0
  13. data/lib/clevic/delegates.rb +51 -67
  14. data/lib/clevic/dirty.rb +101 -0
  15. data/lib/clevic/extensions.rb +24 -38
  16. data/lib/clevic/field.rb +400 -99
  17. data/lib/clevic/item_delegate.rb +32 -33
  18. data/lib/clevic/model_builder.rb +315 -148
  19. data/lib/clevic/order_attribute.rb +53 -0
  20. data/lib/clevic/record.rb +57 -57
  21. data/lib/clevic/search_dialog.rb +71 -67
  22. data/lib/clevic/sql_dialects.rb +33 -0
  23. data/lib/clevic/table_model.rb +73 -120
  24. data/lib/clevic/table_searcher.rb +165 -0
  25. data/lib/clevic/table_view.rb +140 -100
  26. data/lib/clevic/ui/.gitignore +1 -0
  27. data/lib/clevic/ui/browser_ui.rb +55 -56
  28. data/lib/clevic/ui/search_dialog_ui.rb +50 -51
  29. data/lib/clevic/version.rb +2 -2
  30. data/lib/clevic/view.rb +89 -0
  31. data/models/accounts_models.rb +12 -9
  32. data/models/minimal_models.rb +4 -2
  33. data/models/times_models.rb +41 -25
  34. data/models/times_sqlite_models.rb +1 -145
  35. data/models/values_models.rb +15 -16
  36. data/test/test_cache_table.rb +138 -0
  37. data/test/test_helper.rb +131 -0
  38. data/test/test_model_index_extensions.rb +22 -0
  39. data/test/test_order_attribute.rb +62 -0
  40. data/test/test_sql_dialects.rb +77 -0
  41. data/test/test_table_searcher.rb +188 -0
  42. metadata +36 -20
  43. data/bin/import-times +0 -128
  44. data/config/jamis.rb +0 -589
  45. data/env.sh +0 -1
  46. data/lib/active_record/dirty.rb +0 -87
  47. data/lib/clevic/field_builder.rb +0 -42
  48. data/website/index.html +0 -170
  49. data/website/index.txt +0 -17
  50. data/website/screenshot.png +0 -0
  51. data/website/stylesheets/screen.css +0 -131
  52. data/website/template.html.erb +0 -41
@@ -1,3 +1,12 @@
1
+ == 0.11.1
2
+ * Define views in separate classes (subclass of Clevic::View) while
3
+ maintaining view definition inside the ActiveRecord::Base subclass.
4
+ * foreground and background color specifiers for fields
5
+ * better handling of virtual fields
6
+ * more tests
7
+ * make Clevic::Record a module to be included in an ActiveRecord::Base
8
+ * use Gather for hash/block value collection.
9
+
1
10
  == 0.8.0
2
11
  * Big improvements to the way the UI is defined in Entity classes.
3
12
  * Show Entity-specific menus, both in the menu bar and as a right-click.
@@ -4,27 +4,29 @@ README.txt
4
4
  Rakefile
5
5
  TODO
6
6
  bin/clevic
7
- bin/import-times
8
7
  config/hoe.rb
9
- config/jamis.rb
10
8
  config/requirements.rb
11
- env.sh
12
- lib/active_record/dirty.rb
9
+ lib/clevic/dirty.rb
13
10
  lib/clevic.rb
14
11
  lib/clevic/browser.rb
15
12
  lib/clevic/cache_table.rb
16
13
  lib/clevic/db_options.rb
14
+ lib/clevic/default_view.rb
17
15
  lib/clevic/delegates.rb
18
16
  lib/clevic/extensions.rb
19
17
  lib/clevic/field.rb
20
- lib/clevic/field_builder.rb
21
18
  lib/clevic/item_delegate.rb
22
19
  lib/clevic/model_builder.rb
23
20
  lib/clevic/model_column.rb
21
+ lib/clevic/order_attribute.rb
24
22
  lib/clevic/record.rb
25
23
  lib/clevic/search_dialog.rb
24
+ lib/clevic/sql_dialects.rb
26
25
  lib/clevic/table_model.rb
26
+ lib/clevic/table_searcher.rb
27
27
  lib/clevic/table_view.rb
28
+ lib/clevic/view.rb
29
+ lib/clevic/ui/.gitignore
28
30
  lib/clevic/ui/browser.ui
29
31
  lib/clevic/ui/browser_ui.rb
30
32
  lib/clevic/ui/icon.png
@@ -44,8 +46,9 @@ sql/accounts.sql
44
46
  sql/times.sql
45
47
  sql/times_sqlite.sql
46
48
  tasks/website.rake
47
- website/index.html
48
- website/index.txt
49
- website/screenshot.png
50
- website/stylesheets/screen.css
51
- website/template.html.erb
49
+ test/test_cache_table.rb
50
+ test/test_helper.rb
51
+ test/test_model_index_extensions.rb
52
+ test/test_order_attribute.rb
53
+ test/test_sql_dialects.rb
54
+ test/test_table_searcher.rb
data/README.txt CHANGED
@@ -37,20 +37,17 @@ in Linux, slightly tested in Windows and OSX.
37
37
 
38
38
  === Model definition:
39
39
 
40
- Models and their UI representation must be defined in Ruby. A class that
41
- inherits from Clevic::Record (which itself inherits from ActiveRecord::Base) will provide
42
- a minimally functional UI. Beyond that, the framework provides
43
- a DSL for defining more complex and useful behaviour (see Clevic::ModelBuilder).
40
+ Models and their UI representation must be defined in Ruby. A descendant of ActiveRecord::Base
41
+ that includes the Clevic::Record module will provide a minimally functional UI.
44
42
 
45
- Clevic also knows how to build a default UI with sensible defaults from
46
- ActiveRecord::Base subclasses.
43
+ Beyond that, the framework provides a DSL for defining more complex and useful behaviour
44
+ (see Clevic::ModelBuilder).
47
45
 
48
46
  In the models/ subdirectory, start with minimal_models.rb.
49
47
  account_models.rb and times_models.rb provide definitions for more real-world examples.
50
48
  Associated SQL schemas are in the sql subdirectory.
51
49
 
52
- For implementation and more extensive
53
- comments, see Clevic::Browser and Clevic::ModelBuilder.
50
+ For implementation and more extensive comments, see Clevic::ModelBuilder.
54
51
 
55
52
  === Framework
56
53
 
@@ -84,7 +81,7 @@ See TODO file.
84
81
  === Other
85
82
 
86
83
  * bsearch (http://0xcc.net/ruby-bsearch)
87
- * active_record/dirty (included)
84
+ * active_record/dirty (included, for active_record < 2.1.x)
88
85
  * db driver (ie postgres-pr)
89
86
  * rdbms (ie postgres)
90
87
 
data/Rakefile CHANGED
@@ -15,7 +15,7 @@ end
15
15
 
16
16
  # list of .ui files
17
17
  UI_FILES = FileList.new( 'lib/clevic/ui/*.ui' )
18
- CLEAN.include( 'ChangeLog' )
18
+ CLEAN.include( 'ChangeLog', 'coverage', 'profiling' )
19
19
  CLOBBER.include( 'ChangeLog', 'pkg', 'lib/clevic/ui/*_ui.rb' )
20
20
 
21
21
  UI_FILES.each do |ui_file|
@@ -57,12 +57,6 @@ task :run => :ui do |t|
57
57
  exec "ruby -Ilib bin/clevic #{ARGV.join(' ')}"
58
58
  end
59
59
 
60
- desc "Runs Clevic in warning mode, with test databases and debug flag on"
61
- task :sqlite => :ui do |t|
62
- ARGV.shift()
63
- exec "ruby -Ilib bin/clevic #{ARGV.join(' ')} times_sqlite_model.rb"
64
- end
65
-
66
60
  desc "Runs Clevic in debug mode, with test databases"
67
61
  task :debug => :ui do |t|
68
62
  ARGV.shift()
@@ -90,6 +84,7 @@ MODELS_LIST.each do |model_file|
90
84
  namespace :irb do
91
85
  task short_model( model_file ) do |t|
92
86
  ARGV.shift()
87
+ ARGV.shift() if ARGV[0] == '--'
93
88
  ENV['RUBYLIB'] ||= '.'
94
89
  ENV['RUBYLIB'] += ":#{File.expand_path('.')}/lib"
95
90
  exec "irb -Ilib -rclevic -r#{model_file} -rclevic/db_options.rb"
@@ -99,6 +94,17 @@ MODELS_LIST.each do |model_file|
99
94
  # generate runs
100
95
  namespace :run do
101
96
  desc "run clevic with #{model_file}"
97
+ task short_model( model_file ) => :ui do |t|
98
+ ARGV.shift()
99
+ ARGV.shift() if ARGV[0] == '--'
100
+ cmd = "ruby -Ilib bin/clevic -D #{model_file} #{ARGV.join(' ')}"
101
+ puts "cmd: #{cmd.inspect}"
102
+ exec cmd
103
+ end
104
+ end
105
+
106
+ namespace :warn do
107
+ desc "run clevic with #{model_file} and warnings on"
102
108
  task short_model( model_file ) => :ui do |t|
103
109
  ARGV.shift()
104
110
  exec "ruby -w -Ilib bin/clevic -D #{model_file} #{ARGV.join(' ')}"
@@ -108,25 +114,30 @@ end
108
114
 
109
115
  task :package => :ui
110
116
 
111
- # redefine this from the Hoe-1.7.0 sources to use
112
- # the jamis template.
113
- Rake::RDocTask.new(:docs) do |rd|
114
- rd.main = "README.txt"
115
- rd.options << '-d' if RUBY_PLATFORM !~ /win32/ and `which dot` =~ /\/dot/ and not ENV['NODOT']
116
- rd.rdoc_dir = 'doc'
117
- rd.template = 'config/jamis.rb'
118
- files = $hoe.spec.files.grep($hoe.rdoc_pattern)
119
- files -= ['Manifest.txt']
120
- rd.rdoc_files.push(*files)
121
-
122
- title = "#{$hoe.name}-#{$hoe.version} Documentation"
123
- title = "#{$hoe.rubyforge_name}'s " + title if $hoe.rubyforge_name != $hoe.name
124
-
125
- rd.options << "-t #{title}"
126
- end
127
-
128
117
  desc "Update ChangeLog from the SVN log"
129
118
  task :changelog do |t|
130
119
  ARGV.shift
131
120
  exec "svn2cl --break-before-msg -o ChangeLog #{ARGV.join(' ')}"
132
121
  end
122
+
123
+ # remove hoe documentation task
124
+ Rake::Task['docs'].clear
125
+
126
+ # make this respond to docs, so it fits in with the rest of the build
127
+ Rake::RDocTask.new do |rdoc|
128
+ rdoc.name = :docs
129
+ rdoc.title = "Clevic DB UI builder"
130
+ rdoc.main = 'README.txt'
131
+ rdoc.rdoc_dir = 'doc'
132
+ rdoc.rdoc_files.include %w{History.txt lib/**/*.rb README.txt TODO}
133
+ rdoc.options += [
134
+ '-SHN',
135
+ '-f', 'darkfish', # This is the important bit
136
+ '-A', 'property=Property',
137
+ #~ '--quiet',
138
+ "--opname=index.html",
139
+ #~ "--line-numbers",
140
+ #~ '--format=darkfish',
141
+ #~ "--inline-source"
142
+ ]
143
+ end
data/TODO CHANGED
@@ -1,8 +1,23 @@
1
- rename model_class to entity_class, and related terminology clarification.
2
- tests
3
- allow directories for a setup. Problem here is tab order.
4
- metadata for virtual fields
5
- exception when ditto-left/right to a field with incompatible type
1
+ need a :name specified for Field that defaults to the attribute name
2
+ allow directories for a setup.
3
+ implement the :default field option
4
+ ModelBuilder#modify_field to override default_ui definitions
5
+ rename ModelBuilder to ViewBuilder?
6
+
7
+ need a text field (multiple lines, edit in a separate window)
8
+ need a map field (For ie -1 = short, 1 = long). Already in restricted, but it's kinda clunky.
9
+ :records missing in define_ui causes a crash
10
+
11
+ :display and :format in ModelBuilder
12
+ tests. Use ZenTest to generate tests
13
+ Check out ar-extensions. Like operators look nice.
14
+ make sure ActiveRecord doesn't keep updating column definitions. ie production mode.
15
+ caching of repeated related entity lookups. Possibly ActiveRecord::QueryCache
16
+ Ramen http://ramen.rubyforge.org/ for metadata. MySQL and MSSQL only right now.
17
+
18
+ metadata for virtual fields. Add a member to Field for class_name.constantize
19
+ consolidate metadata across TableModel, and Field. Would like to have it all in Field.
20
+ gui_value vs attribute_value vs field_value etc
6
21
  generate models - DrySQL
7
22
  allow moving of tabs
8
23
  habtm relations
@@ -14,17 +29,16 @@ sorting by header. See void QAbstractItemModel::sort ( int column, Qt::SortOrder
14
29
  - layoutChanged
15
30
 
16
31
  undo
32
+ - could possibly handle this in the TableModel
17
33
  - acts_as_trashable to undo deletes
18
34
  - other commands. Possibly via ActiveRecord callbacks?
19
35
  - Keep a history of changes, ie xy, new. xy, changed. x,y copied etc.
20
36
  - Use Transaction::Simple?
21
37
  - undo of field changes
38
+ - memoize
22
39
 
23
40
  Using F4 to open list, and then selecting from the combo and exiting using Return (or tab?) doesn't set the correct value
24
41
  wrap description, and allow Access-style zooming
25
- Ctrl-PgDn to last row in this column. Also extend selection
26
- sorting by header. See void QAbstractItemModel::sort ( int column, Qt::SortOrder order = Qt::AscendingOrder )
27
- - layoutChanged
28
42
 
29
43
  search with acts_as_searchable and hyperestraier
30
44
 
@@ -33,7 +47,7 @@ moving of columns
33
47
  /-style filtering?
34
48
 
35
49
  for dates, add year if not specified, with 6 months on either side range. Configurable?
36
- value formatting not in model
50
+ value parsing not in model
37
51
  copy a field from a mouse-selection (ctrl-b maybe)
38
52
  hiding of fields
39
53
 
@@ -68,11 +82,11 @@ Ctrl-; date formatting goes 07--08 instead of 07-Apr-08. But typing the full mon
68
82
 
69
83
  empty database
70
84
  --------------
71
- resize fields for first record, while it's being entered. use Qt::ExpandingLineEdit for ComboDelegate? Doesn't exist in Ruby bindings
85
+ resize fields for first record, while it's being entered. use Qt::ExpandingLineEdit for ComboDelegate? Doesn't exist in Ruby bindings.
72
86
 
73
87
  editing
74
88
  -------
75
- F2 for standard edit, F4 for calendar edit
89
+ F2 for standard edit, F4 for full edit, ie text window, or calendar edit
76
90
  Only move for data_changed if field was exited with tab, not enter.
77
91
  tooltips for tabs
78
92
  Help in general for new data capture people
@@ -101,14 +115,15 @@ changes more or less instantly.
101
115
  preferences
102
116
  -----------
103
117
  store previous searches, by model & app
118
+ store year ranges for 2 digit years in dates.
104
119
 
105
120
  maybe
106
121
  -----
107
- acts_as_shellable looks nices
122
+ acts_as_shellable looks nice
108
123
  consolidate read-only-ness checks
109
124
  Look at DataMapper. Not suitable - need to declare properties.
110
- use rubigen for creating model definition files
111
- ActiveMDB for migrating.
125
+ use rubigen for creating model definition files?
126
+ ActiveMDB for migrating?
112
127
  allow moving of rows
113
128
  discontiguous copying of entities/csv
114
129
  multi-row copying
@@ -125,7 +140,6 @@ QueryBuilder
125
140
  Accounts
126
141
  --------
127
142
  paste of "common" records with different dates
128
- restricted type for Account Type record
129
143
 
130
144
  Times
131
145
  -----
@@ -133,5 +147,3 @@ Times
133
147
  Ctrl-Shift-" should not copy date if it already exists, and should not copy time if it's a different date.
134
148
  Ctrl-Shift-" after it's done, tab doesn't change fields
135
149
  look up invoice for project leaves the wrong fields highlighted, and focus in the wrong field.
136
- warnings on overlap times (in status bar, or highlight)
137
- warnings on large intervals (in status bar, or highlight)
data/bin/clevic CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  require 'pathname'
4
4
 
5
+ require 'clevic.rb'
5
6
  require 'clevic/browser.rb'
6
- require 'clevic/db_options.rb'
7
7
  require 'optparse'
8
8
  require 'active_support'
9
9
 
@@ -38,49 +38,91 @@ if $options[:debug]
38
38
  pp $options
39
39
  end
40
40
 
41
+ unless $options[:verbose]
42
+ # turn off "Object#type deprecated" messages
43
+ # and anything else output by rb_warn
44
+ $VERBOSE = nil
45
+ end
46
+
41
47
  class Pathname
42
48
  # require this pathname if it exists
43
49
  def require_if_exists
44
50
  require realpath.to_s if exist?
45
51
  end
52
+
53
+ # just for fun, really
54
+ alias_method :/, :+
55
+ end
56
+
57
+ def subclasses( base )
58
+ classes = []
59
+ ObjectSpace.each_object( Class ) do |x|
60
+ if x.ancestors.include?( base )
61
+ case
62
+ when x == ActiveRecord::Base; # don't include this
63
+ else; classes << x
64
+ end
65
+ end
66
+ end
67
+ classes.sort{|a,b| a.name <=> b.name}
46
68
  end
47
69
 
48
70
  def load_rails_models( root, config, models )
49
71
  # initialize Rails
50
- load config + 'environment.rb'
51
- #~ puts "RAILS_ROOT: #{RAILS_ROOT.inspect}"
72
+ load config / 'environment.rb'
52
73
  require 'initializer.rb'
53
74
  Rails::Initializer.run do |config|
54
75
  config.frameworks -= [ :action_mailer, :action_pack, :active_resource ]
55
76
  end
56
77
 
57
- # load lib/ files
58
- $: << ( root + 'lib' ).realpath.to_s
59
- ( root + 'lib' ).children.each do |filename|
60
- puts "filename: #{filename.inspect}"
78
+ # load lib/ files for the rails project
79
+ $: << ( root / 'lib' ).realpath.to_s
80
+ ( root / 'lib' ).children.each do |filename|
61
81
  load filename if filename.file?
62
82
  end
63
-
64
- # TODO check for Dirty in 2.1.x
65
- ActiveRecord::Base.send(:include, ActiveRecord::Dirty)
83
+
84
+ # include Dirty if it isn't already
85
+ begin
86
+ ActiveRecord::Dirty
87
+ rescue NameError
88
+ ActiveRecord::Base.send(:include, ActiveRecord::Dirty)
89
+ end
66
90
 
67
91
  # load models
68
- models.children.each_with_index do |filename,i|
69
- #~ %w{subscriber}.map{|x| models + "#{x}.rb"}.each_with_index do |filename,i|
92
+ models.find do |dir_entry|
93
+ # don't load directory entries
94
+ next unless dir_entry.file?
95
+ # only load .rb files
96
+ next unless dir_entry.basename.to_s =~ /\.rb$/
70
97
  begin
71
- load filename if filename.file?
98
+ load dir_entry
72
99
  rescue Exception => e
73
- puts "Error loading #{filename.basename.to_s}: #{e.message.inspect}"
100
+ puts "Error loading #{dir_entry.basename.to_s}: #{e.message}"
74
101
  puts e.backtrace
75
102
  end
76
103
  end
104
+
105
+ # include the Clevic::Record module in each descendant of
106
+ # ActiveRecord::Base so that the default views will be created.
107
+ subclasses( ActiveRecord::Base ).each do |model|
108
+ if model.table_exists?
109
+ model.send :include, Clevic::Record unless model.abstract_class?
110
+ end
111
+ end
112
+ end
113
+
114
+ def load_single_model_file( pathname )
115
+ ( pathname + '.rb' ).require_if_exists
116
+ pathname.require_if_exists
117
+ ( pathname + '_models' ).require_if_exists
118
+ ( pathname + '_models.rb' ).require_if_exists
77
119
  end
78
120
 
79
121
  def load_models( pathname )
80
122
  if pathname.directory?
81
- config = pathname + 'config'
82
- app = pathname + 'app'
83
- models = app + 'models'
123
+ config = pathname / 'config'
124
+ app = pathname / 'app'
125
+ models = app / 'models'
84
126
  # check if this is a Rails directory
85
127
  if config.exist? && app.exist? && models.exist?
86
128
  # this is probably a Rails project"
@@ -88,26 +130,31 @@ def load_models( pathname )
88
130
  end
89
131
  else
90
132
  # assume we have a single file, and try some variations
91
- ( pathname + '.rb' ).require_if_exists
92
- pathname.require_if_exists
93
- ( pathname + '_models' ).require_if_exists
94
- ( pathname + '_models.rb' ).require_if_exists
133
+ load_single_model_file( pathname )
95
134
  end
96
135
  end
97
136
 
98
- # load model files
99
- raise "no model definition file specified" if args.empty?
100
- args.each { |arg| load_models( Pathname.new( arg ) ) }
101
-
102
- app = Qt::Application.new( args )
103
-
104
- # show UI
105
- main_window = Qt::MainWindow.new
106
- browser = Clevic::Browser.new( main_window )
107
- # this must come after Clevic::Browser.new
108
- # TODO should really find a better place for this
109
- main_window.window_title = $options[:database]
110
- main_window.show
111
- # make sure any partially edited records are saved when the window is closed
112
- app.connect( SIGNAL('lastWindowClosed()') ) { browser.save_all }
113
- app.exec
137
+ begin
138
+ # load model files
139
+ raise "no model definition file specified" if args.empty?
140
+ args.each { |arg| load_models( Pathname.new( arg ) ) }
141
+
142
+ app = Qt::Application.new( args )
143
+
144
+ # show UI
145
+ main_window = Qt::MainWindow.new
146
+ browser = Clevic::Browser.new( main_window )
147
+ # this must come after Clevic::Browser.new
148
+ main_window.show
149
+ # make sure any partially edited records are saved when the window is closed
150
+ app.connect( SIGNAL('lastWindowClosed()') ) { browser.save_all }
151
+ begin
152
+ app.exec
153
+ rescue
154
+ puts $!.message
155
+ puts $!.backtrace
156
+ end
157
+ rescue Exception => e
158
+ puts e.message
159
+ puts e.backtrace
160
+ end