Beispiel #1
0
class Preference(NoModal):
    "Preference window"

    def __init__(self, user, callback):
        NoModal.__init__(self)
        self.callback = callback
        self.win = gtk.Dialog(_('Preferences'), self.parent,
            gtk.DIALOG_DESTROY_WITH_PARENT)
        self.win.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
        self.win.set_icon(TRYTON_ICON)

        self.accel_group = gtk.AccelGroup()
        self.win.add_accel_group(self.accel_group)

        self.but_cancel = self.win.add_button(gtk.STOCK_CANCEL,
                gtk.RESPONSE_CANCEL)
        self.but_ok = self.win.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
        self.but_ok.add_accelerator('clicked', self.accel_group,
                gtk.keysyms.Return, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE)

        self.win.set_default_response(gtk.RESPONSE_OK)
        self.win.connect('response', self.response)

        try:
            view = RPCExecute('model', 'res.user',
                'get_preferences_fields_view')
        except RPCException:
            self.win.destroy()
            self.win = None
            return

        title = gtk.Label(_('Edit User Preferences'))
        title.show()
        self.win.vbox.pack_start(title, expand=False, fill=True)
        self.screen = Screen('res.user', mode=[])
        # Reset readonly set automaticly by MODELACCESS
        self.screen.readonly = False
        self.screen.group.readonly = False
        self.screen.group.skip_model_access = True
        self.screen.add_view(view)
        self.screen.switch_view()
        self.screen.new(default=False)

        try:
            preferences = RPCExecute('model', 'res.user', 'get_preferences',
                False)
        except RPCException:
            self.win.destroy()
            self.win = None
            return
        self.screen.current_record.cancel()
        self.screen.current_record.set(preferences)
        self.screen.current_record.id = rpc._USER
        self.screen.current_record.validate(softvalidation=True)
        self.screen.display(set_cursor=True)

        self.screen.widget.show()
        self.win.vbox.pack_start(self.screen.widget)
        self.win.set_title(_('Preference'))

        width, height = self.parent.get_size()
        self.win.set_default_size(width, height)

        self.register()
        self.win.show()

    def response(self, win, response_id):
        if response_id == gtk.RESPONSE_OK:
            if self.screen.current_record.validate():
                vals = copy.copy(self.screen.get())
                context = rpc.CONTEXT.copy()
                func = lambda parameters: rpc.execute(
                    'model', 'res.user', 'set_preferences', vals, parameters,
                    context)
                try:
                    Login(func)
                except TrytonError, exception:
                    if exception.faultCode == 'QueryCanceled':
                        return
                    raise
        self.parent.present()
        self.destroy()
        self.callback()
