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
32 import libliststorehandler
41 _moduleLogger = logging.getLogger(__name__)
44 class TripleToggleCellRenderer(gtk.CellRendererToggle):
47 "status": (gobject.TYPE_STRING, "Status", "Status", "", gobject.PARAM_READWRITE),
51 'status_changed' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_INT, gobject.TYPE_STRING)),
55 gtk.CellRendererToggle.__init__(self)
56 self.set_property("activatable", True)
57 self.connect('toggled', self._on_toggled)
58 self.status = libliststorehandler.Liststorehandler.SHOW_NEW
60 @gtk_toolbox.log_exception(_moduleLogger)
61 def do_set_property(self, property, value):
62 if getattr(self, property.name) == value or value is None:
65 setattr(self, property.name, value)
67 if property.name == "status":
68 active, inconsistent = {
69 libliststorehandler.Liststorehandler.SHOW_NEW: (False, False),
70 libliststorehandler.Liststorehandler.SHOW_ACTIVE: (False, True),
71 libliststorehandler.Liststorehandler.SHOW_COMPLETE: (True, False),
73 self.set_property("active", active)
74 self.set_property("inconsistent", inconsistent)
76 @gtk_toolbox.log_exception(_moduleLogger)
77 def do_get_property(self, property):
78 return getattr(self, property.name)
80 @gtk_toolbox.log_exception(_moduleLogger)
81 def _on_toggled(self, widget, path):
82 self.emit("status_changed", int(path), "-1")
85 gobject.type_register(TripleToggleCellRenderer)
88 class CellRendererTriple(gtk.GenericCellRenderer):
90 "status": (gobject.TYPE_STRING, "Status", "Status", "", gobject.PARAM_READWRITE),
94 'status_changed' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,(gobject.TYPE_INT,gobject.TYPE_STRING)),
98 gtk.GenericCellRenderer.__init__(self)
100 self.last_cell = None
102 self.set_property('mode', gtk.CELL_RENDERER_MODE_ACTIVATABLE)
103 self.set_property('visible', True)
105 def do_set_property(self,property,value):
106 setattr(self, property.name, value)
108 def do_get_property(self, property):
109 return getattr(self, property.name)
111 def _get_layout(self, widget):
112 '''Gets the Pango layout used in the cell in a TreeView widget.'''
114 layout = pango.Layout(widget.get_pango_context())
115 layout.set_width(-1) # Do not wrap text.
121 def on_get_size(self, widget, cell_area=None):
122 layout = self._get_layout(widget)
123 width, height = layout.get_pixel_size()
134 if cell_area is not None:
135 x_offset = xalign * (cell_area.width - width)
136 x_offset = max(x_offset, xpad)
137 x_offset = int(round(x_offset, 0))
139 y_offset = yalign * (cell_area.height - height)
140 y_offset = max(y_offset, ypad)
141 y_offset = int(round(y_offset, 0))
143 width = width + (xpad * 2)
144 height = height + (ypad * 2)
146 return x_offset, y_offset, width, height
148 def on_render(self, window, widget, background_area, cell_area, expose_area, flags ):
149 self.last_cell = cell_area
153 width = cell_area.width
154 height = cell_area.height
157 # This is how it should work but due to theme issues on Maemo, it doesn't work
158 if widget.state == gtk.STATE_INSENSITIVE:
159 state = gtk.STATE_INSENSITIVE
160 elif flags & gtk.CELL_RENDERER_SELECTED:
161 if widget.is_focus():
162 state = gtk.STATE_SELECTED
164 state = gtk.STATE_ACTIVE
166 state = gtk.STATE_NORMAL
168 if self.status == libliststorehandler.Liststorehandler.SHOW_COMPLETE:
169 shadow = gtk.SHADOW_IN
170 state = gtk.STATE_NORMAL
171 elif self.status == libliststorehandler.Liststorehandler.SHOW_ACTIVE:
172 shadow = gtk.SHADOW_ETCHED_IN
173 state = gtk.STATE_NORMAL
174 elif self.status == libliststorehandler.Liststorehandler.SHOW_NEW:
175 shadow = gtk.SHADOW_OUT
176 state = gtk.STATE_SELECTED
178 raise NotImplementedError(self.status)
180 widget.style.paint_check(window, state, shadow, cell_area, widget, "cellcheck",x,y,width,height)
182 def on_activate(self, event, widget, path, background_area, cell_area, flags):
183 self.emit("status_changed", int(path), "-1")
187 gobject.type_register(CellRendererTriple)
190 class View(gtk.VBox):
192 def __init__(self, db, liststorehandler, parent_window):
194 self.parent_window = parent_window
195 self.liststorehandler = liststorehandler
197 gtk.VBox.__init__(self, homogeneous = False, spacing = 0)
199 logging.info("libview, init")
202 self.scrolled_window = gtk.ScrolledWindow()
203 self.scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
204 self.pack_start(self.scrolled_window, expand = True, fill = True, padding = 0)
209 ls = self.liststorehandler.get_liststore()
210 self.treeview.set_model(ls)
212 def del_active_row(self):
213 path, col = self.treeview.get_cursor()
216 row_iter = self.treeview.get_model().get_iter(path)
217 self.liststorehandler.del_row(irow, row_iter)
219 def reload_view(self):
220 # create the TreeView using liststore
221 self.modelsort = gtk.TreeModelSort(self.liststorehandler.get_liststore())
222 self.modelsort.set_sort_column_id(2, gtk.SORT_ASCENDING)
224 if self.treeview is not None:
225 self.scrolled_window.remove(self.treeview)
226 self.treeview = gtk.TreeView(self.modelsort)
227 self.treeview.set_headers_visible(True)
228 self.treeview.set_reorderable(False)
230 self.cell = range(self.liststorehandler.get_colcount())
231 self.tvcolumn = range(self.liststorehandler.get_colcount())
233 m = self.liststorehandler.get_unitsstore()
235 for i in range(self.liststorehandler.get_colcount()):
236 if i in [1, 2]: # status, title
240 if self.db.ladeDirekt("showcol_"+str(self.liststorehandler.get_colname(i)), default) == "1":
241 if i in [1]: # status
242 # HACK Hildon has theme issues with inconsistent items, so
243 # we have a hacked together toggle to make it work on
245 if hildonize.IS_HILDON_SUPPORTED:
246 self.cell[i] = CellRendererTriple()
248 self.cell[i] = TripleToggleCellRenderer()
249 self.cell[i].connect('status_changed', self._on_col_toggled)
250 self.tvcolumn[i] = gtk.TreeViewColumn("", self.cell[i])
251 self.tvcolumn[i].set_attributes( self.cell[i], status = i)
252 elif i in [3, 5]: # quantity, price
253 self.cell[i] = gtk.CellRendererSpin()
254 adjustment = gtk.Adjustment(0, -sys.float_info.max, sys.float_info.max, 1)
255 self.cell[i].set_property('adjustment', adjustment)
256 self.cell[i].set_property('digits', 2 if i == 5 else 0)
257 self.cell[i].set_property('editable', True)
258 self.cell[i].connect("edited", self._on_col_edited, i)
259 self.tvcolumn[i] = gtk.TreeViewColumn(
260 self.liststorehandler.get_colname(i), self.cell[i]
262 self.tvcolumn[i].set_attributes( self.cell[i], text = i)
263 elif i in [4, 6]: # unit, priority
264 self.cell[i] = gtk.CellRendererCombo()
265 self.cell[i].set_property("model", m)
266 self.cell[i].set_property('text-column', i)
267 self.cell[i].set_property('editable', True)
268 self.cell[i].connect("edited", self._on_col_edited, i)
269 self.tvcolumn[i] = gtk.TreeViewColumn(
270 self.liststorehandler.get_colname(i), self.cell[i]
272 self.tvcolumn[i].set_attributes( self.cell[i], text = i)
274 self.cell[i] = gtk.CellRendererText()
275 self.cell[i].set_property('editable', True)
276 self.cell[i].set_property('editable-set', True)
277 self.cell[i].connect("edited", self._on_col_edited, i)
278 self.tvcolumn[i] = gtk.TreeViewColumn(
279 self.liststorehandler.get_colname(i), self.cell[i]
281 self.tvcolumn[i].set_attributes(self.cell[i], text = i)
283 self.tvcolumn[i].set_sort_column_id(i)
284 self.tvcolumn[i].set_resizable(True)
285 self.treeview.append_column(self.tvcolumn[i])
287 self.scrolled_window.add(self.treeview)
292 @gtk_toolbox.log_exception(_moduleLogger)
293 def _on_col_edited(self, cell, irow, new_text, icol = None):
295 self.liststorehandler.update_row(irow, icol, new_text)
297 print cell, irow, new_text, icol
299 @gtk_toolbox.log_exception(_moduleLogger)
300 def _on_col_toggled(self, widget, irow, status):
301 ls = self.treeview.get_model()
303 if self.liststorehandler.get_filter() == self.liststorehandler.SHOW_ACTIVE:
304 if ls[irow][1] == "0":
305 self.liststorehandler.update_row(irow, 1, "1")
307 self.liststorehandler.update_row(irow, 1, "0")
309 if ls[irow][1] == "1":
310 self.liststorehandler.update_row(irow, 1, "-1")
311 elif ls[irow][1] == "0":
312 self.liststorehandler.update_row(irow, 1, "1")
314 self.liststorehandler.update_row(irow, 1, "0")