9534: Exclude places outside valid date ranges
This commit is contained in:
		| @@ -35,6 +35,7 @@ from gramps.gui.editors import EditPlace | |||||||
| from gramps.gen.errors import WindowActiveError | from gramps.gen.errors import WindowActiveError | ||||||
| from gramps.gui.listmodel import ListModel, NOSORT | from gramps.gui.listmodel import ListModel, NOSORT | ||||||
| from gramps.gen.datehandler import get_date | from gramps.gen.datehandler import get_date | ||||||
|  | from gramps.gen.lib import Date | ||||||
| from gramps.gen.const import GRAMPS_LOCALE as glocale | from gramps.gen.const import GRAMPS_LOCALE as glocale | ||||||
| _ = glocale.translation.gettext | _ = glocale.translation.gettext | ||||||
|  |  | ||||||
| @@ -113,19 +114,19 @@ class Locations(Gramplet, DbGUIElement): | |||||||
|         if active_handle: |         if active_handle: | ||||||
|             active = self.dbstate.db.get_place_from_handle(active_handle) |             active = self.dbstate.db.get_place_from_handle(active_handle) | ||||||
|             if active: |             if active: | ||||||
|                 self.display_place(active, None, [active_handle]) |                 self.display_place(active, None, [active_handle], DateRange()) | ||||||
|             else: |             else: | ||||||
|                 self.set_has_data(False) |                 self.set_has_data(False) | ||||||
|         else: |         else: | ||||||
|             self.set_has_data(False) |             self.set_has_data(False) | ||||||
|  |  | ||||||
|     def display_place(self, place, node, visited): |     def display_place(self, place, node, visited, drange): | ||||||
|         """ |         """ | ||||||
|         Display the location hierarchy for the active place. |         Display the location hierarchy for the active place. | ||||||
|         """ |         """ | ||||||
|         pass |         pass | ||||||
|  |  | ||||||
|     def add_place(self, placeref, place, node, visited): |     def add_place(self, placeref, place, node, visited, drange): | ||||||
|         """ |         """ | ||||||
|         Add a place to the model. |         Add a place to the model. | ||||||
|         """ |         """ | ||||||
| @@ -134,6 +135,9 @@ class Locations(Gramplet, DbGUIElement): | |||||||
|         place_name = place.get_name().get_value() |         place_name = place.get_name().get_value() | ||||||
|         place_type = str(place.get_type()) |         place_type = str(place.get_type()) | ||||||
|  |  | ||||||
|  |         if drange.overlap: | ||||||
|  |             place_date += ' *' | ||||||
|  |  | ||||||
|         new_node = self.model.add([place.handle, |         new_node = self.model.add([place.handle, | ||||||
|                                    place_name, |                                    place_name, | ||||||
|                                    place_type, |                                    place_type, | ||||||
| @@ -141,7 +145,7 @@ class Locations(Gramplet, DbGUIElement): | |||||||
|                                    place_sort], |                                    place_sort], | ||||||
|                                   node=node) |                                   node=node) | ||||||
|  |  | ||||||
|         self.display_place(place, new_node, visited + [place.handle]) |         self.display_place(place, new_node, visited + [place.handle], drange) | ||||||
|  |  | ||||||
|     def edit_place(self, treeview): |     def edit_place(self, treeview): | ||||||
|         """ |         """ | ||||||
| @@ -163,7 +167,7 @@ class Locations(Gramplet, DbGUIElement): | |||||||
| #------------------------------------------------------------------------- | #------------------------------------------------------------------------- | ||||||
| class EnclosedBy(Locations): | class EnclosedBy(Locations): | ||||||
|  |  | ||||||
|     def display_place(self, place, node, visited): |     def display_place(self, place, node, visited, drange): | ||||||
|         """ |         """ | ||||||
|         Display the location hierarchy for the active place. |         Display the location hierarchy for the active place. | ||||||
|         """ |         """ | ||||||
| @@ -172,8 +176,12 @@ class EnclosedBy(Locations): | |||||||
|             if placeref.ref in visited: |             if placeref.ref in visited: | ||||||
|                 continue |                 continue | ||||||
|  |  | ||||||
|  |             dr2 = drange.intersect(placeref.date) | ||||||
|  |             if dr2.is_empty(): | ||||||
|  |                 continue | ||||||
|  |  | ||||||
|             parent_place = self.dbstate.db.get_place_from_handle(placeref.ref) |             parent_place = self.dbstate.db.get_place_from_handle(placeref.ref) | ||||||
|             self.add_place(placeref, parent_place, node, visited) |             self.add_place(placeref, parent_place, node, visited, dr2) | ||||||
|  |  | ||||||
|         self.set_has_data(self.model.count > 0) |         self.set_has_data(self.model.count > 0) | ||||||
|         self.model.tree.expand_all() |         self.model.tree.expand_all() | ||||||
| @@ -195,7 +203,7 @@ class EnclosedBy(Locations): | |||||||
| #------------------------------------------------------------------------- | #------------------------------------------------------------------------- | ||||||
| class Encloses(Locations): | class Encloses(Locations): | ||||||
|  |  | ||||||
|     def display_place(self, place, node, visited): |     def display_place(self, place, node, visited, drange): | ||||||
|         """ |         """ | ||||||
|         Display the location hierarchy for the active place. |         Display the location hierarchy for the active place. | ||||||
|         """ |         """ | ||||||
| @@ -209,7 +217,12 @@ class Encloses(Locations): | |||||||
|             placeref = None |             placeref = None | ||||||
|             for placeref in child_place.get_placeref_list(): |             for placeref in child_place.get_placeref_list(): | ||||||
|                 if placeref.ref == place.handle: |                 if placeref.ref == place.handle: | ||||||
|                     self.add_place(placeref, child_place, node, visited) |  | ||||||
|  |                     dr2 = drange.intersect(placeref.date) | ||||||
|  |                     if dr2.is_empty(): | ||||||
|  |                         continue | ||||||
|  |  | ||||||
|  |                     self.add_place(placeref, child_place, node, visited, dr2) | ||||||
|  |  | ||||||
|         self.set_has_data(self.model.count > 0) |         self.set_has_data(self.model.count > 0) | ||||||
|         self.model.tree.expand_all() |         self.model.tree.expand_all() | ||||||
| @@ -224,3 +237,71 @@ class Encloses(Locations): | |||||||
|                 place.handle, include_classes=['Place']): |                 place.handle, include_classes=['Place']): | ||||||
|             return True |             return True | ||||||
|         return False |         return False | ||||||
|  |  | ||||||
|  | #------------------------------------------------------------------------- | ||||||
|  | # | ||||||
|  | # DateRange class | ||||||
|  | # | ||||||
|  | #------------------------------------------------------------------------- | ||||||
|  | class DateRange: | ||||||
|  |     """ | ||||||
|  |     A class that represents a date range. | ||||||
|  |     """ | ||||||
|  |     def __init__(self, source=None): | ||||||
|  |         self.start = None | ||||||
|  |         self.stop = None | ||||||
|  |         self.overlap = False | ||||||
|  |         if source: | ||||||
|  |             self.start = source.start | ||||||
|  |             self.stop = source.stop | ||||||
|  |             self.overlap = source.overlap | ||||||
|  |  | ||||||
|  |     def intersect(self, date): | ||||||
|  |         """ | ||||||
|  |         Return the intersection of the date range with a given Date object. | ||||||
|  |         """ | ||||||
|  |         result = DateRange(self) | ||||||
|  |         start, stop = self.__get_sortvals(date) | ||||||
|  |         if start is not None: | ||||||
|  |             if self.start is None or start > self.start: | ||||||
|  |                 result.start = start | ||||||
|  |         if stop is not None: | ||||||
|  |             if self.stop is None or stop < self.stop: | ||||||
|  |                 result.stop = stop | ||||||
|  |  | ||||||
|  |         result.overlap = False | ||||||
|  |         if result.start is not None: | ||||||
|  |             if start is None or start < result.start: | ||||||
|  |                 result.overlap = True | ||||||
|  |         if result.stop is not None: | ||||||
|  |             if stop is None or stop > result.stop: | ||||||
|  |                 result.overlap = True | ||||||
|  |  | ||||||
|  |         return result | ||||||
|  |  | ||||||
|  |     def is_empty(self): | ||||||
|  |         """ | ||||||
|  |         Return True if there are no dates in the range. | ||||||
|  |         """ | ||||||
|  |         if self.start is None or self.stop is None: | ||||||
|  |             return False | ||||||
|  |         return True if self.start > self.stop else False | ||||||
|  |  | ||||||
|  |     def __get_sortvals(self, date): | ||||||
|  |         """ | ||||||
|  |         Get the sort values representing the start and end of a Date object. | ||||||
|  |         """ | ||||||
|  |         start = None | ||||||
|  |         stop = None | ||||||
|  |         if date.modifier == Date.MOD_NONE: | ||||||
|  |             start = date.sortval | ||||||
|  |             stop = date.sortval | ||||||
|  |         elif date.modifier == Date.MOD_AFTER: | ||||||
|  |             start = date.sortval | ||||||
|  |         elif date.modifier == Date.MOD_BEFORE: | ||||||
|  |             stop = date.sortval | ||||||
|  |         elif date.is_compound(): | ||||||
|  |             date1, date2 = date.get_start_stop_range() | ||||||
|  |             start = Date(*date1).sortval | ||||||
|  |             stop = Date(*date2).sortval | ||||||
|  |         return (start, stop) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user