481464c7fe07c934218853df9656ba556ff14756
[multilist] / src / libview.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3   
4 """
5     This file is part of Multilist.
6
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.
11
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.
16
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/>.
19     
20     Copyright (C) 2008 Christoph Würstle
21 """
22   
23 import gtk
24 import gobject
25 import logging
26 import pango
27 import libliststorehandler
28   
29
30 class Columns_dialog(gtk.VBox):
31         
32         def is_col_selected(self, icol):
33                 children=self.framebox.get_children()
34                 if icol<len(children):
35                         return children[icol].get_active()
36                 else:
37                         return None
38         
39         def save_column_setting(self):
40                 i=1 #uid can not be shown
41                 while self.liststorehandler.get_colname(i)!=None:
42                         name=str(self.liststorehandler.get_colname(i))
43                         if self.is_col_selected(i-1)==True:
44                                 self.db.speichereDirekt("showcol_"+name,"1")
45                         else:
46                                 self.db.speichereDirekt("showcol_"+name,"0")
47                         i=i+1
48                 
49         
50
51         
52         def __init__(self,db,liststorehandler):
53                 gtk.VBox.__init__(self,homogeneous=False, spacing=0)
54                 
55                 self.db=db
56                 self.liststorehandler=liststorehandler
57                 
58                 #serverbutton=gtk.ToggleButton("SyncServer starten")
59                 #serverbutton.connect("clicked",self.startServer,(None,))
60                 #self.pack_start(serverbutton, expand=False, fill=True, padding=1)
61                 #print "x1"
62                 
63                 frame=gtk.Frame(_("Columns"))
64                 self.framebox=gtk.VBox(homogeneous=False, spacing=0)
65                 
66                 self.scrolled_window = gtk.ScrolledWindow()
67                 self.scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
68
69                 self.scrolled_window.add_with_viewport(self.framebox)
70                 
71                 
72                 i=1 #uid can not be shown
73                 while self.liststorehandler.get_colname(i)!=None:
74                         name=str(self.liststorehandler.get_colname(i))
75                         checkbutton=gtk.CheckButton(name)
76                         if self.db.ladeDirekt("showcol_"+name)=="1":
77                                 checkbutton.set_active(True)
78                                 
79                         self.framebox.pack_start(checkbutton)
80                         i=i+1
81                 
82                 frame.add(self.scrolled_window)
83                 self.pack_start(frame, expand=True, fill=True, padding=1)
84                 
85                 
86                 
87         
88
89
90 class CellRendererTriple(gtk.GenericCellRenderer):
91         __gproperties__ = {
92                 "status": (gobject.TYPE_STRING, "Status",
93                 "Status", "", gobject.PARAM_READWRITE),
94         }
95         
96         __gsignals__ = {
97                 'status_changed' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,(gobject.TYPE_INT,gobject.TYPE_STRING)),
98         }
99
100
101         def __init__(self):
102                 #self.__gobject_init__()
103                 #gtk.GenericCellRenderer.__init__(self,*args,**kwargs)
104                 gtk.GenericCellRenderer.__init__(self)
105                 #self.__gobject_init__()
106                 self.status=-1
107                 self.xpad = 2
108                 self.ypad = 2
109                 self.mode = gtk.CELL_RENDERER_MODE_ACTIVATABLE
110                 self.xpad = -2; self.ypad = -2
111                 self.xalign = 0.5; self.yalign = 0.5
112                 self.active = 0
113                 self.widget=None
114                 self.last_cell=None
115                 self.connect('editing-started', self.on_clicked)
116
117         def do_set_property(self,property,value):
118                 setattr(self, property.name, value)
119
120         def do_get_property(self, property):
121                 return getattr(self, property.name)
122
123         def get_layout(self, widget):
124                 '''Gets the Pango layout used in the cell in a TreeView widget.'''
125
126                 layout = pango.Layout(widget.get_pango_context())
127                 layout.set_width(-1)    # Do not wrap text.
128
129                 layout.set_text('  ')
130
131                 return layout
132
133         def on_get_size(self, widget, cell_area=None):
134                 xpad = 2
135                 ypad = 2
136
137                 xalign = 0
138                 yalign = 0.5
139
140                 layout = self.get_layout(widget)
141                 width, height = layout.get_pixel_size()
142
143                 x_offset = xpad
144                 y_offset = ypad
145
146                 if cell_area:
147
148                         x_offset = xalign * (cell_area.width - width)
149                         x_offset = max(x_offset, xpad)
150                         x_offset = int(round(x_offset, 0))
151
152                         y_offset = yalign * (cell_area.height - height)
153                         y_offset = max(y_offset, ypad)
154                         y_offset = int(round(y_offset, 0))
155
156                 width  = width  + (xpad * 2)
157                 height = height + (ypad * 2)
158
159                 
160                 return x_offset, y_offset, width, height
161                 
162         def on_clicked(self,  widget, data):
163                 print widget,data
164
165         def clicked(self, widget, data1=None):
166                 x,y=widget.get_pointer()
167                 widget.realize()
168                 
169                 path=widget.get_path_at_pos(x,y)
170                 
171                 #print "a",widget.get_cursor()
172                 #print path
173                 
174         
175                 
176                 path=widget.get_cursor()[0]
177                 
178                 if path!=None:
179                         irow=path[0]    #path[0][0]-1
180                         rect=widget.get_cell_area(irow, widget.get_column(0)) #FixME 0 is hardcoded
181                         if x<rect.x+rect.width:
182                                 self.emit("status_changed",irow,self.status)
183                 else:
184                         return
185                 
186                 
187                         #workarround -1 means last item, because bug in treeview?!
188                         #print "not in list"
189                         rect=widget.get_visible_rect() #widget.get_cell_area(-1, widget.get_column(0))
190                         #print rect.x,rect.y,rect.width,rect.height,x,y
191                         irow=-1
192                         rect=widget.get_cell_area(0, widget.get_column(0)) #FixME 0 is hardcoded
193                         if x<rect.x+rect.width:
194                                 self.emit("status_changed",irow,"-1")
195                 
196
197         def on_render(self, window, widget, background_area, cell_area, expose_area, flags ):
198                 if (self.widget==None):
199                         #print widget
200                         self.widget=widget
201                         self.widget.connect("cursor-changed",self.clicked) #button-press-event
202                 
203                 self.last_cell=cell_area
204                 
205                 x=int(cell_area.x+(cell_area.width-2)/2-(cell_area.height-2)/2)
206                 y=int(cell_area.y+1)
207                 height=int(cell_area.height-2)
208                 width=int(height)
209
210                 if (self.status=="1"):
211                         widget.style.paint_check(window,gtk.STATE_NORMAL, gtk.SHADOW_IN,cell_area, widget, "cellradio",x,y,width,height)
212                 elif (self.status=="0"):
213                         #width=height
214                         height=height-3
215                         width=height
216                         
217                         widget.style.paint_flat_box(window, gtk.STATE_NORMAL, gtk.SHADOW_NONE, cell_area, widget, "cellunselected",x,y,width,height)
218                         
219                         widget.style.paint_hline(window, gtk.STATE_NORMAL,cell_area, widget, "cellunselected",x,x+width,y)
220                         widget.style.paint_hline(window, gtk.STATE_NORMAL,cell_area, widget, "cellunselected",x,x+width,y+height)
221                         widget.style.paint_vline(window, gtk.STATE_NORMAL,cell_area, widget, "cellunselected",y,y+height,x)
222                         widget.style.paint_vline(window, gtk.STATE_NORMAL,cell_area, widget, "cellunselected",y,y+height,x+width)
223                         
224                 else:
225                         widget.style.paint_diamond(window, gtk.STATE_NORMAL, gtk.SHADOW_IN, cell_area, widget, "cellunselected",x,y,width,height)
226                         
227                 #widget.show_all()
228                 #print "render"
229                 pass
230     
231         def on_start_editing(self, event, widget, path, background_area, cell_area, flags):
232                 print "on_start_editing",path
233                 return None
234         
235         
236         def on_activate(self, event, widget, path, background_area, cell_area, flags):
237                 print "activate",path
238                 return False
239
240                 
241                 
242 class CellRendererCombo2(gtk.GenericCellRenderer):
243         __gproperties__ = {
244                 "text": (gobject.TYPE_STRING, "text",
245                 "Text", "", gobject.PARAM_READWRITE),
246         }
247         
248         __gsignals__ = {
249                 'status_changed' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,(gobject.TYPE_INT,gobject.TYPE_STRING)),
250         }
251
252
253         def __init__(self):
254                 #self.__gobject_init__()
255                 #gtk.GenericCellRenderer.__init__(self,*args,**kwargs)
256                 gtk.GenericCellRenderer.__init__(self)
257                 #self.__gobject_init__()
258                 self.status=-1
259                 self.xpad = 2
260                 self.ypad = 2
261                 self.mode = gtk.CELL_RENDERER_MODE_ACTIVATABLE
262                 self.xpad = -2; self.ypad = -2
263                 self.xalign = 0.5; self.yalign = 0.5
264                 self.active = 0
265                 self.widget=None
266                 self.last_cell=None
267                 self.text="(none)"
268                 self.connect('editing-started', self.on_clicked)
269
270         def do_set_property(self,property,value):
271                 #print property,value
272                 setattr(self, property.name, value)
273
274         def do_get_property(self, property):
275                 return getattr(self, property.name)
276
277         def get_layout(self, widget):
278                 '''Gets the Pango layout used in the cell in a TreeView widget.'''
279
280                 layout = pango.Layout(widget.get_pango_context())
281                 layout.set_width(-1)    # Do not wrap text.
282
283                 layout.set_text(self.text)
284
285                 return layout
286
287         def on_get_size(self, widget, cell_area=None):
288                 xpad = 2
289                 ypad = 2
290
291                 xalign = 0
292                 yalign = 0.5
293
294                 layout = self.get_layout(widget)
295                 width, height = layout.get_pixel_size()
296
297                 x_offset = xpad
298                 y_offset = ypad
299
300                 if cell_area:
301
302                         x_offset = xalign * (cell_area.width - width)
303                         x_offset = max(x_offset, xpad)
304                         x_offset = int(round(x_offset, 0))
305
306                         y_offset = yalign * (cell_area.height - height)
307                         y_offset = max(y_offset, ypad)
308                         y_offset = int(round(y_offset, 0))
309
310                 width  = width  + (xpad * 2)
311                 height = height + (ypad * 2)
312
313                 
314                 return x_offset, y_offset, width, height
315                 
316         def on_clicked(self,  widget, data):
317                 print widget,data
318
319         def clicked(self, widget, data1=None):
320                 return
321                 x,y=widget.get_pointer()
322                 widget.realize()
323                 
324                 #path=widget.get_path_at_pos(x,y)
325                 
326                 path=widget.get_cursor()[0]
327                 
328                 if path!=None:
329                         irow=path[0]    #path[0][0]-1
330                         rect=widget.get_cell_area(irow, widget.get_column(0)) #FixME 0 is hardcoded
331                         if x<rect.x+rect.width:
332                                 self.emit("status_changed",irow,self.status)
333                 else:
334                         return
335                 
336                 
337                         #workarround -1 means last item, because bug in treeview?!
338                         #print "not in list"
339                         rect=widget.get_visible_rect() #widget.get_cell_area(-1, widget.get_column(0))
340                         #print rect.x,rect.y,rect.width,rect.height,x,y
341                         irow=-1
342                         rect=widget.get_cell_area(0, widget.get_column(0)) #FixME 0 is hardcoded
343                         if x<rect.x+rect.width:
344                                 self.emit("status_changed",irow,"-1")
345                 
346
347         def on_render(self, window, widget, background_area, cell_area, expose_area, flags ):
348                 if (self.widget==None):
349                         self.widget=widget
350                         self.widget.connect("cursor-changed",self.clicked) #button-press-event
351                 
352                 self.last_cell=cell_area
353                 
354                 x=int(cell_area.x+(cell_area.width-2)/2-(cell_area.height-2)/2)
355                 y=int(cell_area.y+1)
356                 height=int(cell_area.height-2)
357                 width=int(height)
358                 
359                 widget.style.paint_layout(window,gtk.STATE_NORMAL, True, cell_area, widget, "cellradio",x,y,self.get_layout(widget))
360                         
361                 #widget.show_all()
362     
363         def on_start_editing(self, event, widget, path, background_area, cell_area, flags):
364                 print "on_start_editing",path
365                 return None
366         
367         
368         def on_activate(self, event, widget, path, background_area, cell_area, flags):
369                 print "activate",path
370                 return False
371
372
373 gobject.type_register(CellRendererCombo2)
374 gobject.type_register(CellRendererTriple)
375
376         
377   
378 class View(gtk.VBox):
379         
380         def loadList(self):
381                 ls=self.liststorehandler.get_liststore()
382                 self.treeview.set_model(ls)
383                 #self.tvcolumn[i].add_attribute( self.cell[i], "active", 1)
384                 #print "setup",ls
385                 
386                 
387         
388         
389         def col_edited(self,cell, irow, new_text,icol=None):
390                 if (irow!=4):
391                         self.liststorehandler.update_row(irow,icol,new_text)
392                 else:
393                         print cell, irow, new_text,icol
394                 
395         def col_toggled(self,widget,irow, status ):
396                 #print irow,ls[irow][1],status
397                 ls=self.treeview.get_model()
398                 
399                 if self.liststorehandler.selection.get_status()=="0":
400                         if ls[irow][1]=="0":
401                                 self.liststorehandler.update_row(irow,1,"1")
402                         else:
403                                 self.liststorehandler.update_row(irow,1,"0")
404                 else:
405                         if ls[irow][1]=="1":
406                                 self.liststorehandler.update_row(irow,1,"-1")
407                         elif ls[irow][1]=="0":
408                                 self.liststorehandler.update_row(irow,1,"1")
409                         else:
410                                 self.liststorehandler.update_row(irow,1,"0")
411                         
412                 #self.tvcolumn[i].set_attributes( self.cell[i], active=i)
413                 
414                 
415         
416         def convert(self,s):
417                 #print s
418                 if (s=="1"):
419                         return 1
420                 else:
421                         return 0
422                 
423                 
424         def del_active_row(self):
425                 path, col = self.treeview.get_cursor()
426                 #print path, col
427                 if path!=None:
428                         irow=path[0]
429                         row_iter=self.treeview.get_model().get_iter(path)
430                         self.liststorehandler.del_row(irow,row_iter)
431
432                         
433                 #treemodel.get_iter()
434                 
435                 
436                 
437         def sort_func_function(self,model, iter1, iter2, data=None):
438                 print "sorting"
439                 
440                 
441         def reload_view(self):
442                 # create the TreeView using liststore
443                 self.modelsort = gtk.TreeModelSort(self.liststorehandler.get_liststore())
444                 self.modelsort.set_sort_column_id(2, gtk.SORT_ASCENDING)
445                 
446                 self.treeview = gtk.TreeView(self.modelsort)
447                 self.treeview.set_headers_visible(True)
448                 
449                 
450                 self.cell=range(self.liststorehandler.get_colcount())
451                 self.tvcolumn=range(self.liststorehandler.get_colcount())
452
453                 
454                 m = self.liststorehandler.get_unitsstore()
455                 
456                 for i in range(self.liststorehandler.get_colcount()):
457                         
458                         if i>5:
459                                 default="0"
460                         else:
461                                 default="1"
462                         if self.db.ladeDirekt("showcol_"+str(self.liststorehandler.get_colname(i)),default)=="1":
463
464                                 if (i==1):
465                                         self.cell[i] = CellRendererTriple()
466                                         self.tvcolumn[i] =      gtk.TreeViewColumn(self.liststorehandler.get_colname(i),self.cell[i])
467                                         self.cell[i].connect( 'status_changed', self.col_toggled)
468                                         self.tvcolumn[i].set_attributes( self.cell[i], status=i)
469                                 
470                                 elif (i==3)or(i==4)or(i==6):
471                                         self.cell[i] = gtk.CellRendererCombo()
472                                         self.tvcolumn[i] =      gtk.TreeViewColumn(self.liststorehandler.get_colname(i),self.cell[i])
473                                         self.cell[i].set_property("model",m)
474                                         self.cell[i].set_property('text-column', i)
475                                         self.cell[i].set_property('editable',True)
476                                         self.cell[i].connect("edited", self.col_edited,i) 
477                                         self.tvcolumn[i].set_attributes( self.cell[i], text=i)
478                                 else:
479                                         self.cell[i] = gtk.CellRendererText()
480                                         self.tvcolumn[i] = gtk.TreeViewColumn(self.liststorehandler.get_colname(i),self.cell[i])
481                                         self.cell[i].set_property('editable',True)
482                                         self.cell[i].set_property('editable-set',True)
483                                         self.cell[i].connect("edited", self.col_edited,i) 
484                                         #self.cell[i].connect("editing-canceled", self.col_edited2,i) 
485                                         self.tvcolumn[i].set_attributes(self.cell[i], text=i)
486
487                                 self.cell[i].set_property('cell-background', 'lightgray')
488                                 self.tvcolumn[i].set_sort_column_id(i)
489                                 self.tvcolumn[i].set_resizable(True)
490                                 
491                                 
492                                 if (i>0):
493                                         self.treeview.append_column(self.tvcolumn[i])
494                                 
495                 
496                 # Allow NOT drag and drop reordering of rows
497                 self.treeview.set_reorderable(False)
498                 
499                 
500                 if self.scrolled_window != None:
501                         self.scrolled_window.destroy()
502                 
503                 self.scrolled_window = gtk.ScrolledWindow()
504                 self.scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
505
506                 self.scrolled_window.add(self.treeview)
507                 self.pack_start(self.scrolled_window, expand=True, fill=True, padding=0)
508                 self.loadList()
509                 
510                 self.show_all()
511         
512         def __init__(self,db,liststorehandler,parent_window):
513                 
514                 self.db=db
515                 self.parent_window=parent_window
516                 self.liststorehandler = liststorehandler
517                 
518                 
519                 gtk.VBox.__init__(self,homogeneous=False, spacing=0)
520                 
521                 logging.info("libview, init")
522
523                 self.scrolled_window = None
524                 self.reload_view()
525                 
526                 
527                 
528                 
529                 
530                 """
531                 bearbeitenFrame=gtk.Frame("Verteilung kopieren nach")
532                 bearbeitenvBox=gtk.VBox(homogeneous=False, spacing=0)
533                 
534                 bearbeitenhBox=gtk.HBox(homogeneous=False, spacing=0)
535                 self.comboKlassen = gtk.combo_box_new_text()
536                 bearbeitenhBox.pack_start(self.comboKlassen, expand=False, fill=True, padding=0)
537                 button=gtk.Button("Kopieren")
538                 button.connect("clicked", self.kopiereStoffverteilung, None)
539                 bearbeitenhBox.pack_start(button, expand=False, fill=True, padding=0)
540                 
541                 label=gtk.Label("   ")
542                 bearbeitenhBox.pack_start(label, expand=False, fill=True, padding=0)
543                 
544                 button=gtk.Button("Export in CSV-Datei")
545                 button.connect("clicked", self.exportStoffverteilung, None)
546                 bearbeitenhBox.pack_start(button, expand=False, fill=True, padding=0)
547                 
548                 bearbeitenvBox.pack_start(bearbeitenhBox, expand=False, fill=True, padding=0)
549                 
550         
551                 bearbeitenFrame.add(bearbeitenvBox)
552                 self.pack_start(bearbeitenFrame, expand=False, fill=True, padding=0)
553                 """
554                 
555                 #self.connect("unmap", self.speichere) 
556                 #self.connect("map", self.ladeWirklich) 
557
558                 #self.show_all()
559                 
560                 
561
562                 #print "libstoffverteilung 9: ",time.clock()
563