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)
Example #2
0
    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)
Example #4
0
    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())
Example #5
0
    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()