clevic 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,8 +1,8 @@
1
1
  =begin
2
2
  ** Form generated from reading ui file 'search_dialog.ui'
3
3
  **
4
- ** Created: Mon Jul 7 22:49:30 2008
5
- ** by: Qt User Interface Compiler version 4.3.2
4
+ ** Created: Wed Jul 23 11:45:29 2008
5
+ ** by: Qt User Interface Compiler version 4.3.3
6
6
  **
7
7
  ** WARNING! All changes made in this file will be lost when recompiling ui file!
8
8
  =end
@@ -20,58 +20,57 @@ class Ui_SearchDialog
20
20
  attr_reader :backwards
21
21
 
22
22
  def setupUi(searchDialog)
23
- searchDialog.setObjectName("searchDialog")
24
- searchDialog.setWindowModality(Qt::WindowModal)
25
- searchDialog.setWindowIcon(Qt::Icon.new("../../hilfer/bin/hilfer-icon.png"))
23
+ if searchDialog.objectName.nil?
24
+ searchDialog.objectName = "searchDialog"
25
+ end
26
+ searchDialog.windowModality = Qt::WindowModal
27
+ searchDialog.resize(307, 400)
28
+ icon = Qt::Icon.new("../../hilfer/bin/hilfer-icon.png")
29
+ searchDialog.windowIcon = icon
26
30
  @button_box = Qt::DialogButtonBox.new(searchDialog)
27
- @button_box.setObjectName("button_box")
28
- @button_box.setGeometry(Qt::Rect.new(30, 240, 261, 32))
29
- @button_box.setOrientation(Qt::Horizontal)
30
- @button_box.setStandardButtons(Qt::DialogButtonBox::Cancel|Qt::DialogButtonBox::NoButton|Qt::DialogButtonBox::Ok)
31
+ @button_box.objectName = "button_box"
32
+ @button_box.geometry = Qt::Rect.new(30, 240, 261, 32)
33
+ @button_box.orientation = Qt::Horizontal
34
+ @button_box.standardButtons = Qt::DialogButtonBox::Cancel|Qt::DialogButtonBox::NoButton|Qt::DialogButtonBox::Ok
31
35
  @selected_rows = Qt::CheckBox.new(searchDialog)
32
- @selected_rows.setObjectName("selected_rows")
33
- @selected_rows.setEnabled(false)
34
- @selected_rows.setGeometry(Qt::Rect.new(30, 280, 191, 21))
36
+ @selected_rows.objectName = "selected_rows"
37
+ @selected_rows.enabled = false
38
+ @selected_rows.geometry = Qt::Rect.new(30, 280, 191, 21)
35
39
  @selected_columns = Qt::CheckBox.new(searchDialog)
36
- @selected_columns.setObjectName("selected_columns")
37
- @selected_columns.setEnabled(false)
38
- @selected_columns.setGeometry(Qt::Rect.new(30, 310, 191, 21))
40
+ @selected_columns.objectName = "selected_columns"
41
+ @selected_columns.enabled = false
42
+ @selected_columns.geometry = Qt::Rect.new(30, 310, 191, 21)
39
43
  @search_label = Qt::Label.new(searchDialog)
40
- @search_label.setObjectName("search_label")
41
- @search_label.setGeometry(Qt::Rect.new(20, 10, 51, 21))
42
- @search_label.setTextFormat(Qt::PlainText)
44
+ @search_label.objectName = "search_label"
45
+ @search_label.geometry = Qt::Rect.new(20, 10, 51, 21)
46
+ @search_label.textFormat = Qt::PlainText
43
47
  @search_combo = Qt::ComboBox.new(searchDialog)
44
- @search_combo.setObjectName("search_combo")
45
- @search_combo.setGeometry(Qt::Rect.new(90, 10, 201, 25))
46
- @search_combo.setFocusPolicy(Qt::StrongFocus)
47
- @search_combo.setEditable(true)
48
+ @search_combo.objectName = "search_combo"
49
+ @search_combo.geometry = Qt::Rect.new(90, 10, 201, 25)
50
+ @search_combo.focusPolicy = Qt::StrongFocus
51
+ @search_combo.editable = true
48
52
  @from_start = Qt::CheckBox.new(searchDialog)
49
- @from_start.setObjectName("from_start")
50
- @from_start.setGeometry(Qt::Rect.new(90, 50, 191, 21))
53
+ @from_start.objectName = "from_start"
54
+ @from_start.geometry = Qt::Rect.new(90, 50, 191, 21)
51
55
  @regex = Qt::CheckBox.new(searchDialog)
