示例#1
0
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
示例#2
0
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
示例#3
0
文件: form.py 项目: gisce/erpclient
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)