def main(self): # return false finishes """ Generator which will be run in the background. """ self._boxes = [0] * (self.max_generations + 1) self._generations = {} self.gui.buffer.set_text("") active_handle = self.get_active('Person') if active_handle is None: return active_person = self.dbstate.db.get_person_from_handle(active_handle) #no wrap in Gramplet self.no_wrap() if active_person is None: return self.process_person(active_person.handle, 1, "f") # father self.process_person(active_person.handle, 0, "a") # active #FIXME: should be 1? self.process_person(active_person.handle, 1, "m") # mother gens = sorted(self._generations) self.append_text(_("\nBreakdown by generation:\n")) all = [active_person.handle] percent_sign = _("percent sign or text string|%") for g in gens: yield True count = len(self._generations[g]) handles = self._generations[g] self.append_text(" ") if g == 0: self.link(_("Generation 1"), 'PersonList', handles, tooltip=_("Double-click to see people in generation")) percent = glocale.format( '%.2f', 100) + percent_sign self.append_text(_(" has 1 of 1 individual (%(percent)s complete)\n") % {'percent': percent}) else: all.extend(handles) self.link(_("Generation %d") % g, 'PersonList', handles, tooltip=_("Double-click to see people in generation %d") % g) percent = glocale.format('%.2f', float(count)/2**(g-1) * 100) + percent_sign self.append_text( # translators: leave all/any {...} untranslated ngettext(" has {count_person} of {max_count_person} " "individuals ({percent} complete)\n", " has {count_person} of {max_count_person} " "individuals ({percent} complete)\n", 2**(g-1) ).format(count_person=count, max_count_person=2**(g-1), percent=percent) ) self.link(_("All generations"), 'PersonList', all, tooltip=_("Double-click to see all generations")) self.append_text( # translators: leave all/any {...} untranslated ngettext(" have {number_of} individual\n", " have {number_of} individuals\n", len(all) ).format(number_of=len(all)) ) # Set to a fixed font if self.box_mode == "UTF": start, end = self.gui.buffer.get_bounds() self.gui.buffer.apply_tag_by_name("fixed", start, end) self.append_text("", scroll_to="begin")
def __by_value(self, first, second): """ Method for sorting keys based on the values. """ fvalue = self.mapping[first] svalue = self.mapping[second] return glocale.strcoll(fvalue, svalue)
def compute_stats(self, hash): """ Returns the statistics of a dictionary of data """ #print "compute_stats", hash hashkeys = sorted(hash) count = sum(hash.values()) sumval = sum(k * hash[k] for k in hash) minval = min(hashkeys) maxval = max(hashkeys) median = 0 average = 0 if count > 0: current = 0 for k in hashkeys: if current + hash[k] > count/2: median = k break current += hash[k] average = sumval/float(count) retval = _("Statistics") + ":\n" retval += " " + _("Total") + ": %d\n" % count retval += " " + _("Minimum") + ": %d\n" % minval retval += " " + _("Average") + glocale.format_string(": %.1f\n", average) retval += " " + _("Median") + ": %d\n" % median retval += " " + _("Maximum") + ": %d\n" % maxval return retval
def compute_stats(self, hash): """ Returns the statistics of a dictionary of data """ # print "compute_stats", hash hashkeys = sorted(hash) count = sum(hash.values()) sumval = sum(k * hash[k] for k in hash) minval = min(hashkeys) maxval = max(hashkeys) median = 0 average = 0 if count > 0: current = 0 for k in hashkeys: if current + hash[k] > count / 2: median = k break current += hash[k] average = sumval / float(count) retval = _("Statistics") + ":\n" retval += " " + _("Total") + ": %d\n" % count retval += " " + _("Minimum") + ": %d\n" % minval retval += " " + _("Average") + glocale.format_string(": %.1f\n", average) retval += " " + _("Median") + ": %d\n" % median retval += " " + _("Maximum") + ": %d\n" % maxval return retval
def __init__(self, db, scol=0, order=Gtk.SortType.ASCENDING, search=None, skip=set(), sort_map=None): cput = time.clock() super(FlatBaseModel, self).__init__() #inheriting classes must set self.map to obtain the data self.prev_handle = None self.prev_data = None #GTK3 We leak ref, yes?? #self.set_property("leak_references", False) self.db = db #normally sort on first column, so scol=0 if sort_map: #sort_map is the stored order of the columns and if they are #enabled or not. We need to store on scol of that map self.sort_map = [ f for f in sort_map if f[0]] #we need the model col, that corresponds with scol col = self.sort_map[scol][1] else: col = scol self.sort_func = lambda x: glocale.sort_key(self.smap[col](x)) self.sort_col = scol self.skip = skip self._in_build = False self.node_map = FlatNodeMap() self.set_search(search) self._reverse = (order == Gtk.SortType.DESCENDING) self.rebuild_data() _LOG.debug(self.__class__.__name__ + ' __init__ ' + str(time.clock() - cput) + ' sec')
def __init__(self, ref, parent, sortkey, handle, secondary): if sortkey: self.name = sortkey #sortkey must be localized sort, so self.sortkey = glocale.sort_key(sortkey) if not self.sortkey: self.sortkey = glocale.sort_key('') else: self.name = '' self.sortkey = glocale.sort_key('') self.ref = ref self.handle = handle self.secondary = secondary self.parent = parent self.prev = None self.next = None self.children = []
def build_columns(self): #first the standard text columns with normal method EmbeddedList.build_columns(self) # now we add the two special columns # combobox for type colno = len(self.columns) name = self._column_combo[0] renderer = Gtk.CellRendererCombo() renderer.set_property('ellipsize', Pango.EllipsizeMode.END) # set up the comboentry editable no = NameOriginType() self.cmborig = Gtk.ListStore(GObject.TYPE_INT, GObject.TYPE_STRING) self.cmborigmap = no.get_map().copy() #sort the keys based on the value keys = sorted(self.cmborigmap, key=lambda x: glocale.sort_key(self.cmborigmap[x])) for key in keys: if key != no.get_custom(): self.cmborig.append(row=[key, self.cmborigmap[key]]) additional = self.dbstate.db.get_origin_types() if additional: for type in additional: if type: self.cmborig.append(row=[no.get_custom(), type]) renderer.set_property("model", self.cmborig) renderer.set_property("text-column", 1) renderer.set_property('editable', not self.dbstate.db.readonly) renderer.connect('editing_started', self.on_edit_start_cmb, colno) renderer.connect('edited', self.on_orig_edited, self._column_combo[3]) # add to treeview column = Gtk.TreeViewColumn(name, renderer, text=self._column_combo[3]) column.set_resizable(True) column.set_sort_column_id(self._column_combo[1]) column.set_min_width(self._column_combo[2]) column.set_expand(False) self.columns.append(column) self.tree.append_column(column) # toggle box for primary colno += 1 name = self._column_toggle[0] renderer = Gtk.CellRendererToggle() renderer.set_property('activatable', True) renderer.set_property('radio', True) renderer.connect('toggled', self.on_prim_toggled, self._column_toggle[3]) # add to treeview column = Gtk.TreeViewColumn(name, renderer, active=self._column_toggle[3]) column.set_resizable(False) column.set_sizing(Gtk.TreeViewColumnSizing.FIXED) column.set_alignment(0.5) column.set_sort_column_id(self._column_toggle[1]) column.set_max_width(self._column_toggle[2]) self.columns.append(column) self.tree.append_column(column)
def create_bargraph(self, hash, handles, title, column, graph_width, bin_size, max_val): """ Create a bargraph based on the data in hash. hash is a dict, like: hash = {12: 4, 20: 6, 35: 13, 50: 5} where the key is the age, and the value stored is the count. """ # first, binify: #print "create_bargraph", hash bin = [0] * int(max_val / bin_size) for value, hash_value in hash.items(): bin[int(value / bin_size)] += hash_value text = "" max_bin = float(max(bin)) if max_bin != 0: i = 0 self.append_text( "--------" + self.format("", graph_width - 4, fill="-", borders="++") + "-----\n") self.append_text( column.center(8) + self.format(title, graph_width - 4, align="center") + " % " + "\n") self.append_text( "--------" + self.format("", graph_width - 4, fill="-", borders="++") + "-----\n") for bin in bin: self.append_text((" %3d-%3d" % ( i * 5, (i + 1) * 5, ))) selected = self.make_handles_set(i * 5, (i + 1) * 5, handles) self.link( self.format("X" * int(bin / max_bin * (graph_width - 4)), graph_width - 4), 'PersonList', selected, tooltip=_("Double-click to see %d people") % len(selected)) procent = (float(len(selected)) / (float(sum(hash.values()))) * 100) self.append_text(glocale.format("%#5.2f", procent)) self.append_text("\n") i += 1 self.append_text( "--------" + self.format("", graph_width - 4, fill="-", borders="++") + "-----\n") self.append_text(" % " + self.ticks(graph_width - 4, start=0, stop=int(max_bin / (float(sum(hash.values()))) * 100)) + "\n\n") self.append_text(self.compute_stats(hash))
def get(self) -> Response: """Get available translations.""" catalog = GRAMPS_LOCALE.get_language_dict() return self.response( 200, [{ "language": language, "code": catalog[language] } for language in catalog], )
def build_columns(self): #first the standard text columns with normal method EmbeddedList.build_columns(self) # now we add the two special columns # combobox for type colno = len(self.columns) name = self._column_combo[0] renderer = Gtk.CellRendererCombo() renderer.set_property('ellipsize', Pango.EllipsizeMode.END) # set up the comboentry editable no = NameOriginType() self.cmborig = Gtk.ListStore(GObject.TYPE_INT, GObject.TYPE_STRING) self.cmborigmap = no.get_map().copy() #sort the keys based on the value keys = sorted(self.cmborigmap, key=lambda x: glocale.sort_key(self.cmborigmap[x])) for key in keys: if key != no.get_custom(): self.cmborig.append(row=[key, self.cmborigmap[key]]) additional = self.dbstate.db.get_origin_types() if additional: for type in additional: if type: self.cmborig.append(row=[no.get_custom(), type]) renderer.set_property("model", self.cmborig) renderer.set_property("text-column", 1) renderer.set_property('editable', not self.dbstate.db.readonly) renderer.connect('editing_started', self.on_edit_start_cmb, colno) renderer.connect('edited', self.on_orig_edited, self._column_combo[3]) # add to treeview column = Gtk.TreeViewColumn(name, renderer, text=self._column_combo[3]) column.set_resizable(True) column.set_sort_column_id(self._column_combo[1]) column.set_min_width(self._column_combo[2]) column.set_expand(False) self.columns.append(column) self.tree.append_column(column) # toggle box for primary colno += 1 name = self._column_toggle[0] renderer = Gtk.CellRendererToggle() renderer.set_property('activatable', True) renderer.set_property('radio', True) renderer.connect( 'toggled', self.on_prim_toggled, self._column_toggle[3]) # add to treeview column = Gtk.TreeViewColumn(name, renderer, active=self._column_toggle[3]) column.set_resizable(False) column.set_sizing(Gtk.TreeViewColumnSizing.FIXED) column.set_alignment(0.5) column.set_sort_column_id(self._column_toggle[1]) column.set_max_width(self._column_toggle[2]) self.columns.append(column) self.tree.append_column(column)
def get_locale_for_language(language: str, default: bool = False) -> GrampsLocale: """Get GrampsLocale set to specified language.""" if language is not None: catalog = GRAMPS_LOCALE.get_language_dict() for entry in catalog: if catalog[entry] == language: return GrampsLocale(lang=language) if default: return GRAMPS_LOCALE return None
def add_localization_option(menu, category): """ Insert an option for localizing the report into a different locale from the UI locale. """ trans = EnumeratedListOption(_("Translation"), glocale.DEFAULT_TRANSLATION_STR) trans.add_item(glocale.DEFAULT_TRANSLATION_STR, _("Default")) languages = glocale.get_language_dict() for language in sorted(languages, key=glocale.sort_key): trans.add_item(languages[language], language) trans.set_help(_("The translation to be used for the report.")) menu.add_option(category, "trans", trans)
def update_listings(): def register(ptype, **kwargs): #global plugins # need to take care of translated types kwargs["ptype"] = PTYPE_STR[ptype] plugins.append(SimpleNamespace(**kwargs)) listings = defaultdict(list) for addon in get_addons(): gprfile = find_gprfile(addon) for lang in languages: plugins = [] local_gettext = glocale.get_addon_translator( gprfile, languages=[lang, "en.UTF-8"]).gettext with open(gprfile) as f: code = compile(f.read(), gprfile, 'exec') exec(code, make_environment(_=local_gettext), { "register": register, "build_script": True }) for p in plugins: #print(p) for gver, grampsver in grampsversions: if addon.startswith("_") and gver == "5.0": continue tgz = get_tgz(addon, grampsver) tgzfile = f"{addon}.addon.tgz" d = dict( t=p.ptype, i=p.id, n=p.name, v=p.version, g=gver, # p.gramps_target_version, d=p.description, z=tgzfile) #print(d) listings[(grampsver, lang)].append(d) for gver, grampsver in grampsversions: print() print(grampsver) for lang in languages: listing = listings[(grampsver, lang)] listing_file = get_listing(grampsver, lang) print("-", listing_file) with open(listing_file, "w") as f: for d in listing: print(d, file=f)
def create_bargraph(self, hash, handles, title, column, graph_width, bin_size, max_val): """ Create a bargraph based on the data in hash. hash is a dict, like: hash = {12: 4, 20: 6, 35: 13, 50: 5} where the key is the age, and the value stored is the count. """ # first, binify: #print "create_bargraph", hash bin = [0] * int(max_val/bin_size) for value, hash_value in hash.items(): bin[int(value/bin_size)] += hash_value text = "" max_bin = float(max(bin)) if max_bin != 0: i = 0 self.append_text("--------" + self.format("", graph_width-4, fill = "-", borders="++") + "-----\n") self.append_text(column.center(8) + self.format(title, graph_width-4, align="center") + " % " + "\n") self.append_text("--------" + self.format("", graph_width-4, fill = "-", borders="++") + "-----\n") for bin in bin: self.append_text((" %3d-%3d" % (i * 5, (i+1)* 5,))) selected = self.make_handles_set(i * 5, (i+1) *5, handles) self.link(self.format("X" * int(bin/max_bin * (graph_width-4)), graph_width-4), 'PersonList', selected, tooltip=_("Double-click to see %d people") % len(selected)) procent = (float(len(selected)) / (float(sum(hash.values())))*100) self.append_text(glocale.format("%#5.2f", procent)) self.append_text("\n") i += 1 self.append_text("--------" + self.format("", graph_width-4, fill = "-", borders="++") + "-----\n") self.append_text(" % " + self.ticks(graph_width-4, start = 0, stop = int(max_bin/(float(sum(hash.values())))*100)) + "\n\n") self.append_text(self.compute_stats(hash))
def compute_stats(self, data): """ Create a table of statistics based on a dictionary of data. """ keys = sorted(data) count = sum(data.values()) sumval = sum(k * data[k] for k in data) minval = min(keys) maxval = max(keys) median = 0 average = 0 if count > 0: current = 0 for k in keys: if current + data[k] > count / 2: median = k break current += data[k] average = sumval / float(count) vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) label = Gtk.Label(label=_("Statistics") + ":") label.set_halign(Gtk.Align.START) vbox.pack_start(label, False, False, 0) grid = Gtk.Grid() grid.set_margin_start(12) grid.set_column_spacing(12) rows = [[_("Total"), "%d" % count], [_("Minimum"), "%d" % minval], [_("Average"), glocale.format_string("%.1f", average)], [_("Median"), "%d" % median], [_("Maximum"), "%d" % maxval]] for row, value in enumerate(rows): label1 = Gtk.Label(label=value[0] + ":") label1.set_halign(Gtk.Align.START) grid.attach(label1, 0, row, 1, 1) label2 = Gtk.Label(label=value[1]) label2.set_halign(Gtk.Align.END) grid.attach(label2, 1, row, 1, 1) vbox.pack_start(grid, False, False, 0) vbox.show_all() return vbox
def search_iter_sorted_column_flat(self, selection, cur_iter, text, count, n): """ Search among the currently set search-column for a cell starting with text It assumes that this column is currently sorted, and as a LIST_ONLY view it therefore contains index2hndl = model.node_map._index2hndl which is a _sorted_ list of (sortkey, handle) tuples """ model = self._treeview.get_model() search_column = self._treeview.get_search_column() is_tree = not (model.get_flags() & Gtk.TreeModelFlags.LIST_ONLY) # If there is a sort_key index, let's use it if not is_tree and hasattr(model, "node_map"): import bisect index2hndl = model.node_map._index2hndl # create lookup key from the appropriate sort_func # TODO: explicitely announce the data->sortkey func in models # sort_key = model.sort_func(text) sort_key = glocale.sort_key(text.lower()) srtkey_hndl = (sort_key, None) lo_bound = 0 # model.get_path(cur_iter) found_index = bisect.bisect_left(index2hndl, srtkey_hndl, lo=lo_bound) # if insert position is at tail, no match if found_index == len(index2hndl): return False srt_key, hndl = index2hndl[found_index] # Check if insert position match for real # (as insert position might not start with the text) if not model[found_index][search_column].lower().startswith( text.lower()): return False found_path = Gtk.TreePath( (model.node_map.real_path(found_index), )) self._treeview.scroll_to_cell(found_path, None, 1, 0.5, 0) selection.select_path(found_path) self._treeview.set_cursor(found_path) return True return False
def get(self, args: Dict, language: str) -> Response: """Get translation.""" try: strings = json.loads(args["strings"]) except json.JSONDecodeError: abort(400) catalog = GRAMPS_LOCALE.get_language_dict() for entry in catalog: if catalog[entry] == language: gramps_locale = GrampsLocale(lang=language) return self.response( 200, [{ "original": s, "translation": gramps_locale.translation.sgettext(s), } for s in strings], ) abort(404)
def search_iter_sorted_column_flat(self, selection, cur_iter, text, count, n): """ Search among the currently set search-column for a cell starting with text It assumes that this column is currently sorted, and as a LIST_ONLY view it therefore contains index2hndl = model.node_map._index2hndl which is a _sorted_ list of (sortkey, handle) tuples """ model = self._treeview.get_model() search_column = self._treeview.get_search_column() is_tree = not (model.get_flags() & Gtk.TreeModelFlags.LIST_ONLY) # If there is a sort_key index, let's use it if not is_tree and hasattr(model, "node_map"): import bisect index2hndl = model.node_map._index2hndl # create lookup key from the appropriate sort_func # TODO: explicitely announce the data->sortkey func in models # sort_key = model.sort_func(text) sort_key = glocale.sort_key(text.lower()) srtkey_hndl = (sort_key, "") lo_bound = 0 # model.get_path(cur_iter) found_index = bisect.bisect_left(index2hndl, srtkey_hndl, lo=lo_bound) # if insert position is at tail, no match if found_index == len(index2hndl): return False srt_key, hndl = index2hndl[found_index] # Check if insert position match for real # (as insert position might not start with the text) if not model[found_index][search_column].lower().startswith(text.lower()): return False found_path = Gtk.TreePath((model.node_map.real_path(found_index),)) self._treeview.scroll_to_cell(found_path, None, 1, 0.5, 0) selection.select_path(found_path) self._treeview.set_cursor(found_path) return True return False
def __init__(self, rlocale): self.iculocale = Locale(rlocale.collation) super().__init__(self.iculocale) # set the maximum number of buckets, the undocumented default is 99 # Latin + Greek + Cyrillic + Hebrew + Arabic + Tamil + Hiragana + # CJK Unified is about 206 different buckets self.maxLabelCount = 500 # pylint: disable=invalid-name # Add bucket labels for scripts other than the one for the output # which is being generated self.iculocale.addLikelySubtags() default_script = self.iculocale.getDisplayScript() used_scripts = [default_script] for lang_code in glocale.get_language_dict().values(): loc = Locale(lang_code) loc.addLikelySubtags() script = loc.getDisplayScript() if script not in used_scripts: used_scripts.append(script) super().addLabels(loc)
def __init__(self, db, uistate, track, handle_list, filtname, namespace): ManagedWindow.__init__(self, uistate, track, self) self.db = db self.filtname = filtname self.namespace = namespace self.define_glade('test', RULE_GLADE,) self.set_window( self.get_widget('test'), self.get_widget('test_title'), _('Filter Test')) self.setup_configs('interface.showresults', 450, 400) render = Gtk.CellRendererText() tree = self.get_widget('list') model = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING) tree.set_model(model) column_n = Gtk.TreeViewColumn(_('Name'), render, text=0) tree.append_column(column_n) column_n = Gtk.TreeViewColumn(_('ID'), render, text=1) tree.append_column(column_n) self.get_widget('test_close').connect('clicked', self.close) new_list = sorted( (self.sort_val_from_handle(h) for h in handle_list), key=lambda x: glocale.sort_key(x[0]) ) for s_, handle in new_list: name, gid = self.get_name_id(handle) model.append(row=[name, gid]) self.show()
def __init__(self, db, uistate, scol=0, order=Gtk.SortType.ASCENDING, search=None, skip=set(), sort_map=None): cput = time.clock() GObject.GObject.__init__(self) BaseModel.__init__(self) #inheriting classes must set self.map to obtain the data self.prev_handle = None self.prev_data = None #GTK3 We leak ref, yes?? #self.set_property("leak_references", False) self.db = db #normally sort on first column, so scol=0 if sort_map: #sort_map is the stored order of the columns and if they are #enabled or not. We need to store on scol of that map self.sort_map = [ f for f in sort_map if f[0]] #we need the model col, that corresponds with scol col = self.sort_map[scol][1] else: col = scol # get the function that maps data to sort_keys self.sort_func = lambda x: glocale.sort_key(self.smap[col](x)) self.sort_col = scol self.skip = skip self._in_build = False self.node_map = FlatNodeMap() self.set_search(search) self._reverse = (order == Gtk.SortType.DESCENDING) self.rebuild_data() _LOG.debug(self.__class__.__name__ + ' __init__ ' + str(time.clock() - cput) + ' sec')
def startElement(self, tag, attrs): """ Overridden class that handles the start of a XML element """ if tag == "sheet": self.s = StyleSheet(self.sheetlist.map["default"]) self.sname = attrs['name'] elif tag == "font": self.f = FontStyle() self.f.set_type_face(int(attrs['face'])) self.f.set_size(int(attrs['size'])) self.f.set_italic(int(attrs['italic'])) self.f.set_bold(int(attrs['bold'])) self.f.set_underline(int(attrs['underline'])) self.f.set_color(cnv2color(attrs['color'])) elif tag == "para": if 'description' in attrs: self.p.set_description(attrs['description']) self.p.set_right_margin(glocale.float(attrs['rmargin'])) self.p.set_left_margin(glocale.float(attrs['lmargin'])) self.p.set_first_indent(glocale.float(attrs['first'])) try: # This is needed to read older style files # lacking tmargin and bmargin self.p.set_top_margin(glocale.float(attrs['tmargin'])) self.p.set_bottom_margin(glocale.float(attrs['bmargin'])) except KeyError: pass self.p.set_padding(glocale.float(attrs['pad'])) self.p.set_alignment(int(attrs['align'])) self.p.set_right_border(int(attrs['rborder'])) self.p.set_header_level(int(attrs['level'])) self.p.set_left_border(int(attrs['lborder'])) self.p.set_top_border(int(attrs['tborder'])) self.p.set_bottom_border(int(attrs['bborder'])) self.p.set_background_color(cnv2color(attrs['bgcolor'])) elif tag == "style": self.p = ParagraphStyle() self.pname = attrs['name']
def __init__(self, filename=None, dirname=None, toplevel=None): """ Class Constructor: Returns a new instance of the Glade class :type filename: string :param filename: The name of the glade file to be used. Defaults to None :type dirname: string :param dirname: The directory to search for the glade file. Defaults to None which will cause a search for the file in the default directory followed by the directory of the calling module. :type toplevel: toplevel :param toplevel: The toplevel object to search for in the glade file. Defaults to None, which will cause a search for a toplevel matching the file name. :rtype: object reference :returns: reference to the newly-created Glade instance """ Gtk.Builder.__init__(self) self.set_translation_domain(glocale.get_localedomain()) filename_given = filename is not None dirname_given = dirname is not None # if filename not given, use module name to derive it if not filename_given: filename = sys._getframe(1).f_code.co_filename filename = os.path.basename(filename) filename = filename.rpartition('.')[0] + '.glade' filename = filename.lstrip('_').lower() # if dirname not given, use current directory if not dirname_given: dirname = sys._getframe(1).f_code.co_filename dirname = os.path.dirname(dirname) # try to find the glade file if filename_given and dirname_given: # both given -- use them path = os.path.join(dirname, filename) elif filename_given: # try default directory first path = os.path.join(GLADE_DIR, filename) if not os.path.exists(path): # then module directory path = os.path.join(dirname, filename) elif dirname_given: # dirname given -- use it path = os.path.join(dirname, filename) # neither filename nor dirname given. Try: # 1. derived filename in default directory # 2. derived filename in module directory else: path = os.path.join(GLADE_DIR, filename) if not os.path.exists(path): path = os.path.join(dirname, filename) # try to build Gtk objects from glade file. Let exceptions happen self.add_from_file(path) self.__dirname, self.__filename = os.path.split(path) # try to find the toplevel widget if toplevel: # toplevel is given self.__toplevel = self.get_object(toplevel) else: # toplevel not given # first, use filename as possible toplevel widget name self.__toplevel = self.get_object(filename.rpartition('.')[0]) # next try lowercase filename as possible widget name if not self.__toplevel: self.__toplevel = self.get_object( filename.rpartition('.')[0].lower()) if not self.__toplevel: # if no match found, search for first toplevel widget for obj in self.get_objects(): if hasattr(obj, 'get_toplevel'): self.__toplevel = obj.get_toplevel() break else: self.__toplevel = None
def listing(LANG): """ Listing files ../listing/{lang}.fr """ if 'GRAMPSPATH' in os.environ: GRAMPSPATH = os.environ['GRAMPSPATH'] else: GRAMPSPATH = '../../../..' try: sys.path.insert(0, GRAMPSPATH) os.environ['GRAMPS_RESOURCES'] = os.path.abspath(GRAMPSPATH) from gramps.gen.const import GRAMPS_LOCALE as glocale from gramps.gen.plug import make_environment, PTYPE_STR except ImportError: raise ValueError("Where is 'GRAMPSPATH' or 'GRAMPS_RESOURCES'?") LOCALE = glocale.get_language_list() compilation_all('ALL') listings = [] need = False # change the method fp = open('../listings/addons-%s.txt' % LANG, 'w') for addon in sorted(ADDONS): tgz_file = '%s.addon.tgz' % addon tgz_exists = os.path.isfile('../download/' + tgz_file) gprs = glob.glob('%(addon)s/*gpr.py' % {'addon': addon}) for gpr in gprs: gpr_file = gpr print(gpr_file, gprs) gpr_exists = os.path.isfile(gpr_file) mo_file = "%s/locale/%s/LC_MESSAGES/addon.mo" % (addon, LANG) mo_exists = os.path.isfile(mo_file) if tgz_exists and gpr_exists: gpr = open(gpr_file.encode('utf-8', errors='backslashreplace')) plug = dict([file.strip(), None] for file in gpr if file.strip()) name = ident = ptype = description = version = target = '' if mo_exists: LANGUAGE = LANG +".UTF-8" else: LANGUAGE = os.environ['LANGUAGE'] # print(plug) for p in plug: # print(repr(p)) if repr(p).startswith("'register("): ptype = p.replace("register(", "") ptype = ptype.replace(",", "") # incomplete dirty hack! print(glocale._get_translation(), LANG+".UTF-8") if LANG != LOCALE[0]: # mixup between LOCALE[0] and 'en' (avoid corruption) # need 'en.UTF-8' ! local_gettext = glocale.get_addon_translator(gpr_file, languages=[LANGUAGE]).ugettext #return else: local_gettext = glocale.get_addon_translator(gpr_file, languages=[LANG, "en"]).ugettext ptype = make_environment(_ = local_gettext)[ptype] # need to match translations build by Gramps program try: ptype = PTYPE_STR[ptype] except: # fallback and corruption with LOCALE[0] print(' wrong PTYPE: %s' % ptype) print(local_gettext('Tool')) # always corrupted by the locale print("LANGUAGE='%(language)s', LANG='%(lang)s'" % {'language': os.environ['LANGUAGE'], 'lang': os.environ['LANG']}) return if not (repr(p).startswith("'include_in_listing = False," ) or repr(p).startswith("'status = UNSTABLE,")): need = True else: print("Ignoring: '%s'" % addon) if repr(p).startswith("'id") or repr(p).startswith('"id' ): ident = p.replace('id', '') ident = ident.replace('=', '') ident = ident.replace(',', '') ident = ident.strip() #ident = repr(ident) if repr(p).startswith("'name") \ or repr(p).startswith('"name'): name = p.replace('name', '') name = name.replace('=', '') name = name.replace(',', '') name = name.strip() name = name.replace('_(', '') name = name.replace(')', '') name = name.replace('"', '') name = glocale._get_translation().ugettext(name) try: if name == local_gettext(name): print(addon, name, local_gettext(name)) name = repr(local_gettext(name)) except: print('Cannot use local_gettext on', repr(p)) # ugly workaround for name_accell (Export GEDCOM Extensions) name = name.replace('_accell ', '') name = name.replace('(GED2', '(GED2)') if repr(p).startswith("'description"): description = p.replace('description', '') description = description.replace('=', '') description = description.replace(',', '') description = description.strip() description = description.replace('_(', '') description = description.replace(')', '') description = description.replace('"', '') description = glocale._get_translation().ugettext(description) try: if description == local_gettext(description): print(addon, description, local_gettext(description)) description = repr(local_gettext(description)) except: print('Cannot use local_gettext on', repr(p)) if repr(p).startswith('"version'): version = p.replace('version', '') version = version.replace('=', '') version = version.replace(',', '') version = version.replace("'", "") version = version.replace('"', '') version = version.strip() version = repr(version) # workaround #7395~c38994 if description == '': description = "''" print(description, addon) if need: plugin = { 'n': name, 'i': ident, 't': repr(ptype), 'd': description, 'v': version, 'g': "'4.2'", 'z': repr(tgz_file), } #if name or ident or version or target == "": #print(plugin) fp.write('{"t":%(t)s,"i":%(i)s,"n":%(n)s,"v":%(v)s,"g":%(g)s,"d":%(d)s,"z":%(z)s}\n' % plugin) # print(plugin) listings.append(plugin) # for plugin in sorted(listings, key=lambda p: p["z"]): # fp.write('{"t":%(t)s,"i":%(i)s,"n":%(n)s,"v":%(v)s,"g":%(g)s,"d":%(d)s,"z":%(z)s}\n' % plugin) fp.close()
def add_menu_options(self, menu): """ Add options to the menu for the statistics report. """ ################################ category_name = _("Report Options") add_option = partial(menu.add_option, category_name) ################################ self.__filter = FilterOption(_("Filter"), 0) self.__filter.set_help(_("Determines what people are included " "in the report.")) add_option("filter", self.__filter) self.__filter.connect('value-changed', self.__filter_changed) self.__pid = PersonOption(_("Filter Person")) self.__pid.set_help(_("The center person for the filter.")) menu.add_option(category_name, "pid", self.__pid) self.__pid.connect('value-changed', self.__update_filters) sortby = EnumeratedListOption(_('Sort chart items by'), _options.SORT_VALUE) for item_idx in range(len(_options.opt_sorts)): item = _options.opt_sorts[item_idx] sortby.add_item(item_idx, item[2]) sortby.set_help(_("Select how the statistical data is sorted.")) add_option("sortby", sortby) reverse = BooleanOption(_("Sort in reverse order"), False) reverse.set_help(_("Check to reverse the sorting order.")) add_option("reverse", reverse) this_year = time.localtime()[0] year_from = NumberOption(_("People Born After"), 1700, 1, this_year) year_from.set_help(_("Birth year from which to include people.")) add_option("year_from", year_from) year_to = NumberOption(_("People Born Before"), this_year, 1, this_year) year_to.set_help(_("Birth year until which to include people")) add_option("year_to", year_to) no_years = BooleanOption(_("Include people without known birth years"), False) no_years.set_help(_("Whether to include people without " "known birth years.")) add_option("no_years", no_years) gender = EnumeratedListOption(_('Genders included'), Person.UNKNOWN) for item_idx in range(len(_options.opt_genders)): item = _options.opt_genders[item_idx] gender.add_item(item[0], item[2]) gender.set_help(_("Select which genders are included into " "statistics.")) add_option("gender", gender) bar_items = NumberOption(_("Max. items for a pie"), 8, 0, 20) bar_items.set_help(_("With fewer items pie chart and legend will be " "used instead of a bar chart.")) add_option("bar_items", bar_items) ################################ category_name = _("Report Options (2)") add_option = partial(menu.add_option, category_name) ################################ self._nf = stdoptions.add_name_format_option(menu, category_name) self._nf.connect('value-changed', self.__update_filters) self.__update_filters() stdoptions.add_private_data_option(menu, category_name) stdoptions.add_living_people_option(menu, category_name) stdoptions.add_localization_option(menu, category_name) ################################ # List of available charts on separate option tabs ################################ idx = 0 third = (len(_Extract.extractors) + 1) // 3 chart_types = [] for (chart_opt, ctuple) in _Extract.extractors.items(): chart_types.append((_(ctuple[1]), chart_opt, ctuple)) sorted_chart_types = sorted(chart_types, key=lambda x: glocale.sort_key(x[0])) for (translated_option_name, opt_name, ctuple) in sorted_chart_types: if idx >= (third * 2): category_name = _("Charts 3") elif idx >= third: category_name = _("Charts 2") else: category_name = _("Charts 1") opt = BooleanOption(translated_option_name, False) opt.set_help(_("Include charts with indicated data.")) menu.add_option(category_name, opt_name, opt) idx += 1 # Enable a couple of charts by default menu.get_option_by_name("data_gender").set_value(True) menu.get_option_by_name("data_ccount").set_value(True) menu.get_option_by_name("data_bmonth").set_value(True)
def button_press_event(self, treeview, event): index = None button_code = None event_time = None func = None if type(event) == bool: # enter button_code = 3 event_time = 0 selection = treeview.get_selection() store, paths = selection.get_selected_rows() tpath = paths[0] if len(paths) > 0 else None node = store.get_iter(tpath) if tpath else None if node: treeview.grab_focus() index = store.get_value(node, 0) # FIXME: make popup come where cursor is #rectangle = treeview.get_visible_rect() #column = treeview.get_column(0) #rectangle = treeview.get_cell_area("0:0", #x, y = rectangle.x, rectangle.y #func = lambda menu: (x, y, True) elif event.button == 3: button_code = 3 event_time = event.time x = int(event.x) y = int(event.y) path_info = treeview.get_path_at_pos(x, y) func = None if path_info is not None: path, col, cellx, celly = path_info selection = treeview.get_selection() store, paths = selection.get_selected_rows() tpath = paths[0] if len(paths) > 0 else None node = store.get_iter(tpath) if tpath else None if path: treeview.grab_focus() treeview.set_cursor(path, col, 0) if store and node: index = store.get_value(node, 0) # index Below, # you need index, treeview, path, button_code, # func, and event_time if index is not None: self.popup = Gtk.Menu() popup = self.popup menu_item = Gtk.MenuItem(label=_("Copy all")) menu_item.connect( "activate", lambda widget: text_to_clipboard( model_to_text(treeview.get_model()))) popup.append(menu_item) menu_item.show() # Now add more items to popup menu, if available if (index is not None and self._link[index]): # See details (edit, etc): objclass, handle = self._link[index] menu_item = Gtk.MenuItem(label=_("the object|See %s details") % glocale.trans_objclass(objclass)) menu_item.connect( "activate", lambda widget: self.on_table_doubleclick(treeview)) popup.append(menu_item) menu_item.show() # Add other items to menu: if (self._callback_leftclick or (index is not None and self._link[index])): objclass, handle = self._link[index] if objclass == 'Person': menu_item = Gtk.MenuItem( label=_("the object|Make %s active") % glocale.trans_objclass('Person')) menu_item.connect( "activate", lambda widget: self.on_table_click(treeview)) popup.append(menu_item) menu_item.show() if (self.simpledoc.doc.dbstate.db != self.simpledoc.doc.dbstate.db.basedb and (index is not None and self._link[index])): objclass, handle = self._link[index] if (objclass == 'Filter' and handle[0] in [ 'Person', 'Family', 'Place', 'Event', 'Repository', 'Note', 'Media', 'Citation', 'Source' ]): menu_item = Gtk.MenuItem(label=_("See data not in Filter")) menu_item.connect( "activate", lambda widget: self.show_not_in_filter(handle[0])) popup.append(menu_item) menu_item.show() # Show the popup menu: popup.popup(None, None, func, None, button_code, event_time) return True return False
def __init__(self, state, uistate, track, categories, msg, label=None, button_label=None, tool_tip=None, content=_REPORTS): """ Display the dialog box, and build up the list of available reports. This is used to build the selection tree on the left hand side of the dialog box. """ self.active = uistate.get_active('Person') self.imap = {} self.msg = msg self.content = content self._pmgr = GuiPluginManager.get_instance() ManagedWindow.__init__(self, uistate, track, self.__class__) self.state = state self.uistate = uistate self.dialog = Gtk.Builder() self.dialog.set_translation_domain(glocale.get_localedomain()) self.dialog.add_from_file(PLUGINS_GLADE) self.dialog.connect_signals({ "on_report_apply_clicked" : self.on_apply_clicked, "destroy_passed_object" : self.close, "on_delete_event": self.close, }) self.tree = self.dialog.get_object("tree") window = self.dialog.get_object("report") self.title = self.dialog.get_object("title") self.set_window(window, self.title, msg) self.store = Gtk.TreeStore(str) self.selection = self.tree.get_selection() self.selection.connect('changed', self.on_node_selected) col = Gtk.TreeViewColumn('', Gtk.CellRendererText(), text=0) self.tree.append_column(col) self.tree.set_model(self.store) self.description = self.dialog.get_object("description") if label: self.description.set_text(label) self.status = self.dialog.get_object("report_status") self.author_name = self.dialog.get_object("author_name") self.author_email = self.dialog.get_object("author_email") self.apply_button = self.dialog.get_object("apply") if button_label: self.apply_button.set_label(button_label) else: self.apply_button.set_label(_("_Apply")) self.apply_button.set_use_underline(True) if tool_tip: self.apply_button.set_tooltip_text(tool_tip) self.item = None if content == _REPORTS: reg_list = self._pmgr.get_reg_reports() elif content == _TOOLS: reg_list = self._pmgr.get_reg_tools() else: reg_list = [] self.build_plugin_tree(reg_list, categories) self.show()
from gramps.gen.db import DbTxn from gramps.gen.display.name import displayer as name_displayer from gramps.gen.plug import Gramplet, MenuOptions from gramps.gen.lib import MediaRef, Person from gramps.gen.lib.date import Today from gramps.gui.editors.editperson import EditPerson from gramps.gui.selectors import SelectorFactory from gramps.gen.plug.menu import BooleanOption, NumberOption from gramps.gui.plug import PluginWindows from gramps.gui.widgets import SelectionWidget, Region from gramps.gui.ddtargets import DdTargets from gramps.gui.display import display_url from gramps.gen.const import GRAMPS_LOCALE as glocale try: _ = glocale.get_addon_translator(__file__).sgettext except ValueError: _ = glocale.translation.sgettext #------------------------------------------------------------------------- # # face detection module # #------------------------------------------------------------------------- sys.path.append(os.path.abspath(os.path.dirname(__file__))) import facedetection #------------------------------------------------------------------------- # # configuration #
def __by_value_key(self, first): """ Method for sorting keys based on the values. """ return glocale.sort_key(self.mapping[first])
def __init__(self, filename=None, dirname=None, toplevel=None): """ Class Constructor: Returns a new instance of the Glade class :type filename: string :param filename: The name of the glade file to be used. Defaults to None :type dirname: string :param dirname: The directory to search for the glade file. Defaults to None which will cause a search for the file in the default directory followed by the directory of the calling module. :type toplevel: toplevel :param toplevel: The toplevel object to search for in the glade file. Defaults to None, which will cause a search for a toplevel matching the file name. :rtype: object reference :returns: reference to the newly-created Glade instance """ GObject.GObject.__init__(self) self.set_translation_domain(glocale.get_localedomain()) filename_given = filename is not None dirname_given = dirname is not None # if filename not given, use module name to derive it if not filename_given: filename = sys._getframe(1).f_code.co_filename filename = os.path.basename(filename) filename = filename.rpartition('.')[0] + '.glade' filename = filename.lstrip('_').lower() # if dirname not given, use current directory if not dirname_given: dirname = sys._getframe(1).f_code.co_filename dirname = os.path.dirname(dirname) # try to find the glade file if filename_given and dirname_given: # both given -- use them path = os.path.join(dirname, filename) elif filename_given: # try default directory first path = os.path.join(GLADE_DIR, filename) if not os.path.exists(path): # then module directory path = os.path.join(dirname, filename) elif dirname_given: # dirname given -- use it path = os.path.join(dirname, filename) # neither filename nor dirname given. Try: # 1. derived filename in default directory # 2. derived filename in module directory else: path = os.path.join(GLADE_DIR, filename) if not os.path.exists(path): path = os.path.join(dirname, filename) # try to build Gtk objects from glade file. Let exceptions happen self.add_from_file(uni_to_gui(path)) self.__dirname, self.__filename = os.path.split(path) # try to find the toplevel widget if toplevel: # toplevel is given self.__toplevel = self.get_object(toplevel) else: # toplevel not given # first, use filename as possible toplevel widget name self.__toplevel = self.get_object(filename.rpartition('.')[0]) # next try lowercase filename as possible widget name if not self.__toplevel: self.__toplevel = self.get_object( filename.rpartition('.')[0].lower()) if not self.__toplevel: # if no match found, search for first toplevel widget for obj in self.get_objects(): if hasattr(obj, 'get_toplevel'): self.__toplevel = obj.get_toplevel() break else: self.__toplevel = None
def create_toolbar(self, uimanager, window): """ Create a formatting toolbar. :returns: toolbar containing text formatting toolitems. :rtype: Gtk.Toolbar """ self.uimanager = uimanager # build the toolbar builder = Gtk.Builder() builder.set_translation_domain(glocale.get_localedomain()) builder.add_from_string(FORMAT_TOOLBAR) # define the actions... _actions = [ ('ITALIC', self._on_toggle_action_activate, '<PRIMARY>i', False), ('BOLD', self._on_toggle_action_activate, '<PRIMARY>b', False), ('UNDERLINE', self._on_toggle_action_activate, '<PRIMARY>u', False), ('FONTCOLOR', self._on_action_activate), ('HIGHLIGHT', self._on_action_activate), ('LINK', self._on_link_activate), ('CLEAR', self._format_clear_cb), ('STUndo', self.undo, '<primary>z'), ('STRedo', self.redo, '<primary><shift>z'), ] # the following are done manually rather than using actions fonts = SystemFonts() fontface = builder.get_object('Fontface') fontface.init(fonts.get_system_fonts(), shortlist=True, validator=None) fontface.set_entry_editable(False) fontface.connect('changed', make_cb( self._on_valueaction_changed, StyledTextTagType.FONTFACE)) # set initial value default = StyledTextTagType.STYLE_DEFAULT[StyledTextTagType.FONTFACE] self.fontface = fontface.get_child() self.fontface.set_text(str(default)) fontface.show() items = FONT_SIZES fontsize = builder.get_object('Fontsize') fontsize.init(items, shortlist=False, validator=is_valid_fontsize) fontsize.set_entry_editable(True) fontsize.connect('changed', make_cb( self._on_valueaction_changed, StyledTextTagType.FONTSIZE)) # set initial value default = StyledTextTagType.STYLE_DEFAULT[StyledTextTagType.FONTSIZE] self.fontsize = fontsize.get_child() self.fontsize.set_text(str(default)) fontsize.show() # create the action group and insert all the actions self.action_group = ActionGroup('Format', _actions, 'ste') act_grp = SimpleActionGroup() window.insert_action_group('ste', act_grp) window.set_application(uimanager.app) uimanager.insert_action_group(self.action_group, act_grp) self.undo_action = uimanager.get_action(self.action_group, "STUndo") self.redo_action = uimanager.get_action(self.action_group, "STRedo") # allow undo/redo to see actions if editable. self.textbuffer.connect('changed', self._on_buffer_changed) # undo/redo are initially greyed out, until something is changed self.undo_action.set_enabled(False) self.redo_action.set_enabled(False) # get the toolbar and set it's style toolbar = builder.get_object('ToolBar') return toolbar, self.action_group
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: # 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: 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
def __init__(self, state, uistate, track, categories, msg, label=None, button_label=None, tool_tip=None, content=_REPORTS): """ Display the dialog box, and build up the list of available reports. This is used to build the selection tree on the left hand side of the dialog box. """ self.active = uistate.get_active('Person') self.imap = {} self.msg = msg self.content = content self._pmgr = GuiPluginManager.get_instance() ManagedWindow.__init__(self, uistate, track, self.__class__) self.state = state self.uistate = uistate self.dialog = Gtk.Builder() self.dialog.set_translation_domain(glocale.get_localedomain()) self.dialog.add_from_file(PLUGINS_GLADE) self.dialog.connect_signals({ "on_report_apply_clicked": self.on_apply_clicked, "destroy_passed_object": self.close, "on_delete_event": self.close, }) self.tree = self.dialog.get_object("tree") window = self.dialog.get_object("report") self.title = self.dialog.get_object("title") self.set_window(window, self.title, msg) if content == _REPORTS: self.setup_configs('interface.reportplugindialog', 600, 400) elif content == _TOOLS: self.setup_configs('interface.toolplugindialog', 600, 400) else: raise ValueError("PluginDialog selection must be a report or tool") self.store = Gtk.TreeStore(str) self.selection = self.tree.get_selection() self.selection.connect('changed', self.on_node_selected) col = Gtk.TreeViewColumn('', Gtk.CellRendererText(), text=0) self.tree.append_column(col) self.tree.set_model(self.store) self.description = self.dialog.get_object("description") if label: self.description.set_text(label) self.status = self.dialog.get_object("report_status") self.author_name = self.dialog.get_object("author_name") self.author_email = self.dialog.get_object("author_email") self.apply_button = self.dialog.get_object("apply") if button_label: self.apply_button.set_label(button_label) else: self.apply_button.set_label(_("_Apply")) self.apply_button.set_use_underline(True) if tool_tip: self.apply_button.set_tooltip_text(tool_tip) self.item = None if content == _REPORTS: reg_list = self._pmgr.get_reg_reports() elif content == _TOOLS: reg_list = self._pmgr.get_reg_tools() else: reg_list = [] self.build_plugin_tree(reg_list, categories) self.show()
def get(self) -> Response: """Get active database and application related metadata information.""" catalog = GRAMPS_LOCALE.get_language_dict() for entry in catalog: if catalog[entry] == GRAMPS_LOCALE.language[0]: language_name = entry break db_handle = self.db_handle db_name = db_handle.get_dbname() db_type = "Unknown" dbstate = DbState() db_summary = CLIDbManager(dbstate).family_tree_summary( database_names=[db_name]) if len(db_summary) == 1: db_key = GRAMPS_LOCALE.translation.sgettext("Database") for key in db_summary[0]: if key == db_key: db_type = db_summary[0][key] result = { "database": { "id": db_handle.get_dbid(), "name": db_name, "type": db_type, }, "default_person": db_handle.get_default_handle(), "gramps": { "version": ENV["VERSION"], }, "gramps_webapi": { "schema": VERSION, "version": VERSION, }, "locale": { "lang": GRAMPS_LOCALE.lang, "language": GRAMPS_LOCALE.language[0], "description": language_name, "incomplete_translation": bool(GRAMPS_LOCALE.language[0] in INCOMPLETE_TRANSLATIONS), }, "object_counts": { "people": db_handle.get_number_of_people(), "families": db_handle.get_number_of_families(), "sources": db_handle.get_number_of_sources(), "citations": db_handle.get_number_of_citations(), "events": db_handle.get_number_of_events(), "media": db_handle.get_number_of_media(), "places": db_handle.get_number_of_places(), "repositories": db_handle.get_number_of_repositories(), "notes": db_handle.get_number_of_notes(), "tags": db_handle.get_number_of_tags(), }, "researcher": db_handle.get_researcher(), "surnames": db_handle.get_surname_list(), } data = db_handle.get_summary() db_version_key = GRAMPS_LOCALE.translation.sgettext("Database version") db_module_key = GRAMPS_LOCALE.translation.sgettext( "Database module version") db_schema_key = GRAMPS_LOCALE.translation.sgettext("Schema version") for item in data: if item == db_version_key: result["database"]["version"] = data[item] elif item == db_module_key: result["database"]["module"] = data[item] elif item == db_schema_key: result["database"]["schema"] = data[item] return self.response(200, result)
def is_listing(LANG): """ Listing files ../listing/{lang}.fr """ if 'GRAMPSPATH' in os.environ: GRAMPSPATH = os.environ['GRAMPSPATH'] else: GRAMPSPATH = '../../../..' try: sys.path.insert(0, GRAMPSPATH) os.environ['GRAMPS_RESOURCES'] = os.path.abspath(GRAMPSPATH) from gramps.gen.const import GRAMPS_LOCALE as glocale from gramps.gen.plug import make_environment, PTYPE_STR except ImportError: raise ValueError("Where is 'GRAMPSPATH' or 'GRAMPS_RESOURCES'?") def register(ptype, **kwargs): global plugins kwargs['ptype'] = PTYPE_STR[ptype] # related to gramps translations plugins.append(kwargs) cmd_arg = LANG # Make the locale for for any local languages for Addon: for addon in ADDONS: for po in glob.glob('%(addon)s/po/*-local.po' % {'addon': addon}): # Compile locale = os.path.basename(po[:-9]) os.system('mkdir -p "%(addon)s/locale/%(locale)s/LC_MESSAGES/"' % {'addon': addon, 'locale': locale}) os.system('msgfmt %(po)s -o "%(addon)s/locale/%(locale)s/LC_MESSAGES/addon.mo"' % {'po': po, 'addon': addon, 'locale': locale}) # Get all languages from all addons: languages = set(['en']) for addon in [file for file in glob.glob('*') if os.path.isdir(file)]: for po in glob.glob('%(addon)s/po/*-local.po' % {'addon': addon}): length = len(po) locale = po[length - 11:length - 9] (locale_path, locale) = po.rsplit('/', 1) languages.add(locale[:-9]) # next, create/edit a file for all languages listing plugins for lang in languages: print("----Building listing for '%s'..." % lang) listings = [] for addon in ADDONS: for gpr in glob.glob('%(addon)s/*.gpr.py' % {'addon': addon}): print(gpr) # Make fallback language English (rather than current LANG) local_gettext = glocale.get_addon_translator(gpr, languages=[lang, 'en.UTF-8']).gettext plugins = [] with open(gpr.encode('utf-8', errors='backslashreplace' )) as f: code = compile(f.read(), gpr.encode('utf-8', errors='backslashreplace'), 'exec') #exec(code, make_environment(_=local_gettext), #{"register": register}) for p in plugins: tgz_file = '%s.addon.tgz' % gpr.split('/', 1)[0] tgz_exists = os.path.isfile('../download/' + tgz_file) if p.get('include_in_listing', True) and tgz_exists: plugin = { 'n': repr(p['name']), 'i': repr(p['id']), 't': repr(p['ptype']), 'd': repr(p['description']), 'v': repr(p['version']), 'g': repr(p['gramps_target_version']), 'z': repr(tgz_file), } listings.append(plugin) else: print(" ignoring '%s'" % p['name'])
def by_value(self, val): """ Method for sorting keys based on the values. """ return glocale.sort_key(self.mapping[val])
def listing(LANG): """ Listing files ../listing/{lang}.fr """ if 'GRAMPSPATH' in os.environ: GRAMPSPATH = os.environ['GRAMPSPATH'] else: GRAMPSPATH = '../../../..' try: sys.path.insert(0, GRAMPSPATH) os.environ['GRAMPS_RESOURCES'] = os.path.abspath(GRAMPSPATH) from gramps.gen.const import GRAMPS_LOCALE as glocale from gramps.gen.plug import make_environment, PTYPE_STR except ImportError: raise ValueError("Where is 'GRAMPSPATH' or 'GRAMPS_RESOURCES'?") LOCALE = glocale.get_language_list() compilation_all('ALL') listings = [] need = False # change the method fp = open('../listings/addons-%s.txt' % LANG, 'w') for addon in sorted(ADDONS): tgz_file = '%s.addon.tgz' % addon tgz_exists = os.path.isfile('../download/' + tgz_file) gprs = glob.glob('%(addon)s/*gpr.py' % {'addon': addon}) for gpr in gprs: gpr_file = gpr print(gpr_file, gprs) gpr_exists = os.path.isfile(gpr_file) mo_file = "%s/locale/%s/LC_MESSAGES/addon.mo" % (addon, LANG) mo_exists = os.path.isfile(mo_file) if tgz_exists and gpr_exists: gpr = open(gpr_file.encode('utf-8', errors='backslashreplace')) plug = dict([file.strip(), None] for file in gpr if file.strip()) name = ident = ptype = description = version = target = '' if mo_exists: LANGUAGE = LANG + ".UTF-8" else: LANGUAGE = os.environ['LANGUAGE'] # print(plug) for p in plug: # print(repr(p)) if repr(p).startswith("'register("): ptype = p.replace("register(", "") ptype = ptype.replace(",", "") # incomplete dirty hack! print(glocale._get_translation(), LANG + ".UTF-8") if LANG != LOCALE[0]: # mixup between LOCALE[0] and 'en' (avoid corruption) # need 'en.UTF-8' ! local_gettext = glocale.get_addon_translator( gpr_file, languages=[LANGUAGE]).ugettext #return else: local_gettext = glocale.get_addon_translator( gpr_file, languages=[LANG, "en"]).ugettext ptype = make_environment(_=local_gettext)[ptype] # need to match translations build by Gramps program try: ptype = PTYPE_STR[ptype] except: # fallback and corruption with LOCALE[0] print(' wrong PTYPE: %s' % ptype) print(local_gettext( 'Tool')) # always corrupted by the locale print( "LANGUAGE='%(language)s', LANG='%(lang)s'" % { 'language': os.environ['LANGUAGE'], 'lang': os.environ['LANG'] }) return if not (repr(p).startswith("'include_in_listing = False,") or repr(p).startswith("'status = UNSTABLE,")): need = True else: print("Ignoring: '%s'" % addon) if repr(p).startswith("'id") or repr(p).startswith('"id'): ident = p.replace('id', '') ident = ident.replace('=', '') ident = ident.replace(',', '') ident = ident.strip() #ident = repr(ident) if repr(p).startswith("'name") \ or repr(p).startswith('"name'): name = p.replace('name', '') name = name.replace('=', '') name = name.replace(',', '') name = name.strip() name = name.replace('_(', '') name = name.replace(')', '') name = name.replace('"', '') name = glocale._get_translation().ugettext(name) try: if name == local_gettext(name): print(addon, name, local_gettext(name)) name = repr(local_gettext(name)) except: print('Cannot use local_gettext on', repr(p)) # ugly workaround for name_accell (Export GEDCOM Extensions) name = name.replace('_accell ', '') name = name.replace('(GED2', '(GED2)') if repr(p).startswith("'description"): description = p.replace('description', '') description = description.replace('=', '') description = description.replace(',', '') description = description.strip() description = description.replace('_(', '') description = description.replace(')', '') description = description.replace('"', '') description = glocale._get_translation().ugettext( description) try: if description == local_gettext(description): print(addon, description, local_gettext(description)) description = repr(local_gettext(description)) except: print('Cannot use local_gettext on', repr(p)) if repr(p).startswith('"version'): version = p.replace('version', '') version = version.replace('=', '') version = version.replace(',', '') version = version.replace("'", "") version = version.replace('"', '') version = version.strip() version = repr(version) # workaround #7395~c38994 if description == '': description = "''" print(description, addon) if need: plugin = { 'n': name, 'i': ident, 't': repr(ptype), 'd': description, 'v': version, 'g': "'4.2'", 'z': repr(tgz_file), } #if name or ident or version or target == "": #print(plugin) fp.write( '{"t":%(t)s,"i":%(i)s,"n":%(n)s,"v":%(v)s,"g":%(g)s,"d":%(d)s,"z":%(z)s}\n' % plugin) # print(plugin) listings.append(plugin) # for plugin in sorted(listings, key=lambda p: p["z"]): # fp.write('{"t":%(t)s,"i":%(i)s,"n":%(n)s,"v":%(v)s,"g":%(g)s,"d":%(d)s,"z":%(z)s}\n' % plugin) fp.close()
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
def register(ptype, **kwargs): global plugins kwargs["ptype"] = PTYPE_STR[ptype] # need to take care of translated types plugins.append(kwargs) # get current build numbers from English listing fp_in = open(r("../addons/%(gramps_version)s/listings/addons-en.txt"), "r", encoding="utf-8") addons = {} for line in fp_in: dictionary = eval(line) if dictionary["i"] in addons: print("Repeated addon ID:", dictionary["i"]) else: addons[dictionary["i"]] = dictionary # go through all gpr's, check their build versions for gpr in glob.glob(r('''*/*.gpr.py''')): local_gettext = glocale.get_addon_translator( gpr, languages=["en", "en.UTF-8"]).gettext plugins = [] with open(gpr.encode("utf-8", errors="backslashreplace")) as f: code = compile(f.read(), gpr.encode("utf-8", errors="backslashreplace"), 'exec') exec(code, make_environment(_=local_gettext), {"register": register}) for p in plugins: gpr_version = p.get("version", None) id = p.get("id", None) if id not in addons: print("Missing in listing:", id) else: add_version = addons[id]["v"] if gpr_version != add_version:
strings as needed. Then remove the strings from your language's :class:`DateParserXX` and :class:`DateHandlerXX` classes. """ if __name__ == '__main__': import sys from ..utils.grampslocale import GrampsLocale from gramps.gen.const import GRAMPS_LOCALE as glocale from ._grampslocale import (_deprecated_long_months as old_long, _deprecated_short_months as old_short, _deprecated_long_days as old_days) from ._datedisplay import DateDisplay import gettext lang = glocale.lang lang_short = lang[:2] available_langs = glocale.get_available_translations() if glocale.check_available_translations(lang) is None: print ("Translation for current language {lang} not available.\n" "Available translations: {list}.\n" "Does po/{lang_short}*.po exist in gramps source tree?!\n" "Please set your LANG / LC_ALL environment to something else...\n".format( lang=lang, list=available_langs, lang_short=lang_short), file=sys.stderr) sys.exit(1) print ("# Generating snippets for {}*.po\n" "# Available languages: {}".format( lang_short, available_langs)) glocale = GrampsLocale(languages=(lang)) dd = glocale.date_displayer ds = dd._ds
# #------------------------------------------------------------------------ from gramps.gen.const import USER_PLUGINS from gramps.gui.glade import Glade from gramps.gui.managedwindow import GrampsWindowManager, ManagedWindow from gramps.gui.plug import tool #------------------------------------------------------------------------ # # Internationalisation # #------------------------------------------------------------------------ from gramps.gen.const import GRAMPS_LOCALE as glocale try: _trans = glocale.get_addon_translator(__file__) except ValueError: _trans = glocale.translation _ = _trans.gettext import gramps.gen.constfunc # Handlers and signal class class GladeHandlers(): """ Experimental try for event functions via python and .glade files """ def on_quit_clicked(): Gtk.main_quit()
def button_press_event(self, treeview, event): index = None button_code = None event_time = None func = None if type(event) == bool: # enter button_code = 3 event_time = 0 selection = treeview.get_selection() store, paths = selection.get_selected_rows() tpath = paths[0] if len(paths) > 0 else None node = store.get_iter(tpath) if tpath else None if node: treeview.grab_focus() index = store.get_value(node, 0) # FIXME: make popup come where cursor is #rectangle = treeview.get_visible_rect() #column = treeview.get_column(0) #rectangle = treeview.get_cell_area("0:0", #x, y = rectangle.x, rectangle.y #func = lambda menu: (x, y, True) elif event.button == 3: button_code = 3 event_time = event.time x = int(event.x) y = int(event.y) path_info = treeview.get_path_at_pos(x, y) func = None if path_info is not None: path, col, cellx, celly = path_info selection = treeview.get_selection() store, paths = selection.get_selected_rows() tpath = paths[0] if len(paths) > 0 else None node = store.get_iter(tpath) if tpath else None if path: treeview.grab_focus() treeview.set_cursor(path, col, 0) if store and node: index = store.get_value(node, 0) # index Below, # you need index, treeview, path, button_code, # func, and event_time if index is not None: self.popup = Gtk.Menu() popup = self.popup menu_item = Gtk.MenuItem(label=_("Copy all")) menu_item.connect("activate", lambda widget: text_to_clipboard(model_to_text(treeview.get_model()))) popup.append(menu_item) menu_item.show() # Now add more items to popup menu, if available if (index is not None and self._link[index]): # See details (edit, etc): objclass, handle = self._link[index] menu_item = Gtk.MenuItem(label=_("the object|See %s details") % glocale.trans_objclass(objclass)) menu_item.connect("activate", lambda widget: self.on_table_doubleclick(treeview)) popup.append(menu_item) menu_item.show() # Add other items to menu: if (self._callback_leftclick or (index is not None and self._link[index])): objclass, handle = self._link[index] if objclass == 'Person': menu_item = Gtk.MenuItem(label=_("the object|Make %s active") % glocale.trans_objclass('Person')) menu_item.connect("activate", lambda widget: self.on_table_click(treeview)) popup.append(menu_item) menu_item.show() if (self.simpledoc.doc.dbstate.db != self.simpledoc.doc.dbstate.db.basedb and (index is not None and self._link[index])): objclass, handle = self._link[index] if (objclass == 'Filter' and handle[0] in ['Person', 'Family', 'Place', 'Event', 'Repository', 'Note', 'MediaObject', 'Citation', 'Source']): menu_item = Gtk.MenuItem(label=_("See data not in Filter")) menu_item.connect("activate", lambda widget: self.show_not_in_filter(handle[0])) popup.append(menu_item) menu_item.show() # Show the popup menu: popup.popup(None, None, func, None, button_code, event_time) return True return False
# GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # $Id$ # from gramps.gui.listmodel import ListModel, NOSORT from gramps.gen.utils.db import navigation_label from gramps.gen.plug import Gramplet from gramps.gui.widgets import Photo from gramps.gen.const import GRAMPS_LOCALE as glocale try: _trans = glocale.get_addon_translator(__file__) except ValueError: _trans = glocale.translation _ = _trans.gettext from gramps.gen.utils.file import media_path_full from gi.repository import Gtk class MediaBrowser(Gramplet): """ Displays an object tree and a media preview for a person. """ def init(self): self.gui.WIDGET = self.build_gui() self.gui.get_container_widget().remove(self.gui.textview) self.gui.get_container_widget().add_with_viewport(self.gui.WIDGET) self.gui.WIDGET.show()
def __init__(self, filename=None, dirname=None, toplevel=None, also_load=[]): """ Class Constructor: Returns a new instance of the Glade class :type filename: string or None :param filename: The name of the glade file to be used. Defaults to None :type dirname: string or None :param dirname: The directory to search for the glade file. Defaults to None which will cause a search for the file in the default directory followed by the directory of the calling module. :type toplevel: string or None :param toplevel: The toplevel object to search for in the glade file. Defaults to None, which will cause a search for a toplevel matching the supplied name. :type also_load: list of strings :param also_load: Additional toplevel objects to load from the glade file. These are typically liststore or other objects needed to operate the toplevel object. Defaults to [] (empty list), which will not load additional objects. :rtype: object reference :returns: reference to the newly-created Glade instance This operates in two modes; when no toplevel parameter is supplied, the entire Glade file is loaded. It is the responsibility of the user to make sure ALL toplevel objects are destroyed. When a toplevel parameter is supplied, only that object and any additional objects requested in the also_load parameter are loaded. The user only has to destroy the requested toplevel objects. """ Gtk.Builder.__init__(self) self.set_translation_domain(glocale.get_localedomain()) filename_given = filename is not None dirname_given = dirname is not None # if filename not given, use module name to derive it if not filename_given: filename = sys._getframe(1).f_code.co_filename filename = os.path.basename(filename) filename = filename.rpartition('.')[0] + '.glade' filename = filename.lstrip('_').lower() # if dirname not given, use current directory if not dirname_given: dirname = sys._getframe(1).f_code.co_filename dirname = os.path.dirname(dirname) # try to find the glade file if filename_given and dirname_given: # both given -- use them path = os.path.join(dirname, filename) elif filename_given: # try default directory first path = os.path.join(GLADE_DIR, filename) if not os.path.exists(path): # then module directory path = os.path.join(dirname, filename) elif dirname_given: # dirname given -- use it path = os.path.join(dirname, filename) # neither filename nor dirname given. Try: # 1. derived filename in default directory # 2. derived filename in module directory else: path = os.path.join(GLADE_DIR, filename) if not os.path.exists(path): path = os.path.join(dirname, filename) # try to build Gtk objects from glade file. Let exceptions happen self.__dirname, self.__filename = os.path.split(path) # try to find the toplevel widget # toplevel is given if toplevel: loadlist = [toplevel] + also_load self.add_objects_from_file(path, loadlist) self.__toplevel = self.get_object(toplevel) # toplevel not given else: self.add_from_file(path) # first, use filename as possible toplevel widget name self.__toplevel = self.get_object(filename.rpartition('.')[0]) # next try lowercase filename as possible widget name if not self.__toplevel: self.__toplevel = self.get_object( filename.rpartition('.')[0].lower()) if not self.__toplevel: # if no match found, search for first toplevel widget for obj in self.get_objects(): if hasattr(obj, 'get_toplevel'): self.__toplevel = obj.get_toplevel() break else: self.__toplevel = None