removed old FamilyLines.py, added new NotRelated.py
svn: r10087
This commit is contained in:
		| @@ -1,3 +1,10 @@ | ||||
| 2008-02-20  Stéphane Charette <stephanecharette@gmail.com> | ||||
| 	* po/POTFILES.in: added Report->View->Not Related | ||||
| 	* src/plugins/Makefile.am: added Report->View->Not Related | ||||
| 	* src/plugins/NotRelated.py: added Report->View->Not Related | ||||
| 	* src/plugins/NotRelated.glade: added Report->View->Not Related | ||||
| 	* src/plugins/FamilyLines.py: deleted (replaced by GVFamilyLines.py) | ||||
|  | ||||
| 2008-02-20  Don Allingham  <don@gramps-project.org> | ||||
| 	* src/GrampsCfg.py: refactoring | ||||
| 	* src/gen/utils/test/callback_test.py: refactoring | ||||
|   | ||||
| @@ -289,6 +289,7 @@ src/plugins/lineage.py | ||||
| src/plugins/MarkerReport.py | ||||
| src/plugins/MediaManager.py | ||||
| src/plugins/NarrativeWeb.py | ||||
| src/plubins/NotRelated.py | ||||
| src/plugins/OnThisDay.py | ||||
| src/plugins/OwnerEditor.py | ||||
| src/plugins/PatchNames.py | ||||
| @@ -667,6 +668,7 @@ src/glade/plugins.glade | ||||
| src/glade/rule.glade | ||||
| src/glade/scratchpad.glade | ||||
| src/glade/paper_settings.glade | ||||
| src/plubins/NotRelated.glade | ||||
| src/plugins/book.glade | ||||
| src/plugins/cdexport.glade | ||||
| src/plugins/changenames.glade | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -48,6 +48,7 @@ pkgdata_PYTHON = \ | ||||
| 	MarkerReport.py\ | ||||
| 	MediaManager.py\ | ||||
| 	NarrativeWeb.py\ | ||||
| 	NotRelated.py\ | ||||
| 	OnThisDay.py\ | ||||
| 	OwnerEditor.py\ | ||||
| 	PatchNames.py\ | ||||
| @@ -98,6 +99,7 @@ pkgpyexecdir = @pkgpyexecdir@/plugins | ||||
| pkgpythondir = @pkgpythondir@/plugins | ||||
|  | ||||
| GLADEFILES = \ | ||||
| 	NotRelated.glade\ | ||||
| 	changetype.glade\ | ||||
| 	csvexport.glade\ | ||||
| 	desbrowse.glade\ | ||||
|   | ||||
							
								
								
									
										225
									
								
								src/plugins/NotRelated.glade
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										225
									
								
								src/plugins/NotRelated.glade
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,225 @@ | ||||
| <?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> | ||||
| <!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> | ||||
|  | ||||
| <glade-interface> | ||||
|  | ||||
| <widget class="GtkDialog" id="top"> | ||||
|   <property name="title" translatable="yes"></property> | ||||
|   <property name="type">GTK_WINDOW_TOPLEVEL</property> | ||||
|   <property name="window_position">GTK_WIN_POS_NONE</property> | ||||
|   <property name="modal">False</property> | ||||
|   <property name="default_width">450</property> | ||||
|   <property name="default_height">400</property> | ||||
|   <property name="resizable">True</property> | ||||
|   <property name="destroy_with_parent">False</property> | ||||
|   <property name="decorated">True</property> | ||||
|   <property name="skip_taskbar_hint">False</property> | ||||
|   <property name="skip_pager_hint">False</property> | ||||
|   <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> | ||||
|   <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> | ||||
|   <property name="focus_on_map">True</property> | ||||
|   <property name="urgency_hint">False</property> | ||||
|   <property name="has_separator">False</property> | ||||
|   <signal name="delete_event" handler="on_delete_event" last_modification_time="Thu, 24 Mar 2005 18:53:09 GMT"/> | ||||
|  | ||||
|   <child internal-child="vbox"> | ||||
|     <widget class="GtkVBox" id="dialog-vbox1"> | ||||
|       <property name="visible">True</property> | ||||
|       <property name="homogeneous">False</property> | ||||
|       <property name="spacing">0</property> | ||||
|  | ||||
|       <child internal-child="action_area"> | ||||
| 	<widget class="GtkHButtonBox" id="dialog-action_area1"> | ||||
| 	  <property name="visible">True</property> | ||||
| 	  <property name="layout_style">GTK_BUTTONBOX_END</property> | ||||
|  | ||||
| 	  <child> | ||||
| 	    <widget class="GtkButton" id="close"> | ||||
| 	      <property name="visible">True</property> | ||||
| 	      <property name="can_default">True</property> | ||||
| 	      <property name="can_focus">True</property> | ||||
| 	      <property name="label">gtk-close</property> | ||||
| 	      <property name="use_stock">True</property> | ||||
| 	      <property name="relief">GTK_RELIEF_NORMAL</property> | ||||
| 	      <property name="focus_on_click">True</property> | ||||
| 	      <property name="response_id">0</property> | ||||
| 	      <signal name="clicked" handler="destroy_passed_object" object="top"/> | ||||
| 	    </widget> | ||||
| 	  </child> | ||||
| 	</widget> | ||||
| 	<packing> | ||||
| 	  <property name="padding">0</property> | ||||
| 	  <property name="expand">False</property> | ||||
| 	  <property name="fill">True</property> | ||||
| 	  <property name="pack_type">GTK_PACK_END</property> | ||||
| 	</packing> | ||||
|       </child> | ||||
|  | ||||
|       <child> | ||||
| 	<widget class="GtkVBox" id="vbox1"> | ||||
| 	  <property name="border_width">6</property> | ||||
| 	  <property name="visible">True</property> | ||||
| 	  <property name="homogeneous">False</property> | ||||
| 	  <property name="spacing">6</property> | ||||
|  | ||||
| 	  <child> | ||||
| 	    <widget class="GtkLabel" id="title"> | ||||
| 	      <property name="visible">True</property> | ||||
| 	      <property name="label" translatable="yes"></property> | ||||
| 	      <property name="use_underline">False</property> | ||||
| 	      <property name="use_markup">False</property> | ||||
| 	      <property name="justify">GTK_JUSTIFY_CENTER</property> | ||||
| 	      <property name="wrap">False</property> | ||||
| 	      <property name="selectable">False</property> | ||||
| 	      <property name="xalign">0.5</property> | ||||
| 	      <property name="yalign">0.5</property> | ||||
| 	      <property name="xpad">0</property> | ||||
| 	      <property name="ypad">0</property> | ||||
| 	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> | ||||
| 	      <property name="width_chars">-1</property> | ||||
| 	      <property name="single_line_mode">False</property> | ||||
| 	      <property name="angle">0</property> | ||||
| 	    </widget> | ||||
| 	    <packing> | ||||
| 	      <property name="padding">8</property> | ||||
| 	      <property name="expand">False</property> | ||||
| 	      <property name="fill">False</property> | ||||
| 	    </packing> | ||||
| 	  </child> | ||||
|  | ||||
| 	  <child> | ||||
| 	    <widget class="GtkScrolledWindow" id="scrolledwindow1"> | ||||
| 	      <property name="visible">True</property> | ||||
| 	      <property name="can_focus">True</property> | ||||
| 	      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> | ||||
| 	      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> | ||||
| 	      <property name="shadow_type">GTK_SHADOW_OUT</property> | ||||
| 	      <property name="window_placement">GTK_CORNER_TOP_LEFT</property> | ||||
|  | ||||
| 	      <child> | ||||
| 		<widget class="GtkTreeView" id="treeview"> | ||||
| 		  <property name="visible">True</property> | ||||
| 		  <property name="can_focus">True</property> | ||||
| 		  <property name="headers_visible">True</property> | ||||
| 		  <property name="rules_hint">False</property> | ||||
| 		  <property name="reorderable">False</property> | ||||
| 		  <property name="enable_search">True</property> | ||||
| 		  <property name="fixed_height_mode">False</property> | ||||
| 		  <property name="hover_selection">False</property> | ||||
| 		  <property name="hover_expand">False</property> | ||||
| 		</widget> | ||||
| 	      </child> | ||||
| 	    </widget> | ||||
| 	    <packing> | ||||
| 	      <property name="padding">0</property> | ||||
| 	      <property name="expand">True</property> | ||||
| 	      <property name="fill">True</property> | ||||
| 	    </packing> | ||||
| 	  </child> | ||||
| 	</widget> | ||||
| 	<packing> | ||||
| 	  <property name="padding">0</property> | ||||
| 	  <property name="expand">True</property> | ||||
| 	  <property name="fill">True</property> | ||||
| 	</packing> | ||||
|       </child> | ||||
|  | ||||
|       <child> | ||||
| 	<widget class="GtkFrame" id="frame"> | ||||
| 	  <property name="border_width">6</property> | ||||
| 	  <property name="visible">True</property> | ||||
| 	  <property name="label_xalign">0</property> | ||||
| 	  <property name="label_yalign">0.5</property> | ||||
| 	  <property name="shadow_type">GTK_SHADOW_IN</property> | ||||
|  | ||||
| 	  <child> | ||||
| 	    <widget class="GtkAlignment" id="alignment"> | ||||
| 	      <property name="border_width">6</property> | ||||
| 	      <property name="visible">True</property> | ||||
| 	      <property name="xalign">0.5</property> | ||||
| 	      <property name="yalign">0.5</property> | ||||
| 	      <property name="xscale">1</property> | ||||
| 	      <property name="yscale">1</property> | ||||
| 	      <property name="top_padding">0</property> | ||||
| 	      <property name="bottom_padding">0</property> | ||||
| 	      <property name="left_padding">12</property> | ||||
| 	      <property name="right_padding">0</property> | ||||
|  | ||||
| 	      <child> | ||||
| 		<widget class="GtkHBox" id="hbox1"> | ||||
| 		  <property name="visible">True</property> | ||||
| 		  <property name="homogeneous">False</property> | ||||
| 		  <property name="spacing">3</property> | ||||
|  | ||||
| 		  <child> | ||||
| 		    <widget class="GtkComboBoxEntry" id="markercombo"> | ||||
| 		      <property name="visible">True</property> | ||||
| 		      <property name="items" translatable="yes"> | ||||
| ToDo | ||||
| NotRelated</property> | ||||
| 		      <property name="add_tearoffs">False</property> | ||||
| 		      <property name="has_frame">True</property> | ||||
| 		      <property name="focus_on_click">True</property> | ||||
| 		      <accelerator key="M" modifiers="GDK_MOD1_MASK" signal="grab_focus"/> | ||||
| 		    </widget> | ||||
| 		    <packing> | ||||
| 		      <property name="padding">0</property> | ||||
| 		      <property name="expand">True</property> | ||||
| 		      <property name="fill">True</property> | ||||
| 		    </packing> | ||||
| 		  </child> | ||||
|  | ||||
| 		  <child> | ||||
| 		    <widget class="GtkButton" id="markerapply"> | ||||
| 		      <property name="visible">True</property> | ||||
| 		      <property name="can_focus">True</property> | ||||
| 		      <property name="label">gtk-apply</property> | ||||
| 		      <property name="use_stock">True</property> | ||||
| 		      <property name="relief">GTK_RELIEF_NORMAL</property> | ||||
| 		      <property name="focus_on_click">True</property> | ||||
| 		    </widget> | ||||
| 		    <packing> | ||||
| 		      <property name="padding">0</property> | ||||
| 		      <property name="expand">False</property> | ||||
| 		      <property name="fill">False</property> | ||||
| 		    </packing> | ||||
| 		  </child> | ||||
| 		</widget> | ||||
| 	      </child> | ||||
| 	    </widget> | ||||
| 	  </child> | ||||
|  | ||||
| 	  <child> | ||||
| 	    <widget class="GtkLabel" id="marker"> | ||||
| 	      <property name="visible">True</property> | ||||
| 	      <property name="label" translatable="yes">_Marker</property> | ||||
| 	      <property name="use_underline">True</property> | ||||
| 	      <property name="use_markup">True</property> | ||||
| 	      <property name="justify">GTK_JUSTIFY_LEFT</property> | ||||
| 	      <property name="wrap">False</property> | ||||
| 	      <property name="selectable">False</property> | ||||
| 	      <property name="xalign">0.5</property> | ||||
| 	      <property name="yalign">0.5</property> | ||||
| 	      <property name="xpad">0</property> | ||||
| 	      <property name="ypad">0</property> | ||||
| 	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> | ||||
| 	      <property name="width_chars">-1</property> | ||||
| 	      <property name="single_line_mode">False</property> | ||||
| 	      <property name="angle">0</property> | ||||
| 	    </widget> | ||||
| 	    <packing> | ||||
| 	      <property name="type">label_item</property> | ||||
| 	    </packing> | ||||
| 	  </child> | ||||
| 	</widget> | ||||
| 	<packing> | ||||
| 	  <property name="padding">0</property> | ||||
| 	  <property name="expand">False</property> | ||||
| 	  <property name="fill">True</property> | ||||
| 	</packing> | ||||
|       </child> | ||||
|     </widget> | ||||
|   </child> | ||||
| </widget> | ||||
|  | ||||
| </glade-interface> | ||||
							
								
								
									
										408
									
								
								src/plugins/NotRelated.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										408
									
								
								src/plugins/NotRelated.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,408 @@ | ||||
