qtext 0.3.3 → 0.4.1
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.
- data/lib/qtext/extensions.rb +16 -0
- data/lib/qtext/object_table_model.rb +218 -0
- data/lib/qtext/version.rb +2 -2
- data/test/test_object_table.rb +27 -0
- metadata +4 -2
data/lib/qtext/extensions.rb
CHANGED
@@ -213,6 +213,14 @@ module Qt
|
|
213
213
|
end
|
214
214
|
end
|
215
215
|
|
216
|
+
class TableView
|
217
|
+
# otherwise model object gets garbage-collected
|
218
|
+
def model=( m )
|
219
|
+
@model = m
|
220
|
+
super( m )
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
216
224
|
class TabWidget
|
217
225
|
include Enumerable
|
218
226
|
def each_tab( &block )
|
@@ -224,6 +232,14 @@ module Qt
|
|
224
232
|
alias_method :each, :each_tab
|
225
233
|
# can't alias this because it doesn't work with Qt bindings
|
226
234
|
def size; self.count; end
|
235
|
+
|
236
|
+
def []( index )
|
237
|
+
self.widget( index )
|
238
|
+
end
|
239
|
+
|
240
|
+
def clear
|
241
|
+
remove_tab( size - 1 ) while size > 0
|
242
|
+
end
|
227
243
|
end
|
228
244
|
|
229
245
|
class Variant
|
@@ -0,0 +1,218 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'qtext/flags.rb'
|
3
|
+
|
4
|
+
class Header
|
5
|
+
attr_reader :attribute, :title, :alignment
|
6
|
+
|
7
|
+
def initialize( args = {} )
|
8
|
+
raise "there must be an attribute" unless args.has_key?( :attribute )
|
9
|
+
@attribute = args[:attribute]
|
10
|
+
@title = args[:title] || @attribute.to_s.humanize
|
11
|
+
@alignment = args[:alignment] || ( Qt::AlignLeft | Qt::AlignVCenter )
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
=begin rdoc
|
16
|
+
A Qt TableModel that is given a collection of objects, and a collection
|
17
|
+
of headers, which are methods to call on the objects to populate columns
|
18
|
+
=end
|
19
|
+
class ObjectTableModel < Qt::AbstractTableModel
|
20
|
+
include QtFlags
|
21
|
+
attr_reader :collection, :headers
|
22
|
+
|
23
|
+
# data => array of objects
|
24
|
+
# headers => array of methods to call on objects
|
25
|
+
def initialize( args = {} )
|
26
|
+
super()
|
27
|
+
@collection = args[:data] || args[:collection] || []
|
28
|
+
set_headers( args[:headers] )
|
29
|
+
end
|
30
|
+
|
31
|
+
# implementation of Qt:AbstractItemModel method
|
32
|
+
def rowCount( parent_model_index )
|
33
|
+
if parent_model_index.valid?
|
34
|
+
0
|
35
|
+
else
|
36
|
+
collection.size
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def columnCount( parent_model_index = Qt::ModelIndex.invalid )
|
41
|
+
if parent_model_index.valid?
|
42
|
+
0
|
43
|
+
else
|
44
|
+
headers.size
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def attribute_for_index( column )
|
49
|
+
headers[column]
|
50
|
+
end
|
51
|
+
|
52
|
+
def field_value_at( index )
|
53
|
+
obj = collection[index.row]
|
54
|
+
att = attribute_for_index( index.column ).attribute
|
55
|
+
obj.send( att ) unless obj.nil? or att.nil?
|
56
|
+
end
|
57
|
+
|
58
|
+
# implementation of Qt:AbstractItemModel method
|
59
|
+
def headerData( section, orientation, role )
|
60
|
+
value =
|
61
|
+
case orientation
|
62
|
+
when Qt::Vertical
|
63
|
+
case role
|
64
|
+
when qt_display_role
|
65
|
+
( section + 1 ).to_s
|
66
|
+
|
67
|
+
when qt_text_alignment_role
|
68
|
+
Qt::AlignVCenter | Qt::AlignRight
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
when Qt::Horizontal
|
73
|
+
case role
|
74
|
+
when qt_display_role
|
75
|
+
headers[section].title
|
76
|
+
|
77
|
+
when qt_text_alignment_role
|
78
|
+
Qt::AlignVCenter | Qt::AlignCenter
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
value.to_variant
|
83
|
+
end
|
84
|
+
|
85
|
+
# implementation of Qt:AbstractItemModel method
|
86
|
+
def data( index, role = qt_display_role )
|
87
|
+
return nil.to_variant unless index.valid?
|
88
|
+
#~ puts "requesting data for index: #{index.inspect} and role: #{const_as_string role}"
|
89
|
+
begin
|
90
|
+
retval =
|
91
|
+
case role
|
92
|
+
when qt_display_role, qt_edit_role
|
93
|
+
field_value_at( index )
|
94
|
+
|
95
|
+
when qt_text_alignment_role
|
96
|
+
headers[index.column].alignment
|
97
|
+
|
98
|
+
when qt_checkstate_role
|
99
|
+
#~ value = self[index.row].send( attribute_for_index( index.column ) )
|
100
|
+
#~ value ? Qt::Checked : Qt::Unchecked
|
101
|
+
|
102
|
+
# these are just here to make debug output quieter
|
103
|
+
when qt_size_hint_role;
|
104
|
+
when qt_background_role;
|
105
|
+
when qt_font_role;
|
106
|
+
when qt_foreground_role;
|
107
|
+
when qt_decoration_role;
|
108
|
+
|
109
|
+
when qt_tooltip_role;
|
110
|
+
|
111
|
+
else
|
112
|
+
puts "data index: #{index}, role: #{const_as_string(role)}" if $OPTIONS[:debug]
|
113
|
+
nil
|
114
|
+
end
|
115
|
+
|
116
|
+
# return a variant
|
117
|
+
retval.to_variant
|
118
|
+
rescue Exception => e
|
119
|
+
puts e.backtrace.join( "\n" )
|
120
|
+
puts "#{index.inspect} #{e.message}"
|
121
|
+
nil.to_variant
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# implementation of Qt:AbstractItemModel method
|
126
|
+
def setData( index, variant, role = qt_edit_role )
|
127
|
+
return false unless index.valid?
|
128
|
+
begin
|
129
|
+
item = self[index.row]
|
130
|
+
method_name = attribute_for_index( index.column ).to_s
|
131
|
+
value =
|
132
|
+
case role
|
133
|
+
when qt_edit_role
|
134
|
+
variant.value
|
135
|
+
when qt_checkstate_role
|
136
|
+
case variant.value
|
137
|
+
when Qt::Checked; true
|
138
|
+
when Qt::Unchecked; false
|
139
|
+
else; false
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# update UI
|
144
|
+
emit dataChanged( index, index )
|
145
|
+
|
146
|
+
# value conversion OK
|
147
|
+
true
|
148
|
+
rescue Exception => e
|
149
|
+
puts e.message
|
150
|
+
false
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# implementation of Qt:AbstractItemModel method
|
155
|
+
# TODO make this editable
|
156
|
+
def flags( index )
|
157
|
+
return 0 unless index.valid?
|
158
|
+
super
|
159
|
+
end
|
160
|
+
|
161
|
+
def []( index )
|
162
|
+
collection[index]
|
163
|
+
end
|
164
|
+
|
165
|
+
def []=( index, value )
|
166
|
+
if index >= collection.size
|
167
|
+
beginInsertRows( Qt::ModelIndex.invalid, collection.size, collection.size + ( index - collection.size ) )
|
168
|
+
collection[index] = value
|
169
|
+
endInsertRows
|
170
|
+
else
|
171
|
+
collection[index] = value
|
172
|
+
emit dataChanged( create_index( index.row, 0 ), create_index( index.row, columnCount ) )
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def <<( obj )
|
177
|
+
beginInsertRows( Qt::ModelIndex.invalid, collection.size, collection.size )
|
178
|
+
collection << obj
|
179
|
+
endInsertRows
|
180
|
+
end
|
181
|
+
|
182
|
+
include Enumerable
|
183
|
+
def each( &block )
|
184
|
+
collection.each( &block )
|
185
|
+
end
|
186
|
+
|
187
|
+
def to_a
|
188
|
+
collection.dup
|
189
|
+
end
|
190
|
+
|
191
|
+
def clear
|
192
|
+
collection.clear
|
193
|
+
reset
|
194
|
+
end
|
195
|
+
|
196
|
+
def collection=( ary )
|
197
|
+
@collection = ary
|
198
|
+
reset
|
199
|
+
end
|
200
|
+
|
201
|
+
# a collection of CheckableFields
|
202
|
+
def headers=( arr )
|
203
|
+
set_headers( arr )
|
204
|
+
reset
|
205
|
+
end
|
206
|
+
|
207
|
+
protected
|
208
|
+
def set_headers( arr )
|
209
|
+
# convert headers to Header objects, if they aren't already
|
210
|
+
@headers = arr.map do |obj|
|
211
|
+
if obj.class == Header
|
212
|
+
obj
|
213
|
+
else
|
214
|
+
Header.new( :attribute => obj.to_sym )
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
data/lib/qtext/version.rb
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
require 'qtext/object_table_model.rb'
|
3
|
+
require 'Qt4'
|
4
|
+
|
5
|
+
class TestObjectTableModel < Test::Unit::TestCase
|
6
|
+
Thing = Struct.new( :name, :value, :location, :price )
|
7
|
+
def setup
|
8
|
+
@data = [
|
9
|
+
Thing.new( "Screwdriver", 'high', 'toolbox', 10.96 ),
|
10
|
+
Thing.new( "Thermometer", '15 degrees', 'bathroom', 0.01 ),
|
11
|
+
Thing.new( "Bed", 'large', 'bedroom' ),
|
12
|
+
Thing.new( "Approximation", 'useful', 'maths', 'none' )
|
13
|
+
]
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_model
|
17
|
+
model = ObjectTableModel.new( :data => @data, :headers => [ :name, :value, :location, :price ] )
|
18
|
+
app = Qt::Application.new( [] )
|
19
|
+
main_window = Qt::MainWindow.new
|
20
|
+
main_window.central_widget = Qt::TableView.construct( main_window ) { |tv| tv.model = model }
|
21
|
+
|
22
|
+
main_window.window_title = 'Test ObjectTableModel'
|
23
|
+
main_window.move( 150, 0 )
|
24
|
+
main_window.show
|
25
|
+
app.exec
|
26
|
+
end
|
27
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qtext
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- FIXME full name
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-07-
|
12
|
+
date: 2008-07-23 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -37,6 +37,7 @@ files:
|
|
37
37
|
- lib/qtext/version.rb
|
38
38
|
- lib/qtext/flags.rb
|
39
39
|
- lib/qtext/extensions.rb
|
40
|
+
- lib/qtext/object_table_model.rb
|
40
41
|
has_rdoc: true
|
41
42
|
homepage: http://qtext.rubyforge.org
|
42
43
|
post_install_message: |+
|
@@ -72,5 +73,6 @@ signing_key:
|
|
72
73
|
specification_version: 2
|
73
74
|
summary: description of gem
|
74
75
|
test_files:
|
76
|
+
- test/test_object_table.rb
|
75
77
|
- test/test_qtext.rb
|
76
78
|
- test/test_helper.rb
|