Module: Knj::Gtk2::Tv

Defined in:
lib/knj/gtk2_tv.rb

Overview

This module contains various helper-methods for handeling stuff regarding treeviews.

Constant Summary collapse

@@editable_text_callbacks =
{
  :datetime => {
    :value => proc{ |data|
      begin
        Knj::Datet.in(data[:value]).dbstr
      rescue Knj::Errors::InvalidData
        raise "Invalid timestamp entered."
      end
    },
    :value_set => proc{ |data|
      Knj::Datet.in(data[:value]).out
    }
  },
  :time_as_sec => {
    :value => proc{ |data| Knj::Strings.human_time_str_to_secs(data[:value]) },
    :value_set => proc{ |data| Knj::Strings.secs_to_human_time_str(data[:value]) }
  },
  :int => {
    :value => proc{ |data| data[:value].to_i.to_s }
  },
  :human_number => {
    :value => proc{ |data| Knj::Locales.number_in(data[:value]) },
    :value_set => proc{ |data| Knj::Locales.number_out(data[:value], data[:col_data][:decimals]) }
  }
}

Class Method Summary collapse

Class Method Details

.append(tv, data) ⇒ Object

Appends data to the treeview.

Examples

Knj::Gtk2::Tv.append(treeview, [1, “Kasper”])



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/knj/gtk2_tv.rb', line 82

def self.append(tv, data)
  iter = tv.model.append
  
  count = 0
  data.each do |value|
    col = tv.columns[count]
    renderer = col.cell_renderers.first
    
    if renderer.is_a?(Gtk::CellRendererText)
      iter[count] = value.to_s
    elsif renderer.is_a?(Gtk::CellRendererToggle)
      iter[count] = Knj::Strings.yn_str(value, 1, 0)
    elsif renderer.is_a?(Gtk::CellRendererCombo)
      iter[count] = value.to_s
    else
      raise "Unknown renderer: '#{renderer.class.name}'."
    end
    
    count += 1
  end
  
  return {:iter => iter}
end

.editable_text_renderers_to_model(args) ⇒ Object



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/knj/gtk2_tv.rb', line 152

def self.editable_text_renderers_to_model(args)
  args[:id_col] = 0 if !args.key?(:id_col)
  
  args[:cols].each do |col_no, col_data|
    col_data = {:col => col_data} if col_data.is_a?(Symbol)
    
    if col_data.key?(:type)
      if callbacks = @@editable_text_callbacks[col_data[:type]]
        col_data[:value_callback] = callbacks[:value] if callbacks.key?(:value)
        col_data[:value_set_callback] = callbacks[:value_set] if callbacks.key?(:value_set)
      else
        raise "Invalid type: '#{col_data[:type]}'."
      end
    end
    
    renderer = args[:renderers][col_no]
    
    if renderer.is_a?(Gtk::CellRendererText)
      renderer.editable = true
      renderer.signal_connect("edited") do |renderer, row_no, value|
        iter = args[:tv].model.get_iter(row_no)
        id = args[:tv].model.get_value(iter, args[:id_col])
        model_obj = args[:ob].get(args[:model_class], id)
        cancel = false
        callback_hash = {:args => args, :value => value, :model => model_obj, :col_no => col_no, :col_data => col_data}
        
        if col_data[:value_callback]
          begin
            value = col_data[:value_callback].call(callback_hash)
            callback_hash[:value] = value
          rescue => e
            Knj::Gtk2.msgbox(e.message, "warning")
            cancel = true
          end
        end
        
        if !cancel
          begin
            args[:change_before].call(callback_hash) if args[:change_before]
          rescue => e
            cancel = true
            Knj::Gtk2.msgbox(e.message, "warning")
          end
          
          if !cancel
            begin
              model_obj[col_data[:col]] = value
              value = col_data[:value_set_callback].call(callback_hash) if col_data.key?(:value_set_callback)
              iter[col_no] = value
            rescue => e
              Knj::Gtk2.msgbox(e.message, "warning")
            ensure
              args[:change_after].call(callback_hash) if args[:change_after]
            end
          end
        end
      end
    elsif renderer.is_a?(Gtk::CellRendererToggle)
      renderer.activatable = true
      renderer.signal_connect("toggled") do |renderer, path, value|
        iter = args[:tv].model.get_iter(path)
        id = args[:tv].model.get_value(iter, 0)
        model_obj = args[:ob].get(args[:model_class], id)
        callback_hash = {:args => args, :value => value, :model => model_obj, :col_no => col_no, :col_data => col_data}
        
        if col_data[:value_callback]
          begin
            value = col_data[:value_callback].call(callback_hash)
            callback_hash[:value] = value
          rescue => e
            Knj::Gtk2.msgbox(e.message, "warning")
            cancel = true
          end
        end
        
        if !cancel
          args[:change_before].call(callback_hash) if args[:change_before]
          begin
            if model_obj[col_data[:col]].to_i == 1
              model_obj[col_data[:col]] = 0
              iter[col_no] = 0
            else
              model_obj[col_data[:col]] = 1
              iter[col_no] = 1
            end
          ensure
            args[:change_after].call(:args => args) if args[:change_after]
          end
        end
      end
    else
      raise "Invalid cellrenderer: '#{renderer.class.name}'."
    end
  end
