def reload_tiles(self): """ We need to reload all visible tiles for the current map """ map_idx = config.get("geography.map_service") map_name = constants.TILES_PATH[map_idx] map_path = os.path.join(config.get('geography.path'), map_name) # get the top left corner and bottom right corner bbox = self.osm.get_bbox() pt1 = bbox[0] pt2 = bbox[1] self.zoom = config.get("geography.zoom") tile_size = float(256) # get the file extension depending on the map provider img_format = self.osm.source_get_image_format(map_idx) # calculate the number of images to download in rows and columns pt1_x = floor(lon2pixel(self.zoom, pt1.rlon, tile_size) / tile_size) pt1_y = floor(lat2pixel(self.zoom, pt1.rlat, tile_size) / tile_size) pt2_x = floor(lon2pixel(self.zoom, pt2.rlon, tile_size) / tile_size) pt2_y = floor(lat2pixel(self.zoom, pt2.rlat, tile_size) / tile_size) for ptx_i in range(pt1_x, pt2_x): for pty_j in range(pt1_y, pt2_y): tile_path = "%s%c%d%c%d%c%d.%s" % (map_path, os.sep, self.zoom, os.sep, ptx_i, os.sep, pty_j, img_format) _LOG.debug("file removed : %s", tile_path) try: os.unlink(tile_path) except: # The tile doesn't exist because it is in the load queue. # That occurs when zooming. pass self.osm.download_maps(pt1, pt2, self.zoom, self.zoom)
def __init__(self, argparser): from gramps.gen.dbstate import DbState from guiQML.viewmanager import ViewManager from gramps.cli.arghandler import ArgHandler from PySide import QtGui self.app = QtGui.QApplication(sys.argv) dbstate = DbState() self.vm = ViewManager(dbstate) #act based on the given arguments ah = ArgHandler(dbstate, argparser, self.vm, self.argerrorfunc, gui=True) ah.handle_args_gui() if ah.open or ah.imp_db_path: # if we opened or imported something, only show the interface self.vm.post_init_interface() elif config.get('paths.recent-file') and config.get('behavior.autoload'): # if we need to autoload last seen file, do so filename = config.get('paths.recent-file') if os.path.isdir(filename) and \ os.path.isfile(os.path.join(filename, "name.txt")) and \ ah.check_db(filename): self.vm.open_activate(filename) self.vm.post_init_interface() else: self.vm.post_init_interface() else: # open without fam tree loaded self.vm.post_init_interface() #start the QT loop self.app.exec_()
def _display_welcome_message(): """ Display a welcome message to the user. """ if not config.get('behavior.betawarn'): from .dialog import WarningDialog WarningDialog( _('Danger: This is unstable code!'), _("This Gramps ('master') is a development release. " "This version is not meant for normal usage. Use " "at your own risk.\n" "\n" "This version may:\n" "1) Work differently than you expect.\n" "2) Fail to run at all.\n" "3) Crash often.\n" "4) Corrupt your data.\n" "5) Save data in a format that is incompatible with the " "official release.\n" "\n" "%(bold_start)sBACKUP%(bold_end)s " "your existing databases before opening " "them with this version, and make sure to export your " "data to XML every now and then.") % { 'bold_start' : '<b>', 'bold_end' : '</b>' } ) config.set('behavior.autoload', False) config.set('behavior.betawarn', True) config.set('behavior.betawarn', config.get('behavior.betawarn'))
def __init__(self, argparser): from gramps.gen.dbstate import DbState from . import viewmanager from .viewmanager import ViewManager from gramps.cli.arghandler import ArgHandler from .tipofday import TipOfDay from .dialog import WarningDialog import gettext _display_welcome_message() # Append image directory to the theme search path theme = Gtk.IconTheme.get_default() theme.append_search_path(IMAGE_DIR) if lin() and glocale.lang != 'C' and not gettext.find(GTK_GETTEXT_DOMAIN): LOG.warn("GTK translations missing, GUI will be broken, especially for RTL languages!") # Note: the warning dialog below will likely have wrong stock icons! # Translators: the current language will be the one you translate into. WarningDialog( _("Gramps detected an incomplete GTK installation"), _("GTK translations for the current language (%(language)s) " "are missing.\n%(bold_start)sGramps%(bold_end)s will " "proceed nevertheless.\nThe GUI will likely be broken " "as a result, especially for RTL languages!\n\n" "See the Gramps README documentation for installation " "prerequisites,\ntypically located in " "/usr/share/doc/gramps.\n") % { 'language' : glocale.lang , 'bold_start' : '<b>' , 'bold_end' : '</b>' } ) dbstate = DbState() self.vm = ViewManager(dbstate, config.get("interface.view-categories")) self.vm.init_interface() #act based on the given arguments ah = ArgHandler(dbstate, argparser, self.vm, self.argerrorfunc, gui=True) ah.handle_args_gui() if ah.open or ah.imp_db_path: # if we opened or imported something, only show the interface self.vm.post_init_interface(show_manager=False) elif config.get('paths.recent-file') and config.get('behavior.autoload'): # if we need to autoload last seen file, do so filename = config.get('paths.recent-file') if os.path.isdir(filename) and \ os.path.isfile(os.path.join(filename, "name.txt")) and \ ah.check_db(filename): self.vm.post_init_interface(show_manager=False) self.vm.open_activate(filename) else: self.vm.post_init_interface() else: # open without fam tree loaded self.vm.post_init_interface() if config.get('behavior.use-tips'): TipOfDay(self.vm.uistate)
def change_new_map(self, name, map_source): """ Change the current map with a new provider This map is not supported by osm-gps-map name : the name of the provider map_source : the url to search for tiles """ try: self.osm.layer_remove_all() self.osm.image_remove_all() self.vbox.remove(self.osm) self.osm.destroy() except: pass tiles_path = os.path.join(config.get('geography.path'), name) if not os.path.isdir(tiles_path): try: os.makedirs(tiles_path, 0o755) # create dir like mkdir -p except: ErrorDialog(_("Can't create " "tiles cache directory for '%s'.") % constants.MAP_TITLE[self.current_map], parent=self.uistate.window) http_proxy = get_env_var('http_proxy') if 0: self.osm = DummyMapNoGpsPoint() else: if http_proxy: self.osm = osmgpsmap.Map(tile_cache=tiles_path, proxy_uri=http_proxy, repo_uri=map_source) else: self.osm = osmgpsmap.Map(tile_cache=tiles_path, repo_uri=map_source) self.osm.props.tile_cache = osmgpsmap.MAP_CACHE_AUTO current_map = osmgpsmap.MapOsd(show_dpad=False, show_zoom=True) self.end_selection = None self.osm.layer_add(current_map) self.osm.layer_add(DummyLayer()) self.selection_layer = self.add_selection_layer() self.kml_layer = self.add_kml_layer() self.lifeway_layer = self.add_lifeway_layer() self.marker_layer = self.add_marker_layer() self.date_layer = self.add_date_layer() self.message_layer = self.add_message_layer() self.cross_map = osmgpsmap.MapOsd(show_crosshair=False) self.set_crosshair(config.get("geography.show_cross")) self.osm.set_center_and_zoom(config.get("geography.center-lat"), config.get("geography.center-lon"), config.get("geography.zoom")) self.osm.connect('button_release_event', self.map_clicked) self.osm.connect('button_press_event', self.map_clicked) self.osm.connect("motion-notify-event", self.motion_event) self.osm.connect('changed', self.zoom_changed) self.update_shortcuts(True) self.osm.show() self.vbox.pack_start(self.osm, True, True, 0) self.goto_handle(handle=None)
def _initialize(self, directory, username, password): config_file = os.path.join(directory, 'settings.ini') config_mgr = ConfigManager(config_file) config_mgr.register('database.dbname', '') config_mgr.register('database.host', '') config_mgr.register('database.port', '') if not os.path.exists(config_file): name_file = os.path.join(directory, 'name.txt') with open(name_file, 'r', encoding='utf8') as file: dbname = file.readline().strip() config_mgr.set('database.dbname', dbname) config_mgr.set('database.host', config.get('database.host')) config_mgr.set('database.port', config.get('database.port')) config_mgr.save() config_mgr.load() dbkwargs = {} for key in config_mgr.get_section_settings('database'): value = config_mgr.get('database.' + key) if value: dbkwargs[key] = value if username: dbkwargs['user'] = username if password: dbkwargs['password'] = password try: self.dbapi = Connection(**dbkwargs) except psycopg2.OperationalError as msg: raise DbConnectionError(str(msg), config_file)
def __init__(self, dbstate, uistate, track, mediaobj, callback=None): """ Create and displays the dialog box db - the database in which the new object is to be stored The mediaobject is updated with the information, and on save, the callback function is called """ ManagedWindow.__init__(self, uistate, track, self) self.dbase = dbstate.db self.obj = mediaobj self.callback = callback self.last_directory = config.get('behavior.addmedia-image-dir') self.relative_path = config.get('behavior.addmedia-relative-path') self.glade = Glade() self.set_window( self.glade.toplevel, self.glade.get_object('title'), _('Select a media object')) self.description = self.glade.get_object("photoDescription") self.image = self.glade.get_object("image") self.file_text = self.glade.get_object("fname") if not(self.last_directory and os.path.isdir(self.last_directory)): self.last_directory = USER_HOME #if existing path, use dir of path if not self.obj.get_path() == "": fullname = media_path_full(self.dbase, self.obj.get_path()) dir = os.path.dirname(fullname) if os.path.isdir(dir): self.last_directory = dir self.file_text.select_filename(fullname) else: self.file_text.set_current_folder(self.last_directory) else: self.file_text.set_current_folder(self.last_directory) if not self.obj.get_description() == "": self.description.set_text(self.obj.get_description()) self.relpath = self.glade.get_object('relpath') self.relpath.set_active(self.relative_path) self.temp_name = "" self.object = None self.glade.get_object('fname').connect('update_preview', self.on_name_changed) self.ok_button = self.glade.get_object('button79') self.help_button = self.glade.get_object('button103') self.cancel_button = self.glade.get_object('button81') self.ok_button.connect('clicked', self.save) self.ok_button.set_sensitive(not self.dbase.readonly) self.help_button.connect('clicked', lambda x: display_help( webpage=WIKI_HELP_PAGE, section=WIKI_HELP_SEC)) self.cancel_button.connect('clicked', self.close) self.show() self.modal_call()
def _initialize(self, directory, username, password): config_file = os.path.join(directory, 'settings.ini') config_mgr = ConfigManager(config_file) config_mgr.register('database.dbname', '') config_mgr.register('database.host', '') config_mgr.register('database.port', '') if not os.path.exists(config_file): name_file = os.path.join(directory, 'name.txt') with open(name_file, 'r', encoding='utf8') as file: dbname = file.readline().strip() config_mgr.set('database.dbname', dbname.replace(' ', '_')) config_mgr.set('database.host', config.get('database.host')) config_mgr.set('database.port', config.get('database.port')) config_mgr.save() config_mgr.load() dbkwargs = {} for key in config_mgr.get_section_settings('database'): value = config_mgr.get('database.' + key) if key != 'dbname': if value: dbkwargs[key] = value else: dbname = value if username: dbkwargs['user'] = username if password: dbkwargs['password'] = password self.client = MongoClient(**dbkwargs) self.db = self.client[dbname]
def change_map(self, obj, map_type): """ Change the current map """ if obj is not None: self.osm.layer_remove_all() self.osm.image_remove_all() self.vbox.remove(self.osm) self.osm.destroy() tiles_path = os.path.join(config.get('geography.path'), constants.TILES_PATH[map_type]) if not os.path.isdir(tiles_path): try: os.makedirs(tiles_path, 0o755) # create dir like mkdir -p except: ErrorDialog(_("Can't create " "tiles cache directory for '%s'.") % constants.MAP_TITLE[map_type], parent=self.uistate.window) config.set("geography.map_service", map_type) self.current_map = map_type http_proxy = get_env_var('http_proxy') if 0: self.osm = DummyMapNoGpsPoint() else: if http_proxy: self.osm = osmgpsmap.Map(tile_cache=tiles_path, proxy_uri=http_proxy, map_source=constants.MAP_TYPE[ map_type]) else: self.osm = osmgpsmap.Map(tile_cache=tiles_path, map_source=constants.MAP_TYPE[ map_type]) self.osm.props.tile_cache = osmgpsmap.MAP_CACHE_AUTO current_map = osmgpsmap.MapOsd(show_dpad=False, show_zoom=True) self.end_selection = None self.osm.layer_add(current_map) self.osm.layer_add(DummyLayer()) self.selection_layer = self.add_selection_layer() self.kml_layer = self.add_kml_layer() self.lifeway_layer = self.add_lifeway_layer() self.marker_layer = self.add_marker_layer() self.date_layer = self.add_date_layer() self.message_layer = self.add_message_layer() self.cross_map = osmgpsmap.MapOsd(show_crosshair=False) self.set_crosshair(config.get("geography.show_cross")) self.osm.set_center_and_zoom(config.get("geography.center-lat"), config.get("geography.center-lon"), config.get("geography.zoom")) self.osm.connect('button_release_event', self.map_clicked) self.osm.connect('button_press_event', self.map_clicked) self.osm.connect("motion-notify-event", self.motion_event) self.osm.connect('changed', self.zoom_changed) self.update_shortcuts(True) self.osm.show() self.vbox.pack_start(self.osm, True, True, 0) self.goto_handle(handle=None)
def _set_size(self): """ Set the dimensions of the window """ if self.width_key is not None: width = config.get(self.width_key) height = config.get(self.height_key) self.window.resize(width, height)
def config_crosshair(self, client, cnxn_id, entry, data): """ We asked to change the crosshair. """ if config.get("geography.show_cross"): config.set("geography.show_cross", False) else: config.set("geography.show_cross", True) self.set_crosshair(config.get("geography.show_cross"))
def _set_size(self): """ Set the dimensions of the window """ # self.width_key is set in the subclass, typically in its _local_init if self.width_key is not None: width = config.get(self.width_key) height = config.get(self.height_key) self.window.resize(width, height)
def _set_size(self): """ Set the dimensions of the window """ # self.width_key is set in the subclass (or in setup_configs) if self.width_key is not None: width = config.get(self.width_key) height = config.get(self.height_key) self.window.resize(width, height)
def _set_position(self): """ Set the position of the window """ # self.horiz_position_key is set in the subclass (or in setup_configs) if self.horiz_position_key is not None: horiz_position = config.get(self.horiz_position_key) vert_position = config.get(self.vert_position_key) self.window.move(horiz_position, vert_position)
def config_zoom_and_position(self, client, cnxn_id, entry, data): """ Do we need to lock the zoom and position ? """ if config.get("geography.lock"): config.set("geography.lock", False) self._set_center_and_zoom() else: config.set("geography.lock", True) self.lock = config.get("geography.lock")
def _create_markers(self): """ Create all markers for the specified person. """ if self.marker_layer is None: return self.remove_all_markers() self.remove_all_gps() self.remove_all_tracks() if (self.current_map is not None and self.current_map != config.get("geography.map_service")): self.change_map(self.osm, config.get("geography.map_service")) last = "" current = "" differtype = False #savetype = None lat = 0.0 lon = 0.0 icon = None count = 0 self.uistate.set_busy_cursor(True) _LOG.debug("%s", time.strftime("start create_marker : " "%a %d %b %Y %H:%M:%S", time.gmtime())) for mark in self.sort: current = ([mark[3], mark[4]]) if last == "": last = current lat = mark[3] lon = mark[4] icon = mark[7] colour = mark[12] differtype = False count = 1 continue if last != current: self.add_marker(None, None, lat, lon, icon, differtype, count, color=colour) differtype = False count = 1 last = current lat = mark[3] lon = mark[4] icon = mark[7] colour = mark[12] else: # This marker already exists. add info. count += 1 if icon != mark[7]: differtype = True if lat != 0.0 and lon != 0.0: self.add_marker(None, None, lat, lon, icon, differtype, count, color=mark[12]) self._set_center_and_zoom() _LOG.debug("%s", time.strftime(" stop create_marker : " "%a %d %b %Y %H:%M:%S", time.gmtime())) self.uistate.set_busy_cursor(False)
def __get_places(self, obj): gov_id = self.entry.get_text() to_do = [gov_id] try: preferred_lang = config.get('preferences.place-lang') except AttributeError: fmt = config.get('preferences.place-format') pf = _pd.get_formats()[fmt] preferred_lang = pf.language if len(preferred_lang) != 2: preferred_lang = 'de' visited = {} type_dic = dict() type_url = 'http://gov.genealogy.net/types.owl/' response = urlopen(type_url) data = response.read() dom = parseString(data) for group in dom.getElementsByTagName('owl:Class') : url_value = group.attributes['rdf:about'].value group_number = 'j.0:' + url_value.split('#')[1] for element in dom.getElementsByTagName(group_number): type_number = element.attributes['rdf:about'].value.split('#')[1] for pname in element.getElementsByTagName('rdfs:label'): type_lang = pname.attributes['xml:lang'].value type_text = pname.childNodes[0].data type_dic[type_number,type_lang] = type_text with DbTxn(_('Add GOV-id place %s') % gov_id, self.dbstate.db) as trans: while to_do: gov_id = to_do.pop() place = self.dbstate.db.get_place_from_gramps_id(gov_id) if place is not None: visited[gov_id] = (place, []) else: place, ref_list = self.__get_place(gov_id, type_dic, preferred_lang) if place.get_name().get_value is not '': self.dbstate.db.add_place(place, trans) visited[gov_id] = (place, ref_list) for ref, date in ref_list: if (ref not in to_do) and (ref not in visited): to_do.append(ref) for place, ref_list in visited.values(): if len(ref_list) > 0: for ref, date in ref_list: handle = visited[ref][0].handle place_ref = PlaceRef() place_ref.ref = handle place_ref.set_date_object(date) place.add_placeref(place_ref) self.dbstate.db.commit_place(place, trans)
def __init__(self, argparser): from gramps.gen.dbstate import DbState from . import viewmanager from .viewmanager import ViewManager from gramps.cli.arghandler import ArgHandler from .tipofday import TipOfDay import gettext # Append image directory to the theme search path theme = Gtk.IconTheme.get_default() theme.append_search_path(IMAGE_DIR) dbstate = DbState() self._vm = ViewManager(dbstate, config.get("interface.view-categories")) if (lin() and glocale.lang != 'C' and not gettext.find(GTK_GETTEXT_DOMAIN)): _display_gtk_gettext_message(parent=self._vm.window) _display_welcome_message(parent=self._vm.window) _display_translator_message(parent=self._vm.window) self._vm.init_interface() #act based on the given arguments arg_h = ArgHandler(dbstate, argparser, self._vm, self.argerrorfunc, gui=True) arg_h.handle_args_gui() if arg_h.open or arg_h.imp_db_path: # if we opened or imported something, only show the interface self._vm.post_init_interface(show_manager=False) elif (config.get('paths.recent-file') and config.get('behavior.autoload')): # if we need to autoload last seen file, do so filename = config.get('paths.recent-file') if (os.path.isdir(filename) and os.path.isfile(os.path.join(filename, "name.txt")) and arg_h.check_db(filename)): self._vm.post_init_interface(show_manager=False) self._vm.open_activate(filename) else: self._vm.post_init_interface() else: # open without fam tree loaded self._vm.post_init_interface() if config.get('behavior.use-tips'): TipOfDay(self._vm.uistate)
def importData(dbase, filename, user): """Function called by Gramps to import data on persons in CSV format.""" if dbase.get_feature("skip-import-additions"): # don't add source or tags parser = CSVParser(dbase, user, None) else: parser = CSVParser(dbase, user, (config.get('preferences.tag-on-import-format') if config.get('preferences.tag-on-import') else None)) try: with open(filename, 'r') as filehandle: parser.parse(filehandle) except EnvironmentError as err: user.notify_error(_("%s could not be opened\n") % filename, str(err)) return return ImportInfo({_("Results"): _("done")})
def save_center(self, lat, lon): """ Save the longitude and lontitude in case we switch between maps. """ _LOG.debug("save_center : %s,%s", lat, lon) if (-90.0 < lat < +90.0) and (-180.0 < lon < +180.0): config.set("geography.center-lat", lat) config.set("geography.center-lon", lon) else: _LOG.debug("save_center : new coordinates : %s,%s", lat, lon) _LOG.debug("save_center : old coordinates : %s,%s", lat, lon) # osmgpsmap bug ? reset to prior values to avoid osmgpsmap problems. self.osm.set_center_and_zoom(config.get("geography.center-lat"), config.get("geography.center-lon"), config.get("geography.zoom"))
def color_graph_family(family, dbstate): """ :return: based on the config the color for graph family node in hex :rtype: tuple (hex color fill, hex color border) """ scheme = config.get('colors.scheme') for event_ref in family.get_event_ref_list(): event = dbstate.db.get_event_from_handle(event_ref.ref) if (event.type == EventType.DIVORCE and event_ref.get_role() in (EventRoleType.FAMILY, EventRoleType.PRIMARY)): return (config.get('colors.family-divorced')[scheme], config.get('colors.border-family-divorced')[scheme]) return (config.get('colors.family')[scheme], config.get('colors.border-family')[scheme])
def get_default_dir(): # Suggested folder: try last open file, last import, last export, # then home. default_dir = os.path.dirname(config.get('paths.recent-file')) if default_dir: default_dir += os.path.sep if len(default_dir)<=1: default_dir = config.get('paths.recent-import-dir') if len(default_dir)<=1: default_dir = config.get('paths.recent-export-dir') if len(default_dir)<=1: default_dir = '~/' else: default_dir = "~/" return default_dir
def build_widget(self): """ create the vbox """ self.vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) cache_path = config.get("geography.path") if not os.path.isdir(cache_path): try: os.makedirs(cache_path, 0o755) # create dir like mkdir -p except: ErrorDialog(_("Can't create tiles cache directory %s") % cache_path) return self.vbox self.change_map(None, config.get("geography.map_service")) return self.vbox
def is_there_a_place_here(self, lat, lon): """ Is there a place at this position ? If too many places, this function is very time consuming """ mark_selected = [] if self.no_show_places_in_status_bar: return mark_selected oldplace = "" _LOG.debug("%s", time.strftime("start is_there_a_place_here : " "%a %d %b %Y %H:%M:%S", time.gmtime())) for mark in self.places_found: # as we are not precise with our hand, reduce the precision # depending on the zoom. if mark[0] != oldplace: oldplace = mark[0] precision = { 1 : '%3.0f', 2 : '%3.1f', 3 : '%3.1f', 4 : '%3.1f', 5 : '%3.2f', 6 : '%3.2f', 7 : '%3.2f', 8 : '%3.3f', 9 : '%3.3f', 10 : '%3.3f', 11 : '%3.3f', 12 : '%3.3f', 13 : '%3.3f', 14 : '%3.4f', 15 : '%3.4f', 16 : '%3.4f', 17 : '%3.4f', 18 : '%3.4f' }.get(config.get("geography.zoom"), '%3.1f') shift = { 1 : 5.0, 2 : 5.0, 3 : 3.0, 4 : 1.0, 5 : 0.5, 6 : 0.3, 7 : 0.15, 8 : 0.06, 9 : 0.03, 10 : 0.015, 11 : 0.005, 12 : 0.003, 13 : 0.001, 14 : 0.0005, 15 : 0.0003, 16 : 0.0001, 17 : 0.0001, 18 : 0.0001 }.get(config.get("geography.zoom"), 5.0) latp = precision % lat lonp = precision % lon mlatp = precision % float(mark[1]) mlonp = precision % float(mark[2]) latok = lonok = False if (float(mlatp) >= (float(latp) - shift)) and \ (float(mlatp) <= (float(latp) + shift)): latok = True if (float(mlonp) >= (float(lonp) - shift)) and \ (float(mlonp) <= (float(lonp) + shift)): lonok = True if latok and lonok: mark_selected.append(mark) _LOG.debug("%s", time.strftime(" end is_there_a_place_here : " "%a %d %b %Y %H:%M:%S", time.gmtime())) return mark_selected
def is_there_a_marker_here(self, event, lat, lon): """ Is there a marker at this position ? """ found = False mark_selected = [] self.uistate.set_busy_cursor(True) for mark in self.sort: # as we are not precise with our hand, reduce the precision # depending on the zoom. precision = { 1 : '%3.0f', 2 : '%3.1f', 3 : '%3.1f', 4 : '%3.1f', 5 : '%3.2f', 6 : '%3.2f', 7 : '%3.2f', 8 : '%3.3f', 9 : '%3.3f', 10 : '%3.3f', 11 : '%3.3f', 12 : '%3.3f', 13 : '%3.3f', 14 : '%3.4f', 15 : '%3.4f', 16 : '%3.4f', 17 : '%3.4f', 18 : '%3.4f' }.get(config.get("geography.zoom"), '%3.1f') shift = { 1 : 5.0, 2 : 5.0, 3 : 3.0, 4 : 1.0, 5 : 0.5, 6 : 0.3, 7 : 0.15, 8 : 0.06, 9 : 0.03, 10 : 0.015, 11 : 0.005, 12 : 0.003, 13 : 0.001, 14 : 0.0005, 15 : 0.0003, 16 : 0.0001, 17 : 0.0001, 18 : 0.0001 }.get(config.get("geography.zoom"), 5.0) latp = precision % lat lonp = precision % lon mlatp = precision % float(mark[3]) mlonp = precision % float(mark[4]) latok = lonok = False _LOG.debug(" compare latitude : %s with %s (precision = %s)" " place='%s'" % (float(mark[3]), lat, precision, mark[0])) _LOG.debug("compare longitude : %s with %s (precision = %s)" " zoom=%d" % (float(mark[4]), lon, precision, config.get("geography.zoom"))) if (float(mlatp) >= (float(latp) - shift) ) and \ (float(mlatp) <= (float(latp) + shift) ): latok = True if (float(mlonp) >= (float(lonp) - shift) ) and \ (float(mlonp) <= (float(lonp) + shift) ): lonok = True if latok and lonok: mark_selected.append(mark) found = True if found: self.bubble_message(event, lat, lon, mark_selected) self.uistate.set_busy_cursor(False)
def __init__(self, pdata, dbstate, uistate, title, model, nav_group): signal_map = { 'place-add' : self.row_add, 'place-update' : self.row_update, 'place-delete' : self.row_delete, 'place-rebuild' : self.object_build, } self.mapservice = config.get('interface.mapservice') self.mapservicedata = {} ListView.__init__( self, title, pdata, dbstate, uistate, model, signal_map, PlaceBookmarks, nav_group, multiple=True, filter_class=PlaceSidebarFilter) self.func_list.update({ '<PRIMARY>J' : self.jump, '<PRIMARY>BackSpace' : self.key_delete, }) self.maptoolbtn = None uistate.connect('placeformat-changed', self.build_tree) self.additional_uis.append(self.additional_ui())
def _populate_cli(self): """ Get the list of current names in the database dir """ # make the default directory if it does not exist dbdir = os.path.expanduser(config.get('behavior.database-path')) db_ok = make_dbdir(dbdir) self.current_names = [] if db_ok: for dpath in os.listdir(dbdir): dirpath = os.path.join(dbdir, dpath) path_name = os.path.join(dirpath, NAME_FILE) if os.path.isfile(path_name): file = io.open(path_name, 'r', encoding='utf8') name = file.readline().strip() file.close() (tval, last) = time_val(dirpath) (enable, stock_id) = self.icon_values(dirpath, self.active, self.dbstate.db.is_open()) if (stock_id == 'gramps-lock'): last = find_locker_name(dirpath) self.current_names.append( (name, os.path.join(dbdir, dpath), path_name, last, tval, enable, stock_id)) self.current_names.sort()
def remove_database(self, dbname, user=None): """ Deletes a database folder given a pattenr that matches its proper name. """ dbdir = os.path.expanduser(config.get('behavior.database-path')) match_list = [] for dpath in os.listdir(dbdir): dirpath = os.path.join(dbdir, dpath) path_name = os.path.join(dirpath, NAME_FILE) if os.path.isfile(path_name): with open(path_name, 'r', encoding='utf8') as file: name = file.readline().strip() if re.match("^" + dbname + "$", name) or dbname == name: match_list.append((name, dirpath)) if len(match_list) == 0: CLIDbManager.ERROR("Family tree not found", "No matching family tree found: '%s'" % dbname) # now delete them: for (name, directory) in match_list: if user is None or user.prompt( _('Remove family tree warning'), _('Are you sure you want to remove the family tree named\n"%s"?' % name), _('yes'), _('no'), default_label=_('no')): try: for (top, dirs, files) in os.walk(directory): for filename in files: os.unlink(os.path.join(top, filename)) os.rmdir(directory) except (IOError, OSError) as msg: CLIDbManager.ERROR(_("Could not delete Family Tree"), str(msg))
def __init__(self, dbstate, uistate, track, family, callback=None): EditPrimary.__init__(self, dbstate, uistate, track, family, dbstate.db.get_family_from_handle, dbstate.db.get_family_from_gramps_id, callback) # look for the scenerio of a child and no parents on a new # family if (self.added and not self.obj.get_father_handle() and not self.obj.get_mother_handle() and len(self.obj.get_child_ref_list()) == 1): self.add_parent = True if not config.get('preferences.family-warn'): for i in self.hidden: i.set_sensitive(False) MessageHideDialog( _("Adding parents to a person"), _("It is possible to accidentally create multiple " "families with the same parents. To help avoid " "this problem, only the buttons to select parents " "are available when you create a new family. The " "remaining fields will become available after you " "attempt to select a parent."), 'preferences.family-warn') else: self.add_parent = False
def setup_format_frame(self): """Set up the format frame of the dialog.""" self.format_menu = GraphvizFormatComboBox() self.format_menu.set(self.options.handler.get_format_name()) self.format_menu.connect('changed', self.doc_type_changed) label = Gtk.Label(label=_("%s:") % _("Output Format")) label.set_halign(Gtk.Align.START) self.grid.attach(label, 1, self.row, 1, 1) self.format_menu.set_hexpand(True) self.grid.attach(self.format_menu, 2, self.row, 2, 1) self.row += 1 self.open_with_app = Gtk.CheckButton( label=_("Open with default viewer")) self.open_with_app.set_active( config.get('interface.open-with-default-viewer')) self.grid.attach(self.open_with_app, 2, self.row, 2, 1) self.row += 1 ext = self.format_menu.get_ext() if ext is None: ext = "" else: spath = self.get_default_directory() if self.options.get_output(): base = os.path.basename(self.options.get_output()) else: if self.dbname is None: default_name = self.raw_name else: default_name = self.dbname + "_" + self.raw_name base = "%s%s" % (default_name, ext) # "ext" already has a dot spath = os.path.normpath(os.path.join(spath, base)) self.target_fileentry.set_filename(spath)
def __init__(self, date, uistate, track): """ Initiate and display the dialog. """ ManagedWindow.__init__(self, uistate, track, self) # Create self.date as a copy of the given Date object. self.date = Date(date) self.top = Glade() self.set_window( self.top.toplevel, self.top.get_object('title'), _('Date selection')) self.setup_configs('interface.editdate', 620, 320) self.statusbar = self.top.get_object('statusbar') self.ok_button = self.top.get_object('ok_button') self.calendar_box = self.top.get_object('calendar_box') for name in Date.ui_calendar_names: self.calendar_box.get_model().append([name]) self.new_year = self.top.get_object('newyear') self.new_year.set_text(self.date.newyear_to_str()) cal = self.date.get_calendar() self.calendar_box.set_active(cal) self.align_newyear_ui_with_calendar(cal) self.calendar_box.connect('changed', self.switch_calendar) self.quality_box = self.top.get_object('quality_box') for item_number, item in enumerate(QUAL_TEXT): self.quality_box.append_text(item[1]) if self.date.get_quality() == item[0]: self.quality_box.set_active(item_number) self.type_box = self.top.get_object('type_box') for item_number, item in enumerate(MOD_TEXT): self.type_box.append_text(item[1]) if self.date.get_modifier() == item[0]: self.type_box.set_active(item_number) self.type_box.connect('changed', self.switch_type) self.start_month_box = self.top.get_object('start_month_box') self.stop_month_box = self.top.get_object('stop_month_box') month_names = CAL_TO_MONTHS_NAMES[self.date.get_calendar()] for name in month_names: self.start_month_box.append_text(name) self.stop_month_box.append_text(name) self.start_month_box.set_active(self.date.get_month()) self.stop_month_box.set_active(self.date.get_stop_month()) self.start_day = self.top.get_object('start_day') self.start_day.set_value(self.date.get_day()) self.start_year = self.top.get_object('start_year') self.start_year.set_value(self.date.get_year()) self.stop_day = self.top.get_object('stop_day') self.stop_day.set_value(self.date.get_stop_day()) self.stop_year = self.top.get_object('stop_year') self.stop_year.set_value(self.date.get_stop_year()) self.dual_dated = self.top.get_object('dualdated') # Disable second date controls if not compound date if not self.date.is_compound(): self.stop_day.set_sensitive(0) self.stop_month_box.set_sensitive(0) self.stop_year.set_sensitive(0) # Disable the rest of controls if a text-only date if self.date.get_modifier() == Date.MOD_TEXTONLY: self.start_day.set_sensitive(0) self.start_month_box.set_sensitive(0) self.start_year.set_sensitive(0) self.calendar_box.set_sensitive(0) self.quality_box.set_sensitive(0) self.dual_dated.set_sensitive(0) self.new_year.set_sensitive(0) self.text_entry = self.top.get_object('date_text_entry') self.text_entry.set_text(self.date.get_text()) if self.date.get_slash(): self.dual_dated.set_active(1) self.calendar_box.set_sensitive(0) self.calendar_box.set_active(Date.CAL_JULIAN) self.dual_dated.connect('toggled', self.switch_dual_dated) cal = config.get('preferences.calendar-format-input') self.calendar_box.set_active(cal) # The dialog is modal -- since dates don't have names, we don't # want to have several open dialogs, since then the user will # loose track of which is which. Much like opening files. self.validated_date = self.return_date = None for obj in self.top.get_objects(): if obj != self.ok_button: for signal in ['changed', 'value-changed']: try: obj.connect_after(signal, self.revalidate) except TypeError: # some of them don't support the signal, ignore them... pass self.revalidate() self.show() while True: response = self.window.run() LOG.debug("response: {0}".format(response)) if response == Gtk.ResponseType.HELP: display_help(webpage=WIKI_HELP_PAGE, section=WIKI_HELP_SEC) elif response == Gtk.ResponseType.DELETE_EVENT: break else: if response == Gtk.ResponseType.OK: # if the user pressed OK/enter while inside an edit field, # e.g., the year, # build_date_from_ui won't pick up the new text in the # run of revalidate that allowed the OK! if not self.revalidate(): continue self.return_date = Date() self.return_date.copy(self.validated_date) self.close() break
def _createmap(self, person, color, place_list, reference): """ Create all markers for each people's event in the database which has a lat/lon. """ dbstate = self.dbstate self.cal = config.get('preferences.calendar-format-report') self.place_list = place_list self.place_without_coordinates = [] self.minlat = self.maxlat = self.minlon = self.maxlon = 0.0 self.minyear = 9999 self.maxyear = 0 latitude = "" longitude = "" if person is not None: # For each event, if we have a place, set a marker. for event_ref in person.get_event_ref_list(): if not event_ref: continue event = dbstate.db.get_event_from_handle(event_ref.ref) role = event_ref.get_role() try: date = event.get_date_object().to_calendar(self.cal) except: continue eyear = str("%04d" % date.get_year()) + \ str("%02d" % date.get_month()) + \ str("%02d" % date.get_day()) place_handle = event.get_place_handle() if place_handle: place = dbstate.db.get_place_from_handle(place_handle) if place: longitude = place.get_longitude() latitude = place.get_latitude() latitude, longitude = conv_lat_lon(latitude, longitude, "D.D8") descr = _pd.display(dbstate.db, place) evt = EventType(event.get_type()) descr1 = _("%(eventtype)s : %(name)s") % { 'eventtype': evt, 'name': _nd.display(person)} # place.get_longitude and place.get_latitude return # one string. We have coordinates when the two values # contains non null string. if ( longitude and latitude ): self._append_to_places_list(descr, evt, _nd.display(person), latitude, longitude, descr1, eyear, event.get_type(), person.gramps_id, place.gramps_id, event.gramps_id, role ) else: self._append_to_places_without_coord( place.gramps_id, descr) family_list = person.get_family_handle_list() descr1 = " - " for family_hdl in family_list: family = self.dbstate.db.get_family_from_handle(family_hdl) if family is not None: fhandle = family_list[0] # first is primary fam = dbstate.db.get_family_from_handle(fhandle) handle = fam.get_father_handle() father = dbstate.db.get_person_from_handle(handle) if father: descr1 = "%s - " % _nd.display(father) handle = fam.get_mother_handle() mother = dbstate.db.get_person_from_handle(handle) if mother: descr1 = "%s%s" % ( descr1, _nd.display(mother)) for event_ref in family.get_event_ref_list(): if event_ref: event = dbstate.db.get_event_from_handle( event_ref.ref) role = event_ref.get_role() if event.get_place_handle(): place_handle = event.get_place_handle() if place_handle: place = dbstate.db.get_place_from_handle( place_handle) if place: longitude = place.get_longitude() latitude = place.get_latitude() latitude, longitude = conv_lat_lon( latitude, longitude, "D.D8") descr = _pd.display(dbstate.db, place) evt = EventType( event.get_type()) eyear = str("%04d" % event.get_date_object().to_calendar(self.cal).get_year()) + \ str("%02d" % event.get_date_object().to_calendar(self.cal).get_month()) + \ str("%02d" % event.get_date_object().to_calendar(self.cal).get_day()) if ( longitude and latitude ): self._append_to_places_list(descr, evt, _nd.display(person), latitude, longitude, descr1, eyear, event.get_type(), person.gramps_id, place.gramps_id, event.gramps_id, role ) else: self._append_to_places_without_coord( place.gramps_id, descr) sort1 = sorted(self.place_list, key=operator.itemgetter(6)) self.draw(None, sort1, color, reference) # merge with the last results merge_list = [] for the_list in self.sort, sort1 : merge_list += the_list self.sort = sorted(merge_list, key=operator.itemgetter(6))
def _createmap(self, place_x): """ Create all markers for each people's event in the database which has a lat/lon. """ dbstate = self.dbstate self.place_list = [] self.places_found = [] self.place_without_coordinates = [] self.minlat = 0.0 self.maxlat = 0.0 self.minlon = 0.0 self.maxlon = 0.0 self.minyear = 9999 self.maxyear = 0 self.without = 0 latitude = "" longitude = "" self.nbmarkers = 0 self.nbplaces = 0 self.remove_all_markers() self.message_layer.clear_messages() self.message_layer.clear_font_attributes() self.kml_layer.clear() self.no_show_places_in_status_bar = False _col = self._config.get self.plc_color = [ (PlaceType.UNKNOWN, _col('geography.color.unknown')), (PlaceType.CUSTOM, _col('geography.color.custom')), (PlaceType.COUNTRY, _col('geography.color.country')), (PlaceType.STATE, _col('geography.color.state')), (PlaceType.COUNTY, _col('geography.color.county')), (PlaceType.CITY, _col('geography.color.city')), (PlaceType.PARISH, _col('geography.color.parish')), (PlaceType.LOCALITY, _col('geography.color.locality')), (PlaceType.STREET, _col('geography.color.street')), (PlaceType.PROVINCE, _col('geography.color.province')), (PlaceType.REGION, _col('geography.color.region')), (PlaceType.DEPARTMENT, _col('geography.color.department')), (PlaceType.NEIGHBORHOOD, _col('geography.color.neighborhood')), (PlaceType.DISTRICT, _col('geography.color.district')), (PlaceType.BOROUGH, _col('geography.color.borough')), (PlaceType.MUNICIPALITY, _col('geography.color.municipality')), (PlaceType.TOWN, _col('geography.color.town')), (PlaceType.VILLAGE, _col('geography.color.village')), (PlaceType.HAMLET, _col('geography.color.hamlet')), (PlaceType.FARM, _col('geography.color.farm')), (PlaceType.BUILDING, _col('geography.color.building')), (PlaceType.NUMBER, _col('geography.color.number')) ] # base "villes de france" : 38101 places : # createmap : 8'50"; create_markers : 1'23" # base "villes de france" : 38101 places : # createmap : 8'50"; create_markers : 0'07" with pixbuf optimization # base "villes de france" : 38101 places : # gramps 3.4 python 2.7 (draw_markers are estimated when moving the map) # 38101 places: createmap: 04'32"; # create_markers: 0'04"; draw markers: N/A :: 0'03" # 65598 places: createmap: 10'03"; # create_markers: 0'07"; draw markers: N/A :: 0'05" # gramps 3.5 python 2.7 new marker layer # 38101 places: createmap: 03'09"; # create_markers: 0'01"; draw markers: 0'04" # 65598 places: createmap: 08'48"; # create_markers: 0'01"; draw markers: 0'07" _LOG.debug( "%s", time.strftime("start createmap : " "%a %d %b %Y %H:%M:%S", time.gmtime())) self.custom_places() if self.show_all: self.show_all = False try: places_handle = dbstate.db.get_place_handles() except: return progress = ProgressMeter(self.window_name, can_cancel=False, parent=self.uistate.window) length = len(places_handle) progress.set_pass(_('Selecting all places'), length) for place_hdl in places_handle: place = dbstate.db.get_place_from_handle(place_hdl) self._create_one_place(place) progress.step() progress.close() elif self.generic_filter: user = self.uistate.viewmanager.user place_list = self.generic_filter.apply(dbstate.db, user=user) progress = ProgressMeter(self.window_name, can_cancel=False, parent=self.uistate.window) length = len(place_list) progress.set_pass(_('Selecting all places'), length) for place_handle in place_list: place = dbstate.db.get_place_from_handle(place_handle) self._create_one_place(place) progress.step() progress.close() # reset completely the filter. It will be recreated next time. self.generic_filter = None elif place_x != None: place = dbstate.db.get_place_from_handle(place_x) self._create_one_place(place) self.message_layer.add_message( _("Right click on the map and select 'show all places'" " to show all known places with coordinates. " "You can change the markers color depending on place type. " "You can use filtering.")) if place.get_latitude() != "" and place.get_longitude() != "": latitude, longitude = conv_lat_lon(place.get_latitude(), place.get_longitude(), "D.D8") if latitude and longitude: self.osm.set_center_and_zoom( float(latitude), float(longitude), int(config.get("geography.zoom_when_center"))) else: self.message_layer.add_message( _("Right click on the map and select 'show all places'" " to show all known places with coordinates. " "You can use the history to navigate on the map. " "You can change the markers color depending on place type. " "You can use filtering.")) _LOG.debug(" stop createmap.") _LOG.debug( "%s", time.strftime("begin sort : " "%a %d %b %Y %H:%M:%S", time.gmtime())) self.sort = sorted(self.place_list, key=operator.itemgetter(0)) _LOG.debug( "%s", time.strftime(" end sort : " "%a %d %b %Y %H:%M:%S", time.gmtime())) if self.nbmarkers > 500: # performance issue. Is it the good value ? self.message_layer.add_message( _("The place name in the status bar is disabled.")) self.no_show_places_in_status_bar = True if self.nbplaces >= self._config.get("geography.max_places"): self.message_layer.set_font_attributes(None, None, "red") self.message_layer.add_message( _("The maximum number of places is reached (%d).") % self._config.get("geography.max_places")) self.message_layer.add_message(_("Some information are missing.")) self.message_layer.add_message( _("Please, use filtering to reduce this number.")) self.message_layer.add_message( _("You can modify this value in the geography option.")) self.message_layer.add_message( _("In this case, it may take time to show all markers.")) self._create_markers()
def _createmap(self, obj): """ Create all markers for each people's event in the database which has a lat/lon. """ if self.osm is None: return dbstate = self.dbstate self.place_list = [] self.places_found = [] self.place_without_coordinates = [] self.minlat = self.maxlat = self.minlon = self.maxlon = 0.0 self.minyear = 9999 self.maxyear = 0 self.nbmarkers = 0 self.nbplaces = 0 self.without = 0 self.cal = config.get('preferences.calendar-format-report') self.message_layer.clear_messages() self.message_layer.clear_font_attributes() self.no_show_places_in_status_bar = False if self.show_all: self.show_all = False events_handle = dbstate.db.get_event_handles() progress = ProgressMeter(self.window_name, can_cancel=False, parent=self.uistate.window) length = len(events_handle) progress.set_pass(_('Selecting all events'), length) for event_hdl in events_handle: event = dbstate.db.get_event_from_handle(event_hdl) self._createmap_for_one_event(event) progress.step() progress.close() elif self.generic_filter: user=self.uistate.viewmanager.user events_list = self.generic_filter.apply(dbstate.db, user=user) progress = ProgressMeter(self.window_name, can_cancel=False, parent=self.uistate.window) length = len(events_list) progress.set_pass(_('Selecting all events'), length) for event_handle in events_list: event = dbstate.db.get_event_from_handle(event_handle) self._createmap_for_one_event(event) progress.step() progress.close() else: if obj: event = dbstate.db.get_event_from_handle(obj) self._createmap_for_one_event(event) self.message_layer.add_message( _("Right click on the map and select 'show all events'" " to show all known events with coordinates. " "You can use the history to navigate on the map. " "You can use filtering.")) self.sort = sorted(self.place_list, key=operator.itemgetter(3, 4, 6) ) if self.nbmarkers > 500: # performance issue. Is it the good value ? self.no_show_places_in_status_bar = True self._create_markers()
def __init__(self, dbstate, uistate, track, handle1, handle2, callback=None): ManagedWindow.__init__(self, uistate, track, self.__class__) self.dbstate = dbstate database = dbstate.db self.callback = callback self.pl1 = database.get_place_from_handle(handle1) self.pl2 = database.get_place_from_handle(handle2) self.define_glade('mergeplace', _GLADE_FILE) self.set_window(self._gladeobj.toplevel, self.get_widget('place_title'), _("Merge Places")) self.setup_configs('interface.merge-place', 500, 250) # Detailed selection widgets if not config.get('preferences.place-auto'): title1 = self.pl1.get_title() title2 = self.pl2.get_title() entry1 = self.get_widget("title1") entry2 = self.get_widget("title2") entry1.set_text(title1) entry2.set_text(title2) if entry1.get_text() == entry2.get_text(): for widget_name in ('title1', 'title2', 'title_btn1', 'title_btn2'): self.get_widget(widget_name).set_sensitive(False) for widget_name in ('title1', 'title2', 'title_btn1', 'title_btn2'): self.get_widget(widget_name).show() for widget_name in ('name_btn1', 'name_btn2'): self.get_widget(widget_name).set_label(PLACE_NAME) entry1 = self.get_widget("name1") entry2 = self.get_widget("name2") entry1.set_text(self.pl1.get_name().get_value()) entry2.set_text(self.pl2.get_name().get_value()) if entry1.get_text() == entry2.get_text(): for widget_name in ('name1', 'name2', 'name_btn1', 'name_btn2'): self.get_widget(widget_name).set_sensitive(False) entry1 = self.get_widget("type1") entry2 = self.get_widget("type2") entry1.set_text(str(self.pl1.get_type())) entry2.set_text(str(self.pl2.get_type())) if entry1.get_text() == entry2.get_text(): for widget_name in ('type1', 'type2', 'type_btn1', 'type_btn2'): self.get_widget(widget_name).set_sensitive(False) entry1 = self.get_widget("code1") entry2 = self.get_widget("code2") entry1.set_text(self.pl1.get_code()) entry2.set_text(self.pl2.get_code()) if entry1.get_text() == entry2.get_text(): for widget_name in ('code1', 'code2', 'code_btn1', 'code_btn2'): self.get_widget(widget_name).set_sensitive(False) entry1 = self.get_widget("lat1") entry2 = self.get_widget("lat2") entry1.set_text(self.pl1.get_latitude()) entry2.set_text(self.pl2.get_latitude()) if entry1.get_text() == entry2.get_text(): for widget_name in ('lat1', 'lat2', 'lat_btn1', 'lat_btn2'): self.get_widget(widget_name).set_sensitive(False) entry1 = self.get_widget("long1") entry2 = self.get_widget("long2") entry1.set_text(self.pl1.get_longitude()) entry2.set_text(self.pl2.get_longitude()) if entry1.get_text() == entry2.get_text(): for widget_name in ('long1', 'long2', 'long_btn1', 'long_btn2'): self.get_widget(widget_name).set_sensitive(False) gramps1 = self.pl1.get_gramps_id() gramps2 = self.pl2.get_gramps_id() entry1 = self.get_widget("gramps1") entry2 = self.get_widget("gramps2") entry1.set_text(gramps1) entry2.set_text(gramps2) if entry1.get_text() == entry2.get_text(): for widget_name in ('gramps1', 'gramps2', 'gramps_btn1', 'gramps_btn2'): self.get_widget(widget_name).set_sensitive(False) # Main window widgets that determine which handle survives title1 = place_displayer.display(database, self.pl1) title2 = place_displayer.display(database, self.pl2) rbutton1 = self.get_widget("handle_btn1") rbutton_label1 = self.get_widget("label_handle_btn1") rbutton_label2 = self.get_widget("label_handle_btn2") rbutton_label1.set_label(title1 + " [" + gramps1 + "] " + str(self.pl1.place_type)) rbutton_label2.set_label(title2 + " [" + gramps2 + "] " + str(self.pl2.place_type)) rbutton1.connect("toggled", self.on_handle1_toggled) self.connect_button('place_help', self.cb_help) self.connect_button('place_ok', self.cb_merge) self.connect_button('place_cancel', self.close) self.show()
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # """ Show uncollected objects in a window. """ #------------------------------------------------------------------------ # # standard python modules # #------------------------------------------------------------------------ import sys from gramps.gen.const import GRAMPS_LOCALE as glocale _ = glocale.translation.gettext from gramps.gen.config import config if config.get('preferences.use-bsddb3') or sys.version_info[0] >= 3: from bsddb3.db import DBError else: from bsddb.db import DBError #------------------------------------------------------------------------ # # GNOME/GTK modules # #------------------------------------------------------------------------ from gi.repository import Gtk from gi.repository import Gdk import gc #------------------------------------------------------------------------ #
pt2cm = ReportUtils.pt2cm from gramps.gen.plug.report import MenuReportOptions from gramps.gen.plug.report import stdoptions from gramps.gen.plug.docgen import (FontStyle, ParagraphStyle, GraphicsStyle, FONT_SANS_SERIF, DASHED, PARA_ALIGN_CENTER, IndexMark, INDEX_TYPE_TOC) from gramps.gen.sort import Sort from gramps.gen.config import config from gramps.gen.utils.db import get_birth_or_fallback, get_death_or_fallback #------------------------------------------------------------------------ # # private constants # #------------------------------------------------------------------------ cal = config.get('preferences.calendar-format-report') #------------------------------------------------------------------------ # # Private Functions # #------------------------------------------------------------------------ def _get_sort_functions(sort): return [ (_("sorted by|Birth Date"), sort.by_birthdate_key), (_("sorted by|Name"), sort.by_last_name_key), ] #------------------------------------------------------------------------
def _create_markers(self): """ Create all markers for the specified person. """ if self.marker_layer is None: return self.remove_all_markers() self.remove_all_gps() self.remove_all_tracks() if (self.current_map is not None and self.current_map != config.get("geography.map_service")): self.change_map(self.osm, config.get("geography.map_service")) last = "" current = "" differtype = False lat = 0.0 lon = 0.0 icon = None count = 0 colour = None self.uistate.set_busy_cursor(True) _LOG.debug( "%s", time.strftime("start create_marker : " "%a %d %b %Y %H:%M:%S", time.gmtime())) for mark in self.sort: current = ([mark[3], mark[4]]) if last == "": last = current lat = mark[3] lon = mark[4] icon = mark[7] colour = mark[12] differtype = False count = 1 continue if last != current: self.add_marker(None, None, lat, lon, icon, differtype, count, color=colour) differtype = False count = 1 last = current lat = mark[3] lon = mark[4] icon = mark[7] colour = mark[12] else: # This marker already exists. add info. count += 1 if icon != mark[7]: differtype = True if lat != 0.0 and lon != 0.0: self.add_marker(None, None, lat, lon, icon, differtype, count, color=colour) self._set_center_and_zoom() _LOG.debug( "%s", time.strftime(" stop create_marker : " "%a %d %b %Y %H:%M:%S", time.gmtime())) self.uistate.set_busy_cursor(False)
def is_there_a_marker_here(self, event, lat, lon): """ Is there a marker at this position ? """ found = False mark_selected = [] self.uistate.set_busy_cursor(True) for mark in self.sort: # as we are not precise with our hand, reduce the precision # depending on the zoom. precision = { 1: '%3.0f', 2: '%3.1f', 3: '%3.1f', 4: '%3.1f', 5: '%3.2f', 6: '%3.2f', 7: '%3.2f', 8: '%3.3f', 9: '%3.3f', 10: '%3.3f', 11: '%3.3f', 12: '%3.3f', 13: '%3.3f', 14: '%3.4f', 15: '%3.4f', 16: '%3.4f', 17: '%3.4f', 18: '%3.4f' }.get(config.get("geography.zoom"), '%3.1f') shift = { 1: 5.0, 2: 5.0, 3: 3.0, 4: 1.0, 5: 0.5, 6: 0.3, 7: 0.15, 8: 0.06, 9: 0.03, 10: 0.015, 11: 0.005, 12: 0.003, 13: 0.001, 14: 0.0005, 15: 0.0003, 16: 0.0001, 17: 0.0001, 18: 0.0001 }.get(config.get("geography.zoom"), 5.0) latp = precision % lat lonp = precision % lon mlatp = precision % float(mark[3]) mlonp = precision % float(mark[4]) latok = lonok = False _LOG.debug( " compare latitude : %s with %s (precision = %s)" " place='%s'", float(mark[3]), lat, precision, mark[0]) _LOG.debug( "compare longitude : %s with %s (precision = %s)" " zoom=%d", float(mark[4]), lon, precision, config.get("geography.zoom")) if (float(mlatp) >= (float(latp) - shift)) and \ (float(mlatp) <= (float(latp) + shift)): latok = True if (float(mlonp) >= (float(lonp) - shift)) and \ (float(mlonp) <= (float(lonp) + shift)): lonok = True if latok and lonok: mark_selected.append(mark) found = True if found: self.bubble_message(event, lat, lon, mark_selected) self.uistate.set_busy_cursor(False)
def build_nav_menu(self, osm, event, lat, lon): """ Builds the menu for actions on the map. """ self.menu = Gtk.Menu() menu = self.menu if config.get("geography.show_cross"): title = _('Remove cross hair') else: title = _('Add cross hair') add_item = Gtk.MenuItem(label=title) add_item.connect("activate", self.config_crosshair, event, lat, lon) add_item.show() menu.append(add_item) if config.get("geography.lock"): title = _('Unlock zoom and position') else: title = _('Lock zoom and position') add_item = Gtk.MenuItem(label=title) add_item.connect("activate", self.config_zoom_and_position, event, lat, lon) add_item.show() menu.append(add_item) add_item = Gtk.MenuItem(label=_("Add place")) add_item.connect("activate", self.add_place, event, lat, lon) add_item.show() menu.append(add_item) add_item = Gtk.MenuItem(label=_("Link place")) add_item.connect("activate", self.link_place, event, lat, lon) add_item.show() menu.append(add_item) add_item = Gtk.MenuItem(label=_("Add place from kml")) add_item.connect("activate", self.add_place_from_kml, event, lat, lon) add_item.show() menu.append(add_item) add_item = Gtk.MenuItem(label=_("Center here")) add_item.connect("activate", self.set_center, event, lat, lon) add_item.show() menu.append(add_item) # Add specific module menu self.add_specific_menu(menu, event, lat, lon) # Add a separator line add_item = Gtk.MenuItem() add_item.show() menu.append(add_item) map_name = constants.MAP_TITLE[config.get("geography.map_service")] title = _("Replace '%(map)s' by =>") % {'map': map_name} add_item = Gtk.MenuItem(label=title) add_item.show() menu.append(add_item) self.changemap = Gtk.Menu() changemap = self.changemap changemap.set_title(title) changemap.show() add_item.set_submenu(changemap) # show in the map menu all available providers for my_map in constants.MAP_TYPE: changemapitem = Gtk.MenuItem(label=constants.MAP_TITLE[my_map]) changemapitem.show() changemapitem.connect("activate", self.change_map, my_map) changemap.append(changemapitem) reload_text = _("Reload all visible tiles for '%(map)s'.") % { 'map': map_name } self.reloadtiles = Gtk.MenuItem(label=reload_text) reloadtiles = self.reloadtiles reloadtiles.connect("activate", self.reload_visible_tiles) reloadtiles.show() menu.append(reloadtiles) clear_text = _("Clear the '%(map)s' tiles cache.") % {'map': map_name} self.clearmap = Gtk.MenuItem(label=clear_text) clearmap = self.clearmap clearmap.connect( "activate", self.clear_map, constants.TILES_PATH[config.get("geography.map_service")]) clearmap.show() menu.append(clearmap) menu.show() menu.popup(None, None, None, None, event.button, event.time) return 1
def __refresh_addon_list(self, obj): """ Reloads the addons from the wiki into the list. """ if sys.version_info[0] < 3: from urllib2 import urlopen else: from urllib.request import urlopen from ..utils import ProgressMeter URL = "%s%s" % (URL_WIKISTRING, WIKI_EXTRAPLUGINS_RAWDATA) try: fp = urlopen(URL) except: print("Error: cannot open %s" % URL) return pm = ProgressMeter(_("Refreshing Addon List")) pm.set_pass(header=_("Reading gramps-project.org...")) state = "read" rows = [] row = [] lines = fp.readlines() pm.set_pass(total=len(lines), header=_("Reading gramps-project.org...")) for line in lines: pm.step() if line.startswith("|-") or line.startswith("|}"): if row != []: rows.append(row) state = "row" row = [] elif state == "row": if line.startswith("|"): row.append(line[1:].strip()) else: state = "read" fp.close() rows.sort(key=lambda row: (row[1], row[0])) self.addon_model.clear() # clear the config list: config.get('plugin.addonplugins')[:] = [] pm.set_pass(total=len(rows), header=_("Checking addon...")) for row in rows: pm.step() try: # from wiki: help_name, ptype, image, desc, use, rating, contact, download = row except: continue help_url = _("Unknown Help URL") if help_name.startswith("[[") and help_name.endswith("]]"): name = help_name[2:-2] if "|" in name: help_url, name = name.split("|", 1) elif help_name.startswith("[") and help_name.endswith("]"): name = help_name[1:-1] if " " in name: help_url, name = name.split(" ", 1) else: name = help_name url = _("Unknown URL") if download.startswith("[[") and download.endswith("]]"): # Not directly possible to get the URL: url = download[2:-2] if "|" in url: url, text = url.split("|", 1) # need to get a page that says where it is: fp = urlopen("%s%s%s" % (URL_WIKISTRING, url, "&action=edit&externaledit=true&mode=file")) for line in fp: if line.startswith("URL="): junk, url = line.split("=", 1) break fp.close() elif download.startswith("[") and download.endswith("]"): url = download[1:-1] if " " in url: url, text = url.split(" ", 1) if (url.endswith(".zip") or url.endswith(".ZIP") or url.endswith(".tar.gz") or url.endswith(".tgz")): # Then this is ok: self.addon_model.append(row=[ help_name, name, ptype, image, desc, use, rating, contact, download, url ]) config.get('plugin.addonplugins').append([ help_name, name, ptype, image, desc, use, rating, contact, download, url ]) pm.close() config.save()
def install_addons(self, obj): """ Process all of the selected addons. """ self.update_dialog.hide() model = self.list.model iter = model.get_iter_first() length = 0 while iter: iter = model.iter_next(iter) if iter: length += model.iter_n_children(iter) longop = LongOpStatus( _("Downloading and installing selected addons..."), length, 1, # total, increment-by can_cancel=True) pm = ProgressMonitor(GtkProgressDialog, ("Title", self.window, Gtk.DialogFlags.MODAL)) pm.add_op(longop) count = 0 if not config.get('behavior.do-not-show-previously-seen-updates'): # reset list config.get('behavior.previously-seen-updates')[:] = [] iter = model.get_iter_first() while iter: for rowcnt in range(model.iter_n_children(iter)): child = model.iter_nth_child(iter, rowcnt) row = [model.get_value(child, n) for n in range(6)] if longop.should_cancel(): break elif row[0]: # toggle on load_addon_file(row[4], callback=LOG.debug) count += 1 else: # add to list of previously seen, but not installed if row[5] not in config.get( 'behavior.previously-seen-updates'): config.get('behavior.previously-seen-updates').append( row[5]) longop.heartbeat() pm._get_dlg()._process_events() iter = model.iter_next(iter) if not longop.was_cancelled(): longop.end() if count: OkDialog( _("Done downloading and installing addons"), # translators: leave all/any {...} untranslated "%s %s" % (ngettext("{number_of} addon was installed.", "{number_of} addons were installed.", count).format(number_of=count), _("You need to restart Gramps to see new views.")), self.window) else: OkDialog(_("Done downloading and installing addons"), _("No addons were installed."), self.window) self.close()
COLUMN_CHANGE = 9 COLUMN_TAGS = 10 COLUMN_PRIV = 11 # Data for the Source object COLUMN2_HANDLE = 0 COLUMN2_ID = 1 COLUMN2_TITLE = 2 COLUMN2_AUTHOR = 3 COLUMN2_PUBINFO = 4 COLUMN2_ABBREV = 7 COLUMN2_CHANGE = 8 COLUMN2_TAGS = 11 COLUMN2_PRIV = 12 INVALID_DATE_FORMAT = config.get('preferences.invalid-date-format') #------------------------------------------------------------------------- # # CitationModel # #------------------------------------------------------------------------- class CitationBaseModel: # Fields access when 'data' is a Citation def citation_date(self, data): if data[COLUMN_DATE]: citation = Citation() citation.unserialize(data)
def available_updates(): whattypes = config.get('behavior.check-for-addon-update-types') do_not_show_prev = config.get( 'behavior.do-not-show-previously-seen-addon-updates') prev_seen = config.get('behavior.previously-seen-addon-updates') LOG.debug("Checking for updated addons...") langs = glocale.get_language_list() langs.append("en") # now we have a list of languages to try: f_ptr = None for lang in langs: url = ("%s/listings/addons-%s.txt" % (config.get("behavior.addons-url"), lang)) LOG.debug(" trying: %s", url) try: f_ptr = urlopen_maybe_no_check_cert(url) except: try: url = ("%s/listings/addons-%s.txt" % (config.get("behavior.addons-url"), lang[:2])) f_ptr = urlopen_maybe_no_check_cert(url) except Exception as err: # some error LOG.warning("Failed to open addon metadata for %s %s: %s", lang, url, err) f_ptr = None if f_ptr and f_ptr.getcode() == 200 or f_ptr.file: # ok break try: wfp = open(os.path.join(VERSION_DIR, "new_addons.txt"), mode='wt', encoding='utf-8') except Exception as err: LOG.warning("Failed to open addon status file: %s", err) pmgr = BasePluginManager.get_instance() addon_update_list = [] if f_ptr and f_ptr.getcode() == 200 or f_ptr.file: lines = list(f_ptr.readlines()) count = 0 for line in lines: line = line.decode('utf-8') try: plugin_dict = safe_eval(line) if type(plugin_dict) != type({}): raise TypeError("Line with addon metadata is not " "a dictionary") except: LOG.warning("Skipped a line in the addon listing: " + str(line)) continue if wfp: wfp.write(str(plugin_dict) + '\n') pid = plugin_dict["i"] plugin = pmgr.get_plugin(pid) if plugin: LOG.debug("Comparing %s > %s", version_str_to_tup(plugin_dict["v"], 3), version_str_to_tup(plugin.version, 3)) if (version_str_to_tup(plugin_dict["v"], 3) > version_str_to_tup(plugin.version, 3)): LOG.debug(" Downloading '%s'...", plugin_dict["z"]) if "update" in whattypes: if (not do_not_show_prev or plugin_dict["i"] not in prev_seen): addon_update_list.append( (_("Updated"), "%s/download/%s" % (config.get("behavior.addons-url"), plugin_dict["z"]), plugin_dict)) else: LOG.debug(" '%s' is ok", plugin_dict["n"]) else: LOG.debug(" '%s' is not installed", plugin_dict["n"]) if "new" in whattypes: if (not do_not_show_prev or plugin_dict["i"] not in prev_seen): addon_update_list.append( (_("updates|New"), "%s/download/%s" % (config.get("behavior.addons-url"), plugin_dict["z"]), plugin_dict)) config.set("behavior.last-check-for-addon-updates", datetime.date.today().strftime("%Y/%m/%d")) count += 1 if f_ptr: f_ptr.close() if wfp: wfp.close() else: LOG.debug("Checking Addons Failed") LOG.debug("Done checking!") return addon_update_list
# #------------------------------------------------------------------------- COLUMN_ID = 1 COLUMN_GENDER = 2 COLUMN_NAME = 3 COLUMN_DEATH = 5 COLUMN_BIRTH = 6 COLUMN_EVENT = 7 COLUMN_FAMILY = 8 COLUMN_PARENT = 9 COLUMN_NOTES = 16 COLUMN_CHANGE = 17 COLUMN_TAGS = 18 COLUMN_PRIV = 19 invalid_date_format = config.get('preferences.invalid-date-format') #------------------------------------------------------------------------- # # PeopleBaseModel # #------------------------------------------------------------------------- class PeopleBaseModel(BaseModel): """ Basic Model interface to handle the PersonViews """ _GENDER = [_('female'), _('male'), _('unknown')] def __init__(self, db): """
def color_graph_box(alive=False, gender=Person.MALE): """ :return: based on the config the color for graph boxes in hex If gender is None, an empty box is assumed :rtype: tuple (hex color fill, hex color border) """ scheme = config.get('colors.scheme') if gender == Person.MALE: if alive: return (config.get('colors.male-alive')[scheme], config.get('colors.border-male-alive')[scheme]) else: return (config.get('colors.male-dead')[scheme], config.get('colors.border-male-dead')[scheme]) elif gender == Person.FEMALE: if alive: return (config.get('colors.female-alive')[scheme], config.get('colors.border-female-alive')[scheme]) else: return (config.get('colors.female-dead')[scheme], config.get('colors.border-female-dead')[scheme]) elif gender == Person.UNKNOWN: if alive: return (config.get('colors.unknown-alive')[scheme], config.get('colors.border-unknown-alive')[scheme]) else: return (config.get('colors.unknown-dead')[scheme], config.get('colors.border-unknown-dead')[scheme]) #empty box, no gender return ('#d2d6ce', '#000000')
def _setup_fields(self): self.date_field = MonitoredDate(self.top.get_object("date_entry"), self.top.get_object("date_stat"), self.source_ref.get_date_object(), self.uistate, self.track, self.db.readonly) if not config.get('preferences.place-auto'): self.top.get_object("place_title").show() self.top.get_object("place_title_label").show() self.title = MonitoredEntry(self.top.get_object("place_title"), self.source.set_title, self.source.get_title, self.db.readonly) self.name = MonitoredEntry(self.top.get_object("name_entry"), self.source.get_name().set_value, self.source.get_name().get_value, self.db.readonly, changed=self.name_changed) edit_button = self.top.get_object("name_button") edit_button.connect('clicked', self.edit_place_name) self.gid = MonitoredEntry(self.top.get_object("gid"), self.source.set_gramps_id, self.source.get_gramps_id, self.db.readonly) self.tags = MonitoredTagList(self.top.get_object("tag_label"), self.top.get_object("tag_button"), self.source.set_tag_list, self.source.get_tag_list, self.db, self.uistate, self.track, self.db.readonly) self.privacy = PrivacyButton(self.top.get_object("private"), self.source, self.db.readonly) custom_place_types = sorted(self.db.get_place_types(), key=lambda s: s.lower()) self.place_type = MonitoredDataType(self.top.get_object("place_type"), self.source.set_type, self.source.get_type, self.db.readonly, custom_place_types) self.code = MonitoredEntry(self.top.get_object("code_entry"), self.source.set_code, self.source.get_code, self.db.readonly) entry = self.top.get_object("lon_entry") entry.set_ltr_mode() self.longitude = MonitoredEntry(entry, self.source.set_longitude, self.source.get_longitude, self.db.readonly) self.longitude.connect("validate", self._validate_coordinate, "lon") #force validation now with initial entry entry.validate(force=True) entry = self.top.get_object("lat_entry") entry.set_ltr_mode() self.latitude = MonitoredEntry(entry, self.source.set_latitude, self.source.get_latitude, self.db.readonly) self.latitude.connect("validate", self._validate_coordinate, "lat") #force validation now with initial entry entry.validate(force=True) entry = self.top.get_object("latlon_entry") entry.set_ltr_mode() self.latlon = MonitoredEntry(entry, self.set_latlongitude, self.get_latlongitude, self.db.readonly)
from gi import Repository from gramps.gen.config import config from gramps.gen.const import GRAMPS_LOCALE as glocale from gramps.gen.plug._pluginreg import register, VIEW, STABLE #, END, START _ = glocale.translation.gettext # Attempting to import goocanvas gives an error dialog if goocanvas is not # available so test first and log just a warning to the console instead. try: config.get('interface.ignore-goocanvas') except: config.register('interface.ignore-goocanvas', False) GOOCANVAS = False REPOSITORY = Repository.get_default() if REPOSITORY.enumerate_versions("GooCanvas"): try: # current goocanvas support GTK3 import gi gi.require_version('GooCanvas', '2.0') from gi.repository import GooCanvas as goocanvas GOOCANVAS = True except: pass if not GOOCANVAS: from gramps.gen.config import config if not config.get('interface.ignore-goocanvas'): from gramps.gen.constfunc import has_display if has_display():
def get_default_directory(self): """Get the name of the directory to which the target dialog box should default. This value can be set in the preferences panel.""" return config.get('paths.report-directory')
def parse_args(self): """ Fill in lists with open, exports, imports, and actions options. Any errors are added to self.errors """ try: # Convert arguments to unicode, otherwise getopt will not work # if a non latin character is used as an option (by mistake). # getopt will try to treat the first char in an utf-8 sequence. Example: # -Ärik is '-\xc3\x84rik' and getopt will respond : # option -\xc3 not recognized for arg in range(len(self.args) - 1): self.args[arg + 1] = conv_to_unicode(self.args[arg + 1], sys.stdin.encoding) options, leftargs = getopt.getopt(self.args[1:], SHORTOPTS, LONGOPTS) except getopt.GetoptError as msg: # Extract the arguments in the list. # The % operator replaces the list elements with repr() of the list elemements # which is OK for latin characters, but not for non latin characters in list elements cliargs = "[ " for arg in range(len(self.args) - 1): cliargs += self.args[arg + 1] + " " cliargs += "]" # Must first do str() of the msg object. msg = str(msg) self.errors += [ (_('Error parsing the arguments'), msg + '\n' + _("Error parsing the arguments: %s \n" "Type gramps --help for an overview of commands, or " "read the manual pages.") % cliargs) ] return if leftargs: # if there were an argument without option, # use it as a file to open and return self.open_gui = leftargs[0] print(_("Trying to open: %s ...") % leftargs[0], file=sys.stderr) #see if force open is on for opt_ix in range(len(options)): option, value = options[opt_ix] if option in ('-u', '--force-unlock'): self.force_unlock = True break return # Go over all given option and place them into appropriate lists cleandbg = [] need_to_quit = False for opt_ix in range(len(options)): option, value = options[opt_ix] if option in ['-O', '--open']: self.open = value elif option in ['-C', '--create']: self.create = value elif option in ['-i', '--import']: family_tree_format = None if opt_ix < len(options) - 1 \ and options[opt_ix + 1][0] in ( '-f', '--format'): family_tree_format = options[opt_ix + 1][1] self.imports.append((value, family_tree_format)) elif option in ['-e', '--export']: family_tree_format = None if opt_ix < len(options) - 1 \ and options[opt_ix + 1][0] in ( '-f', '--format'): family_tree_format = options[opt_ix + 1][1] self.exports.append((value, family_tree_format)) elif option in ['-a', '--action']: action = value if action not in ('report', 'tool', 'book'): print(_("Unknown action: %s. Ignoring.") % action, file=sys.stderr) continue options_str = "" if opt_ix < len(options)-1 \ and options[opt_ix+1][0] in ( '-p', '--options' ): options_str = options[opt_ix + 1][1] self.actions.append((action, options_str)) elif option in ['-d', '--debug']: print(_('setup debugging'), value, file=sys.stderr) logger = logging.getLogger(value) logger.setLevel(logging.DEBUG) cleandbg += [opt_ix] elif option in ['-l']: self.list = True elif option in ['-L']: self.list_more = True elif option in ['-t']: self.list_table = True elif option in ['-s', '--show']: print(_("Gramps config settings from %s:") % config.filename) for section in config.data: for setting in config.data[section]: print("%s.%s=%s" % (section, setting, repr(config.data[section][setting]))) print() sys.exit(0) elif option in ['-c', '--config']: setting_name = value set_value = False if setting_name: if ":" in setting_name: setting_name, new_value = setting_name.split(":", 1) set_value = True if config.has_default(setting_name): setting_value = config.get(setting_name) print(_("Current Gramps config setting: " "%(name)s:%(value)s") % { 'name': setting_name, 'value': repr(setting_value) }, file=sys.stderr) if set_value: # does a user want the default config value? if new_value in ("DEFAULT", _("DEFAULT")): new_value = config.get_default(setting_name) else: converter = get_type_converter(setting_value) new_value = converter(new_value) config.set(setting_name, new_value) # translators: indent "New" to match "Current" print(_(" New Gramps config setting: " "%(name)s:%(value)s") % { 'name': setting_name, 'value': repr(config.get(setting_name)) }, file=sys.stderr) else: need_to_quit = True else: print(_("Gramps: no such config setting: '%s'") % setting_name, file=sys.stderr) need_to_quit = True cleandbg += [opt_ix] elif option in ['-h', '-?', '--help']: self.help = True elif option in ['-u', '--force-unlock']: self.force_unlock = True elif option in ['--usage']: self.usage = True elif option in ['--qml']: self.runqml = True elif option in ['-y', '--yes']: self.auto_accept = True elif option in ['-q', '--quiet']: self.quiet = True #clean options list cleandbg.reverse() for ind in cleandbg: del options[ind] if len(options) > 0 and self.open is None and self.imports == [] \ and not (self.list or self.list_more or self.list_table or self.help or self.runqml): # Extract and convert to unicode the arguments in the list. # The % operator replaces the list elements with repr() of # the list elements, which is OK for latin characters # but not for non-latin characters in list elements cliargs = "[ " for arg in range(len(self.args) - 1): cliargs += conv_to_unicode(self.args[arg + 1], sys.stdin.encoding) + ' ' cliargs += "]" self.errors += [(_('Error parsing the arguments'), _("Error parsing the arguments: %s \n" "To use in the command-line mode, supply at " "least one input file to process.") % cliargs)] if need_to_quit: sys.exit(0)
def _createpersonmarkers(self, dbstate, person, comment, fam_id): """ Create all markers for the specified person. """ self.cal = config.get('preferences.calendar-format-report') latitude = longitude = "" if person: # For each event, if we have a place, set a marker. for event_ref in person.get_event_ref_list(): if not event_ref: continue role = event_ref.get_role() event = dbstate.db.get_event_from_handle(event_ref.ref) eyear = event.get_date_object().to_calendar( self.cal).get_year() place_handle = event.get_place_handle() if place_handle: place = dbstate.db.get_place_from_handle(place_handle) if place: longitude = place.get_longitude() latitude = place.get_latitude() latitude, longitude = conv_lat_lon( latitude, longitude, "D.D8") descr = _pd.display(dbstate.db, place) evt = EventType(event.get_type()) descr1 = _("%(eventtype)s : %(name)s") % { 'eventtype': evt, 'name': _nd.display(person) } # place.get_longitude and place.get_latitude return # one string. We have coordinates when the two values # contains non null string. if longitude and latitude: if not self._present_in_places_list( 2, str(descr1 + descr + str(evt))): self._append_to_places_list( descr, str(descr1 + descr + str(evt)), _nd.display(person), latitude, longitude, role, eyear, event.get_type(), person.gramps_id, place.gramps_id, event.gramps_id, fam_id) else: self._append_to_places_without_coord( place.gramps_id, descr) family_list = person.get_family_handle_list() for family_hdl in family_list: family = self.dbstate.db.get_family_from_handle(family_hdl) if family is not None: for event_ref in family.get_event_ref_list(): if event_ref: event = dbstate.db.get_event_from_handle( event_ref.ref) role = event_ref.get_role() if event.get_place_handle(): place_handle = event.get_place_handle() if place_handle: place = dbstate.db.get_place_from_handle( place_handle) if place: longitude = place.get_longitude() latitude = place.get_latitude() (latitude, longitude) = conv_lat_lon( latitude, longitude, "D.D8") descr = _pd.display(dbstate.db, place) evt = EventType(event.get_type()) (father_name, mother_name ) = self._get_father_and_mother_name( event) descr1 = "%s : %s - " % (evt, father_name) descr1 = "%s%s" % (descr1, mother_name) eyear = event.get_date_object( ).to_calendar(self.cal).get_year() if longitude and latitude: if not self._present_in_places_list( 2, str(descr1 + descr + str(evt))): self._append_to_places_list( descr, str(descr1 + descr + str(evt)), _nd.display(person), latitude, longitude, role, eyear, event.get_type(), person.gramps_id, place.gramps_id, event.gramps_id, family.gramps_id) else: self._append_to_places_without_coord( place.gramps_id, descr)
def ParseXML(self, tree, filename): """ Parse the validated .gramps """ root = tree.getroot() # GtkTextView ; buffer limitation ... self.text.set_text(_('Parsing file...')) #LOG.info(etree.tostring(root, pretty_print=True)) # namespace issues ! namespace = root.nsmap surname_tag = etree.SubElement(root, NAMESPACE + 'surname') pname_tag = etree.SubElement(root, NAMESPACE + 'pname') private_surname = config.get('preferences.private-surname-text') private_record = config.get('preferences.private-record-text') # variable expr = "//*[local-name() = $name]" # count function # float and seems to also count the parent tag: name[0] ! count_elements = etree.XPath("count(//*[local-name() = $name])") # textual children strings function desc = etree.XPath('descendant-or-self::text()') # TODO: cleanup ! # quick but not a nice method ... msg = [] #tags = [] places = [] sources = [] surnames = [] timestamp = [] thumbs = [] LOG.info('start iteration') for one in root.iter(): #(tag, item) = one.tag, one.items() #print(tag, item) for two in one.iter(): #tags.append(two.tag) msg.append(two.items()) if two.tag == NAMESPACE + 'mediapath': mediapath = two.text else: mediapath = '' # privacy if two.get('priv'): # XML: optional text = private_record else: text = "" # search ptitle and time log for three in two.iter(): # timestamp if two.get('change'): timestamp.append(two.get('change')) # with namespace ... #print(desc(three)) (tag, items) = three.tag, three.items() if three.tag == NAMESPACE + 'ptitle': if text != private_record: text = str(three.text) if text not in places: places.append(text) # temp display if three.tag == NAMESPACE + 'pname': if text != private_record: text = str(three.attrib.get('value')) translation = str(three.attrib.get('lang')) if translation == 'None': translation = xml_lang()[0:2] text = text + _(' - (? or %(lang)s)') % { 'lang': translation } else: text = text + _(' - (%(lang)s)') % { 'lang': translation } if text not in places: places.append(text) # temp display if three.tag == NAMESPACE + 'stitle' and three.text not in sources: # need to add an exception if not three.text: three.text = "" sources.append(three.text) if three.tag == NAMESPACE + 'file' and three.items( ) not in thumbs: thumbs.append(three.items()) # search last name for four in three.iter(): # with namespace ... if four.tag == NAMESPACE + 'surname' and four.text != None: if text != private_record: surnames.append(four.text) else: surnames.append(private_surname) LOG.info('end of loops') # All tags #print(tags) # keys, values; no textual data; # root child level items as keys for revision control ??? #revision = msg #print(revision) log = msg[2] if not log: ErrorDialog( _('Missing header'), _('Not a valid .gramps.\n' 'Cannot run the gramplet...\n' 'Please, try to use a .gramps\n' 'generated by Gramps 5.1.')) LOG.error('header missing') return # dirty XML write method ... # need to create a fake entry ! if int(count_elements(root, name='surname')) > 1: nb_surnames = int(count_elements(root, name='surname')) else: nb_surnames = surnames = [_('0')] if int(count_elements(root, name='pname')) > 1: nb_pnames = int(count_elements(root, name='pname')) else: nb_pnames = places = [_('0')] if int(count_elements(root, name='note')) > 1: nb_notes = int(count_elements(root, name='note')) else: nb_notes = _('0') if int(count_elements(root, name='stitle')) > 1: nb_sources = int(count_elements(root, name='stitle')) else: nb_sources = _('0') # time logs timestamp.sort() start = timestamp[0] end = timestamp[-1] timestamp = [] first = epoch(start) last = epoch(end) header = _('File parsed with') + ' LXML' + str(LXML_VERSION) + '\n\n' [(k1, v1), (k2, v2)] = log file_info = _('File was generated on ') + v1 + '\n\t' + _( ' by Gramps ') + v2 + '\n\n' period = _('Period: ') + first + ' => ' + last + '\n\n' su = '\t' + str(nb_surnames) + '\t' + _( ' entries for surname(s); no frequency yet') + '\n' p = '\t' + str(nb_pnames) + '\t' + _(' entries for place(s)') + '\n' n = '\t' + str(nb_notes) + '\t' + _(' note(s)') + '\n' so = '\t' + str(nb_sources) + '\t' + _(' source(s)') + '\n\n' counters = su + p + n + so libs = 'LIBXML' + str(LIBXML_VERSION) + '\tLIBXSLT' + str( LIBXSLT_VERSION) # GtkTextView self.text.set_text(header + file_info + period + counters + libs) LOG.info('### NEW FILES ###') LOG.info('content parsed and copied') self.WriteXML(log, first, last, surnames, places, sources) self.PrintMedia(thumbs, mediapath) images = os.path.join(USER_PLUGINS, 'lxml', _('Gallery.html')) sys.stdout.write( _('2. Has generated a media index on "%(file)s".\n') % {'file': images}) self.WriteBackXML(filename, root, surnames, places, sources) sys.stdout.write( _('3. Has written entries into "%(file)s".\n') % {'file': filename})
def get_info(self, person_handle, generation): """ get info about a person """ person = self.database.get_person_from_handle(person_handle) p_pn = person.get_primary_name() self.calendar = config.get('preferences.calendar-format-report') birth = get_birth_or_fallback(self.database, person) bth = "" if birth: bth = birth.get_date_object() bth = str(bth.to_calendar(self.calendar).get_year()) if bth == 0: bth = "" elif birth.get_type() != EventType.BIRTH: bth += '*' death = get_death_or_fallback(self.database, person) dth = "" if death: dth = death.get_date_object() dth = str(dth.to_calendar(self.calendar).get_year()) if dth == 0: dth = "" elif death.get_type() != EventType.DEATH: dth += '*' if bth and dth: val = "%s - %s" % (str(bth), str(dth)) elif bth: val = "* %s" % (str(bth)) elif dth: val = "+ %s" % (str(dth)) else: val = "" if generation > 7: if (p_pn.get_first_name() != "") and (p_pn.get_surname() != ""): name = p_pn.get_first_name() + " " + p_pn.get_surname() else: name = p_pn.get_first_name() + p_pn.get_surname() if (name != "") and (val != ""): string = name + ", " + val else: string = name + val return [string] elif generation == 7: if (p_pn.get_first_name() != "") and (p_pn.get_surname() != ""): name = p_pn.get_first_name() + " " + p_pn.get_surname() else: name = p_pn.get_first_name() + p_pn.get_surname() if self.circle == FULL_CIRCLE: return [name, val] elif self.circle == HALF_CIRCLE: return [name, val] else: if (name != "") and (val != ""): string = name + ", " + val else: string = name + val return [string] elif generation == 6: if self.circle == FULL_CIRCLE: return [p_pn.get_first_name(), p_pn.get_surname(), val] elif self.circle == HALF_CIRCLE: return [p_pn.get_first_name(), p_pn.get_surname(), val] else: if (p_pn.get_first_name() != "") and (p_pn.get_surname() != ""): name = p_pn.get_first_name() + " " + p_pn.get_surname() else: name = p_pn.get_first_name() + p_pn.get_surname() return [name, val] else: return [p_pn.get_first_name(), p_pn.get_surname(), val]
def __init__(self, dbstate, uistate, plugins, callback=None): """ A dialog to import a file into Gramps """ self.dbstate = dbstate self.uistate = uistate self.plugins = plugins self.debug = True self.title = _("Plugin installation from a ZIP file") ManagedWindow.__init__(self, uistate, [], self.__class__, modal=True) # the choose_plugin_name_dialog.run() below makes it modal, so any change to # the previous line's "modal" would require that line to be changed import_dialog = Gtk.FileChooserDialog( title='', transient_for=self.uistate.window, action=Gtk.FileChooserAction.OPEN) import_dialog.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL, _('Open'), Gtk.ResponseType.OK) self.set_window(import_dialog, None, self.title) self.setup_configs('interface.zipimportfiledialog', 780, 630) import_dialog.set_local_only(False) # Always add automatic (match all files) filter add_supported_files_filter(import_dialog) # .zip and .tgz add_tgz_files_filter(import_dialog) # *.tgz add_zip_files_filter(import_dialog) # *.zip add_all_files_filter(import_dialog) # * import_dialog.set_current_folder(config.get('paths.recent-import-dir')) while True: # the choose_plugin_name_dialog.run() makes it modal, so any change to that # line would require the ManagedWindow.__init__ to be changed also response = import_dialog.run() if response == Gtk.ResponseType.CANCEL: break elif response == Gtk.ResponseType.DELETE_EVENT: # ??? return elif response == Gtk.ResponseType.OK: filename = import_dialog.get_filename() #if self.check_errors(filename): # # displays errors if any # continue (the_path, the_file) = os.path.split(filename) config.set('paths.recent-import-dir', the_path) if not self.extension_ok(the_file): ErrorDialog(_("Error"), _("Could not open file: %s") % the_file + ": " + _('File is not a .zip or .tgz file.\n\n'), parent=self.uistate.window) continue try: plugindata = self.get_plugin_data(filename) except Exception as e: traceback.print_exc() ErrorDialog(_("Error"), _("Could not process file %s") % filename + ": " + str(e), parent=self.uistate.window) continue plugin_info = None for plugin_id in plugindata: plugin_info = plugindata[plugin_id] plugin_name = plugin_info['name'] if plugin_id in self.plugins: # print(plugin_id,"already exists") p = self.plugins[plugin_id] old_plugin = p if self.debug: ptypestr = PTYPE_STR[p.ptype] print(" type:", ptypestr) print(" name:", p.name) print(" desc:", p.description) print(" path:", p.fpath) print(" file:", p.fname) print(" version:", p.version) print() print("This plugin:") print(plugin_info) else: old_plugin = None if not plugin_info: # some error, possibly invalid gpr file? continue self.backup_zipfname = None self.gramps_view_installed = False try: dirname = self.install_plugin_dialog( filename, plugin_info, old_plugin) except Exception as e: traceback.print_exc() ErrorDialog(_("Error"), _("Could not process file %s") % filename + ": " + str(e), parent=self.uistate.window) continue msg = _("Plugin '%s' installed in\n %s") % (plugin_name, dirname) if self.backup_zipfname: msg += _("\nOld version saved in\n %s" ) % self.backup_zipfname if self.gramps_view_installed: msg += _("\n\nRestart Gramps.") if dirname: OkDialog(_("Installed"), msg, parent=self.uistate.window) break self.close()
def _createmap(self, active): """ Create all markers for each people's event in the database which has a lat/lon. @param: active is mandatory but unused in this view. Fix : 10088 """ dbstate = self.dbstate self.cal = config.get('preferences.calendar-format-report') self.place_list = [] self.place_without_coordinates = [] self.places_found = [] self.minlat = self.maxlat = self.minlon = self.maxlon = 0.0 self.minyear = 9999 self.maxyear = 0 latitude = "" longitude = "" self.nbplaces = 0 self.nbmarkers = 0 self.message_layer.clear_messages() self.message_layer.set_font_attributes(None, None, None) self.kml_layer.clear() person_handle = self.uistate.get_active('Person') person = None if person_handle: person = dbstate.db.get_person_from_handle(person_handle) if person is not None: # For each event, if we have a place, set a marker. self.load_kml_files(person) self.message_layer.add_message( _("Person places for %s") % _nd.display(person)) for event_ref in person.get_event_ref_list(): if not event_ref: continue event = dbstate.db.get_event_from_handle(event_ref.ref) self.load_kml_files(event) role = event_ref.get_role() eyear = str( "%04d" % event.get_date_object().to_calendar(self.cal).get_year()) + \ str("%02d" % event.get_date_object().to_calendar(self.cal).get_month()) + \ str("%02d" % event.get_date_object().to_calendar(self.cal).get_day()) place_handle = event.get_place_handle() if place_handle: place = dbstate.db.get_place_from_handle(place_handle) if place: longitude = place.get_longitude() latitude = place.get_latitude() latitude, longitude = conv_lat_lon( latitude, longitude, "D.D8") descr = _pd.display(dbstate.db, place) evt = EventType(event.get_type()) descr1 = _("%(eventtype)s : %(name)s") % { 'eventtype': evt, 'name': _nd.display(person) } self.load_kml_files(place) # place.get_longitude and place.get_latitude return # one string. We have coordinates when the two values # contains non null string. if longitude and latitude: self._append_to_places_list( descr, evt, _nd.display(person), latitude, longitude, descr1, eyear, event.get_type(), person.gramps_id, place.gramps_id, event.gramps_id, role) else: self._append_to_places_without_coord( place.gramps_id, descr) family_list = person.get_family_handle_list() for family_hdl in family_list: family = self.dbstate.db.get_family_from_handle(family_hdl) if family is not None: fhandle = family_list[0] # first is primary fam = dbstate.db.get_family_from_handle(fhandle) father = mother = None handle = fam.get_father_handle() if handle: father = dbstate.db.get_person_from_handle(handle) descr1 = " - " if father: descr1 = "%s - " % _nd.display(father) handle = fam.get_mother_handle() if handle: mother = dbstate.db.get_person_from_handle(handle) if mother: descr1 = "%s%s" % (descr1, _nd.display(mother)) for event_ref in family.get_event_ref_list(): if event_ref: event = dbstate.db.get_event_from_handle( event_ref.ref) self.load_kml_files(event) role = event_ref.get_role() if event.get_place_handle(): place_handle = event.get_place_handle() if place_handle: place = dbstate.db.get_place_from_handle( place_handle) if place: longitude = place.get_longitude() latitude = place.get_latitude() (latitude, longitude) = conv_lat_lon( latitude, longitude, "D.D8") descr = _pd.display(dbstate.db, place) evt = EventType(event.get_type()) eyear = str( "%04d" % event.get_date_object().to_calendar(self.cal).get_year()) + \ str("%02d" % event.get_date_object().to_calendar(self.cal).get_month()) + \ str("%02d" % event.get_date_object().to_calendar(self.cal).get_day()) self.load_kml_files(place) if longitude and latitude: self._append_to_places_list( descr, evt, _nd.display(person), latitude, longitude, descr1, eyear, event.get_type(), person.gramps_id, place.gramps_id, event.gramps_id, role) else: self._append_to_places_without_coord( place.gramps_id, descr) self.sort = sorted(self.place_list, key=operator.itemgetter(6)) self._create_markers()
GRAMPLET, id="Metadata Viewer", name=_("Image Metadata"), description=_("Gramplet showing metadata for a media object"), version="1.0.0", gramps_target_version=MODULE_VERSION, status=STABLE, fname="metadataviewer.py", height=200, gramplet='MetadataViewer', gramplet_title=_("Image Metadata"), navtypes=["Media"], ) else: from gramps.gen.config import config if not config.get('interface.ignore-gexiv2'): from gramps.gen.constfunc import has_display if has_display(): from gramps.gui.dialog import MessageHideDialog from gramps.gen.const import URL_WIKISTRING gexiv2_dict = { 'gramps_wiki_build_gexiv2_url': URL_WIKISTRING + "GEPS_029:_GTK3-GObject_introspection" "_Conversion#GExiv2_for_Image_metadata" } title = _("GExiv2 module not loaded.") message = _("Image metadata functionality will not be available.\n" "To build it for Gramps see " "%(gramps_wiki_build_gexiv2_url)s" % gexiv2_dict) if uistate: MessageHideDialog(title,
def __create_gui(self): """ __create_gui """ vbox = Gtk.VBox(orientation=Gtk.Orientation.VERTICAL) vbox.set_spacing(4) grid = Gtk.Grid(column_spacing=10, row_spacing=10) grid.set_margin_top(20) grid.set_margin_left(20) label_url = Gtk.Label(_("Isotammi URL")) grid.attach(label_url, 0, 0, 1, 1) self.entry_apiurl = Gtk.Entry() self.entry_apiurl.set_width_chars(40) grid.attach(self.entry_apiurl, 1, 0, 1, 1) label_apikey = Gtk.Label(_("API Key")) grid.attach(label_apikey, 0, 1, 1, 1) self.entry_apikey = Gtk.Entry() grid.attach(self.entry_apikey, 1, 1, 1, 1) label = Gtk.Label(_("Addon source")) #abel.set_markup("<b>{}</b>".format(_("Select the source for installing add-ons"))) label.set_halign(Gtk.Align.START) label.set_line_wrap(True) grid.attach(label, 0, 2, 1, 1) self.addons_url = config.get("behavior.addons-url") group = None group = Gtk.RadioButton.new_with_label_from_widget(group, _("Default")) group.connect("toggled", self.cb_select, DEFAULT_URL) grid.attach(group, left=1, top=2, width=1, height=1) if self.addons_url == DEFAULT_URL: group.set_active(True) rownum = 1 group = Gtk.RadioButton.new_with_label_from_widget( group, _("Isotammi")) group.connect("toggled", self.cb_select, ISOTAMMI_URL) if self.addons_url == ISOTAMMI_URL: group.set_active(True) grid.attach(group, 1, 3, 1, 1) btnbox = Gtk.ButtonBox() btn_save = Gtk.Button(_("Save")) btn_save.connect("clicked", self.save) btnbox.add(btn_save) btn = Gtk.Button(_("Gramps preferences")) btn.connect( "clicked", lambda obj: GrampsPreferences(self.gui.uistate, self.dbstate).show( )) btnbox.add(btn) vbox.pack_start(grid, False, True, 0) #vbox.pack_start(label, False, True, 0) #vbox.pack_start(grid, False, True, 0) vbox.pack_start(btnbox, False, True, 0) apikey = get_apikey() self.entry_apikey.set_text(apikey) apiurl = get_apiurl() self.entry_apiurl.set_text(apiurl) vbox.show_all() return vbox
def import_new_db(self, filename, user): """ Attempt to import the provided file into a new database. A new database will only be created if an appropriate importer was found. :param filename: a fully-qualified path, filename, and extension to open. :param user: a :class:`.cli.user.User` or :class:`.gui.user.User` instance for managing user interaction. :returns: A tuple of (new_path, name) for the new database or (None, None) if no import was performed. """ pmgr = BasePluginManager.get_instance() # check to see if it isn't a filename directly: if not os.path.isfile(filename): # Allow URL names here; make temp file if necessary url = urlparse(filename) if url.scheme != "": if url.scheme == "file": filename = url2pathname(filename[7:]) else: url_fp = urlopen(filename) # open URL # make a temp local file: ext = os.path.splitext(url.path)[1] fd, filename = tempfile.mkstemp(suffix=ext) temp_fp = os.fdopen(fd, "w") # read from URL: data = url_fp.read() # write locally: temp_fp.write(data) url_fp.close() temp_fp.close() (name, ext) = os.path.splitext(os.path.basename(filename)) format = ext[1:].lower() for plugin in pmgr.get_import_plugins(): if format == plugin.get_extension(): dbid = config.get('database.backend') new_path, name = self._create_new_db(name, dbid=dbid, edit_entry=False) # Create a new database self.__start_cursor(_("Importing data...")) dbase = make_database(dbid) dbase.load(new_path, user.callback) import_function = plugin.get_import_function() import_function(dbase, filename, user) # finish up self.__end_cursor() dbase.close() return new_path, name return None, None
# Gramps classes # #------------------------------------------------------------------------- from ...widgets.undoablebuffer import UndoableBuffer from gramps.gen.lib import EventRoleType from gramps.gen.datehandler import get_date, get_date_valid from gramps.gen.config import config from gramps.gen.utils.db import get_participant_from_event from gramps.gen.display.place import displayer as place_displayer #------------------------------------------------------------------------- # # Globals # #------------------------------------------------------------------------- invalid_date_format = config.get('preferences.invalid-date-format') age_precision = config.get('preferences.age-display-precision') #------------------------------------------------------------------------- # # EventRefModel # #------------------------------------------------------------------------- class EventRefModel(Gtk.TreeStore): #index of the working group _ROOTINDEX = 0 _GROUPSTRING = _('%(groupname)s - %(groupnumber)d') COL_DESCR = (0, str) COL_TYPE = (1, str) COL_GID = (2, str)
def _createmap(self,place_x): """ Create all markers for each people's event in the database which has a lat/lon. """ dbstate = self.dbstate self.cal = config.get('preferences.calendar-format-report') self.place_list = [] self.place_without_coordinates = [] self.minlat = 0.0 self.maxlat = 0.0 self.minlon = 0.0 self.maxlon = 0.0 self.minyear = 9999 self.maxyear = 0 self.without = 0 latitude = "" longitude = "" self.nbmarkers = 0 self.nbplaces = 0 self.message_layer.clear_messages() self.message_layer.clear_font_attributes() self.no_show_places_in_status_bar = False # base "villes de france" : 38101 places : # createmap : 8'50"; create_markers : 1'23" # base "villes de france" : 38101 places : # createmap : 8'50"; create_markers : 0'07" with pixbuf optimization # base "villes de france" : 38101 places : # gramps 3.4 python 2.7 ( draw_markers are estimated when we move the map) # 38101 places : createmap : 04'32"; create_markers : 0'04"; draw markers : N/A :: 0'03" # 65598 places : createmap : 10'03"; create_markers : 0'07"; draw markers : N/A :: 0'05" # gramps 3.5 python 2.7 new marker layer # 38101 places : createmap : 03'09"; create_markers : 0'01"; draw markers : 0'04" # 65598 places : createmap : 08'48"; create_markers : 0'01"; draw markers : 0'07" _LOG.debug("%s" % time.strftime("start createmap : " "%a %d %b %Y %H:%M:%S", time.gmtime())) if self.generic_filter: place_list = self.generic_filter.apply(dbstate.db) for place_handle in place_list: place = dbstate.db.get_place_from_handle(place_handle) self._create_one_place(place) else: try: places_handle = dbstate.db.get_place_handles() except: return for place_hdl in places_handle: place = dbstate.db.get_place_from_handle(place_hdl) self._create_one_place(place) if place_x: place = dbstate.db.get_place_from_handle(place_x) if ( place.get_latitude() != "" and place.get_longitude() != "" ): self.osm.set_center_and_zoom(float(place.get_latitude()), float(place.get_longitude()), int(config.get("geography.zoom"))) _LOG.debug(" stop createmap.") _LOG.debug("%s" % time.strftime("begin sort : " "%a %d %b %Y %H:%M:%S", time.gmtime())) self.sort = sorted(self.place_list, key=operator.itemgetter(0) ) _LOG.debug("%s" % time.strftime(" end sort : " "%a %d %b %Y %H:%M:%S", time.gmtime())) if self.nbmarkers > 500 : # performance issue. Is it the good value ? self.message_layer.add_message( _("The place name in the status bar is disabled.")) self.no_show_places_in_status_bar = True if self.nbplaces >= self._config.get("geography.max_places") : self.message_layer.set_font_attributes(None,None,"red") self.message_layer.add_message( _("The maximum number of places is reached (%d)." % self._config.get("geography.max_places"))) self.message_layer.add_message( _("Some information are missing.")) self.message_layer.add_message( _("Please, use filtering to reduce this number.")) self.message_layer.add_message( _("You can modify this value in the geography option.")) self.message_layer.add_message( _("In this case, it may take time to show all markers.")) self._create_markers()