def __init__(self, base_dir='lightdm', base_name='lightdm-gtk-greeter.conf'): self._base_dir = base_dir self._base_name = base_name self._output_path = helpers.get_config_path() self._groups = OrderedDict() self._key_values = helpers.SimpleDictWrapper( getter=self._get_key_values)
def _init_window(self): self._bindings = {section: {key: self._new_binding(*args) for key, args in list(keys.items())} for section, keys in list(OPTIONS_BINDINGS.items())} self._initial_values = {} self._changed_values = None self._config_path = helpers.get_config_path() self._allow_edit = self._has_access_to_write(self._config_path) self._no_access_infobar.props.visible = not self._allow_edit self._apply_button.props.visible = self._allow_edit if not self._allow_edit: helpers.show_message( text=_('No permissions to save configuration'), secondary_text=_( 'It seems that you don\'t have permissions to write to ' 'file:\n{path}\n\nTry to run this program using "sudo" ' 'or "pkexec"').format(path=self._config_path), message_type=Gtk.MessageType.WARNING) self._configure_special_entries() self._config = configparser.RawConfigParser() self._read()
def __init__(self, base_dir='lightdm', base_name='lightdm-gtk-greeter.conf'): self._base_dir = base_dir self._base_name = base_name self._output_path = helpers.get_config_path() self._groups = OrderedDict() self._key_values = helpers.SimpleDictWrapper(getter=self._get_key_values)
def on_show_menu(self, entry, group, key): def new_item(activate=None, width=90): item = Gtk.MenuItem('') label = item.get_child() label.props.use_markup = True label.props.ellipsize = Pango.EllipsizeMode.END label.props.max_width_chars = width if activate: item.connect('activate', activate) else: item.props.sensitive = False return item if not self._entry_menu: class EntryMenu: menu = Gtk.Menu() group = new_item() value = new_item() file = new_item() error_separator = Gtk.SeparatorMenuItem() error = new_item() error_action = new_item(self.on_entry_fix_clicked) reset_separator = Gtk.SeparatorMenuItem() initial = new_item(self.on_entry_reset_clicked) default = new_item(self.on_entry_reset_clicked) other = [] menu.append(group) menu.append(value) menu.append(file) menu.append(error_separator) menu.append(error) menu.append(error_action) menu.append(reset_separator) menu.append(initial) menu.append(default) menu.show_all() self._entry_menu = EntryMenu() def format_value(value=None, enabled=True): if not enabled: return _('<i>disabled</i>') if value == '': return _('<i>empty string</i>') elif value is None: return _('<i>None</i>') else: return escape_markup(str(value)) menu = self._entry_menu # [group] if group.name: menu.group.props.label = '[{group}]'.format(group=group.name) menu.group.show() else: menu.group.hide() # key = value if entry.enabled: menu.value.props.label = '{key} = {value}'.format( key=key, value=format_value(value=entry.value, enabled=entry.enabled)) else: menu.value.props.label = '# {key} ='.format(key=key) # File with key definition config_values = self._config.key_values[group.name, key] if entry not in self._changed_entries and \ config_values and config_values[-1][0] != helpers.get_config_path(): menu.file.props.label = _('Value defined in file: {path}')\ .format(path=escape_markup(config_values[-1][0])) menu.file.set_tooltip_text(config_values[-1][0]) menu.file.show() else: menu.file.hide() # Error message error = entry.error error_action = None if error: aname = ('get_entry_fix_%s_%s' % (group.name, key)).replace( '-', '_') get_fix = getattr(self, aname, None) if get_fix: label, error_action = get_fix(entry) if label: menu.error_action.props.label = label or '' if error_action: menu.error_action._fix_entry_data = entry, error_action menu.error.set_label(escape_markup(error)) menu.error.props.visible = error is not None menu.error_action.props.visible = error_action is not None menu.error_separator.props.visible = error_action is not None # Reset to initial value initial = self._initial_values[entry] if initial.enabled != entry.enabled or initial.value != entry.value: if entry.enabled != initial.enabled and not initial.enabled: menu.initial._reset_entry_data = entry, None, initial.enabled else: menu.initial._reset_entry_data = entry, initial.value, None value = format_value(value=initial.value, enabled=initial.enabled) menu.initial.set_tooltip_markup(value) menu.initial.props.visible = True menu.initial.props.label = \ _('Reset to initial value: <b>{value}</b>').format(value=value) else: menu.initial.props.visible = False # Reset to default value default = group.defaults[key] if default is not None and entry.value != default: value = format_value(value=default) menu.default._reset_entry_data = entry, default, None menu.default.set_tooltip_markup(value) menu.default.props.visible = True menu.default.props.label = \ _('Reset to default value: <b>{value}</b>').format(value=value) else: menu.default.props.visible = False # Reset to values from all other (.conf item_idx = 0 if config_values and len(config_values) > 1: values = { None, default, self._initial_values[entry].value, entry.value } for __, value in config_values[:-1]: if value in values: continue if len(menu.other) <= item_idx: item = new_item(self.on_entry_reset_clicked) menu.other.append(item) menu.menu.append(item) else: item = menu.other[item_idx] item._reset_entry_data = entry, value, None value = format_value(value=value) item.set_tooltip_markup(value) item.props.label = _('Reset to value: <b>{value}</b>').format( value=value) item.show() item_idx += 1 for item in menu.other[item_idx:]: item.hide() menu.reset_separator.props.visible = \ menu.initial.props.visible or menu.default.props.visible or \ any(item.props.visible for item in menu.other) self._entry_menu.menu.popup(None, None, None, None, 0, Gtk.get_current_event_time())
def init_window(self): self._widgets = self.Widgets(builder=self.builder) if self.mode == WindowMode.Embedded: self.on_entry_removed = self.on_entry_removed_embedded self.on_entry_changed = self.on_entry_changed_embedded self._write = self._write_embedded self._widgets.buttons.hide() self._widgets.content.reorder_child(self._widgets.infobar, 0) self._widgets.content.connect('destroy', self.on_destroy, True) # Socket/Plug focus issues workaround self._widgets.multihead_label.connect('button-press-event', self.on_multihead_click) elif self.mode == WindowMode.GtkHeader: for button in (self._widgets.apply, self._widgets.reload): self._widgets.buttons.remove(button) button.set_label('') button.set_always_show_image(True) self._widgets.buttons.hide() header = Gtk.HeaderBar() header.set_show_close_button(True) header.props.title = self.get_title() header.pack_start(self._widgets.reload) header.pack_start(self._widgets.apply) header.show_all() self.set_titlebar(header) self._config = Config.Config() self._entry_menu = None self._initial_values = {} self._entries = None self._changed_entries = None self._new_entries = None self._removed_entries = None self._groups = (SimpleGroup('greeter', WidgetsWrapper(self.builder, 'greeter'), self.GreeterGroupSetup), MonitorsGroup(self.builder)) for group in self._groups: group.entry_added.connect(self.on_entry_added) group.entry_removed.connect(self.on_entry_removed) self._allow_edit = self._config.is_writable() self._update_apply_button() if not self._allow_edit: self._set_message( _('You don\'t have permissions to change greeter configuration' ), Gtk.MessageType.WARNING) if self.mode != WindowMode.Embedded: helpers.show_message( text=_('No permissions to save configuration'), secondary_text=_( 'It seems that you don\'t have permissions to write to ' 'file:\n{path}\n\nTry to run this program using "sudo" ' 'or "pkexec"').format(path=helpers.get_config_path()), message_type=Gtk.MessageType.WARNING) self._read()
def init_window(self): self._widgets = self.Widgets(builder=self.builder) self._multihead_dialog = None self._entry_menu = None self._initial_values = {} self._changed_entries = None self._entries = None self._groups = ( SimpleGroup('greeter', self.builder, { # Appearance 'theme-name': (OptionEntry.StringEntry, ''), 'icon-theme-name': (OptionEntry.StringEntry, ''), 'font-name': (OptionEntry.FontEntry, 'Sans 10'), 'xft-antialias': (OptionEntry.BooleanEntry, 'false'), 'xft-dpi': (OptionEntry.StringEntry, None), 'xft-rgba': (OptionEntry.ChoiceEntry, None), 'xft-hintstyle': (OptionEntry.ChoiceEntry, None), 'background': (OptionEntry.BackgroundEntry, '#000000'), 'user-background': (OptionEntry.BooleanEntry, 'true'), 'hide-user-image': (OptionEntry.InvertedBooleanEntry, 'false'), 'default-user-image': (IconEntry.IconEntry, '#avatar-default'), # Panel 'clock-format': (OptionEntry.ClockFormatEntry, '%a, %H:%M'), 'indicators': (IndicatorsEntry.IndicatorsEntry, '~host;~spacer;~clock;~spacer;~language;~session;~a11y;~power'), # Position 'position': (PositionEntry.PositionEntry, '50%,center'), # Misc 'screensaver-timeout': (OptionEntry.AdjustmentEntry, '60'), 'keyboard': (OptionEntry.StringPathEntry, ''), 'reader': (OptionEntry.StringPathEntry, ''), 'a11y-states': (OptionEntry.AccessibilityStatesEntry, ''), 'allow-debugging': (OptionEntry.BooleanEntry, 'false'), }), MonitorsGroup(self.builder)) for group in self._groups: group.entry_added.connect(self.on_entry_added) group.entry_removed.connect(self.on_entry_removed) self._config_path = helpers.get_config_path() self._allow_edit = self._has_access_to_write(self._config_path) self._widgets.apply.props.visible = self._allow_edit if not self._allow_edit: self._set_message(_('You don\'t have permissions to change greeter configuration'), Gtk.MessageType.WARNING) if self.mode != WindowMode.Embedded: helpers.show_message( text=_('No permissions to save configuration'), secondary_text=_( 'It seems that you don\'t have permissions to write to ' 'file:\n{path}\n\nTry to run this program using "sudo" ' 'or "pkexec"').format(path=self._config_path), message_type=Gtk.MessageType.WARNING) if self.mode == WindowMode.Embedded: self.on_entry_changed = self.on_entry_changed_embedded self._widgets.buttons.hide() self._widgets.content.reorder_child(self._widgets.infobar, 0) # Socket/Plug focus issues workaround self._widgets.multihead_label.connect('button-press-event', self.on_multihead_click) elif self.mode == WindowMode.GtkHeader: for button in (self._widgets.apply, self._widgets.reload): self._widgets.buttons.remove(button) button.set_label('') button.set_always_show_image(True) self._widgets.buttons.hide() header = Gtk.HeaderBar() header.set_show_close_button(True) header.props.title = self.get_title() header.pack_start(self._widgets.reload) header.pack_start(self._widgets.apply) header.show_all() self.set_titlebar(header) self._config = configparser.RawConfigParser(strict=False) self._read()
def on_show_menu(self, entry, group, key): def new_item(activate=None, width=90): item = Gtk.MenuItem('') label = item.get_child() label.props.use_markup = True label.props.ellipsize = Pango.EllipsizeMode.END label.props.max_width_chars = width if activate: item.connect('activate', activate) else: item.props.sensitive = False return item if not self._entry_menu: class EntryMenu: menu = Gtk.Menu() group = new_item() value = new_item() file = new_item() error_separator = Gtk.SeparatorMenuItem() error = new_item() error_action = new_item(self.on_entry_fix_clicked) reset_separator = Gtk.SeparatorMenuItem() initial = new_item(self.on_entry_reset_clicked) default = new_item(self.on_entry_reset_clicked) other = [] menu.append(group) menu.append(value) menu.append(file) menu.append(error_separator) menu.append(error) menu.append(error_action) menu.append(reset_separator) menu.append(initial) menu.append(default) menu.show_all() self._entry_menu = EntryMenu() def format_value(value=None, enabled=True): if not enabled: return _('<i>disabled</i>') if value == '': return _('<i>empty string</i>') elif value is None: return _('<i>None</i>') else: return escape_markup(str(value)) menu = self._entry_menu # [group] if group.name: menu.group.props.label = '[{group}]'.format(group=group.name) menu.group.show() else: menu.group.hide() # key = value if entry.enabled: menu.value.props.label = '{key} = {value}'.format( key=key, value=format_value(value=entry.value, enabled=entry.enabled)) else: menu.value.props.label = '# {key} ='.format(key=key) # File with key definition config_values = self._config.key_values[group.name, key] if entry not in self._changed_entries and \ config_values and config_values[-1][0] != helpers.get_config_path(): menu.file.props.label = _('Value defined in file: {path}')\ .format(path=escape_markup(config_values[-1][0])) menu.file.set_tooltip_text(config_values[-1][0]) menu.file.show() else: menu.file.hide() # Error message error = entry.error error_action = None if error: aname = ('get_entry_fix_%s_%s' % (group.name, key)).replace('-', '_') get_fix = getattr(self, aname, None) if get_fix: label, error_action = get_fix(entry) if label: menu.error_action.props.label = label or '' if error_action: menu.error_action._fix_entry_data = entry, error_action menu.error.set_label(escape_markup(error)) menu.error.props.visible = error is not None menu.error_action.props.visible = error_action is not None menu.error_separator.props.visible = error_action is not None # Reset to initial value initial = self._initial_values[entry] if initial.enabled != entry.enabled or initial.value != entry.value: if entry.enabled != initial.enabled and not initial.enabled: menu.initial._reset_entry_data = entry, None, initial.enabled else: menu.initial._reset_entry_data = entry, initial.value, None value = format_value(value=initial.value, enabled=initial.enabled) menu.initial.set_tooltip_markup(value) menu.initial.props.visible = True menu.initial.props.label = \ _('Reset to initial value: <b>{value}</b>').format(value=value) else: menu.initial.props.visible = False # Reset to default value default = group.defaults[key] if default is not None and entry.value != default: value = format_value(value=default) menu.default._reset_entry_data = entry, default, None menu.default.set_tooltip_markup(value) menu.default.props.visible = True menu.default.props.label = \ _('Reset to default value: <b>{value}</b>').format(value=value) else: menu.default.props.visible = False # Reset to values from all other (.conf item_idx = 0 if config_values and len(config_values) > 1: values = {None, default, self._initial_values[entry].value, entry.value} for __, value in config_values[:-1]: if value in values: continue if len(menu.other) <= item_idx: item = new_item(self.on_entry_reset_clicked) menu.other.append(item) menu.menu.append(item) else: item = menu.other[item_idx] item._reset_entry_data = entry, value, None value = format_value(value=value) item.set_tooltip_markup(value) item.props.label = _('Reset to value: <b>{value}</b>').format(value=value) item.show() item_idx += 1 for item in menu.other[item_idx:]: item.hide() menu.reset_separator.props.visible = \ menu.initial.props.visible or menu.default.props.visible or \ any(item.props.visible for item in menu.other) self._entry_menu.menu.popup(None, None, None, None, 0, Gtk.get_current_event_time())
def init_window(self): self._widgets = self.Widgets(builder=self.builder) if self.mode == WindowMode.Embedded: self.on_entry_removed = self.on_entry_removed_embedded self.on_entry_changed = self.on_entry_changed_embedded self._write = self._write_embedded self._widgets.buttons.hide() self._widgets.content.reorder_child(self._widgets.infobar, 0) self._widgets.content.connect('destroy', self.on_destroy, True) # Socket/Plug focus issues workaround self._widgets.multihead_label.connect('button-press-event', self.on_multihead_click) elif self.mode == WindowMode.GtkHeader: for button in (self._widgets.apply, self._widgets.reload): self._widgets.buttons.remove(button) button.set_label('') button.set_always_show_image(True) self._widgets.buttons.hide() header = Gtk.HeaderBar() header.set_show_close_button(True) header.props.title = self.get_title() header.pack_start(self._widgets.reload) header.pack_start(self._widgets.apply) header.show_all() self.set_titlebar(header) self._config = Config.Config() self._entry_menu = None self._initial_values = {} self._entries = None self._changed_entries = None self._new_entries = None self._removed_entries = None self._groups = ( SimpleGroup('greeter', WidgetsWrapper(self.builder, 'greeter'), self.GreeterGroupSetup), MonitorsGroup(self.builder)) for group in self._groups: group.entry_added.connect(self.on_entry_added) group.entry_removed.connect(self.on_entry_removed) self._allow_edit = self._config.is_writable() self._update_apply_button() if not self._allow_edit: self._set_message(_('You don\'t have permissions to change greeter configuration'), Gtk.MessageType.WARNING) if self.mode != WindowMode.Embedded: helpers.show_message( text=_('No permissions to save configuration'), secondary_text=_( 'It seems that you don\'t have permissions to write to ' 'file:\n{path}\n\nTry to run this program using "sudo" ' 'or "pkexec"').format(path=helpers.get_config_path()), message_type=Gtk.MessageType.WARNING) self._read()