* src/PedView.py: More work on it.
* src/MapView.py: New View showing locations on a map. Early unfinished version. * src/gramps_main.py: Enable MapView * src/land_shallow_topo_2048.jpg: * src/land_shallow_topo_350.jpg: Two new map images downloaded from NASA so the are assumed to be public domain. svn: r5050
This commit is contained in:
		| @@ -1,3 +1,11 @@ | ||||
| 2005-08-11  Martin Hawlisch  <Martin.Hawlisch@gmx.de> | ||||
| 	* src/PedView.py: More work on it. | ||||
| 	* src/MapView.py: New View showing locations on a map. Early unfinished version. | ||||
| 	* src/gramps_main.py: Enable MapView | ||||
| 	* src/land_shallow_topo_2048.jpg: | ||||
| 	* src/land_shallow_topo_350.jpg: Two new map images downloaded from NASA | ||||
| 	so the are assumed to be public domain. | ||||
|  | ||||
| 2005-08-10  Don Allingham  <don@gramps-project.org> | ||||
| 	* src/DbState.py: separate database class from display class | ||||
| 	* src/EditPerson.py: separate database class from display class | ||||
|   | ||||
							
								
								
									
										356
									
								
								src/MapView.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										356
									
								
								src/MapView.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,356 @@ | ||||