Beispiel #2
0
class Wizard(InfoBar):
    def __init__(self, name=''):
        super(Wizard, self).__init__()
        self.widget = Gtk.VBox(spacing=3)
        self.widget.show()
        self.name = name or _('Wizard')
        self.id = None
        self.ids = None
        self.action = None
        self.action_id = None
        self.direct_print = False
        self.email_print = False
        self.email = False
        self.context = None
        self.states = {}
        self.response2button = {}
        self.__processing = False
        self.__waiting_response = False
        self.session_id = None
        self.start_state = None
        self.end_state = None
        self.screen = None
        self.screen_state = None
        self.state = None

    def run(self,
            action,
            data,
            direct_print=False,
            email_print=False,
            email=None,
            context=None):
        self.action = action
        self.action_id = data.get('action_id')
        self.id = data.get('id')
        self.ids = data.get('ids')
        self.model = data.get('model')
        self.direct_print = direct_print
        self.email_print = email_print
        self.email = email
        self.context = context.copy() if context is not None else {}
        self.context['active_id'] = self.id
        self.context['active_ids'] = self.ids
        self.context['active_model'] = self.model
        self.context['action_id'] = self.action_id

        def callback(result):
            try:
                result = result()
            except RPCException:
                self.destroy()
                return
            self.session_id, self.start_state, self.end_state = result
            self.state = self.start_state
            self.process()

        RPCExecute('wizard', action, 'create', callback=callback)

    def process(self):
        from tryton.action import Action
        if self.__processing or self.__waiting_response:
            return
        self.__processing = True

        ctx = self.context.copy()
        if self.screen:
            data = {
                self.screen_state: self.screen.get_on_change_value(),
            }
        else:
            data = {}

        def callback(result):
            try:
                result = result()
            except RPCException as rpc_exception:
                if (not isinstance(rpc_exception.exception, TrytonServerError)
                        or not self.screen):
                    self.state = self.end_state
                    self.end()
                self.__processing = False
                return

            if 'view' in result:
                self.clean()
                view = result['view']
                self.update(view['fields_view'], view['buttons'])

                self.screen.new(default=False)
                self.screen.current_record.set_default(view['defaults'])
                self.update_buttons(self.screen.current_record)
                self.screen.set_cursor()

                self.screen_state = view['state']
                self.__waiting_response = True
            else:
                self.state = self.end_state

            def execute_actions():
                for action in result.get('actions', []):
                    for k, v in [
                        ('direct_print', self.direct_print),
                        ('email_print', self.email_print),
                        ('email', self.email),
                    ]:
                        action[0].setdefault(k, v)
                    context = self.context.copy()
                    # Remove wizard keys added by run
                    del context['active_id']
                    del context['active_ids']
                    del context['active_model']
                    del context['action_id']
                    Action.execute(*action, context=context)

            if self.state == self.end_state:
                self.end(lambda *a: execute_actions())
            else:
                execute_actions()
            self.__processing = False

        RPCExecute('wizard',
                   self.action,
                   'execute',
                   self.session_id,
                   data,
                   self.state,
                   context=ctx,
                   callback=callback)

    def destroy(self, action=None):
        if self.screen:
            self.screen.destroy()

    def end(self, callback=None):
        def end_callback(action):
            self.destroy(action=action())
            if callback:
                callback()

        try:
            RPCExecute('wizard',
                       self.action,
                       'delete',
                       self.session_id,
                       process_exception=False,
                       callback=end_callback)
        except Exception:
            logger.warn(_("Unable to delete wizard %s") % self.session_id,
                        exc_info=True)

    def clean(self):
        for widget in self.widget.get_children():
            self.widget.remove(widget)
        self.states = {}

    def response(self, widget, response):
        self.__waiting_response = False
        button_attrs = self.response2button[response].attrs
        state = button_attrs.get('state', self.end_state)
        self.screen.current_view.set_value()
        if (button_attrs.get('validate', True)
                and not self.screen.current_record.validate()):
            self.screen.display(set_cursor=True)
            self.message_info(self.screen.invalid_message(),
                              Gtk.MessageType.ERROR)
            return
        self.message_info()
        self.state = state
        self.process()

    def _get_button(self, definition):
        button = Button(definition)
        self.states[definition['state']] = button
        response = len(self.states)
        self.response2button[response] = button
        button.show()
        return button

    def _record_changed(self, screen, record):
        self.update_buttons(record)

    def update_buttons(self, record):
        for button in self.states.values():
            button.state_set(record)

    def update(self, view, buttons):
        tooltips = common.Tooltips()
        for button in buttons:
            self._get_button(button)

        self.screen = Screen(view['model'], mode=[], context=self.context)
        self.screen.add_view(view)
        self.screen.switch_view()
        self.screen.widget.show()
        self.screen.signal_connect(self, 'group-changed', self._record_changed)

        title = Gtk.Label(label=common.ellipsize(self.name, 80),
                          halign=Gtk.Align.START,
                          margin=5,
                          ellipsize=Pango.EllipsizeMode.END)
        tooltips.set_tip(title, self.name)
        title.set_size_request(0, -1)  # Allow overflow
        title.show()

        hbox = Gtk.HBox()
        hbox.pack_start(title, expand=True, fill=True, padding=0)
        hbox.show()

        frame = Gtk.Frame()
        frame.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
        widget_class(frame, 'wizard-title', True)
        frame.add(hbox)
        frame.show()

        self.widget.pack_start(frame, expand=False, fill=True, padding=3)

        viewport = Gtk.Viewport()
        viewport.set_shadow_type(Gtk.ShadowType.NONE)
        viewport.add(self.screen.widget)
        viewport.show()
        self.scrolledwindow = Gtk.ScrolledWindow()
        self.scrolledwindow.set_shadow_type(Gtk.ShadowType.NONE)
        self.scrolledwindow.set_policy(Gtk.PolicyType.AUTOMATIC,
                                       Gtk.PolicyType.AUTOMATIC)
        self.scrolledwindow.add(viewport)
        self.scrolledwindow.show()

        self.widget.pack_start(self.scrolledwindow,
                               expand=True,
                               fill=True,
                               padding=0)

        self.create_info_bar()
        self.widget.pack_start(self.info_bar,
                               expand=False,
                               fill=True,
                               padding=0)
