2 # -*- coding: utf-8 -*-
5 This file is part of Multilist.
7 Multilist is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 Multilist is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Multilist. If not, see <http://www.gnu.org/licenses/>.
20 Copyright (C) 2008 Christoph Würstle
38 _moduleLogger = logging.getLogger(__name__)
41 class CellRendererTriple(gtk.GenericCellRenderer):
43 "status": (gobject.TYPE_STRING, "Status",
44 "Status", "", gobject.PARAM_READWRITE),
48 'status_changed' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_INT, gobject.TYPE_STRING)),
52 #self.__gobject_init__()
53 #gtk.GenericCellRenderer.__init__(self, *args, **kwargs)
54 gtk.GenericCellRenderer.__init__(self)
55 #self.__gobject_init__()
59 self.mode = gtk.CELL_RENDERER_MODE_ACTIVATABLE
67 self.connect('editing-started', self.on_clicked)
69 def do_set_property(self, property, value):
70 setattr(self, property.name, value)
72 def do_get_property(self, property):
73 return getattr(self, property.name)
75 def get_layout(self, widget):
76 '''Gets the Pango layout used in the cell in a TreeView widget.'''
78 layout = pango.Layout(widget.get_pango_context())
79 layout.set_width(-1) # Do not wrap text.
85 def on_get_size(self, widget, cell_area = None):
92 layout = self.get_layout(widget)
93 width, height = layout.get_pixel_size()
100 x_offset = xalign * (cell_area.width - width)
101 x_offset = max(x_offset, xpad)
102 x_offset = int(round(x_offset, 0))
104 y_offset = yalign * (cell_area.height - height)
105 y_offset = max(y_offset, ypad)
106 y_offset = int(round(y_offset, 0))
108 width = width + (xpad * 2)
109 height = height + (ypad * 2)
111 return x_offset, y_offset, width, height
113 def on_clicked(self, widget, data):
116 def clicked(self, widget, data1 = None):
117 x, y = widget.get_pointer()
120 path = widget.get_path_at_pos(x, y)
122 #print "a", widget.get_cursor()
125 path = widget.get_cursor()[0]
128 irow = path[0] #path[0][0]-1
129 rect = widget.get_cell_area(irow, widget.get_column(0)) #FixME 0 is hardcoded
130 if x < rect.x+rect.width:
131 self.emit("status_changed", irow, self.status)
135 #workarround -1 means last item, because bug in treeview?!
137 rect = widget.get_visible_rect() #widget.get_cell_area(-1, widget.get_column(0))
138 #print rect.x, rect.y, rect.width, rect.height, x, y
140 rect = widget.get_cell_area(0, widget.get_column(0)) #FixME 0 is hardcoded
141 if x < rect.x+rect.width:
142 self.emit("status_changed", irow, "-1")
144 def on_render(self, window, widget, background_area, cell_area, expose_area, flags ):
145 if (self.widget == None):
148 self.widget.connect("cursor-changed", self.clicked) #button-press-event
150 self.last_cell = cell_area
152 x = int(cell_area.x+(cell_area.width-2)/2-(cell_area.height-2)/2)
153 y = int(cell_area.y+1)
154 height = int(cell_area.height-2)
157 if (self.status == "1"):
158 widget.style.paint_check(window, gtk.STATE_NORMAL, gtk.SHADOW_IN, cell_area, widget, "cellradio", x, y, width, height)
159 elif (self.status == "0"):
164 widget.style.paint_flat_box(window, gtk.STATE_NORMAL, gtk.SHADOW_NONE, cell_area, widget, "cellunselected", x, y, width, height)
166 widget.style.paint_hline(window, gtk.STATE_NORMAL, cell_area, widget, "cellunselected", x, x+width, y)
167 widget.style.paint_hline(window, gtk.STATE_NORMAL, cell_area, widget, "cellunselected", x, x+width, y+height)
168 widget.style.paint_vline(window, gtk.STATE_NORMAL, cell_area, widget, "cellunselected", y, y+height, x)
169 widget.style.paint_vline(window, gtk.STATE_NORMAL, cell_area, widget, "cellunselected", y, y+height, x+width)
172 widget.style.paint_diamond(window, gtk.STATE_NORMAL, gtk.SHADOW_IN, cell_area, widget, "cellunselected", x, y, width, height)
178 def on_start_editing(self, event, widget, path, background_area, cell_area, flags):
179 print "on_start_editing", path
182 def on_activate(self, event, widget, path, background_area, cell_area, flags):
183 print "activate", path
187 class CellRendererCombo2(gtk.GenericCellRenderer):
189 "text": (gobject.TYPE_STRING, "text",
190 "Text", "", gobject.PARAM_READWRITE),
194 'status_changed' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_INT, gobject.TYPE_STRING)),
198 #self.__gobject_init__()
199 #gtk.GenericCellRenderer.__init__(self, *args, **kwargs)
200 gtk.GenericCellRenderer.__init__(self)
201 #self.__gobject_init__()
205 self.mode = gtk.CELL_RENDERER_MODE_ACTIVATABLE
212 self.last_cell = None
214 self.connect('editing-started', self.on_clicked)
216 def do_set_property(self, property, value):
217 #print property, value
218 setattr(self, property.name, value)
220 def do_get_property(self, property):
221 return getattr(self, property.name)
223 def get_layout(self, widget):
224 '''Gets the Pango layout used in the cell in a TreeView widget.'''
226 layout = pango.Layout(widget.get_pango_context())
227 layout.set_width(-1) # Do not wrap text.
229 layout.set_text(self.text)
233 def on_get_size(self, widget, cell_area = None):
240 layout = self.get_layout(widget)
241 width, height = layout.get_pixel_size()
248 x_offset = xalign * (cell_area.width - width)
249 x_offset = max(x_offset, xpad)
250 x_offset = int(round(x_offset, 0))
252 y_offset = yalign * (cell_area.height - height)
253 y_offset = max(y_offset, ypad)
254 y_offset = int(round(y_offset, 0))
256 width = width + (xpad * 2)
257 height = height + (ypad * 2)
259 return x_offset, y_offset, width, height
261 @gtk_toolbox.log_exception(_moduleLogger)
262 def on_clicked(self, widget, data):
265 def clicked(self, widget, data1 = None):
267 x, y = widget.get_pointer()
270 #path = widget.get_path_at_pos(x, y)
272 path = widget.get_cursor()[0]
275 irow = path[0] #path[0][0]-1
276 rect = widget.get_cell_area(irow, widget.get_column(0)) #FixME 0 is hardcoded
277 if x < rect.x+rect.width:
278 self.emit("status_changed", irow, self.status)
282 #workarround -1 means last item, because bug in treeview?!
284 rect = widget.get_visible_rect() #widget.get_cell_area(-1, widget.get_column(0))
285 #print rect.x, rect.y, rect.width, rect.height, x, y
287 rect = widget.get_cell_area(0, widget.get_column(0)) #FixME 0 is hardcoded
288 if x < rect.x+rect.width:
289 self.emit("status_changed", irow, "-1")
291 def on_render(self, window, widget, background_area, cell_area, expose_area, flags ):
292 if (self.widget == None):
294 self.widget.connect("cursor-changed", self.clicked) #button-press-event
296 self.last_cell = cell_area
298 x = int(cell_area.x+(cell_area.width-2)/2-(cell_area.height-2)/2)
299 y = int(cell_area.y+1)
300 height = int(cell_area.height-2)
303 widget.style.paint_layout(window, gtk.STATE_NORMAL, True, cell_area, widget, "cellradio", x, y, self.get_layout(widget))
307 def on_start_editing(self, event, widget, path, background_area, cell_area, flags):
308 print "on_start_editing", path
311 def on_activate(self, event, widget, path, background_area, cell_area, flags):
312 print "activate", path
316 gobject.type_register(CellRendererCombo2)
317 gobject.type_register(CellRendererTriple)
320 class View(gtk.VBox):
322 def __init__(self, db, liststorehandler, parent_window):
324 self.parent_window = parent_window
325 self.liststorehandler = liststorehandler
327 gtk.VBox.__init__(self, homogeneous = False, spacing = 0)
329 logging.info("libview, init")
331 self.scrolled_window = None
335 ls = self.liststorehandler.get_liststore()
336 self.treeview.set_model(ls)
338 def col_edited(self, cell, irow, new_text, icol = None):
340 self.liststorehandler.update_row(irow, icol, new_text)
342 print cell, irow, new_text, icol
344 def col_toggled(self, widget, irow, status ):
345 ls = self.treeview.get_model()
347 if self.liststorehandler.get_filter() == self.liststorehandler.SHOW_ACTIVE:
348 if ls[irow][1] == "0":
349 self.liststorehandler.update_row(irow, 1, "1")
351 self.liststorehandler.update_row(irow, 1, "0")
353 if ls[irow][1] == "1":
354 self.liststorehandler.update_row(irow, 1, "-1")
355 elif ls[irow][1] == "0":
356 self.liststorehandler.update_row(irow, 1, "1")
358 self.liststorehandler.update_row(irow, 1, "0")
360 def convert(self, s):
366 def del_active_row(self):
367 path, col = self.treeview.get_cursor()
370 row_iter = self.treeview.get_model().get_iter(path)
371 self.liststorehandler.del_row(irow, row_iter)
373 def sort_func_function(self, model, iter1, iter2, data = None):
376 def reload_view(self):
377 # create the TreeView using liststore
378 self.modelsort = gtk.TreeModelSort(self.liststorehandler.get_liststore())
379 self.modelsort.set_sort_column_id(2, gtk.SORT_ASCENDING)
381 self.treeview = gtk.TreeView(self.modelsort)
382 self.treeview.set_headers_visible(True)
384 self.cell = range(self.liststorehandler.get_colcount())
385 self.tvcolumn = range(self.liststorehandler.get_colcount())
387 m = self.liststorehandler.get_unitsstore()
389 for i in range(self.liststorehandler.get_colcount()):
394 if self.db.ladeDirekt("showcol_"+str(self.liststorehandler.get_colname(i)), default) == "1":
396 self.cell[i] = CellRendererTriple()
397 self.tvcolumn[i] = gtk.TreeViewColumn("", self.cell[i])
398 self.cell[i].connect( 'status_changed', self.col_toggled)
399 self.tvcolumn[i].set_attributes( self.cell[i], status = i)
401 self.cell[i] = gtk.CellRendererCombo()
402 self.tvcolumn[i] = gtk.TreeViewColumn(self.liststorehandler.get_colname(i), self.cell[i])
403 self.cell[i].set_property("model", m)
404 self.cell[i].set_property('text-column', i)
405 self.cell[i].set_property('editable', True)
406 self.cell[i].connect("edited", self.col_edited, i)
407 self.tvcolumn[i].set_attributes( self.cell[i], text = i)
409 self.cell[i] = gtk.CellRendererText()
410 self.tvcolumn[i] = gtk.TreeViewColumn(self.liststorehandler.get_colname(i), self.cell[i])
411 self.cell[i].set_property('editable', True)
412 self.cell[i].set_property('editable-set', True)
413 self.cell[i].connect("edited", self.col_edited, i)
414 #self.cell[i].connect("editing-canceled", self.col_edited2, i)
415 self.tvcolumn[i].set_attributes(self.cell[i], text = i)
417 self.cell[i].set_property('cell-background', 'lightgray')
418 self.tvcolumn[i].set_sort_column_id(i)
419 self.tvcolumn[i].set_resizable(True)
420 self.treeview.append_column(self.tvcolumn[i])
422 # Disable drag and drop reordering of rows
423 self.treeview.set_reorderable(False)
425 if self.scrolled_window is not None:
426 self.scrolled_window.destroy()
428 self.scrolled_window = gtk.ScrolledWindow()
429 self.scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
431 self.scrolled_window.add(self.treeview)
432 self.pack_start(self.scrolled_window, expand = True, fill = True, padding = 0)