| # | ||||
| # Gramps - a GTK+/GNOME based genealogy program | ||||
| # | ||||
| # Copyright (C) 2001-2005  Donald N. Allingham | ||||
| # | ||||
| # This program is free software; you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation; either version 2 of the License, or | ||||
| # (at your option) any later version. | ||||
| # | ||||
| # This program is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
| # | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with this program; if not, write to the Free Software | ||||
| # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||||
| # | ||||
|  | ||||
| # $Id$ | ||||
|  | ||||
| #------------------------------------------------------------------------- | ||||
| # | ||||
| # Python modules | ||||
| # | ||||
| #------------------------------------------------------------------------- | ||||
| from gettext import gettext as _ | ||||
|  | ||||
| #------------------------------------------------------------------------- | ||||
| # | ||||
| # GTK/Gnome modules | ||||
| # | ||||
| #------------------------------------------------------------------------- | ||||
| import gobject | ||||
| import gtk | ||||
| import gtk.gdk | ||||
| import gc | ||||
|  | ||||
| #------------------------------------------------------------------------- | ||||
| # | ||||
| # Gramps Modules | ||||
| # | ||||
| #------------------------------------------------------------------------- | ||||
| import RelLib | ||||
| import PageView | ||||
|  | ||||
|  | ||||
| data = (("_Center", 0,0), | ||||
|         ("_North",0,80), | ||||
|         ("_South",0,-80), | ||||
|         ("_West",-170,0), | ||||
|         ("_East",170,0), | ||||
|         ("Chicago",-87.75,41.83), | ||||
|         ("Berlin",13.42,52.53), | ||||
|         ("Honolulu",-157.83,21.32), | ||||
|         ("Madrid",-3.72,40.42), | ||||
|         ("Moscow",37.70,55.75), | ||||
|         ("Vienna",16.37,48.22), | ||||
|         ("Sidney",151.17,-33.92), | ||||
|         ("Rio de Janeiro",-43.28,-22.88), | ||||
|         ("Tokyo",139.75,35.67), | ||||
|         ("Cape Town",18.47,-33.93), | ||||
|         ("Anchorage",-150.00,61.17)) | ||||
|  | ||||
|  | ||||
| # Draws a map image and tries to allocate space in the correct aspect ratio | ||||
| class GuideMap(gtk.DrawingArea): | ||||
|     def __init__(self, map_pixbuf): | ||||
|         gtk.DrawingArea.__init__(self) | ||||
|         self.map_pixbuf = map_pixbuf | ||||
|         self.connect("expose-event", self.expose_cb) | ||||
|         self.connect("size-allocate", self.size_allocate_cb) | ||||
|         #self.connect("size-request", self.size_request_cb) | ||||
|         self.gc = None | ||||
|         self.current_area = None | ||||
|         self.old_size = (-1,-1) | ||||
|      | ||||
|     # Set hightlight region | ||||
|     def hightlight_area( self, area): | ||||
|         print "GuideMap.hightlight_area" | ||||
|         print area | ||||
|         self.current_area = area | ||||
|         self.queue_draw() | ||||
|          | ||||
|     # Redraw the image | ||||
|     def expose_cb(self,widget,event): | ||||
|         a = widget.get_allocation() | ||||
|         print "GuideMap.expose_cb (%dx%d)" % (a.width,a.height) | ||||
|         if not self.gc: | ||||
|             self.gc = self.window.new_gc() | ||||
|             self.gc.set_foreground( self.get_colormap().alloc_color("red")) | ||||
|             self.gc.set_background( self.get_colormap().alloc_color("blue")) | ||||
|         if self.backbuf and self.gc: | ||||
|             self.window.draw_pixbuf( self.gc, self.backbuf, 0,0, 0,0, -1,-1) | ||||
|             if self.current_area: | ||||
|                 r = self.map_to_screen(self.current_area[0],self.current_area[1],self.current_area[2],self.current_area[3]) | ||||
|                 self.window.draw_rectangle( self.gc, False, r[0],r[1], r[2],r[3]) | ||||
|  | ||||
|     # Scale backbuffer | ||||
|     def size_allocate_cb(self,widget,allocation): | ||||
|         a = allocation | ||||
|         print "GuideMap.size_allocate_cb (%dx%d)" % (a.width,a.height) | ||||
|         # Always request a height, that is half of the width | ||||
|         w = max( 128,allocation.width) | ||||
|         self.set_size_request(-1,w/2) | ||||
|          | ||||
|         # only create new backbuffer if size is different | ||||
|         new_size = (allocation.width,allocation.height) | ||||
|         if new_size is not self.old_size: | ||||
|             self.old_size = new_size | ||||
|             self.backbuf = self.map_pixbuf.scale_simple(self.old_size[0],self.old_size[1],gtk.gdk.INTERP_BILINEAR) | ||||
|             gc.collect() | ||||
|  | ||||
|     def map_to_screen( self, x,y,w,h): | ||||
|         px = int((float(x) + 180.0) / 360.0 * self.backbuf.get_width()) | ||||
|         py = int((90-float(y)) / 180.0 * self.backbuf.get_height()) | ||||
|         pw = int(float(w) / 360.0 * self.backbuf.get_width()) | ||||
|         ph = int(float(h) / 180.0 * self.backbuf.get_height()) | ||||
|          | ||||
|         return (px,py,pw,ph) | ||||
|  | ||||
| # Zoomable map image | ||||
| class ZoomMap( gtk.DrawingArea): | ||||
|     def __init__(self, map_pixbuf, place_marker_pixbuf, hightlight_marker_pixbuf): | ||||
|         gtk.DrawingArea.__init__(self) | ||||
|         self.map_pixbuf = map_pixbuf | ||||
|         self.place_marker_pixbuf = place_marker_pixbuf | ||||
|         self.hightlight_marker_pixbuf = hightlight_marker_pixbuf | ||||
|         self.connect("expose-event", self.expose_cb) | ||||
|         self.connect("size-allocate", self.size_allocate_cb) | ||||
|         self.gc = None | ||||
|         self.old_size = (-1,-1) | ||||
|         self.zoom_pos = (0,0) | ||||
|         self.current_area = (0,0,0,0) | ||||
|         self.magnifer = 0.5 | ||||
|         self.guide = None | ||||
|      | ||||
|     # Set the guide map that should follow the zoom area | ||||
|     def set_guide( self, guide): | ||||
|         self.guide = guide | ||||
|          | ||||
|     # Redraw the image | ||||
|     def expose_cb(self,widget,event): | ||||
|         a = widget.get_allocation() | ||||
|         print "GuideMap.expose_cb (%dx%d)" % (a.width,a.height) | ||||
|         if not self.gc: | ||||
|             self.gc = self.window.new_gc() | ||||
|             self.gc.set_foreground( self.get_colormap().alloc_color("red")) | ||||
|             self.gc.set_background( self.get_colormap().alloc_color("blue")) | ||||
|         if not self.backbuf: | ||||
|             self.size_allocate_cb( self,self.get_allocation()) | ||||
|         if self.backbuf and self.gc: | ||||
|             self.window.draw_pixbuf( self.gc, self.backbuf, 0,0, 0,0, -1,-1) | ||||
|             px = int((float(self.zoom_pos[1]) + 180.0) / 360.0 * self.backbuf.get_width()) | ||||
|             py = int((90-float(self.zoom_pos[0])) / 180.0 * self.backbuf.get_height()) | ||||
|             self.window.draw_pixbuf( self.gc, self.hightlight_marker_pixbuf, 0,0, px-self.hightlight_marker_pixbuf.get_width()/2,py-self.hightlight_marker_pixbuf.get_height()/2, -1,-1) | ||||
|             self.window.draw_rectangle( self.gc, False, px-3,py-3, 6,6) | ||||
|  | ||||
|     # Scale backbuffer | ||||
|     def size_allocate_cb(self,widget,allocation): | ||||
|         a = allocation | ||||
|         print "GuideMap.size_allocate_cb (%dx%d)" % (a.width,a.height) | ||||
|          | ||||
|         # only create new backbuffer if size is different | ||||
|         new_size = (allocation.width,allocation.height) | ||||
|         if new_size is not self.old_size or not self.backbuf: | ||||
|             self.old_size = new_size | ||||
|              | ||||
|             # Desired midpoint in map | ||||
|             pw = int(self.old_size[0]*self.magnifer) | ||||
|             ph = int(self.old_size[1]*self.magnifer) | ||||
|              | ||||
|             px = int((float(self.zoom_pos[1]) + 180.0) / 360.0 * self.map_pixbuf.get_width()) | ||||
|             py = int((90-float(self.zoom_pos[0])) / 180.0 * self.map_pixbuf.get_height()) | ||||
|  | ||||
|             px = max( pw/2, px) | ||||
|             py = max( ph/2, py) | ||||
|              | ||||
|             px = min( px, self.map_pixbuf.get_width()-pw/2) | ||||
|             py = min( py, self.map_pixbuf.get_height()-ph/2) | ||||
|              | ||||
|             zoomebuf = self.map_pixbuf.subpixbuf( int(px-pw/2), int(py-ph/2), pw,ph) | ||||
|             print ( px-pw/2, py-ph/2, pw,ph) | ||||
|              | ||||
|             self.backbuf = zoomebuf.scale_simple(self.old_size[0],self.old_size[1],gtk.gdk.INTERP_BILINEAR) | ||||
|             gc.collect() | ||||
|             if self.guide: | ||||
|                 mx = 360.0 / self.map_pixbuf.get_width() * (px-pw/2.0) - 180.0 | ||||
|                 my = 90.0 - 180.0 / self.map_pixbuf.get_height() * (py-ph/2.0) | ||||
|                 mw = 360.0 / self.map_pixbuf.get_width() * pw | ||||
|                 mh = 180.0 / self.map_pixbuf.get_height() * ph | ||||
|                 self.guide.hightlight_area( (mx,my,mw,mh)) | ||||
|             self.current_area = (px-pw/2, py-ph/2, pw,ph) | ||||
|  | ||||
|     # Scroll to requested position | ||||
|     def scroll_to( self, lat, lon): | ||||
|         self.zoom_pos = ( min(90,(max(-90,lon))), min(180,(max(-180,lat)))) | ||||
|         self.backbuf = None | ||||
|         self.queue_draw() | ||||
|  | ||||
|     def zoom_in(self): | ||||
|         self.magnifer = min( 10, self.magnifer * 1.5) | ||||
|         self.backbuf = None | ||||
|         self.queue_draw() | ||||
|      | ||||
|     def zoom_out(self): | ||||
|         self.magnifer = max( 0.1, self.magnifer * 0.75) | ||||
|         self.backbuf = None | ||||
|         self.queue_draw() | ||||
|      | ||||
|     def zoom_normal(self): | ||||
|         self.magnifer = 1 | ||||
|         self.backbuf = None | ||||
|         self.queue_draw() | ||||
|  | ||||
|     def zoom_fit(self): | ||||
|         self.magnifer = 2 | ||||
|         self.backbuf = None | ||||
|         self.queue_draw() | ||||
|  | ||||
|  | ||||
| # Place list widget | ||||
| class MapPlacesList(gtk.TreeView): | ||||
|     def __init__(self, data): | ||||
|         lstore = gtk.ListStore( | ||||
|             gobject.TYPE_STRING, | ||||
|             gobject.TYPE_FLOAT, | ||||
|             gobject.TYPE_FLOAT) | ||||
|          | ||||
|         for item in data: | ||||
|             iter = lstore.append() | ||||
|             lstore.set(iter, | ||||
|                 0, item[0], | ||||
|                 1, item[1], | ||||
|                 2, item[2]) | ||||
|  | ||||
|         gtk.TreeView.__init__(self, lstore) | ||||
|         self.set_rules_hint(True) | ||||
|         self.set_search_column(0) | ||||
|  | ||||
|         column = gtk.TreeViewColumn('Place', gtk.CellRendererText(), text=0) | ||||
|         column.set_sort_column_id(0) | ||||
|         self.append_column(column) | ||||
|  | ||||
|         column = gtk.TreeViewColumn('Lat', gtk.CellRendererText(), text=1) | ||||
|         column.set_sort_column_id(1) | ||||
|         self.append_column(column) | ||||
|  | ||||
|         column = gtk.TreeViewColumn('Long', gtk.CellRendererText(),text=2) | ||||
|         column.set_sort_column_id(2) | ||||
|         self.append_column(column) | ||||
|  | ||||
|  | ||||
|  | ||||
| # Map View main class | ||||
| class MapView(PageView.PageView): | ||||
|     def __init__(self,dbstate,uistate): | ||||
|         PageView.PageView.__init__(self,'Pedigree View',dbstate,uistate) | ||||
|         dbstate.connect('database-changed',self.change_db) | ||||
|         self.current_marker = None | ||||
|  | ||||
|     def navigation_type(self): | ||||
|         print "MapView.navigation_type" | ||||
|         return PageView.NAVIGATION_NONE | ||||
|  | ||||
|     def define_actions(self): | ||||
|         print "MapView.define_actions" | ||||
|         self.add_action('ZoomIn',   gtk.STOCK_ZOOM_IN,  "Zoom _In",     callback=self.zoom_in_cb) | ||||
|         self.add_action('ZoomOut',  gtk.STOCK_ZOOM_OUT, "Zoom _Out",    callback=self.zoom_out_cb) | ||||
|         self.add_action('ZoomNormal',gtk.STOCK_ZOOM_100,"_Normal Size", callback=self.zoom_100_cb) | ||||
|         self.add_action('ZoomFit',  gtk.STOCK_ZOOM_FIT, "Best _Fit",    callback=self.zoom_fit_cb) | ||||
|  | ||||
|     def get_stock(self): | ||||
|         """ | ||||
|         Returns the name of the stock icon to use for the display. | ||||
|         This assumes that this icon has already been registered with | ||||
|         GNOME as a stock icon. | ||||
|         """ | ||||
|         return 'gramps-place' | ||||
|  | ||||
|     def build_widget(self): | ||||
|         hbox = gtk.HBox( False, 4) | ||||
|         hbox.set_border_width( 4) | ||||
|  | ||||
|         # The large zoomable map | ||||
|         self.zoom_map = ZoomMap( | ||||
|             gtk.gdk.pixbuf_new_from_file("land_shallow_topo_2048.jpg"), | ||||
|             gtk.gdk.pixbuf_new_from_file("bad.png"), | ||||
|             gtk.gdk.pixbuf_new_from_file("good.png")) | ||||
|         self.zoom_map.set_size_request(300,300) | ||||
|         hbox.pack_start( self.zoom_map, True, True, 0) | ||||
|          | ||||
|         # On the right side | ||||
|         vbox = gtk.VBox( False, 4) | ||||
|         hbox.pack_start( vbox, False, True, 0) | ||||
|          | ||||
|         # The small guide map | ||||
|         self.guide_map = GuideMap( gtk.gdk.pixbuf_new_from_file("land_shallow_topo_350.jpg")) | ||||
|         self.guide_map.set_size_request(128,64) | ||||
|         vbox.pack_start( self.guide_map, False, True, 0) | ||||
|          | ||||
|         self.zoom_map.set_guide(self.guide_map) | ||||
|          | ||||
|         # And the place list | ||||
|         self.place_list_view = MapPlacesList( data) | ||||
|         vbox.pack_start( self.place_list_view,True,True,0) | ||||
|  | ||||
|         self.place_list_view.connect("cursor-changed", self.entry_select_cb) | ||||
|         | ||||
|         return hbox | ||||
|  | ||||
|     def ui_definition(self): | ||||
|         """ | ||||
|         Specifies the UIManager XML code that defines the menus and buttons | ||||
|         associated with the interface. | ||||
|         """ | ||||
|         return '''<ui> | ||||
|           <toolbar name="ToolBar"> | ||||
|             <toolitem action="ZoomIn"/>   | ||||
|             <toolitem action="ZoomOut"/>   | ||||
|             <toolitem action="ZoomNormal"/> | ||||
|             <toolitem action="ZoomFit"/> | ||||
|           </toolbar> | ||||
|         </ui>''' | ||||
|  | ||||
|     def change_db(self,db): | ||||
|         print "MapView.change_db" | ||||
|         """ | ||||
|         Callback associated with DbState. Whenenver the database | ||||
|         changes, this task is called. In this case, we rebuild the | ||||
|         columns, and connect signals to the connected database. Tere | ||||
|         is no need to store the database, since we will get the value | ||||
|         from self.state.db | ||||
|         """ | ||||
|         self.db = db | ||||
|  | ||||
|     def entry_select_cb(self,treeview): | ||||
|         s = treeview.get_selection() | ||||
|         (model,sel) = s.get_selected_rows() | ||||
|         for path in sel: | ||||
|             iter = model.get_iter(path) | ||||
|             self.zoom_map.scroll_to(model.get_value(iter,1), model.get_value(iter,2)) | ||||
|             break | ||||
|  | ||||
|     def zoom_in_cb(self,obj): | ||||
|         self.zoom_map.zoom_in() | ||||
|  | ||||
|     def zoom_out_cb(self,obj): | ||||
|         self.zoom_map.zoom_out() | ||||
|  | ||||
|     def zoom_100_cb(self,obj): | ||||
|         self.zoom_map.zoom_normal() | ||||
|  | ||||
|     def zoom_fit_cb(self,obj): | ||||
|         self.zoom_map.zoom_fit() | ||||
							
								
								
									
										186
									
								
								src/PedView.py
									
									
									
									
									
								
							
							
						
						
									
										186
									
								
								src/PedView.py
									
									
									
									
									
								
							| @@ -41,12 +41,10 @@ import gtk.gdk | ||||