Beispiel #3
0
class Preference(NoModal):
    "Preference window"

    def __init__(self, user, callback):
        NoModal.__init__(self)
        self.callback = callback
        self.win = Gtk.Dialog(title=_('Preferences'),
                              transient_for=self.parent,
                              destroy_with_parent=True)
        Main().add_window(self.win)
        self.win.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
        self.win.set_icon(TRYTON_ICON)

        self.accel_group = Gtk.AccelGroup()
        self.win.add_accel_group(self.accel_group)

        self.but_cancel = self.win.add_button(set_underline(_("Cancel")),
                                              Gtk.ResponseType.CANCEL)
        self.but_cancel.set_image(
            IconFactory.get_image('tryton-cancel', Gtk.IconSize.BUTTON))
        self.but_cancel.set_always_show_image(True)
        self.but_ok = self.win.add_button(set_underline(_("OK")),
                                          Gtk.ResponseType.OK)
        self.but_ok.set_image(
            IconFactory.get_image('tryton-ok', Gtk.IconSize.BUTTON))
        self.but_ok.set_always_show_image(True)
        self.but_ok.add_accelerator('clicked', self.accel_group,
                                    Gdk.KEY_Return,
                                    Gdk.ModifierType.CONTROL_MASK,
                                    Gtk.AccelFlags.VISIBLE)

        self.win.set_default_response(Gtk.ResponseType.OK)
        self.win.connect('response', self.response)

        try:
            view = RPCExecute('model', 'res.user',
                              'get_preferences_fields_view')
        except RPCException:
            self.win.destroy()
            self.win = None
            return

        title = Gtk.Label(label=_('Edit User Preferences'))
        title.show()
        self.win.vbox.pack_start(title, expand=False, fill=True, padding=0)
        self.screen = Screen('res.user', mode=[])
        # Reset readonly set automaticly by MODELACCESS
        self.screen.readonly = False
        self.screen.group.readonly = False
        self.screen.group.skip_model_access = True
        self.screen.add_view(view)
        self.screen.switch_view()
        self.screen.new(default=False)

        try:
            preferences = RPCExecute('model', 'res.user', 'get_preferences',
                                     False)
        except RPCException:
            self.win.destroy()
            self.win = None
            return
        self.screen.current_record.cancel()
        self.screen.current_record.set(preferences)
        self.screen.current_record.id = rpc._USER
        self.screen.current_record.validate(softvalidation=True)
        self.screen.display(set_cursor=True)

        self.screen.widget.show()
        self.win.vbox.pack_start(self.screen.widget,
                                 expand=True,
                                 fill=True,
                                 padding=0)
        self.win.set_title(_('Preference'))

        self.win.set_default_size(*self.default_size())

        self.register()
        self.win.show()

    def response(self, win, response_id):
        if response_id == Gtk.ResponseType.OK:
            if self.screen.current_record.validate():
                vals = copy.copy(self.screen.get())
                try:
                    RPCExecute('model', 'res.user', 'set_preferences', vals)
                except RPCException:
                    return
        self.parent.present()
        self.destroy()
        self.callback()

    def destroy(self):
        self.screen.destroy()
        self.win.destroy()
        NoModal.destroy(self)