52
- @regex.setObjectName("regex")
53
- @regex.setGeometry(Qt::Rect.new(90, 80, 191, 21))
56
+ @regex.objectName = "regex"
57
+ @regex.geometry = Qt::Rect.new(90, 80, 191, 21)
54
58
  @whole_words = Qt::CheckBox.new(searchDialog)
55
- @whole_words.setObjectName("whole_words")
56
- @whole_words.setGeometry(Qt::Rect.new(90, 110, 191, 21))
59
+ @whole_words.objectName = "whole_words"
60
+ @whole_words.geometry = Qt::Rect.new(90, 110, 191, 21)
57
61
  @forwards = Qt::RadioButton.new(searchDialog)
58
- @forwards.setObjectName("forwards")
59
- @forwards.setGeometry(Qt::Rect.new(90, 140, 171, 26))
60
- @forwards.setChecked(true)
62
+ @forwards.objectName = "forwards"
63
+ @forwards.geometry = Qt::Rect.new(90, 140, 171, 26)
64
+ @forwards.checked = true
61
65
  @backwards = Qt::RadioButton.new(searchDialog)
62
- @backwards.setObjectName("backwards")
63
- @backwards.setGeometry(Qt::Rect.new(90, 170, 176, 26))
64
- @search_label.setBuddy(@search_combo)
65
- Qt::Widget::setTabOrder(@search_combo, @selected_columns)
66
- Qt::Widget::setTabOrder(@selected_columns, @selected_rows)
67
- Qt::Widget::setTabOrder(@selected_rows, @button_box)
66
+ @backwards.objectName = "backwards"
67
+ @backwards.geometry = Qt::Rect.new(90, 170, 176, 26)
68
+ @search_label.buddy = @search_combo
69
+ Qt::Widget.setTabOrder(@search_combo, @selected_columns)
70
+ Qt::Widget.setTabOrder(@selected_columns, @selected_rows)
71
+ Qt::Widget.setTabOrder(@selected_rows, @button_box)
68
72
 
69
73
  retranslateUi(searchDialog)
70
-
71
- size = Qt::Size.new(307, 400)
72
- size = size.expandedTo(searchDialog.minimumSizeHint())
73
- searchDialog.resize(size)
74
-
75
74
  Qt::Object.connect(@button_box, SIGNAL('accepted()'), searchDialog, SLOT('accept()'))
76
75
  Qt::Object.connect(@button_box, SIGNAL('rejected()'), searchDialog, SLOT('reject()'))
77
76
 
@@ -83,15 +82,15 @@ class Ui_SearchDialog
83
82
  end
84
83
 
85
84
  def retranslateUi(searchDialog)
86
- searchDialog.setWindowTitle(Qt::Application.translate("SearchDialog", "Search", nil, Qt::Application::UnicodeUTF8))
87
- @selected_rows.setText(Qt::Application.translate("SearchDialog", "Selected Rows", nil, Qt::Application::UnicodeUTF8))
88
- @selected_columns.setText(Qt::Application.translate("SearchDialog", "Selected Columns", nil, Qt::Application::UnicodeUTF8))
89
- @search_label.setText(Qt::Application.translate("SearchDialog", "Search", nil, Qt::Application::UnicodeUTF8))
90
- @from_start.setText(Qt::Application.translate("SearchDialog", "From &Start", nil, Qt::Application::UnicodeUTF8))
91
- @regex.setText(Qt::Application.translate("SearchDialog", "&Regular Expression", nil, Qt::Application::UnicodeUTF8))
92
- @whole_words.setText(Qt::Application.translate("SearchDialog", "&Whole Words", nil, Qt::Application::UnicodeUTF8))
93
- @forwards.setText(Qt::Application.translate("SearchDialog", "&Forwards", nil, Qt::Application::UnicodeUTF8))
94
- @backwards.setText(Qt::Application.translate("SearchDialog", "&Backwards", nil, Qt::Application::UnicodeUTF8))
85
+ searchDialog.windowTitle = Qt::Application.translate("SearchDialog", "Search", nil, Qt::Application::UnicodeUTF8)
86
+ @selected_rows.text = Qt::Application.translate("SearchDialog", "Selected Rows", nil, Qt::Application::UnicodeUTF8)
87
+ @selected_columns.text = Qt::Application.translate("SearchDialog", "Selected Columns", nil, Qt::Application::UnicodeUTF8)
88
+ @search_label.text = Qt::Application.translate("SearchDialog", "Search", nil, Qt::Application::UnicodeUTF8)
89
+ @from_start.text = Qt::Application.translate("SearchDialog", "From &Start", nil, Qt::Application::UnicodeUTF8)
90
+ @regex.text = Qt::Application.translate("SearchDialog", "&Regular Expression", nil, Qt::Application::UnicodeUTF8)
91
+ @whole_words.text = Qt::Application.translate("SearchDialog", "&Whole Words", nil, Qt::Application::UnicodeUTF8)
92
+ @forwards.text = Qt::Application.translate("SearchDialog", "&Forwards", nil, Qt::Application::UnicodeUTF8)
93
+ @backwards.text = Qt::Application.translate("SearchDialog", "&Backwards", nil, Qt::Application::UnicodeUTF8)
95
94
  end # retranslateUi