| # | ||||
| # NotRelated.py - Plugin for Gramps | ||||
| # | ||||
| # Copyright (C) 2007 Stephane Charette | ||||
| # | ||||
| # 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$ | ||||
|  | ||||
| "Find people who are not related to the selected person" | ||||
|  | ||||
| #------------------------------------------------------------------------ | ||||
| # | ||||
| # standard python modules | ||||
| # | ||||
| #------------------------------------------------------------------------ | ||||
| import os | ||||
| from gettext import gettext as _ | ||||
|  | ||||
| #------------------------------------------------------------------------ | ||||
| # | ||||
| # GNOME/GTK modules | ||||
| # | ||||
| #------------------------------------------------------------------------ | ||||
| import gtk | ||||
| import gobject | ||||
|  | ||||
| #------------------------------------------------------------------------ | ||||
| # | ||||
| # GRAMPS modules | ||||
| # | ||||
| #------------------------------------------------------------------------ | ||||
| from PluginUtils import register_report | ||||
| from ReportBase import ReportUtils, CATEGORY_VIEW, MODE_GUI | ||||
| from Editors import EditPerson, EditFamily | ||||
| from QuestionDialog import WarningDialog | ||||
| import ManagedWindow | ||||
| import Utils | ||||
|  | ||||
| #------------------------------------------------------------------------ | ||||
| # | ||||
| #  | ||||
| # | ||||
| #------------------------------------------------------------------------ | ||||
| class NotRelated(ManagedWindow.ManagedWindow) : | ||||
|  | ||||
|     def __init__(self, dbstate, uistate) : | ||||
|         person = dbstate.get_active_person() | ||||
|         self.name = person.get_primary_name().get_regular_name() | ||||
|         self.title = _('Not related to "%s"') % self.name | ||||
|         ManagedWindow.ManagedWindow.__init__(self, uistate, [], self.__class__) | ||||
|         self.dbstate = dbstate | ||||
|         self.uistate = uistate | ||||
|         self.db = dbstate.db | ||||
|         glade_file = "%s/NotRelated.glade" % os.path.dirname(__file__) | ||||
|         topDialog = gtk.glade.XML(glade_file, "top", "gramps") | ||||
|         topDialog.signal_autoconnect({"destroy_passed_object" : self.close}) | ||||
|  | ||||
|         window = topDialog.get_widget("top") | ||||
|         title = topDialog.get_widget("title") | ||||
|         self.set_window(window, title, self.title) | ||||
|  | ||||
|         self.markercombo = topDialog.get_widget("markercombo") | ||||
|         self.markerapply = topDialog.get_widget("markerapply") | ||||
|         self.markercombo.set_sensitive(False) | ||||
|         self.markerapply.set_sensitive(False) | ||||
|         self.markerapply.connect('clicked', self.applyMarkerClicked) | ||||
|  | ||||
|         # start the progress indicator | ||||
|         self.progress = Utils.ProgressMeter(self.title,_('Starting')) | ||||
|  | ||||
|         # setup the columns | ||||
|         self.model = gtk.TreeStore( | ||||
|             gobject.TYPE_STRING,    # 0==name | ||||
|             gobject.TYPE_STRING,    # 1==person gid | ||||
|             gobject.TYPE_STRING,    # 2==parents | ||||
|             gobject.TYPE_STRING,    # 3==marker | ||||
|             gobject.TYPE_STRING)    # 4==family gid (not shown to user) | ||||
|  | ||||
|         # note -- don't assign the model to the tree until it has been populated, | ||||
|         # otherwise the screen updates are terribly slow while names are appended | ||||
|         self.treeView = topDialog.get_widget("treeview") | ||||
|         col1 = gtk.TreeViewColumn(_('Name'),    gtk.CellRendererText(), text=0) | ||||
|         col2 = gtk.TreeViewColumn(_('ID'),      gtk.CellRendererText(), text=1) | ||||
|         col3 = gtk.TreeViewColumn(_('Parents'), gtk.CellRendererText(), text=2) | ||||
|         col4 = gtk.TreeViewColumn(_('Marker'),  gtk.CellRendererText(), text=3) | ||||
|         col1.set_resizable(True) | ||||
|         col2.set_resizable(True) | ||||
|         col3.set_resizable(True) | ||||
|         col4.set_resizable(True) | ||||
|         col1.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE) | ||||
|         col2.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE) | ||||
|         col3.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE) | ||||
|         col4.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE) | ||||
|         col1.set_sort_column_id(0) | ||||
| #        col2.set_sort_column_id(1) | ||||
| #        col3.set_sort_column_id(2) | ||||
|         col4.set_sort_column_id(3) | ||||
|         self.treeView.append_column(col1) | ||||
|         self.treeView.append_column(col2) | ||||
|         self.treeView.append_column(col3) | ||||
|         self.treeView.append_column(col4) | ||||
|         self.treeSelection = self.treeView.get_selection() | ||||
|         self.treeSelection.set_mode(gtk.SELECTION_MULTIPLE) | ||||
|         self.treeSelection.set_select_function(self.selectIsAllowed, full=True) | ||||
|         self.treeSelection.connect('changed', self.rowSelectionChanged) | ||||
|         self.treeView.connect('row-activated', self.rowActivated) | ||||
|  | ||||
|         # initialize a few variables we're going to need | ||||
|         self.numberOfPeopleInDatabase    = self.db.get_number_of_people() | ||||
|         self.numberOfRelatedPeople       = 0 | ||||
|         self.numberOfUnrelatedPeople     = 0 | ||||
|  | ||||
|         # create the sets used to track related and unrelated people | ||||
|         self.handlesOfPeopleToBeProcessed       = set() | ||||
|         self.handlesOfPeopleAlreadyProcessed    = set() | ||||
|         self.handlesOfPeopleNotRelated          = set() | ||||
|  | ||||
|         # build a set of all people related to the selected person | ||||
|         self.handlesOfPeopleToBeProcessed.add(person.get_handle()) | ||||
|         self.findRelatedPeople() | ||||
|  | ||||
|         # now that we have our list of related people, find everyone | ||||
|         # in the database who isn't on our list | ||||
|         self.findUnrelatedPeople() | ||||
|  | ||||
|         # populate the treeview model with the names of unrelated people | ||||
|         if self.numberOfUnrelatedPeople == 0: | ||||
|             title.set_text('Everyone in the database is related to %s' % self.name) | ||||
|         else: | ||||
|             self.populateModel() | ||||
|             self.model.set_sort_column_id(0, gtk.SORT_ASCENDING) | ||||
|             self.treeView.set_model(self.model) | ||||
| #            self.treeView.set_row_separator_func(self.iterIsSeparator) | ||||
|             self.treeView.expand_all() | ||||
|  | ||||
|         # done searching through the database, so close the progress bar | ||||
|         self.progress.close() | ||||
|  | ||||
|         self.show() | ||||
|  | ||||
|  | ||||
|     def iterIsSeparator(self, model, iter) : | ||||
|         # return True only if the row is to be treated as a separator | ||||
|         if self.model.get_value(iter, 1) == '':  # does the row have a GID? | ||||
|             return True | ||||
|         return False | ||||
|  | ||||
|  | ||||
|     def selectIsAllowed(self, selection, model, path, isSelected) : | ||||
|         # return True/False depending on if the row being selected is a leaf node | ||||
|         iter = self.model.get_iter(path) | ||||
|         if self.model.get_value(iter, 1) == '': # does the row have a GID? | ||||
|             return False | ||||
|         return True | ||||
|  | ||||
|  | ||||
|     def rowSelectionChanged(self, selection) : | ||||
|         state = selection.count_selected_rows() > 0 | ||||
|         self.markercombo.set_sensitive(state) | ||||
|         self.markerapply.set_sensitive(state) | ||||
|  | ||||
|  | ||||
|     def rowActivated(self, treeView, path, column) : | ||||
|         # first we need to check that the row corresponds to a person | ||||
|         iter = self.model.get_iter(path) | ||||
|         personGid = self.model.get_value(iter, 1) | ||||
|         familyGid = self.model.get_value(iter, 4) | ||||
|  | ||||
|         if familyGid != '': # do we have a family? | ||||
|             # get the parent family for this person | ||||
|             family = self.db.get_family_from_gramps_id(familyGid) | ||||
|             if family: | ||||
|                 try: | ||||
|                     EditFamily(self.dbstate, self.uistate, [], family) | ||||
|                 except Errors.WindowActiveError: | ||||
|                     pass | ||||
|  | ||||
|         elif personGid != '': # do we have a person? | ||||
|             # get the person that corresponds to this GID | ||||
|             person = self.db.get_person_from_gramps_id(personGid) | ||||
|             if person: | ||||
|                 try: | ||||
|                     EditPerson(self.dbstate, self.uistate, [], person) | ||||
|                 except Errors.WindowActiveError: | ||||
|                     pass | ||||
|  | ||||
|  | ||||
|     def applyMarkerClicked(self, button) : | ||||
|         progress    = None | ||||
|         rows        = self.treeSelection.count_selected_rows() | ||||
|         marker      = self.markercombo.get_active_text() | ||||
|  | ||||
|         # if more than 1 person is selected, use a progress indicator | ||||
|         if rows > 1: | ||||
|             progress = Utils.ProgressMeter(self.title,_('Starting')) | ||||
|             progress.set_pass(_('Setting marker for %d people') % rows, rows) | ||||
|  | ||||
|         # start the db transaction | ||||
|         transaction = self.db.transaction_begin() | ||||
|  | ||||
|         # iterate through all of the selected rows | ||||
|         (model, paths) = self.treeSelection.get_selected_rows() | ||||
|         for path in paths: | ||||
|             if progress: | ||||
|                 progress.step() | ||||
|  | ||||
|             # for the current row, get the GID and the person from the database | ||||
|             iter        = self.model.get_iter(path) | ||||
|             personGid   = self.model.get_value(iter, 1) | ||||
|             person      = self.db.get_person_from_gramps_id(personGid) | ||||
|  | ||||
|             # change the marker | ||||
|             person.set_marker(marker) | ||||
|             self.model.set_value(iter, 3, marker) | ||||
|  | ||||
|             # save this change | ||||
|             self.db.commit_person(person, transaction) | ||||
|  | ||||
|         # commit the entire transaction | ||||
|         self.db.transaction_commit(transaction, "mark not related") | ||||
|  | ||||
|         if progress: | ||||
|             progress.close() | ||||
|  | ||||
|  | ||||
|     def findRelatedPeople(self) : | ||||
|  | ||||
|         self.progress.set_pass(_('Finding relationships between %d people') % self.numberOfPeopleInDatabase, self.numberOfPeopleInDatabase) | ||||
|  | ||||
|         # as long as we have people we haven't processed yet, keep looping | ||||
|         while len(self.handlesOfPeopleToBeProcessed) > 0: | ||||
|             handle = self.handlesOfPeopleToBeProcessed.pop() | ||||
|  | ||||
| ### DEBUG DEBUG DEBUG | ||||
| #            if len(self.handlesOfPeopleAlreadyProcessed) > 50: | ||||
| #                break | ||||
| ### | ||||
|  | ||||
|             # see if we've already processed this person | ||||
|             if handle in self.handlesOfPeopleAlreadyProcessed: | ||||
|                 continue | ||||
|  | ||||
|             person = self.db.get_person_from_handle(handle) | ||||
|  | ||||
|             # if we get here, then we're dealing with someone new | ||||
|             self.progress.step() | ||||
|  | ||||
|             # remember that we've now seen this person | ||||
|             self.handlesOfPeopleAlreadyProcessed.add(handle) | ||||
|  | ||||
|             # we have 3 things to do:  find (1) spouses, (2) parents, and (3) children | ||||
|  | ||||
|             # step 1 -- spouses | ||||
|             for familyHandle in person.get_family_handle_list(): | ||||
|                 family = self.db.get_family_from_handle(familyHandle) | ||||
|                 spouseHandle = ReportUtils.find_spouse(person, family) | ||||
|                 if spouseHandle: | ||||
|                     if spouseHandle not in self.handlesOfPeopleAlreadyProcessed or spouseHandle not in self.handlesOfPeopleToBeProcessed: | ||||
|                         self.handlesOfPeopleToBeProcessed.add(spouseHandle) | ||||
|  | ||||
|             # step 2 -- parents | ||||
|             for familyHandle in person.get_parent_family_handle_list(): | ||||
|                 family = self.db.get_family_from_handle(familyHandle) | ||||
|                 fatherHandle = family.get_father_handle() | ||||
|                 motherHandle = family.get_mother_handle() | ||||
|                 if fatherHandle: | ||||
|                     if fatherHandle not in self.handlesOfPeopleAlreadyProcessed or fatherHandle not in self.handlesOfPeopleToBeProcessed: | ||||
|                         self.handlesOfPeopleToBeProcessed.add(fatherHandle) | ||||
|                 if motherHandle: | ||||
|                     if motherHandle not in self.handlesOfPeopleAlreadyProcessed or motherHandle not in self.handlesOfPeopleToBeProcessed: | ||||
|                         self.handlesOfPeopleToBeProcessed.add(motherHandle) | ||||
|  | ||||
|             # step 3 -- children | ||||
|             for familyHandle in person.get_family_handle_list(): | ||||
|                 family = self.db.get_family_from_handle(familyHandle) | ||||
|                 for childRef in family.get_child_ref_list(): | ||||
|                     childHandle = childRef.ref | ||||
|                     if childHandle: | ||||
|                         if childHandle not in self.handlesOfPeopleAlreadyProcessed or childHandle not in self.handlesOfPeopleToBeProcessed: | ||||
|                             self.handlesOfPeopleToBeProcessed.add(childHandle) | ||||
|  | ||||
|  | ||||
|     def findUnrelatedPeople(self) : | ||||
|  | ||||
|         # update our numbers | ||||
|         self.numberOfRelatedPeople   = len(self.handlesOfPeopleAlreadyProcessed) | ||||
|         self.numberOfUnrelatedPeople = self.numberOfPeopleInDatabase - self.numberOfRelatedPeople | ||||
|  | ||||
|         if self.numberOfUnrelatedPeople > 0: | ||||
|             # we have at least 1 "unrelated" person to find | ||||
|  | ||||
|             if self.numberOfUnrelatedPeople == 1: | ||||
|                 self.progress.set_pass(_('Looking for 1 person'), self.numberOfPeopleInDatabase) | ||||
|             else: | ||||
|                 self.progress.set_pass(_('Looking for %d people') % self.numberOfUnrelatedPeople, self.numberOfPeopleInDatabase) | ||||
|  | ||||
|             # loop through everyone in the database | ||||
|             for handle in self.db.get_person_handles(False): | ||||
|  | ||||
|                 self.progress.step() | ||||
|  | ||||
|                 # if this person is related, then skip to the next one | ||||
|                 if handle in self.handlesOfPeopleAlreadyProcessed: | ||||
|                     continue | ||||
|  | ||||
| ### DEBUG DEBUG DEBUG | ||||
| #                if len(self.handlesOfPeopleNotRelated) > 10: | ||||
| #                    break | ||||
| ### | ||||
|  | ||||
|                 # if we get here, we have someone who is "not related" | ||||
|                 self.handlesOfPeopleNotRelated.add(handle) | ||||
|  | ||||
|  | ||||
|     def populateModel(self) : | ||||
|  | ||||
|         if self.numberOfUnrelatedPeople == 1: | ||||
|             self.progress.set_pass(_('Looking up the name for 1 person'), 1) | ||||
|         else: | ||||
|             self.progress.set_pass(_('Looking up the names for %d people') % self.numberOfUnrelatedPeople, self.numberOfUnrelatedPeople) | ||||
|  | ||||
|         # loop through the entire list of unrelated people | ||||
|         for handle in self.handlesOfPeopleNotRelated: | ||||
|             self.progress.step() | ||||
|             person      = self.db.get_person_from_handle(handle) | ||||
|             primaryname = person.get_primary_name() | ||||
|             surname     = primaryname.get_surname() | ||||
|             name        = primaryname.get_name() | ||||
|             gid         = person.get_gramps_id() | ||||
|             marker      = person.get_marker() | ||||
|  | ||||
|             # find the names of the parents | ||||
|             familygid   = '' | ||||
|             parentNames = '' | ||||
|             parentFamilyHandle = person.get_main_parents_family_handle() | ||||
|             if parentFamilyHandle: | ||||
|                 parentFamily = self.db.get_family_from_handle(parentFamilyHandle) | ||||
|                 familygid    = parentFamily.get_gramps_id() | ||||
|                 fatherName   = None | ||||
|                 motherName   = None | ||||
|                 fatherHandle = parentFamily.get_father_handle() | ||||
|                 if fatherHandle: | ||||
|                     father      = self.db.get_person_from_handle(fatherHandle) | ||||
|                     fatherName  = father.get_primary_name().get_first_name() | ||||
|                 motherHandle = parentFamily.get_mother_handle() | ||||
|                 if motherHandle: | ||||
|                     mother      = self.db.get_person_from_handle(motherHandle) | ||||
|                     motherName  = mother.get_primary_name().get_first_name() | ||||
|  | ||||
|                 # now that we have the names, come up with a label we can use | ||||
|                 if fatherName: | ||||
|                     parentNames += fatherName | ||||
|                 if fatherName and motherName: | ||||
|                     parentNames += ' & ' | ||||
|                 if motherName: | ||||
|                     parentNames += motherName | ||||
|  | ||||
|             # get the surname node (or create it if it doesn't exist) | ||||
|  | ||||
|             # start with the root | ||||
|             iter = self.model.get_iter_root() | ||||
|             # look for a node with a matching surname | ||||
|             while iter: | ||||
|                 if self.model.get_value(iter, 0) == surname: | ||||
|                     break; | ||||
|                 iter = self.model.iter_next(iter) | ||||
|  | ||||
|             # if we don't have a valid iter, then create a new top-level node | ||||
|             if not iter: | ||||
|                 iter = self.model.append(None, [surname, '', '', '', '']) | ||||
|  | ||||
|             # finally, we now get to add this person to the model | ||||
|             self.model.append(iter, [name, gid, parentNames, marker, familygid]) | ||||
|  | ||||
|  | ||||
|     def build_menu_names(self,obj): | ||||
|         return (self.title, None) | ||||
|  | ||||
| #------------------------------------------------------------------------- | ||||
| # | ||||
| # | ||||
| # | ||||
| #------------------------------------------------------------------------- | ||||
| register_report( | ||||
|     name = 'not_related', | ||||
|     category = CATEGORY_VIEW, | ||||
|     report_class = NotRelated, | ||||
|     options_class = None, | ||||
|     modes = MODE_GUI, | ||||
|     translated_name = _("Not Related"), | ||||
|     status = _("Stable"), | ||||
|     description= _("Find people who are not in any way related to the selected person") | ||||
|     ) | ||||
|  | ||||
		Reference in New Issue
	
	Block a user