Beispiel #4
0
class Preference(NoModal):
    "Preference window"

    def __init__(self, user, callback):
        NoModal.__init__(self)
        self.callback = callback
        self.win = gtk.Dialog(_('Preferences'), self.parent,
            gtk.DIALOG_DESTROY_WITH_PARENT)
        Main().add_window(self.win)
        self.win.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
        self.win.set_icon(TRYTON_ICON)

        self.accel_group = gtk.AccelGroup()
        self.win.add_accel_group(self.accel_group)

        self.but_cancel = self.win.add_button(
            set_underline(_("Cancel")), gtk.RESPONSE_CANCEL)
        self.but_cancel.set_image(IconFactory.get_image(
                'tryton-cancel', gtk.ICON_SIZE_BUTTON))
        self.but_cancel.set_always_show_image(True)
        self.but_ok = self.win.add_button(
            set_underline(_("OK")), gtk.RESPONSE_OK)
        self.but_ok.set_image(IconFactory.get_image(
                'tryton-ok', gtk.ICON_SIZE_BUTTON))
        self.but_ok.set_always_show_image(True)
        self.but_ok.add_accelerator('clicked', self.accel_group,
                gtk.keysyms.Return, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE)

        self.win.set_default_response(gtk.RESPONSE_OK)
        self.win.connect('response', self.response)

        try:
            view = RPCExecute('model', 'res.user',
                'get_preferences_fields_view')
        except RPCException:
            self.win.destroy()
            self.win = None
            return

        title = gtk.Label(_('Edit User Preferences'))
        title.show()
        self.win.vbox.pack_start(title, expand=False, fill=True)
        self.screen = Screen('res.user', mode=[])
        # Reset readonly set automaticly by MODELACCESS
        self.screen.readonly = False
        self.screen.group.readonly = False
        self.screen.group.skip_model_access = True
        self.screen.add_view(view)
        self.screen.switch_view()
        self.screen.new(default=False)

        try:
            preferences = RPCExecute('model', 'res.user', 'get_preferences',
                False)
        except RPCException:
            self.win.destroy()
            self.win = None
            return
        self.screen.current_record.cancel()
        self.screen.current_record.set(preferences)
        self.screen.current_record.id = rpc._USER
        self.screen.current_record.validate(softvalidation=True)
        self.screen.display(set_cursor=True)

        self.screen.widget.show()
        self.win.vbox.pack_start(self.screen.widget)
        self.win.set_title(_('Preference'))

        width, height = self.parent.get_size()
        self.win.set_default_size(width, height)

        self.register()
        self.win.show()

    def response(self, win, response_id):
        if response_id == gtk.RESPONSE_OK:
            if self.screen.current_record.validate():
                vals = copy.copy(self.screen.get())
                try:
                    RPCExecute('model', 'res.user', 'set_preferences', vals)
                except RPCException:
                    return
        self.parent.present()
        self.destroy()
        self.callback()

    def destroy(self):
        self.screen.destroy()
        self.win.destroy()
        NoModal.destroy(self)