96
95
 
97
96
  def retranslate_ui(searchDialog)
@@ -1,7 +1,7 @@
1
1
  module Clevic #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
- MINOR = 6
4
+ MINOR = 7
5
5
  TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
@@ -2,13 +2,17 @@ require 'clevic.rb'
2
2
 
3
3
  # db connection
4
4
  Clevic::DbOptions.connect( $options ) do
5
- database( debug? ? :accounts_test : :accounts )
5
+ # use a different db for testing, so real data doesn't get broken.
6
+ if options[:database].nil? || options[:database].empty?
7
+ database( debug? ? :accounts_test : :accounts )
8
+ else
9
+ database options[:database]
10
+ end
6
11
  adapter :postgresql
7
- username 'panic'
12
+ username 'accounts'
8
13
  end
9
14
 
10
- class Entry < ActiveRecord::Base
11
- include ActiveRecord::Dirty
15
+ class Entry < Clevic::Record
12
16
  belongs_to :debit, :class_name => 'Account', :foreign_key => 'debit_id'
13
17
  belongs_to :credit, :class_name => 'Account', :foreign_key => 'credit_id'
14
18
 
@@ -16,9 +20,9 @@ class Entry < ActiveRecord::Base
16
20
  def self.ui( parent )
17
21
  Clevic::TableView.new( self, parent ).create_model do
18
22
  plain :date, :sample => '88-WWW-99'
19
- distinct :description, :conditions => "now() - date <= '1 year'", :sample => 'm' * 26, :frequency => true
20
- relational :debit, 'name', :class_name => 'Account', :conditions => 'active = true', :order => 'lower(name)', :sample => 'Leilani Member Loan'
21
- relational :credit, 'name', :class_name => 'Account', :conditions => 'active = true', :order => 'lower(name)', :sample => 'Leilani Member Loan'
23
+ distinct :description, :conditions => "now() - date <= '1 year'", :sample => 'm' * 26
24
+ relational :debit, :display => 'name', :conditions => 'active = true', :order => 'lower(name)', :sample => 'Leilani Member Loan'
25
+ relational :credit, :display => 'name', :conditions => 'active = true', :order => 'lower(name)', :sample => 'Leilani Member Loan'
22
26
  plain :amount, :sample => 999999.99
23
27
  distinct :category
24
28
  plain :cheque_number
@@ -73,8 +77,7 @@ class Entry < ActiveRecord::Base
73
77
  end
74
78
  end
75
79
 
76
- class Account < ActiveRecord::Base
77
- include ActiveRecord::Dirty
80
+ class Account < Clevic::Record
78
81
  has_many :debits, :class_name => 'Entry', :foreign_key => 'debit_id'
79
82
  has_many :credits, :class_name => 'Entry', :foreign_key => 'credit_id'
80
83
 
@@ -92,6 +95,3 @@ class Account < ActiveRecord::Base
92
95
  end
93
96
  end
94
97
  end
