def open_file_with_default_application(path, uistate): """ Launch a program to open an arbitrary file. The file will be opened using whatever program is configured on the host as the default program for that type of file. :param file_path: The path to the file to be opened. Example: "c:\\foo.txt" :type file_path: string :return: nothing """ norm_path = os.path.normpath(path) if not os.path.exists(norm_path): display_error_dialog(0, _("File %s does not exist") % norm_path, uistate) return if win(): try: os.startfile(norm_path) except WindowsError as msg: display_error_dialog(0, str(msg), uistate) return if not norm_path.startswith('file://'): norm_path = 'file://' + norm_path try: Gio.AppInfo.launch_default_for_uri(norm_path) except GLib.Error as error: display_error_dialog(0, str(error), uistate)
def __init__(self, text): Gtk.Label.__init__(self, label=text) self.set_halign(Gtk.Align.START) if win(): pangoFont = Pango.FontDescription('Arial') self.override_font(pangoFont) self.show()
def __init__(self, text): GObject.GObject.__init__(self, label=text) self.set_alignment(0, 0.5) if win(): pangoFont = Pango.FontDescription('Arial') self.override_font(pangoFont) self.show()
def match(self, handle, db): if win(): return self.invert ^ (self.func(handle).upper().find(str( self.text)) != -1) else: return self.invert ^ (self.func(handle).upper().find(self.text) != -1)
def on_print(self, action=None): self.print_op = Gtk.PrintOperation() self.print_op.connect("begin_print", self.begin_print) self.print_op.connect("draw_page", self.draw_page) page_setup = Gtk.PageSetup() if self.print_settings is None: self.print_settings = Gtk.PrintSettings() page_setup = Gtk.print_run_page_setup_dialog(None, page_setup, self.print_settings) paper_size_used = page_setup.get_paper_size() self.format = paper_size_used.get_name() self.print_settings.set_paper_size(paper_size_used) self.print_settings.set_orientation(page_setup.get_orientation()) self.print_op.set_print_settings(self.print_settings) if page_setup.get_orientation() == Gtk.PageOrientation.PORTRAIT: self.height_used = int(paper_size_used.get_height(Gtk.Unit.POINTS)) self.width_used = int(paper_size_used.get_width(Gtk.Unit.POINTS)) else: self.height_used = int(paper_size_used.get_width(Gtk.Unit.POINTS)) self.width_used = int(paper_size_used.get_height(Gtk.Unit.POINTS)) if win(): res = self.print_op.run(Gtk.PrintOperationAction.PRINT_DIALOG, self.uistate.window) else: res = self.print_op.run(Gtk.PrintOperationAction.PREVIEW, self.uistate.window)
def default_clicked(self, obj): self.gtksettings.set_property('gtk-font-name', self.def_font) self.gtksettings.set_property('gtk-theme-name', self.def_theme) self.gtksettings.set_property('gtk-application-prefer-dark-theme', self.def_dark) config.set('preferences.font', '') config.set('preferences.theme', '') config.set('preferences.theme-dark-variant', '') # fill combo with names and select active if current matches self.theme.remove_all() for indx, theme in enumerate(self.t_names): self.theme.append_text(theme) if theme == self.def_theme: self.theme.set_active(indx) self.dark.set_active(self.def_dark) # Clear out scrollbar stuff if not win(): # don't mess with this on Linux etc. return self.sc_text.set_active(False) config.set('interface.fixed-scrollbar', '') self.gtksettings.set_property('gtk-primary-button-warps-slider', 1) if hasattr(MyPrefs, 'provider'): Gtk.StyleContext.remove_provider_for_screen( Screen.get_default(), MyPrefs.provider) try: txt = subprocess.check_output( 'reg delete HKCU\Environment /v GTK_OVERLAY_SCROLLING /f', shell=True) except subprocess.CalledProcessError: pass
def get_identity(): if lin(): platform = "X11" elif win(): platform = "Windows" elif mac(): platform = "Macintosh" else: platform = "Unknown" lang = glocale.lang[:5].replace('_','-') return "Mozilla/5.0 (%s; U; %s) Gramps/3.2" % ( platform, lang)
def get_identity(): if lin(): platform = "X11" elif win(): platform = "Windows" elif mac(): platform = "Macintosh" else: platform = "Unknown" lang = glocale.lang[:5].replace('_', '-') return "Mozilla/5.0 (%s; U; %s) Gramps/3.2" % (platform, lang)
def load_icons(self, icons, dir): """ Load icons in the iconfactory of Gramps, so they can be used in the plugin. The plugin directory must contain the directories scalable, 48x48, 22x22 and 16x16 with the icons, e.g. in dir we have: - scalable/gramps_myplugin.svg - 48x48/gramps_myplugin.png - 22x22/gramps_myplugin.png :param icons: New stock icons to register. e.g. [('gramps_myplugin', _('My Plugin')), ('gramps_myplugin_open', _('Open Plugin'))] :type icons: A list of tuples (stock_id, icon_label) :param dir: Directory from where to load the icons :type dir: str """ if win(): iconpaths = [ (os.path.join(dir, '48x48'), '.png'), (dir, '.png'), ] else: iconpaths = [ (os.path.join(dir, 'scalable'), '.svg'), (dir, '.svg'), (dir, '.png'), ] #sizes: menu=16, small_toolbar=18, large_toolbar=24, # button=20, dnd=32, dialog=48 #add to the back of this list to overrule images set at beginning of list extraiconsize = [ (os.path.join(dir, '22x22'), Gtk.IconSize.LARGE_TOOLBAR), (os.path.join(dir, '16x16'), Gtk.IconSize.MENU), (os.path.join(dir, '22x22'), Gtk.IconSize.BUTTON), ] items = [] for stock_id, label in icons: items.append( (stock_id, label, Gdk.ModifierType.CONTROL_MASK, 0, '')) base_reg_stock_icons(iconpaths, extraiconsize, items)
def open_file_with_default_application(path, uistate): """ Launch a program to open an arbitrary file. The file will be opened using whatever program is configured on the host as the default program for that type of file. :param file_path: The path to the file to be opened. Example: "c:\\foo.txt" :type file_path: string :return: nothing """ errstrings = None norm_path = os.path.normpath(path) if not os.path.exists(norm_path): display_error_dialog(0, _("File %s does not exist") % norm_path, uistate) return if win(): try: os.startfile(norm_path) except WindowsError as msg: display_error_dialog(0, str(msg), uistate) return if mac(): utility = '/usr/bin/open' else: utility = 'xdg-open' errstrings = { 1: 'Error in command line syntax.', 2: 'One of the files passed on the command line did not exist.', 3: ' A required tool could not be found.', 4: 'The action failed.' } proc = subprocess.Popen([utility, norm_path], stderr=subprocess.STDOUT) from gi.repository import GLib GLib.timeout_add_seconds(1, poll_external, (proc, errstrings, uistate)) return
def open_file_with_default_application(path, uistate): """ Launch a program to open an arbitrary file. The file will be opened using whatever program is configured on the host as the default program for that type of file. :param file_path: The path to the file to be opened. Example: "c:\\foo.txt" :type file_path: string :return: nothing """ errstrings = None norm_path = os.path.normpath(path) if not os.path.exists(norm_path): display_error_dialog(0, _("File %s does not exist") % norm_path, uistate) return if win(): try: os.startfile(norm_path) except WindowsError as msg: display_error_dialog(0, str(msg), uistate) return if mac(): utility = '/usr/bin/open' else: utility = 'xdg-open' errstrings = {1:'Error in command line syntax.', 2:'One of the files passed on the command line did not exist.', 3:' A required tool could not be found.', 4:'The action failed.'} proc = subprocess.Popen([utility, norm_path], stderr=subprocess.STDOUT) from gi.repository import GLib GLib.timeout_add_seconds(1, poll_external, (proc, errstrings, uistate)) return
def time_val(dirpath): """ Return the last modified time of the database. We do this by looking at the modification time of the meta db file. If this file does not exist, we indicate that database as never modified. """ meta = os.path.join(dirpath, META_NAME) if os.path.isfile(meta): tval = os.stat(meta)[9] # This gives creation date in Windows, but correct date in Linux if win(): # Try to use last modified date instead in Windows # and check that it is later than the creation date. tval_mod = os.stat(meta)[8] if tval_mod > tval: tval = tval_mod last = time.strftime('%x %X', time.localtime(tval)) else: tval = 0 last = _("Never") return (tval, last)
def writepkg(self, pkg_filename, include_media): "Code copied from gramps/plugins/export/exportpkg.py" try: archive = tarfile.open(pkg_filename, 'w:gz') except EnvironmentError as msg: log.warning(str(msg)) self.user.notify_error( _('Failure writing %s') % pkg_filename, str(msg)) return 0 # Write media files first, since the database may be modified # during the process (i.e. when removing object) if include_media: for m_id in self.db.get_media_handles(sort_handles=True): mobject = self.db.get_media_from_handle(m_id) filename = media_path_full(self.db, mobject.get_path()) archname = str(mobject.get_path()) if os.path.isfile(filename) and os.access(filename, os.R_OK): archive.add(filename, archname, filter=fix_mtime) # Write XML now g = BytesIO() gfile = XmlWriter(self.db, self.user, 2, compress=1, material_type=self.material_type, description=self.description) gfile.write_handle(g) tarinfo = tarfile.TarInfo('data.gramps') tarinfo.size = len(g.getvalue()) tarinfo.mtime = time.time() if not win(): tarinfo.uid = os.getuid() tarinfo.gid = os.getgid() g.seek(0) archive.addfile(tarinfo, g) archive.close() g.close() return True
def drag_data_received(self, widget, context, x, y, sel_data, info, time): """ Handle the standard gtk interface for drag_data_received. If the selection data is define, extract the value from sel_data.data, and decide if this is a move or a reorder. The only data we accept on mediaview is dropping a file, so URI_LIST. We assume this is what we obtain """ if not sel_data: return #modern file managers provide URI_LIST. For Windows split sel_data.data files = sel_data.get_uris() for file in files: if win(): clean_string = conv_to_unicode( file.replace('\0', ' ').replace("\r", " ").strip(), None) else: clean_string = file protocol, site, mfile, j, k, l = urlparse(clean_string) if protocol == "file": name = url2pathname(mfile) mime = get_type(name) if not is_valid_type(mime): return photo = MediaObject() self.uistate.set_busy_cursor(True) photo.set_checksum(create_checksum(name)) self.uistate.set_busy_cursor(False) base_dir = str(media_path(self.dbstate.db)) if os.path.exists(base_dir): name = relative_path(name, base_dir) photo.set_path(name) photo.set_mime_type(mime) basename = os.path.basename(name) (root, ext) = os.path.splitext(basename) photo.set_description(root) with DbTxn(_("Drag Media Object"), self.dbstate.db) as trans: self.dbstate.db.add_object(photo, trans) widget.emit_stop_by_name('drag_data_received')
def match(self, handle, db): if win(): return self.invert ^ (self.func(handle).upper().find(str(self.text)) != -1) else: return self.invert ^ (self.func(handle).upper().find(self.text) != -1)
def export(self): # missmedia_action = 0 #-------------------------------------------------------------- # def remove_clicked(): # # File is lost => remove all references and the object itself # for p_id in self.db.iter_family_handles(): # p = self.db.get_family_from_handle(p_id) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_family(p,None) # for key in self.db.iter_person_handles(): # p = self.db.get_person_from_handle(key) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_person(p,None) # for key in self.db.get_source_handles(): # p = self.db.get_source_from_handle(key) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_source(p,None) # for key in self.db.get_place_handles(): # p = self.db.get_place_from_handle(key) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_place(p,None) # for key in self.db.get_event_handles(): # p = self.db.get_event_from_handle(key) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_event(p,None) # self.db.remove_media(m_id,None) # def leave_clicked(): # # File is lost => do nothing, leave as is # pass # def select_clicked(): # # File is lost => select a file to replace the lost one # def fs_close_window(obj): # pass # def fs_ok_clicked(obj): # name = fs_top.get_filename() # if os.path.isfile(name): # archive.add(name) # fs_top = gtk.FileChooserDialog("%s - GRAMPS" % _("Select file"), # buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, # gtk.STOCK_OK, Gtk.ResponseType.OK) # ) # response = fs_top.run() # if response == Gtk.ResponseType.OK: # fs_ok_clicked(fs_top) # elif response == gtk.RESPONSE_CANCEL: # fs_close_window(fs_top) # fs_top.destroy() #--------------------------------------------------------------- try: archive = tarfile.open(self.filename,'w:gz') except EnvironmentError as msg: log.warning(str(msg)) self.user.notify_error(_('Failure writing %s') % self.filename, str(msg)) return 0 # Write media files first, since the database may be modified # during the process (i.e. when removing object) for m_id in self.db.get_media_handles(sort_handles=True): mobject = self.db.get_media_from_handle(m_id) filename = media_path_full(self.db, mobject.get_path()) archname = str(mobject.get_path()) if os.path.isfile(filename) and os.access(filename, os.R_OK): archive.add(filename, archname) # Write XML now g = BytesIO() gfile = XmlWriter(self.db, self.user, 2) gfile.write_handle(g) tarinfo = tarfile.TarInfo('data.gramps') tarinfo.size = len(g.getvalue()) tarinfo.mtime = time.time() if not win(): tarinfo.uid = os.getuid() tarinfo.gid = os.getgid() g.seek(0) archive.addfile(tarinfo, g) archive.close() g.close() return True
def export(self): # missmedia_action = 0 #-------------------------------------------------------------- # def remove_clicked(): # # File is lost => remove all references and the object itself # for p_id in self.db.iter_family_handles(): # p = self.db.get_family_from_handle(p_id) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_family(p,None) # for key in self.db.iter_person_handles(): # p = self.db.get_person_from_handle(key) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_person(p,None) # for key in self.db.get_source_handles(): # p = self.db.get_source_from_handle(key) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_source(p,None) # for key in self.db.get_place_handles(): # p = self.db.get_place_from_handle(key) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_place(p,None) # for key in self.db.get_event_handles(): # p = self.db.get_event_from_handle(key) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_event(p,None) # self.db.remove_object(m_id,None) # def leave_clicked(): # # File is lost => do nothing, leave as is # pass # def select_clicked(): # # File is lost => select a file to replace the lost one # def fs_close_window(obj): # pass # def fs_ok_clicked(obj): # name = conv_to_unicode(fs_top.get_filename()) # if os.path.isfile(name): # archive.add(name) # fs_top = gtk.FileChooserDialog("%s - GRAMPS" % _("Select file"), # buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, # gtk.STOCK_OK, Gtk.ResponseType.OK) # ) # response = fs_top.run() # if response == Gtk.ResponseType.OK: # fs_ok_clicked(fs_top) # elif response == gtk.RESPONSE_CANCEL: # fs_close_window(fs_top) # fs_top.destroy() #--------------------------------------------------------------- try: archive = tarfile.open(self.filename,'w:gz') except EnvironmentError as msg: log.warn(str(msg)) self.user.notify_error(_('Failure writing %s') % self.filename, str(msg)) return 0 # Write media files first, since the database may be modified # during the process (i.e. when removing object) for m_id in self.db.get_media_object_handles(sort_handles=True): mobject = self.db.get_object_from_handle(m_id) filename = media_path_full(self.db, mobject.get_path()) archname = str(mobject.get_path()) if os.path.isfile(filename) and os.access(filename, os.R_OK): archive.add(filename, archname) # else: # # File is lost => ask what to do # if missmedia_action == 0: # mmd = MissingMediaDialog( # _("Media object could not be found"), # _("%(file_name)s is referenced in the database, " # "but no longer exists. The file may have been " # "deleted or moved to a different location. " # "You may choose to either remove the reference " # "from the database, keep the reference to the " # "missing file, or select a new file." # ) % { 'file_name' : filename }, # remove_clicked, leave_clicked, select_clicked) # missmedia_action = mmd.default_action # elif missmedia_action == 1: # remove_clicked() # elif missmedia_action == 2: # leave_clicked() # elif missmedia_action == 3: # select_clicked() # Write XML now g = BytesIO() gfile = XmlWriter(self.db, self.user, 2) gfile.write_handle(g) tarinfo = tarfile.TarInfo('data.gramps') tarinfo.size = len(g.getvalue()) tarinfo.mtime = time.time() if not win(): tarinfo.uid = os.getuid() tarinfo.gid = os.getgid() g.seek(0) archive.addfile(tarinfo, g) archive.close() g.close() return True
def __init__(self, dbstate, user, options_class, name, callback=None): uistate = user.uistate tool.Tool.__init__(self, dbstate, options_class, name) ManagedWindow.__init__(self, uistate, [], self.__class__) self.db = dbstate.db self.uistate = uistate self.map = {} self.list = [] self.index = 0 self.fam_h = self.fam_iter = self.family = self.progress = None self.update = callback self.top = Gtk.Builder() # Found out that Glade does not support translations for plugins, so # have to do it manually. base = os.path.dirname(__file__) glade_file = base + os.sep + "birthorder.glade" # This is needed to make gtk.Builder work by specifying the # translations directory in a separate 'domain' try: localedomain = "addon" localepath = base + os.sep + "locale" if hasattr(locale, 'bindtextdomain'): libintl = locale elif win(): # apparently wants strings in bytes localedomain = localedomain.encode('utf-8') localepath = localepath.encode('utf-8') libintl = ctypes.cdll.LoadLibrary('libintl-8.dll') else: # mac, No way for author to test this libintl = ctypes.cdll.LoadLibrary('libintl.dylib') libintl.bindtextdomain(localedomain, localepath) libintl.textdomain(localedomain) libintl.bind_textdomain_codeset(localedomain, "UTF-8") # and finally, tell Gtk Builder to use that domain self.top.set_translation_domain("addon") except (OSError, AttributeError): # Will leave it in English print("Localization of BirthOrder failed!") # start with a file name dialog self.top.add_from_file(glade_file) # self.top = Glade() self.fam_liststore = self.top.get_object("fam_liststore") self.ch_liststore = self.top.get_object("ch_liststore") self.ch_liststore_s = self.top.get_object("ch_liststore_s") self.fam_view = self.top.get_object("Families_treeview") self.ch_view = self.top.get_object("children_treeview") self.ch_view_s = self.top.get_object("children_treeview_s") chs_style_cntx = self.ch_view.get_style_context() style_provider = Gtk.CssProvider() style_provider.load_from_data(CSS.encode('utf8')) chs_style_cntx.add_provider(style_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) window = self.top.get_object("main") self.set_window(window, None, TITLE) self.setup_configs('interface.birthordertool', 750, 520) self.top.connect_signals({ "on_close": self.close, "on_help_clicked": self.on_help_clicked, "on_delete_event": self.close, "on_accept_clicked": self.on_accept, "on_easy_clicked": self.on_easy, "on_accept_all_clicked": self.on_accept_all, "on_up_btn_clicked": self.on_up, "on_down_btn_clicked": self.on_down }) self.fam_sel = self.fam_view.get_selection() self.fam_sel.connect('changed', self.on_fam_row_changed) self.ch_s_sel = self.ch_view_s.get_selection() self.show() self.find_potentials() if len(self.fam_liststore) == 0: self.kill_buttons() OkDialog(_("No families need sorting"), _("No children were out of birth order."), parent=self.window)
def drag_data_received(self, widget, context, x, y, sel_data, info, time): """ Handle the standard gtk interface for drag_data_received. If the selection data is define, extract the value from sel_data.data, and decide if this is a move or a reorder. """ if sel_data and sel_data.get_data(): try: (mytype, selfid, obj, row_from) = pickle.loads(sel_data.get_data()) # make sure this is the correct DND type for this object if mytype == self._DND_TYPE.drag_type: # determine the destination row data = self.iconlist.get_dest_item_at_pos(x, y) if data: (path, pos) = data row = path.get_indices()[0] if pos == Gtk.IconViewDropPosition.DROP_LEFT: row = max(row, 0) elif pos == Gtk.IconViewDropPosition.DROP_RIGHT: row = min(row, len(self.get_data())) elif pos == Gtk.IconViewDropPosition.DROP_INTO: row = min(row+1, len(self.get_data())) else: row = len(self.get_data()) # if the is same object, we have a move, otherwise, # it is a standard drag-n-drop if id(self) == selfid: self._move(row_from, row, obj) else: self._handle_drag(row, obj) self.rebuild() elif mytype == DdTargets.MEDIAOBJ.drag_type: oref = MediaRef() oref.set_reference_handle(obj) self.get_data().append(oref) self.changed = True self.rebuild() elif self._DND_EXTRA and mytype == self._DND_EXTRA.drag_type: self.handle_extra_type(mytype, obj) except pickle.UnpicklingError: #modern file managers provide URI_LIST. For Windows split sel_data.data if win(): files = sel_data.get_data().split('\n') else: files = sel_data.get_uris() for file in files: if win(): d = conv_to_unicode((file.replace('\0',' ').strip()), None) else: d = file protocol, site, mfile, j, k, l = urlparse(d) if protocol == "file": name = url2pathname(mfile) mime = get_type(name) if not is_valid_type(mime): return photo = MediaObject() self.uistate.set_busy_cursor(True) photo.set_checksum(create_checksum(name)) self.uistate.set_busy_cursor(False) base_dir = str(media_path(self.dbstate.db)) if os.path.exists(base_dir): name = relative_path(name, base_dir) photo.set_path(name) photo.set_mime_type(mime) basename = os.path.basename(name) (root, ext) = os.path.splitext(basename) photo.set_description(root) with DbTxn(_("Drag Media Object"), self.dbstate.db) as trans: self.dbstate.db.add_object(photo, trans) oref = MediaRef() oref.set_reference_handle(photo.get_handle()) self.get_data().append(oref) self.changed = True self.rebuild()
def __create_gui(self): """ Create and display the GUI components of the gramplet. """ self.top = Gtk.Builder() # IGNORE:W0201 # Found out that Glade does not support translations for plugins, so # have to do it manually. base = os.path.dirname(__file__) glade_file = base + os.sep + "placecleanup.glade" # This is needed to make gtk.Builder work by specifying the # translations directory in a separate 'domain' try: localedomain = "addon" localepath = base + os.sep + "locale" if hasattr(locale, 'bindtextdomain'): libintl = locale elif win(): # apparently wants strings in bytes localedomain = localedomain.encode('utf-8') localepath = localepath.encode('utf-8') libintl = ctypes.cdll.LoadLibrary('libintl-8.dll') else: # mac, No way for author to test this libintl = ctypes.cdll.LoadLibrary('libintl.dylib') libintl.bindtextdomain(localedomain, localepath) libintl.textdomain(localedomain) libintl.bind_textdomain_codeset(localedomain, "UTF-8") # and finally, tell Gtk Builder to use that domain self.top.set_translation_domain("addon") except (OSError, AttributeError): # Will leave it in English print("Localization of PlaceCleanup failed!") self.top.add_from_file(glade_file) # the results screen items self.results_win = self.top.get_object("results") self.alt_store = self.top.get_object("alt_names_liststore") self.alt_selection = self.top.get_object("alt_names_selection") self.res_lbl = self.top.get_object("res_label") self.find_but = self.top.get_object("find_but") self.top.connect_signals({ # for results screen "on_res_ok_clicked" : self.on_res_ok_clicked, "on_res_cancel_clicked" : self.on_res_cancel_clicked, "on_keep_clicked" : self.on_keep_clicked, "on_prim_clicked" : self.on_prim_clicked, "on_disc_clicked" : self.on_disc_clicked, "on_alt_row_activated" : self.on_alt_row_activated, "on_latloncheck" : self.on_latloncheck, "on_postalcheck" : self.on_postalcheck, "on_typecheck" : self.on_typecheck, "on_idcheck" : self.on_idcheck, # Preferences screen item "on_pref_help_clicked" : self.on_pref_help_clicked, # main screen items "on_find_clicked" : self.on_find_clicked, "on_prefs_clicked" : self.on_prefs_clicked, "on_select_clicked" : self.on_select_clicked, "on_edit_clicked" : self.on_edit_clicked, "on_next_clicked" : self.on_next_clicked, "on_res_row_activated" : self.on_select_clicked, "on_res_sel_changed" : self.on_res_sel_changed, "on_title_entry_changed" : self.on_title_entry_changed, "on_help_clicked" : self.on_help_clicked}) # main screen items self.res_store = self.top.get_object("res_names_liststore") self.res_selection = self.top.get_object("res_selection") self.mainwin = self.top.get_object("main") return self.mainwin
def build_gui(self): """ Build the GUI interface. """ self.top = Gtk.Builder() # IGNORE:W0201 # Found out that Glade does not support translations for plugins, so # have to do it manually. base = os.path.dirname(__file__) glade_file = base + os.sep + "placecoordinate.glade" # This is needed to make gtk.Builder work by specifying the # translations directory in a separate 'domain' try: localedomain = "addon" localepath = base + os.sep + "locale" if hasattr(locale, 'bindtextdomain'): libintl = locale elif win(): # apparently wants strings in bytes localedomain = localedomain.encode('utf-8') localepath = localepath.encode('utf-8') libintl = ctypes.cdll.LoadLibrary('libintl-8.dll') else: # mac, No way for author to test this libintl = ctypes.cdll.LoadLibrary('libintl.dylib') libintl.bindtextdomain(localedomain, localepath) libintl.textdomain(localedomain) libintl.bind_textdomain_codeset(localedomain, "UTF-8") # and finally, tell Gtk Builder to use that domain self.top.set_translation_domain("addon") except (OSError, AttributeError): # Will leave it in English _LOG.warn("Localization of PlaceCleanup failed!") self.top.add_from_file(glade_file) self.view = self.top.get_object("grid") # grid.attach(Gtk.Label(_("Search for:")), 1, i, 1, 1) self.entry_name = self.top.get_object("entry_name") self.searchButton = self.top.get_object("searchButton") # Go self.searchButton.connect("clicked", self.on_searchButton_clicked) # grid.attach(Gtk.Label(_("Found place:")), 1, i, 1, 1) self.entry_foundName = self.top.get_object("entry_foundName") # grid.attach(Gtk.Label(_("Latitude:")), 1, i, 1, 1) self.entry_lat = self.top.get_object("entry_lat") # grid.attach(Gtk.Label(_("Longitude:")), 3, i, 1, 1) self.entry_long = self.top.get_object("entry_long") self.showInBrowserButton = self.top.get_object("showInBrowserButton") self.showInBrowserButton.connect( "clicked", self.on_showInBrowserButton_clicked) self.place_id_label = self.top.get_object("place_id_label") # grid.attach(Gtk.Label(_("Postal-Code:")), 1, i, 1, 1) self.entry_code = self.top.get_object("entry_code") # grid.attach(Gtk.Label(_("Latitude:")), 1, i, 1, 1) self.entry_lat_db = self.top.get_object("entry_lat_db") # grid.attach(Gtk.Label(_("Longitude:")), 3, i, 1, 1) self.entry_long_db = self.top.get_object("entry_long_db") self.fromMapButton = self.top.get_object("fromMapButton") self.fromMapButton.connect("clicked", self.on_fromMapButton_clicked) self.fromDBButton = self.top.get_object("fromDBButton") self.fromDBButton.connect("clicked", self.on_fromDBButton_clicked) self.applyButton = self.top.get_object("applyButton") self.applyButton.connect("clicked", self.on_apply_clicked) self.helpButton = self.top.get_object("helpButton") self.helpButton.connect("clicked", self.on_help_clicked) self.view.show_all() return self.view
def __create_gui(self): """ Create and display the GUI components of the gramplet. """ self.top = Gtk.Builder() # IGNORE:W0201 # Found out that Glade does not support translations for plugins, so # have to do it manually. base = os.path.dirname(__file__) glade_file = base + os.sep + "placecleanup.glade" # This is needed to make gtk.Builder work by specifying the # translations directory in a separate 'domain' try: localedomain = "addon" localepath = base + os.sep + "locale" if hasattr(locale, 'bindtextdomain'): libintl = locale elif win(): # apparently wants strings in bytes localedomain = localedomain.encode('utf-8') localepath = localepath.encode('utf-8') libintl = ctypes.cdll.LoadLibrary('libintl-8.dll') else: # mac, No way for author to test this libintl = ctypes.cdll.LoadLibrary('libintl.dylib') libintl.bindtextdomain(localedomain, localepath) libintl.textdomain(localedomain) libintl.bind_textdomain_codeset(localedomain, "UTF-8") # and finally, tell Gtk Builder to use that domain self.top.set_translation_domain("addon") except (OSError, AttributeError): # Will leave it in English print("Localization of PlaceCleanup failed!") self.top.add_from_file(glade_file) # the results screen items self.results_win = self.top.get_object("results") self.alt_store = self.top.get_object("alt_names_liststore") self.alt_selection = self.top.get_object("alt_names_selection") self.res_lbl = self.top.get_object("res_label") self.find_but = self.top.get_object("find_but") self.top.connect_signals({ # for results screen "on_res_ok_clicked": self.on_res_ok_clicked, "on_res_cancel_clicked": self.on_res_cancel_clicked, "on_keep_clicked": self.on_keep_clicked, "on_prim_clicked": self.on_prim_clicked, "on_disc_clicked": self.on_disc_clicked, "on_alt_row_activated": self.on_alt_row_activated, "on_latloncheck": self.on_latloncheck, "on_postalcheck": self.on_postalcheck, "on_typecheck": self.on_typecheck, "on_idcheck": self.on_idcheck, # Preferences screen item "on_pref_help_clicked": self.on_pref_help_clicked, # main screen items "on_find_clicked": self.on_find_clicked, "on_prefs_clicked": self.on_prefs_clicked, "on_select_clicked": self.on_select_clicked, "on_edit_clicked": self.on_edit_clicked, "on_next_clicked": self.on_next_clicked, "on_res_row_activated": self.on_select_clicked, "on_res_sel_changed": self.on_res_sel_changed, "on_title_entry_changed": self.on_title_entry_changed, "on_help_clicked": self.on_help_clicked }) # main screen items self.res_store = self.top.get_object("res_names_liststore") self.res_selection = self.top.get_object("res_selection") self.mainwin = self.top.get_object("main") return self.mainwin
def __init__(self, uistate, track, addon_update_list): self.title = _('Available Gramps Updates for Addons') ManagedWindow.__init__(self, uistate, track, self.__class__) glade = Glade("updateaddons.glade") self.update_dialog = glade.toplevel self.set_window(self.update_dialog, glade.get_object('title'), self.title) self.window.set_size_request(750, 400) if win() and Gtk.get_minor_version() < 11: self.window.set_transient_for(self.window.get_toplevel()) apply_button = glade.get_object('apply') cancel_button = glade.get_object('cancel') select_all = glade.get_object('select_all') select_all.connect("clicked", self.select_all_clicked) select_none = glade.get_object('select_none') select_none.connect("clicked", self.select_none_clicked) apply_button.connect("clicked", self.install_addons) cancel_button.connect("clicked", self.close) self.list = ListModel( glade.get_object("list"), [ # name, click?, width, toggle { "name": _('Select'), "width": 60, "type": TOGGLE, "visible_col": 6, "editable": True }, # 0 selected? (_('Type'), 1, 180), # 1 new gramplet (_('Name'), 2, 200), # 2 name (version) (_('Description'), 3, 200), # 3 description ('', NOSORT, 0), # 4 url ('', NOSORT, 0), # 5 id { "name": '', "type": TOGGLE }, # 6 visible? bool ], list_mode="tree") pos = None addon_update_list.sort(key=lambda x: "%s %s" % (x[0], x[2]["t"])) last_category = None for (status, plugin_url, plugin_dict) in addon_update_list: count = get_count(addon_update_list, plugin_dict["t"]) category = _("%(adjective)s: %(addon)s") % { "adjective": status, "addon": _(plugin_dict["t"]) } if last_category != category: last_category = category node = self.list.add([ False, # initially selected? category, "", "", "", "", False ]) # checkbox visible? iter = self.list.add( [ False, # initially selected? "%s %s" % (status, _(plugin_dict["t"])), "%s (%s)" % (plugin_dict["n"], plugin_dict["v"]), plugin_dict["d"], plugin_url, plugin_dict["i"], True ], node=node) if pos is None: pos = iter if pos: self.list.selection.select_iter(pos) self.update_dialog.run()
def add_themes_panel(self, configdialog): ''' This adds a Theme panel ''' grid = Gtk.Grid() grid.set_border_width(12) grid.set_column_spacing(6) grid.set_row_spacing(6) # Theme combo self.theme = Gtk.ComboBoxText() self.t_names = set() # scan for standard Gtk themes themes = Gio.resources_enumerate_children("/org/gtk/libgtk/theme", 0) for theme in themes: if theme.endswith('/'): # the modern way of finding self.t_names.add(theme[:-1]) elif (theme.startswith('HighContrast') or theme.startswith('Raleigh') or theme.startswith('gtk-win32')): # older method of hard coded self.t_names.add(theme.replace('.css', '')) # scan for user themes self.gtk_css(os.path.join(GLib.get_home_dir(), '.themes')) self.gtk_css(os.path.join(GLib.get_user_data_dir(), 'themes')) # scan for system themes dirs = GLib.get_system_data_dirs() for directory in dirs: self.gtk_css(os.path.join(directory, 'themes')) self.gtksettings = Gtk.Settings.get_default() # get current theme c_theme = self.gtksettings.get_property('gtk-theme-name') # fill combo with names and select active if current matches for indx, theme in enumerate(self.t_names): self.theme.append_text(theme) if theme == c_theme: self.theme.set_active(indx) if os.environ.get("GTK_THEME"): # theme is hardcoded, nothing we can do self.theme.set_sensitive(False) self.theme.set_tooltip_text(_("Theme is hardcoded by GTK_THEME")) else: self.theme.connect('changed', self.theme_changed) lwidget = Gtk.Label(label=(_("%s: ") % _('Theme'))) grid.attach(lwidget, 0, 0, 1, 1) grid.attach(self.theme, 1, 0, 1, 1) # Dark theme self.dark = Gtk.CheckButton(label=_("Dark Variant")) value = self.gtksettings.get_property( 'gtk-application-prefer-dark-theme') self.dark.set_active(value) self.dark.connect('toggled', self.dark_variant_changed) grid.attach(self.dark, 2, 0, 1, 1) self.dark_variant_changed(self.dark) if os.environ.get("GTK_THEME"): # theme is hardcoded, nothing we can do self.dark.set_sensitive(False) self.dark.set_tooltip_text(_("Theme is hardcoded by GTK_THEME")) # Font font_button = Gtk.FontButton(show_style=False) font_button.set_filter_func(self.font_filter, None) self.gtksettings.bind_property( 'gtk-font-name', font_button, "font-name", BindingFlags.BIDIRECTIONAL | BindingFlags.SYNC_CREATE) lwidget = Gtk.Label(label=_("%s: ") % _('Font')) grid.attach(lwidget, 0, 1, 1, 1) grid.attach(font_button, 1, 1, 1, 1) font_button.connect('font-set', self.font_changed) # Toolbar Text t_text = Gtk.CheckButton.new_with_mnemonic( _("_Toolbar") + ' ' + _('Text')) value = config.get('interface.toolbar-text') t_text.set_active(value) t_text.connect('toggled', self.t_text_changed) grid.attach(t_text, 0, 2, 2, 1) # Scrollbar Windows style if win(): self.sc_text = Gtk.CheckButton.new_with_mnemonic( _("Fixed Scrollbar (requires restart)")) value = config.get('interface.fixed-scrollbar') self.sc_text.set_active(value) self.sc_text.connect('toggled', self.scroll_changed) grid.attach(self.sc_text, 0, 3, 2, 1) # Default button = Gtk.Button(label=_('Restore to defaults'), expand=False) button.connect('clicked', self.default_clicked) grid.attach(button, 0, 4, 2, 1) return _('Theme'), grid
def export(self): # missmedia_action = 0 #-------------------------------------------------------------- # def remove_clicked(): # # File is lost => remove all references and the object itself # for p_id in self.db.iter_family_handles(): # p = self.db.get_family_from_handle(p_id) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_family(p,None) # for key in self.db.iter_person_handles(): # p = self.db.get_person_from_handle(key) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_person(p,None) # for key in self.db.get_source_handles(): # p = self.db.get_source_from_handle(key) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_source(p,None) # for key in self.db.get_place_handles(): # p = self.db.get_place_from_handle(key) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_place(p,None) # for key in self.db.get_event_handles(): # p = self.db.get_event_from_handle(key) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_event(p,None) # self.db.remove_object(m_id,None) # def leave_clicked(): # # File is lost => do nothing, leave as is # pass # def select_clicked(): # # File is lost => select a file to replace the lost one # def fs_close_window(obj): # pass # def fs_ok_clicked(obj): # name = conv_to_unicode(fs_top.get_filename()) # if os.path.isfile(name): # archive.add(name) # fs_top = gtk.FileChooserDialog("%s - GRAMPS" % _("Select file"), # buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, # gtk.STOCK_OK, Gtk.ResponseType.OK) # ) # response = fs_top.run() # if response == Gtk.ResponseType.OK: # fs_ok_clicked(fs_top) # elif response == gtk.RESPONSE_CANCEL: # fs_close_window(fs_top) # fs_top.destroy() #--------------------------------------------------------------- try: archive = tarfile.open(self.filename, 'w:gz') except EnvironmentError as msg: log.warn(str(msg)) self.user.notify_error( _('Failure writing %s') % self.filename, str(msg)) return 0 # Write media files first, since the database may be modified # during the process (i.e. when removing object) for m_id in self.db.get_media_object_handles(sort_handles=True): mobject = self.db.get_object_from_handle(m_id) filename = media_path_full(self.db, mobject.get_path()) archname = str(mobject.get_path()) if os.path.isfile(filename) and os.access(filename, os.R_OK): archive.add(filename, archname) # else: # # File is lost => ask what to do # if missmedia_action == 0: # mmd = MissingMediaDialog( # _("Media object could not be found"), # _("%(file_name)s is referenced in the database, " # "but no longer exists. The file may have been " # "deleted or moved to a different location. " # "You may choose to either remove the reference " # "from the database, keep the reference to the " # "missing file, or select a new file." # ) % { 'file_name' : filename }, # remove_clicked, leave_clicked, select_clicked) # missmedia_action = mmd.default_action # elif missmedia_action == 1: # remove_clicked() # elif missmedia_action == 2: # leave_clicked() # elif missmedia_action == 3: # select_clicked() # Write XML now g = BytesIO() gfile = XmlWriter(self.db, self.user, 2) gfile.write_handle(g) tarinfo = tarfile.TarInfo('data.gramps') tarinfo.size = len(g.getvalue()) tarinfo.mtime = time.time() if not win(): tarinfo.uid = os.getuid() tarinfo.gid = os.getgid() g.seek(0) archive.addfile(tarinfo, g) archive.close() g.close() return True
def export_data(self): self.dirname = os.path.dirname (self.filename) try: self.fp = open(self.filename, "w", encoding='utf_8_sig' if win() else 'utf_8', newline='') self.g = csv.writer(self.fp) except IOError as msg: msg2 = _("Could not create %s") % self.filename self.user.notify_error(msg2,str(msg)) return False except: self.user.notify_error(_("Could not create %s") % self.filename) return False ######################### initialize progress bar self.count = 0 self.total = 0 self.oldval = 0 if self.include_individuals: self.total += len(self.plist) if self.include_marriages: self.total += len(self.flist) if self.include_children: self.total += len(self.flist) if self.include_places: self.total += len(self.place_list) ######################## LOG.debug("Possible people to export: %s", len(self.plist)) LOG.debug("Possible families to export: %s", len(self.flist)) LOG.debug("Possible places to export: %s", len(self.place_list)) ########################### if self.include_places: if self.translate_headers: self.write_csv(_("Place"), _("Title"), _("Name"), _("Type"), _("Latitude"), _("Longitude"), _("Code"), _("Enclosed_by"), _("Date")) else: self.write_csv("Place", "Title", "Name", "Type", "Latitude", "Longitude", "Code", "Enclosed_by", "Date") for key in self.place_list: place = self.db.get_place_from_handle(key) if place: place_id = place.gramps_id place_title = place.title place_name = place.name.value place_type = str(place.place_type) place_latitude = place.lat place_longitude = place.long place_code = place.code if place.placeref_list: for placeref in place.placeref_list: placeref_obj = self.db.get_place_from_handle(placeref.ref) placeref_date = "" if not placeref.date.is_empty(): placeref_date = placeref.date placeref_id = "" if placeref_obj: placeref_id = "[%s]" % placeref_obj.gramps_id self.write_csv("[%s]" % place_id, place_title, place_name, place_type, place_latitude, place_longitude, place_code, placeref_id, placeref_date) else: self.write_csv("[%s]" % place_id, place_title, place_name, place_type, place_latitude, place_longitude, place_code, "", "") self.update() self.writeln() ########################### sort: sortorder = [] dropped_surnames = set() for key in self.plist: person = self.db.get_person_from_handle(key) if person: primary_name = person.get_primary_name() first_name = primary_name.get_first_name() surname_obj = primary_name.get_primary_surname() surname = surname_obj.get_surname() # See bug #6955 nonprimary_surnames = set(primary_name.get_surname_list()) nonprimary_surnames.remove(surname_obj) dropped_surnames.update(nonprimary_surnames) sortorder.append( (surname, first_name, key) ) if dropped_surnames: LOG.warning( _("CSV export doesn't support non-primary surnames, " "{count} dropped").format( count=len(dropped_surnames)) ) LOG.debug( "Dropped surnames: " + ', '.join([("%s %s %s" % (surname.get_prefix(), surname.get_surname(), surname.get_connector())).strip() for surname in dropped_surnames])) sortorder.sort() # will sort on tuples plist = [data[2] for data in sortorder] ########################### if self.include_individuals: if self.translate_headers: self.write_csv( _("Person"), _("Surname"), _("Given"), _("Call"), _("Suffix"), _("Prefix"), _("Person|Title"), _("Gender"), _("Birth date"), _("Birth place"), _("Birth source"), _("Baptism date"), _("Baptism place"), _("Baptism source"), _("Death date"), _("Death place"), _("Death source"), _("Burial date"), _("Burial place"), _("Burial source"), _("Note")) else: self.write_csv( "Person", "Surname", "Given", "Call", "Suffix", "Prefix", "Title", "Gender", "Birth date", "Birth place", "Birth source", "Baptism date", "Baptism place", "Baptism source", "Death date", "Death place", "Death source", "Burial date", "Burial place", "Burial source", "Note") for key in plist: person = self.db.get_person_from_handle(key) if person: primary_name = person.get_primary_name() first_name = primary_name.get_first_name() surname_obj = primary_name.get_primary_surname() surname = surname_obj.get_surname() prefix = surname_obj.get_prefix() suffix = primary_name.get_suffix() title = primary_name.get_title() grampsid = person.get_gramps_id() grampsid_ref = "" if grampsid != "": grampsid_ref = "[" + grampsid + "]" note = '' # don't export notes callname = primary_name.get_call_name() gender = person.get_gender() if gender == Person.MALE: gender = gender_map[Person.MALE] elif gender == Person.FEMALE: gender = gender_map[Person.FEMALE] else: gender = gender_map[Person.UNKNOWN] # Birth: birthdate = "" birthplace = "" birthsource = "" birth_ref = person.get_birth_ref() if birth_ref: birth = self.db.get_event_from_handle(birth_ref.ref) if birth: birthdate = self.format_date( birth) place_handle = birth.get_place_handle() if place_handle: birthplace = _pd.display_event(self.db, birth) birthsource = get_primary_source_title(self.db, birth) # Baptism: baptismdate = "" baptismplace = "" baptismsource = "" baptism_ref = get_primary_event_ref_from_type( self.db, person, "Baptism") if baptism_ref: baptism = self.db.get_event_from_handle(baptism_ref.ref) if baptism: baptismdate = self.format_date( baptism) place_handle = baptism.get_place_handle() if place_handle: baptismplace = _pd.display_event(self.db, baptism) baptismsource = get_primary_source_title(self.db, baptism) # Death: deathdate = "" deathplace = "" deathsource = "" death_ref = person.get_death_ref() if death_ref: death = self.db.get_event_from_handle(death_ref.ref) if death: deathdate = self.format_date( death) place_handle = death.get_place_handle() if place_handle: deathplace = _pd.display_event(self.db, death) deathsource = get_primary_source_title(self.db, death) # Burial: burialdate = "" burialplace = "" burialsource = "" burial_ref = get_primary_event_ref_from_type( self.db, person, "Burial") if burial_ref: burial = self.db.get_event_from_handle(burial_ref.ref) if burial: burialdate = self.format_date( burial) place_handle = burial.get_place_handle() if place_handle: burialplace = _pd.display_event(self.db, burial) burialsource = get_primary_source_title(self.db, burial) # Write it out: self.write_csv(grampsid_ref, surname, first_name, callname, suffix, prefix, title, gender, birthdate, birthplace, birthsource, baptismdate, baptismplace, baptismsource, deathdate, deathplace, deathsource, burialdate, burialplace, burialsource, note) self.update() self.writeln() ########################### sort: sortorder = [] for key in self.flist: family = self.db.get_family_from_handle(key) if family: marriage_id = family.get_gramps_id() sortorder.append( (sortable_string_representation(marriage_id), key) ) sortorder.sort() # will sort on tuples flist = [data[1] for data in sortorder] ########################### if self.include_marriages: if self.translate_headers: self.write_csv(_("Marriage"), _("Husband"), _("Wife"), _("Date"), _("Place"), _("Source"), _("Note")) else: self.write_csv("Marriage", "Husband", "Wife", "Date", "Place", "Source", "Note") for key in flist: family = self.db.get_family_from_handle(key) if family: marriage_id = family.get_gramps_id() if marriage_id != "": marriage_id = "[" + marriage_id + "]" mother_id = '' father_id = '' father_handle = family.get_father_handle() if father_handle: father = self.db.get_person_from_handle(father_handle) father_id = father.get_gramps_id() if father_id != "": father_id = "[" + father_id + "]" mother_handle = family.get_mother_handle() if mother_handle: mother = self.db.get_person_from_handle(mother_handle) mother_id = mother.get_gramps_id() if mother_id != "": mother_id = "[" + mother_id + "]" # get mdate, mplace mdate, mplace, source = '', '', '' event_ref_list = family.get_event_ref_list() for event_ref in event_ref_list: event = self.db.get_event_from_handle(event_ref.ref) if event.get_type() == EventType.MARRIAGE: mdate = self.format_date( event) place_handle = event.get_place_handle() if place_handle: mplace = _pd.display_event(self.db, event) source = get_primary_source_title(self.db, event) note = '' self.write_csv(marriage_id, father_id, mother_id, mdate, mplace, source, note) self.update() self.writeln() if self.include_children: if self.translate_headers: self.write_csv(_("Family"), _("Child")) else: self.write_csv("Family", "Child") for key in flist: family = self.db.get_family_from_handle(key) if family: family_id = family.get_gramps_id() if family_id != "": family_id = "[" + family_id + "]" for child_ref in family.get_child_ref_list(): child_handle = child_ref.ref child = self.db.get_person_from_handle(child_handle) grampsid = child.get_gramps_id() grampsid_ref = "" if grampsid != "": grampsid_ref = "[" + grampsid + "]" self.write_csv(family_id, grampsid_ref) self.update() self.writeln() self.fp.close() return True
from gramps.gen.const import GRAMPS_LOCALE as glocale _ = glocale.translation.gettext #------------------------------------------------------------------------- # # set up logging # #------------------------------------------------------------------------- LOG = logging.getLogger(".DbManager") #------------------------------------------------------------------------- # # constants # #------------------------------------------------------------------------- if win(): _RCS_FOUND = os.system("rcs -V >nul 2>nul") == 0 if _RCS_FOUND and "TZ" not in os.environ: # RCS requires the "TZ" variable be set. os.environ["TZ"] = str(time.timezone) else: _RCS_FOUND = os.system("rcs -V >/dev/null 2>/dev/null") == 0 _RETURN = Gdk.keyval_from_name("Return") _KP_ENTER = Gdk.keyval_from_name("KP_Enter") WIKI_HELP_PAGE = _('%s_-_Manage_Family_Trees') % URL_MANUAL_PAGE WIKI_HELP_SEC = _('Family_Trees_manager_window') ARCHIVE = "rev.gramps" ARCHIVE_V = "rev.gramps,v"
TOOLKIT = NOWEB # Attempting to import webkit gives an error dialog if webkit is not # available so test first and log just a warning to the console instead. repository = Repository.get_default() if repository.enumerate_versions("WebKit"): try: from gi.repository import WebKit TOOLKIT = WEBKIT except: pass from gramps.gen.config import config if TOOLKIT == NOWEB and not config.get('interface.ignore-webkit'): from gramps.gen.constfunc import has_display, mac, win if win() or mac(): # WebKit is not put into either Windows or Mac bundles config.set('interface.ignore-webkit', True) if has_display() and not config.get('interface.ignore-webkit'): from gramps.gui.dialog import MessageHideDialog title = _("Webkit module not loaded.") msg = _("Webkit module not loaded. " "Embedded web page viewing will not be available. " "Use your package manager to install gir1.2-webkit-3.0") MessageHideDialog(title, msg, 'interface.ignore-webkit') #no interfaces present, we do not register these plugins if not (TOOLKIT == NOWEB): register( VIEW, id='htmlview', name=_("Html View"),
def export_data(self): self.dirname = os.path.dirname(self.filename) try: self.fp = open(self.filename, "w", encoding='utf_8_sig' if win() else 'utf_8', newline='') self.g = csv.writer(self.fp) except IOError as msg: msg2 = _("Could not create %s") % self.filename self.user.notify_error(msg2, str(msg)) return False except: self.user.notify_error(_("Could not create %s") % self.filename) return False ######################### initialize progress bar self.count = 0 self.total = 0 self.oldval = 0 if self.include_individuals: self.total += len(self.plist) if self.include_marriages: self.total += len(self.flist) if self.include_children: self.total += len(self.flist) if self.include_places: self.total += len(self.place_list) ######################## LOG.debug("Possible people to export: %s", len(self.plist)) LOG.debug("Possible families to export: %s", len(self.flist)) LOG.debug("Possible places to export: %s", len(self.place_list)) ########################### if self.include_places: if self.translate_headers: self.write_csv(_("Place"), _("Title"), _("Name"), _("Type"), _("Latitude"), _("Longitude"), _("Code"), _("Enclosed_by"), _("Date")) else: self.write_csv("Place", "Title", "Name", "Type", "Latitude", "Longitude", "Code", "Enclosed_by", "Date") for key in self.place_list: place = self.db.get_place_from_handle(key) if place: place_id = place.gramps_id place_title = place.title place_name = place.name.value place_type = str(place.place_type) place_latitude = place.lat place_longitude = place.long place_code = place.code if place.placeref_list: for placeref in place.placeref_list: placeref_obj = self.db.get_place_from_handle( placeref.ref) placeref_date = "" if not placeref.date.is_empty(): placeref_date = placeref.date placeref_id = "" if placeref_obj: placeref_id = "[%s]" % placeref_obj.gramps_id self.write_csv("[%s]" % place_id, place_title, place_name, place_type, place_latitude, place_longitude, place_code, placeref_id, placeref_date) else: self.write_csv("[%s]" % place_id, place_title, place_name, place_type, place_latitude, place_longitude, place_code, "", "") self.update() self.writeln() ########################### sort: sortorder = [] dropped_surnames = set() for key in self.plist: person = self.db.get_person_from_handle(key) if person: primary_name = person.get_primary_name() first_name = primary_name.get_first_name() surname_obj = primary_name.get_primary_surname() surname = surname_obj.get_surname() # See bug #6955 nonprimary_surnames = set(primary_name.get_surname_list()) nonprimary_surnames.remove(surname_obj) dropped_surnames.update(nonprimary_surnames) sortorder.append((surname, first_name, key)) if dropped_surnames: LOG.warning( _("CSV export doesn't support non-primary surnames, " "{count} dropped").format(count=len(dropped_surnames))) LOG.debug("Dropped surnames: " + ', '.join([("%s %s %s" % (surname.get_prefix(), surname.get_surname(), surname.get_connector())).strip() for surname in dropped_surnames])) sortorder.sort() # will sort on tuples plist = [data[2] for data in sortorder] ########################### if self.include_individuals: if self.translate_headers: self.write_csv(_("Person"), _("Surname"), _("Given"), _("Call"), _("Suffix"), _("Prefix"), _("Title", "Person"), _("Gender"), _("Birth date"), _("Birth place"), _("Birth source"), _("Baptism date"), _("Baptism place"), _("Baptism source"), _("Death date"), _("Death place"), _("Death source"), _("Burial date"), _("Burial place"), _("Burial source"), _("Note")) else: self.write_csv("Person", "Surname", "Given", "Call", "Suffix", "Prefix", "Title", "Gender", "Birth date", "Birth place", "Birth source", "Baptism date", "Baptism place", "Baptism source", "Death date", "Death place", "Death source", "Burial date", "Burial place", "Burial source", "Note") for key in plist: person = self.db.get_person_from_handle(key) if person: primary_name = person.get_primary_name() first_name = primary_name.get_first_name() surname_obj = primary_name.get_primary_surname() surname = surname_obj.get_surname() prefix = surname_obj.get_prefix() suffix = primary_name.get_suffix() title = primary_name.get_title() grampsid = person.get_gramps_id() grampsid_ref = "" if grampsid != "": grampsid_ref = "[" + grampsid + "]" note = '' # don't export notes callname = primary_name.get_call_name() gender = person.get_gender() if gender == Person.MALE: gender = gender_map[Person.MALE] elif gender == Person.FEMALE: gender = gender_map[Person.FEMALE] else: gender = gender_map[Person.UNKNOWN] # Birth: birthdate = "" birthplace = "" birthsource = "" birth_ref = person.get_birth_ref() if birth_ref: birth = self.db.get_event_from_handle(birth_ref.ref) if birth: birthdate = self.format_date(birth) birthplace = self.format_place(birth) birthsource = get_primary_source_title( self.db, birth) # Baptism: baptismdate = "" baptismplace = "" baptismsource = "" baptism_ref = get_primary_event_ref_from_type( self.db, person, "Baptism") if baptism_ref: baptism = self.db.get_event_from_handle( baptism_ref.ref) if baptism: baptismdate = self.format_date(baptism) baptismplace = self.format_place(baptism) baptismsource = get_primary_source_title( self.db, baptism) # Death: deathdate = "" deathplace = "" deathsource = "" death_ref = person.get_death_ref() if death_ref: death = self.db.get_event_from_handle(death_ref.ref) if death: deathdate = self.format_date(death) deathplace = self.format_place(death) deathsource = get_primary_source_title( self.db, death) # Burial: burialdate = "" burialplace = "" burialsource = "" burial_ref = get_primary_event_ref_from_type( self.db, person, "Burial") if burial_ref: burial = self.db.get_event_from_handle(burial_ref.ref) if burial: burialdate = self.format_date(burial) burialplace = self.format_place(burial) burialsource = get_primary_source_title( self.db, burial) # Write it out: self.write_csv(grampsid_ref, surname, first_name, callname, suffix, prefix, title, gender, birthdate, birthplace, birthsource, baptismdate, baptismplace, baptismsource, deathdate, deathplace, deathsource, burialdate, burialplace, burialsource, note) self.update() self.writeln() ########################### sort: sortorder = [] for key in self.flist: family = self.db.get_family_from_handle(key) if family: marriage_id = family.get_gramps_id() sortorder.append( (sortable_string_representation(marriage_id), key)) sortorder.sort() # will sort on tuples flist = [data[1] for data in sortorder] ########################### if self.include_marriages: if self.translate_headers: self.write_csv(_("Marriage"), _("Husband"), _("Wife"), _("Date"), _("Place"), _("Source"), _("Note")) else: self.write_csv("Marriage", "Husband", "Wife", "Date", "Place", "Source", "Note") for key in flist: family = self.db.get_family_from_handle(key) if family: marriage_id = family.get_gramps_id() if marriage_id != "": marriage_id = "[" + marriage_id + "]" mother_id = '' father_id = '' father_handle = family.get_father_handle() if father_handle: father = self.db.get_person_from_handle(father_handle) father_id = father.get_gramps_id() if father_id != "": father_id = "[" + father_id + "]" mother_handle = family.get_mother_handle() if mother_handle: mother = self.db.get_person_from_handle(mother_handle) mother_id = mother.get_gramps_id() if mother_id != "": mother_id = "[" + mother_id + "]" # get mdate, mplace mdate, mplace, source = '', '', '' event_ref_list = family.get_event_ref_list() for event_ref in event_ref_list: event = self.db.get_event_from_handle(event_ref.ref) if event.get_type() == EventType.MARRIAGE: mdate = self.format_date(event) mplace = self.format_place(event) source = get_primary_source_title(self.db, event) note = '' self.write_csv(marriage_id, father_id, mother_id, mdate, mplace, source, note) self.update() self.writeln() if self.include_children: if self.translate_headers: self.write_csv(_("Family"), _("Child")) else: self.write_csv("Family", "Child") for key in flist: family = self.db.get_family_from_handle(key) if family: family_id = family.get_gramps_id() if family_id != "": family_id = "[" + family_id + "]" for child_ref in family.get_child_ref_list(): child_handle = child_ref.ref child = self.db.get_person_from_handle(child_handle) grampsid = child.get_gramps_id() grampsid_ref = "" if grampsid != "": grampsid_ref = "[" + grampsid + "]" self.write_csv(family_id, grampsid_ref) self.update() self.writeln() self.fp.close() return True
def export(self): # missmedia_action = 0 #-------------------------------------------------------------- # def remove_clicked(): # # File is lost => remove all references and the object itself # for p_id in self.db.iter_family_handles(): # p = self.db.get_family_from_handle(p_id) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_family(p,None) # for key in self.db.iter_person_handles(): # p = self.db.get_person_from_handle(key) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_person(p,None) # for key in self.db.get_source_handles(): # p = self.db.get_source_from_handle(key) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_source(p,None) # for key in self.db.get_place_handles(): # p = self.db.get_place_from_handle(key) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_place(p,None) # for key in self.db.get_event_handles(): # p = self.db.get_event_from_handle(key) # nl = p.get_media_list() # for o in nl: # if o.get_reference_handle() == m_id: # nl.remove(o) # p.set_media_list(nl) # self.db.commit_event(p,None) # self.db.remove_media(m_id,None) # def leave_clicked(): # # File is lost => do nothing, leave as is # pass # def select_clicked(): # # File is lost => select a file to replace the lost one # def fs_close_window(obj): # pass # def fs_ok_clicked(obj): # name = fs_top.get_filename() # if os.path.isfile(name): # archive.add(name) # fs_top = gtk.FileChooserDialog("%s - GRAMPS" % _("Select file"), # buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, # gtk.STOCK_OK, Gtk.ResponseType.OK) # ) # response = fs_top.run() # if response == Gtk.ResponseType.OK: # fs_ok_clicked(fs_top) # elif response == gtk.RESPONSE_CANCEL: # fs_close_window(fs_top) # fs_top.destroy() #--------------------------------------------------------------- try: archive = tarfile.open(self.filename, 'w:gz') except EnvironmentError as msg: log.warning(str(msg)) self.user.notify_error( _('Failure writing %s') % self.filename, str(msg)) return 0 # Write media files first, since the database may be modified # during the process (i.e. when removing object) for m_id in self.db.get_media_handles(sort_handles=True): mobject = self.db.get_media_from_handle(m_id) filename = media_path_full(self.db, mobject.get_path()) archname = str(mobject.get_path()) if os.path.isfile(filename) and os.access(filename, os.R_OK): archive.add(filename, archname) # Write XML now g = BytesIO() gfile = XmlWriter(self.db, self.user, 2) gfile.write_handle(g) tarinfo = tarfile.TarInfo('data.gramps') tarinfo.size = len(g.getvalue()) tarinfo.mtime = time.time() if not win(): tarinfo.uid = os.getuid() tarinfo.gid = os.getgid() g.seek(0) archive.addfile(tarinfo, g) archive.close() g.close() return True
def draw_window(self): """Draw the dialog box.""" # Copied from PlaceCleanup: # Found out that Glade does not support translations for plugins, so # have to do it manually. import os import locale import ctypes from gramps.gen.constfunc import win base = os.path.dirname(__file__) glade_file = base + os.sep + "nameeditortool.glade" # This is needed to make gtk.Builder work by specifying the # translations directory in a separate 'domain' try: localedomain = "addon" localepath = base + os.sep + "locale" if hasattr(locale, 'bindtextdomain'): libintl = locale elif win(): # apparently wants strings in bytes localedomain = localedomain.encode('utf-8') localepath = localepath.encode('utf-8') libintl = ctypes.cdll.LoadLibrary('libintl-8.dll') else: # mac, No way for author to test this libintl = ctypes.cdll.LoadLibrary('libintl.dylib') libintl.bindtextdomain(localedomain, localepath) libintl.textdomain(localedomain) libintl.bind_textdomain_codeset(localedomain, "UTF-8") # and finally, tell Gtk Builder to use that domain self.top.set_translation_domain("addon") except (OSError, AttributeError): # Will leave it in English print("Localization of PlaceCleanup failed!") glade = Glade() self.glade = glade self.top = glade.toplevel columns = [ (_('Id'), 0, 80), (_('Gender'), 1, 100), (_('Prefix'), 2, 100), (_('Surname'), 3, 200), (_('First name'), 4, 200), (_('Suffix'), 5, 200), (_('Title'), 6, 300), (_('Type'), 7, 100), ] # ('',-1,0)] self.namelist = MyTreeView() self.namemodel = MyListModel(self.namelist, columns, event_func=self.cb_double_click) find = glade.get_child_object("find") find.connect('clicked', self.find_clicked) reset = glade.get_child_object("reset") reset.connect('clicked', self.reset_clicked) self.searchtext = glade.get_child_object("searchtext") self.searchtext.connect("key-press-event", self.keypress) slist = glade.get_child_object("slist") slist.add(self.namelist) #self.namelist.connect('button-release-event', self.__button_release) select = self.namelist.get_selection() select.connect("changed", self.on_selection_changed) self.replace_button = glade.get_child_object("replace") self.replace_button.connect('clicked', self.replace_clicked) button_undo = glade.get_child_object("button_undo") button_undo.connect('clicked', self.undo_clicked) clear_button = glade.get_child_object("clear_button") clear_button.connect('clicked', self.clear_form) editgrid = self.glade.get_child_object('editgrid') self.special_prefix = self.build_combobox() self.special_surname = self.build_combobox() self.special_firstname = self.build_combobox() self.special_suffix = self.build_combobox() self.special_title = self.build_combobox() self.old_prefix = self.glade.get_child_object("old_prefix") self.old_surname = self.glade.get_child_object("old_surname") self.old_firstname = self.glade.get_child_object("old_firstname") self.old_suffix = self.glade.get_child_object("old_suffix") self.old_title = self.glade.get_child_object("old_title") self.new_prefix = self.glade.get_child_object('new_prefix') self.new_surname = self.glade.get_child_object('new_surname') self.new_firstname = self.glade.get_child_object('new_firstname') self.new_suffix = self.glade.get_child_object('new_suffix') self.new_title = self.glade.get_child_object("new_title") editgrid.attach(self.special_prefix, 2, 1, 1, 1) editgrid.attach(self.special_surname, 2, 2, 1, 1) editgrid.attach(self.special_firstname, 2, 3, 1, 1) editgrid.attach(self.special_suffix, 2, 4, 1, 1) editgrid.attach(self.special_title, 2, 5, 1, 1) self.use_special = glade.get_child_object("use_special") self.use_special.connect('clicked', self.use_special_clicked) self.use_regex_checkbox = self.glade.get_child_object("use_regex") self.find_use_regex = self.glade.get_child_object("find_regex") self.find_all = self.glade.get_child_object("find_all") self.find_prefix = self.glade.get_child_object("find_prefix") self.find_surname = self.glade.get_child_object("find_surname") self.find_firstname = self.glade.get_child_object("find_firstname") self.find_suffix = self.glade.get_child_object("find_suffix") self.find_title = self.glade.get_child_object("find_title") self.find_type = self.glade.get_child_object("find_type") self.fill_typecombo(self.find_type) self.old_nametype = self.glade.get_child_object("old_nametype") self.fill_typecombo(self.old_nametype) self.new_nametype = self.glade.get_child_object("new_nametype") self.fill_typecombo(self.new_nametype) self.type_primary = self.glade.get_child_object("type_primary") self.type_alternate = self.glade.get_child_object("type_alternate") self.find_all.connect('clicked', self.find_all_clicked) self.gender_all = self.glade.get_child_object("gender_all") self.gender_male = self.glade.get_child_object("gender_male") self.gender_female = self.glade.get_child_object("gender_female") self.gender_unknown = self.glade.get_child_object("gender_unknown") self.label_count = self.glade.get_child_object("label_count") self.help_button = self.glade.get_child_object("help_button") self.help_button.connect("clicked", self.show_help) self.find_in_progress = True self.reset_clicked(None) self.find_in_progress = False return self.top
def register_stock_icons(): """ Add the gramps names for its icons (eg gramps-person) to the GTK icon factory. This allows all gramps modules to call up the icons by their name """ from .pluginmanager import base_reg_stock_icons #iconpath to the base image. The front of the list has highest priority if win(): iconpaths = [ (os.path.join(IMAGE_DIR, '48x48'), '.png'), (IMAGE_DIR, '.png'), ] else: iconpaths = [ (os.path.join(IMAGE_DIR, 'scalable'), '.svg'), (IMAGE_DIR, '.svg'), (IMAGE_DIR, '.png'), ] #sizes: menu=16, small_toolbar=18, large_toolbar=24, # button=20, dnd=32, dialog=48 #add to the back of this list to overrule images set at beginning of list extraiconsize = [ (os.path.join(IMAGE_DIR, '22x22'), Gtk.IconSize.LARGE_TOOLBAR), (os.path.join(IMAGE_DIR, '16x16'), Gtk.IconSize.MENU), (os.path.join(IMAGE_DIR, '22x22'), Gtk.IconSize.BUTTON), ] items = [ ('gramps-db', _('Family Trees'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-address', _('Address'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-attribute', _('Attribute'), Gdk.ModifierType.CONTROL_MASK, 0, ''), #('gramps-bookmark', _('Bookmarks'), Gdk.ModifierType.CONTROL_MASK, 0, ''), #('gramps-bookmark-delete', _('Delete bookmark'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-bookmark-new', _('_Add bookmark'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-bookmark-edit', _('Organize Bookmarks'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-config', _('Configure'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-date', _('Date'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-date-edit', _('Edit Date'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-event', _('Events'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-family', _('Family'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-fanchart', _('Fan Chart'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-fanchartdesc', _('Descendant Fan Chart'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-font', _('Font'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-font-color', _('Font Color'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-font-bgcolor', _('Font Background Color'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-gramplet', _('Gramplets'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-geo', _('Geography'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-geo-mainmap', _('Geography'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-geo-altmap', _('Geography'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('geo-show-person', _('GeoPerson'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('geo-show-family', _('GeoFamily'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('geo-show-event', _('GeoEvents'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('geo-show-place', _('GeoPlaces'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-lock', _('Public'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-media', _('Media'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-merge', _('Merge'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-notes', _('Notes'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-parents', _('Parents'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-parents-add', _('Add Parents'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-parents-open', _('Select Parents'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-pedigree', _('Pedigree'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-person', _('Person'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-place', _('Places'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-relation', _('Relationships'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-reports', _('Reports'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-repository', _('Repositories'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-source', _('Sources'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-spouse', _('Add Spouse'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-tag', _('Tag'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-tag-new', _('New Tag'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-tools', _('Tools'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-tree-group', _('Grouped List'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-tree-list', _('List'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-tree-select', _('Select'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-unlock', _('Private'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-view', _('View'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-viewmedia', _('View'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-zoom-in', _('Zoom In'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-zoom-out', _('Zoom Out'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-zoom-fit-width', _('Fit Width'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-zoom-best-fit', _('Fit Page'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-citation', _('Citations'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ] # the following icons are not yet in new directory structure # they should be ported in the near future items_legacy = [ ('gramps-export', _('Export'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-import', _('Import'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-undo-history', _('Undo History'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-url', _('URL'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ] base_reg_stock_icons(iconpaths, extraiconsize, items + items_legacy)
import time import copy import subprocess from urllib.parse import urlparse #------------------------------------------------------------------------- # # set up logging # #------------------------------------------------------------------------- import logging LOG = logging.getLogger(".DbManager") from gramps.gen.constfunc import win, conv_to_unicode if win(): _RCS_FOUND = os.system("rcs -V >nul 2>nul") == 0 if _RCS_FOUND and "TZ" not in os.environ: # RCS requires the "TZ" variable be set. os.environ["TZ"] = str(time.timezone) else: _RCS_FOUND = os.system("rcs -V >/dev/null 2>/dev/null") == 0 #------------------------------------------------------------------------- # # GTK/Gnome modules # #------------------------------------------------------------------------- from gi.repository import Gdk from gi.repository import Gtk from gi.repository import Pango
def register_stock_icons (): """ Add the gramps names for its icons (eg gramps-person) to the GTK icon factory. This allows all gramps modules to call up the icons by their name """ from .pluginmanager import base_reg_stock_icons #iconpath to the base image. The front of the list has highest priority if win(): iconpaths = [ (os.path.join(IMAGE_DIR, '48x48'), '.png'), (IMAGE_DIR, '.png'), ] else : iconpaths = [ (os.path.join(IMAGE_DIR, 'scalable'), '.svg'), (IMAGE_DIR, '.svg'), (IMAGE_DIR, '.png'), ] #sizes: menu=16, small_toolbar=18, large_toolbar=24, # button=20, dnd=32, dialog=48 #add to the back of this list to overrule images set at beginning of list extraiconsize = [ (os.path.join(IMAGE_DIR, '22x22'), Gtk.IconSize.LARGE_TOOLBAR), (os.path.join(IMAGE_DIR, '16x16'), Gtk.IconSize.MENU), (os.path.join(IMAGE_DIR, '22x22'), Gtk.IconSize.BUTTON), ] items = [ ('gramps-db', _('Family Trees'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-address', _('Address'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-attribute', _('Attribute'), Gdk.ModifierType.CONTROL_MASK, 0, ''), #('gramps-bookmark', _('Bookmarks'), Gdk.ModifierType.CONTROL_MASK, 0, ''), #('gramps-bookmark-delete', _('Delete bookmark'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-bookmark-new', _('_Add bookmark'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-bookmark-edit', _('Organize Bookmarks'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-config', _('Configure'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-date', _('Date'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-date-edit', _('Edit Date'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-event', _('Events'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-family', _('Family'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-fanchart', _('Fan Chart'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-fanchartdesc', _('Descendant Fan Chart'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-font', _('Font'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-font-color', _('Font Color'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-font-bgcolor', _('Font Background Color'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-gramplet', _('Gramplets'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-geo', _('Geography'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-geo-mainmap', _('Geography'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-geo-altmap', _('Geography'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('geo-show-person', _('GeoPerson'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('geo-show-family', _('GeoFamily'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('geo-show-event', _('GeoEvents'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('geo-show-place', _('GeoPlaces'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-lock', _('Public'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-media', _('Media'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-merge', _('Merge'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-notes', _('Notes'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-parents', _('Parents'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-parents-add', _('Add Parents'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-parents-open', _('Select Parents'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-pedigree', _('Pedigree'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-person', _('Person'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-place', _('Places'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-relation', _('Relationships'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-reports', _('Reports'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-repository', _('Repositories'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-source', _('Sources'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-spouse', _('Add Spouse'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-tag', _('Tag'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-tag-new', _('New Tag'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-tools', _('Tools'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-tree-group', _('Grouped List'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-tree-list', _('List'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-tree-select', _('Select'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-unlock', _('Private'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-view', _('View'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-viewmedia', _('View'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-zoom-in', _('Zoom In'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-zoom-out', _('Zoom Out'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-zoom-fit-width', _('Fit Width'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-zoom-best-fit', _('Fit Page'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-citation', _('Citations'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ] #TODO# the following icons are not yet in new directory structure # they should be ported in the near future items_legacy = [ ('gramps-export', _('Export'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-import', _('Import'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-undo-history', _('Undo History'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ('gramps-url', _('URL'), Gdk.ModifierType.CONTROL_MASK, 0, ''), ] base_reg_stock_icons(iconpaths, extraiconsize, items+items_legacy)