Beispiel #5
0
class Wizard(InfoBar):
    def __init__(self, name=''):
        super(Wizard, self).__init__()
        self.widget = gtk.VBox(spacing=3)
        self.toolbar_box = None
        self.widget.show()
        self.name = name or ''
        self.id = None
        self.ids = None
        self.action = None
        self.action_id = None
        self.direct_print = False
        self.email_print = False
        self.email = False
        self.context = None
        self.states = {}
        self.response2state = {}
        self.__processing = False
        self.__waiting_response = False
        self.session_id = None
        self.start_state = None
        self.end_state = None
        self.screen = None
        self.screen_state = None
        self.state = None

    def run(self,
            action,
            data,
            direct_print=False,
            email_print=False,
            email=None,
            context=None):
        self.action = action
        self.action_id = data.get('action_id')
        self.id = data.get('id')
        self.ids = data.get('ids')
        self.model = data.get('model')
        self.direct_print = direct_print
        self.email_print = email_print
        self.email = email
        self.context = context.copy() if context is not None else {}
        self.context['active_id'] = self.id
        self.context['active_ids'] = self.ids
        self.context['active_model'] = self.model
        self.context['action_id'] = self.action_id

        def callback(result):
            try:
                result = result()
            except RPCException:
                self.destroy()
                return
            self.session_id, self.start_state, self.end_state = result
            self.state = self.start_state
            self.process()

        RPCExecute('wizard', action, 'create', callback=callback)

    def process(self):
        from tryton.action import Action
        if self.__processing or self.__waiting_response:
            return
        self.__processing = True

        ctx = self.context.copy()
        if self.screen:
            data = {
                self.screen_state: self.screen.get_on_change_value(),
            }
        else:
            data = {}

        def callback(result):
            try:
                result = result()
            except RPCException as rpc_exception:
                if (not isinstance(rpc_exception.exception, TrytonServerError)
                        or not self.screen):
                    self.state = self.end_state
                    self.end()
                self.__processing = False
                return

            if 'view' in result:
                self.clean()
                view = result['view']
                self.update(view['fields_view'], view['buttons'])

                self.screen.new(default=False)
                self.screen.current_record.set_default(view['defaults'])
                self.update_buttons(self.screen.current_record)
                self.screen.set_cursor()

                self.screen_state = view['state']
                self.__waiting_response = True
            else:
                self.state = self.end_state

            def execute_actions():
                for action in result.get('actions', []):
                    for k, v in [
                        ('direct_print', self.direct_print),
                        ('email_print', self.email_print),
                        ('email', self.email),
                    ]:
                        action[0].setdefault(k, v)
                    context = self.context.copy()
                    # Remove wizard keys added by run
                    del context['active_id']
                    del context['active_ids']
                    del context['active_model']
                    del context['action_id']
                    Action._exec_action(*action, context=context)

            if self.state == self.end_state:
                self.end(lambda *a: execute_actions())
            else:
                execute_actions()
            self.__processing = False

        RPCExecute('wizard',
                   self.action,
                   'execute',
                   self.session_id,
                   data,
                   self.state,
                   context=ctx,
                   callback=callback)

    def destroy(self, action=None):
        if self.screen:
            self.screen.destroy()

    def end(self, callback=None):
        def end_callback(action):
            self.destroy(action=action())
            if callback:
                callback()

        try:
            RPCExecute('wizard',
                       self.action,
                       'delete',
                       self.session_id,
                       process_exception=False,
                       callback=end_callback)
        except Exception:
            logger.warn(_("Unable to delete wizard %s") % self.session_id,
                        exc_info=True)

    def clean(self):
        for widget in self.widget.get_children():
            self.widget.remove(widget)
        self.states = {}

    def response(self, widget, response):
        self.__waiting_response = False
        state = self.response2state.get(response, self.end_state)
        self.screen.current_view.set_value()
        if (not self.screen.current_record.validate()
                and state != self.end_state):
            self.screen.display(set_cursor=True)
            self.message_info(self.screen.invalid_message(), gtk.MESSAGE_ERROR)
            return
        self.message_info()
        self.state = state
        self.process()

    def _get_button(self, definition):
        button = Button(definition)
        self.states[definition['state']] = button
        response = len(self.states)
        self.response2state[response] = definition['state']
        button.show()
        return button

    def _record_changed(self, screen, record):
        self.update_buttons(record)

    def update_buttons(self, record):
        for button in self.states.values():
            button.state_set(record)

    def update(self, view, buttons):
        tooltips = common.Tooltips()
        for button in buttons:
            self._get_button(button)

        self.screen = Screen(view['model'], mode=[], context=self.context)
        self.screen.add_view(view)
        self.screen.switch_view()
        self.screen.widget.show()
        self.screen.signal_connect(self, 'group-changed', self._record_changed)

        title = gtk.Label()
        title.modify_font(pango.FontDescription("bold 14"))
        title.set_label(common.ellipsize(self.name, 80))
        tooltips.set_tip(title, self.name)
        title.set_padding(20, 4)
        title.set_alignment(0.0, 0.5)
        title.set_max_width_chars(1)
        title.set_ellipsize(pango.ELLIPSIZE_END)
        title.set_size_request(0, -1)  # Allow overflow
        title.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#000000"))
        title.show()

        hbox = gtk.HBox()
        hbox.pack_start(title, expand=True, fill=True)
        hbox.show()

        frame = gtk.Frame()
        frame.set_shadow_type(gtk.SHADOW_ETCHED_IN)
        frame.add(hbox)
        frame.show()

        eb = gtk.EventBox()
        eb.add(frame)
        eb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#ffffff"))
        eb.show()

        self.widget.pack_start(eb, expand=False, fill=True, padding=3)

        if self.toolbar_box:
            self.widget.pack_start(self.toolbar_box, False, True)

        viewport = gtk.Viewport()
        viewport.set_shadow_type(gtk.SHADOW_NONE)
        viewport.add(self.screen.widget)
        viewport.show()
        self.scrolledwindow = gtk.ScrolledWindow()
        self.scrolledwindow.set_shadow_type(gtk.SHADOW_NONE)
        self.scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC,
                                       gtk.POLICY_AUTOMATIC)
        self.scrolledwindow.add(viewport)
        self.scrolledwindow.show()

        self.widget.pack_start(self.scrolledwindow, expand=True, fill=True)

        self.create_info_bar()
        self.widget.pack_start(self.info_bar, False, True)
