2 This table model allows an ActiveRecord or ActiveResource to be used as a
3 basis for a Qt::AbstractTableModel for viewing in a Qt::TableView. Example
6 app = Qt::Application.new(ARGV)
7 agencies = TravelAgency.find(:all, :conditions => [:name => 'Another Agency'])
8 model = ActiveTableModel.new(agencies)
9 table = Qt::TableView.new
14 Written by Richard Dale and Silvio Fonseca
21 class ActiveTableModel < Qt::AbstractTableModel
22 def initialize(collection, columns=nil)
24 @collection = collection
26 if columns.kind_of? Hash
28 @labels=columns.values
33 @keys = build_keys([], @collection.first.attributes)
35 @labels||=@keys.collect { |k| k.humanize.gsub(/\./, ' ') }
38 def build_keys(keys, attrs, prefix="")
39 attrs.inject(keys) do |cols, a|
40 if a[1].respond_to? :attributes
41 build_keys(cols, a[1].attributes, prefix + a[0] + ".")
52 def columnCount(parent)
58 row = row.row if row.is_a?Qt::ModelIndex
66 def data(index, role=Qt::DisplayRole)
67 invalid = Qt::Variant.new
68 return invalid unless role == Qt::DisplayRole or role == Qt::EditRole
69 item = @collection[index.row]
70 return invalid if item.nil?
71 raise "invalid column #{index.column}" if (index.column < 0 ||
72 index.column >= @keys.size)
73 value = eval("item.attributes['%s']" % @keys[index.column].gsub(/\./, "'].attributes['"))
74 return Qt::Variant.new(value)
77 def headerData(section, orientation, role=Qt::DisplayRole)
78 invalid = Qt::Variant.new
79 return invalid unless role == Qt::DisplayRole
86 return Qt::Variant.new(v)
90 return Qt::ItemIsEditable | super(index)
93 def setData(index, variant, role=Qt::EditRole)
94 if index.valid? and role == Qt::EditRole
95 att = @keys[index.column]
96 # Don't allow the primary key to be changed
101 item = @collection[index.row]
102 raise "invalid column #{index.column}" if (index.column < 0 ||
103 index.column >= @keys.size)
104 value = variant.value
106 if value.class.name == "Qt::Date"
107 value = Date.new(value.year, value.month, value.day)
108 elsif value.class.name == "Qt::Time"
109 value = Time.new(value.hour, value.min, value.sec)
112 eval("item.attributes['%s'] = value" % att.gsub(/\./, "'].attributes['"))
114 emit dataChanged(index, index)
122 # kate: indent-width 4;