3 # A class including Gtk::TreeModel which contains a result set from an SQL Statement
6 # Perish the thought! Those are _features_!
9 # Andrew McMillan <andrew@mcmillan.net.nz>
12 # Copyright (c) Andrew McMillan, 2007
13 # GNU General Public License version 2
19 include Gtk::TreeModel
21 def initialize( file_name )
27 def parse_definition( file_name )
29 File.foreach(filename) do |ln|
32 if ln.match( /^([A-Z]+):\s*(#.*)?$/ )
34 elsif ln.match( /^\s*(\S+)(:\S+)?\s*=\s*(\S.*\S?)\s*$/ ) then
37 @size_x = $3.to_i if ( $3.to_i > 100)
40 @size_y = $3.to_i if ( $3.to_i > 100)
46 puts "State: '#{state}', Line: '#{ln.chomp}'"
48 if ln.match( /^:#{state}$/ ) then
55 if ln.match( /^\s*(\S+)(:\S+)?\s*=\s*(\S.*\S?)\s*$/ ) then
56 @fields.set($1, $2, $3 )
63 if ln.match( /^\s*(\S+)\s*=\s*(\S.*\S?)\s*$/ ) then
64 @keys[$1] = $2.split(/\s*,\s*/)
97 # A basic field in an ApmsRecordBrowser
100 attr_reader :name, :heading, :type, :position
101 attr_writer :heading, :type, :position
103 def initialize(in_name)
108 puts " New field '#{in_name}'"
111 def set( what, value )
113 when 'heading', '', nil
115 puts "#{@name} heading set to '#{@heading}'"
118 puts "#{@name} type set to '#{@type}'"
124 # Hash of ApmsField objects which is keyed on the field name
128 @positions = Array.new
132 return @positions.size
144 @positions.each_index do |idx|
145 yield idx, @positions[idx], @fields[@positions[idx]]
149 def set( name, what, value )
150 # puts " Setting '#{what}' to '#{value}' in field '#{name}' "
151 if ( @fields[name] == nil ) then
152 @fields[name] = ApmsField.new(name)
153 @positions.push(name)
154 @fields[name].position = @positions.size
156 @fields[name].set(what,value)
160 class ApmsRecordBrowser
163 # Creates an empty record browser with no columns and no rows, based on
164 # Gtk::TreeView. This class adds some utility functionality to load
165 # the definition of the browser widget from a file.
167 def columns=(col_name_hash)
168 set_columns(col_name_hash)
171 attr_reader :columns, :treeview, :size_x, :size_y
174 @fields = ApmsFieldList.new
175 @treeview = Gtk::TreeView.new
176 @liststore = Gtk::ListStore.new(String,String,String,String,String,String,String,String)
177 load_browse_definition(path)
178 @treeview.set_model(@liststore)
179 @treeview.set_size_request(@size_x, @size_y)
180 @treeview.set_headers_clickable(true)
181 @treeview.set_enable_search(true)
182 @treeview.set_rules_hint(true)
184 # @treeview.signal_connect("event") do |w,e|
185 # if e.event_type != Gdk::Event::MOTION_NOTIFY then
186 # puts "Got event #{e} - '#{e.event_type.inspect}'"
191 # @treeview.signal_connect("key-release-event") do |w,e|
192 # puts "Got key-release event #{e} - '#{e.event_type.inspect}'"
199 n_columns = @fields.size
200 @fields.each_field do |position,field,value|
201 @treeview.append_column(Gtk::TreeViewColumn.new(value.heading, Gtk::CellRendererText.new, {:text => position} ))
205 # This does kind of depend on the SQL returning the columns as named in the
206 # call to set_columns
208 puts "SQL is: #{sql}"
209 rows_sth = $dbh.prepare(sql)
212 rows_sth.each do |row|
213 values = @liststore.append
214 @fields.each_field do |position,field,value|
215 values.set_value(position,row[field])
221 # Read the definitions of this browse window from a file
223 def load_browse_definition( filename )
231 return @treeview.selection
234 def get_key( key_name )
235 iter = @treeview.selection
237 @keys[key_name].each_index do |fieldname|
238 key.push( iter[@fields.fields[fieldname].position] )