Beispiel #6
0
class Preference(NoModal):
    "Preference window"

    def __init__(self, user, callback):
        NoModal.__init__(self)
        self.callback = callback
        self.win = gtk.Dialog(_('Preferences'), self.parent,
            gtk.DIALOG_DESTROY_WITH_PARENT)
        self.win.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
        self.win.set_has_separator(False)
        self.win.set_icon(TRYTON_ICON)

        self.accel_group = gtk.AccelGroup()
        self.win.add_accel_group(self.accel_group)

        self.but_cancel = self.win.add_button(gtk.STOCK_CANCEL,
                gtk.RESPONSE_CANCEL)
        self.but_ok = self.win.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
        self.but_ok.add_accelerator('clicked', self.accel_group,
                gtk.keysyms.Return, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE)

        self.win.set_default_response(gtk.RESPONSE_OK)
        self.win.connect('response', self.response)

        try:
            view = RPCExecute('model', 'res.user',
                'get_preferences_fields_view')
        except RPCException:
            self.win.destroy()
            self.win = None
            return

        title = gtk.Label(_('Edit User Preferences'))
        title.show()
        self.win.vbox.pack_start(title, expand=False, fill=True)
        self.screen = Screen('res.user', mode=[])
        # Reset readonly set automaticly by MODELACCESS
        self.screen.readonly = False
        self.screen.group.readonly = False
        self.screen.group.skip_model_access = True
        self.screen.add_view(view)
        self.screen.switch_view()
        self.screen.new(default=False)

        try:
            preferences = RPCExecute('model', 'res.user', 'get_preferences',
                False)
        except RPCException:
            self.win.destroy()
            self.win = None
            return
        self.screen.current_record.set(preferences)
        self.screen.current_record.id = rpc._USER
        self.screen.current_record.validate(softvalidation=True)
        self.screen.display(set_cursor=True)

        self.screen.widget.show()
        self.win.vbox.pack_start(self.screen.widget)
        self.win.set_title(_('Preference'))

        width, height = self.parent.get_size()
        self.win.set_default_size(int(width * 0.9), int(height * 0.9))

        self.register()
        self.win.show()

    def response(self, win, response_id):
        if response_id == gtk.RESPONSE_OK:
            if self.screen.current_record.validate():
                vals = copy.copy(self.screen.get())
                if 'password' in vals:
                    password = common.ask(_('Current Password:'******'model', 'res.user', 'set_preferences',
                        vals, password)
                except RPCException:
                    return
        self.parent.present()
        self.destroy()
        self.callback()

    def destroy(self):
        self.screen.destroy()
        self.win.destroy()
        NoModal.destroy(self)
class Preference(object):
    "Preference window"

    def __init__(self, user):
        self.parent = common.get_toplevel_window()
        self.win = gtk.Dialog(_("Preferences"), self.parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
        self.win.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
        self.win.set_has_separator(False)
        self.win.set_icon(TRYTON_ICON)

        self.accel_group = gtk.AccelGroup()
        self.win.add_accel_group(self.accel_group)

        self.but_cancel = self.win.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
        self.but_ok = self.win.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
        self.but_ok.add_accelerator(
            "clicked", self.accel_group, gtk.keysyms.Return, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE
        )

        self.win.set_default_response(gtk.RESPONSE_OK)

        try:
            view = RPCExecute("model", "res.user", "get_preferences_fields_view")
        except RPCException:
            self.win.destroy()
            self.win = None
            return

        title = gtk.Label(_("Edit User Preferences"))
        title.show()
        self.win.vbox.pack_start(title, expand=False, fill=True)
        self.screen = Screen("res.user", mode=[])
        self.screen.add_view(view)
        self.screen.new(default=False)

        try:
            preferences = RPCExecute("model", "res.user", "get_preferences", False)
        except RPCException:
            self.win.destroy()
            self.win = None
            return
        self.screen.current_record.set(preferences)
        self.screen.current_record.validate(softvalidation=True)
        self.screen.screen_container.set(self.screen.current_view.widget)
        self.screen.display(set_cursor=True)

        self.screen.widget.show()
        self.win.vbox.pack_start(self.screen.widget)
        self.win.set_title(_("Preference"))

        width, height = self.parent.get_size()
        self.win.set_default_size(int(width * 0.9), int(height * 0.9))

        self.win.show()

    def run(self):
        "Run the window"
        if not self.win:
            return False
        res = False
        while True:
            if self.win.run() == gtk.RESPONSE_OK:
                if self.screen.current_record.validate():
                    vals = copy.copy(self.screen.get(get_modifiedonly=True))
                    if "password" in vals:
                        password = common.ask(_("Current Password:"******"model", "res.user", "set_preferences", vals, password)
                    except RPCException:
                        continue
                    res = True
                    break
            else:
                break
        self.parent.present()
        self.win.destroy()
        return res