Package Simple :: Module _SimpleTable
[frames] | no frames]

Source Code for Module Simple._SimpleTable

  1  # 
  2  # Gramps - a GTK+/GNOME based genealogy program 
  3  # 
  4  # Copyright (C) 2008  Donald N. Allingham 
  5  # 
  6  # This program is free software; you can redistribute it and/or modify 
  7  # it under the terms of the GNU General Public License as published by 
  8  # the Free Software Foundation; either version 2 of the License, or 
  9  # (at your option) any later version. 
 10  # 
 11  # This program is distributed in the hope that it will be useful, 
 12  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 13  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 14  # GNU General Public License for more details. 
 15  # 
 16  # You should have received a copy of the GNU General Public License 
 17  # along with this program; if not, write to the Free Software 
 18  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 19  # 
 20   
 21  """ 
 22  Provide a simplified table creation interface 
 23  """ 
 24   
 25  import copy 
 26  from gettext import gettext as _ 
 27   
 28  import gen.lib 
 29  import Errors 
 30  import DateHandler 
 31   
32 -class SimpleTable:
33 """ 34 Provide a simplified table creation interface. 35 """ 36
37 - def __init__(self, access, doc, title=None):
38 """ 39 Initialize the class with a simpledb, and simpledoc 40 """ 41 self.access = access 42 self.simpledoc = doc # simpledoc; simpledoc.doc = docgen object 43 self.title = title 44 self.__columns = [] 45 self.__rows = [] 46 self.__link = [] 47 self.__sort_col = None 48 self.__sort_reverse = False 49 self.__link_col = None 50 self.__callback_leftclick = None 51 self.__callback_leftdouble = None
52
53 - def get_row_count(self):
54 return len(self.__rows)
55
56 - def columns(self, *columns):
57 """ 58 Set the columns 59 """ 60 self.__columns = list(copy.copy(columns)) 61 self.__sort_vals = [[] for i in range(len(self.__columns))]
62
63 - def set_callback(self, which, callback):
64 """ 65 Override (or add) a function for click/double-click 66 """ 67 if which == "leftclick": 68 self.__callback_leftclick = callback 69 elif which == "leftdouble": 70 self.__callback_leftdouble = callback
71
72 - def on_table_doubleclick(self, obj, path, view_column):
73 """ 74 Handle events on tables. obj is a treeview 75 """ 76 from Editors import (EditPerson, EditEvent, EditFamily, EditSource, 77 EditPlace, EditRepository) 78 selection = obj.get_selection() 79 store, node = selection.get_selected() 80 if not node: 81 return 82 index = store.get_value(node, 0) # index 83 if self.__callback_leftdouble: 84 self.__callback_leftdouble(store.get_value(node, 1)) 85 return True 86 elif self.__link[index]: 87 objclass, handle = self.__link[index] 88 if objclass == 'Person': 89 person = self.access.dbase.get_person_from_handle(handle) 90 try: 91 EditPerson(self.simpledoc.doc.dbstate, 92 self.simpledoc.doc.uistate, [], person) 93 return True # handled event 94 except Errors.WindowActiveError: 95 pass 96 elif objclass == 'Event': 97 event = self.access.dbase.get_event_from_handle(handle) 98 try: 99 EditEvent(self.simpledoc.doc.dbstate, 100 self.simpledoc.doc.uistate, [], event) 101 return True # handled event 102 except Errors.WindowActiveError: 103 pass 104 elif objclass == 'Family': 105 ref = self.access.dbase.get_family_from_handle(handle) 106 try: 107 EditFamily(self.simpledoc.doc.dbstate, 108 self.simpledoc.doc.uistate, [], ref) 109 return True # handled event 110 except Errors.WindowActiveError: 111 pass 112 elif objclass == 'Source': 113 ref = self.access.dbase.get_source_from_handle(handle) 114 try: 115 EditSource(self.simpledoc.doc.dbstate, 116 self.simpledoc.doc.uistate, [], ref) 117 return True # handled event 118 except Errors.WindowActiveError: 119 pass 120 elif objclass == 'Place': 121 ref = self.access.dbase.get_place_from_handle(handle) 122 try: 123 EditPlace(self.simpledoc.doc.dbstate, 124 self.simpledoc.doc.uistate, [], ref) 125 return True # handled event 126 except Errors.WindowActiveError: 127 pass 128 elif objclass == 'Repository': 129 ref = self.access.dbase.get_repository_from_handle(handle) 130 try: 131 EditRepository(self.simpledoc.doc.dbstate, 132 self.simpledoc.doc.uistate, [], ref) 133 return True # handled event 134 except Errors.WindowActiveError: 135 pass 136 return False # didn't handle event
137
138 - def on_table_click(self, obj):
139 """ 140 Handle events on tables. obj is a treeview 141 """ 142 selection = obj.get_selection() 143 store, node = selection.get_selected() 144 if not node: 145 return 146 index = store.get_value(node, 0) # index 147 if self.__callback_leftclick: 148 self.__callback_leftclick(store.get_value(node, 1)) 149 return True 150 elif self.__link[index]: 151 objclass, handle = self.__link[index] 152 if objclass == 'Person': 153 person = self.access.dbase.get_person_from_handle(handle) 154 self.simpledoc.doc.dbstate.change_active_person(person) 155 return True 156 return False # didn't handle event
157
158 - def row_sort_val(self, col, val):
159 """ 160 Add a row of data to sort by. 161 """ 162 self.__sort_vals[col].append(val)
163 169
170 - def row(self, *data):
171 """ 172 Add a row of data. 173 """ 174 retval = [] 175 link = None 176 for col in range(len(data)): 177 item = data[col] 178 # FIXME: add better text representations of these objects 179 if type(item) in [str, unicode]: 180 retval.append(item) 181 elif type(item) in [int, float, long]: 182 retval.append(item) 183 self.row_sort_val(col, item) 184 elif isinstance(item, gen.lib.Person): 185 name = self.access.name(item) 186 retval.append(name) 187 if (self.__link_col == col or link == None): 188 link = ('Person', item.handle) 189 elif isinstance(item, gen.lib.Family): 190 father = self.access.father(item) 191 mother = self.access.mother(item) 192 text = "" 193 if father: 194 text += " " + self.access.name(father) 195 else: 196 text += " " + _("Unknown father") 197 text += " and" 198 if mother: 199 text += " " + self.access.name(mother) 200 else: 201 text += " " + _("Unknown mother") 202 retval.append(text) 203 if (self.__link_col == col or link == None): 204 link = ('Family', item.handle) 205 elif isinstance(item, gen.lib.Source): 206 retval.append(_('Source')) 207 if (self.__link_col == col or link == None): 208 link = ('Souce', item.handle) 209 elif isinstance(item, gen.lib.Event): 210 name = self.access.event_type(item) 211 retval.append(name) 212 if (self.__link_col == col or link == None): 213 link = ('Event', item.handle) 214 elif isinstance(item, gen.lib.MediaObject): 215 retval.append(_('Media')) 216 if (self.__link_col == col or link == None): 217 link = ('Media', item.handle) 218 elif isinstance(item, gen.lib.Place): 219 retval.append(_('Place')) 220 if (self.__link_col == col or link == None): 221 link = ('Place', item.handle) 222 elif isinstance(item, gen.lib.Repository): 223 retval.append(_('Repository')) 224 if (self.__link_col == col or link == None): 225 link = ('Repository', item.handle) 226 elif isinstance(item, gen.lib.Note): 227 retval.append(_('Note')) 228 if (self.__link_col == col or link == None): 229 link = ('Note', item.handle) 230 elif isinstance(item, gen.lib.Date): 231 text = DateHandler.displayer.display(item) 232 retval.append(text) 233 self.row_sort_val(col, item.sortval) 234 if (self.__link_col == col or link == None): 235 link = ('Date', item) 236 else: 237 raise AttributeError, ("unknown object type: '%s': %s" % 238 (item, type(item))) 239 self.__link.append(link) 240 self.__rows.append(retval)
241
242 - def sort(self, column_name, reverse=False):
243 self.__sort_col = column_name 244 self.__sort_reverse = reverse
245
246 - def __sort(self):
247 idx = self.__columns.index(self.__sort_col) 248 if self.__sort_reverse: 249 self.__rows.sort(lambda a, b: -cmp(a[idx],b[idx])) 250 else: 251 self.__rows.sort(lambda a, b: cmp(a[idx],b[idx]))
252
253 - def write(self):
254 if self.simpledoc.doc.type == "standard": 255 doc = self.simpledoc.doc 256 doc.start_table('simple','Table') 257 columns = len(self.__columns) 258 if self.title: 259 doc.start_row() 260 doc.start_cell('TableHead',columns) 261 doc.start_paragraph('TableTitle') 262 doc.write_text(_(self.title)) 263 doc.end_paragraph() 264 doc.end_cell() 265 doc.end_row() 266 if self.__sort_col: 267 self.__sort() 268 doc.start_row() 269 for col in self.__columns: 270 doc.start_cell('TableNormalCell',1) 271 doc.write_text(col,'TableTitle') 272 doc.end_cell() 273 doc.end_row() 274 for row in self.__rows: 275 doc.start_row() 276 for col in row: 277 doc.start_cell('TableNormalCell',1) 278 doc.write_text(col,'Normal') 279 doc.end_cell() 280 doc.end_row() 281 doc.end_table() 282 doc.start_paragraph("Normal") 283 doc.end_paragraph() 284 elif self.simpledoc.doc.type == "gtk": 285 import gtk 286 buffer = self.simpledoc.doc.buffer 287 text_view = self.simpledoc.doc.text_view 288 model_index = 1 # start after index 289 if self.__sort_col: 290 sort_index = self.__columns.index(self.__sort_col) 291 else: 292 sort_index = 0 293 treeview = gtk.TreeView() 294 treeview.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH) 295 treeview.connect('row-activated', self.on_table_doubleclick) 296 treeview.connect('cursor-changed', self.on_table_click) 297 renderer = gtk.CellRendererText() 298 types = [int] # index 299 cnt = 0 300 sort_data = [] 301 sort_data_types = [] 302 for col in self.__columns: 303 types.append(type(col)) 304 column = gtk.TreeViewColumn(col,renderer,text=model_index) 305 if self.__sort_vals[cnt] != []: 306 sort_data.append(self.__sort_vals[cnt]) 307 column.set_sort_column_id(len(self.__columns) + 308 len(sort_data)) 309 sort_data_types.append(int) 310 else: 311 column.set_sort_column_id(model_index) 312 treeview.append_column(column) 313 #if model_index == sort_index: 314 # FIXME: what to set here? 315 model_index += 1 316 cnt += 1 317 if self.title: 318 self.simpledoc.paragraph(self.title) 319 # Make a GUI to put the tree view in 320 types += sort_data_types 321 model = gtk.ListStore(*types) 322 treeview.set_model(model) 323 iter = buffer.get_end_iter() 324 anchor = buffer.create_child_anchor(iter) 325 text_view.add_child_at_anchor(treeview, anchor) 326 count = 0 327 for data in self.__rows: 328 model.append(row=([count] + list(data) + [col[count] for col in sort_data])) 329 count += 1 330 text_view.show_all() 331 self.simpledoc.paragraph("") 332 self.simpledoc.paragraph("")
333