95
-
96
- # order of tab display
97
- $options[:models] = [ Entry, Account ]
@@ -0,0 +1,19 @@
1
+ require 'clevic.rb'
2
+
3
+ # db connection
4
+ Clevic::DbOptions.connect do
5
+ database 'accounts_test'
6
+ adapter :postgresql
7
+ username 'accounts'
8
+ end
9
+
10
+ # minimal definition to get combo boxes to show up
11
+ class Entry < Clevic::Record
12
+ belongs_to :debit, :class_name => 'Account', :foreign_key => 'debit_id'
13
+ belongs_to :credit, :class_name => 'Account', :foreign_key => 'credit_id'
14
+ end
15
+
16
+ # minimal definition to get sensible values in combo boxes
17
+ class Account < Clevic::Record
18
+ def to_s; name; end
19
+ end
@@ -0,0 +1,156 @@
1
+ require 'clevic.rb'
2
+
3
+ # db connection options
4
+ db = Clevic::DbOptions.connect( $options ) do
5
+ # use a different db for testing, so real data doesn't get broken.
6
+ database( debug? ? :times_test : :times )
7
+ adapter :postgresql
8
+ username 'times'
9
+ end
10
+
11
+ # model definitions
12
+ class Entry < Clevic::Record
13
+ belongs_to :invoice
14
+ belongs_to :activity
15
+ belongs_to :project
16
+
17
+ # define how fields are displayed
18
+ def self.ui( parent )
19
+ Clevic::TableView.new( self, parent ).create_model do
20
+ plain :date, :sample => '28-Dec-08'
21
+ relational :project, :display => 'project', :conditions => 'active = true', :order => 'lower(project)'
22
+ relational :invoice, :display => 'invoice_number', :conditions => "status = 'not sent'", :order => 'invoice_number'
23
+ plain :start
24
+ plain :end
25
+ plain :description, :sample => 'This is a long string designed to hold lots of data and description'
26
+ relational :activity, :display => 'activity', :order => 'lower(activity)', :sample => 'Troubleshooting', :conditions => 'active = true'
27
+ distinct :module, :tooltip => 'Module or sub-project'
28
+ plain :charge, :tooltip => 'Is this time billable?'
29
+ distinct :person, :tooltip => 'The person who did the work'
30
+
31
+ records :order => 'date, start, id'
32
+ end
33
+ end
34
+
35
+ # called when a key is pressed in this model's table view
36
+ def self.key_press_event( event, current_index, view )
37
+ case
38
+ # copy almost all of the previous line
39
+ when event.ctrl? && event.quote_dbl?
40
+ if current_index.row > 1
41
+ # fetch previous item
42
+ model = current_index.model
43
+ previous_item = model.collection[current_index.row - 1]
44
+
45
+ # copy the relevant fields
46
+ current_index.entity.start = previous_item.end
47
+ [:date, :project, :invoice, :activity, :module, :charge, :person].each do |attr|
48
+ current_index.entity.send( "#{attr.to_s}=", previous_item.send( attr ) )
49
+ end
50
+
51
+ # tell view to update
52
+ top_left_index = model.create_index( current_index.row, 0 )
53
+ bottom_right_index = model.create_index( current_index.row, current_index.column + view.builder.fields.size )
54
+ view.dataChanged( top_left_index, bottom_right_index )
55
+
56
+ # move to end time field
57
+ view.override_next_index( model.create_index( current_index.row, view.builder.index( :end ) ) )
58
+ end
59
+ # don't let anybody else handle the keypress
60
+ return true
61
+
62
+ when event.ctrl? && event.i?
63
+ invoice_from_project( current_index, view )
64
+ # don't let anybody else handle the keypress
65
+ return true
66
+ end
67
+ end
68
+
69
+ # called when data is changed in this model's table view
70
+ def self.data_changed( top_left, bottom_right, view )
71
+ invoice_from_project( top_left, view ) if ( top_left == bottom_right )
72
+ end
73
+
74
+ def self.invoice_from_project( current_index, view )
75
+ # auto-complete invoice number field from project
76
+ current_field = current_index.attribute
77
+ if current_field == :project && current_index.entity.project != nil
78
+ # most recent entry, ordered in reverse
79
+ invoice = current_index.entity.project.latest_invoice
80
+
81
+ unless invoice.nil?
82
+ # make a reference to the invoice
83
+ current_index.entity.invoice = invoice
84
+
85
+ # update view from top_left to bottom_right
86
+ model = current_index.model
87
+ changed_index = model.create_index( current_index.row, view.builder.index( :invoice ) )
88
+ view.dataChanged( changed_index, changed_index )
89
+
90
+ # move edit cursor to start time field
91
+ view.override_next_index( model.create_index( current_index.row, view.builder.index( :start ) ) )
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ class Invoice < Clevic::Record
98
+ has_many :entries
99
+
100
+ # define how fields are displayed
101
+ def self.ui( parent )
102
+ Clevic::TableView.new( self, parent ).create_model do
103
+ plain :date
104
+ distinct :client
105
+ plain :invoice_number
106
+ restricted :status, :set => ['not sent', 'sent', 'paid', 'debt', 'writeoff', 'internal']
107
+ restricted :billing, :set => %w{Hours Quote Internal}
108
+ plain :quote_date
109
+ plain :quote_amount
110
+ plain :description
111
+
112
+ records :order => 'invoice_number'
113
+ end
114
+ end
115
+ end
116
+
117
+ class Project < Clevic::Record
118
+ has_many :entries
119
+
120
+ def self.ui( parent )
121
+ Clevic::TableView.new( Project, parent ).create_model do
122
+ plain :project
123
+ plain :description
124
+ distinct :client
125
+ plain :rate
126
+ plain :active
127
+
128
+ records :order => 'project'
129
+ end
130
+ end
131
+
132
+ # Return the latest invoice for this project
133
+ # Not part of the UI.
134
+ def latest_invoice
135
+ Invoice.find(
136
+ :first,
137
+ :conditions => ["client = ? and status = 'not sent'", self.client],
138
+ :order => 'invoice_number desc'
139
+ )
140
+ end
141
+
142
+ end
143
+
144
+ class Activity < Clevic::Record
145
+ has_many :entries
146
+
147
+ # define how fields are displayed
148
+ def self.ui( parent )
149
+ Clevic::TableView.new( Activity, parent ).create_model do
150
+ plain :activity
151
+ plain :active
152
+
153
+ records :order => 'activity'
154
+ end
155
+ end
156
+ end
@@ -2,14 +2,12 @@ require 'clevic.rb'
2
2
 
