def load_on_reg(dbstate, uistate, plugin): """ Runs when plugin is registered. """ if uistate: # It is necessary to avoid load GUI elements when run under CLI mode. # So we just don't load it at all. # Monkey patch my version of Prefs into the system from gi.repository.Gtk import (Settings, ToolbarStyle, CssProvider, StyleContext, STYLE_PROVIDER_PRIORITY_APPLICATION) from gi.repository.Gdk import Screen from gramps.gui.configure import GrampsPreferences from gramps.gen.config import config sys.path.append(os.path.abspath(os.path.dirname(__file__))) from themes import MyPrefs GrampsPreferences.__init__ = MyPrefs.__init__ gtksettings = Settings.get_default() # save default (original) settings for later, if not already done if not hasattr(GrampsPreferences, 'def_dark'): GrampsPreferences.def_dark = gtksettings.get_property( 'gtk-application-prefer-dark-theme') GrampsPreferences.def_theme = gtksettings.get_property( 'gtk_theme_name') GrampsPreferences.def_font = gtksettings.get_property( 'gtk-font-name') # establish config Settings and load current prefs if available config.register('preferences.theme-dark-variant', '') value = config.get('preferences.theme-dark-variant') if value: gtksettings.set_property('gtk-application-prefer-dark-theme', value == 'True') config.register('preferences.theme', '') value = config.get('preferences.theme') if value: gtksettings.set_property('gtk_theme_name', value) config.register('preferences.font', '') value = config.get('preferences.font') if value: gtksettings.set_property('gtk-font-name', value) config.register('interface.toolbar-text', False) value = config.get('interface.toolbar-text') toolbar = uistate.uimanager.get_widget('ToolBar') toolbar.set_style(ToolbarStyle.BOTH if value else ToolbarStyle.ICONS) config.register('interface.fixed-scrollbar', '0') value = config.get('interface.fixed-scrollbar') if value: gtksettings.set_property('gtk-primary-button-warps-slider', not value) MyPrefs.provider = CssProvider() css = ('* { -GtkScrollbar-has-backward-stepper: 1; ' '-GtkScrollbar-has-forward-stepper: 1; }') MyPrefs.provider.load_from_data(css.encode('utf8')) StyleContext.add_provider_for_screen( Screen.get_default(), MyPrefs.provider, STYLE_PROVIDER_PRIORITY_APPLICATION)
def setup_configs(self, config_base, default_width, default_height, default_horiz_position=None, default_vert_position=None): """ Helper method to setup the window's configuration settings @param config_base: the common config name, e.g. 'interface.clipboard' @type config_base: str @param default_width, default_height: the default width and height @type default_width, default_height: int @param default_horiz_position, default_vert_position: if either is None then that position is centered on the parent, else explicitly set @type default_horiz_position, default_vert_position: int or None """ self.width_key = config_base + '-width' self.height_key = config_base + '-height' self.horiz_position_key = config_base + '-horiz-position' self.vert_position_key = config_base + '-vert-position' (p_width, p_height) = self.parent_window.get_size() (p_horiz, p_vert) = self.parent_window.get_position() if default_horiz_position is None: default_horiz_position = p_horiz + ((p_width - default_width) // 2) if default_vert_position is None: default_vert_position = p_vert + ((p_height - default_height) // 2) config.register(self.width_key, default_width) config.register(self.height_key, default_height) config.register(self.horiz_position_key, default_horiz_position) config.register(self.vert_position_key, default_vert_position) self._set_size() self._set_position()
def setup_configs(self, config_base, default_width, default_height, default_horiz_position=None, default_vert_position=None, p_width=None, p_height=None): # for fullscreen """ Helper method to setup the window's configuration settings @param config_base: the common config name, e.g. 'interface.clipboard' @type config_base: str @param default_width, default_height: the default width and height @type default_width, default_height: int @param default_horiz_position, default_vert_position: if either is None then that position is centered on the parent, else explicitly set @type default_horiz_position, default_vert_position: int or None @param p_width, p_height: the parent's width and height @type p_width, p_height: int or None """ self.width_key = config_base + '-width' self.height_key = config_base + '-height' self.horiz_position_key = config_base + '-horiz-position' self.vert_position_key = config_base + '-vert-position' if p_width is None and p_height is None: # default case (p_width, p_height) = self.parent_window.get_size() (p_horiz, p_vert) = self.parent_window.get_position() else: p_horiz = p_vert = 0 # fullscreen if default_horiz_position is None: default_horiz_position = p_horiz + ((p_width - default_width) // 2) if default_vert_position is None: default_vert_position = p_vert + ((p_height - default_height) // 2) config.register(self.width_key, default_width) config.register(self.height_key, default_height) config.register(self.horiz_position_key, default_horiz_position) config.register(self.vert_position_key, default_vert_position) self._set_size() self._set_position()
from gi import Repository from gramps.gen.config import config from gramps.gen.const import GRAMPS_LOCALE as glocale from gramps.gen.plug._pluginreg import register, VIEW, STABLE #, END, START _ = glocale.translation.gettext # Attempting to import goocanvas gives an error dialog if goocanvas is not # available so test first and log just a warning to the console instead. try: config.get('interface.ignore-goocanvas') except: config.register('interface.ignore-goocanvas', False) GOOCANVAS = False REPOSITORY = Repository.get_default() if REPOSITORY.enumerate_versions("GooCanvas"): try: # current goocanvas support GTK3 import gi gi.require_version('GooCanvas', '2.0') from gi.repository import GooCanvas as goocanvas GOOCANVAS = True except: pass if not GOOCANVAS: from gramps.gen.config import config if not config.get('interface.ignore-goocanvas'): from gramps.gen.constfunc import has_display if has_display():
def __init__(self, namespace, dbstate, uistate, track, filterdb, val, label, update, filter_name): ManagedWindow.__init__(self, uistate, track, EditRule) self.namespace = namespace self.dbstate = dbstate self.db = dbstate.db self.filterdb = filterdb self.update_rule = update self.filter_name = filter_name self.active_rule = val self.define_glade('rule_editor', RULE_GLADE) self.set_window(self.get_widget('rule_editor'), self.get_widget('rule_editor_title'), label) self.setup_configs('interface.edit-rule', 600, 450) self.window.hide() self.valuebox = self.get_widget('valuebox') self.rname_filter = self.get_widget('ruletreefilter') self.rname = self.get_widget('ruletree') self.rule_name = self.get_widget('rulename') self.description = self.get_widget('description') self.notebook = Gtk.Notebook() self.notebook.set_show_tabs(0) self.notebook.set_show_border(0) self.notebook.show() self.valuebox.pack_start(self.notebook, True, True, 0) self.page_num = 0 self.page = [] self.class2page = {} if self.namespace == 'Person': class_list = rules.person.editor_rule_list elif self.namespace == 'Family': class_list = rules.family.editor_rule_list elif self.namespace == 'Event': class_list = rules.event.editor_rule_list elif self.namespace == 'Source': class_list = rules.source.editor_rule_list elif self.namespace == 'Citation': class_list = rules.citation.editor_rule_list elif self.namespace == 'Place': class_list = rules.place.editor_rule_list elif self.namespace == 'Media': class_list = rules.media.editor_rule_list elif self.namespace == 'Repository': class_list = rules.repository.editor_rule_list elif self.namespace == 'Note': class_list = rules.note.editor_rule_list for class_obj in class_list: arglist = class_obj.labels vallist = [] tlist = [] pos = 0 l2 = Gtk.Label(label=class_obj.name, halign=Gtk.Align.START) l2.show() grid = Gtk.Grid() grid.set_border_width(12) grid.set_column_spacing(6) grid.set_row_spacing(6) grid.show() for v in arglist: if isinstance(v, tuple): # allows filter to create its own GUI element l = Gtk.Label(label=v[0], halign=Gtk.Align.END) else: l = Gtk.Label(label=v, halign=Gtk.Align.END) l.show() if v == _('Place:'): t = MyPlaces([]) elif v in [_('Reference count:'), _('Number of instances:')]: t = MyInteger(0, 999) elif v == _('Reference count must be:'): t = MyLesserEqualGreater() elif v == _('Number must be:'): t = MyLesserEqualGreater(2) elif v == _('Number of generations:'): t = MyInteger(1, 32) elif v == _('ID:'): t = MyID(self.dbstate, self.uistate, self.track, self.namespace) elif v == _('Source ID:'): t = MySource(self.dbstate, self.uistate, self.track) elif v == _('Filter name:'): t = MyFilters(self.filterdb.get_filters(self.namespace), self.filter_name) # filters of another namespace, name may be same as caller! elif v == _('Person filter name:'): t = MyFilters(self.filterdb.get_filters('Person')) elif v == _('Event filter name:'): t = MyFilters(self.filterdb.get_filters('Event')) elif v == _('Source filter name:'): t = MyFilters(self.filterdb.get_filters('Source')) elif v == _('Repository filter name:'): t = MyFilters(self.filterdb.get_filters('Repository')) elif v == _('Place filter name:'): t = MyFilters(self.filterdb.get_filters('Place')) elif v in _name2typeclass: additional = None if v in (_('Event type:'), _('Personal event:'), _('Family event:')): additional = self.db.get_event_types() elif v == _('Personal attribute:'): additional = self.db.get_person_attribute_types() elif v == _('Family attribute:'): additional = self.db.get_family_attribute_types() elif v == _('Event attribute:'): additional = self.db.get_event_attribute_types() elif v == _('Media attribute:'): additional = self.db.get_media_attribute_types() elif v == _('Relationship type:'): additional = self.db.get_family_relation_types() elif v == _('Note type:'): additional = self.db.get_note_types() elif v == _('Name type:'): additional = self.db.get_name_types() elif v == _('Surname origin type:'): additional = self.db.get_origin_types() elif v == _('Place type:'): additional = sorted(self.db.get_place_types(), key=lambda s: s.lower()) t = MySelect(_name2typeclass[v], additional) elif v == _('Inclusive:'): t = MyBoolean(_('Include selected Gramps ID')) elif v == _('Case sensitive:'): t = MyBoolean(_('Use exact case of letters')) elif v == _('Regular-Expression matching:'): t = MyBoolean(_('Use regular expression')) elif v == _('Include Family events:'): t = MyBoolean( _('Also family events where person is spouse')) elif v == _('Primary Role:'): t = MyBoolean(_('Only include primary participants')) elif v == _('Tag:'): taglist = [''] taglist = taglist + [ tag.get_name() for tag in dbstate.db.iter_tags() ] t = MyList(taglist, taglist) elif v == _('Confidence level:'): t = MyList(list(map(str, list(range(5)))), [_(conf_strings[i]) for i in range(5)]) elif v == _('Date:'): t = DateEntry(self.uistate, self.track) elif v == _('Day of Week:'): long_days = displayer.long_days days_of_week = long_days[2:] + long_days[1:2] t = MyList(list(map(str, range(7))), days_of_week) elif v == _('Units:'): t = MyList( [0, 1, 2], [_('kilometers'), _('miles'), _('degrees')]) elif isinstance(v, tuple): # allow filter to create its own GUI element t = v[1](self.db) else: t = MyEntry() t.set_hexpand(True) tlist.append(t) grid.attach(l, 0, pos, 1, 1) grid.attach(t, 1, pos, 1, 1) pos += 1 use_regex = None if class_obj.allow_regex: use_regex = Gtk.CheckButton(label=_('Use regular expressions')) tip = _('Interpret the contents of string fields as regular ' 'expressions.\n' 'A decimal point will match any character. ' 'A question mark will match zero or one occurences ' 'of the previous character or group. ' 'An asterisk will match zero or more occurences. ' 'A plus sign will match one or more occurences. ' 'Use parentheses to group expressions. ' 'Specify alternatives using a vertical bar. ' 'A caret will match the start of a line. ' 'A dollar sign will match the end of a line.') use_regex.set_tooltip_text(tip) grid.attach(use_regex, 1, pos, 1, 1) self.page.append((class_obj, vallist, tlist, use_regex)) # put the grid into a scrollable area: scrolled_win = Gtk.ScrolledWindow() scrolled_win.add(grid) scrolled_win.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) scrolled_win.show() self.notebook.append_page(scrolled_win, Gtk.Label(label=class_obj.name)) self.class2page[class_obj] = self.page_num self.page_num = self.page_num + 1 self.page_num = 0 self.store = Gtk.TreeStore(GObject.TYPE_STRING, GObject.TYPE_PYOBJECT) self.ruletree_filter = self.store.filter_new() self.ruletree_filter.set_visible_func(self.rtree_visible_func) self.selection = self.rname.get_selection() col = Gtk.TreeViewColumn(_('Rule Name'), Gtk.CellRendererText(), text=0) self.rname.append_column(col) self.rname.set_model(self.ruletree_filter) prev = None last_top = None top_level = {} top_node = {} # # If editing a rule, get the name so that we can select it later # sel_node = None if self.active_rule is not None: self.sel_class = self.active_rule.__class__ else: self.sel_class = None keys = sorted(class_list, key=lambda x: x.name, reverse=True) catlist = sorted(set(class_obj.category for class_obj in keys)) for category in catlist: top_node[category] = self.store.insert_after(None, last_top) top_level[category] = [] last_top = top_node[category] self.store.set(last_top, 0, category, 1, '') for class_obj in keys: category = class_obj.category top_level[category].append(class_obj.name) node = self.store.insert_after(top_node[category], prev) self.store.set(node, 0, class_obj.name, 1, class_obj) # if this is an edit rule, save the node if class_obj == self.sel_class: sel_node = (top_node[category], node) if sel_node: self.select_iter(sel_node) page = self.class2page[self.active_rule.__class__] self.notebook.set_current_page(page) self.display_values(self.active_rule.__class__) (class_obj, vallist, tlist, use_regex) = self.page[page] r = list(self.active_rule.values()) for i in range(0, min(len(tlist), len(r))): tlist[i].set_text(r[i]) if class_obj.allow_regex: use_regex.set_active(self.active_rule.use_regex) self.selection.connect('changed', self.on_node_selected) self.rname.connect('button-press-event', self._button_press) self.rname.connect('key-press-event', self._key_press) self.get_widget('rule_editor_ok').connect('clicked', self.rule_ok) self.get_widget('rule_editor_cancel').connect('clicked', self.close_window) self.get_widget('rule_editor_help').connect('clicked', self.on_help_clicked) self.rname_filter.connect('changed', self.on_rname_filter_changed) self._set_size() config.register('interface.edit-rule-pane', 205) panepos = config.get('interface.edit-rule-pane') self.get_widget('hpaned1').set_position(panepos) self.show()
from gi import Repository from gramps.gen.config import config from gramps.gen.const import GRAMPS_LOCALE as glocale from gramps.gen.plug._pluginreg import register, VIEW, STABLE #, END, START _ = glocale.translation.gettext # Attempting to import goocanvas gives an error dialog if goocanvas is not # available so test first and log just a warning to the console instead. try: config.get('interface.ignore-goocanvas') except: config.register('interface.ignore-goocanvas', False) GOOCANVAS = False REPOSITORY = Repository.get_default() if REPOSITORY.enumerate_versions("GooCanvas"): try: # current goocanvas support GTK3 import gi gi.require_version('GooCanvas', '2.0') from gi.repository import GooCanvas as goocanvas GOOCANVAS = True except: pass if not GOOCANVAS: from gramps.gen.config import config if not config.get('interface.ignore-goocanvas'): from gramps.gen.constfunc import has_display if has_display(): from gramps.gui.dialog import MessageHideDialog