end

.init(tv, columns) ⇒ Object

Initializes a treeview with a model and a number of columns. Returns a hash containing various data like the renderers.

Examples

Knj::Gtk2::Tv.init(treeview, [“ID”, “Name”])



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/knj/gtk2_tv.rb', line 6

def self.init(tv, columns)
  ret = {
    :renderers => []
  }
  
  model_args = []
  columns.each do |args|
    if args.is_a?(String)
      args = {:type => :string, :title => args}
    end
    
    if args[:type] == :string
      model_args << String
    elsif args[:type] == :toggle
      model_args << Integer
    elsif args[:type] == :combo
      model_args << String
    else
      raise "Invalid type: '#{args[:type]}'."
    end
  end
  
  list_store = Gtk::ListStore.new(*model_args)
  tv.model = list_store
  
  count = 0
  columns.each do |args|
    if args.is_a?(String)
      args = {:type => :string, :title => args}
    end
    
    if args[:type] == :string
      if args[:markup]
        col_args = {:markup => count}
      else
        col_args = {:text => count}
      end
      
      renderer = Gtk::CellRendererText.new
      col = Gtk::TreeViewColumn.new(args[:title], renderer, col_args)
      col.resizable = true
      tv.append_column(col)
    elsif args[:type] == :toggle
      renderer = Gtk::CellRendererToggle.new
      col = Gtk::TreeViewColumn.new(args[:title], renderer, :active => count)
      tv.append_column(col)
    elsif args[:type] == :combo
      renderer = Gtk::CellRendererCombo.new
      renderer.text_column = 0
      
      if args[:markup]
        col_args = {:markup => count}
      else
        col_args = {:text => count}
      end
      
      col = Gtk::TreeViewColumn.new(args[:title], renderer, col_args)
      
      renderer.model = args[:model] if args.key?(:model)
      renderer.has_entry = args[:has_entry] if args.key?(:has_entry)
      tv.append_column(col)
    else
      raise "Invalid type: '#{args[:type]}'."
    end
    
    count += 1
    
    ret[:renderers] << renderer
  end
  
  return ret
end

.sel(tv) ⇒ Object

Gets the selected data from the treeview.

Examples

Knj::Gtk2::Tv.sel(treeview) #=> [1, “Kasper”]



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/knj/gtk2_tv.rb', line 109

def self.sel(tv)
  selected = tv.selection.selected_rows
  return nil if !tv.model or selected.size <= 0
  
  iter = tv.model.get_iter(selected[0])
  returnval = []
  columns = tv.columns
  
  count = 0
  columns.each do |column|
    returnval[count] = iter[count]
    count += 1
  end
  
  return returnval
end