3
3
  # db connection options
4
4
  Clevic::DbOptions.connect( $options ) do
5
- database( debug? ? :times_test : :times )
6
- adapter :postgresql
7
- username 'panic'
5
+ database :times
6
+ adapter :sqlite3
8
7
  end
9
8
 
10
9
  # model definitions
11
- class Entry < ActiveRecord::Base
12
- include ActiveRecord::Dirty
10
+ class Entry < Clevic::Record
13
11
  belongs_to :invoice
14
12
  belongs_to :activity
15
13
  belongs_to :project
@@ -18,12 +16,12 @@ class Entry < ActiveRecord::Base
18
16
  def self.ui( parent )
19
17
  Clevic::TableView.new( self, parent ).create_model do
20
18
  plain :date, :sample => '28-Dec-08'
21
- relational :project, 'project', :conditions => 'active = true', :order => 'lower(project)'
22
- relational :invoice, 'invoice_number', :conditions => "status = 'not sent'", :order => 'invoice_number'
19
+ relational :project, :display => 'project', :conditions => "active = true", :order => 'lower(project)'
20
+ relational :invoice, :display => 'invoice_number', :conditions => "status = 'not sent'", :order => 'invoice_number'
23
21
  plain :start
24
22
  plain :end
25
23
  plain :description, :sample => 'This is a long string designed to hold lots of data and description'
26
- relational :activity, 'activity', :order => 'lower(activity)', :sample => 'Troubleshooting', :conditions => 'active = true'
24
+ relational :activity, :display => 'activity', :order => 'lower(activity)', :sample => 'Troubleshooting', :conditions => 'active = #{connection.quoted_true}'
27
25
  distinct :module, :tooltip => 'Module or sub-project'
28
26
  plain :charge, :tooltip => 'Is this time billable?'
29
27
  distinct :person, :tooltip => 'The person who did the work'
@@ -94,8 +92,7 @@ class Entry < ActiveRecord::Base
94
92
  end
95
93
  end
96
94
 
97
- class Project < ActiveRecord::Base
98
- include ActiveRecord::Dirty
95
+ class Project < Clevic::Record
99
96
  has_many :entries
100
97
 
101
98
  def self.ui( parent )
@@ -122,8 +119,7 @@ class Project < ActiveRecord::Base
122
119
 
123
120
  end
124
121
 
125
- class Activity < ActiveRecord::Base
126
- include ActiveRecord::Dirty
122
+ class Activity < Clevic::Record
127
123
  has_many :entries
128
124
 
129
125
  # define how fields are displayed
@@ -137,15 +133,14 @@ class Activity < ActiveRecord::Base
137
133
  end
138
134
  end
139
135
 
140
- class Invoice < ActiveRecord::Base
141
- include ActiveRecord::Dirty
136
+ class Invoice < Clevic::Record
142
137
  has_many :entries
143
138
 
144
139
  # define how fields are displayed
145
140
  def self.ui( parent )
146
141
  Clevic::TableView.new( Invoice, parent ).create_model do
147
142
  plain :date
148
- distinct :client, :frequency => true
143
+ distinct :client
149
144
  plain :invoice_number
150
145
  restricted :status, :set => ['not sent', 'sent', 'paid', 'debt', 'writeoff', 'internal']
151
146
  restricted :billing, :set => %w{Hours Quote Internal}
@@ -157,6 +152,3 @@ class Invoice < ActiveRecord::Base
157
152
  end
158
153
  end
159
154
  end
160
-
161
- # tab widget order
162
- $options[:models] = [ Entry, Invoice, Project, Activity ]