| # Gramps Modules | ||||
| # | ||||
| #------------------------------------------------------------------------- | ||||
| import PageView | ||||
| import const | ||||
| import GrampsCfg | ||||
| import Relationship | ||||
| import NameDisplay | ||||
| import RelLib | ||||
| import PageView | ||||
| import EditPerson | ||||
| import NameDisplay | ||||
| import Utils | ||||
| import DateHandler | ||||
|  | ||||
| @@ -55,9 +53,7 @@ import DateHandler | ||||
| # Constants | ||||
| # | ||||
| #------------------------------------------------------------------------- | ||||
| _PAD       = 3 | ||||
| _CANVASPAD = 3 | ||||
| _PERSON    = "p" | ||||
| _PERSON = "p" | ||||
| _BORN = _('b.') | ||||
| _DIED = _('d.') | ||||
| _BAPT = _('bap.') | ||||
| @@ -74,18 +70,98 @@ _CREM = _('crem.') | ||||
| class PedView(PageView.PageView): | ||||
|  | ||||
|     def __init__(self,dbstate,uistate): | ||||
|         print "PedView.__init__" | ||||
|         PageView.PageView.__init__(self,'Pedigree View',dbstate,uistate) | ||||
|         self.inactive = False | ||||
|         dbstate.connect('database-changed',self.change_db) | ||||
|         dbstate.connect('active-changed',self.goto_active_person) | ||||
|         self.force_size = 0 # Automatic resize | ||||
|  | ||||
|     def navigation_type(self): | ||||
|         print "PedView.navigation_type" | ||||
|         return PageView.NAVIGATION_PERSON | ||||
|  | ||||
|     def init_parent_signals_cb(self, widget, event): | ||||
|         print "PedView.init_parent_signals_cb" | ||||
|         self.notebook.disconnect(self.bootstrap_handler) | ||||
|         self.notebook.parent.connect("size-allocate", self.size_request_cb) | ||||
|         self.size_request_cb(widget.parent,event) | ||||
|          | ||||
|     def add_table_to_notebook( self, table): | ||||
|         frame = gtk.ScrolledWindow(None,None) | ||||
|         frame.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC) | ||||
|         frame.add_with_viewport(table) | ||||
|         try: | ||||
|             self.notebook.append_page(frame,None) | ||||
|         except: | ||||
|             # for PyGtk < 2.4 | ||||
|             self.notebook.append_page(frame,gtk.Label("")) | ||||
|  | ||||
|     def define_actions(self): | ||||
|         print "PedView.define_actions" | ||||
|         self.add_action('Forward',gtk.STOCK_GO_FORWARD,"_Forward", callback=self.fwd_clicked) | ||||
|         self.add_action('Back',   gtk.STOCK_GO_BACK,   "_Back",    callback=self.back_clicked) | ||||
|         self.add_action('HomePerson', gtk.STOCK_HOME,  "_Home",    callback=self.home) | ||||
|  | ||||
|         # add the Forward action group to handle the Forward button | ||||
|         self.fwd_action = gtk.ActionGroup(self.title + '/Forward') | ||||
|         self.fwd_action.add_actions([ | ||||
|             ('Forward',gtk.STOCK_GO_FORWARD,"_Forward", None, None, self.fwd_clicked) | ||||
|             ]) | ||||
|  | ||||
|         # add the Backward action group to handle the Forward button | ||||
|         self.back_action = gtk.ActionGroup(self.title + '/Backward') | ||||
|         self.back_action.add_actions([ | ||||
|             ('Back',gtk.STOCK_GO_BACK,"_Back", None, None, self.back_clicked) | ||||
|             ]) | ||||
|  | ||||
|         self.add_action_group(self.back_action) | ||||
|         self.add_action_group(self.fwd_action) | ||||
|  | ||||
|     def disable_action_group(self): | ||||
|         print "PedView.disable_action_group" | ||||
|         """ | ||||
|         Normally, this would not be overridden from the base class. However, | ||||
|         in this case, we have additional action groups that need to be | ||||
|         handled correctly. | ||||
|         """ | ||||
|         PageView.PageView.disable_action_group(self) | ||||
|          | ||||
|         self.fwd_action.set_visible(False) | ||||
|         self.back_action.set_visible(False) | ||||
|  | ||||
|     def enable_action_group(self,obj): | ||||
|         print "PedView.enable_action_group" | ||||
|         """ | ||||
|         Normally, this would not be overridden from the base class. However, | ||||
|         in this case, we have additional action groups that need to be | ||||
|         handled correctly. | ||||
|         """ | ||||
|         PageView.PageView.enable_action_group(self,obj) | ||||
|          | ||||
|         self.fwd_action.set_visible(True) | ||||
|         self.back_action.set_visible(True) | ||||
|         hobj = self.uistate.phistory | ||||
|         self.fwd_action.set_sensitive(not hobj.at_end()) | ||||
|         self.back_action.set_sensitive(not hobj.at_front()) | ||||
|  | ||||
|     def get_stock(self): | ||||
|         """ | ||||
|         Returns the name of the stock icon to use for the display. | ||||
|         This assumes that this icon has already been registered with | ||||
|         GNOME as a stock icon. | ||||
|         """ | ||||
|         return 'gramps-pedigree' | ||||
|  | ||||
|     def build_widget(self): | ||||
|         print "PedView.build_widget" | ||||
|         """ | ||||
|         Builds the interface and returns a gtk.Container type that | ||||
|         contains the interface. This containter will be inserted into | ||||
|         a gtk.Notebook page. | ||||
|         """ | ||||
|         self.notebook = gtk.Notebook() | ||||
|         self.notebook.connect("button-press-event", self.on_show_option_menu_cb) | ||||
|         self.bootstrap_handler = self.notebook.connect("expose-event", self.init_parent_signals_cb) | ||||
|         self.notebook.set_show_border(False) | ||||
|         self.notebook.set_show_tabs(False) | ||||
|              | ||||
| @@ -105,75 +181,82 @@ class PedView(PageView.PageView): | ||||
|         self.table_5.connect("button-press-event", self.on_show_option_menu_cb) | ||||
|         self.add_table_to_notebook( self.table_5) | ||||
|  | ||||
|         #self.parent_container.connect("size-allocate", self.size_request_cb) | ||||
|         self.rebuild_trees(None) | ||||
|  | ||||
|         return self.notebook | ||||
|  | ||||
|     def add_table_to_notebook( self, table): | ||||
|         frame = gtk.ScrolledWindow(None,None) | ||||
|         frame.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC) | ||||
|         frame.add_with_viewport(table) | ||||
|         try: | ||||
|             self.notebook.append_page(frame,None) | ||||
|         except: | ||||
|             # for PyGtk < 2.4 | ||||
|             self.notebook.append_page(frame,gtk.Label("")) | ||||
|  | ||||
|     def define_actions(self): | ||||
|         #self.add_action('Add',    gtk.STOCK_ADD,       "_Add",     callback=self.add) | ||||
|         #self.add_action('Edit',   gtk.STOCK_EDIT,      "_Edit",    callback=self.edit) | ||||
|         #self.add_action('Remove', gtk.STOCK_REMOVE,    "_Remove",  callback=self.remove) | ||||
|         #self.add_action('Forward',gtk.STOCK_GO_FORWARD,"_Forward", callback=self.fwd_clicked) | ||||
|         #self.add_action('Back',   gtk.STOCK_GO_BACK,   "_Back",    callback=self.back_clicked) | ||||
|         self.add_action('HomePerson', gtk.STOCK_HOME,  "_Home",    callback=self.home) | ||||
|         #self.add_toggle_action('Filter',  None,        '_Filter',  callback=self.filter_toggle) | ||||
|  | ||||
|     def ui_definition(self): | ||||
|         """ | ||||
|         Specifies the UIManager XML code that defines the menus and buttons | ||||
|         associated with the interface. | ||||
|         """ | ||||
|         return '''<ui> | ||||
|           <menubar name="MenuBar"> | ||||
|             <menu action="GoMenu"> | ||||
|               <placeholder name="CommonGo"> | ||||
|                 <menuitem action="Back"/> | ||||
|                 <menuitem action="Forward"/> | ||||
|                 <separator/> | ||||
|                 <menuitem action="HomePerson"/> | ||||
|                 <separator/> | ||||
|               </placeholder> | ||||
|             </menu> | ||||
|           </menubar> | ||||
|           <toolbar name="ToolBar"> | ||||
|             <placeholder name="CommonNavigation"> | ||||
|               <toolitem action="Back"/>   | ||||
|               <toolitem action="Forward"/>   | ||||
|               <toolitem action="HomePerson"/> | ||||
|             </placeholder> | ||||
|           </toolbar> | ||||
|         </ui>''' | ||||
|  | ||||
|     def get_stock(self): | ||||
|         return 'gramps-pedigree' | ||||
|  | ||||
|     def change_db(self,db): | ||||
|         # Reconnect signals | ||||
|         print "PedView.change_db" | ||||
|         """ | ||||
|         Callback associated with DbState. Whenenver the database | ||||
|         changes, this task is called. In this case, we rebuild the | ||||
|         columns, and connect signals to the connected database. Tere | ||||
|         is no need to store the database, since we will get the value | ||||
|         from self.state.db | ||||
|         """ | ||||
|         self.db = db | ||||
|         db.connect('person-add', self.person_updated_cb) | ||||
|         db.connect('person-update', self.person_updated_cb) | ||||
|         db.connect('person-delete', self.person_updated_cb) | ||||
|         db.connect('person-rebuild', self.person_rebuild) | ||||
|         self.active_person = None | ||||
|  | ||||
|     def person_updated_cb(self,handle_list): | ||||
|         self.rebuild_trees(self.active_person) | ||||
|  | ||||
|     def person_rebuild(self): | ||||
|         self.rebuild_trees(self.active_person) | ||||
|  | ||||
|     def goto_active_person(self,handle): | ||||
|         self.rebuild_trees(None) | ||||
|   | ||||
|     def goto_active_person(self,handle=None): | ||||
|         print "PedView.goto_active_person" | ||||
|         if handle: | ||||
|             self.active_person = self.db.get_person_from_handle(handle) | ||||
|             self.rebuild_trees(self.active_person) | ||||
|             self.rebuild_trees(self.db.get_person_from_handle(handle)) | ||||
|         else: | ||||
|             self.rebuild_trees(None) | ||||
|      | ||||
|     def fwd_clicked(self,obj,step=1): | ||||
|         pass | ||||
|      | ||||
|     def back_clicked(self,obj,step=1): | ||||
|         pass | ||||
|          | ||||
|     def person_updated_cb(self,handle_list): | ||||
|         print "PedView.person_updated_cb" | ||||
|         self.rebuild_trees(self.dbstate.active) | ||||
|  | ||||
|     def person_rebuild(self): | ||||
|         print "PedView.person_rebuild" | ||||
|         self.rebuild_trees(self.dbstate.active) | ||||
|  | ||||
|     def person_edited_cb(self, p1=None, p2=None): | ||||
|         print "PedView.person_edited_cb" | ||||
|  | ||||
|     def request_resize(self): | ||||
|         print "PedView.request_resize" | ||||
|         self.size_request_cb(self.notebook.parent,None,None) | ||||
|          | ||||
|     def size_request_cb(self, widget, event, data=None): | ||||
|         print "PedView.size_request_cb" | ||||
|         if self.force_size == 0: | ||||
|             v = widget.get_allocation() | ||||
|             page_list = range(0,self.notebook.get_n_pages()) | ||||
| @@ -248,13 +331,14 @@ class PedView(PageView.PageView): | ||||
|         self.rebuild( self.table_4, pos_4, person) | ||||
|         self.rebuild( self.table_5, pos_5, person) | ||||
|          | ||||
|         gobject.idle_add(self.request_resize) | ||||
|         #gobject.idle_add(self.request_resize) | ||||
|  | ||||
|  | ||||
|     def rebuild( self, table_widget, positions, active_person): | ||||
|         print "PedView.rebuild" | ||||
|         # Build ancestor tree | ||||
|         lst = [None]*31 | ||||
|         self.find_tree(self.active_person,0,1,lst) | ||||
|         self.find_tree(active_person,0,1,lst) | ||||
|  | ||||
|         # Purge current table content | ||||
|         for child in table_widget.get_children(): | ||||
| @@ -389,9 +473,9 @@ class PedView(PageView.PageView): | ||||
|         person_handle = obj.get_data(_PERSON) | ||||
|         person = self.db.get_person_from_handle(person_handle) | ||||
|         if person: | ||||
|             self.edit_person(person) | ||||
|             EditPerson.EditPerson(self.dbstate, person, self.person_edited_cb) | ||||
|             return True | ||||
|         return 0 | ||||
|         return False | ||||
|  | ||||
|     def on_show_option_menu_cb(self,obj,data=None): | ||||
|         myMenu = gtk.Menu() | ||||
| @@ -402,16 +486,16 @@ class PedView(PageView.PageView): | ||||
|     def on_show_child_menu(self,obj): | ||||
|         """User clicked button to move to child of active person""" | ||||
|  | ||||
|         if self.active_person: | ||||
|         if self.dbstate.active: | ||||
|             # Build and display the menu attached to the left pointing arrow | ||||
|             # button. The menu consists of the children of the current root | ||||
|             # person of the tree. Attach a child to each menu item. | ||||
|  | ||||
|             childlist = find_children(self.db,self.active_person) | ||||
|             childlist = find_children(self.db,self.dbstate.active) | ||||
|             if len(childlist) == 1: | ||||
|                 child = self.db.get_person_from_handle(childlist[0]) | ||||
|                 if child: | ||||
|                     self.parent.change_active_person(child) | ||||
|                     self.dbstate.change_active_person(child) | ||||
|             elif len(childlist) > 1: | ||||
|                 myMenu = gtk.Menu() | ||||
|                 for child_handle in childlist: | ||||
|   | ||||
| @@ -24,6 +24,7 @@ import gtk | ||||
| import ViewManager | ||||
| import PersonView | ||||
| import PedView | ||||
| import MapView | ||||
| import ArgHandler | ||||
| import DisplayTrace | ||||
| import GrampsKeys | ||||
| @@ -190,6 +191,7 @@ class Gramps: | ||||
|         a = ViewManager.ViewManager(state) | ||||
|         a.register_view(PersonView.PersonView) | ||||
|         a.register_view(PedView.PedView) | ||||
|         a.register_view(MapView.MapView) | ||||
|         a.init_interface() | ||||
|          | ||||
|         if GrampsKeys.get_usetips(): | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								src/land_shallow_topo_2048.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/land_shallow_topo_2048.jpg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 233 KiB | 
							
								
								
									
										
											BIN
										
									
								
								src/land_shallow_topo_350.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/land_shallow_topo_350.jpg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 15 KiB | 
		Reference in New Issue
	
	Block a user