def __init__(self, parent=None): self.glade = glade.XML(common.terp_path("openerp.glade"), 'win_preference', gettext.textdomain()) self.win = self.glade.get_widget('win_preference') self.win.set_icon(common.OPENERP_ICON) if not parent: parent = service.LocalService('gui.main').window self.win.set_transient_for(parent) self.parent = parent action_id = rpc.session.rpc_exec_auth('/object', 'execute', 'res.users', 'action_get', {}) action = rpc.session.rpc_exec_auth('/object', 'execute', 'ir.actions.act_window', 'read', [action_id], False, rpc.session.context)[0] view_ids = [] if action.get('views', []): view_ids = [x[0] for x in action['views']] elif action.get('view_id', False): view_ids = [action['view_id'][0]] self.screen = Screen('res.users', view_type=[], window=parent) self.screen.add_view_id(view_ids[0], 'form', display=True) self.screen.load([rpc.session.uid]) self.screen.display(rpc.session.uid) vbox = self.glade.get_widget('preference_vbox') vbox.pack_start(self.screen.widget) self.win.set_title(_('Preferences')) self.win.show_all()
def __init__(self, window, parent, model, attrs={}): interface.widget_interface.__init__(self, window, parent, model, attrs) self.act_id = int(attrs['name']) res = rpc.session.rpc_exec_auth('/object', 'execute', 'ir.actions.actions', 'read', [self.act_id], ['type'], rpc.session.context) if not res: raise Exception, 'ActionNotFound' type = res[0]['type'] self.action = rpc.session.rpc_exec_auth('/object', 'execute', type, 'read', [self.act_id], False, rpc.session.context)[0] if 'view_mode' in attrs: self.action['view_mode'] = attrs['view_mode'] if self.action['type'] == 'ir.actions.act_window': if not self.action.get('domain', False): self.action['domain'] = '[]' if attrs.get('domain', False): self.action['domain'] = attrs.get('domain') self.context = {'active_id': False, 'active_ids': []} self.context.update( tools.expr_eval(self.action.get('context', '{}'), self.context.copy())) self.domain = tools.expr_eval(self.action['domain'], self.context.copy()) view_id = [] if self.action['view_id']: view_id = [self.action['view_id'][0]] if self.action['view_type'] == 'form': mode = (self.action['view_mode'] or 'form,tree').split(',') self.screen = Screen(self.action['res_model'], view_type=mode, context=self.context, view_ids=view_id, domain=self.domain) self.win_gl = glade.XML(common.terp_path("openerp.glade"), 'widget_paned', gettext.textdomain()) self.win_gl.signal_connect('on_switch_button_press_event', self._sig_switch) self.win_gl.signal_connect('on_search_button_press_event', self._sig_search) self.win_gl.signal_connect('on_open_button_press_event', self._sig_open) label = self.win_gl.get_widget('widget_paned_lab') label.set_text( attrs.get('string', self.screen.current_view.title)) vbox = self.win_gl.get_widget('widget_paned_vbox') vbox.add(self.screen.widget) self.widget = self.win_gl.get_widget('widget_paned') self.widget.set_size_request(int(attrs.get('width', -1)), int(attrs.get('height', -1))) elif self.action['view_type'] == 'tree': pass #TODO
def __init__(self, model, sel_multi=True, ids=[], context={}, domain=[], parent=None): self.model = model self.sel_multi = sel_multi self.ids = ids self.ctx = context self.glade = glade.XML(common.terp_path("openerp.glade"), 'win_search', gettext.textdomain()) self.win = self.glade.get_widget('win_search') self.win.set_icon(common.OPENERP_ICON) if not parent: parent = service.LocalService('gui.main').window self.parent = parent self.win.set_transient_for(parent) self.screen = Screen(model, view_type=['tree'], show_search=True, domain=domain, context=context, parent=self.win, win_search=True) self.view = self.screen.current_view if self.screen.filter_widget.focusable: self.screen.filter_widget.focusable.grab_focus() self.title = _('OpenERP Search: %s') % self.screen.name self.title_results = _('OpenERP Search: %s (%%d result(s))') % ( self.screen.name, ) self.win.set_title(self.title) self.view.unset_editable() sel = self.view.widget_tree.get_selection() if not sel_multi: sel.set_mode('single') else: sel.set_mode(gtk.SELECTION_MULTIPLE) self.view.widget_tree.connect('row_activated', self.sig_activate) self.view.widget_tree.connect('button_press_event', self.sig_button) self.screen.win_search_callback = self.update_title vp = gtk.Viewport() vp.set_shadow_type(gtk.SHADOW_NONE) vp.add(self.screen.widget) vp.show() self.sw = gtk.ScrolledWindow() self.sw.set_shadow_type(gtk.SHADOW_NONE) self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.sw.add(vp) self.sw.show() self.wid = self.glade.get_widget('win_search_vbox') self.wid.pack_start(self.sw) self.wid.show_all()
class dialog(object): def __init__(self, arch, fields, state, name, parent=None): buttons = [] self.states=[] default=-1 if not parent: parent = service.LocalService('gui.main').window self.dia = gtk.Dialog('OpenERP', parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT) for x in state: but = gtk.Button(x[1]) but.show() if len(x) >= 3: icon = gtk.Image() icon.set_from_stock(x[2], gtk.ICON_SIZE_BUTTON) but.set_image(icon) self.dia.add_action_widget(but, len(self.states)) if len(x) >= 4 and x[3]: but.set_flags(gtk.CAN_DEFAULT) default = len(self.states) self.states.append(x[0]) if default >= 0: self.dia.set_default_response(default) val = {} for f in fields: if 'value' in fields[f]: val[f] = fields[f]['value'] self.screen = Screen('wizard.'+name, view_type=[], window=self.dia, is_wizard=True) self.screen.new(default=False) self.screen.add_view_custom(arch, fields, display=True) self.screen.current_model.set(val) x,y = self.screen.screen_container.size_get() width, height = parent.get_size() self.screen.widget.set_size_request(min(width - 20, x + 20), min(height - 60, y + 25)) self.screen.widget.show() self.dia.vbox.pack_start(self.screen.widget) self.dia.set_title(self.screen.current_view.title) self.dia.show() def run(self, datas={}): while True: res = self.dia.run() self.screen.current_view.set_value() if self.screen.current_model.validate() or (res<0) or (self.states[res]=='end'): break self.screen.display() if res<len(self.states) and res>=0: datas.update(self.screen.get()) self.dia.destroy() return (self.states[res], datas) else: self.dia.destroy() self.screen.destroy() return False
class win_preference(object): def __init__(self, parent=None): self.glade = glade.XML(common.terp_path("openerp.glade"), 'win_preference', gettext.textdomain()) self.win = self.glade.get_widget('win_preference') self.win.set_icon(common.OPENERP_ICON) if not parent: parent = service.LocalService('gui.main').window self.win.set_transient_for(parent) self.parent = parent action_id = rpc.session.rpc_exec_auth('/object', 'execute', 'res.users', 'action_get', {}) action = rpc.session.rpc_exec_auth('/object', 'execute', 'ir.actions.act_window', 'read', [action_id], False, rpc.session.context)[0] view_ids = [] if action.get('views', []): view_ids = [x[0] for x in action['views']] elif action.get('view_id', False): view_ids = [action['view_id'][0]] self.screen = Screen('res.users', view_type=[], window=parent) self.screen.add_view_id(view_ids[0], 'form', display=True) self.screen.load([rpc.session.uid]) self.screen.display(rpc.session.uid) vbox = self.glade.get_widget('preference_vbox') vbox.pack_start(self.screen.widget) self.win.set_title(_('Preferences')) self.win.show_all() def run(self, datas={}): lang = rpc.session.context.get('lang', 'en_US') end = False while not end: res = self.win.run() end = (res != gtk.RESPONSE_OK) or self.screen.current_model.validate() if not end: self.screen.display() self.screen.current_view.set_cursor() if res == gtk.RESPONSE_OK: values = self.screen.get() rpc.session.rpc_exec_auth('/object', 'execute', 'res.users', 'write', [rpc.session.uid], values) rpc.session.context_reload() new_lang = rpc.session.context.get('lang', 'en_US') if lang != new_lang: common.message(_("The default language of the interface has been modified, do not forget to restart " \ "the client to have the interface in your language"), _("Default language modified !"), parent=self.win) self.parent.present() self.win.destroy() return True
def _click_and_relate(self, action, value, model): data={} context={} act=action.copy() if not(value): common.message(_('You must select a record to use the relation !')) return False from widget.screen import Screen screen = Screen(model) screen.load([value]) act['domain'] = screen.current_model.expr_eval(act['domain'], check_load=False) act['context'] = str(screen.current_model.expr_eval(act['context'], check_load=False)) obj = service.LocalService('action.main') value = obj._exec_action(act, data, context) return value
def click_and_relate(self, action): data={} context={} act=action.copy() id = self._view.modelfield.get(self._view.model) if not(id): common.message(_('You must select a record to use the relation !')) return False screen = Screen(self.attrs['relation']) screen.load([id]) act['domain'] = screen.current_model.expr_eval(act['domain'], check_load=False) act['context'] = str(screen.current_model.expr_eval(act['context'], check_load=False)) obj = service.LocalService('action.main') value = obj._exec_action(act, data, context) return value
def __init__(self, model, id=None, attrs=None ,domain=None, context=None, window=None, view_ids=None,target=False,view_type=['form']): if attrs is None: attrs = {} if domain is None: domain = [] if context is None: context = {} if not window: window = service.LocalService('gui.main').window self.dia = gtk.Dialog('OpenERP', window, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT) self.window = window if not target: self.dia.set_property('default-width', 760) self.dia.set_property('default-height', 500) self.dia.set_position(gtk.WIN_POS_CENTER_ON_PARENT) self.dia.set_icon(common.OPENERP_ICON) self.accel_group = gtk.AccelGroup() self.dia.add_accel_group(self.accel_group) self.but_cancel = self.dia.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) self.but_cancel.add_accelerator('clicked', self.accel_group, gtk.keysyms.Escape, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) self.but_ok = self.dia.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) scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scroll.set_placement(gtk.CORNER_TOP_LEFT) scroll.set_shadow_type(gtk.SHADOW_NONE) self.dia.vbox.pack_start(scroll, expand=True, fill=True) vp = gtk.Viewport() vp.set_shadow_type(gtk.SHADOW_NONE) scroll.add(vp) self.screen = Screen(model, view_ids=view_ids, domain=domain, context=context, window=self.dia, view_type=view_type) if id: self.screen.load([id]) else: self.screen.new() if ('string' in attrs) and attrs['string']: self.dia.set_title(self.dia.get_title() + ' - ' + attrs['string']) elif self.screen.current_view: self.dia.set_title(self.dia.get_title() + ' - ' + self.screen.current_view.title) vp.add(self.screen.widget) x,y = self.screen.screen_container.size_get() x+=20 y+=25 width, height = window.get_size() if not target: vp.set_size_request(min(width - 20, x),min(height - 60, y)) else: vp.set_size_request(x,y) self.dia.show_all() self.screen.display()
def __init__(self, parent=None): self.ui = openerp_gtk_builder('openerp.ui', ['win_preference']) self.win = self.ui.get_object('win_preference') self.win.set_icon(common.OPENERP_ICON) if not parent: parent = service.LocalService('gui.main').window self.win.set_transient_for(parent) self.parent = parent action_id = rpc.session.rpc_exec_auth('/object', 'execute', 'res.users', 'action_get', {}) action = rpc.session.rpc_exec_auth('/object', 'execute', 'ir.actions.act_window', 'read', [action_id], False, rpc.session.context)[0] view_ids = [] if action.get('views', []): view_ids = [x[0] for x in action['views']] elif action.get('view_id', False): view_ids = [action['view_id'][0]] self.screen = Screen('res.users', view_type=[], window=parent) self.screen.add_view_id(view_ids[0], 'form', display=True) self.screen.load([rpc.session.uid]) self.screen.display(rpc.session.uid) vbox = self.ui.get_object('preference_vbox') vbox.pack_start(self.screen.widget) self.win.set_title(_('Preferences')) self.win.show_all()
def __init__(self, arch, fields, state, name, parent=None): buttons = [] self.states = [] default = -1 if not parent: parent = service.LocalService('gui.main').window self.dia = gtk.Dialog( 'OpenERP', parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT) for x in state: but = gtk.Button(x[1]) but.show() if len(x) >= 3: icon = gtk.Image() icon.set_from_stock(x[2], gtk.ICON_SIZE_BUTTON) but.set_image(icon) self.dia.add_action_widget(but, len(self.states)) if len(x) >= 4 and x[3]: but.set_flags(gtk.CAN_DEFAULT) default = len(self.states) self.states.append(x[0]) if default >= 0: self.dia.set_default_response(default) val = {} for f in fields: if 'value' in fields[f]: val[f] = fields[f]['value'] self.screen = Screen('wizard.' + name, view_type=[], window=self.dia, is_wizard=True) self.screen.new(default=False) self.screen.add_view_custom(arch, fields, display=True) self.screen.current_model.set(val) x, y = self.screen.screen_container.size_get() width, height = parent.get_size() self.screen.widget.set_size_request(min(width - 20, x + 20), min(height - 60, y + 25)) self.screen.widget.show() self.dia.vbox.pack_start(self.screen.widget) self.dia.set_title(self.screen.current_view.title) self.dia.show()
def click_and_relate(self, action): data = {} context = {} act = action.copy() id = self._view.modelfield.get(self._view.model) if not (id): common.message(_('You must select a record to use the relation !')) return False screen = Screen(self.attrs['relation']) screen.load([id]) act['domain'] = screen.current_model.expr_eval(act['domain'], check_load=False) act['context'] = str( screen.current_model.expr_eval(act['context'], check_load=False)) obj = service.LocalService('action.main') value = obj._exec_action(act, data, context) return value
class win_preference(object): def __init__(self, parent=None): self.ui = openerp_gtk_builder('openerp.ui', ['win_preference']) self.win = self.ui.get_object('win_preference') self.win.set_icon(common.OPENERP_ICON) if not parent: parent = service.LocalService('gui.main').window self.win.set_transient_for(parent) self.parent = parent action_id = rpc.session.rpc_exec_auth('/object', 'execute', 'res.users', 'action_get', {}) action = rpc.session.rpc_exec_auth('/object', 'execute', 'ir.actions.act_window', 'read', [action_id], False, rpc.session.context)[0] view_ids = [] if action.get('views', []): view_ids = [x[0] for x in action['views']] elif action.get('view_id', False): view_ids = [action['view_id'][0]] self.screen = Screen('res.users', view_type=[], window=parent) self.screen.add_view_id(view_ids[0], 'form', display=True) self.screen.load([rpc.session.uid]) self.screen.display(rpc.session.uid) vbox = self.ui.get_object('preference_vbox') vbox.pack_start(self.screen.widget) self.win.set_title(_('Preferences')) self.win.show_all() def run(self, datas={}): lang = rpc.session.context.get('lang', 'en_US') end = False while not end: res = self.win.run() end = (res != gtk.RESPONSE_OK) or self.screen.current_model.validate() if not end: self.screen.display() self.screen.current_view.set_cursor() if res == gtk.RESPONSE_OK: values = self.screen.get() rpc.session.rpc_exec_auth('/object', 'execute', 'res.users', 'write', [rpc.session.uid], values) rpc.session.context_reload() new_lang = rpc.session.context.get('lang', 'en_US') if lang != new_lang: common.message(_("The default language of the interface has been modified, do not forget to restart " \ "the client to have the interface in your language"), _("Default language modified !"), parent=self.win) self.parent.present() self.win.destroy() return True
def __init__(self, model, sel_multi=True, ids=[], context={}, domain = [], parent=None): self.model = model self.first = True self.domain =domain self.context = context self.context.update(rpc.session.context) self.sel_multi = sel_multi self.glade = glade.XML(common.terp_path("openerp.glade"),'win_search',gettext.textdomain()) self.win = self.glade.get_widget('win_search') self.win.set_icon(common.OPENERP_ICON) if not parent: parent = service.LocalService('gui.main').window self.parent = parent self.win.set_transient_for(parent) self.screen = Screen(model, view_type=['tree'], context=self.context, parent=self.win) self.view = self.screen.current_view self.view.unset_editable() sel = self.view.widget_tree.get_selection() if not sel_multi: sel.set_mode('single') else: sel.set_mode(gtk.SELECTION_MULTIPLE) vp = gtk.Viewport() vp.set_shadow_type(gtk.SHADOW_NONE) vp.add(self.screen.widget) sw = self.glade.get_widget('search_sw') sw.add(vp) sw.show_all() self.view.widget_tree.connect('row_activated', self.sig_activate) self.view.widget_tree.connect('button_press_event', self.sig_button) self.model_name = model view_form = rpc.session.rpc_exec_auth('/object', 'execute', self.model_name, 'fields_view_get', False, 'form', self.context) self.form = widget_search.form(view_form['arch'], view_form['fields'], model, parent=self.win) self.title = _('OpenERP Search: %s') % self.form.name self.title_results = _('OpenERP Search: %s (%%d result(s))') % self.form.name self.win.set_title(self.title) x, y = self.form.widget.size_request() hbox = self.glade.get_widget('search_hbox') hbox.pack_start(self.form.widget) self.ids = ids if self.ids: self.reload() self.old_search = None self.old_offset = self.old_limit = None if self.ids: self.old_search = [] self.old_limit = self.form.get_limit() self.old_offset = self.form.get_offset() self.view.widget.show_all() if self.form.focusable: self.form.focusable.grab_focus()
def __init__(self, window, parent, model, attrs={}): interface.widget_interface.__init__(self, window, parent, model, attrs) self.widget = gtk.VBox(homogeneous=False, spacing=1) hb = gtk.HBox(homogeneous=False, spacing=3) self.wid_text = gtk.Entry() self.wid_text.set_property('width_chars', 13) self.wid_text.connect('activate', self._sig_activate) self.wid_text.connect('button_press_event', self._menu_open) hb.pack_start(self.wid_text, expand=True, fill=True) hb.pack_start(gtk.VSeparator(), padding=2, expand=False, fill=False) self.wid_but_add = gtk.Button(stock='gtk-add') self.wid_but_add.set_relief(gtk.RELIEF_HALF) self.wid_but_add.set_focus_on_click(True) self.wid_but_add.connect('clicked', self._sig_add) hb.pack_start(self.wid_but_add, padding=3, expand=False, fill=False) self.wid_but_remove = gtk.Button(stock='gtk-remove') self.wid_but_remove.set_relief(gtk.RELIEF_HALF) self.wid_but_remove.set_focus_on_click(True) self.wid_but_remove.connect('clicked', self._sig_remove) hb.pack_start(self.wid_but_remove, expand=False, fill=False) self.widget.pack_start(hb, expand=False, fill=False) self.widget.pack_start(gtk.HSeparator(), expand=False, fill=True) scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scroll.set_placement(gtk.CORNER_TOP_LEFT) scroll.set_shadow_type(gtk.SHADOW_NONE) self.screen = Screen(attrs['relation'], view_type=['tree'], views_preload=attrs.get('views', {})) scroll.add_with_viewport(self.screen.widget) self.widget.pack_start(scroll, expand=True, fill=True) # self.old = None self.avail_ids = set()
def __init__(self, model, sel_multi=True, ids=[], context={}, domain=[], parent=None): self.model = model self.sel_multi = sel_multi self.ids = ids self.ctx = context self.glade = glade.XML(common.terp_path("openerp.glade"), "win_search", gettext.textdomain()) self.win = self.glade.get_widget("win_search") self.win.set_icon(common.OPENERP_ICON) if not parent: parent = service.LocalService("gui.main").window self.parent = parent self.win.set_transient_for(parent) self.screen = Screen( model, view_type=["tree"], show_search=True, domain=domain, context=context, parent=self.win, win_search=True, ) self.view = self.screen.current_view if self.screen.filter_widget.focusable: self.screen.filter_widget.focusable.grab_focus() self.title = _("OpenERP Search: %s") % self.screen.name self.title_results = _("OpenERP Search: %s (%%d result(s))") % (self.screen.name,) self.win.set_title(self.title) self.view.unset_editable() sel = self.view.widget_tree.get_selection() if not sel_multi: sel.set_mode("single") else: sel.set_mode(gtk.SELECTION_MULTIPLE) self.view.widget_tree.connect("row_activated", self.sig_activate) self.view.widget_tree.connect("button_press_event", self.sig_button) self.screen.win_search_callback = self.update_title vp = gtk.Viewport() vp.set_shadow_type(gtk.SHADOW_NONE) vp.add(self.screen.widget) vp.show() self.sw = gtk.ScrolledWindow() self.sw.set_shadow_type(gtk.SHADOW_NONE) self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.sw.add(vp) self.sw.show() self.wid = self.glade.get_widget("win_search_vbox") self.wid.pack_start(self.sw) self.wid.show_all()
def __init__(self, model, domain=None, context=None, window=None, target=False): if domain is None: domain = [] if context is None: context = {} if not window: window = service.LocalService("gui.main").window self.dia = gtk.Dialog(_("OpenERP - Link"), window, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT) self.window = window if not target: self.dia.set_property("default-width", 760) self.dia.set_property("default-height", 500) self.dia.set_position(gtk.WIN_POS_CENTER_ON_PARENT) self.dia.set_icon(common.OPENERP_ICON) self.accel_group = gtk.AccelGroup() self.dia.add_accel_group(self.accel_group) self.but_cancel = self.dia.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) self.but_cancel.add_accelerator( "clicked", self.accel_group, gtk.keysyms.Escape, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE ) self.but_ok = self.dia.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 ) scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scroll.set_placement(gtk.CORNER_TOP_LEFT) scroll.set_shadow_type(gtk.SHADOW_NONE) self.dia.vbox.pack_start(scroll, expand=True, fill=True) vp = gtk.Viewport() vp.set_shadow_type(gtk.SHADOW_NONE) scroll.add(vp) self.screen = Screen(model, view_ids=None, domain=domain, context=context, window=self.dia, view_type=["form"]) self.screen.new() vp.add(self.screen.widget) x, y = self.screen.screen_container.size_get() width, height = window.get_size() vp.set_size_request(min(width - 20, x + 20), min(height - 60, y + 25)) self.dia.show_all() self.screen.display()
def __init__(self, window, parent, model, attrs={}): interface.widget_interface.__init__(self, window, parent, model, attrs) self.act_id = int(attrs['name']) res = rpc.session.rpc_exec_auth('/object', 'execute', 'ir.actions.actions', 'read', [self.act_id], ['type'], rpc.session.context) if not res: raise Exception, 'ActionNotFound' type = res[0]['type'] self.action = rpc.session.rpc_exec_auth('/object', 'execute', type, 'read', [self.act_id], False, rpc.session.context)[0] if 'view_mode' in attrs: self.action['view_mode'] = attrs['view_mode'] self.action_view_ids = False if self.action['type'] == 'ir.actions.act_window': if not self.action.get('domain', False): self.action['domain'] = '[]' if attrs.get('domain',False): self.action['domain'] = attrs.get('domain') self.context = {'active_id': False, 'active_ids': []} self.context.update(tools.expr_eval(self.action.get('context', '{}'), self.context.copy())) self.domain = tools.expr_eval(self.action['domain'], self.context.copy()) view_id = [] if self.action['view_id']: view_id = [self.action['view_id'][0]] if self.action.get('views'): self.action_view_ids = map(lambda y:y[0], filter(lambda x:x[1] == 'tree',self.action['views'])) if self.action['view_type']=='form': mode = (self.action['view_mode'] or 'form,tree').split(',') self.screen = Screen(self.action['res_model'], view_type=mode, context=self.context, view_ids = view_id, domain=self.domain) self.ui = openerp_gtk_builder('openerp.ui', ['widget_paned']) self.ui.connect_signals({ 'on_switch_button_press_event': self._sig_switch, 'on_search_button_press_event': self._sig_search, 'on_open_button_press_event': self._sig_open, }) label = self.ui.get_object('widget_paned_lab') label.set_text(attrs.get('string', self.screen.current_view.title)) vbox = self.ui.get_object('widget_paned_vbox') vbox.add(self.screen.widget) self.widget = self.ui.get_object('widget_paned') self.widget.set_size_request(int(attrs.get('width', -1)), int(attrs.get('height', -1))) elif self.action['view_type']=='tree': pass #TODO
def __init__(self, window, parent, model, attrs={}): interface.widget_interface.__init__(self, window, parent, model, attrs) self.act_id=attrs['name'] res = rpc.session.rpc_exec_auth('/object', 'execute', 'ir.actions.actions', 'read', [self.act_id], ['type'], rpc.session.context) if not res: raise Exception, 'ActionNotFound' type=res[0]['type'] self.action = rpc.session.rpc_exec_auth('/object', 'execute', type, 'read', [self.act_id], False, rpc.session.context)[0] if 'view_mode' in attrs: self.action['view_mode'] = attrs['view_mode'] if self.action['type']=='ir.actions.act_window': if not self.action.get('domain', False): self.action['domain']='[]' self.context = {'active_id': False, 'active_ids': []} self.context.update(eval(self.action.get('context', '{}'), self.context.copy())) a = self.context.copy() a['time'] = time a['datetime'] = datetime self.domain = tools.expr_eval(self.action['domain'], a) view_id = [] if self.action['view_id']: view_id = [self.action['view_id'][0]] if self.action['view_type']=='form': mode = (self.action['view_mode'] or 'form,tree').split(',') self.screen = Screen(self.action['res_model'], view_type=mode, context=self.context, view_ids = view_id, domain=self.domain) self.win_gl = glade.XML(common.terp_path("openerp.glade"), 'widget_paned', gettext.textdomain()) self.win_gl.signal_connect('on_switch_button_press_event', self._sig_switch) self.win_gl.signal_connect('on_search_button_press_event', self._sig_search) self.win_gl.signal_connect('on_open_button_press_event', self._sig_open) label=self.win_gl.get_widget('widget_paned_lab') label.set_text(attrs.get('string', self.screen.current_view.title)) vbox=self.win_gl.get_widget('widget_paned_vbox') vbox.add(self.screen.widget) self.widget=self.win_gl.get_widget('widget_paned') self.widget.set_size_request(int(attrs.get('width', -1)), int(attrs.get('height', -1))) elif self.action['view_type']=='tree': pass #TODO
def __init__(self, model, sel_multi=True, ids=[], view_ids=False, context={}, domain = [], parent=None): self.model = model self.sel_multi = sel_multi self.ids = ids self.ui = openerp_gtk_builder('openerp.ui', ['win_search']) self.win = self.ui.get_object('win_search') self.win.set_icon(common.OPENERP_ICON) if not parent: parent = service.LocalService('gui.main').window self.parent = parent self.win.set_transient_for(parent) self.screen = Screen(model, view_type=['tree'], view_ids=view_ids, show_search=True, domain=domain, context=context, parent=self.win, win_search=True) self.view = self.screen.current_view if self.screen.filter_widget.focusable: self.screen.filter_widget.focusable.grab_focus() self.title = _('OpenERP Search: %s') % self.screen.name self.title_results = _('OpenERP Search: %s (%%d result(s))') % (self.screen.name,) self.win.set_title(self.title) self.view.unset_editable() sel = self.view.widget_tree.get_selection() if not sel_multi: sel.set_mode('single') else: sel.set_mode(gtk.SELECTION_MULTIPLE) self.view.widget_tree.connect('row_activated', self.sig_activate) self.view.widget_tree.connect('button_press_event', self.sig_button) self.screen.win_search_callback = self.update_title vp = gtk.Viewport() vp.set_shadow_type(gtk.SHADOW_NONE) vp.add(self.screen.widget) vp.show() self.sw = gtk.ScrolledWindow() self.sw.set_shadow_type(gtk.SHADOW_NONE) self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.sw.add(vp) self.sw.show() self.wid = self.ui.get_object('win_search_vbox') self.wid.pack_start(self.sw) self.wid.show_all()
class dialog(object): def __init__(self, model_name, parent, model=None, attrs=None, model_ctx=None, window=None, default_get_ctx=None, readonly=False): if attrs is None: attrs = {} if model_ctx is None: model_ctx = {} if default_get_ctx is None: default_get_ctx = {} if not window: window = service.LocalService('gui.main').window self.dia = gtk.Dialog(_('OpenERP - Link'), window, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT) self.window = window if ('string' in attrs) and attrs['string']: self.dia.set_title(self.dia.get_title() + ' - ' + attrs['string']) self.dia.set_property('default-width', 760) self.dia.set_property('default-height', 500) self.dia.set_position(gtk.WIN_POS_CENTER_ON_PARENT) self.dia.set_icon(common.OPENERP_ICON) self.accel_group = gtk.AccelGroup() self.dia.add_accel_group(self.accel_group) self.but_cancel = self.dia.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CANCEL) self.but_cancel.add_accelerator('clicked', self.accel_group, gtk.keysyms.Escape, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) self.but_ok = self.dia.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.default_get_ctx = default_get_ctx scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scroll.set_placement(gtk.CORNER_TOP_LEFT) scroll.set_shadow_type(gtk.SHADOW_NONE) self.dia.vbox.pack_start(scroll, expand=True, fill=True) vp = gtk.Viewport() vp.set_shadow_type(gtk.SHADOW_NONE) scroll.add(vp) self.screen = Screen(model_name, view_type=[], parent=parent, window=self.dia, readonly=readonly) self.screen.models._context.update(model_ctx) if not model: model = self.screen.new(context=default_get_ctx) else: self.screen.models.model_add(model) self.screen.current_model = model if ('views' in attrs) and ('form' in attrs['views']): arch = attrs['views']['form']['arch'] fields = attrs['views']['form']['fields'] self.screen.add_view(arch, fields, display=True, context=default_get_ctx) else: self.screen.add_view_id(False, 'form', display=True, context=default_get_ctx) vp.add(self.screen.widget) x,y = self.screen.screen_container.size_get() vp.set_size_request(x,y+30) self.dia.show_all() self.screen.readonly = readonly self.screen.display() def new(self): model = self.screen.new(context=self.default_get_ctx) self.screen.models.model_add(model) self.screen.current_model = model return True def run(self, datas={}): end = False while not end: res = self.dia.run() if res == gtk.RESPONSE_CANCEL: self.screen.current_model.cancel() end = (res != gtk.RESPONSE_OK) or self.screen.current_model.validate() if not end: self.screen.display() if res==gtk.RESPONSE_OK: self.screen.current_view.set_value() model = self.screen.current_model return (True, model) return (False, False) def destroy(self): self.screen.signal_unconnect(self) self.window.present() self.dia.destroy() self.screen.destroy()
class one2many_list(interface.widget_interface): def __init__(self, window, parent, model, attrs={}): interface.widget_interface.__init__(self, window, parent, model, attrs) self.context = {} self._readonly = self.default_readonly self.widget = gtk.VBox(homogeneous=False, spacing=5) hb = gtk.HBox(homogeneous=False, spacing=5) event_box = gtk.EventBox() event_box.set_events(gtk.gdk.BUTTON_PRESS_MASK) hb.pack_start(event_box, expand=True, fill=True) # the context to pass to default_get can be optionally specified in # the context of the one2many field. We also support a legacy # 'default_get' attribute for the same effect (pending removal) default_get_ctx = (attrs.get('default_get') or attrs.get('context')) self.context = tools.expr_eval(attrs.get('context',"{}"), {"__builtins__":None, "parent": parent}) self.screen = Screen(attrs['relation'], view_type=attrs.get('mode','tree,form').split(','), parent=self.parent, views_preload=attrs.get('views', {}), tree_saves=attrs.get('saves', False), create_new=True, context=self.context, row_activate=self._on_activate, default_get=default_get_ctx, window=self._window, readonly=self._readonly, limit=pager.DEFAULT_LIMIT) self.screen.type = 'one2many' self.pager = pager(object=self, relation=attrs['relation'], screen=self.screen) # Button New self.eb_new = self.pager.create_event_box(_('Create a new entry'), self._sig_new, 'gtk-new') hb.pack_start(self.eb_new, expand=False, fill=False) # Button Edit self.eb_open = self.pager.create_event_box(_('Edit this entry'), self._sig_edit, 'gtk-open') hb.pack_start(self.eb_open, expand=False, fill=False) # Button Delete self.eb_del = self.pager.create_event_box(_('Remove this entry'), self._sig_remove, 'gtk-delete') hb.pack_start(self.eb_del, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # Button Previous Page self.eb_prev_page = self.pager.create_event_box(_('Previous Page'), self._sig_prev_page, 'gtk-goto-first') hb.pack_start(self.eb_prev_page, expand=False, fill=False) # Button Previous Record self.eb_pre = self.pager.create_event_box(_('Previous Record'), self._sig_previous, 'gtk-go-back') hb.pack_start(self.eb_pre, expand=False, fill=False) # Record display self.label = gtk.Label('(0,0)') hb.pack_start(self.label, expand=False, fill=False) # Button Next self.eb_next = self.pager.create_event_box(_('Next Record'), self._sig_next, 'gtk-go-forward') hb.pack_start(self.eb_next, expand=False, fill=False) # Button Next Page self.eb_next_page = self.pager.create_event_box(_('Next Page'), self._sig_next_page, 'gtk-goto-last') hb.pack_start(self.eb_next_page, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # Button Switch self.eb_switch = self.pager.create_event_box(_('Switch'), self.switch_view, 'gtk-justify-left') hb.pack_start(self.eb_switch, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # Limit Combo self.cb = self.pager.create_combo_box(_('Choose Limit'), self.limit_changed) hb.pack_start(self.cb, expand=False, fill=False) self.widget.pack_start(hb, expand=False, fill=True) self.screen.signal_connect(self, 'record-message', self._sig_label) menu_title = gtk.Label('<b>'+self.screen.current_view.title.replace('&','&').replace('<','<').replace('>','>')+'</b>') menu_title.set_use_markup(True) menu_title.set_alignment(0, 0) event_box.add(menu_title) event_box.connect('button_press_event',self.load_menu) self.screen.widget.set_property('height-request', 100) self.widget.pack_start(self.screen.widget, expand=True, fill=True) self.screen.widget.connect('key_press_event', self.on_keypress) self.model = None self.model_field = None self.name = attrs['name'] def load_menu(self, widget, event): if event.button != 3: return menu = gtk.Menu() menuitem_set_to_default = gtk.MenuItem(_('Set to default value'), True) menuitem_set_to_default.connect('activate', lambda *x:self._menu_sig_default_get()) menu.add(menuitem_set_to_default) menuitem_set_default = gtk.MenuItem(_('Set Default'), True) menuitem_set_default.connect('activate', lambda *x: self._menu_sig_default_set()) menu.add(menuitem_set_default) menu.show_all() menu.popup(None,None,None,event.button,event.time) return True def on_keypress(self, widget, event): if (not self._readonly) and ((event.keyval in (gtk.keysyms.N, gtk.keysyms.n) and event.state & gtk.gdk.CONTROL_MASK\ and event.state & gtk.gdk.SHIFT_MASK)): self._sig_new(widget, event) return False if event.keyval in (gtk.keysyms.E, gtk.keysyms.e) and event.state & gtk.gdk.CONTROL_MASK\ and event.state & gtk.gdk.SHIFT_MASK: self._sig_edit(widget, event) return False if event.keyval in (gtk.keysyms.L, gtk.keysyms.l) and event.state & gtk.gdk.CONTROL_MASK\ and event.state & gtk.gdk.SHIFT_MASK: self.switch_view(widget, event) return False def destroy(self): self.screen.destroy() def _on_activate(self, screen, *args): self._sig_edit() def click_and_action(self, type): pos = self.tree_view.pos_get() if pos!=None: val = self._value[pos] id = val.get('id', False) obj = service.LocalService('action.main') res = obj.exec_keyword(type, {'model':self.model, 'id': id or False, 'ids':[id], 'report_type': 'pdf'}) return True else: common.message(_('You have to select a resource !')) return False def switch_view(self, btn, arg): self.screen.make_buttons_readonly(True) self.screen.switch_view() def _readonly_set(self, value): self._readonly = value self.eb_new.set_sensitive(not value) self.eb_del.set_sensitive(not value) self.screen.readonly = value self.screen.display() def set_disable(self, value): self.eb_open.set_sensitive(value) self.eb_switch.set_sensitive(value) if self._readonly: value = not self._readonly self.eb_del.set_sensitive(value) ## This method is specially developed to store old values of ## the modified records. def _get_old_values(self, models=None): group_model = {} model_value = {} if models is None: models = [] for o2m_model in models: values = o2m_model.value.copy() model_value.setdefault(o2m_model, values) group_model.setdefault(o2m_model, {}) for key, val in values.iteritems(): if isinstance(val, ModelRecordGroup): group_model[o2m_model][key] = val.models[:] del model_value[o2m_model][key] return model_value,group_model ## This method is specially developed to restore old values def _restore_values(self, modified_model_values, group_model): for model, value in modified_model_values.iteritems(): model.set(value, modified=True) for f_name, models in group_model.get(model, {}): model.value[f_name].clear() for sub_model in models: # add model in ModelRecordGroup model.value[f_name].model_add(sub_model) return True def _sig_new(self, *args): _, event = args ctx = dict(self._view.model.expr_eval(self.screen.default_get), **self.context) ctx.update(self._view.model.expr_eval('dict(%s)' % self.attrs.get('context', '{}'))) if event.type in (gtk.gdk.BUTTON_PRESS, gtk.gdk.KEY_PRESS): if (self.screen.current_view.view_type=='form') or self.screen.editable_get(): self.screen.new(context=ctx) self.screen.make_buttons_readonly() self._readonly = False self.screen.current_view.widget.set_sensitive(True) self.set_disable(True) else: ok = True dia = dialog(self.attrs['relation'], parent=self._view.model, attrs=self.attrs, model_ctx=self.screen.models._context, window=self._window, readonly=self._readonly, context=ctx) while ok: ok, value, res = dia.run() if ok or res == gtk.RESPONSE_APPLY: modified_model_values, group_model = self._get_old_values(self.screen.models.models) self.screen.models.model_add(value) value.signal('record-changed', value.parent) self._restore_values(modified_model_values, group_model) self.screen.display() dia.new() self.set_disable(True) self.pager.reset_pager() dia.destroy() def _sig_edit(self, *args): ctx = dict(self._view.model.expr_eval(self.screen.default_get), **self.context) ctx.update(self._view.model.expr_eval('dict(%s)' % self.attrs.get('context', '{}'))) ok = True modified_model_values, group_model = self._get_old_values(self.screen.models.models) dia = dialog(self.attrs['relation'], parent=self._view.model, model=self.screen.current_model, attrs=self.attrs, window=self._window, readonly=self._readonly, context=ctx) while ok: ok, value, res = dia.run() if not any([ok, value, res]) and dia.screen.is_modified(): if modified_model_values: self._restore_values(modified_model_values, group_model) if res == gtk.RESPONSE_OK: dia.new() if value and value.id is None: modified_model_values, group_model = self._get_old_values(self.screen.models.models) if value not in modified_model_values: self.screen.models.model_add(value) value.signal('record-changed', value.parent) if modified_model_values: self._restore_values(modified_model_values, group_model) self.screen.display() self.pager.reset_pager() dia.destroy() def limit_changed(self,*args): self.pager.limit_changed() def _sig_prev_page(self, *args): self.pager.prev_page() def _sig_next_page(self, *args): self.pager.next_page() def _sig_next(self, *args): _, event = args if event.type == gtk.gdk.BUTTON_PRESS: self.pager.next_record() def _sig_previous(self, *args): _, event = args if event.type == gtk.gdk.BUTTON_PRESS: self.pager.prev_record() def _sig_remove(self, *args): lst, event = args if event.type == gtk.gdk.BUTTON_PRESS: if self.screen.current_view.view_type == 'form': msg = _('Are you sure to remove this record ?') else: msg = _('Are you sure to remove those records ?') if common.sur(msg): model = self.screen.current_model model.signal('record-changed', model.parent) self.screen.remove() self.pager.reset_pager() if not self.screen.models.models: self.screen.current_view.widget.set_sensitive(False) def _sig_label(self, screen, signal_data): name = '_' if signal_data[0] >= 0: name = str(signal_data[0] + 1) line = '(%s/%s of %s)' % (name, signal_data[1], signal_data[2]) self.label.set_text(line) def _sig_refresh(self, *args): pass def _sig_sequence(self, *args): pass def display(self, model, model_field): if model: self.context.update(model.expr_eval(self.attrs.get('context',"{}"))) self.screen.context.update(self.context) self.model = model self.model_field = model_field if not model_field: self.screen.current_model = None self.screen.display() return False super(one2many_list, self).display(model, model_field) new_models = model_field.get_client(model) if self.screen.models != new_models: self.screen.models_set(new_models) if (self.screen.current_view.view_type=='tree') and self.screen.editable_get(): if len(self.screen.models.models): self.screen.current_model = self.screen.models.models[0] else: self.screen.current_model = None if self.screen.current_view.view_type=='form': self.screen.make_buttons_readonly(self.screen.current_model \ and self.screen.current_model.id and True or False) self.set_disable(self.screen.models.models and True or False) self.pager.search_count() self.pager.set_sensitivity() self.screen.display() return True def set_value(self, model, model_field): self.screen.current_view.set_value() if self.screen.is_modified(): model.modified = True model.modified_fields.setdefault(model_field.name) return True def grab_focus(self): return self.screen.widget.grab_focus()
class form(object): def __init__(self, model, res_id=False, domain=None, view_type=None, view_ids=None, window=None, context=None, name=False, help={}, limit=100, auto_refresh=False, auto_search=True, search_view=None): if not view_type: view_type = ['form', 'tree'] if domain is None: domain = [] if view_ids is None: view_ids = [] if context is None: context = {} fields = {} self.model = model self.window = window self.previous_action = None self.glade = glade.XML(common.terp_path("openerp.glade"), 'win_form_container', gettext.textdomain()) self.widget = self.glade.get_widget('win_form_container') self.widget.show_all() self.fields = fields self.domain = domain self.context = context self.screen = Screen(self.model, view_type=view_type, context=self.context, view_ids=view_ids, domain=domain, help=help, hastoolbar=options.options['form.toolbar'], hassubmenu=options.options['form.submenu'], show_search=True, window=self.window, limit=limit, readonly=bool(auto_refresh), auto_search=auto_search, search_view=search_view) self.screen.signal_connect(self, 'record-message', self._record_message) self.screen.widget.show() oregistry.add_receiver('misc-message', self._misc_message) if not name: self.name = self.screen.current_view.title else: self.name = name vp = gtk.Viewport() vp.set_shadow_type(gtk.SHADOW_NONE) vp.add(self.screen.widget) vp.show() self.sw = gtk.ScrolledWindow() self.sw.set_shadow_type(gtk.SHADOW_NONE) self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.sw.add(vp) self.sw.show() self.has_backup = False self.backup = {} self.widget.pack_start(self.sw) self.handlers = { 'but_new': self.sig_new, 'but_copy': self.sig_copy, 'but_save': self.sig_save, 'but_save_as': self.sig_save_as, 'but_import': self.sig_import, 'but_print_repeat': self.sig_print_repeat, 'but_remove': self.sig_remove, 'but_search': self.sig_search, 'but_previous': self.sig_previous, 'but_next': self.sig_next, 'but_goto_id': self.sig_goto, 'but_log': self.sig_logs, 'but_print': self.sig_print, 'but_reload': self.sig_reload, 'but_print_html': self.sig_print_html, 'but_action': self.sig_action, 'but_switch': self.sig_switch, 'but_attach': self.sig_attach, 'but_close': self.sig_close, } if 'tree' in view_type: self.handlers['radio_tree'] = self.sig_switch_tree if 'form' in view_type: self.handlers['radio_form'] = self.sig_switch_form if 'graph' in view_type: self.handlers['radio_graph'] = self.sig_switch_graph if 'calendar' in view_type: self.handlers['radio_calendar'] = self.sig_switch_calendar if 'diagram' in view_type: self.handlers['radio_diagram'] = self.sig_switch_diagram if res_id: if isinstance(res_id, ( int, long, )): res_id = [res_id] self.screen.load(res_id) else: if self.screen.current_view.view_type == 'form': self.sig_new(autosave=False) if self.screen.current_view.view_type in ('tree', 'graph', 'calendar'): self.screen.search_filter() if auto_refresh and int(auto_refresh): gobject.timeout_add(int(auto_refresh) * 1000, self.sig_reload) def sig_switch_diagram(self, widget=None): return self.sig_switch(widget, 'diagram') def sig_switch_form(self, widget=None): return self.sig_switch(widget, 'form') def sig_switch_tree(self, widget=None): return self.sig_switch(widget, 'tree') def sig_switch_calendar(self, widget=None): return self.sig_switch(widget, 'calendar') def sig_switch_graph(self, widget=None): return self.sig_switch(widget, 'graph') def get_resource(self, widget=None, get_id=None): ## This has been done due to virtual ids coming from ## crm meeting. like '3-20101012155505' which are not in existence ## and needed to be converted to real ids if isinstance(get_id, str): get_id = int(get_id.split('-')[0]) if widget: get_id = int(widget.get_value()) # We need listed / searched set of IDS when we switch back to a view listed_ids = self.screen.ids_get() ## If the record is already among the previously searched records or inside ## the listed_ids, we do not need to call search record_exists = False if get_id in listed_ids: self.screen.display(get_id) record_exists = True else: # User is trying to see the record with Ctrl + G option! So we search domainless, limitless! record_exists = rpc.session.rpc_exec_auth('/object', 'execute', self.model, 'search', [('id', '=', get_id)], False, False, False, self.screen.context) if record_exists: self.screen.load([get_id]) if get_id and record_exists: self.screen.current_view.set_cursor() else: common.message(_('Resource ID does not exist for this object!')) def get_event(self, widget, event, win): if event.keyval in (gtk.keysyms.Return, gtk.keysyms.KP_Enter): win.destroy() self.get_resource(widget) def sig_goto(self, *args): if not self.modified_save(): return glade2 = glade.XML(common.terp_path("openerp.glade"), 'dia_goto_id', gettext.textdomain()) widget = glade2.get_widget('goto_spinbutton') win = glade2.get_widget('dia_goto_id') widget.connect('key_press_event', self.get_event, win) win.set_transient_for(self.window) win.show_all() response = win.run() win.destroy() if response == gtk.RESPONSE_OK: self.get_resource(widget) def destroy(self): """ Destroy the page object and all the child (or at least should do this) """ oregistry.remove_receiver('misc-message', self._misc_message) self.screen.signal_unconnect(self) self.screen.destroy() self.widget.destroy() self.sw.destroy() del self.screen del self.handlers def ids_get(self): return self.screen.ids_get() def id_get(self): return self.screen.id_get() def sig_attach(self, widget=None): id = self.id_get() if id: ctx = self.context.copy() ctx.update(rpc.session.context) action = rpc.session.rpc_exec_auth('/object', 'execute', 'ir.attachment', 'action_get', ctx) action['domain'] = [('res_model', '=', self.model), ('res_id', '=', id)] ctx['default_res_model'] = self.model ctx['default_res_id'] = id obj = service.LocalService('action.main') obj._exec_action(action, {}, ctx) else: self.message_state(_( 'No record selected ! You can only attach to existing record.' ), color='red') return True def sig_switch(self, widget=None, mode=None): if not self.modified_save(): return id = self.screen.id_get() if mode <> self.screen.current_view.view_type: self.screen.switch_view(mode=mode) if id: self.sig_reload() self.get_resource(get_id=id) def sig_logs(self, widget=None): id = self.id_get() if not id: self.message_state(_('You have to select a record !'), color='red') return False res = rpc.session.rpc_exec_auth('/object', 'execute', self.model, 'perm_read', [id]) message = '' for line in res: todo = [('id', _('ID')), ('create_uid', _('Creation User')), ('create_date', _('Creation Date')), ('write_uid', _('Latest Modification by')), ('write_date', _('Latest Modification Date')), ('xmlid', _('Internal Module Data ID'))] for (key, val) in todo: if line[key] and key in ('create_uid', 'write_uid', 'uid'): line[key] = line[key][1] message += val + ': ' + str(line[key] or '/') + '\n' common.message(message) return True def sig_remove(self, widget=None): if not self.id_get(): msg = _( 'Record is not saved ! \n Do you want to clear current record ?' ) else: if self.screen.current_view.view_type == 'form': msg = _('Are you sure to remove this record ?') else: msg = _('Are you sure to remove those records ?') if common.sur(msg): id = self.screen.remove(unlink=True) if not id: self.message_state(_('Resources cleared.'), color='darkgreen') else: self.message_state(_('Resources successfully removed.'), color='darkgreen') self.sig_reload() def sig_import(self, widget=None): fields = [] while (self.screen.view_to_load): self.screen.load_view_to_load() screen_fields = copy.deepcopy(self.screen.models.fields) win = win_import.win_import(self.model, screen_fields, fields, parent=self.window, local_context=self.screen.context) res = win.go() def sig_save_as(self, widget=None): fields = [] while (self.screen.view_to_load): self.screen.load_view_to_load() screen_fields = copy.deepcopy(self.screen.models.fields) ids = self.screen.ids_get() if not ids: msg = _('No records to export! \n Select at least one record ') if not ids and self.context.get('group_by_no_leaf', False): msg = _( 'You cannot export these record(s) ! Either use copy and paste' ) common.warning(msg, _('Warning !'), parent=self.window) return win = win_export.win_export(self.model, ids, screen_fields, fields, parent=self.window, context=self.context) res = win.go() def sig_new(self, widget=None, autosave=True): if autosave: if not self.modified_save(): return self.screen.create_new = True self.screen.new() self.message_state('') def sig_copy(self, *args): if not self.modified_save(): return res_id = self.id_get() ctx = self.context.copy() ctx.update(rpc.session.context) new_id = rpc.session.rpc_exec_auth('/object', 'execute', self.model, 'copy', res_id, {}, ctx) if new_id: self.screen.load([new_id]) self.screen.current_view.set_cursor() self.message_state(_('Working now on the duplicated document !')) self.sig_reload() def _form_save(self, auto_continue=True): pass def sig_save(self, widget=None, sig_new=True, auto_continue=True): res = self.screen.save_current() warning = False if isinstance(res, dict): id = res.get('id', False) warning = res.get('warning', False) else: id = res if id: self.message_state(_('Document Saved.'), color="darkgreen") elif len(self.screen.models.models) and res != None: common.warning(_('Invalid form, correct red fields !'), _('Error !'), parent=self.screen.current_view.window) self.message_state(_('Invalid form, correct red fields !'), color="red") if warning: common.warning(warning, _('Warning !'), parent=self.screen.current_view.window) return bool(id) def sig_previous(self, widget=None): if not self.modified_save(): return self.screen.display_prev() self.message_state('') def sig_next(self, widget=None): if not self.modified_save(): return self.screen.display_next() self.message_state('') def sig_reload(self, test_modified=True): if not hasattr(self, 'screen'): return False if test_modified and self.screen.is_modified(): res = common.sur_3b(_('This record has been modified\n' \ 'do you want to save it ?')) if res == 'ok': self.sig_save() elif res == 'ko': pass else: return False if self.screen.current_view.view_type == 'form': self.screen.cancel_current() self.screen.display() else: id = self.screen.id_get() self.screen.search_filter() for model in self.screen.models: if model.id == id: self.screen.current_model = model self.screen.display() break self.message_state('') return True def sig_action(self, keyword='client_action_multi', previous=False, report_type='pdf', adds={}): ids = self.screen.ids_get() group_by = self.screen.context.get('group_by') if self.screen.current_model: id = self.screen.current_model.id else: id = False if self.screen.current_view.view_type == 'form': id = self.screen.save_current() if not id: return False ids = [id] if self.screen.current_view.view_type == 'tree': self.modified_save() sel_ids = self.screen.sel_ids_get() if sel_ids: ids = sel_ids if len(ids) or group_by: obj = service.LocalService('action.main') data = { 'model': self.screen.resource, 'id': id or False, 'ids': ids, 'report_type': report_type, '_domain': self.screen.domain } # When group by header is selected add it's children as a active_ids if group_by: self.screen.context.update({ 'active_id': id, 'active_ids': ids }) if previous and self.previous_action: obj._exec_action(self.previous_action[1], data, self.screen.context) else: res = obj.exec_keyword(keyword, data, adds, self.screen.context) if res: self.previous_action = res self.sig_reload(test_modified=False) else: self.message_state(_('You must select one or several records !'), color='red') def sig_print_repeat(self): self.sig_action('client_print_multi', True) def sig_print_html(self): self.sig_action('client_print_multi', report_type='html') def sig_print(self): self.sig_action('client_print_multi', adds={ _('Print Screen').encode('utf8'): { 'report_name': 'printscreen.list', 'name': _('Print Screen'), 'type': 'ir.actions.report.xml' } }) def sig_search(self, widget=None): if not self.modified_save(): return dom = self.domain win = win_search.win_search(self.model, domain=self.domain, context=self.context, parent=self.window) res = win.go() if res: self.screen.clear() self.screen.load(res) def message_state(self, message, context='message', color=None): sb = self.glade.get_widget('stat_state') if color is not None: message = '<span foreground="%s">%s</span>' % (color, message) sb.set_label(message) def _record_message(self, screen, signal_data): if not signal_data[3]: msg = _('No record selected') else: name = '_' if signal_data[0] >= 0: name = str(signal_data[0] + 1) name2 = _('New document') if signal_data[3]: name2 = _('Editing document (id: ') + str(signal_data[3]) + ')' # Total Records should never change tot_count = signal_data[2] < signal_data[1] and str( signal_data[1]) or str(signal_data[2]) msg = _('Record: ') + name + ' / ' + str(signal_data[1]) + \ _(' of ') + str(tot_count) + ' - ' + name2 sb = self.glade.get_widget('stat_form') cid = sb.get_context_id('message') sb.push(cid, msg) def _misc_message(self, obj, message, color=None): self.message_state(message, color=color) def modified_save(self, reload=True): if self.screen.is_modified(): value = common.sur_3b( _('This record has been modified\ndo you want to save it ?')) if value == 'ok': return self.sig_save() elif value == 'ko': if reload: self.sig_reload(test_modified=False) return True else: return False return True def sig_close(self, urgent=False): res = self.modified_save(reload=False) return res
class win_search(object): def __init__(self, model, sel_multi=True, ids=[], view_ids=False, context={}, domain = [], parent=None): self.model = model self.sel_multi = sel_multi self.ids = ids self.ui = openerp_gtk_builder('openerp.ui', ['win_search']) self.win = self.ui.get_object('win_search') self.win.set_icon(common.OPENERP_ICON) if not parent: parent = service.LocalService('gui.main').window self.parent = parent self.win.set_transient_for(parent) self.screen = Screen(model, view_type=['tree'], view_ids=view_ids, show_search=True, domain=domain, context=context, parent=self.win, win_search=True) self.view = self.screen.current_view if self.screen.filter_widget.focusable: self.screen.filter_widget.focusable.grab_focus() self.title = _('OpenERP Search: %s') % self.screen.name self.title_results = _('OpenERP Search: %s (%%d result(s))') % (self.screen.name,) self.win.set_title(self.title) self.view.unset_editable() sel = self.view.widget_tree.get_selection() if not sel_multi: sel.set_mode('single') else: sel.set_mode(gtk.SELECTION_MULTIPLE) self.view.widget_tree.connect('row_activated', self.sig_activate) self.view.widget_tree.connect('button_press_event', self.sig_button) self.screen.win_search_callback = self.update_title vp = gtk.Viewport() vp.set_shadow_type(gtk.SHADOW_NONE) vp.add(self.screen.widget) vp.show() self.sw = gtk.ScrolledWindow() self.sw.set_shadow_type(gtk.SHADOW_NONE) self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.sw.add(vp) self.sw.show() self.wid = self.ui.get_object('win_search_vbox') self.wid.pack_start(self.sw) self.wid.show_all() def sig_activate(self, treeview, path, column, *args): self.view.widget_tree.emit_stop_by_name('row_activated') if not self.sel_multi: self.win.response(gtk.RESPONSE_OK) return False def sig_button(self, view, event): if event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS: self.win.response(gtk.RESPONSE_OK) return False def find(self, widget=None, *args): self.screen.search_filter() self.update_title() def update_title(self): self.ids = self.screen.win_search_ids self.reload() self.win.set_title(self.title_results % len(self.ids)) def reload(self): sel = self.view.widget_tree.get_selection() if sel.get_mode() == gtk.SELECTION_MULTIPLE: sel.select_all() def sel_ids_get(self): return self.screen.sel_ids_get() def destroy(self): self.parent.present() self.win.destroy() def go(self): ## This is if the user has set some filters by default with search_default_XXX if self.ids: self.screen.win_search_domain += [('id','in', self.ids)] self.find() else: self.screen.update_scroll() end = False while not end: sel = self.view.widget_tree.get_selection() if sel.get_mode() == gtk.SELECTION_MULTIPLE: sel.unselect_all() button = self.win.run() if button == gtk.RESPONSE_OK: res = self.sel_ids_get() or self.ids end = True elif button== gtk.RESPONSE_APPLY: self.find() else: res = None end = True self.destroy() if button == gtk.RESPONSE_ACCEPT: dia = dialog(self.model, window=self.parent, domain=self.screen.domain_init ,context=self.screen.context) id = dia.run() res = id and [id] or None dia.destroy() return res
class action(interface.widget_interface): def __init__(self, window, parent, model, attrs={}): interface.widget_interface.__init__(self, window, parent, model, attrs) self.act_id = int(attrs['name']) res = rpc.session.rpc_exec_auth('/object', 'execute', 'ir.actions.actions', 'read', [self.act_id], ['type'], rpc.session.context) if not res: raise Exception, 'ActionNotFound' type = res[0]['type'] self.action = rpc.session.rpc_exec_auth('/object', 'execute', type, 'read', [self.act_id], False, rpc.session.context)[0] if 'view_mode' in attrs: self.action['view_mode'] = attrs['view_mode'] self.action_view_ids = False if self.action['type'] == 'ir.actions.act_window': if not self.action.get('domain', False): self.action['domain'] = '[]' if attrs.get('domain',False): self.action['domain'] = attrs.get('domain') self.context = {'active_id': False, 'active_ids': []} self.context.update(tools.expr_eval(self.action.get('context', '{}'), self.context.copy())) self.domain = tools.expr_eval(self.action['domain'], self.context.copy()) view_id = [] if self.action['view_id']: view_id = [self.action['view_id'][0]] if self.action.get('views'): self.action_view_ids = map(lambda y:y[0], filter(lambda x:x[1] == 'tree',self.action['views'])) if self.action['view_type']=='form': mode = (self.action['view_mode'] or 'form,tree').split(',') self.screen = Screen(self.action['res_model'], view_type=mode, context=self.context, view_ids = view_id, domain=self.domain) self.ui = openerp_gtk_builder('openerp.ui', ['widget_paned']) self.ui.connect_signals({ 'on_switch_button_press_event': self._sig_switch, 'on_search_button_press_event': self._sig_search, 'on_open_button_press_event': self._sig_open, }) label = self.ui.get_object('widget_paned_lab') label.set_text(attrs.get('string', self.screen.current_view.title)) vbox = self.ui.get_object('widget_paned_vbox') vbox.add(self.screen.widget) self.widget = self.ui.get_object('widget_paned') self.widget.set_size_request(int(attrs.get('width', -1)), int(attrs.get('height', -1))) elif self.action['view_type']=='tree': pass #TODO def _sig_switch(self, *args): self.screen.switch_view() def _sig_search(self, *args): win = win_search(self.action['res_model'], view_ids = self.action_view_ids, domain=self.domain, context=self.context) res = win.go() if res: self.screen.clear() self.screen.load(res) def _sig_open(self, *args): obj = service.LocalService('action.main') obj.execute(self.act_id, datas={}, type=None, context={}) def set_value(self, mode, model_field): self.screen.current_view.set_value() return True def display(self, model, model_field): limit = self.screen.current_view.view_type != 'graph' and self.action.get('limit', 100) or False res_id = rpc.session.rpc_exec_auth('/object', 'execute', self.action['res_model'], 'search', self.domain, 0, limit, False, self.context) self.screen.clear() self.screen.load(res_id) return True
def __init__(self, window, parent, model, attrs={}): interface.widget_interface.__init__(self, window, parent, model, attrs) self.context = {} self._readonly = self.default_readonly self.widget = gtk.VBox(homogeneous=False, spacing=5) hb = gtk.HBox(homogeneous=False, spacing=5) event_box = gtk.EventBox() event_box.set_events(gtk.gdk.BUTTON_PRESS_MASK) hb.pack_start(event_box, expand=True, fill=True) # the context to pass to default_get can be optionally specified in # the context of the one2many field. We also support a legacy # 'default_get' attribute for the same effect (pending removal) default_get_ctx = (attrs.get('default_get') or attrs.get('context')) self.context = tools.expr_eval(attrs.get('context',"{}"), {"__builtins__":None, "parent": parent}) self.screen = Screen(attrs['relation'], view_type=attrs.get('mode','tree,form').split(','), parent=self.parent, views_preload=attrs.get('views', {}), tree_saves=attrs.get('saves', False), create_new=True, context=self.context, row_activate=self._on_activate, default_get=default_get_ctx, window=self._window, readonly=self._readonly, limit=pager.DEFAULT_LIMIT) self.screen.type = 'one2many' self.pager = pager(object=self, relation=attrs['relation'], screen=self.screen) # Button New self.eb_new = self.pager.create_event_box(_('Create a new entry'), self._sig_new, 'gtk-new') hb.pack_start(self.eb_new, expand=False, fill=False) # Button Edit self.eb_open = self.pager.create_event_box(_('Edit this entry'), self._sig_edit, 'gtk-open') hb.pack_start(self.eb_open, expand=False, fill=False) # Button Delete self.eb_del = self.pager.create_event_box(_('Remove this entry'), self._sig_remove, 'gtk-delete') hb.pack_start(self.eb_del, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # Button Previous Page self.eb_prev_page = self.pager.create_event_box(_('Previous Page'), self._sig_prev_page, 'gtk-goto-first') hb.pack_start(self.eb_prev_page, expand=False, fill=False) # Button Previous Record self.eb_pre = self.pager.create_event_box(_('Previous Record'), self._sig_previous, 'gtk-go-back') hb.pack_start(self.eb_pre, expand=False, fill=False) # Record display self.label = gtk.Label('(0,0)') hb.pack_start(self.label, expand=False, fill=False) # Button Next self.eb_next = self.pager.create_event_box(_('Next Record'), self._sig_next, 'gtk-go-forward') hb.pack_start(self.eb_next, expand=False, fill=False) # Button Next Page self.eb_next_page = self.pager.create_event_box(_('Next Page'), self._sig_next_page, 'gtk-goto-last') hb.pack_start(self.eb_next_page, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # Button Switch self.eb_switch = self.pager.create_event_box(_('Switch'), self.switch_view, 'gtk-justify-left') hb.pack_start(self.eb_switch, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # Limit Combo self.cb = self.pager.create_combo_box(_('Choose Limit'), self.limit_changed) hb.pack_start(self.cb, expand=False, fill=False) self.widget.pack_start(hb, expand=False, fill=True) self.screen.signal_connect(self, 'record-message', self._sig_label) menu_title = gtk.Label('<b>'+self.screen.current_view.title.replace('&','&').replace('<','<').replace('>','>')+'</b>') menu_title.set_use_markup(True) menu_title.set_alignment(0, 0) event_box.add(menu_title) event_box.connect('button_press_event',self.load_menu) self.screen.widget.set_property('height-request', 100) self.widget.pack_start(self.screen.widget, expand=True, fill=True) self.screen.widget.connect('key_press_event', self.on_keypress) self.model = None self.model_field = None self.name = attrs['name']
class dialog(object): def __init__(self, model, domain=None, context=None, window=None, target=False): if domain is None: domain = [] if context is None: context = {} if not window: window = service.LocalService('gui.main').window self.dia = gtk.Dialog(_('OpenERP - Link'), window, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT) self.window = window if not target: self.dia.set_property('default-width', 760) self.dia.set_property('default-height', 500) self.dia.set_position(gtk.WIN_POS_CENTER_ON_PARENT) self.dia.set_icon(common.OPENERP_ICON) self.accel_group = gtk.AccelGroup() self.dia.add_accel_group(self.accel_group) self.but_cancel = self.dia.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) self.but_cancel.add_accelerator('clicked', self.accel_group, gtk.keysyms.Escape, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) self.but_ok = self.dia.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) scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scroll.set_placement(gtk.CORNER_TOP_LEFT) scroll.set_shadow_type(gtk.SHADOW_NONE) self.dia.vbox.pack_start(scroll, expand=True, fill=True) vp = gtk.Viewport() vp.set_shadow_type(gtk.SHADOW_NONE) scroll.add(vp) self.screen = Screen(model, view_ids=None, domain=domain, context=context, window=self.dia, view_type=['form']) self.screen.new() vp.add(self.screen.widget) x,y = self.screen.screen_container.size_get() width, height = window.get_size() vp.set_size_request(min(width - 20, x + 20),min(height - 60, y + 25)) self.dia.show_all() self.screen.display() def run(self, datas={}): while True: try: res = self.dia.run() if res == gtk.RESPONSE_OK: if self.screen.current_model.validate() and self.screen.save_current(): return self.screen.current_model.id else: self.screen.display() self.screen.current_view.set_cursor() else: break except Exception: # Passing all exceptions, most preferably the one of sql_constraint pass return False def destroy(self): self.window.present() self.dia.destroy() self.screen.destroy()
def __init__(self, model, res_id=False, domain=None, view_type=None, view_ids=None, window=None, context=None, name=False, help={}, limit=100, auto_refresh=False, auto_search=True, search_view=None): if not view_type: view_type = ['form','tree'] if domain is None: domain = [] if view_ids is None: view_ids = [] if context is None: context = {} fields = {} self.model = model self.window = window self.previous_action = None self.ui = openerp_gtk_builder('openerp.ui', ['win_form_container']) self.widget = self.ui.get_object('win_form_container') self.widget.show_all() self.fields = fields self.domain = domain self.context = context self.page_label = None self.screen = Screen(self.model, view_type=view_type, context=self.context, view_ids=view_ids, domain=domain,help=help, hastoolbar=options.options['form.toolbar'], hassubmenu=options.options['form.submenu'], show_search=True, window=self.window, limit=limit, readonly=bool(auto_refresh), auto_search=auto_search, search_view=search_view) self.screen.signal_connect(self, 'record-message', self._record_message) self.screen.widget.show() oregistry.add_receiver('misc-message', self._misc_message) if not name: self.name = self.screen.current_view.title else: self.name = name vp = gtk.Viewport() vp.set_shadow_type(gtk.SHADOW_NONE) vp.add(self.screen.widget) vp.show() self.sw = gtk.ScrolledWindow() self.sw.set_shadow_type(gtk.SHADOW_NONE) self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.sw.add(vp) self.sw.show() self.has_backup = False self.backup = {} self.widget.pack_start(self.sw) self.handlers = { 'but_new': self.sig_new, 'but_copy': self.sig_copy, 'but_save': self.sig_save, 'but_save_as': self.sig_save_as, 'but_import': self.sig_import, 'but_print_repeat': self.sig_print_repeat, 'but_remove': self.sig_remove, 'but_search': self.sig_search, 'but_previous': self.sig_previous, 'but_next': self.sig_next, 'but_goto_id': self.sig_goto, 'but_log': self.sig_logs, 'but_print': self.sig_print, 'but_reload': self.sig_reload, 'but_print_html': self.sig_print_html, 'but_action': self.sig_action, 'but_switch': self.sig_switch, 'but_attach': self.sig_attach, 'but_close': self.sig_close, } if 'tree' in view_type: self.handlers['radio_tree'] = self.sig_switch_tree if 'form' in view_type: self.handlers['radio_form'] = self.sig_switch_form if 'graph' in view_type: self.handlers['radio_graph'] = self.sig_switch_graph if 'calendar' in view_type: self.handlers['radio_calendar'] = self.sig_switch_calendar if 'diagram' in view_type: self.handlers['radio_diagram'] = self.sig_switch_diagram if res_id: if isinstance(res_id, (int, long,)): res_id = [res_id] self.screen.load(res_id) else: if self.screen.current_view.view_type == 'form': self.sig_new(autosave=False) if self.screen.current_view.view_type in ('tree', 'graph', 'calendar'): self.screen.search_filter() if auto_refresh and int(auto_refresh): gobject.timeout_add(int(auto_refresh) * 1000, self.sig_reload)
def __init__(self, window, parent, model, attrs={}): interface.widget_interface.__init__(self, window, parent, model, attrs) self.context = {} #TODO: # group by context are evaled here as we need the context in screen # while displaying. # We need a better way to eval context that has group_by' # We needed to do this as normal context also get evaled here # and results in a traceback which should not be evaled here. if str(attrs.get('context',"{}")).find('group_by') != -1: self.context = tools.expr_eval(attrs.get('context',"{}")) self._readonly = self.default_readonly self.widget = gtk.VBox(homogeneous=False, spacing=5) hb = gtk.HBox(homogeneous=False, spacing=5) menubar = gtk.MenuBar() if hasattr(menubar, 'set_pack_direction') and \ hasattr(menubar, 'set_child_pack_direction'): menubar.set_pack_direction(gtk.PACK_DIRECTION_LTR) menubar.set_child_pack_direction(gtk.PACK_DIRECTION_LTR) menuitem_title = gtk.ImageMenuItem(stock_id='gtk-preferences') menu_title = gtk.Menu() menuitem_set_to_default = gtk.MenuItem(_('Set to default value'), True) menuitem_set_to_default.connect('activate', lambda *x:self._menu_sig_default_get()) menu_title.add(menuitem_set_to_default) menuitem_set_default = gtk.MenuItem(_('Set Default'), True) menuitem_set_default.connect('activate', lambda *x: self._menu_sig_default_set()) menu_title.add(menuitem_set_default) menuitem_title.set_submenu(menu_title) menubar.add(menuitem_title) hb.pack_start(menubar, expand=True, fill=True) if self.context.get('group_by'): self.context['group_by'] = [self.context['group_by']] # the context to pass to default_get can be optionally specified in # the context of the one2many field. We also support a legacy # 'default_get' attribute for the same effect (pending removal) default_get_ctx = (attrs.get('default_get') or attrs.get('context')) self.screen = Screen(attrs['relation'], view_type=attrs.get('mode','tree,form').split(','), parent=self.parent, views_preload=attrs.get('views', {}), tree_saves=attrs.get('saves', False), create_new=True, context=self.context, row_activate=self._on_activate, default_get=default_get_ctx, window=self._window, readonly=self._readonly, limit=pager.DEFAULT_LIMIT) self.screen.type = 'one2many' self.pager = pager(object=self, relation=attrs['relation'], screen=self.screen) # Button New self.eb_new = self.pager.create_event_box(_('Create a new entry'), self._sig_new, 'gtk-new') hb.pack_start(self.eb_new, expand=False, fill=False) # Button Edit self.eb_open = self.pager.create_event_box(_('Edit this entry'), self._sig_edit, 'gtk-open') hb.pack_start(self.eb_open, expand=False, fill=False) # Button Delete self.eb_del = self.pager.create_event_box(_('Remove this entry'), self._sig_remove, 'gtk-delete') hb.pack_start(self.eb_del, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # Button Previous Page self.eb_prev_page = self.pager.create_event_box(_('Previous Page'), self._sig_prev_page, 'gtk-goto-first') hb.pack_start(self.eb_prev_page, expand=False, fill=False) # Button Previous Record self.eb_pre = self.pager.create_event_box(_('Previous Record'), self._sig_previous, 'gtk-go-back') hb.pack_start(self.eb_pre, expand=False, fill=False) # Record display self.label = gtk.Label('(0,0)') hb.pack_start(self.label, expand=False, fill=False) # Button Next self.eb_next = self.pager.create_event_box(_('Next Record'), self._sig_next, 'gtk-go-forward') hb.pack_start(self.eb_next, expand=False, fill=False) # Button Next Page self.eb_next_page = self.pager.create_event_box(_('Next Page'), self._sig_next_page, 'gtk-goto-last') hb.pack_start(self.eb_next_page, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # Button Switch self.eb_switch = self.pager.create_event_box(_('Switch'), self.switch_view, 'gtk-justify-left') hb.pack_start(self.eb_switch, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # Limit Combo self.cb = self.pager.create_combo_box(_('Choose Limit'), self.limit_changed) hb.pack_start(self.cb, expand=False, fill=False) self.widget.pack_start(hb, expand=False, fill=True) self.screen.signal_connect(self, 'record-message', self._sig_label) menuitem_title.get_child().set_markup('<b>'+self.screen.current_view.title.replace('&','&').replace('<','<').replace('>','>')+'</b>') self.widget.pack_start(self.screen.widget, expand=True, fill=True) self.screen.widget.connect('key_press_event', self.on_keypress) self.model = None self.model_field = None self.name = attrs['name']
class many2many(interface.widget_interface): def __init__(self, window, parent, model, attrs={}): interface.widget_interface.__init__(self, window, parent, model, attrs) self.widget = gtk.VBox(homogeneous=False, spacing=1) hb = gtk.HBox(homogeneous=False, spacing=3) self.wid_text = gtk.Entry() self.wid_text.set_property('width_chars', 13) self.wid_text.connect('activate', self._sig_activate) self.wid_text.connect('populate-popup', self._menu_open) hb.pack_start(self.wid_text, expand=True, fill=True) hb.pack_start(gtk.VSeparator(), padding=2, expand=False, fill=False) self.wid_but_add = gtk.Button(stock='gtk-add') self.wid_but_add.set_relief(gtk.RELIEF_HALF) self.wid_but_add.set_focus_on_click(True) self.wid_but_add.connect('clicked', self._sig_add) hb.pack_start(self.wid_but_add, padding=3, expand=False, fill=False) self.wid_but_remove = gtk.Button(stock='gtk-remove') self.wid_but_remove.set_relief(gtk.RELIEF_HALF) self.wid_but_remove.set_focus_on_click(True) self.wid_but_remove.connect('clicked', self._sig_remove) hb.pack_start(self.wid_but_remove, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) self.context = tools.expr_eval(attrs.get('context',"{}")) self.screen = Screen(attrs['relation'], view_type=['tree'], views_preload=attrs.get('views', {}), row_activate=self.row_activate, limit=pager.DEFAULT_LIMIT, context=self.context) self.screen.signal_connect(self, 'record-message', self._sig_label) self.screen.type = 'many2many' self.model = None self.model_field = None self.name = attrs['name'] self.pager = pager(object=self, relation=attrs['relation'], screen=self.screen) # Button Previous Page self.eb_prev_page = self.pager.create_event_box(_('Previous Page'), self._sig_prev_page, 'gtk-goto-first') hb.pack_start(self.eb_prev_page, expand=False, fill=False) # Button Previous Record self.eb_pre = self.pager.create_event_box(_('Previous Record'), self._sig_previous, 'gtk-go-back') hb.pack_start(self.eb_pre, expand=False, fill=False) # Record display self.label = gtk.Label('(0,0)') hb.pack_start(self.label, expand=False, fill=False) # Button Next self.eb_next = self.pager.create_event_box(_('Next Record'), self._sig_next, 'gtk-go-forward') hb.pack_start(self.eb_next, expand=False, fill=False) # Button Next Page self.eb_next_page = self.pager.create_event_box(_('Next Page'), self._sig_next_page, 'gtk-goto-last') hb.pack_start(self.eb_next_page, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # LIMIT COMBO self.cb = self.pager.create_combo_box(_('Choose Limit'), self.limit_changed) hb.pack_start(self.cb, expand=False, fill=False) self.widget.pack_start(hb, expand=False, fill=False) self.widget.pack_start(gtk.HSeparator(), expand=False, fill=True) scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scroll.set_property('height-request', 200) scroll.set_placement(gtk.CORNER_TOP_LEFT) scroll.set_shadow_type(gtk.SHADOW_NONE) scroll.add_with_viewport(self.screen.widget) self.widget.pack_start(scroll, expand=True, fill=True) def row_activate(self, screen): gui_window = service.LocalService('gui.window') domain = self._view.modelfield.domain_get(self._view.model) dia = dialog(screen.name, id=screen.id_get(), attrs=self.attrs, domain=domain, window=screen.window,context=screen.context,target=False, view_type=['form']) if dia.dia.get_has_separator(): dia.dia.set_has_separator(False) ok, value = dia.run() if ok: screen.current_model.validate_set() screen.current_view.set_value() dia.destroy() def destroy(self): self.screen.destroy() self.widget.destroy() del self.widget del self.screen def _menu_sig_default(self, obj): res = rpc.session.rpc_exec_auth('/object', 'execute', self.attrs['model'], 'default_get', [self.name]) self.value = res.get(self.name, False) def _sig_add(self, *args): domain = self._view.modelfield.domain_get(self._view.model) context = self._view.modelfield.context_get(self._view.model) records = rpc.session.rpc_exec_auth('/object', 'execute', self.attrs['relation'], 'name_search', self.wid_text.get_text(), domain, 'ilike', context) ids = [oid for oid, _ in records] #Updating the context in order to avoid domain of name_search and custom domain of search_context context.update({'name_search':self.wid_text.get_text()}) self.wid_text.set_text('') win = win_search(self.attrs['relation'], sel_multi=True, ids=ids, context=context, domain=domain, parent=self._window) ids = win.go() if ids == None: ids = [] if self.name in self.model.pager_cache: self.model.pager_cache[self.name] = list(set(self.model.pager_cache[self.name] + ids)) else: self.model.pager_cache[self.name] = ids self.model.is_m2m_modified = True self._focus_out() self.pager.reset_pager() self.pager.search_count() def _sig_remove(self, *args): remove_ids = self.screen.current_view.sel_ids_get() if not remove_ids: return for oid in remove_ids: if oid in self.model.pager_cache[self.name]: self.model.pager_cache[self.name].remove(oid) self.model.is_m2m_modified = True self.screen.remove() self.screen.display() self._focus_out() self.pager.reset_pager() self.pager.search_count() def _sig_activate(self, *args): self._sig_add() def _readonly_set(self, ro): self.wid_text.set_editable(not ro) self.wid_text.set_sensitive(not ro) self.wid_but_remove.set_sensitive(not ro) self.wid_but_add.set_sensitive(not ro) def limit_changed(self,*args): self.pager.limit_changed() def _sig_prev_page(self, *args): self.pager.prev_page() def _sig_next_page(self, *args): self.pager.next_page() def _sig_next(self, *args): _, event = args if event.type == gtk.gdk.BUTTON_PRESS: self.pager.next_record() def _sig_previous(self, *args): _, event = args if event.type == gtk.gdk.BUTTON_PRESS: self.pager.prev_record() def _sig_label(self, screen, signal_data): name = '_' if signal_data[0] >= 0: name = str(signal_data[0] + 1) line = '(%s/%s of %s)' % (name, signal_data[1], signal_data[2]) self.label.set_text(line) def display(self, model, model_field): self.model = model self.model_field = model_field super(many2many, self).display(model, model_field) ids = [] if model_field: ids = model_field.get_client(model) self.model.pager_cache.setdefault(model_field.name, model.value[model_field.name] or []) self.pager.search_count() self.screen.clear() self.screen.load(ids) self.screen.display() self.pager.set_sensitivity() return True def set_value(self, model, model_field): self.model.pager_cache.setdefault(model_field.name, model.value[model_field.name] or []) if self.name in model.pager_cache: model_field.set_client(model, model.pager_cache[self.name]) def grab_focus(self): return self.wid_text.grab_focus()
class form(object): def __init__(self, model, res_id=False, domain=None, view_type=None, view_ids=None, window=None, context=None, name=False, limit=80, auto_refresh=False): if not view_type: view_type = ['form','tree'] if domain is None: domain = [] if view_ids is None: view_ids = [] if context is None: context = {} fields = {} self.model = model self.window = window self.previous_action = None self.glade = glade.XML(common.terp_path("openerp.glade"),'win_form_container',gettext.textdomain()) self.widget = self.glade.get_widget('win_form_container') self.widget.show_all() self.fields = fields self.domain = domain self.context = context self.screen = Screen(self.model, view_type=view_type, context=self.context, view_ids=view_ids, domain=domain, hastoolbar=options.options['form.toolbar'], show_search=True, window=self.window, limit=limit, readonly=bool(auto_refresh)) self.screen.signal_connect(self, 'record-message', self._record_message) self.screen.widget.show() oregistry.add_receiver('misc-message', self._misc_message) if not name: self.name = self.screen.current_view.title else: self.name = name vp = gtk.Viewport() vp.set_shadow_type(gtk.SHADOW_NONE) vp.add(self.screen.widget) vp.show() self.sw = gtk.ScrolledWindow() self.sw.set_shadow_type(gtk.SHADOW_NONE) self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.sw.add(vp) self.sw.show() self.has_backup = False self.backup = {} self.widget.pack_start(self.sw) self.handlers = { 'but_new': self.sig_new, 'but_copy': self.sig_copy, 'but_save': self.sig_save, 'but_save_as': self.sig_save_as, 'but_import': self.sig_import, 'but_print_repeat': self.sig_print_repeat, 'but_remove': self.sig_remove, 'but_search': self.sig_search, 'but_previous': self.sig_previous, 'but_next': self.sig_next, 'but_goto_id': self.sig_goto, 'but_log': self.sig_logs, 'but_print': self.sig_print, 'but_reload': self.sig_reload, 'but_print_html': self.sig_print_html, 'but_action': self.sig_action, 'but_switch': self.sig_switch, 'but_attach': self.sig_attach, 'but_close': self.sig_close, } if 'tree' in view_type: self.handlers['radio_tree'] = self.sig_switch_tree if 'form' in view_type: self.handlers['radio_form'] = self.sig_switch_form if 'graph' in view_type: self.handlers['radio_graph'] = self.sig_switch_graph if 'calendar' in view_type: self.handlers['radio_calendar'] = self.sig_switch_calendar if res_id: if isinstance(res_id, (int, long,)): res_id = [res_id] self.screen.load(res_id) else: if self.screen.current_view.view_type == 'form': self.sig_new(autosave=False) if self.screen.current_view.view_type in ('tree', 'graph', 'calendar'): self.screen.search_filter() if auto_refresh and int(auto_refresh): gobject.timeout_add(int(auto_refresh) * 1000, self.sig_reload) def sig_switch_form(self, widget=None): return self.sig_switch(widget, 'form') def sig_switch_tree(self, widget=None): return self.sig_switch(widget, 'tree') def sig_switch_calendar(self, widget=None): return self.sig_switch(widget, 'calendar') def sig_switch_graph(self, widget=None): return self.sig_switch(widget, 'graph') def get_resource(self,widget): all_ids = rpc.session.rpc_exec_auth('/object', 'execute', self.model, 'search', []) get_id = int(widget.get_value()) if get_id in all_ids: current_ids = self.screen.ids_get() if get_id in current_ids: self.screen.display(get_id) else: self.screen.load([get_id]) self.screen.current_view.set_cursor() else: common.message(_('Resource ID does not exist for this object!')) def get_event(self, widget, event, win): if event.keyval in (gtk.keysyms.Return, gtk.keysyms.KP_Enter): win.destroy() self.get_resource(widget) def sig_goto(self, *args): if not self.modified_save(): return glade2 = glade.XML(common.terp_path("openerp.glade"),'dia_goto_id',gettext.textdomain()) widget = glade2.get_widget('goto_spinbutton') win = glade2.get_widget('dia_goto_id') widget.connect('key_press_event',self.get_event,win) win.set_transient_for(self.window) win.show_all() response = win.run() win.destroy() if response == gtk.RESPONSE_OK: self.get_resource(widget) def destroy(self): oregistry.remove_receiver('misc-message', self._misc_message) self.screen.signal_unconnect(self) self.screen.destroy() del self.screen del self.glade del self.widget self.sw.destroy() del self.sw gc.collect() def ids_get(self): return self.screen.ids_get() def id_get(self): return self.screen.id_get() def sig_attach(self, widget=None): id = self.id_get() if id: ctx = self.context.copy() ctx.update(rpc.session.context) action = rpc.session.rpc_exec_auth('/object', 'execute', 'ir.attachment', 'action_get', ctx) action['domain'] = [('res_model', '=', self.model), ('res_id', '=', id)] ctx['default_res_model'] = self.model ctx['default_res_id'] = id obj = service.LocalService('action.main') obj._exec_action(action, {}, ctx) else: self.message_state(_('No record selected ! You can only attach to existing record.'), color='red') return True def sig_switch(self, widget=None, mode=None): if not self.modified_save(): return if mode<>self.screen.current_view.view_type: self.screen.switch_view(mode=mode) self.sig_reload() self.screen.current_view.set_cursor() def sig_logs(self, widget=None): id = self.id_get() if not id: self.message_state(_('You have to select a record !'), color='red') return False res = rpc.session.rpc_exec_auth('/object', 'execute', self.model, 'perm_read', [id]) message = '' for line in res: todo = [ ('id', _('ID')), ('create_uid', _('Creation User')), ('create_date', _('Creation Date')), ('write_uid', _('Latest Modification by')), ('write_date', _('Latest Modification Date')) ] for (key,val) in todo: if line[key] and key in ('create_uid','write_uid','uid'): line[key] = line[key][1] message+=val+': '+str(line[key] or '/')+'\n' common.message(message) return True def sig_remove(self, widget=None): if not self.id_get(): msg = _('Record is not saved ! \n Do You want to Clear Current Record ?') else: if self.screen.current_view.view_type == 'form': msg = _('Are you sure to remove this record ?') else: msg = _('Are you sure to remove those records ?') if common.sur(msg): id = self.screen.remove(unlink=True) if not id: self.message_state(_('Resources cleared.'), color='darkgreen') else: self.message_state(_('Resources successfully removed.'), color='darkgreen') self.sig_reload() def sig_import(self, widget=None): fields = [] while(self.screen.view_to_load): self.screen.load_view_to_load() win = win_import.win_import(self.model, self.screen.fields, fields, parent=self.window,local_context= self.screen.context) res = win.go() def sig_save_as(self, widget=None): fields = [] while(self.screen.view_to_load): self.screen.load_view_to_load() win = win_export.win_export(self.model, self.screen.ids_get(), self.screen.fields, fields, parent=self.window, context=self.context) res = win.go() def sig_new(self, widget=None, autosave=True): if autosave: if not self.modified_save(): return self.screen.new() self.message_state('') def sig_copy(self, *args): if not self.modified_save(): return res_id = self.id_get() ctx = self.context.copy() ctx.update(rpc.session.context) new_id = rpc.session.rpc_exec_auth('/object', 'execute', self.model, 'copy', res_id, {}, ctx) if new_id: self.screen.load([new_id]) self.screen.current_view.set_cursor() self.message_state(_('Working now on the duplicated document !')) self.sig_reload() def _form_save(self, auto_continue=True): pass def sig_save(self, widget=None, sig_new=True, auto_continue=True): id = self.screen.save_current() if id: self.message_state(_('Document Saved.'), color="darkgreen") else: common.warning(_('Invalid form, correct red fields !'),_('Error !')) self.message_state(_('Invalid form, correct red fields !'), color="red") return bool(id) def sig_previous(self, widget=None): if not self.modified_save(): return self.screen.display_prev() self.message_state('') def sig_next(self, widget=None): if not self.modified_save(): return self.screen.display_next() self.message_state('') def sig_reload(self, test_modified=True): if not hasattr(self, 'screen'): return False if test_modified and self.screen.is_modified(): res = common.sur_3b(_('This record has been modified\n' \ 'do you want to save it ?')) if res == 'ok': self.sig_save() elif res == 'ko': pass else: return False if self.screen.current_view.view_type == 'form': self.screen.cancel_current() self.screen.display() else: id = self.screen.id_get() self.screen.search_filter() for model in self.screen.models: if model.id == id: self.screen.current_model = model self.screen.display() break self.message_state('') return True def sig_action(self, keyword='client_action_multi', previous=False, report_type='pdf', adds={}): ids = self.screen.ids_get() if self.screen.current_model: id = self.screen.current_model.id else: id = False if self.screen.current_view.view_type == 'form': id = self.screen.save_current() if not id: return False ids = [id] if self.screen.current_view.view_type == 'tree': sel_ids = self.screen.current_view.sel_ids_get() if sel_ids: ids = sel_ids if len(ids): obj = service.LocalService('action.main') if previous and self.previous_action: obj._exec_action(self.previous_action[1], {'model':self.screen.resource, 'id': id or False, 'ids':ids, 'report_type': report_type}, self.screen.context) else: res = obj.exec_keyword(keyword, {'model':self.screen.resource, 'id': id or False, 'ids':ids, 'report_type': report_type}, adds, self.screen.context) if res: self.previous_action = res self.sig_reload(test_modified=False) else: self.message_state(_('You must select one or several records !'),color='red') def sig_print_repeat(self): self.sig_action('client_print_multi', True) def sig_print_html(self): self.sig_action('client_print_multi', report_type='html') def sig_print(self): self.sig_action('client_print_multi', adds={_('Print Screen').encode('utf8'): {'report_name':'printscreen.list', 'name':_('Print Screen'), 'type':'ir.actions.report.xml'}}) def sig_search(self, widget=None): if not self.modified_save(): return dom = self.domain win = win_search.win_search(self.model, domain=self.domain, context=self.context, parent=self.window) res = win.go() if res: self.screen.clear() self.screen.load(res) def message_state(self, message, context='message', color=None): sb = self.glade.get_widget('stat_state') if color is not None: message = '<span foreground="%s">%s</span>' % (color, message) sb.set_label(message) def _record_message(self, screen, signal_data): if not signal_data[3]: msg = _('No record selected') else: name = '_' if signal_data[0]>=0: name = str(signal_data[0]+1) name2 = _('New document') if signal_data[3]: name2 = _('Editing document (id: ')+str(signal_data[3])+')' # Total Records should never change tot_count = signal_data[2] < signal_data[1] and str(signal_data[1]) or str(signal_data[2]) msg = _('Record: ') + name + ' / ' + str(signal_data[1]) + \ _(' of ') + str(tot_count) + ' - ' + name2 sb = self.glade.get_widget('stat_form') cid = sb.get_context_id('message') sb.push(cid, msg) def _misc_message(self, obj, message, color=None): self.message_state(message, color=color) def modified_save(self, reload=True): if self.screen.is_modified(): value = common.sur_3b(_('This record has been modified\ndo you want to save it ?')) if value == 'ok': return self.sig_save() elif value == 'ko': if reload: self.sig_reload(test_modified=False) return True else: return False return True def sig_close(self, urgent=False): return self.modified_save(reload=False)
class action(interface.widget_interface): def __init__(self, window, parent, model, attrs={}): interface.widget_interface.__init__(self, window, parent, model, attrs) self.act_id = attrs['name'] res = rpc.session.rpc_exec_auth('/object', 'execute', 'ir.actions.actions', 'read', [self.act_id], ['type'], rpc.session.context) if not res: raise Exception, 'ActionNotFound' type = res[0]['type'] self.action = rpc.session.rpc_exec_auth('/object', 'execute', type, 'read', [self.act_id], False, rpc.session.context)[0] if 'view_mode' in attrs: self.action['view_mode'] = attrs['view_mode'] if self.action['type'] == 'ir.actions.act_window': if not self.action.get('domain', False): self.action['domain'] = '[]' self.context = {'active_id': False, 'active_ids': []} self.context.update( eval(self.action.get('context', '{}'), self.context.copy())) a = self.context.copy() a['time'] = time a['datetime'] = datetime self.domain = tools.expr_eval(self.action['domain'], a) view_id = [] if self.action['view_id']: view_id = [self.action['view_id'][0]] if self.action['view_type'] == 'form': mode = (self.action['view_mode'] or 'form,tree').split(',') self.screen = Screen(self.action['res_model'], view_type=mode, context=self.context, view_ids=view_id, domain=self.domain) self.win_gl = glade.XML(common.terp_path("openerp.glade"), 'widget_paned', gettext.textdomain()) self.win_gl.signal_connect('on_switch_button_press_event', self._sig_switch) self.win_gl.signal_connect('on_search_button_press_event', self._sig_search) self.win_gl.signal_connect('on_open_button_press_event', self._sig_open) label = self.win_gl.get_widget('widget_paned_lab') label.set_text( attrs.get('string', self.screen.current_view.title)) vbox = self.win_gl.get_widget('widget_paned_vbox') vbox.add(self.screen.widget) self.widget = self.win_gl.get_widget('widget_paned') self.widget.set_size_request(int(attrs.get('width', -1)), int(attrs.get('height', -1))) elif self.action['view_type'] == 'tree': pass #TODO def _sig_switch(self, *args): self.screen.switch_view() def _sig_search(self, *args): win = win_search(self.action['res_model'], domain=self.domain, context=self.context) res = win.go() if res: self.screen.clear() self.screen.load(res) def _sig_open(self, *args): obj = service.LocalService('action.main') obj.execute(self.act_id, {}) def set_value(self, mode, model_field): self.screen.current_view.set_value() return True def display(self, model, model_field): res_id = rpc.session.rpc_exec_auth('/object', 'execute', self.action['res_model'], 'search', self.domain, 0, self.action.get('limit', 80), False, self.context) self.screen.clear() self.screen.load(res_id) return True
def __init__(self, model, id=None, attrs=None, domain=None, context=None, window=None, view_ids=None, target=False, view_type=['form'], help={}): if attrs is None: attrs = {} if domain is None: domain = [] if context is None: context = {} if not window: window = service.LocalService('gui.main').window self.dia = gtk.Dialog( 'OpenERP', window, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT) self.window = window if not target: self.dia.set_property('default-width', 760) self.dia.set_property('default-height', 500) self.dia.set_position(gtk.WIN_POS_CENTER_ON_PARENT) self.dia.set_icon(common.OPENERP_ICON) self.accel_group = gtk.AccelGroup() self.dia.add_accel_group(self.accel_group) self.but_cancel = self.dia.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) self.but_cancel.add_accelerator('clicked', self.accel_group, gtk.keysyms.Escape, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) self.but_ok = self.dia.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) scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scroll.set_placement(gtk.CORNER_TOP_LEFT) scroll.set_shadow_type(gtk.SHADOW_NONE) self.dia.vbox.pack_start(scroll, expand=True, fill=True) vp = gtk.Viewport() vp.set_shadow_type(gtk.SHADOW_NONE) scroll.add(vp) self.screen = Screen(model, view_ids=view_ids, domain=domain, context=context, window=self.dia, view_type=view_type, help=help) if id: self.screen.load([id]) else: self.screen.new() if ('string' in attrs) and attrs['string']: self.dia.set_title(self.dia.get_title() + ' - ' + attrs['string']) elif self.screen.current_view: self.dia.set_title(self.dia.get_title() + ' - ' + self.screen.current_view.title) vp.add(self.screen.widget) width, height = self.screen.screen_container.size_get() window_width, window_height = window.get_size() dia_width, dia_height = self.dia.get_size() widget_width = min(window_width - 20, max(dia_width, width + 30)) if target: widget_height = min(window_height - 60, height + 10) else: widget_height = min(window_height - 60, height + 20) vp.set_size_request(widget_width, widget_height) self.dia.show_all() self.screen.display()
class one2many_list(interface.widget_interface): def __init__(self, window, parent, model, attrs={}): interface.widget_interface.__init__(self, window, parent, model, attrs) self.context = {} #TODO: # group by context are evaled here as we need the context in screen # while displaying. # We need a better way to eval context that has group_by' # We needed to do this as normal context also get evaled here # and results in a traceback which should not be evaled here. if str(attrs.get('context', "{}")).find('group_by') != -1: self.context = tools.expr_eval(attrs.get('context', "{}")) self._readonly = self.default_readonly self.widget = gtk.VBox(homogeneous=False, spacing=5) hb = gtk.HBox(homogeneous=False, spacing=5) menubar = gtk.MenuBar() if hasattr(menubar, 'set_pack_direction') and \ hasattr(menubar, 'set_child_pack_direction'): menubar.set_pack_direction(gtk.PACK_DIRECTION_LTR) menubar.set_child_pack_direction(gtk.PACK_DIRECTION_LTR) menuitem_title = gtk.ImageMenuItem(stock_id='gtk-preferences') menu_title = gtk.Menu() menuitem_set_to_default = gtk.MenuItem(_('Set to default value'), True) menuitem_set_to_default.connect( 'activate', lambda *x: self._menu_sig_default_get()) menu_title.add(menuitem_set_to_default) menuitem_set_default = gtk.MenuItem(_('Set Default'), True) menuitem_set_default.connect('activate', lambda *x: self._menu_sig_default_set()) menu_title.add(menuitem_set_default) menuitem_title.set_submenu(menu_title) menubar.add(menuitem_title) hb.pack_start(menubar, expand=True, fill=True) if self.context.get('group_by'): self.context['group_by'] = [self.context['group_by']] # the context to pass to default_get can be optionally specified in # the context of the one2many field. We also support a legacy # 'default_get' attribute for the same effect (pending removal) default_get_ctx = (attrs.get('default_get') or attrs.get('context')) self.screen = Screen(attrs['relation'], view_type=attrs.get('mode', 'tree,form').split(','), parent=self.parent, views_preload=attrs.get('views', {}), tree_saves=attrs.get('saves', False), create_new=True, context=self.context, row_activate=self._on_activate, default_get=default_get_ctx, window=self._window, readonly=self._readonly, limit=pager.DEFAULT_LIMIT) self.screen.type = 'one2many' self.pager = pager(object=self, relation=attrs['relation'], screen=self.screen) # Button New self.eb_new = self.pager.create_event_box(_('Create a new entry'), self._sig_new, 'gtk-new') hb.pack_start(self.eb_new, expand=False, fill=False) # Button Edit self.eb_open = self.pager.create_event_box(_('Edit this entry'), self._sig_edit, 'gtk-open') hb.pack_start(self.eb_open, expand=False, fill=False) # Button Delete self.eb_del = self.pager.create_event_box(_('Remove this entry'), self._sig_remove, 'gtk-delete') hb.pack_start(self.eb_del, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # Button Previous Page self.eb_prev_page = self.pager.create_event_box( _('Previous Page'), self._sig_prev_page, 'gtk-goto-first') hb.pack_start(self.eb_prev_page, expand=False, fill=False) # Button Previous Record self.eb_pre = self.pager.create_event_box(_('Previous Record'), self._sig_previous, 'gtk-go-back') hb.pack_start(self.eb_pre, expand=False, fill=False) # Record display self.label = gtk.Label('(0,0)') hb.pack_start(self.label, expand=False, fill=False) # Button Next self.eb_next = self.pager.create_event_box(_('Next Record'), self._sig_next, 'gtk-go-forward') hb.pack_start(self.eb_next, expand=False, fill=False) # Button Next Page self.eb_next_page = self.pager.create_event_box( _('Next Page'), self._sig_next_page, 'gtk-goto-last') hb.pack_start(self.eb_next_page, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # Button Switch self.eb_switch = self.pager.create_event_box(_('Switch'), self.switch_view, 'gtk-justify-left') hb.pack_start(self.eb_switch, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # Limit Combo self.cb = self.pager.create_combo_box(_('Choose Limit'), self.limit_changed) hb.pack_start(self.cb, expand=False, fill=False) self.widget.pack_start(hb, expand=False, fill=True) self.screen.signal_connect(self, 'record-message', self._sig_label) menuitem_title.get_child().set_markup( '<b>' + self.screen.current_view.title.replace('&', '&').replace( '<', '<').replace('>', '>') + '</b>') self.widget.pack_start(self.screen.widget, expand=True, fill=True) self.screen.widget.connect('key_press_event', self.on_keypress) self.model = None self.model_field = None self.name = attrs['name'] def on_keypress(self, widget, event): if (not self._readonly) and ((event.keyval in (gtk.keysyms.N, gtk.keysyms.n) and event.state & gtk.gdk.CONTROL_MASK\ and event.state & gtk.gdk.SHIFT_MASK)): self._sig_new(widget, event) return False if event.keyval in (gtk.keysyms.E, gtk.keysyms.e) and event.state & gtk.gdk.CONTROL_MASK\ and event.state & gtk.gdk.SHIFT_MASK: self._sig_edit(widget, event) return False if event.keyval in (gtk.keysyms.L, gtk.keysyms.l) and event.state & gtk.gdk.CONTROL_MASK\ and event.state & gtk.gdk.SHIFT_MASK: self.switch_view(widget, event) return False def destroy(self): self.screen.destroy() def _on_activate(self, screen, *args): self._sig_edit() def click_and_action(self, type): pos = self.tree_view.pos_get() if pos != None: val = self._value[pos] id = val.get('id', False) obj = service.LocalService('action.main') res = obj.exec_keyword( type, { 'model': self.model, 'id': id or False, 'ids': [id], 'report_type': 'pdf' }) return True else: common.message(_('You have to select a resource !')) return False def switch_view(self, btn, arg): self.screen.make_buttons_readonly(True) self.screen.switch_view() def _readonly_set(self, value): self._readonly = value self.eb_new.set_sensitive(not value) self.eb_del.set_sensitive(not value) self.screen.readonly = value self.screen.display() def set_disable(self, value): self.eb_open.set_sensitive(value) self.eb_switch.set_sensitive(value) if self._readonly: value = not self._readonly self.eb_del.set_sensitive(value) def _sig_new(self, *args): _, event = args ctx = dict(self._view.model.expr_eval(self.screen.default_get), **self.context) ctx.update( self._view.model.expr_eval('dict(%s)' % self.attrs.get('context', '{}'))) if event.type in (gtk.gdk.BUTTON_PRESS, gtk.gdk.KEY_PRESS): if (self.screen.current_view.view_type == 'form') or self.screen.editable_get(): self.screen.new(context=ctx) self.screen.make_buttons_readonly() self._readonly = False self.screen.current_view.widget.set_sensitive(True) self.set_disable(True) else: ok = True dia = dialog(self.attrs['relation'], parent=self._view.model, attrs=self.attrs, model_ctx=self.screen.models._context, window=self._window, readonly=self._readonly, context=ctx) while ok: ok, value, res = dia.run() if ok or res == gtk.RESPONSE_APPLY: self.screen.models.model_add(value) value.signal('record-changed', value.parent) self.screen.display() dia.new() self.set_disable(True) self.pager.reset_pager() dia.destroy() def _sig_edit(self, *args): ctx = dict(self._view.model.expr_eval(self.screen.default_get), **self.context) ctx.update( self._view.model.expr_eval('dict(%s)' % self.attrs.get('context', '{}'))) if self.screen.current_model: ok = True edited_model = self.screen.current_model dia = dialog(self.attrs['relation'], parent=self._view.model, model=self.screen.current_model, attrs=self.attrs, window=self._window, readonly=self._readonly, context=ctx) while ok: ok, value, res = dia.run() if res == gtk.RESPONSE_OK: dia.new() if value and value != edited_model: self.screen.models.model_add(value) value.signal('record-changed', value.parent) self.screen.display() self.pager.reset_pager() edited_model.modified = True dia.destroy() def limit_changed(self, *args): self.pager.limit_changed() def _sig_prev_page(self, *args): self.pager.prev_page() def _sig_next_page(self, *args): self.pager.next_page() def _sig_next(self, *args): _, event = args if event.type == gtk.gdk.BUTTON_PRESS: self.pager.next_record() def _sig_previous(self, *args): _, event = args if event.type == gtk.gdk.BUTTON_PRESS: self.pager.prev_record() def _sig_remove(self, *args): lst, event = args if event.type == gtk.gdk.BUTTON_PRESS: if self.screen.current_view.view_type == 'form': msg = _('Are you sure to remove this record ?') else: msg = _('Are you sure to remove those records ?') if common.sur(msg): model = self.screen.current_model model.signal('record-changed', model.parent) self.screen.remove() self.pager.reset_pager() if not self.screen.models.models: self.screen.current_view.widget.set_sensitive(False) def _sig_label(self, screen, signal_data): name = '_' if signal_data[0] >= 0: name = str(signal_data[0] + 1) line = '(%s/%s of %s)' % (name, signal_data[1], signal_data[2]) self.label.set_text(line) def _sig_refresh(self, *args): pass def _sig_sequence(self, *args): pass def display(self, model, model_field): self.model = model self.model_field = model_field if not model_field: self.screen.current_model = None self.screen.display() return False super(one2many_list, self).display(model, model_field) new_models = model_field.get_client(model) if self.screen.models != new_models: self.screen.models_set(new_models) if (self.screen.current_view.view_type == 'tree') and self.screen.editable_get(): if len(self.screen.models.models): self.screen.current_model = self.screen.models.models[0] else: self.screen.current_model = None if self.screen.current_view.view_type == 'form': self.screen.make_buttons_readonly(self.screen.current_model \ and self.screen.current_model.id and True or False) self.set_disable(self.screen.models.models and True or False) self.pager.search_count() self.pager.set_sensitivity() self.screen.display() return True def set_value(self, model, model_field): self.screen.current_view.set_value() if self.screen.is_modified(): model.modified = True model.modified_fields.setdefault(model_field.name) return True def grab_focus(self): return self.screen.widget.grab_focus()
def __init__(self, window, parent, model, attrs={}, label=None): interface.widget_interface.__init__(self, window, parent, model, attrs, label_ebox=label) self.context = {} self._readonly = self.default_readonly self.widget = gtk.VBox(homogeneous=False, spacing=5) hb = gtk.HBox(homogeneous=False, spacing=5) event_box = gtk.EventBox() event_box.set_events(gtk.gdk.BUTTON_PRESS_MASK) hb.pack_start(event_box, expand=True, fill=True) # the context to pass to default_get can be optionally specified in # the context of the one2many field. We also support a legacy # 'default_get' attribute for the same effect (pending removal) default_get_ctx = (attrs.get('default_get') or attrs.get('context')) self.context = tools.expr_eval(attrs.get('context',"{}"), {"__builtins__":None}) self.screen = Screen(attrs['relation'], view_type=attrs.get('mode','tree,form').split(','), parent=self.parent, views_preload=attrs.get('views', {}), tree_saves=attrs.get('saves', False), create_new=True, row_activate=self._on_activate, default_get=default_get_ctx, context = self.context, window=self._window, readonly=self._readonly, limit=pager.DEFAULT_LIMIT) self.screen.type = 'one2many' self.pager = pager(object=self, relation=attrs['relation'], screen=self.screen) # Button New self.eb_new = self.pager.create_event_box(_('Create a new entry'), self._sig_new, 'gtk-new') hb.pack_start(self.eb_new, expand=False, fill=False) # Button Edit self.eb_open = self.pager.create_event_box(_('Edit this entry'), self._sig_edit, 'gtk-open') hb.pack_start(self.eb_open, expand=False, fill=False) # Button Delete self.eb_del = self.pager.create_event_box(_('Remove this entry'), self._sig_remove, 'gtk-delete') hb.pack_start(self.eb_del, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # Button Previous Page self.eb_prev_page = self.pager.create_event_box(_('Previous Page'), self._sig_prev_page, 'gtk-goto-first') hb.pack_start(self.eb_prev_page, expand=False, fill=False) # Button Previous Record self.eb_pre = self.pager.create_event_box(_('Previous Record'), self._sig_previous, 'gtk-go-back') hb.pack_start(self.eb_pre, expand=False, fill=False) # Record display self.label = gtk.Label('(0,0)') hb.pack_start(self.label, expand=False, fill=False) # Button Next self.eb_next = self.pager.create_event_box(_('Next Record'), self._sig_next, 'gtk-go-forward') hb.pack_start(self.eb_next, expand=False, fill=False) # Button Next Page self.eb_next_page = self.pager.create_event_box(_('Next Page'), self._sig_next_page, 'gtk-goto-last') hb.pack_start(self.eb_next_page, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # Button Switch self.eb_switch = self.pager.create_event_box(_('Switch'), self.switch_view, 'gtk-justify-left') hb.pack_start(self.eb_switch, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # Limit Combo self.cb = self.pager.create_combo_box(_('Choose Limit'), self.limit_changed) hb.pack_start(self.cb, expand=False, fill=False) self.widget.pack_start(hb, expand=False, fill=True) self.screen.signal_connect(self, 'record-message', self._sig_label) menu_title = gtk.Label('<b>'+self.screen.current_view.title.replace('&','&').replace('<','<').replace('>','>')+'</b>') menu_title.set_use_markup(True) menu_title.set_alignment(0, 0) event_box.add(menu_title) event_box.connect('button_press_event',self.load_menu) self.screen.widget.set_property('height-request', 100) self.widget.pack_start(self.screen.widget, expand=True, fill=True) self.screen.widget.connect('key_press_event', self.on_keypress) self.model = None self.model_field = None self.name = attrs['name']
class form(object): def __init__(self, model, res_id=False, domain=None, view_type=None, view_ids=None, window=None, context=None, name=False, help={}, limit=100, auto_refresh=False, auto_search=True, search_view=None): if not view_type: view_type = ['form','tree'] if domain is None: domain = [] if view_ids is None: view_ids = [] if context is None: context = {} fields = {} self.model = model self.window = window self.previous_action = None self.ui = openerp_gtk_builder('openerp.ui', ['win_form_container']) self.widget = self.ui.get_object('win_form_container') self.widget.show_all() self.fields = fields self.domain = domain self.context = context self.page_label = None self.screen = Screen(self.model, view_type=view_type, context=self.context, view_ids=view_ids, domain=domain,help=help, hastoolbar=options.options['form.toolbar'], hassubmenu=options.options['form.submenu'], show_search=True, window=self.window, limit=limit, readonly=bool(auto_refresh), auto_search=auto_search, search_view=search_view) self.screen.signal_connect(self, 'record-message', self._record_message) self.screen.widget.show() oregistry.add_receiver('misc-message', self._misc_message) if not name: self.name = self.screen.current_view.title else: self.name = name vp = gtk.Viewport() vp.set_shadow_type(gtk.SHADOW_NONE) vp.add(self.screen.widget) vp.show() self.sw = gtk.ScrolledWindow() self.sw.set_shadow_type(gtk.SHADOW_NONE) self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.sw.add(vp) self.sw.show() self.has_backup = False self.backup = {} self.widget.pack_start(self.sw) self.handlers = { 'but_new': self.sig_new, 'but_copy': self.sig_copy, 'but_save': self.sig_save, 'but_save_as': self.sig_save_as, 'but_import': self.sig_import, 'but_print_repeat': self.sig_print_repeat, 'but_remove': self.sig_remove, 'but_search': self.sig_search, 'but_previous': self.sig_previous, 'but_next': self.sig_next, 'but_goto_id': self.sig_goto, 'but_log': self.sig_logs, 'but_print': self.sig_print, 'but_reload': self.sig_reload, 'but_print_html': self.sig_print_html, 'but_action': self.sig_action, 'but_switch': self.sig_switch, 'but_attach': self.sig_attach, 'but_close': self.sig_close, } if 'tree' in view_type: self.handlers['radio_tree'] = self.sig_switch_tree if 'form' in view_type: self.handlers['radio_form'] = self.sig_switch_form if 'graph' in view_type: self.handlers['radio_graph'] = self.sig_switch_graph if 'calendar' in view_type: self.handlers['radio_calendar'] = self.sig_switch_calendar if 'diagram' in view_type: self.handlers['radio_diagram'] = self.sig_switch_diagram if res_id: if isinstance(res_id, (int, long,)): res_id = [res_id] self.screen.load(res_id) else: if self.screen.current_view.view_type == 'form': self.sig_new(autosave=False) if self.screen.current_view.view_type in ('tree', 'graph', 'calendar'): self.screen.search_filter() if auto_refresh and int(auto_refresh): gobject.timeout_add(int(auto_refresh) * 1000, self.sig_reload) def set_tooltips(fn): def _decorate(self, *args, **kws): result = fn(self, *args, **kws) if self.screen.current_view.view_type == 'form': tips= unicode(self.screen.current_model and self.screen.current_model.value.get('name') or self.name) tooltips = tips == self.name and self.name or self.name + ': ' + tips[:64] lable = tips == self.name and self.name or self.name + ': ' + tips[:6] self.page_label.set_text(lable) self.page_label.set_tooltip_text(tooltips) else: self.page_label.set_text(self.name) self.page_label.set_tooltip_text(self.name) return result return _decorate def sig_switch_diagram(self, widget=None): return self.sig_switch(widget, 'diagram') def sig_switch_form(self, widget=None): return self.sig_switch(widget, 'form') def sig_switch_tree(self, widget=None): return self.sig_switch(widget, 'tree') def sig_switch_calendar(self, widget=None): return self.sig_switch(widget, 'calendar') def sig_switch_graph(self, widget=None): return self.sig_switch(widget, 'graph') def get_resource(self, widget=None, get_id=None): ## This has been done due to virtual ids coming from ## crm meeting. like '3-20101012155505' which are not in existence ## and needed to be converted to real ids if isinstance(get_id, str): get_id = int(get_id.split('-')[0]) all_ids = rpc.session.rpc_exec_auth('/object', 'execute', self.model, 'search', []) if widget: get_id = int(widget.get_value()) if get_id in all_ids: current_ids = self.screen.ids_get() if get_id in current_ids: self.screen.display(get_id) else: self.screen.load([get_id]) self.screen.current_view.set_cursor() else: if widget: common.message(_('Resource ID does not exist for this object!')) def get_event(self, widget, event, win): if event.keyval in (gtk.keysyms.Return, gtk.keysyms.KP_Enter): win.destroy() self.get_resource(widget) @set_tooltips def sig_goto(self, *args): if not self.modified_save(): return goto_ui = openerp_gtk_builder('openerp.ui', ['dia_goto_id', 'adjustment2']) widget = goto_ui.get_object('goto_spinbutton') win = goto_ui.get_object('dia_goto_id') widget.connect('key_press_event',self.get_event,win) win.set_transient_for(self.window) win.show_all() response = win.run() win.destroy() if response == gtk.RESPONSE_OK: self.get_resource(widget) def destroy(self): """ Destroy the page object and all the child (or at least should do this) """ oregistry.remove_receiver('misc-message', self._misc_message) self.screen.signal_unconnect(self) self.screen.destroy() self.widget.destroy() self.sw.destroy() del self.screen del self.handlers def ids_get(self): return self.screen.ids_get() def id_get(self): return self.screen.id_get() def sig_attach(self, widget=None): id = self.id_get() if id: ctx = self.context.copy() ctx.update(rpc.session.context) action = rpc.session.rpc_exec_auth('/object', 'execute', 'ir.attachment', 'action_get', ctx) action['domain'] = [('res_model', '=', self.model), ('res_id', '=', id)] ctx['default_res_model'] = self.model ctx['default_res_id'] = id obj = service.LocalService('action.main') obj._exec_action(action, {}, ctx) else: self.message_state(_('No record selected ! You can only attach to existing record.'), color='red') return True @set_tooltips def sig_switch(self, widget=None, mode=None): if not self.modified_save(): return id = self.screen.id_get() if mode<>self.screen.current_view.view_type: self.screen.switch_view(mode=mode) if id: self.sig_reload() self.get_resource(get_id=id) def sig_logs(self, widget=None): id = self.id_get() if not id: self.message_state(_('You have to select a record !'), color='red') return False res = rpc.session.rpc_exec_auth('/object', 'execute', self.model, 'perm_read', [id]) message = '' for line in res: todo = [ ('id', _('ID')), ('create_uid', _('Creation User')), ('create_date', _('Creation Date')), ('write_uid', _('Latest Modification by')), ('write_date', _('Latest Modification Date')), ('xmlid', _('Internal Module Data ID')) ] for (key,val) in todo: if line[key] and key in ('create_uid','write_uid','uid'): line[key] = line[key][1] message+=val+': '+str(line[key] or '/')+'\n' common.message(message) return True @set_tooltips def sig_remove(self, widget=None): if not self.id_get(): msg = _('Record is not saved ! \n Do you want to clear current record ?') else: if self.screen.current_view.view_type == 'form': msg = _('Are you sure to remove this record ?') else: msg = _('Are you sure to remove those records ?') if common.sur(msg): id = self.screen.remove(unlink=True) if not id: self.message_state(_('Resources cleared.'), color='darkgreen') else: self.message_state(_('Resources successfully removed.'), color='darkgreen') self.sig_reload() def sig_import(self, widget=None): fields = [] while(self.screen.view_to_load): self.screen.load_view_to_load(mode = self.screen.view_to_load[0]) screen_fields = copy.deepcopy(self.screen.models.fields) win = win_import.win_import(self.model, screen_fields, fields, parent=self.window,local_context= self.screen.context) res = win.go() def sig_save_as(self, widget=None): fields = [] while(self.screen.view_to_load): self.screen.load_view_to_load(mode = self.screen.view_to_load[0]) screen_fields = copy.deepcopy(self.screen.models.fields) win = win_export.win_export(self.model, self.screen.ids_get(), screen_fields, fields, parent=self.window, context=self.context) res = win.go() def sig_new(self, widget=None, autosave=True): if autosave: if not self.modified_save(): return if self.screen.current_view.view_type in ['calendar','graph']: return self.screen.new() self.message_state('') self.page_label and self.page_label.set_text(self.name) self.page_label and self.page_label.set_tooltip_text(self.name) def sig_copy(self, *args): if not self.modified_save(): return res_id = self.id_get() ctx = self.context.copy() ctx.update(rpc.session.context) new_id = rpc.session.rpc_exec_auth('/object', 'execute', self.model, 'copy', res_id, {}, ctx) if new_id: self.screen.load([new_id]) self.screen.current_view.set_cursor() self.message_state(_('Working now on the duplicated document !')) self.sig_reload() def _form_save(self, auto_continue=True): pass @set_tooltips def sig_save(self, widget=None, sig_new=True, auto_continue=True): res = self.screen.save_current() warning = False if isinstance(res,dict): id = res.get('id',False) warning = res.get('warning',False) else: id = res if id: self.message_state(_('Document Saved.'), color="darkgreen") elif len(self.screen.models.models) and res != None and self.screen.models.mfields: fields = common.get_invalid_field(self.screen.current_model, self.screen) msg = '' for req, inv in fields: if not inv: msg += req + ' (<b>invisible</b>) ' else: msg += req msg += '\n' common.warning(_('Correct following red fields !\n\n%s') % ( msg ),_('Input Error !'), parent=self.screen.current_view.window, to_xml=False) self.message_state(_('Invalid form, correct red fields !'), color="red") if warning: common.warning(warning,_('Warning !'), parent=self.screen.current_view.window) return bool(id) @set_tooltips def sig_previous(self, widget=None): if not self.modified_save(): return self.screen.display_prev() self.message_state('') @set_tooltips def sig_next(self, widget=None): if not self.modified_save(): return self.screen.display_next() self.message_state('') def sig_reload(self, test_modified=True): if not hasattr(self, 'screen'): return False if test_modified and self.screen.is_modified(): res = common.sur_3b(_('This record has been modified\n' \ 'do you want to save it ?')) if res == 'ok': self.sig_save() elif res == 'ko': pass else: return False if self.screen.current_view.view_type == 'form': self.screen.cancel_current() self.screen.display() else: id = self.screen.id_get() self.screen.search_filter() for model in self.screen.models: if model.id == id: self.screen.current_model = model self.screen.display() break self.message_state('') return True def sig_action(self, keyword='client_action_multi', previous=False, report_type='pdf', adds={}): ids = self.screen.ids_get() group_by = self.screen.context.get('group_by') if self.screen.current_model: id = self.screen.current_model.id else: id = False if self.screen.current_view.view_type == 'form': id = self.screen.save_current() if not id: return False ids = [id] if self.screen.current_view.view_type == 'tree': self.modified_save() sel_ids = self.screen.sel_ids_get() if sel_ids: ids = sel_ids if len(ids) or group_by: obj = service.LocalService('action.main') data = {'model':self.screen.resource, 'id': id or False, 'ids':ids, 'report_type': report_type, '_domain':self.screen.domain } # When group by header is selected add it's children as a active_ids if group_by: self.screen.context.update({'active_id':id, 'active_ids':ids}) if previous and self.previous_action: obj._exec_action(self.previous_action[1], data, self.screen.context) else: res = obj.exec_keyword(keyword, data, adds, self.screen.context) if res: self.previous_action = res self.sig_reload(test_modified=False) else: self.message_state(_('You must select one or several records !'),color='red') def sig_print_repeat(self): self.sig_action('client_print_multi', True) def sig_print_html(self): self.sig_action('client_print_multi', report_type='html') def sig_print(self): self.sig_action('client_print_multi', adds={_('Print Screen').encode('utf8'): {'report_name':'printscreen.list', 'name':_('Print Screen'), 'type':'ir.actions.report.xml'}}) def sig_search(self, widget=None): if not self.modified_save(): return dom = self.domain win = win_search.win_search(self.model, domain=self.domain, context=self.context, parent=self.window) res = win.go() if res: self.screen.clear() self.screen.load(res) def message_state(self, message, context='message', color=None): sb = self.ui.get_object('stat_state') if color is not None: message = '<span foreground="%s">%s</span>' % (color, message) sb.set_label(message) def _record_message(self, screen, signal_data): if not signal_data[3]: msg = _('No record selected') else: name = '_' if signal_data[0]>=0: name = str(signal_data[0]+1) name2 = _('New document') if signal_data[3]: name2 = _('Editing document (id: ')+str(signal_data[3])+')' # Total Records should never change tot_count = signal_data[2] < signal_data[1] and str(signal_data[1]) or str(signal_data[2]) msg = _('Record: ') + name + ' / ' + str(signal_data[1]) + \ _(' of ') + str(tot_count) + ' - ' + name2 sb = self.ui.get_object('stat_form') cid = sb.get_context_id('message') sb.push(cid, msg) def _misc_message(self, obj, message, color=None): self.message_state(message, color=color) def modified_save(self, reload=True): if self.screen.is_modified(): value = common.sur_3b(_('This record has been modified\ndo you want to save it ?')) if value == 'ok': return self.sig_save() elif value == 'ko': if reload: self.sig_reload(test_modified=False) return True else: return False return True def sig_close(self, urgent=False): res = self.modified_save(reload=False) return res
class many2many(interface.widget_interface): def __init__(self, window, parent, model, attrs={}): interface.widget_interface.__init__(self, window, parent, model, attrs) self.widget = gtk.VBox(homogeneous=False, spacing=1) hb = gtk.HBox(homogeneous=False, spacing=3) self.wid_text = gtk.Entry() self.wid_text.set_property('width_chars', 13) self.wid_text.connect('activate', self._sig_activate) self.wid_text.connect('button_press_event', self._menu_open) hb.pack_start(self.wid_text, expand=True, fill=True) hb.pack_start(gtk.VSeparator(), padding=2, expand=False, fill=False) self.wid_but_add = gtk.Button(stock='gtk-add') self.wid_but_add.set_relief(gtk.RELIEF_HALF) self.wid_but_add.set_focus_on_click(True) self.wid_but_add.connect('clicked', self._sig_add) hb.pack_start(self.wid_but_add, padding=3, expand=False, fill=False) self.wid_but_remove = gtk.Button(stock='gtk-remove') self.wid_but_remove.set_relief(gtk.RELIEF_HALF) self.wid_but_remove.set_focus_on_click(True) self.wid_but_remove.connect('clicked', self._sig_remove) hb.pack_start(self.wid_but_remove, expand=False, fill=False) self.widget.pack_start(hb, expand=False, fill=False) self.widget.pack_start(gtk.HSeparator(), expand=False, fill=True) scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scroll.set_placement(gtk.CORNER_TOP_LEFT) scroll.set_shadow_type(gtk.SHADOW_NONE) self.screen = Screen(attrs['relation'], view_type=['tree'], views_preload=attrs.get('views', {})) scroll.add_with_viewport(self.screen.widget) self.widget.pack_start(scroll, expand=True, fill=True) # self.old = None self.avail_ids = set() def check_exist(self): if not len(self.screen.models.models): self.avail_ids.clear() else: for i in self.screen.models.models: self.avail_ids.add(i.id) def destroy(self): self.screen.destroy() self.widget.destroy() del self.widget def _menu_sig_default(self, obj): res = rpc.session.rpc_exec_auth('/object', 'execute', self.attrs['model'], 'default_get', [self.attrs['name']]) self.value = res.get(self.attrs['name'], False) def _sig_add(self, *args): flag=False newids=[] domain = self._view.modelfield.domain_get(self._view.model) context = self._view.modelfield.context_get(self._view.model) ids = rpc.session.rpc_exec_auth('/object', 'execute', self.attrs['relation'], 'name_search', self.wid_text.get_text(), domain, 'ilike', context) ids = map(lambda x: x[0], ids) self.check_exist() # if len(ids)<>1: win = win_search(self.attrs['relation'], sel_multi=True, ids=ids, context=context, domain=domain, parent=self._window) ids = win.go() if ids == None: ids=[] if len(self.avail_ids) and len(ids): for i in ids: if i not in self.avail_ids: newids.append(i) flag=True if flag==True: ids=newids else: ids=[] self.screen.load(ids) for i in ids: self.avail_ids.add(i) self.screen.display() self.wid_text.set_text('') self._focus_out() def _sig_remove(self, *args): rem_id=[] self.check_exist() rem_id=self.screen.current_view.sel_ids_get() for i in rem_id: self.avail_ids.remove(i) self.screen.remove() self.screen.display() self._focus_out() def _sig_activate(self, *args): self._sig_add() def _readonly_set(self, ro): self.wid_text.set_editable(not ro) self.wid_text.set_sensitive(not ro) self.wid_but_remove.set_sensitive(not ro) self.wid_but_add.set_sensitive(not ro) def display(self, model, model_field): super(many2many, self).display(model, model_field) ids = [] if model_field: ids = model_field.get_client(model) # if ids<>self.old: self.screen.clear() self.screen.load(ids) # self.old = ids self.avail_ids.clear() self.screen.display() return True def set_value(self, model, model_field): model_field.set_client(model, [x.id for x in self.screen.models.models])
class many2many(interface.widget_interface): def __init__(self, window, parent, model, attrs={}): interface.widget_interface.__init__(self, window, parent, model, attrs) self.widget = gtk.VBox(homogeneous=False, spacing=1) hb = gtk.HBox(homogeneous=False, spacing=3) self.wid_text = gtk.Entry() self.wid_text.set_property('width_chars', 13) self.wid_text.connect('activate', self._sig_activate) self.wid_text.connect('button_press_event', self._menu_open) hb.pack_start(self.wid_text, expand=True, fill=True) hb.pack_start(gtk.VSeparator(), padding=2, expand=False, fill=False) self.wid_but_add = gtk.Button(stock='gtk-add') self.wid_but_add.set_relief(gtk.RELIEF_HALF) self.wid_but_add.set_focus_on_click(True) self.wid_but_add.connect('clicked', self._sig_add) hb.pack_start(self.wid_but_add, padding=3, expand=False, fill=False) self.wid_but_remove = gtk.Button(stock='gtk-remove') self.wid_but_remove.set_relief(gtk.RELIEF_HALF) self.wid_but_remove.set_focus_on_click(True) self.wid_but_remove.connect('clicked', self._sig_remove) hb.pack_start(self.wid_but_remove, expand=False, fill=False) self.widget.pack_start(hb, expand=False, fill=False) self.widget.pack_start(gtk.HSeparator(), expand=False, fill=True) scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scroll.set_placement(gtk.CORNER_TOP_LEFT) scroll.set_shadow_type(gtk.SHADOW_NONE) self.screen = Screen(attrs['relation'], view_type=['tree'], views_preload=attrs.get('views', {})) scroll.add_with_viewport(self.screen.widget) self.widget.pack_start(scroll, expand=True, fill=True) # self.old = None self.avail_ids = set() def check_exist(self): if not len(self.screen.models.models): self.avail_ids.clear() else: for i in self.screen.models.models: self.avail_ids.add(i.id) def destroy(self): self.screen.destroy() self.widget.destroy() del self.widget def _menu_sig_default(self, obj): res = rpc.session.rpc_exec_auth('/object', 'execute', self.attrs['model'], 'default_get', [self.attrs['name']]) self.value = res.get(self.attrs['name'], False) def _sig_add(self, *args): flag = False newids = [] domain = self._view.modelfield.domain_get(self._view.model) context = self._view.modelfield.context_get(self._view.model) ids = rpc.session.rpc_exec_auth('/object', 'execute', self.attrs['relation'], 'name_search', self.wid_text.get_text(), domain, 'ilike', context) ids = map(lambda x: x[0], ids) self.check_exist() # if len(ids)<>1: win = win_search(self.attrs['relation'], sel_multi=True, ids=ids, context=context, domain=domain, parent=self._window) ids = win.go() if ids == None: ids = [] if len(self.avail_ids) and len(ids): for i in ids: if i not in self.avail_ids: newids.append(i) flag = True if flag == True: ids = newids else: ids = [] self.screen.load(ids) for i in ids: self.avail_ids.add(i) self.screen.display() self.wid_text.set_text('') self._focus_out() def _sig_remove(self, *args): rem_id = [] self.check_exist() rem_id = self.screen.current_view.sel_ids_get() for i in rem_id: self.avail_ids.remove(i) self.screen.remove() self.screen.display() self._focus_out() def _sig_activate(self, *args): self._sig_add() def _readonly_set(self, ro): self.wid_text.set_editable(not ro) self.wid_text.set_sensitive(not ro) self.wid_but_remove.set_sensitive(not ro) self.wid_but_add.set_sensitive(not ro) def display(self, model, model_field): super(many2many, self).display(model, model_field) ids = [] if model_field: ids = model_field.get_client(model) # if ids<>self.old: self.screen.clear() self.screen.load(ids) # self.old = ids self.avail_ids.clear() self.screen.display() return True def set_value(self, model, model_field): model_field.set_client(model, [x.id for x in self.screen.models.models])
def __init__(self, model, domain=None, context=None, window=None, target=False): if domain is None: domain = [] if context is None: context = {} if not window: window = service.LocalService('gui.main').window self.dia = gtk.Dialog( _('OpenERP - Link'), window, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT) self.window = window if not target: self.dia.set_property('default-width', 760) self.dia.set_property('default-height', 500) self.dia.set_position(gtk.WIN_POS_CENTER_ON_PARENT) self.dia.set_icon(common.OPENERP_ICON) self.accel_group = gtk.AccelGroup() self.dia.add_accel_group(self.accel_group) self.but_cancel = self.dia.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) self.but_cancel.add_accelerator('clicked', self.accel_group, gtk.keysyms.Escape, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) self.but_ok = self.dia.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) scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scroll.set_placement(gtk.CORNER_TOP_LEFT) scroll.set_shadow_type(gtk.SHADOW_NONE) self.dia.vbox.pack_start(scroll, expand=True, fill=True) vp = gtk.Viewport() vp.set_shadow_type(gtk.SHADOW_NONE) scroll.add(vp) self.screen = Screen(model, view_ids=None, domain=domain, context=context, window=self.dia, view_type=['form']) self.screen.new() vp.add(self.screen.widget) x, y = self.screen.screen_container.size_get() width, height = window.get_size() vp.set_size_request(min(width - 20, x + 20), min(height - 60, y + 25)) self.dia.show_all() self.screen.display()
class one2many_list(interface.widget_interface): def __init__(self, window, parent, model, attrs={}): interface.widget_interface.__init__(self, window, parent, model, attrs) self.context = {} self._readonly = self.default_readonly self.widget = gtk.VBox(homogeneous=False, spacing=5) hb = gtk.HBox(homogeneous=False, spacing=5) event_box = gtk.EventBox() event_box.set_events(gtk.gdk.BUTTON_PRESS_MASK) hb.pack_start(event_box, expand=True, fill=True) # the context to pass to default_get can be optionally specified in # the context of the one2many field. We also support a legacy # 'default_get' attribute for the same effect (pending removal) default_get_ctx = (attrs.get('default_get') or attrs.get('context')) self.context = tools.expr_eval(attrs.get('context',"{}"), {"__builtins__":None, "parent": parent}) self.screen = Screen(attrs['relation'], view_type=attrs.get('mode','tree,form').split(','), parent=self.parent, views_preload=attrs.get('views', {}), tree_saves=attrs.get('saves', False), create_new=True, context=self.context, row_activate=self._on_activate, default_get=default_get_ctx, window=self._window, readonly=self._readonly, limit=pager.DEFAULT_LIMIT) self.screen.type = 'one2many' self.pager = pager(object=self, relation=attrs['relation'], screen=self.screen) # Button New self.eb_new = self.pager.create_event_box(_('Create a new entry'), self._sig_new, 'gtk-new') hb.pack_start(self.eb_new, expand=False, fill=False) # Button Edit self.eb_open = self.pager.create_event_box(_('Edit this entry'), self._sig_edit, 'gtk-open') hb.pack_start(self.eb_open, expand=False, fill=False) # Button Delete self.eb_del = self.pager.create_event_box(_('Remove this entry'), self._sig_remove, 'gtk-delete') hb.pack_start(self.eb_del, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # Button Previous Page self.eb_prev_page = self.pager.create_event_box(_('Previous Page'), self._sig_prev_page, 'gtk-goto-first') hb.pack_start(self.eb_prev_page, expand=False, fill=False) # Button Previous Record self.eb_pre = self.pager.create_event_box(_('Previous Record'), self._sig_previous, 'gtk-go-back') hb.pack_start(self.eb_pre, expand=False, fill=False) # Record display self.label = gtk.Label('(0,0)') hb.pack_start(self.label, expand=False, fill=False) # Button Next self.eb_next = self.pager.create_event_box(_('Next Record'), self._sig_next, 'gtk-go-forward') hb.pack_start(self.eb_next, expand=False, fill=False) # Button Next Page self.eb_next_page = self.pager.create_event_box(_('Next Page'), self._sig_next_page, 'gtk-goto-last') hb.pack_start(self.eb_next_page, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # Button Switch self.eb_switch = self.pager.create_event_box(_('Switch'), self.switch_view, 'gtk-justify-left') hb.pack_start(self.eb_switch, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # Limit Combo self.cb = self.pager.create_combo_box(_('Choose Limit'), self.limit_changed) hb.pack_start(self.cb, expand=False, fill=False) self.widget.pack_start(hb, expand=False, fill=True) self.screen.signal_connect(self, 'record-message', self._sig_label) menu_title = gtk.Label('<b>'+self.screen.current_view.title.replace('&','&').replace('<','<').replace('>','>')+'</b>') menu_title.set_use_markup(True) menu_title.set_alignment(0, 0) event_box.add(menu_title) event_box.connect('button_press_event',self.load_menu) self.screen.widget.set_property('height-request', 100) self.widget.pack_start(self.screen.widget, expand=True, fill=True) self.screen.widget.connect('key_press_event', self.on_keypress) self.model = None self.model_field = None self.name = attrs['name'] def load_menu(self, widget, event): if event.button != 3: return menu = gtk.Menu() menuitem_set_to_default = gtk.MenuItem(_('Set to default value'), True) menuitem_set_to_default.connect('activate', lambda *x:self._menu_sig_default_get()) menu.add(menuitem_set_to_default) menuitem_set_default = gtk.MenuItem(_('Set Default'), True) menuitem_set_default.connect('activate', lambda *x: self._menu_sig_default_set()) menu.add(menuitem_set_default) menu.show_all() menu.popup(None,None,None,event.button,event.time) return True def on_keypress(self, widget, event): if (not self._readonly) and ((event.keyval in (gtk.keysyms.N, gtk.keysyms.n) and event.state & gtk.gdk.CONTROL_MASK\ and event.state & gtk.gdk.SHIFT_MASK)): self._sig_new(widget, event) return False if event.keyval in (gtk.keysyms.E, gtk.keysyms.e) and event.state & gtk.gdk.CONTROL_MASK\ and event.state & gtk.gdk.SHIFT_MASK: self._sig_edit(widget, event) return False if event.keyval in (gtk.keysyms.L, gtk.keysyms.l) and event.state & gtk.gdk.CONTROL_MASK\ and event.state & gtk.gdk.SHIFT_MASK: self.switch_view(widget, event) return False def destroy(self): self.screen.destroy() def _on_activate(self, screen, *args): self._sig_edit() def click_and_action(self, type): pos = self.tree_view.pos_get() if pos!=None: val = self._value[pos] id = val.get('id', False) obj = service.LocalService('action.main') res = obj.exec_keyword(type, {'model':self.model, 'id': id or False, 'ids':[id], 'report_type': 'pdf'}) return True else: common.message(_('You have to select a resource !')) return False def switch_view(self, btn, arg): self.screen.make_buttons_readonly(True) self.screen.switch_view() def _readonly_set(self, value): self._readonly = value self.eb_new.set_sensitive(not value) self.eb_del.set_sensitive(not value) self.screen.readonly = value self.screen.display() def set_disable(self, value): self.eb_open.set_sensitive(value) self.eb_switch.set_sensitive(value) if self._readonly: value = not self._readonly self.eb_del.set_sensitive(value) ## This method is specially developed to store old values of ## the modified records. def _get_old_values(self, models=None): group_model = {} model_value = {} if models is None: models = [] for o2m_model in models: values = o2m_model.value.copy() model_value[o2m_model] = values.copy() group_model[o2m_model] = {} for key, val in values.iteritems(): if isinstance(val, ModelRecordGroup): group_model[o2m_model][key] = val.models[:] del model_value[o2m_model][key] return model_value,group_model ## This method is specially developed to restore old values def _restore_values(self, modified_model_values, group_model): for model, value in modified_model_values.iteritems(): model.set(value, modified=True) for f_name, models in group_model.get(model, {}).iteritems(): model.value[f_name].clear() for sub_model in models: # add model in ModelRecordGroup model.value[f_name].model_add(sub_model) return True def _sig_new(self, *args): _, event = args ctx = dict(self._view.model.expr_eval(self.screen.default_get), **self.context) ctx.update(self._view.model.expr_eval('dict(%s)' % self.attrs.get('context', '{}'))) if event.type in (gtk.gdk.BUTTON_PRESS, gtk.gdk.KEY_PRESS): if (self.screen.current_view.view_type=='form') or self.screen.editable_get(): self.screen.new(context=ctx) self.screen.make_buttons_readonly() self._readonly = False self.screen.current_view.widget.set_sensitive(True) self.set_disable(True) else: ok = True dia = dialog(self.attrs['relation'], parent=self._view.model, attrs=self.attrs, model_ctx=self.screen.models._context, window=self._window, readonly=self._readonly, context=ctx) while ok: ok, value, res = dia.run() if ok or res == gtk.RESPONSE_APPLY: modified_model_values, group_model = self._get_old_values(self.screen.models.models) self.screen.models.model_add(value) value.signal('record-changed', value.parent) self._restore_values(modified_model_values, group_model) self.screen.display() dia.new() self.set_disable(True) self.pager.reset_pager() dia.destroy() def _sig_edit(self, *args): ctx = dict(self._view.model.expr_eval(self.screen.default_get), **self.context) ctx.update(self._view.model.expr_eval('dict(%s)' % self.attrs.get('context', '{}'))) ok = True modified_model_values, group_model = self._get_old_values(self.screen.models.models) dia = dialog(self.attrs['relation'], parent=self._view.model, model=self.screen.current_model, attrs=self.attrs, window=self._window, readonly=self._readonly, context=ctx) while ok: ok, value, res = dia.run() if not any([ok, value, res]) and dia.screen.is_modified(): if modified_model_values: self._restore_values(modified_model_values, group_model) if res == gtk.RESPONSE_OK: dia.new() if value and value.id is None: modified_model_values, group_model = self._get_old_values(self.screen.models.models) if value not in modified_model_values: self.screen.models.model_add(value) value.signal('record-changed', value.parent) if modified_model_values: self._restore_values(modified_model_values, group_model) self.screen.display() self.pager.reset_pager() dia.destroy() def limit_changed(self,*args): self.pager.limit_changed() def _sig_prev_page(self, *args): self.pager.prev_page() def _sig_next_page(self, *args): self.pager.next_page() def _sig_next(self, *args): _, event = args if event.type == gtk.gdk.BUTTON_PRESS: self.pager.next_record() def _sig_previous(self, *args): _, event = args if event.type == gtk.gdk.BUTTON_PRESS: self.pager.prev_record() def _sig_remove(self, *args): lst, event = args if event.type == gtk.gdk.BUTTON_PRESS: if self.screen.current_view.view_type == 'form': msg = _('Are you sure to remove this record ?') else: msg = _('Are you sure to remove those records ?') if common.sur(msg): model = self.screen.current_model model.signal('record-changed', model.parent) self.screen.remove() self.pager.reset_pager() if not self.screen.models.models: self.screen.current_view.widget.set_sensitive(False) def _sig_label(self, screen, signal_data): name = '_' if signal_data[0] >= 0: name = str(signal_data[0] + 1) line = '(%s/%s of %s)' % (name, signal_data[1], signal_data[2]) self.label.set_text(line) def _sig_refresh(self, *args): pass def _sig_sequence(self, *args): pass def display(self, model, model_field): if model: self.context.update(model.expr_eval(self.attrs.get('context',"{}"))) self.screen.context.update(self.context) self.model = model self.model_field = model_field if not model_field: self.screen.current_model = None self.screen.display() return False super(one2many_list, self).display(model, model_field) new_models = model_field.get_client(model) if self.screen.models != new_models: self.screen.models_set(new_models) if (self.screen.current_view.view_type=='tree') and self.screen.editable_get(): if len(self.screen.models.models): self.screen.current_model = self.screen.models.models[0] else: self.screen.current_model = None if self.screen.current_view.view_type=='form': self.screen.make_buttons_readonly(self.screen.current_model \ and self.screen.current_model.id and True or False) self.set_disable(self.screen.models.models and True or False) self.pager.search_count() self.pager.set_sensitivity() self.screen.display() return True def set_value(self, model, model_field): self.screen.current_view.set_value() if self.screen.is_modified(): model.modified = True model.modified_fields.setdefault(model_field.name) return True def grab_focus(self): return self.screen.widget.grab_focus()
def __init__(self, window, parent, model, attrs={}): interface.widget_interface.__init__(self, window, parent, model, attrs) self._readonly = self.default_readonly self.widget = gtk.VBox(homogeneous=False, spacing=5) hb = gtk.HBox(homogeneous=False, spacing=5) menubar = gtk.MenuBar() if hasattr(menubar, 'set_pack_direction') and \ hasattr(menubar, 'set_child_pack_direction'): menubar.set_pack_direction(gtk.PACK_DIRECTION_LTR) menubar.set_child_pack_direction(gtk.PACK_DIRECTION_LTR) menuitem_title = gtk.ImageMenuItem(stock_id='gtk-preferences') menu_title = gtk.Menu() menuitem_set_to_default = gtk.MenuItem(_('Set to default value'), True) menuitem_set_to_default.connect('activate', lambda *x:self._menu_sig_default_get()) menu_title.add(menuitem_set_to_default) menuitem_set_default = gtk.MenuItem(_('Set Default'), True) menuitem_set_default.connect('activate', lambda *x: self._menu_sig_default_set()) menu_title.add(menuitem_set_default) menuitem_title.set_submenu(menu_title) menubar.add(menuitem_title) hb.pack_start(menubar, expand=True, fill=True) self.eb_new = gtk.EventBox() self.eb_new.set_tooltip_text(_('Create a new entry')) self.eb_new.set_events(gtk.gdk.BUTTON_PRESS) self.eb_new.connect('button_press_event', self._sig_new) img_new = gtk.Image() img_new.set_from_stock('gtk-new', gtk.ICON_SIZE_MENU) img_new.set_alignment(0.5, 0.5) self.eb_new.add(img_new) hb.pack_start(self.eb_new, expand=False, fill=False) self.eb_open = gtk.EventBox() self.eb_open.set_tooltip_text(_('Edit this entry')) self.eb_open.set_events(gtk.gdk.BUTTON_PRESS) self.eb_open.connect('button_press_event', self._sig_edit) img_open = gtk.Image() img_open.set_from_stock('gtk-open', gtk.ICON_SIZE_MENU) img_open.set_alignment(0.5, 0.5) self.eb_open.add(img_open) hb.pack_start(self.eb_open, expand=False, fill=False) self.eb_del = gtk.EventBox() self.eb_del.set_tooltip_text(_('Remove this entry')) self.eb_del.set_events(gtk.gdk.BUTTON_PRESS) self.eb_del.connect('button_press_event', self._sig_remove) img_del = gtk.Image() img_del.set_from_stock('gtk-delete', gtk.ICON_SIZE_MENU) img_del.set_alignment(0.5, 0.5) self.eb_del.add(img_del) hb.pack_start(self.eb_del, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) eb_pre = gtk.EventBox() eb_pre.set_tooltip_text(_('Previous')) eb_pre.set_events(gtk.gdk.BUTTON_PRESS) eb_pre.connect('button_press_event', self._sig_previous) img_pre = gtk.Image() img_pre.set_from_stock('gtk-go-back', gtk.ICON_SIZE_MENU) img_pre.set_alignment(0.5, 0.5) eb_pre.add(img_pre) hb.pack_start(eb_pre, expand=False, fill=False) self.label = gtk.Label('(0,0)') hb.pack_start(self.label, expand=False, fill=False) eb_next = gtk.EventBox() eb_next.set_tooltip_text(_('Next')) eb_next.set_events(gtk.gdk.BUTTON_PRESS) eb_next.connect('button_press_event', self._sig_next) img_next = gtk.Image() img_next.set_from_stock('gtk-go-forward', gtk.ICON_SIZE_MENU) img_next.set_alignment(0.5, 0.5) eb_next.add(img_next) hb.pack_start(eb_next, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) eb_switch = gtk.EventBox() eb_switch.set_tooltip_text(_('Switch')) eb_switch.set_events(gtk.gdk.BUTTON_PRESS) eb_switch.connect('button_press_event', self.switch_view) img_switch = gtk.Image() img_switch.set_from_stock('gtk-justify-left', gtk.ICON_SIZE_MENU) img_switch.set_alignment(0.5, 0.5) eb_switch.add(img_switch) hb.pack_start(eb_switch, expand=False, fill=False) self.widget.pack_start(hb, expand=False, fill=True) self.screen = Screen(attrs['relation'], view_type=attrs.get('mode','tree,form').split(','), parent=self.parent, views_preload=attrs.get('views', {}), tree_saves=attrs.get('saves', False), create_new=True, row_activate=self._on_activate, default_get=attrs.get('default_get', {}), window=self._window, readonly=self._readonly) self.screen.signal_connect(self, 'record-message', self._sig_label) menuitem_title.get_child().set_markup('<b>'+self.screen.current_view.title.replace('&','&').replace('<','<').replace('>','>')+'</b>') self.widget.pack_start(self.screen.widget, expand=True, fill=True) self.screen.widget.connect('key_press_event', self.on_keypress)
def __init__(self, model_name, parent, model=None, attrs=None, model_ctx=None, window=None, context=None, readonly=False): if attrs is None: attrs = {} if model_ctx is None: model_ctx = {} if context is None: context = {} if not window: window = service.LocalService('gui.main').window self.dia = gtk.Dialog(_('OpenERP'), window, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT) self.window = window if ('string' in attrs) and attrs['string']: self.dia.set_title(self.dia.get_title() + ' - ' + attrs['string']) self.dia.set_property('default-width', 760) self.dia.set_property('default-height', 500) self.dia.set_position(gtk.WIN_POS_CENTER_ON_PARENT) self.dia.set_icon(common.OPENERP_ICON) self.accel_group = gtk.AccelGroup() self.dia.add_accel_group(self.accel_group) self.but_cancel = self.dia.add_button(_('Cancel'), gtk.RESPONSE_CANCEL) icon = gtk.Image() icon.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_BUTTON) self.but_cancel.set_image(icon) self.but_cancel.add_accelerator('clicked', self.accel_group, gtk.keysyms.Escape, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) self.but_save_close = self.dia.add_button(_('Save & Close'), gtk.RESPONSE_APPLY) icon = gtk.Image() icon.set_from_stock(gtk.STOCK_APPLY, gtk.ICON_SIZE_BUTTON) self.but_save_close.set_image(icon) self.but_save_new = self.dia.add_button(_('Save & New'), gtk.RESPONSE_OK) icon = gtk.Image() icon.set_from_stock(gtk.STOCK_ADD, gtk.ICON_SIZE_BUTTON) self.but_save_new.set_image(icon) self.but_save_new.add_accelerator('clicked', self.accel_group, gtk.keysyms.Return, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) self.context = context scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scroll.set_placement(gtk.CORNER_TOP_LEFT) scroll.set_shadow_type(gtk.SHADOW_NONE) self.dia.vbox.pack_start(scroll, expand=True, fill=True) vp = gtk.Viewport() vp.set_shadow_type(gtk.SHADOW_NONE) scroll.add(vp) self.screen = Screen(model_name, view_type=[], parent=parent, window=self.dia, readonly=readonly, context=context) self.screen.models._context.update(model_ctx) if not model: model = self.screen.new(context=context) else: self.screen.models.model_add(model) self.screen.current_model = model if ('views' in attrs) and ('form' in attrs['views']): arch = attrs['views']['form']['arch'] fields = attrs['views']['form']['fields'] self.screen.add_view(arch, fields, display=True, context=context) else: self.screen.add_view_id(False, 'form', display=True, context=context) if not model or model.id is None: self.screen.make_buttons_readonly() vp.add(self.screen.widget) x,y = self.screen.screen_container.size_get() vp.set_size_request(x,y+30) self.dia.show_all() self.screen.readonly = readonly self.screen.display()
class dialog(object): def __init__(self, model, id=None, attrs=None ,domain=None, context=None, window=None, view_ids=None, target=False,view_type=['form'], help={}): if attrs is None: attrs = {} if domain is None: domain = [] if context is None: context = {} if not window: window = service.LocalService('gui.main').window self.dia = gtk.Dialog('OpenERP', window, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT) self.window = window if not target: self.dia.set_property('default-width', 760) self.dia.set_property('default-height', 500) self.dia.set_position(gtk.WIN_POS_CENTER_ON_PARENT) self.dia.set_icon(common.OPENERP_ICON) self.accel_group = gtk.AccelGroup() self.dia.add_accel_group(self.accel_group) self.but_cancel = self.dia.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) self.but_cancel.add_accelerator('clicked', self.accel_group, gtk.keysyms.Escape, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) self.but_ok = self.dia.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) scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scroll.set_placement(gtk.CORNER_TOP_LEFT) scroll.set_shadow_type(gtk.SHADOW_NONE) self.dia.vbox.pack_start(scroll, expand=True, fill=True) vp = gtk.Viewport() vp.set_shadow_type(gtk.SHADOW_NONE) scroll.add(vp) self.screen = Screen(model, view_ids=view_ids, domain=domain, context=context, window=self.dia, view_type=view_type, help=help) if id: self.screen.load([id]) else: self.screen.new() if ('string' in attrs) and attrs['string']: self.dia.set_title(self.dia.get_title() + ' - ' + attrs['string']) elif self.screen.current_view: self.dia.set_title(self.dia.get_title() + ' - ' + self.screen.current_view.title) vp.add(self.screen.widget) width, height = self.screen.screen_container.size_get() window_width, window_height = window.get_size() dia_width, dia_height = self.dia.get_size() widget_width = min(window_width - 20, max(dia_width, width + 30)) if target: widget_height = min(window_height - 60, height + 10) else: widget_height = min(window_height - 60, height + 20) vp.set_size_request(widget_width, widget_height) self.dia.show_all() self.screen.display() def run(self, datas={}): while True: try: res = self.dia.run() if res == gtk.RESPONSE_OK: if self.screen.current_model.validate() and self.screen.save_current(): return (True, self.screen.current_model.name_get()) else: self.screen.display() self.screen.current_view.set_cursor() else: break except Exception,e: # Passing all exceptions, most preferably the one of sql_constraint pass return (False, False)
def __init__(self, model, res_id=False, domain=None, view_type=None, view_ids=None, window=None, context=None, name=False, help={}, limit=100, auto_refresh=False, auto_search=True, search_view=None): if not view_type: view_type = ['form', 'tree'] if domain is None: domain = [] if view_ids is None: view_ids = [] if context is None: context = {} fields = {} self.model = model self.window = window self.previous_action = None self.glade = glade.XML(common.terp_path("openerp.glade"), 'win_form_container', gettext.textdomain()) self.widget = self.glade.get_widget('win_form_container') self.widget.show_all() self.fields = fields self.domain = domain self.context = context self.screen = Screen(self.model, view_type=view_type, context=self.context, view_ids=view_ids, domain=domain, help=help, hastoolbar=options.options['form.toolbar'], hassubmenu=options.options['form.submenu'], show_search=True, window=self.window, limit=limit, readonly=bool(auto_refresh), auto_search=auto_search, search_view=search_view) self.screen.signal_connect(self, 'record-message', self._record_message) self.screen.widget.show() oregistry.add_receiver('misc-message', self._misc_message) if not name: self.name = self.screen.current_view.title else: self.name = name vp = gtk.Viewport() vp.set_shadow_type(gtk.SHADOW_NONE) vp.add(self.screen.widget) vp.show() self.sw = gtk.ScrolledWindow() self.sw.set_shadow_type(gtk.SHADOW_NONE) self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.sw.add(vp) self.sw.show() self.has_backup = False self.backup = {} self.widget.pack_start(self.sw) self.handlers = { 'but_new': self.sig_new, 'but_copy': self.sig_copy, 'but_save': self.sig_save, 'but_save_as': self.sig_save_as, 'but_import': self.sig_import, 'but_print_repeat': self.sig_print_repeat, 'but_remove': self.sig_remove, 'but_search': self.sig_search, 'but_previous': self.sig_previous, 'but_next': self.sig_next, 'but_goto_id': self.sig_goto, 'but_log': self.sig_logs, 'but_print': self.sig_print, 'but_reload': self.sig_reload, 'but_print_html': self.sig_print_html, 'but_action': self.sig_action, 'but_switch': self.sig_switch, 'but_attach': self.sig_attach, 'but_close': self.sig_close, } if 'tree' in view_type: self.handlers['radio_tree'] = self.sig_switch_tree if 'form' in view_type: self.handlers['radio_form'] = self.sig_switch_form if 'graph' in view_type: self.handlers['radio_graph'] = self.sig_switch_graph if 'calendar' in view_type: self.handlers['radio_calendar'] = self.sig_switch_calendar if 'diagram' in view_type: self.handlers['radio_diagram'] = self.sig_switch_diagram if res_id: if isinstance(res_id, ( int, long, )): res_id = [res_id] self.screen.load(res_id) else: if self.screen.current_view.view_type == 'form': self.sig_new(autosave=False) if self.screen.current_view.view_type in ('tree', 'graph', 'calendar'): self.screen.search_filter() if auto_refresh and int(auto_refresh): gobject.timeout_add(int(auto_refresh) * 1000, self.sig_reload)
class win_search(object): def __init__(self, model, sel_multi=True, ids=[], context={}, domain=[], parent=None): self.model = model self.sel_multi = sel_multi self.ids = ids self.ctx = context self.glade = glade.XML(common.terp_path("openerp.glade"), "win_search", gettext.textdomain()) self.win = self.glade.get_widget("win_search") self.win.set_icon(common.OPENERP_ICON) if not parent: parent = service.LocalService("gui.main").window self.parent = parent self.win.set_transient_for(parent) self.screen = Screen( model, view_type=["tree"], show_search=True, domain=domain, context=context, parent=self.win, win_search=True, ) self.view = self.screen.current_view if self.screen.filter_widget.focusable: self.screen.filter_widget.focusable.grab_focus() self.title = _("OpenERP Search: %s") % self.screen.name self.title_results = _("OpenERP Search: %s (%%d result(s))") % (self.screen.name,) self.win.set_title(self.title) self.view.unset_editable() sel = self.view.widget_tree.get_selection() if not sel_multi: sel.set_mode("single") else: sel.set_mode(gtk.SELECTION_MULTIPLE) self.view.widget_tree.connect("row_activated", self.sig_activate) self.view.widget_tree.connect("button_press_event", self.sig_button) self.screen.win_search_callback = self.update_title vp = gtk.Viewport() vp.set_shadow_type(gtk.SHADOW_NONE) vp.add(self.screen.widget) vp.show() self.sw = gtk.ScrolledWindow() self.sw.set_shadow_type(gtk.SHADOW_NONE) self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.sw.add(vp) self.sw.show() self.wid = self.glade.get_widget("win_search_vbox") self.wid.pack_start(self.sw) self.wid.show_all() def sig_activate(self, treeview, path, column, *args): self.view.widget_tree.emit_stop_by_name("row_activated") if not self.sel_multi: self.win.response(gtk.RESPONSE_OK) return False def sig_button(self, view, event): if event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS: self.win.response(gtk.RESPONSE_OK) return False def find(self, widget=None, *args): self.screen.search_filter() self.update_title() def update_title(self): self.ids = self.screen.win_search_ids self.reload() self.win.set_title(self.title_results % len(self.ids)) def reload(self): sel = self.view.widget_tree.get_selection() if sel.get_mode() == gtk.SELECTION_MULTIPLE: sel.select_all() def sel_ids_get(self): return self.screen.sel_ids_get() def destroy(self): self.parent.present() self.win.destroy() def go(self): ## This is if the user has set some filters by default with search_default_XXX if self.ids: # Add the domain only if there was no name_search performed with name name_search = self.ctx.get("name_search", False) self.screen.win_search_domain += [("id", "in", self.ids)] if name_search else [] self.find() else: self.screen.update_scroll() end = False while not end: button = self.win.run() if button == gtk.RESPONSE_OK: res = self.sel_ids_get() or self.ids end = True elif button == gtk.RESPONSE_APPLY: self.find() else: res = None end = True self.destroy() if button == gtk.RESPONSE_ACCEPT: dia = dialog(self.model, window=self.parent, domain=self.screen.domain_init, context=self.screen.context) id = dia.run() res = id and [id] or None dia.destroy() return res
class one2many_list(interface.widget_interface): def __init__(self, window, parent, model, attrs={}): interface.widget_interface.__init__(self, window, parent, model, attrs) self._readonly = self.default_readonly self.widget = gtk.VBox(homogeneous=False, spacing=5) hb = gtk.HBox(homogeneous=False, spacing=5) menubar = gtk.MenuBar() if hasattr(menubar, 'set_pack_direction') and \ hasattr(menubar, 'set_child_pack_direction'): menubar.set_pack_direction(gtk.PACK_DIRECTION_LTR) menubar.set_child_pack_direction(gtk.PACK_DIRECTION_LTR) menuitem_title = gtk.ImageMenuItem(stock_id='gtk-preferences') menu_title = gtk.Menu() menuitem_set_to_default = gtk.MenuItem(_('Set to default value'), True) menuitem_set_to_default.connect('activate', lambda *x:self._menu_sig_default_get()) menu_title.add(menuitem_set_to_default) menuitem_set_default = gtk.MenuItem(_('Set Default'), True) menuitem_set_default.connect('activate', lambda *x: self._menu_sig_default_set()) menu_title.add(menuitem_set_default) menuitem_title.set_submenu(menu_title) menubar.add(menuitem_title) hb.pack_start(menubar, expand=True, fill=True) self.eb_new = gtk.EventBox() self.eb_new.set_tooltip_text(_('Create a new entry')) self.eb_new.set_events(gtk.gdk.BUTTON_PRESS) self.eb_new.connect('button_press_event', self._sig_new) img_new = gtk.Image() img_new.set_from_stock('gtk-new', gtk.ICON_SIZE_MENU) img_new.set_alignment(0.5, 0.5) self.eb_new.add(img_new) hb.pack_start(self.eb_new, expand=False, fill=False) self.eb_open = gtk.EventBox() self.eb_open.set_tooltip_text(_('Edit this entry')) self.eb_open.set_events(gtk.gdk.BUTTON_PRESS) self.eb_open.connect('button_press_event', self._sig_edit) img_open = gtk.Image() img_open.set_from_stock('gtk-open', gtk.ICON_SIZE_MENU) img_open.set_alignment(0.5, 0.5) self.eb_open.add(img_open) hb.pack_start(self.eb_open, expand=False, fill=False) self.eb_del = gtk.EventBox() self.eb_del.set_tooltip_text(_('Remove this entry')) self.eb_del.set_events(gtk.gdk.BUTTON_PRESS) self.eb_del.connect('button_press_event', self._sig_remove) img_del = gtk.Image() img_del.set_from_stock('gtk-delete', gtk.ICON_SIZE_MENU) img_del.set_alignment(0.5, 0.5) self.eb_del.add(img_del) hb.pack_start(self.eb_del, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) eb_pre = gtk.EventBox() eb_pre.set_tooltip_text(_('Previous')) eb_pre.set_events(gtk.gdk.BUTTON_PRESS) eb_pre.connect('button_press_event', self._sig_previous) img_pre = gtk.Image() img_pre.set_from_stock('gtk-go-back', gtk.ICON_SIZE_MENU) img_pre.set_alignment(0.5, 0.5) eb_pre.add(img_pre) hb.pack_start(eb_pre, expand=False, fill=False) self.label = gtk.Label('(0,0)') hb.pack_start(self.label, expand=False, fill=False) eb_next = gtk.EventBox() eb_next.set_tooltip_text(_('Next')) eb_next.set_events(gtk.gdk.BUTTON_PRESS) eb_next.connect('button_press_event', self._sig_next) img_next = gtk.Image() img_next.set_from_stock('gtk-go-forward', gtk.ICON_SIZE_MENU) img_next.set_alignment(0.5, 0.5) eb_next.add(img_next) hb.pack_start(eb_next, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) eb_switch = gtk.EventBox() eb_switch.set_tooltip_text(_('Switch')) eb_switch.set_events(gtk.gdk.BUTTON_PRESS) eb_switch.connect('button_press_event', self.switch_view) img_switch = gtk.Image() img_switch.set_from_stock('gtk-justify-left', gtk.ICON_SIZE_MENU) img_switch.set_alignment(0.5, 0.5) eb_switch.add(img_switch) hb.pack_start(eb_switch, expand=False, fill=False) self.widget.pack_start(hb, expand=False, fill=True) self.screen = Screen(attrs['relation'], view_type=attrs.get('mode','tree,form').split(','), parent=self.parent, views_preload=attrs.get('views', {}), tree_saves=attrs.get('saves', False), create_new=True, row_activate=self._on_activate, default_get=attrs.get('default_get', {}), window=self._window, readonly=self._readonly) self.screen.signal_connect(self, 'record-message', self._sig_label) menuitem_title.get_child().set_markup('<b>'+self.screen.current_view.title.replace('&','&').replace('<','<').replace('>','>')+'</b>') self.widget.pack_start(self.screen.widget, expand=True, fill=True) self.screen.widget.connect('key_press_event', self.on_keypress) def on_keypress(self, widget, event): if (not self._readonly) and ((event.keyval in (gtk.keysyms.N, gtk.keysyms.n) and event.state & gtk.gdk.CONTROL_MASK\ and event.state & gtk.gdk.SHIFT_MASK)): self._sig_new(widget, event) return False if event.keyval in (gtk.keysyms.E, gtk.keysyms.e) and event.state & gtk.gdk.CONTROL_MASK\ and event.state & gtk.gdk.SHIFT_MASK: self._sig_edit(widget, event) return False if event.keyval in (gtk.keysyms.L, gtk.keysyms.l) and event.state & gtk.gdk.CONTROL_MASK\ and event.state & gtk.gdk.SHIFT_MASK: self.switch_view(widget, event) return False def destroy(self): self.screen.destroy() def _on_activate(self, screen, *args): self._sig_edit() def click_and_action(self, type): pos = self.tree_view.pos_get() if pos!=None: val = self._value[pos] id = val.get('id', False) obj = service.LocalService('action.main') res = obj.exec_keyword(type, {'model':self.model, 'id': id or False, 'ids':[id], 'report_type': 'pdf'}) return True else: common.message(_('You have to select a resource !')) return False def switch_view(self, btn, arg): self.screen.switch_view() def _readonly_set(self, value): self._readonly = value self.eb_new.set_sensitive(not value) self.eb_del.set_sensitive(not value) self.screen.readonly = value self.screen.display() def _sig_new(self, *args): _, event = args ctx = self._view.model.expr_eval(self.screen.default_get) ctx.update(self._view.model.expr_eval('dict(%s)' % self.attrs.get('context', ''))) if event.type in (gtk.gdk.BUTTON_PRESS, gtk.gdk.KEY_PRESS): if (self.screen.current_view.view_type=='form') or self.screen.editable_get(): self.screen.new(context=ctx) self._readonly = False self.screen.current_view.widget.set_sensitive(True) else: ok = 1 dia = dialog(self.attrs['relation'], parent=self._view.model, attrs=self.attrs, model_ctx=self.screen.models._context, default_get_ctx=ctx, window=self._window, readonly=self._readonly) while ok: ok, value = dia.run() if ok: self.screen.models.model_add(value) value.signal('record-changed', value.parent) self.screen.display() dia.new() dia.destroy() def _sig_edit(self, *args): if self.screen.current_model: dia = dialog(self.attrs['relation'], parent=self._view.model, model=self.screen.current_model, attrs=self.attrs, window=self._window, readonly=self._readonly) ok, value = dia.run() dia.destroy() def _sig_next(self, *args): _, event = args if event.type == gtk.gdk.BUTTON_PRESS: self.screen.display_next() def _sig_previous(self, *args): _, event = args if event.type == gtk.gdk.BUTTON_PRESS: self.screen.display_prev() def _sig_remove(self, *args): _, event = args if event.type == gtk.gdk.BUTTON_PRESS: if self.screen.current_view.view_type == 'form': msg = 'Are you sure to remove this record ?' else: msg = 'Are you sure to remove those records ?' if common.sur(msg): self.screen.remove() if not self.screen.models.models: self.screen.current_view.widget.set_sensitive(False) def _sig_label(self, screen, signal_data): name = '_' if signal_data[0] >= 0: name = str(signal_data[0] + 1) line = '(%s/%s)' % (name, signal_data[1]) self.label.set_text(line) def _sig_refresh(self, *args): pass def _sig_sequence(self, *args): pass def display(self, model, model_field): if not model_field: self.screen.current_model = None self.screen.display() return False super(one2many_list, self).display(model, model_field) new_models = model_field.get_client(model) if self.screen.models != new_models: self.screen.models_set(new_models) if (self.screen.current_view.view_type=='tree') and self.screen.editable_get(): self.screen.current_model = None self.screen.display() return True def set_value(self, model, model_field): self.screen.current_view.set_value() if self.screen.is_modified(): model.modified = True model.modified_fields.setdefault(model_field.name) return True
class win_search(object): def __init__(self, model, sel_multi=True, ids=[], context={}, domain = [], parent=None): self.model = model self.first = True self.domain =domain self.context = context self.context.update(rpc.session.context) self.sel_multi = sel_multi self.glade = glade.XML(common.terp_path("openerp.glade"),'win_search',gettext.textdomain()) self.win = self.glade.get_widget('win_search') self.win.set_icon(common.OPENERP_ICON) if not parent: parent = service.LocalService('gui.main').window self.parent = parent self.win.set_transient_for(parent) self.screen = Screen(model, view_type=['tree'], context=self.context, parent=self.win) self.view = self.screen.current_view self.view.unset_editable() sel = self.view.widget_tree.get_selection() if not sel_multi: sel.set_mode('single') else: sel.set_mode(gtk.SELECTION_MULTIPLE) vp = gtk.Viewport() vp.set_shadow_type(gtk.SHADOW_NONE) vp.add(self.screen.widget) sw = self.glade.get_widget('search_sw') sw.add(vp) sw.show_all() self.view.widget_tree.connect('row_activated', self.sig_activate) self.view.widget_tree.connect('button_press_event', self.sig_button) self.model_name = model view_form = rpc.session.rpc_exec_auth('/object', 'execute', self.model_name, 'fields_view_get', False, 'form', self.context) self.form = widget_search.form(view_form['arch'], view_form['fields'], model, parent=self.win) self.title = _('OpenERP Search: %s') % self.form.name self.title_results = _('OpenERP Search: %s (%%d result(s))') % self.form.name self.win.set_title(self.title) x, y = self.form.widget.size_request() hbox = self.glade.get_widget('search_hbox') hbox.pack_start(self.form.widget) self.ids = ids if self.ids: self.reload() self.old_search = None self.old_offset = self.old_limit = None if self.ids: self.old_search = [] self.old_limit = self.form.get_limit() self.old_offset = self.form.get_offset() self.view.widget.show_all() if self.form.focusable: self.form.focusable.grab_focus() def sig_activate(self, treeview, path, column, *args): self.view.widget_tree.emit_stop_by_name('row_activated') if not self.sel_multi: self.win.response(gtk.RESPONSE_OK) return False def sig_button(self, view, event): if event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS: self.win.response(gtk.RESPONSE_OK) return False def find(self, widget=None, *args): limit = self.form.get_limit() offset = self.form.get_offset() if (self.old_search == self.form.value) and (self.old_limit==limit) and (self.old_offset==offset) and not self.first: self.win.response(gtk.RESPONSE_OK) return False self.first = False self.old_offset = offset self.old_limit = limit v = self.form.value v_keys = map(lambda x: x[0], v) v += self.domain try: self.ids = rpc.session.rpc_exec_auth_try('/object', 'execute', self.model_name, 'search', v, offset, limit, 0, self.context) except: # Try if it is not an old server self.ids = rpc.session.rpc_exec_auth('/object', 'execute', self.model_name, 'search', v, offset, limit) self.reload() self.old_search = self.form.value self.win.set_title(self.title_results % len(self.ids)) return True def reload(self): self.screen.clear() self.screen.load(self.ids) sel = self.view.widget_tree.get_selection() if sel.get_mode() == gtk.SELECTION_MULTIPLE: sel.select_all() def sel_ids_get(self): return self.screen.sel_ids_get() def destroy(self): self.parent.present() self.win.destroy() def go(self): end = False while not end: button = self.win.run() if button == gtk.RESPONSE_OK: res = self.sel_ids_get() or self.ids end = True elif button== gtk.RESPONSE_APPLY: end = not self.find() if end: res = self.sel_ids_get() or self.ids else: res = None end = True self.destroy() if button== gtk.RESPONSE_ACCEPT: dia = dialog(self.model, window=self.parent, domain=self.domain ,context=self.context) id = dia.run() res = id and [id] or None dia.destroy() return res
class win_search(object): def __init__(self, model, sel_multi=True, ids=[], context={}, domain=[], parent=None): self.model = model self.sel_multi = sel_multi self.ids = ids self.glade = glade.XML(common.terp_path("openerp.glade"), 'win_search', gettext.textdomain()) self.win = self.glade.get_widget('win_search') self.win.set_icon(common.OPENERP_ICON) if not parent: parent = service.LocalService('gui.main').window self.parent = parent self.win.set_transient_for(parent) self.screen = Screen(model, view_type=['tree'], show_search=True, domain=domain, context=context, parent=self.win, win_search=True) self.view = self.screen.current_view if self.screen.filter_widget.focusable: self.screen.filter_widget.focusable.grab_focus() self.title = _('OpenERP Search: %s') % self.screen.name self.title_results = _('OpenERP Search: %s (%%d result(s))') % ( self.screen.name, ) self.win.set_title(self.title) self.view.unset_editable() sel = self.view.widget_tree.get_selection() if not sel_multi: sel.set_mode('single') else: sel.set_mode(gtk.SELECTION_MULTIPLE) self.view.widget_tree.connect('row_activated', self.sig_activate) self.view.widget_tree.connect('button_press_event', self.sig_button) self.screen.win_search_callback = self.update_title vp = gtk.Viewport() vp.set_shadow_type(gtk.SHADOW_NONE) vp.add(self.screen.widget) vp.show() self.sw = gtk.ScrolledWindow() self.sw.set_shadow_type(gtk.SHADOW_NONE) self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.sw.add(vp) self.sw.show() self.wid = self.glade.get_widget('win_search_vbox') self.wid.pack_start(self.sw) self.wid.show_all() def sig_activate(self, treeview, path, column, *args): self.view.widget_tree.emit_stop_by_name('row_activated') if not self.sel_multi: self.win.response(gtk.RESPONSE_OK) return False def sig_button(self, view, event): if event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS: self.win.response(gtk.RESPONSE_OK) return False def find(self, widget=None, *args): self.screen.search_filter() self.update_title() def update_title(self): self.ids = self.screen.win_search_ids self.reload() self.win.set_title(self.title_results % len(self.ids)) def reload(self): sel = self.view.widget_tree.get_selection() if sel.get_mode() == gtk.SELECTION_MULTIPLE: sel.select_all() def sel_ids_get(self): return self.screen.sel_ids_get() def destroy(self): self.parent.present() self.win.destroy() def go(self): ## This is if the user has set some filters by default with search_default_XXX if self.ids: self.screen.win_search_domain += [('id', 'in', self.ids)] self.find() else: self.screen.update_scroll() end = False while not end: button = self.win.run() if button == gtk.RESPONSE_OK: res = self.sel_ids_get() or self.ids end = True elif button == gtk.RESPONSE_APPLY: self.find() else: res = None end = True self.destroy() if button == gtk.RESPONSE_ACCEPT: dia = dialog(self.model, window=self.parent, domain=self.screen.domain_init, context=self.screen.context) id = dia.run() res = id and [id] or None dia.destroy() return res
class dialog(object): def __init__(self, model, domain=None, context=None, window=None, target=False): if domain is None: domain = [] if context is None: context = {} if not window: window = service.LocalService('gui.main').window self.dia = gtk.Dialog( _('OpenERP - Link'), window, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT) self.window = window if not target: self.dia.set_property('default-width', 760) self.dia.set_property('default-height', 500) self.dia.set_position(gtk.WIN_POS_CENTER_ON_PARENT) self.dia.set_icon(common.OPENERP_ICON) self.accel_group = gtk.AccelGroup() self.dia.add_accel_group(self.accel_group) self.but_cancel = self.dia.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) self.but_cancel.add_accelerator('clicked', self.accel_group, gtk.keysyms.Escape, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) self.but_ok = self.dia.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) scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scroll.set_placement(gtk.CORNER_TOP_LEFT) scroll.set_shadow_type(gtk.SHADOW_NONE) self.dia.vbox.pack_start(scroll, expand=True, fill=True) vp = gtk.Viewport() vp.set_shadow_type(gtk.SHADOW_NONE) scroll.add(vp) self.screen = Screen(model, view_ids=None, domain=domain, context=context, window=self.dia, view_type=['form']) self.screen.new() vp.add(self.screen.widget) x, y = self.screen.screen_container.size_get() width, height = window.get_size() vp.set_size_request(min(width - 20, x + 20), min(height - 60, y + 25)) self.dia.show_all() self.screen.display() def run(self, datas={}): while True: try: res = self.dia.run() if res == gtk.RESPONSE_OK: if self.screen.current_model.validate( ) and self.screen.save_current(): return self.screen.current_model.id else: self.screen.display() self.screen.current_view.set_cursor() else: break except Exception: # Passing all exceptions, most preferably the one of sql_constraint pass return False def destroy(self): self.window.present() self.dia.destroy() self.screen.destroy()
class one2many_list(interface.widget_interface): def __init__(self, window, parent, model, attrs={}): interface.widget_interface.__init__(self, window, parent, model, attrs) self.context = {} #TODO: # group by context are evaled here as we need the context in screen # while displaying. # We need a better way to eval context that has group_by' # We needed to do this as normal context also get evaled here # and results in a traceback which should not be evaled here. if str(attrs.get('context',"{}")).find('group_by') != -1: self.context = tools.expr_eval(attrs.get('context',"{}")) self._readonly = self.default_readonly self.widget = gtk.VBox(homogeneous=False, spacing=5) hb = gtk.HBox(homogeneous=False, spacing=5) menubar = gtk.MenuBar() if hasattr(menubar, 'set_pack_direction') and \ hasattr(menubar, 'set_child_pack_direction'): menubar.set_pack_direction(gtk.PACK_DIRECTION_LTR) menubar.set_child_pack_direction(gtk.PACK_DIRECTION_LTR) menuitem_title = gtk.ImageMenuItem(stock_id='gtk-preferences') menu_title = gtk.Menu() menuitem_set_to_default = gtk.MenuItem(_('Set to default value'), True) menuitem_set_to_default.connect('activate', lambda *x:self._menu_sig_default_get()) menu_title.add(menuitem_set_to_default) menuitem_set_default = gtk.MenuItem(_('Set Default'), True) menuitem_set_default.connect('activate', lambda *x: self._menu_sig_default_set()) menu_title.add(menuitem_set_default) menuitem_title.set_submenu(menu_title) menubar.add(menuitem_title) hb.pack_start(menubar, expand=True, fill=True) if self.context.get('group_by'): self.context['group_by'] = [self.context['group_by']] # the context to pass to default_get can be optionally specified in # the context of the one2many field. We also support a legacy # 'default_get' attribute for the same effect (pending removal) default_get_ctx = (attrs.get('default_get') or attrs.get('context')) self.screen = Screen(attrs['relation'], view_type=attrs.get('mode','tree,form').split(','), parent=self.parent, views_preload=attrs.get('views', {}), tree_saves=attrs.get('saves', False), create_new=True, context=self.context, row_activate=self._on_activate, default_get=default_get_ctx, window=self._window, readonly=self._readonly, limit=pager.DEFAULT_LIMIT) self.screen.type = 'one2many' self.pager = pager(object=self, relation=attrs['relation'], screen=self.screen) # Button New self.eb_new = self.pager.create_event_box(_('Create a new entry'), self._sig_new, 'gtk-new') hb.pack_start(self.eb_new, expand=False, fill=False) # Button Edit self.eb_open = self.pager.create_event_box(_('Edit this entry'), self._sig_edit, 'gtk-open') hb.pack_start(self.eb_open, expand=False, fill=False) # Button Delete self.eb_del = self.pager.create_event_box(_('Remove this entry'), self._sig_remove, 'gtk-delete') hb.pack_start(self.eb_del, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # Button Previous Page self.eb_prev_page = self.pager.create_event_box(_('Previous Page'), self._sig_prev_page, 'gtk-goto-first') hb.pack_start(self.eb_prev_page, expand=False, fill=False) # Button Previous Record self.eb_pre = self.pager.create_event_box(_('Previous Record'), self._sig_previous, 'gtk-go-back') hb.pack_start(self.eb_pre, expand=False, fill=False) # Record display self.label = gtk.Label('(0,0)') hb.pack_start(self.label, expand=False, fill=False) # Button Next self.eb_next = self.pager.create_event_box(_('Next Record'), self._sig_next, 'gtk-go-forward') hb.pack_start(self.eb_next, expand=False, fill=False) # Button Next Page self.eb_next_page = self.pager.create_event_box(_('Next Page'), self._sig_next_page, 'gtk-goto-last') hb.pack_start(self.eb_next_page, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # Button Switch self.eb_switch = self.pager.create_event_box(_('Switch'), self.switch_view, 'gtk-justify-left') hb.pack_start(self.eb_switch, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # Limit Combo self.cb = self.pager.create_combo_box(_('Choose Limit'), self.limit_changed) hb.pack_start(self.cb, expand=False, fill=False) self.widget.pack_start(hb, expand=False, fill=True) self.screen.signal_connect(self, 'record-message', self._sig_label) menuitem_title.get_child().set_markup('<b>'+self.screen.current_view.title.replace('&','&').replace('<','<').replace('>','>')+'</b>') self.widget.pack_start(self.screen.widget, expand=True, fill=True) self.screen.widget.connect('key_press_event', self.on_keypress) self.model = None self.model_field = None self.name = attrs['name'] def on_keypress(self, widget, event): if (not self._readonly) and ((event.keyval in (gtk.keysyms.N, gtk.keysyms.n) and event.state & gtk.gdk.CONTROL_MASK\ and event.state & gtk.gdk.SHIFT_MASK)): self._sig_new(widget, event) return False if event.keyval in (gtk.keysyms.E, gtk.keysyms.e) and event.state & gtk.gdk.CONTROL_MASK\ and event.state & gtk.gdk.SHIFT_MASK: self._sig_edit(widget, event) return False if event.keyval in (gtk.keysyms.L, gtk.keysyms.l) and event.state & gtk.gdk.CONTROL_MASK\ and event.state & gtk.gdk.SHIFT_MASK: self.switch_view(widget, event) return False def destroy(self): self.screen.destroy() def _on_activate(self, screen, *args): self._sig_edit() def click_and_action(self, type): pos = self.tree_view.pos_get() if pos!=None: val = self._value[pos] id = val.get('id', False) obj = service.LocalService('action.main') res = obj.exec_keyword(type, {'model':self.model, 'id': id or False, 'ids':[id], 'report_type': 'pdf'}) return True else: common.message(_('You have to select a resource !')) return False def switch_view(self, btn, arg): self.screen.make_buttons_readonly(True) self.screen.switch_view() def _readonly_set(self, value): self._readonly = value self.eb_new.set_sensitive(not value) self.eb_del.set_sensitive(not value) self.screen.readonly = value self.screen.display() def set_disable(self, value): self.eb_open.set_sensitive(value) self.eb_switch.set_sensitive(value) if self._readonly: value = not self._readonly self.eb_del.set_sensitive(value) def _sig_new(self, *args): _, event = args ctx = dict(self._view.model.expr_eval(self.screen.default_get), **self.context) ctx.update(self._view.model.expr_eval('dict(%s)' % self.attrs.get('context', '{}'))) if event.type in (gtk.gdk.BUTTON_PRESS, gtk.gdk.KEY_PRESS): if (self.screen.current_view.view_type=='form') or self.screen.editable_get(): self.screen.new(context=ctx) self.screen.make_buttons_readonly() self._readonly = False self.screen.current_view.widget.set_sensitive(True) self.set_disable(True) else: ok = True dia = dialog(self.attrs['relation'], parent=self._view.model, attrs=self.attrs, model_ctx=self.screen.models._context, window=self._window, readonly=self._readonly, context=ctx) while ok: ok, value, res = dia.run() if ok or res == gtk.RESPONSE_APPLY: self.screen.models.model_add(value) value.signal('record-changed', value.parent) self.screen.display() dia.new() self.set_disable(True) self.pager.reset_pager() dia.destroy() def _sig_edit(self, *args): ctx = dict(self._view.model.expr_eval(self.screen.default_get), **self.context) ctx.update(self._view.model.expr_eval('dict(%s)' % self.attrs.get('context', '{}'))) if self.screen.current_model: ok = True edited_model = self.screen.current_model dia = dialog(self.attrs['relation'], parent=self._view.model, model=self.screen.current_model, attrs=self.attrs, window=self._window, readonly=self._readonly, context=ctx) while ok: ok, value, res = dia.run() if res == gtk.RESPONSE_OK: dia.new() if value and value != edited_model: self.screen.models.model_add(value) value.signal('record-changed', value.parent) self.screen.display() self.pager.reset_pager() edited_model.modified = True dia.destroy() def limit_changed(self,*args): self.pager.limit_changed() def _sig_prev_page(self, *args): self.pager.prev_page() def _sig_next_page(self, *args): self.pager.next_page() def _sig_next(self, *args): _, event = args if event.type == gtk.gdk.BUTTON_PRESS: self.pager.next_record() def _sig_previous(self, *args): _, event = args if event.type == gtk.gdk.BUTTON_PRESS: self.pager.prev_record() def _sig_remove(self, *args): lst, event = args if event.type == gtk.gdk.BUTTON_PRESS: if self.screen.current_view.view_type == 'form': msg = _('Are you sure to remove this record ?') else: msg = _('Are you sure to remove those records ?') if common.sur(msg): model = self.screen.current_model model.signal('record-changed', model.parent) self.screen.remove() self.pager.reset_pager() if not self.screen.models.models: self.screen.current_view.widget.set_sensitive(False) def _sig_label(self, screen, signal_data): name = '_' if signal_data[0] >= 0: name = str(signal_data[0] + 1) line = '(%s/%s of %s)' % (name, signal_data[1], signal_data[2]) self.label.set_text(line) def _sig_refresh(self, *args): pass def _sig_sequence(self, *args): pass def display(self, model, model_field): self.model = model self.model_field = model_field if not model_field: self.screen.current_model = None self.screen.display() return False super(one2many_list, self).display(model, model_field) new_models = model_field.get_client(model) if self.screen.models != new_models: self.screen.models_set(new_models) if (self.screen.current_view.view_type=='tree') and self.screen.editable_get(): if len(self.screen.models.models): self.screen.current_model = self.screen.models.models[0] else: self.screen.current_model = None if self.screen.current_view.view_type=='form': self.screen.make_buttons_readonly(self.screen.current_model \ and self.screen.current_model.id and True or False) self.set_disable(self.screen.models.models and True or False) self.pager.search_count() self.pager.set_sensitivity() self.screen.display() return True def set_value(self, model, model_field): self.screen.current_view.set_value() if self.screen.is_modified(): model.modified = True model.modified_fields.setdefault(model_field.name) return True def grab_focus(self): return self.screen.widget.grab_focus()
def __init__(self, window, parent, model, attrs={}): interface.widget_interface.__init__(self, window, parent, model, attrs) self.context = {} #TODO: # group by context are evaled here as we need the context in screen # while displaying. # We need a better way to eval context that has group_by' # We needed to do this as normal context also get evaled here # and results in a traceback which should not be evaled here. if str(attrs.get('context', "{}")).find('group_by') != -1: self.context = tools.expr_eval(attrs.get('context', "{}")) self._readonly = self.default_readonly self.widget = gtk.VBox(homogeneous=False, spacing=5) hb = gtk.HBox(homogeneous=False, spacing=5) menubar = gtk.MenuBar() if hasattr(menubar, 'set_pack_direction') and \ hasattr(menubar, 'set_child_pack_direction'): menubar.set_pack_direction(gtk.PACK_DIRECTION_LTR) menubar.set_child_pack_direction(gtk.PACK_DIRECTION_LTR) menuitem_title = gtk.ImageMenuItem(stock_id='gtk-preferences') menu_title = gtk.Menu() menuitem_set_to_default = gtk.MenuItem(_('Set to default value'), True) menuitem_set_to_default.connect( 'activate', lambda *x: self._menu_sig_default_get()) menu_title.add(menuitem_set_to_default) menuitem_set_default = gtk.MenuItem(_('Set Default'), True) menuitem_set_default.connect('activate', lambda *x: self._menu_sig_default_set()) menu_title.add(menuitem_set_default) menuitem_title.set_submenu(menu_title) menubar.add(menuitem_title) hb.pack_start(menubar, expand=True, fill=True) if self.context.get('group_by'): self.context['group_by'] = [self.context['group_by']] # the context to pass to default_get can be optionally specified in # the context of the one2many field. We also support a legacy # 'default_get' attribute for the same effect (pending removal) default_get_ctx = (attrs.get('default_get') or attrs.get('context')) self.screen = Screen(attrs['relation'], view_type=attrs.get('mode', 'tree,form').split(','), parent=self.parent, views_preload=attrs.get('views', {}), tree_saves=attrs.get('saves', False), create_new=True, context=self.context, row_activate=self._on_activate, default_get=default_get_ctx, window=self._window, readonly=self._readonly, limit=pager.DEFAULT_LIMIT) self.screen.type = 'one2many' self.pager = pager(object=self, relation=attrs['relation'], screen=self.screen) # Button New self.eb_new = self.pager.create_event_box(_('Create a new entry'), self._sig_new, 'gtk-new') hb.pack_start(self.eb_new, expand=False, fill=False) # Button Edit self.eb_open = self.pager.create_event_box(_('Edit this entry'), self._sig_edit, 'gtk-open') hb.pack_start(self.eb_open, expand=False, fill=False) # Button Delete self.eb_del = self.pager.create_event_box(_('Remove this entry'), self._sig_remove, 'gtk-delete') hb.pack_start(self.eb_del, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # Button Previous Page self.eb_prev_page = self.pager.create_event_box( _('Previous Page'), self._sig_prev_page, 'gtk-goto-first') hb.pack_start(self.eb_prev_page, expand=False, fill=False) # Button Previous Record self.eb_pre = self.pager.create_event_box(_('Previous Record'), self._sig_previous, 'gtk-go-back') hb.pack_start(self.eb_pre, expand=False, fill=False) # Record display self.label = gtk.Label('(0,0)') hb.pack_start(self.label, expand=False, fill=False) # Button Next self.eb_next = self.pager.create_event_box(_('Next Record'), self._sig_next, 'gtk-go-forward') hb.pack_start(self.eb_next, expand=False, fill=False) # Button Next Page self.eb_next_page = self.pager.create_event_box( _('Next Page'), self._sig_next_page, 'gtk-goto-last') hb.pack_start(self.eb_next_page, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # Button Switch self.eb_switch = self.pager.create_event_box(_('Switch'), self.switch_view, 'gtk-justify-left') hb.pack_start(self.eb_switch, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # Limit Combo self.cb = self.pager.create_combo_box(_('Choose Limit'), self.limit_changed) hb.pack_start(self.cb, expand=False, fill=False) self.widget.pack_start(hb, expand=False, fill=True) self.screen.signal_connect(self, 'record-message', self._sig_label) menuitem_title.get_child().set_markup( '<b>' + self.screen.current_view.title.replace('&', '&').replace( '<', '<').replace('>', '>') + '</b>') self.widget.pack_start(self.screen.widget, expand=True, fill=True) self.screen.widget.connect('key_press_event', self.on_keypress) self.model = None self.model_field = None self.name = attrs['name']
class win_search(object): def __init__(self, model, sel_multi=True, ids=[], context={}, domain=[], parent=None): self.model = model self.first = True self.domain = domain self.context = context self.context.update(rpc.session.context) self.sel_multi = sel_multi self.glade = glade.XML(common.terp_path("openerp.glade"), 'win_search', gettext.textdomain()) self.win = self.glade.get_widget('win_search') self.win.set_icon(common.OPENERP_ICON) if not parent: parent = service.LocalService('gui.main').window self.parent = parent self.win.set_transient_for(parent) self.screen = Screen(model, view_type=['tree'], context=self.context, parent=self.win) self.view = self.screen.current_view self.view.unset_editable() sel = self.view.widget_tree.get_selection() if not sel_multi: sel.set_mode('single') else: sel.set_mode(gtk.SELECTION_MULTIPLE) vp = gtk.Viewport() vp.set_shadow_type(gtk.SHADOW_NONE) vp.add(self.screen.widget) sw = self.glade.get_widget('search_sw') sw.add(vp) sw.show_all() self.view.widget_tree.connect('row_activated', self.sig_activate) self.view.widget_tree.connect('button_press_event', self.sig_button) self.model_name = model view_form = rpc.session.rpc_exec_auth('/object', 'execute', self.model_name, 'fields_view_get', False, 'form', self.context) self.form = widget_search.form(view_form['arch'], view_form['fields'], model, parent=self.win) self.title = _('OpenERP Search: %s') % self.form.name self.title_results = _( 'OpenERP Search: %s (%%d result(s))') % self.form.name self.win.set_title(self.title) x, y = self.form.widget.size_request() hbox = self.glade.get_widget('search_hbox') hbox.pack_start(self.form.widget) self.ids = ids if self.ids: self.reload() self.old_search = None self.old_offset = self.old_limit = None if self.ids: self.old_search = [] self.old_limit = self.form.get_limit() self.old_offset = self.form.get_offset() self.view.widget.show_all() if self.form.focusable: self.form.focusable.grab_focus() def sig_activate(self, treeview, path, column, *args): self.view.widget_tree.emit_stop_by_name('row_activated') if not self.sel_multi: self.win.response(gtk.RESPONSE_OK) return False def sig_button(self, view, event): if event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS: self.win.response(gtk.RESPONSE_OK) return False def find(self, widget=None, *args): limit = self.form.get_limit() offset = self.form.get_offset() if (self.old_search == self.form.value) and ( self.old_limit == limit) and (self.old_offset == offset) and not self.first: self.win.response(gtk.RESPONSE_OK) return False self.first = False self.old_offset = offset self.old_limit = limit v = self.form.value v_keys = map(lambda x: x[0], v) v += self.domain try: self.ids = rpc.session.rpc_exec_auth_try('/object', 'execute', self.model_name, 'search', v, offset, limit, 0, self.context) except: # Try if it is not an old server self.ids = rpc.session.rpc_exec_auth('/object', 'execute', self.model_name, 'search', v, offset, limit) self.reload() self.old_search = self.form.value self.win.set_title(self.title_results % len(self.ids)) return True def reload(self): self.screen.clear() self.screen.load(self.ids) sel = self.view.widget_tree.get_selection() if sel.get_mode() == gtk.SELECTION_MULTIPLE: sel.select_all() def sel_ids_get(self): return self.screen.sel_ids_get() def destroy(self): self.parent.present() self.win.destroy() def go(self): end = False while not end: button = self.win.run() if button == gtk.RESPONSE_OK: res = self.sel_ids_get() or self.ids end = True elif button == gtk.RESPONSE_APPLY: end = not self.find() if end: res = self.sel_ids_get() or self.ids else: res = None end = True self.destroy() if button == gtk.RESPONSE_ACCEPT: dia = dialog(self.model, window=self.parent, domain=self.domain, context=self.context) id = dia.run() res = id and [id] or None dia.destroy() return res
def __init__(self, window, parent, model, attrs={}): interface.widget_interface.__init__(self, window, parent, model, attrs) self.widget = gtk.VBox(homogeneous=False, spacing=1) hb = gtk.HBox(homogeneous=False, spacing=3) self.wid_text = gtk.Entry() self.wid_text.set_property('width_chars', 13) self.wid_text.connect('activate', self._sig_activate) self.wid_text.connect('populate-popup', self._menu_open) hb.pack_start(self.wid_text, expand=True, fill=True) hb.pack_start(gtk.VSeparator(), padding=2, expand=False, fill=False) self.wid_but_add = gtk.Button(stock='gtk-add') self.wid_but_add.set_relief(gtk.RELIEF_HALF) self.wid_but_add.set_focus_on_click(True) self.wid_but_add.connect('clicked', self._sig_add) hb.pack_start(self.wid_but_add, padding=3, expand=False, fill=False) self.wid_but_remove = gtk.Button(stock='gtk-remove') self.wid_but_remove.set_relief(gtk.RELIEF_HALF) self.wid_but_remove.set_focus_on_click(True) self.wid_but_remove.connect('clicked', self._sig_remove) hb.pack_start(self.wid_but_remove, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) self.context = tools.expr_eval(attrs.get('context',"{}")) self.screen = Screen(attrs['relation'], view_type=['tree'], views_preload=attrs.get('views', {}), row_activate=self.row_activate, limit=pager.DEFAULT_LIMIT, context=self.context) self.screen.signal_connect(self, 'record-message', self._sig_label) self.screen.type = 'many2many' self.model = None self.model_field = None self.name = attrs['name'] self.pager = pager(object=self, relation=attrs['relation'], screen=self.screen) # Button Previous Page self.eb_prev_page = self.pager.create_event_box(_('Previous Page'), self._sig_prev_page, 'gtk-goto-first') hb.pack_start(self.eb_prev_page, expand=False, fill=False) # Button Previous Record self.eb_pre = self.pager.create_event_box(_('Previous Record'), self._sig_previous, 'gtk-go-back') hb.pack_start(self.eb_pre, expand=False, fill=False) # Record display self.label = gtk.Label('(0,0)') hb.pack_start(self.label, expand=False, fill=False) # Button Next self.eb_next = self.pager.create_event_box(_('Next Record'), self._sig_next, 'gtk-go-forward') hb.pack_start(self.eb_next, expand=False, fill=False) # Button Next Page self.eb_next_page = self.pager.create_event_box(_('Next Page'), self._sig_next_page, 'gtk-goto-last') hb.pack_start(self.eb_next_page, expand=False, fill=False) hb.pack_start(gtk.VSeparator(), expand=False, fill=True) # LIMIT COMBO self.cb = self.pager.create_combo_box(_('Choose Limit'), self.limit_changed) hb.pack_start(self.cb, expand=False, fill=False) self.widget.pack_start(hb, expand=False, fill=False) self.widget.pack_start(gtk.HSeparator(), expand=False, fill=True) scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scroll.set_property('height-request', 200) scroll.set_placement(gtk.CORNER_TOP_LEFT) scroll.set_shadow_type(gtk.SHADOW_NONE) scroll.add_with_viewport(self.screen.widget) self.widget.pack_start(scroll, expand=True, fill=True)
def __init__(self, model, sel_multi=True, ids=[], context={}, domain=[], parent=None): self.model = model self.first = True self.domain = domain self.context = context self.context.update(rpc.session.context) self.sel_multi = sel_multi self.glade = glade.XML(common.terp_path("openerp.glade"), 'win_search', gettext.textdomain()) self.win = self.glade.get_widget('win_search') self.win.set_icon(common.OPENERP_ICON) if not parent: parent = service.LocalService('gui.main').window self.parent = parent self.win.set_transient_for(parent) self.screen = Screen(model, view_type=['tree'], context=self.context, parent=self.win) self.view = self.screen.current_view self.view.unset_editable() sel = self.view.widget_tree.get_selection() if not sel_multi: sel.set_mode('single') else: sel.set_mode(gtk.SELECTION_MULTIPLE) vp = gtk.Viewport() vp.set_shadow_type(gtk.SHADOW_NONE) vp.add(self.screen.widget) sw = self.glade.get_widget('search_sw') sw.add(vp) sw.show_all() self.view.widget_tree.connect('row_activated', self.sig_activate) self.view.widget_tree.connect('button_press_event', self.sig_button) self.model_name = model view_form = rpc.session.rpc_exec_auth('/object', 'execute', self.model_name, 'fields_view_get', False, 'form', self.context) self.form = widget_search.form(view_form['arch'], view_form['fields'], model, parent=self.win) self.title = _('OpenERP Search: %s') % self.form.name self.title_results = _( 'OpenERP Search: %s (%%d result(s))') % self.form.name self.win.set_title(self.title) x, y = self.form.widget.size_request() hbox = self.glade.get_widget('search_hbox') hbox.pack_start(self.form.widget) self.ids = ids if self.ids: self.reload() self.old_search = None self.old_offset = self.old_limit = None if self.ids: self.old_search = [] self.old_limit = self.form.get_limit() self.old_offset = self.form.get_offset() self.view.widget.show_all() if self.form.focusable: self.form.focusable.grab_focus()