def trigger_onUpdating(self,record_data,old_record=None): if old_record['rec_type'] == 'AC' and record_data['rec_type'] == 'AN': #closing action record_data['done_user_id'] = self.db.currentEnv.get('user_id') record_data['done_ts'] = datetime.datetime.now(pytz.utc) record_data['annotation_date'] = record_data['done_ts'].date() record_data['annotation_time'] = record_data['done_ts'].time() confirmed_type_id = self.db.table('orgn.annotation_type').sysRecord('ACT_CONFIRMED')['id'] rescheduled_type_id = self.db.table('orgn.annotation_type').sysRecord('ACT_RESCHEDULED')['id'] if record_data['annotation_type_id'] == rescheduled_type_id: rescheduling = record_data.pop('rescheduling',None) if rescheduling: rescheduled_action = self.record(pkey=record_data['id']).output('dict') rescheduling.update(dictExtract(rescheduled_action,'le_',slice_prefix=False)) rescheduling.update(dictExtract(rescheduled_action,'linked_',slice_prefix=False)) rescheduling['date_due'] = rescheduling['date_due'] or rescheduled_action['date_due'] rescheduling['time_due'] = rescheduling['time_due'] or rescheduled_action['time_due'] rescheduling['assigned_tag'] = rescheduling['assigned_tag'] or rescheduled_action['assigned_tag'] rescheduling['assigned_user_id'] = rescheduling['assigned_user_id'] or rescheduled_action['assigned_user_id'] self.insert(rescheduling) elif record_data['annotation_type_id'] == confirmed_type_id and record_data.pop('outcome_id',None): next_action = record_data.pop('next_action',None) if next_action: followed_action = self.record(pkey=record_data['id']).output('dict') next_action['rec_type'] = 'AC' next_action['priority'] = next_action['priority'] or 'L' next_action.update(dictExtract(followed_action,'le_',slice_prefix=False)) next_action.update(dictExtract(followed_action,'linked_',slice_prefix=False)) next_action['parent_annotation_id'] = record_data['id'] self.insert(next_action) #if outcome_id: if self.fieldsChanged('annotation_date,annotation_time',record_data,old_record): self.setAnnotationTs(record_data)
def df_makeDynamicField(self,fb,tag=None,wdg_attr=None,data_type=None,fields=None,dbstore_kwargs=None,fieldPrefix=None,df_is_new=None,**kwargs): mask = wdg_attr.pop('field_mask',None) if tag.endswith('_nopopup'): tag = tag.replace('_nopopup','') wdg_attr['popup'] = False wdg_attr['tag'] =tag #wdg_attr['colspan'] = col_max if data_type == 'TL' else 1 code = wdg_attr.get('code') description = wdg_attr.pop('description','') fieldPrefix = fieldPrefix or '.' wdg_attr['value']='^%s%s' %(fieldPrefix,code) if tag.lower() in ('checkbox' or 'radiobutton'): wdg_attr['label'] = description else: wdg_attr['lbl'] = description wdg_attr['ghost'] = wdg_attr.pop('field_placeholder',None) wdg_attr['tip'] = wdg_attr.pop('field_tip',None) wdg_attr['style'] = wdg_attr.pop('field_style',None) wdg_attr['format'] = wdg_attr.pop('field_format',None) wdg_attr['dtype'] = data_type wdg_attr['mask'] = mask wdg_attr['colspan'] = 1 wdg_kwargs = wdg_attr.pop('wdg_kwargs',None) if wdg_kwargs: if isinstance(wdg_kwargs,basestring): wdg_kwargs = Bag(wdg_kwargs) wdg_kwargs = wdg_kwargs.asDict(ascii=True) wdg_attr.update(wdg_kwargs) for dim in ('height','width','crop_height','crop_width'): c = wdg_attr.pop(dim, None) if isinstance(c,int) or (c and c.isdigit()): wdg_attr[dim] = '%spx' %c if c else None else: wdg_attr[dim] = c wdg_attr['colspan'] = wdg_attr.pop('colspan',1) or 1 if tag.lower()=='simpletextarea': wdg_attr.setdefault('speech',True) wdg_attr['width'] = wdg_attr.get('width') or '94%' customizer = getattr(self,'df_%(tag)s' %wdg_attr,None) if customizer: customizer(wdg_attr,dbstore_kwargs=dbstore_kwargs) dictExtract(wdg_attr,'source_',pop=True) self._df_handleFieldFormula(wdg_attr,fb=fb,fields=fields,**kwargs) self._df_handleFieldValidation(wdg_attr,fields=fields) code = wdg_attr.pop('code') getter = wdg_attr.pop('getter',None) default_value = wdg_attr.pop('default_value',None) if default_value is not None and df_is_new: print 'SET setting default for ',code fb.data('.%s' %code,default_value) wdg = self.df_child(fb,**wdg_attr) if not getter: return wdg if isinstance(getter,basestring): getter = Bag(getter) if getter['table']: self._df_handleGetter(fb,code=code,getter=getter)
def trigger_onUpdating(self, record_data, old_record=None): if old_record['rec_type'] == 'AC' and record_data['rec_type'] == 'AN': #closing action record_data['done_user_id'] = self.db.currentEnv.get('user_id') record_data['done_ts'] = datetime.datetime.now(pytz.utc) record_data['annotation_date'] = record_data['done_ts'].date() record_data['annotation_time'] = record_data['done_ts'].time() confirmed_type_id = self.db.table( 'orgn.annotation_type').sysRecord('ACT_CONFIRMED')['id'] rescheduled_type_id = self.db.table( 'orgn.annotation_type').sysRecord('ACT_RESCHEDULED')['id'] if record_data['annotation_type_id'] == rescheduled_type_id: rescheduling = record_data.pop('rescheduling', None) if rescheduling: rescheduled_action = self.record( pkey=record_data['id']).output('dict') rescheduling.update( dictExtract(rescheduled_action, 'le_', slice_prefix=False)) rescheduling.update( dictExtract(rescheduled_action, 'linked_', slice_prefix=False)) rescheduling['date_due'] = rescheduling[ 'date_due'] or rescheduled_action['date_due'] rescheduling['time_due'] = rescheduling[ 'time_due'] or rescheduled_action['time_due'] rescheduling['assigned_tag'] = rescheduling[ 'assigned_tag'] or rescheduled_action['assigned_tag'] rescheduling['assigned_user_id'] = rescheduling[ 'assigned_user_id'] or rescheduled_action[ 'assigned_user_id'] self.insert(rescheduling) elif record_data[ 'annotation_type_id'] == confirmed_type_id and record_data.pop( 'outcome_id', None): next_action = record_data.pop('next_action', None) if next_action: followed_action = self.record( pkey=record_data['id']).output('dict') next_action['rec_type'] = 'AC' next_action['priority'] = next_action['priority'] or 'L' next_action.update( dictExtract(followed_action, 'le_', slice_prefix=False)) next_action.update( dictExtract(followed_action, 'linked_', slice_prefix=False)) next_action['parent_annotation_id'] = record_data['id'] self.insert(next_action) #if outcome_id: if self.fieldsChanged('annotation_date,annotation_time', record_data, old_record): self.setAnnotationTs(record_data)
def _th_appendExternalForm(self,sc,formId=None,pars=None,columnslist=None,switchdict=None,storetable=None, caption_field=None,frameCode=None,switch=None): form_kwargs = dictExtract(pars,'form_',pop=True) default_kwargs = dictExtract(pars,'default_',pop=True) datapath = pars.pop('datapath','.forms.%s' %formId) switchValues = pars.pop('switchValues') table = pars.pop('table',None) or storetable pkeyColumn = pars.pop('pkeyColumn',None) or self.db.table(table).pkey if table!=storetable: columnslist.append('$%s' %pkeyColumn) joiner = self.db.table(table).model.getJoiner(storetable) fkey = joiner['many_relation'].split('.')[-1] else: fkey = pkeyColumn for c in switchValues.split(','): switchdict[c] = dict(formId=formId,pkeyColumn=pkeyColumn,fkey=fkey,default_kwargs=default_kwargs) form = sc.contentPane(pageName=formId,overflow='hidden').thFormHandler(table=table, formResource=pars.pop('formResource','Form'), formId=formId,datapath=datapath, **form_kwargs) form.dataController(""" if (pkey=='*newrecord*'){ var store = mainstack.getRelativeData('.store'); if(!store){ store = new gnr.GnrBag(); mainstack.setRelativeData('.store',store); } kw = {newrecord:true}; kw[caption_field] = data.attr.caption; fkey = fkey || '_newrecord_'; kw['_pkey'] = fkey; kw[switch_field] = data.getValue().getItem(switch_field); store.setItem(fkey,null,kw) } if(mainstack.form){ mainstack.form.childForms[code] = this.form; } mainstack.setRelativeData('.value',fkey); mainstack.setRelativeData('.selectedForm',fid); """, mainstack=sc,fid=formId,caption_field=caption_field, fkey='=#FORM.record.%s' %fkey,code=frameCode,switch_field=switch, formsubscribe_onLoaded=True) form.dataController(""" mainstack.setRelativeData('.value',fkey); mainstack.setRelativeData('.selectedForm',fid); """,formsubscribe_onCancel=True,mainstack=sc,fid=formId, fkey='=#FORM.record.%s' %fkey)
def df_makeDynamicFields(self,fb,fields=None,setInAttributes=None,**kwargs): dbstore_kwargs = dictExtract(kwargs,'dbstore_',pop=True) if not fields: return fieldPrefix = '.?' if setInAttributes else '.' for r in fields: fb.dynamicField(r,fields=fields,dbstore_kwargs=dbstore_kwargs,fieldPrefix=fieldPrefix,**kwargs)
def ht_remoteHtableViewStore(self, table=None, caption_field=None, condition=None, condition_kwargs=None, caption=None, dbstore=None, columns=None, related_kwargs=None, **kwargs): b = Bag() tblobj = self.db.table(table) caption = caption or tblobj.name_plural condition_kwargs = condition_kwargs or dict() condition_kwargs.update(dictExtract(kwargs, 'condition_')) v = TableHandlerTreeResolver(_page=self, table=table, caption_field=caption_field, condition=condition, dbstore=dbstore, columns=columns, related_kwargs=related_kwargs, condition_kwargs=condition_kwargs) b.setItem('root', v, caption=caption, child_count=1, pkey='', treeIdentifier='_root_') return b
def getRelatedChildren(self, parent_id=None): related_tblobj = self.db.table(self.related_kwargs['table']) result = [] if parent_id: related_kwargs = dict(self.related_kwargs) includeAlias = related_kwargs.pop('includeAlias', None) caption_field = self.relatedCaptionField columns = self.related_kwargs.get( 'columns') or '*,$%s' % caption_field relation_path = self.related_kwargs['path'] condition = self.related_kwargs.get('condition') condition_kwargs = dictExtract(related_kwargs, 'condition_') where = ' (%s=:pkey) ' % relation_path if includeAlias: tblobj = self.db.table(self.table) aliasTableName = '%s_alias' % tblobj.fullname aliasJoiner = related_tblobj.model.getJoiner(aliasTableName) aliasRelationName = aliasJoiner['relation_name'] mainJoiner = tblobj.model.getJoiner(aliasTableName) aliasFkey = mainJoiner.get('many_relation', '').split('.')[-1] where = "(%s) OR @%s.%s=:pkey" % (where, aliasRelationName, aliasFkey) if condition: where = '(%s) AND %s' % (where, condition) result = related_tblobj.query(where=where, columns=columns, _storename=self.dbstore, pkey=parent_id, **condition_kwargs).fetch() return result
def authenticate(self, username, **kwargs): result = self.application.db.query('adm.user', columns='*', where='$username = :user', user=username, limit=1).fetch() if result: user_record = dict(result[0]) kwargs['tags'] = user_record.pop('auth_tags') kwargs['pwd'] = user_record.pop('md5pwd') kwargs['status'] = user_record['status'] kwargs['email'] = user_record['email'] kwargs['firstname'] = user_record['firstname'] kwargs['lastname'] = user_record['lastname'] kwargs['user_id'] = user_record['id'] kwargs['locale'] = user_record['locale'] or self.application.config('default?client_locale') kwargs['user_name'] = '%s %s' % (user_record['firstname'], user_record['lastname']) kwargs.update(dictExtract(user_record, 'avatar_')) access_groups = self.db.table('adm.user_access_group').query(where='$user_id=:uid',uid=user_record['id'], columns='@access_group_code.allowed_ip AS allowed_ip').fetch() allowed_ip = set([]) for ag in access_groups: allowed_ip = allowed_ip.union(set(ag['allowed_ip'].split(',') if ag['allowed_ip'] else [])) if allowed_ip: kwargs['allowed_ip'] = ','.join(allowed_ip) return kwargs
def getRelatedChildren(self,parent_id=None): related_tblobj = self.db.table(self.related_kwargs['table']) result = [] if parent_id: related_kwargs = dict(self.related_kwargs) includeAlias = related_kwargs.pop('includeAlias', None) caption_field = self.relatedCaptionField columns = self.related_kwargs.get('columns') or '*,$%s' %caption_field relation_path = self.related_kwargs['path'] condition = self.related_kwargs.get('condition') condition_kwargs = dictExtract(related_kwargs,'condition_') where = ' (%s=:pkey) ' % relation_path if includeAlias: tblobj = self.db.table(self.table) aliasTableName = '%s_alias' %tblobj.fullname aliasJoiner = related_tblobj.model.getJoiner(aliasTableName) aliasRelationName = aliasJoiner['relation_name'] mainJoiner = tblobj.model.getJoiner(aliasTableName) aliasFkey = mainJoiner.get('many_relation','').split('.')[-1] where = "(%s) OR @%s.%s=:pkey"%(where, aliasRelationName, aliasFkey) if condition: where = '(%s) AND %s'%(where,condition) result = related_tblobj.query(where=where,columns=columns, _storename=self.dbstore, pkey=parent_id,**condition_kwargs).fetch() return result
def cb(cache=None,identifier=None,**kwargs): if identifier in cache: return cache[identifier],True result = tblobj.query(columns='*,$all_tags',where='$username = :user',user=username, limit=1).fetch() kwargs = dict() if result: user_record = dict(result[0]) kwargs['tags'] = user_record.pop('all_tags') kwargs['pwd'] = user_record.pop('md5pwd') kwargs['status'] = user_record['status'] kwargs['email'] = user_record['email'] kwargs['firstname'] = user_record['firstname'] kwargs['lastname'] = user_record['lastname'] kwargs['user_id'] = user_record['id'] kwargs['group_code'] = user_record['group_code'] kwargs['avatar_rootpage'] = user_record['avatar_rootpage'] kwargs['locale'] = user_record['locale'] or self.application.config('default?client_locale') kwargs['user_name'] = '%s %s' % (user_record['firstname'], user_record['lastname']) kwargs.update(dictExtract(user_record, 'avatar_')) access_groups = self.db.table('adm.user_access_group').query(where='$user_id=:uid',uid=user_record['id'], columns='@access_group_code.allowed_ip AS allowed_ip').fetch() allowed_ip = set([]) for ag in access_groups: allowed_ip = allowed_ip.union(set(ag['allowed_ip'].split(',') if ag['allowed_ip'] else [])) if allowed_ip: kwargs['allowed_ip'] = ','.join(allowed_ip) cache[identifier] = kwargs return kwargs,False
def init_options(self): self.siteconfig = self.get_config() options = self.options.__dict__ envopt = dictExtract(os.environ,'GNR_WSGI_OPT_') for option in options.keys(): if options.get(option, None) is None: # not specified on the command-line site_option = self.siteconfig['wsgi?%s' % option] self.options.__dict__[option] = site_option or wsgi_options.get(option) or envopt.get(option)
def th_slotbar_sections(self,parent,sections=None,condition=None,condition_kwargs=None,all_begin=None,all_end=None,**kwargs): inattr = parent.getInheritedAttributes() th_root = inattr['th_root'] pane = parent.div(datapath='.sections.%s' %sections) tblobj = self.db.table(inattr['table']) if sections in tblobj.model.columns and tblobj.column(sections).relatedTable() is not None: sectionslist = self._th_section_from_fkey(tblobj,sections,condition=condition,condition_kwargs=condition_kwargs,all_begin=all_begin,all_end=all_end) dflt = None multivalue = True variable_struct = False isMain = False mandatory = None depending_condition = False depending_condition_kwargs = dict() else: m = self._th_hook('sections_%s' %sections,mangler=th_root) sectionslist = m() dflt = getattr(m,'default',None) multivalue=getattr(m,'multivalue',False) isMain = getattr(m,'isMain',False) variable_struct = getattr(m,'variable_struct',False) mandatory=getattr(m,'mandatory',True) depending_condition = getattr(m,'_if',False) depending_condition_kwargs = dictExtract(dict(m.__dict__),'_if_') if not sectionslist: return sectionsBag = Bag() for i,kw in enumerate(sectionslist): sectionsBag.setItem(kw.get('code') or 'r_%i' %i,None,**kw) pane.data('.data',sectionsBag) if not dflt: dflt = sectionsBag.getNode('#0').label pane.data('.current',dflt) pane.data('.variable_struct',variable_struct) if multivalue and variable_struct: raise Exception('multivalue cannot be set with variable_struct') mb = pane.multiButton(items='^.data',value='^.current',multivalue=multivalue,mandatory=mandatory, disabled='^.#parent.parent.grid.loadingData',**kwargs) parent.dataController("""var enabled = depending_condition?funcApply('return '+depending_condition,_kwargs):true; genro.dom.toggleVisible(__mb,enabled) SET .%s.enabled = enabled; FIRE .#parent.#parent.sections_changed; """ %sections, __mb=mb,ss=sections,datapath='.sections', depending_condition=depending_condition,_onBuilt=True, **depending_condition_kwargs) pane.dataController(""" genro.assert(currentSection,'missing current section for sections %s') var sectionNode = sectionbag.getNode(currentSection); if(isMain){ FIRE .#parent.#parent.clearStore; SET .#parent.#parent.excludeDraft = !sectionNode.attr.includeDraft; } FIRE .#parent.#parent.sections_changed; """ %sections ,isMain=isMain,mb=mb,_onBuilt=True, currentSection='^.current',sectionbag='=.data', th_root=th_root)
def ht_remoteHtableViewStore(self,table=None,caption_field=None,condition=None, condition_kwargs=None,caption=None,dbstore=None,columns=None,related_kwargs=None,**kwargs): b = Bag() tblobj = self.db.table(table) caption = caption or tblobj.name_plural condition_kwargs = condition_kwargs or dict() condition_kwargs.update(dictExtract(kwargs,'condition_')) v = TableHandlerTreeResolver(_page=self,table=table,caption_field=caption_field,condition=condition,dbstore=dbstore,columns=columns,related_kwargs=related_kwargs, condition_kwargs=condition_kwargs) b.setItem('root',v,caption=caption,child_count=1,pkey='',treeIdentifier='_root_') return b
def authenticate(self, username, **kwargs): result = self.application.db.query('adm.user', columns='*', where='$username = :user AND $status != :waiting', user=username, waiting='wait', limit=1).fetch() if result: user_record = dict(result[0]) kwargs['tags'] = user_record.pop('auth_tags') kwargs['pwd'] = user_record.pop('md5pwd') kwargs['user_id'] = user_record['id'] kwargs['user_name'] = '%s %s' % (user_record['firstname'], user_record['lastname']) kwargs.update(dictExtract(user_record, 'avatar_')) return kwargs
def ivnew_adaptSlotbar(self, pane, label=None, slots=None, hasToolbar=False, **kwargs): assert not callable(label), "use the attachpoint .footer instead of" searchOn = kwargs.pop("searchOn", None) or kwargs.pop("filterOn", None) slots = slots.split(",") if slots else [] add_kw = dictExtract(kwargs, "add_", True, slice_prefix=False) del_kw = dictExtract(kwargs, "del_", True, slice_prefix=False) upd_kw = dictExtract(kwargs, "upd_", True, slice_prefix=False) tools_kw = dictExtract(kwargs, "tools_", True, slice_prefix=False) print_kw = dictExtract(kwargs, "print_", True, slice_prefix=False) export_kw = dictExtract(kwargs, "export_", True, slice_prefix=False) slotbarKwargs = dict() if label: slots.append("label") slotbarKwargs["label"] = label slots.append("*") if searchOn: slots.append("searchOn") for slot, kw in (("add", add_kw), ("del", del_kw), ("upd", upd_kw)): if kw: slots.append(slot) slotbarKwargs.update(kw) if slots: _class = "pbl_viewBoxLabel" if not hasToolbar else None slotbar = pane.slotBar( slots=",".join(slots), _class=_class, toolbar=hasToolbar, searchOn=searchOn, _attachname="slotbar", namespace="iv", **slotbarKwargs ) return kwargs
def ivnew_adaptSlotbar(self,pane,label=None,slots=None,hasToolbar=False,**kwargs): assert not callable(label), 'use the attachpoint .footer instead of' searchOn = kwargs.pop('searchOn',None) or kwargs.pop('filterOn',None) slots = slots.split(',') if slots else [] add_kw = dictExtract(kwargs,'add_',True,slice_prefix=False) del_kw = dictExtract(kwargs,'del_',True,slice_prefix=False) upd_kw = dictExtract(kwargs,'upd_',True,slice_prefix=False) tools_kw = dictExtract(kwargs,'tools_',True,slice_prefix=False) print_kw = dictExtract(kwargs,'print_',True,slice_prefix=False) export_kw = dictExtract(kwargs,'export_',True,slice_prefix=False) slotbarKwargs = dict() if label: slots.append('label') slotbarKwargs['label'] = label slots.append('*') if searchOn: slots.append('searchOn') for slot,kw in (('add',add_kw),('del',del_kw),('upd',upd_kw)): if kw: slots.append(slot) slotbarKwargs.update(kw) if slots: _class = 'pbl_viewBoxLabel' if not hasToolbar else None slotbar = pane.slotBar(slots=','.join(slots),_class=_class,toolbar=hasToolbar,searchOn=searchOn, _attachname='slotbar',namespace='iv',**slotbarKwargs) return kwargs
def rpc_upload_file(self, file_handle=None, uploadPath=None, uploaderId=None, **kwargs): site = self.page.site kwargs = site.parse_kwargs(kwargs) file_actions = dictExtract(kwargs, 'process_') or {} if not uploadPath: uploadPath = 'site:uploaded_files' if uploaderId: uploadPath = '%s/%s' % (uploadPath, uploaderId) if file_handle is None or uploadPath is None: return dest_dir = site.getStaticPath(uploadPath, autocreate=True) f = file_handle.file content = f.read() filename = file_handle.filename file_ext = os.path.splitext(filename)[1] file_path = site.getStaticPath(uploadPath, filename) file_url = site.getStaticUrl(uploadPath, filename) with file(file_path, 'wb') as outfile: outfile.write(content) action_results = dict() for action_name, action_params in file_actions.items(): if action_params == True: action_params = getattr(self.page, 'process_%s' % action_name)() command_name = action_params.pop('fileaction', None) if not command_name: continue action_runner = getattr(self.page, 'fileaction_%s' % command_name) if action_runner: for action_param in action_params: action_params[str(action_param)] = action_params.pop( action_param) action_results[action_name] = action_runner( file_url=file_url, file_path=file_path, file_ext=file_ext, action_name=action_name, **action_params) if uploaderId: handler = getattr(self.page, 'onUploading_%s' % uploaderId) if handler: return handler(file_url=file_url, file_path=file_path, file_ext=file_ext, action_results=action_results, **kwargs) return file_url
def sh_adaptKwargs(self, kwargs): if 'frameCode' in kwargs: return kwargs['frameCode'] = kwargs.get('nodeId') dialogPars = kwargs.pop('dialogPars', None) if dialogPars: kwargs['dialog_kwargs'] = dialogPars kwargs['default_kwargs'] = dictExtract(dialogPars, 'default_', slice_prefix=False, pop=True) if 'formCb' in dialogPars: kwargs['form_center_content'] = dialogPars.pop('formCb') if 'dlgPars' in dialogPars: dialogPars.update(dialogPars.pop('dlgPars'))
def df_makeDynamicFields(self, fb, fields=None, setInAttributes=None, **kwargs): dbstore_kwargs = dictExtract(kwargs, 'dbstore_', pop=True) if not fields: return fieldPrefix = '.?' if setInAttributes else '.' for r in fields: fb.dynamicField(r, fields=fields, dbstore_kwargs=dbstore_kwargs, fieldPrefix=fieldPrefix, **kwargs)
def getHierarchicalData(self, caption_field=None, condition=None, condition_kwargs=None, caption=None, dbstore=None, columns=None, related_kwargs=None, resolved=False, parent_id=None, root_id=None, alt_pkey_field=None, **kwargs): b = Bag() caption = caption or self.tblobj.name_plural condition_kwargs = condition_kwargs or dict() condition_kwargs.update(dictExtract(kwargs, 'condition_')) related_kwargs = related_kwargs or {} v = TableHandlerTreeResolver(_page=self, table=self.tblobj.fullname, caption_field=caption_field, condition=condition, dbstore=dbstore, columns=columns, related_kwargs=related_kwargs, condition_kwargs=condition_kwargs, root_id=root_id, parent_id=parent_id, alt_pkey_field=alt_pkey_field) b.setItem( 'root', v, caption=caption, child_count=1, pkey='', treeIdentifier='_root_', table=self.tblobj.fullname, search_method=self.tblobj.hierarchicalSearch, search_related_table=related_kwargs.get('table'), search_related_path=related_kwargs.get('path'), search_related_caption_field=related_kwargs.get('caption_field')) if resolved: def cb(self, *args, **kwargs): pass b.walk(cb, _mode='') return b
def th_slotbar_addrowmenu(self,pane,parameters=None,**kwargs): view = pane.parent.parent.parent grid = view.grid many = parameters['relation_field'] condition = parameters.get('condition') condition_kwargs = dictExtract(parameters,'condition_') unique = parameters.get('unique',False) cacheTime = parameters.get('cacheTime',-1) one = False maintable = pane.getInheritedAttributes()['table'] relation_tblobj = self.db.table(maintable).column(many).relatedTable().dbtable formNode = view.parentNode.attributeOwnerNode('formId') if formNode: formtblobj = self.db.table(formNode.attr.get('table')) oneJoiner = formtblobj.model.getJoiner(maintable) one = oneJoiner.get('many_relation').split('.')[-1] hiddenItemCb = None if unique: hiddenItemCb="""var excludelist = genro.wdgById('%s').getColumnValues('%s') return (dojo.indexOf(excludelist,item.pkey)>=0) """ %(grid.attributes.get('nodeId'),many) pane.menudiv(storepath='.picker_menu',iconClass='add_row',tip='!!Add', action='FIRE .grid.addrowmenu_%s = $1.pkey' %many, hiddenItemCb=hiddenItemCb,parentForm=True) pane.dataRemote('.picker_menu',self.th_addmenu_menucontent,dbtable=relation_tblobj.fullname,many=many,one=one, formpkey='=#FORM.pkey',cacheTime=cacheTime,condition=condition,condition_kwargs=condition_kwargs) method = getattr(relation_tblobj,'insertMenu',self._th_insertPicker) grid.dataController(""" var kw = {dropPkey:mainpkey,tbl:tbl,one:one,many:many}; kw.dragPkeys = [fkey]; kw['_sourceNode'] = this; if(grid.gridEditor && grid.gridEditor.editorPars){ var rows = []; dojo.forEach(kw.dragPkeys,function(fkey){ var r = {}; r[many] = fkey; rows.push(r); }); grid.gridEditor.addNewRows(rows); }else if(mainpkey){ genro.serverCall(rpcmethod,kw,function(){},null,'POST'); } """,fkey='^.addrowmenu_%s' %many ,mainpkey='=#FORM.pkey', rpcmethod=method,tbl=maintable, one=one,many=many,grid=grid.js_widget)
def newFunc(self,*args, **kwargs): if _adapter: adapter=getattr(self,_adapter) if adapter: adapter(kwargs) for extract_key,extract_value in extract_kwargs.items(): grp_key='%s_kwargs' %extract_key curr=kwargs.pop(grp_key,dict()) dfltExtract=dict(slice_prefix=True,pop=False) if extract_value is True: dfltExtract['pop']=True elif isinstance(extract_value,dict): dfltExtract.update(extract_value) curr.update(dictExtract(kwargs,'%s_' %extract_key,**dfltExtract)) kwargs[grp_key] = curr return func(self,*args,**kwargs)
def getHierarchicalData(self,caption_field=None,condition=None, condition_kwargs=None,caption=None, dbstore=None,columns=None,related_kwargs=None, resolved=False,parent_id=None,root_id=None,**kwargs): b = Bag() caption = caption or self.tblobj.name_plural condition_kwargs = condition_kwargs or dict() condition_kwargs.update(dictExtract(kwargs,'condition_')) v = TableHandlerTreeResolver(_page=self,table=self.tblobj.fullname,caption_field=caption_field,condition=condition,dbstore=dbstore,columns=columns,related_kwargs=related_kwargs, condition_kwargs=condition_kwargs,root_id=root_id,parent_id=parent_id) b.setItem('root',v,caption=caption,child_count=1,pkey='',treeIdentifier='_root_') if resolved: def cb(self,*args,**kwargs): pass b.walk(cb) return b
def getRelatedChildren(self,parent_id=None): related_tblobj = self.db.table(self.related_kwargs['table']) result = [] if parent_id: related_kwargs = dict(self.related_kwargs) caption_field = self.relatedCaptionField columns = self.related_kwargs.get('columns') or '*,$%s' %caption_field relation_path = self.related_kwargs['path'] condition = self.related_kwargs.get('condition') condition_kwargs = dictExtract(related_kwargs,'condition_') wherelist = [' (%s=:pkey) ' % relation_path] if condition: wherelist.append(condition) result = related_tblobj.query(where=' AND '.join(wherelist),columns=columns, _storename=self.dbstore, pkey=parent_id,**condition_kwargs).fetch() return result
def authenticate(self, username, **kwargs): result = self.application.db.query( 'adm.user', columns='*', where='$username = :user AND $status != :waiting', user=username, waiting='wait', limit=1).fetch() if result: user_record = dict(result[0]) kwargs['tags'] = user_record.pop('auth_tags') kwargs['pwd'] = user_record.pop('md5pwd') kwargs['user_id'] = user_record['id'] kwargs['user_name'] = '%s %s' % (user_record['firstname'], user_record['lastname']) kwargs.update(dictExtract(user_record, 'avatar_')) return kwargs
def lookupTablesDefaultStruct(self,struct): r = struct.view().rows() for k,v in struct.tblobj.model.columns.items(): attr = v.attributes if attr.get('counter'): r.fieldcell(k,hidden=True,counter=True) elif not (attr.get('_sysfield') or attr.get('dtype') == 'X'): condition = attr.get('condition') condition_kwargs = dict() if condition: condition_kwargs = dictExtract(attr,'condition_',slice_prefix=False) cell_edit = attr.setdefault('cell_edit',dict()) cell_edit['condition'] = condition cell_edit['condition_kwargs'] = condition_kwargs r.fieldcell(k,edit=attr['cell_edit'] if 'cell_edit' in attr else True) if '__syscode' in struct.tblobj.model.columns and self.application.checkResourcePermission('_DEV_,superadmin', self.userTags): r.fieldcell('__syscode',edit=True)
def authenticate(self, username, **kwargs): result = self.application.db.query('adm.user', columns='*', where='$username = :user', user=username, limit=1).fetch() if result: user_record = dict(result[0]) kwargs['tags'] = user_record.pop('auth_tags') kwargs['pwd'] = user_record.pop('md5pwd') kwargs['status'] = user_record['status'] kwargs['email'] = user_record['email'] kwargs['firstname'] = user_record['firstname'] kwargs['lastname'] = user_record['lastname'] kwargs['user_id'] = user_record['id'] kwargs['locale'] = user_record['locale'] or self.application.config('default?client_locale') kwargs['user_name'] = '%s %s' % (user_record['firstname'], user_record['lastname']) kwargs.update(dictExtract(user_record, 'avatar_')) return kwargs
def pyColumn_zoomlink(self,record=None,field=None): for colname,colobj in self.columns.items(): if colname.startswith('le_') and colobj.relatedTable().fullname == record['linked_table']: attr = colobj.attributes entity = record['linked_entity'] zoomPars = dictExtract(attr,'linked_%s_' %entity) zoomMode = zoomPars.get('zoomMode') title = None if zoomMode == 'page': title = '%s - %s' %(self.db.currentPage.getRemoteTranslation(self.db.table(record['linked_table']).name_long)['translation'], record['connected_description']) result = self.db.currentPage.zoomLink(table=record['linked_table'],pkey=record['linked_fkey'], formResource=zoomPars.get('formResource','Form'), caption=record['connected_description'], zoomMode=zoomMode, zoomUrl=zoomPars.get('zoomUrl'), title=title) return result
def fgr_slotbar_filterset(self,parent,filterset=None,cb=None,cb_kwargs=None, all_begin=None,all_end=None,include_inherited=False, multiButton=None,multivalue=None,mandatory=None,lbl=None,lbl_kwargs=None, frameCode=None,**kwargs): pane = parent.div(datapath='.grid.filterset.%s' %filterset) m = self.mangledHook('filterset_%s' %filterset,mangler=frameCode,defaultCb=False) filterlist = None if m: filterlist = m() dflt = getattr(m,'default',None) multivalue=getattr(m,'multivalue',True) mandatory= getattr(m,'mandatory',False) multiButton = getattr(m,'multiButton',multiButton) lbl = lbl or getattr(m,'lbl',None) lbl_kwargs = lbl_kwargs or dictExtract(dict(m.__dict__),'lbl_',slice_prefix=False) if filterlist: filtersetBag = Bag() dflt = [] for i,kw in enumerate(filterlist): code = kw.get('code') or 'r_%i' %i if kw.get('isDefault'): dflt.append(code) filtersetBag.setItem(code,None,**kw) pane.data('.data',filtersetBag) pane.data('.current',','.join(dflt) if dflt else None) multiButton = multiButton is True or multiButton is None or multiButton and len(filtersetBag)<=multiButton if multiButton: mb = pane.multiButton(items='^.data',value='^.current',multivalue=multivalue,mandatory=mandatory, disabled='^.#parent.#parent.loadingData',**kwargs) else: mb = pane.formbuilder(cols=1,border_spacing='3px',**lbl_kwargs) lbl = lbl or filterset.capitalize() if multivalue: mb.checkBoxText(values='^.data',value='^.current',lbl=lbl, labelAttribute='caption',parentForm=False, disabled='^.#parent.#parent.loadingData', popup=True,cols=1) else: mb.filteringSelect(storepath='.data',value='^.current',lbl=lbl, disabled='^.#parent.#parent.loadingData', storeid='#k',parentForm=False, validate_notnull=mandatory, popup=True,cols=1)
def ht_hviewTree(self,box,table=None,picker=None,_class=None,**kwargs): if picker: bar = box.slotToolbar('*,treePicker,2',height='20px') pane = box.div(position='relative',height='100%').div(position='absolute',top='2px',left='2px',right='2px',bottom='2px',overflow='auto') tree = pane.hTableTree(table=table,childname='htree', onDrag="""var sn = dragInfo.sourceNode; if(sn.form.isNewRecord() || sn.form.locked ){return false;}""", selected_pkey='.tree.pkey', selected_hierarchical_pkey='.tree.hierarchical_pkey', selectedPath='.tree.path',margin='2px',_class=_class,**kwargs) if picker: picker_kwargs = dictExtract(kwargs,'picker_') picker_table = self.db.table(table).column(picker).relatedTable().dbtable.fullname paletteCode = 'picker_%s' %picker_table.replace('.','_') picker_kwargs['paletteCode'] = paletteCode bar.treePicker.palettePicker(table=picker_table,autoInsert=False,multiSelect=False,**picker_kwargs) tree.attributes['onDrop_%s' %paletteCode] = "THTree.onPickerDrop(this,data,dropInfo,{type_field:'%s',maintable:'%s',typetable:'%s'});" %(picker,table,picker_table) return tree
def getHierarchicalData(self,caption_field=None,condition=None, condition_kwargs=None,caption=None, dbstore=None,columns=None,related_kwargs=None, resolved=False,parent_id=None,root_id=None,alt_pkey_field=None,**kwargs): b = Bag() caption = caption or self.tblobj.name_plural condition_kwargs = condition_kwargs or dict() condition_kwargs.update(dictExtract(kwargs,'condition_')) related_kwargs = related_kwargs or {} v = TableHandlerTreeResolver(_page=self,table=self.tblobj.fullname,caption_field=caption_field,condition=condition,dbstore=dbstore,columns=columns,related_kwargs=related_kwargs, condition_kwargs=condition_kwargs,root_id=root_id,parent_id=parent_id,alt_pkey_field=alt_pkey_field) b.setItem('root',v,caption=caption,child_count=1,pkey='',treeIdentifier='_root_',table=self.tblobj.fullname, search_method=self.tblobj.hierarchicalSearch,search_related_table=related_kwargs.get('table'), search_related_path=related_kwargs.get('path'),search_related_caption_field=related_kwargs.get('caption_field')) if resolved: def cb(self,*args,**kwargs): pass b.walk(cb,_mode='') return b
def ht_hviewTree(self,box,table=None,picker=None,_class=None,**kwargs): pane = box.div(height='100%').div(position='absolute',top='2px',left='2px',right='2px',bottom='2px',overflow='auto') if picker: bar = pane.slotToolbar('*,treePicker,2',height='20px') tree = pane.hTableTree(table=table,childname='htree', onDrag="""var sn = dragInfo.sourceNode; if(sn.widget._filteringValue || sn.form.isNewRecord() || sn.form.locked ){return false;}""", selected_pkey='.tree.pkey', selected_hierarchical_pkey='.tree.hierarchical_pkey', selectedPath='.tree.path',margin='2px',_class=_class,**kwargs) if picker: picker_kwargs = dictExtract(kwargs,'picker_') picker_table = self.db.table(table).column(picker).relatedTable().dbtable.fullname paletteCode = 'picker_%s' %picker_table.replace('.','_') picker_kwargs['paletteCode'] = paletteCode bar.treePicker.palettePicker(table=picker_table,autoInsert=False,multiSelect=False,picker_kwargs=picker_kwargs,dockButton=dict(parentForm=False,iconClass='iconbox app')) tree.attributes['onDrop_%s' %paletteCode] = "THTree.onPickerDrop(this,data,dropInfo,{type_field:'%s',maintable:'%s',typetable:'%s'});" %(picker,table,picker_table) return tree
def getRelatedChildren(self, parent_id=None): related_tblobj = self.db.table(self.related_kwargs['table']) result = [] if parent_id: related_kwargs = dict(self.related_kwargs) caption_field = self.relatedCaptionField columns = self.related_kwargs.get( 'columns') or '*,$%s' % caption_field relation_path = self.related_kwargs['path'] condition = self.related_kwargs.get('condition') condition_kwargs = dictExtract(related_kwargs, 'condition_') wherelist = [' (%s=:pkey) ' % relation_path] if condition: wherelist.append(condition) result = related_tblobj.query(where=' AND '.join(wherelist), columns=columns, _storename=self.dbstore, pkey=parent_id, **condition_kwargs).fetch() return result
def authenticate(self, username, **kwargs): result = self.application.db.query('adm.user', columns='*', where='$username = :user', user=username, limit=1).fetch() if result: user_record = dict(result[0]) kwargs['tags'] = user_record.pop('auth_tags') kwargs['pwd'] = user_record.pop('md5pwd') kwargs['status'] = user_record['status'] kwargs['email'] = user_record['email'] kwargs['firstname'] = user_record['firstname'] kwargs['lastname'] = user_record['lastname'] kwargs['user_id'] = user_record['id'] kwargs['locale'] = user_record[ 'locale'] or self.application.config('default?client_locale') kwargs['user_name'] = '%s %s' % (user_record['firstname'], user_record['lastname']) kwargs.update(dictExtract(user_record, 'avatar_')) return kwargs
def lookupTablesDefaultStruct(self, struct): r = struct.view().rows() for k, v in struct.tblobj.model.columns.items(): attr = v.attributes if attr.get('counter'): r.fieldcell(k, hidden=True, counter=True) elif not (attr.get('_sysfield') or attr.get('dtype') == 'X'): condition = attr.get('condition') condition_kwargs = dict() if condition: condition_kwargs = dictExtract(attr, 'condition_', slice_prefix=False) cell_edit = attr.setdefault('cell_edit', dict()) cell_edit['condition'] = condition cell_edit['condition_kwargs'] = condition_kwargs r.fieldcell( k, edit=attr['cell_edit'] if 'cell_edit' in attr else True) if '__syscode' in struct.tblobj.model.columns and self.application.checkResourcePermission( '_DEV_,superadmin', self.userTags): r.fieldcell('__syscode', edit=True)
def ht_hdbselect(self,pane,caption_field=None,treeMode=None,folderSelectable=False,cacheTime=None,connectedMenu=None,tree_kwargs=None,**kwargs): dbselect = pane.dbselect(**kwargs) attr = dbselect.attributes dbselect_condition = attr.get('condition') dbselect_condition_kwargs = dictExtract(attr,'condition_') if not folderSelectable: attr['condition'] = '$child_count=0' if not dbselect_condition else ' ( %s ) AND $child_count=0' %dbselect_condition attr['hasDownArrow'] = True attr['_hdbselect'] = True dbselect_nodeId = attr.get('nodeId') or str(id(dbselect)) connectedMenu = connectedMenu or 'hmenu_%s' %dbselect_nodeId currentHMenu = self.workspace.setdefault('hmenu',{}) if connectedMenu not in currentHMenu: tree_kwargs['openOnClick'] = not folderSelectable tree_kwargs['selected_pkey'] = kwargs.get('value').replace('^','') menupath = 'gnr.htablestores.%s_%s' %(attr['dbtable'],connectedMenu) dbselect.treemenu(storepath=menupath,table=attr['dbtable'],condition=dbselect_condition, condition_kwargs=dbselect_condition_kwargs,modifiers='*', caption_field=caption_field,cacheTime=cacheTime, menuId=connectedMenu,dbstore=kwargs.get('_storename'),**tree_kwargs) currentHMenu[connectedMenu] = currentHMenu attr['connectedMenu'] = connectedMenu
def ht_hdbselect(self, pane, caption_field=None, treeMode=None, folderSelectable=False, cacheTime=None, connectedMenu=None, tree_kwargs=None, **kwargs): dbselect = pane.dbselect(**kwargs) attr = dbselect.attributes dbselect_condition = attr.get('condition') dbselect_condition_kwargs = dictExtract(attr, 'condition_') if not folderSelectable: attr[ 'condition'] = '$child_count=0' if not dbselect_condition else ' ( %s ) AND $child_count=0' % dbselect_condition attr['hasDownArrow'] = True attr['_hdbselect'] = True dbselect_nodeId = attr.get('nodeId') or str(id(dbselect)) connectedMenu = connectedMenu or 'hmenu_%s' % dbselect_nodeId currentHMenu = self.workspace.setdefault('hmenu', {}) if not connectedMenu in currentHMenu: tree_kwargs['openOnClick'] = not folderSelectable tree_kwargs['selected_pkey'] = kwargs.get('value').replace('^', '') menupath = 'gnr.htablestores.%s_%s' % (attr['dbtable'], connectedMenu) dbselect.treemenu(storepath=menupath, table=attr['dbtable'], condition=dbselect_condition, condition_kwargs=dbselect_condition_kwargs, modifiers='*', caption_field=caption_field, cacheTime=cacheTime, menuId=connectedMenu, dbstore=kwargs.get('_storename'), **tree_kwargs) currentHMenu[connectedMenu] = currentHMenu attr['connectedMenu'] = connectedMenu
def rpc_upload_file(self, file_handle=None, uploadPath=None, uploaderId=None, **kwargs): site = self.page.site kwargs = site.parse_kwargs(kwargs) file_actions = dictExtract(kwargs, 'process_') or {} if not uploadPath: uploadPath = 'site:uploaded_files' if uploaderId: uploadPath = '%s/%s' % (uploadPath, uploaderId) if file_handle is None or uploadPath is None: return dest_dir = site.getStaticPath(uploadPath, autocreate=True) f = file_handle.file content = f.read() filename = file_handle.filename file_ext = os.path.splitext(filename)[1] file_path = site.getStaticPath(uploadPath, filename) file_url = site.getStaticUrl(uploadPath, filename) with file(file_path, 'wb') as outfile: outfile.write(content) action_results = dict() for action_name, action_params in file_actions.items(): if action_params == True: action_params = getattr(self.page, 'process_%s' % action_name)() command_name = action_params.pop('fileaction', None) if not command_name: continue action_runner = getattr(self.page, 'fileaction_%s' % command_name) if action_runner: for action_param in action_params: action_params[str(action_param)] = action_params.pop(action_param) action_results[action_name] = action_runner(file_url=file_url, file_path=file_path, file_ext=file_ext, action_name=action_name, **action_params) if uploaderId: handler = getattr(self.page, 'onUploading_%s' % uploaderId) if handler: return handler(file_url=file_url, file_path=file_path, file_ext=file_ext, action_results=action_results, **kwargs) return file_url
def th_tableViewer(self,pane,frameCode=None,table=None,th_pkey=None,viewResource=None, virtualStore=None,condition=None,condition_kwargs=None,**kwargs): self._th_mixinResource(frameCode,table=table,resourceName=viewResource,defaultClass='View') options = self._th_hook('options',mangler=frameCode)() or dict() self._th_setDocumentation(table=table,resource = viewResource or 'View',doc=options.get('doc'), custdoc=options.get('custdoc')) resourceConditionPars = self._th_hook('condition',mangler=frameCode,dflt=dict())() resourceCondition = resourceConditionPars.pop('condition',None) if resourceCondition: condition = condition='( %s ) AND ( %s ) ' %(condition,resourceCondition) if condition else resourceCondition condition_kwargs.update(dictExtract(resourceConditionPars,'condition_')) view = pane.thFrameGrid(frameCode=frameCode,th_root=frameCode,th_pkey=th_pkey,table=table, virtualStore=virtualStore, condition=condition,condition_kwargs=condition_kwargs, **kwargs) for side in ('top','bottom','left','right'): hooks = self._th_hook(side,mangler=frameCode,asDict=True) for k in sorted(hooks.keys()): hooks[k](getattr(view,side)) viewhook = self._th_hook('view',mangler=frameCode) if viewhook: viewhook(view) return view
def pyColumn_zoomlink(self, record=None, field=None): for colname, colobj in self.columns.items(): if colname.startswith('le_') and colobj.relatedTable( ).fullname == record['linked_table']: attr = colobj.attributes entity = record['linked_entity'] zoomPars = dictExtract(attr, 'linked_%s_' % entity) zoomMode = zoomPars.get('zoomMode') title = None if zoomMode == 'page': title = '%s - %s' % ( self.db.currentPage.getRemoteTranslation( self.db.table(record['linked_table']).name_long) ['translation'], record['connected_description']) result = self.db.currentPage.zoomLink( table=record['linked_table'], pkey=record['linked_fkey'], formResource=zoomPars.get('formResource', 'Form'), caption=record['connected_description'], zoomMode=zoomMode, zoomUrl=zoomPars.get('zoomUrl'), title=title) return result
def df_makeDynamicField(self, fb, tag=None, wdg_attr=None, data_type=None, fields=None, dbstore_kwargs=None, fieldPrefix=None, df_is_new=None, **kwargs): mask = wdg_attr.pop('field_mask', None) if tag.endswith('_nopopup'): tag = tag.replace('_nopopup', '') wdg_attr['popup'] = False wdg_attr['tag'] = tag #wdg_attr['colspan'] = col_max if data_type == 'TL' else 1 code = wdg_attr.get('code') description = wdg_attr.pop('description', '') fieldPrefix = fieldPrefix or '.' wdg_attr['value'] = '^%s%s' % (fieldPrefix, code) if tag.lower() in ('checkbox' or 'radiobutton'): wdg_attr['label'] = description else: wdg_attr['lbl'] = description wdg_attr['ghost'] = wdg_attr.pop('field_placeholder', None) wdg_attr['tip'] = wdg_attr.pop('field_tip', None) wdg_attr['style'] = wdg_attr.pop('field_style', None) wdg_attr['format'] = wdg_attr.pop('field_format', None) wdg_attr['dtype'] = data_type wdg_attr['mask'] = mask wdg_attr['colspan'] = 1 wdg_kwargs = wdg_attr.pop('wdg_kwargs', None) if wdg_kwargs: if isinstance(wdg_kwargs, basestring): wdg_kwargs = Bag(wdg_kwargs) wdg_kwargs = wdg_kwargs.asDict(ascii=True) wdg_attr.update(wdg_kwargs) for dim in ('height', 'width', 'crop_height', 'crop_width'): c = wdg_attr.pop(dim, None) if isinstance(c, int) or (c and c.isdigit()): wdg_attr[dim] = '%spx' % c if c else None elif c is not None: wdg_attr[dim] = c wdg_attr['colspan'] = wdg_attr.pop('colspan', 1) or 1 if tag.lower() == 'simpletextarea': wdg_attr.setdefault('speech', True) wdg_attr['width'] = wdg_attr.get('width') or '94%' customizer = getattr(self, 'df_%(tag)s' % wdg_attr, None) if customizer: customizer(wdg_attr, dbstore_kwargs=dbstore_kwargs) dictExtract(wdg_attr, 'source_', pop=True) self._df_handleFieldFormula(wdg_attr, fb=fb, fields=fields, **kwargs) self._df_handleFieldValidation(wdg_attr, fields=fields) code = wdg_attr.pop('code') getter = wdg_attr.pop('getter', None) default_value = wdg_attr.pop('default_value', None) if default_value is not None and df_is_new: fb.data('.%s' % code, self.catalog.fromText(default_value, data_type)) wdg = self.df_child(fb, **wdg_attr) if not getter: return wdg if isinstance(getter, basestring): getter = Bag(getter) if getter['table']: self._df_handleGetter(fb, code=code, getter=getter)
def includedViewBox(self, parentBC, nodeId=None, table=None, datapath=None, storepath=None, selectionPars=None, formPars=None, label=None, caption=None, footer=None, add_action=None, add_class='buttonIcon icnBaseAdd', add_enable='^form.canWrite', del_action=None, del_class='buttonIcon icnBaseDelete', del_enable='^form.canWrite', upd_action=None, upd_class='buttonIcon icnBaseEdit', upd_enable='^form.canWrite', close_action=None, close_class='buttonIcon icnTabClose', print_action=None, print_class='buttonIcon icnBasePrinter', pdf_action=None, pdf_class='buttonIcon icnBasePdf', pdf_name=None, export_action=None, export_class='buttonIcon icnBaseExport', tools_action=None, tools_class='buttonIcon icnBaseAction', tools_enable='^form.canWrite', tools_lbl=None, lock_action=False, tools_menu=None, _onStart=False, filterOn=None, pickerPars=None, centerPaneCb=None, editorEnabled=None, parentLock='^status.locked', reloader=None, externalChanges=None, addOnCb=None, zoom=True, hasToolbar=False, canSort=True, configurable=None, dropCodes=None, **kwargs): """This method returns a grid (includedView) for viewing and selecting rows from a many to many table related to the main table, and it returns the widget that allows to edit data. You can edit data of a single row (record) using a form (formPars), or picking some rows from another table with the picker widget (pickerPars). The form can be contained inside a dialog or a contentPane and is useful to edit a single record. If the data is stored inside another table you should use the picker to select the rows from that table. :param parentBC: MANDATORY - parentBC is a :ref:`bordercontainer` .. note:: The includedViewBox and its sons can only accept the borderContainer layout container :param nodeId: the includedViewbox's Id. For more information, check :ref:`nodeid` page :param table: the :ref:`database table <table>` name on which the query will be executed, in the form ``packageName.tableName`` (packageName is the name of the :ref:`package <packages>` to which the table belongs to) :param datapath: allow to create a hierarchy of your data’s addresses into the datastore. For more information, check the :ref:`datapath` and the :ref:`datastore` pages :param storepath: the path of the data of the includedViewBox :param selectionPars: TODO **selectionPars parameters**: * applymethod: TODO * where: the sql "WHERE" clause. For more information check the :ref:`sql_where` section. :param formPars: (dict) it contains all the params of the widget who hosts the form. . **formPars parameters:** * mode: `dialog` / `pane` * height: the dialog's height * width: the dialog's width * formCb: MANDATORY - callback method used to create the form **formCb parameters:** * formBorderCont: a :ref:`bordercontainer` used as root for the formCb's construction. * datapath: allow to create a hierarchy of your data’s addresses into the datastore. For more information, check the :ref:`datapath` and the :ref:`datastore` pages. * region: 'center' of the pane/borderContainer where you place it into * toolbarHandler: OPTIONAL - a callback for the form toolbar * title: MANDATORY - for dialog mode * pane: OPTIONAL - pane of the form input :param label: (string) allow to create a label for the includedView :param caption: TODO :param footer: TODO :param add_action: (boolean) allow the insertion of a row in the includedView :param add_class: the css class of the add button :param add_enable: a path to enable/disable add action :param del_action: (boolean) allow the deleting of a row in the includedView :param del_class: the css class of the delete button :param del_enable: a path to enable/disable del action :param upd_action: TODO :param upd_class: TODO :param upd_enable: TODO :param close_action: (boolean) adding closing button in tooltipDialog :param close_class: css class of close button :param print_action: TODO :param print_class: TODO :param pdf_action: TODO :param pdf_class: TODO :param pdf_name: TODO :param export_action: TODO :param export_class: TODO :param tools_action: TODO :param tools_class: TODO :param tools_enable: TODO :param tools_lbl: TODO :param lock_action: an optional parameter; TODO :param tools_menu: TODO :param _onStart: boolean. If ``True``, the controller is executed only after that all the line codes are read :param filterOn: (boolean, only for picker) allow the filter into the picker grid :param pickerPars: (dict) it contains all the params of the tooltip dialog which host the picker grid **Parameters:** * height: height of the tooltipdialog * width: width of the tooltipdialog * label: label of the tooltipdialog * table: MANDATORY - the table of the picker grid. From this table you can pick a row for the many to many table you handle * columns: MANDATORY - columns of the picker grid * nodeId: MANDATORY - id for the picker * filterOn: the columns on which to apply filter :param centerPaneCb: TODO :param editorEnabled: TODO :param parentLock: TODO :param reloader: TODO :param externalChanges: TODO :param addOnCb: TODO :param zoom: It allows to open the linked record in a :ref:`dialog`. For further details, check the :ref:`zoom` documentation page :param hasToolbar: TODO :param canSort: TODO :param fromPicker_target_fields: allow to bind the picker's table. columns to the includedView columns of the many to many table. :param fromPicker_nodup_field: if this column value is present in the includedView it allows to replace that row instead of adding a duplicate row :param \*\*kwargs: **autowidth**, **storepath**, etc""" if storepath: assert not storepath.startswith('^') and not storepath.startswith('='),\ "storepath should be a plain datapath, no ^ or =" if not datapath: if storepath.startswith('.'): inherited_attributes = parentBC.parentNode.getInheritedAttributes() #assert inherited_attributes.has_key('sqlContextRoot'),\ #'please specify an absolute storepath, if sqlContextRoot is not available' #storepath = '%s%s' % (inherited_attributes['sqlContextRoot'], storepath) storepath = '#FORM.record%s' %storepath viewPars = dict(kwargs) gridId = nodeId or self.getUuid() viewPars['nodeId'] = gridId if dropCodes: for dropCode in dropCodes.split(','): mode = 'grid' if ':' in dropCode: dropCode, mode = dropCode.split(':') dropmode = 'dropTarget_%s' % mode viewPars[dropmode] = '%s,%s' % (viewPars[dropmode], dropCode) if dropmode in viewPars else dropCode viewPars['onDrop_%s' % dropCode] = 'FIRE .dropped_%s = data' % dropCode viewPars['onCreated'] = """dojo.connect(widget,'_onFocus',function(){genro.publish("show_palette_%s")})""" % dropCode #provo?si # controllerPath = datapath or 'grids.%s' % gridId storepath = storepath or '.selection' viewPars['storepath'] = storepath viewPars['controllerPath'] = controllerPath controller = parentBC.dataController(datapath=controllerPath) assert not 'selectedIndex' in viewPars viewPars['selectedIndex'] = '^.selectedIndex' assert not 'selectedLabel' in viewPars if not viewPars.get('selectedId'): viewPars['selectedId'] = '^.selectedId' viewPars['selectedLabel'] = '^.selectedLabel' label_pars = dict([(k[6:], kwargs.pop(k)) for k in kwargs.keys() if k.startswith('label_')]) label_pars['_class'] = label_pars.pop('class', None) or (not hasToolbar and 'pbl_viewBoxLabel') box_pars = dict([(k[4:], kwargs.pop(k)) for k in kwargs.keys() if k.startswith('box_')]) box_pars['_class'] = (box_pars.pop('class', None) or 'pbl_viewBox') if label is not False: gridtop = parentBC.contentPane(region='top', datapath=controllerPath, overflow='hidden',childname='top', nodeId='%s_top' % gridId, **label_pars) if hasToolbar is True: gridtop = gridtop.toolbar(_class='pbl_viewBoxToolbar') gridtop_left = gridtop.div(float='left') if callable(label): label(gridtop_left) else: gridtop_left.div(label, margin_top='2px', float='left') gridtop_right = gridtop.div(float='right',childname='right') if filterOn: gridtop_filter = gridtop_right.div(float='left', margin_right='5px') self.gridFilterBox(gridtop_filter, gridId=gridId, filterOn=filterOn, table=table) if print_action or export_action or tools_menu or tools_action or pdf_action: gridtop_actions = gridtop_right.div(float='left', margin_right='5px') self._iv_gridAction(gridtop_actions, print_action=print_action, export_action=export_action, export_class=export_class, print_class=print_class, tools_class=tools_class, tools_menu=tools_menu, tools_action=tools_action, pdf_action=pdf_action, pdf_class=pdf_class, pdf_name=pdf_name, table=table, gridId=gridId, tools_enable=tools_enable, tools_lbl=tools_lbl) if add_action or del_action or upd_action: gridtop_add_del = gridtop_right.div(float='left', margin_right='5px',childname='add_del') self._iv_gridAddDel(gridtop_add_del, add_action=add_action, del_action=del_action, upd_action=upd_action, upd_class=upd_class, upd_enable=upd_enable, add_class=add_class, add_enable=add_enable, del_class=del_class, del_enable=del_enable, pickerPars=pickerPars, formPars=formPars, gridId=gridId) if lock_action: gridtop_lock = gridtop_right.div(float='left', margin_right='5px') self._iv_gridLock(gridtop_lock, lock_action=lock_action) if footer: assert callable(footer), 'footer param must be a callable' footerPars = dict([(k[7:], v) for k, v in kwargs.items() if k.startswith('footer_')]) if not 'height' in footerPars: footerPars['height'] = '18px' if not '_class'in footerPars: footerPars['_class'] = 'pbl_roundedGroupBottom' gridbottom = parentBC.contentPane(region='bottom', datapath=controllerPath, **footerPars) footer(gridbottom) self._iv_IncludedViewController(controller, gridId, controllerPath, table=table) if centerPaneCb: gridcenter = getattr(self, centerPaneCb)(parentBC, region='center', datapath=controllerPath, **box_pars) else: gridcenter = parentBC.contentPane(region='center', datapath=controllerPath, **box_pars) viewPars['structpath'] = viewPars.get('structpath') or '.struct' or 'grids.%s.struct' % nodeId if filterOn is True: gridcenter.dataController("""var colsMenu = new gnr.GnrBag(); struct.forEach(function(n){ colsMenu.setItem(n.label, null, {col:n.attr.field, caption:n.attr.name}) }); SET .flt.colsMenu = colsMenu;""", struct='^%s.view_0.row_0' % viewPars['structpath']) if parentLock: gridcenter.dataFormula(".editorEnabled", "parentLock==null?false:!parentLock", parentLock=parentLock) elif parentLock is False: editorEnabled = True if caption: innerbc = gridcenter.borderContainer() caption_pars = dictExtract(viewPars, 'caption_', pop=True) innerbc.contentPane(region='top').div(caption, **caption_pars) gridcenter = innerbc.contentPane(region='center') view = gridcenter.includedView(extension='includedViewPicker', table=table, editorEnabled=editorEnabled or '^.editorEnabled', reloader=reloader, **viewPars) if addOnCb: addOnCb(gridcenter) if _onStart: controller.dataController("FIRE .reload", _onStart=True) if externalChanges: externalChangesTypes = '' if isinstance(externalChanges, basestring): if ':' in externalChanges: externalChanges, externalChangesTypes = externalChanges.split(':') if externalChanges == '*': externalChanges = True subscribed_tables = [t for t in getattr(self, 'subscribed_tables', '').split(',') if t] assert table in subscribed_tables, "table %s must be subscribed to get externalChanges" % table event_path = 'gnr.dbevent.%s' % table.replace('.', '_') pars = dict() conditions = list() if isinstance(externalChanges, basestring): for fld in externalChanges.split(','): fldname, fldpath = fld.split('=') conditions.append('genro.isEqual(curr_%s,event_%s)' % (fldname, fldname)) pars['event_%s' % fldname] = '=%s.%s' % (event_path, fldname) pars['curr_%s' % fldname] = '=%s' % fldpath if externalChangesTypes: conditions.append('evtypes.indexOf(evtype)>=0') pars['evtypes'] = externalChangesTypes pars['evtype'] = '=%s?dbevent' % event_path gridcenter.dataController("FIRE .reload;", _if=' && '.join(conditions), _fired='^%s' % event_path, **pars) if selectionPars: self._iv_includedViewSelection(gridcenter, gridId, table, storepath, selectionPars, controllerPath) if formPars: formPars.setdefault('pane', gridcenter) self._includedViewForm(controller, controllerPath, view, formPars) if pickerPars: pickerPars.setdefault('pane', gridcenter) self._iv_Picker(controller, controllerPath, view, pickerPars) return view
def ht_relatedTableHandler(self,tree,th,dropOnRoot=True, inherited=None,relation_kwargs=None): relation_table = relation_kwargs.pop('table',None) vstore = th.view.store vstoreattr = vstore.attributes grid = th.view.grid gridattr = grid.attributes maintable = tree.getInheritedAttributes()['table'] maintableobj = self.db.table(maintable) if inherited: bar = th.view.top.bar.replaceSlots('searchOn','showInherited,10,searchOn') bar.showInherited.checkbox(value='^.showInherited',label='!!Show Inherited', parentForm=False,label_color='#666') if not relation_table: tblalias = maintableobj.pkg.tables['%s_alias' %maintable.split('.')[1]] relation_table = tblalias.fullname if tblalias else '' dragTable = th.attributes['table'] fkey_name = vstoreattr.get('_fkey_name') assert fkey_name or relation_table, 'If there is no relation: relation_table is mandatory' fkey_name_alt = dictExtract(vstoreattr,'_fkey_name_') condlist = [] condpars = dict(suffix='/%%',curr_hpkey='=#FORM.record.hierarchical_pkey',showInherited='^.showInherited') hiddencolumns = gridattr['hiddencolumns'].split(',') if gridattr.get('hiddencolumns') else [] for k in relation_kwargs.keys(): altrelname = k.split('_')[0] #altrelname must not contain '_' if altrelname not in relation_kwargs: relation_kwargs[altrelname] = dictExtract(relation_kwargs,altrelname+'_',pop=True) for k,v in fkey_name_alt.items(): condlist.append(" $%s = :fkey " %v) if k in relation_kwargs: hiddencolumns.append("$%s" %v) relation_kwargs[k]['fkey_name'] = v assert relation_kwargs[k]['modifiers'],'Missing modifiers for handling alt relation %s' %k rel_fkey_name = False if fkey_name: hiddencolumns.append('@%s.hierarchical_pkey AS one_hpkey' %fkey_name) condlist.append("""( CASE WHEN :fkey IS NULL THEN $%s IS NULL ELSE (( :showInherited IS TRUE AND (@%s.hierarchical_pkey ILIKE (:curr_hpkey || :suffix)) ) OR ( $%s =:fkey ) ) END ) """ %(fkey_name,fkey_name,fkey_name)) vstoreattr['_if'] = None #remove the default _if vstoreattr['_else'] = None if relation_table: mainjoiner = maintableobj.model.getJoiner(relation_table) relatedjoiner = self.db.table(dragTable).model.getJoiner(relation_table) relation_name = relatedjoiner['relation_name'] rel_fkey_name = mainjoiner['many_relation'].split('.')[-1] condlist.append(""" ( ( @%s.%s =:fkey ) OR ( :showInherited IS TRUE AND ( @%s.@%s.hierarchical_pkey ILIKE (:curr_hpkey || :suffix) ) ) ) """ %(relation_name,rel_fkey_name,relation_name,rel_fkey_name)) hiddencolumns.append('@%s.@%s.hierarchical_pkey AS many_hpkey' %(relation_name,rel_fkey_name)) vstoreattr['condition'] = ' OR '.join(condlist) vstoreattr['fullReloadOnChange'] = True vstoreattr.update(condpars) dragCode = 'hrows_%s' %dragTable.replace('.','_') trashId = False if fkey_name and relation_table: trashId=str(id(tree)) tree.parent.div(_class='treeTrash',id=trashId,onCreated=""" var that = this; var c1 = dojo.connect(window,'dragend',function(){ genro.dom.removeClass(that,'treeShowTrash'); }); """,dropTarget=True,**{'onDrop_%s' %dragCode:""" genro.serverCall("ht_removeAliasRows",{aliastable:"%s",dragtable:'%s',fkeys:data.alias_pkeys}); """ %(relation_table,dragTable)}) gridattr.update(onDrag=""" if(!dragValues.gridrow){return;} var sourceNode = dragInfo.sourceNode; var curr_hfkey = sourceNode._curr_hfkey; var alt_relations = objectUpdate({},sourceNode.attr._th_alt_relations); var rows = dragValues.gridrow.rowset; var inherited_pkeys = []; var alias_pkeys = []; var pkeys = []; dojo.forEach(rows,function(r){ THTreeRelatedTableHandler.onRelatedRow(r,curr_hfkey,alt_relations); var pkey = r['_pkey']; if(r['_hieararchical_inherited']){ inherited_pkeys.push(pkey); } if(r['_alias_row']){ alias_pkeys.push(pkey); } var d = objectExtract(r,'_altrelation_*',true) if(objectNotEmpty(d)){ for(var k in d){ alt_relations[k]['pkeys'] = alt_relations[k]['pkeys'] || []; alt_relations[k]['pkeys'].push(pkey) } } pkeys.push(pkey); }); if(pkeys.length==alias_pkeys.length && inherited_pkeys.length==0 && !sourceNode.form.locked ){ dojo.addClass(dojo.byId(sourceNode.attr.trashId),'treeShowTrash'); } dragValues['%s'] = {pkeys:pkeys,inherited_pkeys:inherited_pkeys,alias_pkeys:alias_pkeys, alt_relations:alt_relations};""" %dragCode, rowCustomClassesCb="""function(row){ return THTreeRelatedTableHandler.onRelatedRow(row,this.sourceNode._curr_hfkey,this.sourceNode.attr._th_alt_relations); }""", hiddencolumns=','.join(hiddencolumns) if hiddencolumns else None,trashId=trashId, _th_alt_relations=relation_kwargs or False ) tree.dataController("grid._curr_hfkey = curr_hfkey;",grid=grid,tree=tree,curr_hfkey='^#FORM.record.hierarchical_pkey') treeattr = tree.attributes treeattr['dropTargetCb_%s' %dragCode]="""if(!data){ return true; } if(data['inherited_pkeys']!=null || data.alias_pkeys!=null){ return data.inherited_pkeys.length==0 && data.alias_pkeys.length==0; } return true; """ treeattr['onDrop_%s' %dragCode] = """ var relationValue = dropInfo.treeItem.attr.pkey || null; var relationRecord = dropInfo.treeItem.attr._record || null; var modifiers = dropInfo.modifiers; var alias_on_field = this.getRelativeData('#FORM.controller.table?alias_on_field'); var asAlias = (relationRecord && alias_on_field)?relationRecord[alias_on_field]:modifiers=="Shift" if(%s){ genro.serverCall('ht_updateRelatedRows',{table:'%s',fkey_name:'%s',pkeys:data.pkeys, relationValue:relationValue,modifiers:dropInfo.modifiers, asAlias:asAlias, relation_table:'%s',maintable:'%s',alt_relations:data.alt_relations},null,null,'POST'); }else{ return false; } """ %('relationValue' if not dropOnRoot else 'true',dragTable,fkey_name,relation_table,maintable)
def _th_applyOnForm(self,form,options=None,mangler=None): if not self.th_checkPermission(form): form.attributes['_notallowed'] = True parent = form.parent if hasattr(parent,'view'): th_attributes = parent.attributes th_class = th_attributes.get('_class') or '' th_attributes['_class'] = '%s th_form_not_allowed' %th_class table = form.getInheritedAttributes()['table'] form.dataController("""var title = newrecord?( newTitleTemplate? dataTemplate(newTitleTemplate,record): caption ): (titleTemplate? dataTemplate(titleTemplate,record) : tablename+': '+caption); SET #FORM.controller.title = title; this.form.publish('onChangedTitle',{title:title}); """, tablename=self.db.table(table).name_long, caption='=#FORM.record?caption', newrecord='=#FORM.record?_newrecord', record='=#FORM.record',titleTemplate=options.pop('titleTemplate',False), newTitleTemplate=options.pop('newTitleTemplate',False), _fired='^#FORM.controller.loaded') if form.attributes.get('form_isRootForm'): form.data('gnr.rootform.size',Bag(height=options.pop('dialog_height','500px'),width=options.pop('dialog_width','600px'))) if 'lazyBuild' in options: form.attributes['_lazyBuild'] = options.pop('lazyBuild') showtoolbar = boolean(options.pop('showtoolbar',True)) navigation = options.pop('navigation',None) hierarchical = options.pop('hierarchical',None) tree_kwargs = dictExtract(options,'tree_',pop=True) readOnly = options.pop('readOnly',False) modal = options.pop('modal',False) autoSave = options.pop('autoSave',False) draftIfInvalid= options.pop('draftIfInvalid',False) allowSaveInvalid= options.pop('allowSaveInvalid',draftIfInvalid) form_add = options.pop('form_add',True) form_delete = options.pop('form_delete',True) form.attributes.update(form_draftIfInvalid=draftIfInvalid,form_allowSaveInvalid=allowSaveInvalid) if autoSave: form.store.attributes.update(autoSave=autoSave) form.dataController(""" if(reason=='nochange' && modal){return;} genro.dlg.alert(msg+' '+this.form.getRecordCaption()+': '+(reason=='invalid'?invalid:nochange),titledialog);""", reason="^.controller.save_failed",_if='reason', titledialog='!!Save failed', msg='!!You cannot save', invalid='!!Invalid record', nochange='!!No change to save',modal=modal) box_kwargs = dictExtract(options,'box_',pop=True) extra_slots = [] if hierarchical: box_kwargs['sidebar'] = True box_kwargs['persist'] = True if box_kwargs: sidebar = box_kwargs.pop('sidebar') if sidebar: box_kwargs['design'] = 'sidebar' form.attributes.update(**box_kwargs) if form.store.attributes.get('storeType') == 'Collection': if navigation is not False: navigation = True if readOnly: form.attributes.update(form_readOnly=True) if options.get('saveOnChange'): form.attributes.update(form_saveOnChange=options.pop('saveOnChange')) showtoolbar = False if 'parentLock' in options: form.attributes.update(form_parentLock=options.pop('parentLock')) if modal: slots='revertbtn,*,cancel,savebtn' form.attributes['hasBottomMessage'] = False bar = form.bottom.slotBar(slots,margin_bottom='2px',_class='slotbar_dialog_footer') bar.revertbtn.button('!!Revert',action='this.form.publish("reload")',disabled='^.controller.changed?=!#v',hidden=readOnly) bar.cancel.button('!!Cancel',action='this.form.abort();') bar.savebtn.button('!!Save',iconClass='fh_semaphore',action='this.form.publish("save",{destPkey:"*dismiss*"})',hidden=readOnly) elif showtoolbar: default_slots = '*,semaphore,5' if readOnly else '*,form_delete,form_add,form_revert,form_save,semaphore,locker' if form_add is False: default_slots.replace('form_add','') if form_delete is False: default_slots.replace('form_delete','') if options.pop('duplicate',False): default_slots= default_slots.replace('form_add','form_add,form_duplicate') if hierarchical: default_slots = 'dismiss,hbreadcrumb,%s' %default_slots elif navigation: default_slots = 'navigation,%s' %default_slots elif options.pop('selector',False): default_slots = default_slots.replace('*','5,form_selectrecord,*') if options.pop('printMenu',False): #default_slots = default_slots.replace('form_delete','form_print,100,form_delete') extra_slots.append('form_print') if options.pop('copypaste',False): extra_slots.append('form_copypaste') if options.pop('linker',False): default_slots = default_slots.replace('form_delete',','.join(extra_slots) if extra_slots else '') default_slots = default_slots.replace('form_add','') #default_slots = default_slots.replace('locker','') table = form.getInheritedAttributes()['table'] if extra_slots: default_slots = default_slots.replace('form_delete','%s,10,form_delete' %(','.join(extra_slots))) slots = options.pop('slots',default_slots) if table == self.maintable: slots = 'logicalDeleter,%s' %slots form.top.slotToolbar(slots,form_add_defaults=form_add if form_add and form_add is not True else None,**options) if not options.pop('showfooter',True): form.attributes['hasBottomMessage'] = False if hierarchical: form.left.attributes.update(splitter=True) leftkw = dict() if hierarchical is True or hierarchical=='open': form.store.attributes.setdefault('startKey','*norecord*') form.attributes.update(form_deleted_destPkey='*norecord*') if hierarchical=='open': leftkw['closable'] = 'open' elif hierarchical=='closed': leftkw['closable'] = 'close' bar = form.left.slotBar('0,htreeSlot,0',width=tree_kwargs.pop('width','200px'),border_right='1px solid silver',**leftkw) bar.htreeSlot.treeViewer(**tree_kwargs) for side in ('top','bottom','left','right'): hooks = self._th_hook(side,mangler=mangler,asDict=True) for hook in hooks.values(): hook(getattr(form,side)) form.store.handler('load',onLoadingHandler=self._th_hook('onLoading',mangler=mangler)) form.store.handler('save',onSavingHandler=self._th_hook('onSaving',mangler=mangler), onSavedHandler=self._th_hook('onSaved',mangler=mangler))
def rpc_upload_file(self, *args ,**kwargs): onUploadingMethod= kwargs.get('onUploadingMethod') if onUploadingMethod: onUploading = self.page.getPublicMethod('rpc', onUploadingMethod) onUploading(kwargs) file_handle = kwargs.get('file_handle') dataUrl = kwargs.get('dataUrl') uploadPath = kwargs.get('uploadPath') uploaderId = kwargs.get('uploaderId') onUploadedMethod = kwargs.get('onUploadedMethod') filename = kwargs.get('filename') site = self.page.site #kwargs = site.parse_kwargs(kwargs) it's provided by gnrwsgisite file_actions = dictExtract(kwargs, 'process_') or {} if not uploadPath: uploadPath = 'site:uploaded_files' if uploaderId: uploadPath = '%s/%s' % (uploadPath, uploaderId) if uploadPath is None: return if file_handle is not None: f = file_handle.file content = f.read() original_filename = os.path.basename(file_handle.filename) original_ext = os.path.splitext(original_filename)[1] filename = filename or original_filename elif dataUrl: dataUrlPattern = re.compile('data:(.*);base64,(.*)$') g= dataUrlPattern.match(dataUrl)#.group(2) mimetype,base64Content = g.groups() original_ext = mimetypes.guess_extension(mimetype) content = base64.b64decode(base64Content) else: return file_ext = os.path.splitext(filename)[1] if not file_ext: filename = '%s%s' %(filename,original_ext) file_ext = original_ext file_path = site.getStaticPath(uploadPath, filename,autocreate=-1) file_url = site.getStaticUrl(uploadPath, filename) with file(file_path, 'wb') as outfile: outfile.write(content) action_results = dict() for action_name, action_params in file_actions.items(): if action_params == True: action_params = getattr(self.page, 'process_%s' % action_name)() command_name = action_params.pop('fileaction', None) if not command_name: continue action_runner = getattr(self.page, 'fileaction_%s' % command_name) if action_runner: for action_param in action_params: action_params[str(action_param)] = action_params.pop(action_param) action_results[action_name] = action_runner(file_url=file_url, file_path=file_path, file_ext=file_ext, action_name=action_name, **action_params) if onUploadedMethod: handler = self.page.getPublicMethod('rpc', onUploadedMethod) if handler: return handler(file_url=file_url, file_path=file_path, file_ext=file_ext, action_results=action_results, **kwargs) elif uploaderId: handler = getattr(self.page, 'onUploading_%s' % uploaderId,None) if handler: return handler(file_url=file_url, file_path=file_path, file_ext=file_ext, action_results=action_results, **kwargs) return file_url
def dropFileGrid_uploader_grid(self, bc, uploaderId=None, label=None, footer=None, enabled=True, onResult=None, onFileUploaded=None, uploadPath=None, preview=False, **kwargs): uploadPath = uploadPath or 'site:uploaded_files' metacol_dict = dictExtract(kwargs, 'metacol_') external_dict = dictExtract(kwargs, 'external_') or {} process_dict = dictExtract(kwargs, 'process_', slice_prefix=False) or {} external_dict.update(process_dict) datapath = '.uploader' gridId = '%s_uploader' % uploaderId def _struct(struct): r = struct.view().rows() r.cell('_name', name='!!File name', width='10em') r.cell('_size', name='!!Size', width='5em') r.cell('_type', name='!!Type', width='5em') for k, v in metacol_dict.items(): r.cell(k, **v) r.cell('_status', name='Status', width='6em') if preview: self._dropFileGrid_preview(bc, datapath=datapath) iv = self.includedViewBox(bc.borderContainer(region='center'), label=label, storepath='.uploading_data', nodeId=gridId, struct=_struct, datamode='bag', datapath=datapath, footer=footer, del_action=True, del_enabled=enabled, editorEnabled=enabled, autoWidth=True, onDrop="FIRE .prepare_files=files;FIRE .on_drop = 1000;", dropTarget_grid='Files', dropTarget=True, dropTypes='Files') gridEditor = iv.gridEditor() for k, v in metacol_dict.items(): _tag = 'textbox' dtype = v.get('dtype') widget = v.get('widget') if widget: _tag = widget elif dtype: if(dtype == 'I' or dtype == 'R' or dtype == 'N'): _tag = 'numberTextBox' elif(dtype == 'D'): _tag = 'dateTextBox' elif(dtype == 'B'): _tag = 'checkbox' gridEditor.child(_tag, gridcell=k) bc.dataController("""genro.wdgById(gridId).editBagRow(null,fired);""", fired='^.on_drop', gridId=gridId, datapath=datapath) bc.dataController(""" dojo.forEach(files, function(f){ var row = objectUpdate({_name:f.name,_size:f.size,_type:f.type,_file:f,_uploaderId:uploaderId},external_params); var label = (f.name+'_'+f.size+'_'+f.type).replace(/\W/g,'_'); if(filebag.index(label)<0){ var r = new gnr.GnrBag(row); filebag.setItem(label,r); } }); """, filebag="=.uploading_data", files='^.prepare_files', datapath=datapath, external_params=external_dict, uploaderId=uploaderId) bc.dataController(""" genro.rpc.uploadMultipartFiles(filebag,{onResult:funcCreate(onResult,'result',this), onFileUploaded:funcCreate(onFileUploaded,'node',this), uploadPath:uploadPath,uploaderId:uploaderId}); """, filebag='=.uploading_data', datapath=datapath, uploaderId=uploaderId, onResult=onResult or '', onFileUploaded=onFileUploaded or '', uploadPath=uploadPath, **{'subscribe_%s_upload' % uploaderId: True})
def pk_palettePicker(self, pane, grid=None, table=None, relation_field=None, paletteCode=None, viewResource=None, searchOn=True, multiSelect=True, structure_field=None, title=None, autoInsert=None, dockButton=None, picker_kwargs=None, height=None, width=None, checkbox=False, defaults=None, **kwargs): dockButton = dockButton or dict(parentForm=True, iconClass='iconbox app') picker_kwargs = picker_kwargs or dict() checkbox = checkbox or picker_kwargs.get('checkbox', False) one = picker_kwargs.get('one', False) picker_kwargs.setdefault('uniqueRow', True) condition = picker_kwargs.pop('condition', None) many = relation_field or picker_kwargs.get('relation_field', None) table = table or picker_kwargs.get('table', None) height = height or picker_kwargs.get('height', '600px') width = width or picker_kwargs.get('width', '400px') defaults = defaults or picker_kwargs.get('defaults', False) if autoInsert is None: autoInsert = picker_kwargs.get('autoInsert', True) title = title or picker_kwargs.get('title') viewResource = viewResource or picker_kwargs.get('viewResource') if viewResource is True: viewResource = 'ViewPicker' searchOn = searchOn or picker_kwargs.get('searchOn') maintable = None if grid is not None: maintable = grid.getInheritedAttributes()['table'] if not table: tblobj = self.db.table(maintable).column( many).relatedTable().dbtable table = tblobj.fullname else: tblobj = self.db.table(table) elif table: tblobj = self.db.table(table) paletteCode = paletteCode or picker_kwargs.get( 'paletteCode') or '%s_picker' % table.replace('.', '_') title = title or tblobj.name_long treepicker = tblobj.attributes.get('hierarchical') and not viewResource condition_kwargs = dictExtract(picker_kwargs, 'condition_', pop=True, slice_prefix=not treepicker) if treepicker: palette = pane.palettePane(paletteCode=paletteCode, dockButton=dockButton, title=title, width=width, height=height) frame = palette.framePane(frameCode=paletteCode) frame.top.slotToolbar('*,searchOn,5') frame.center.contentPane(overflow='auto').div( margin='10px').hTableTree( table=table, draggableFolders=picker_kwargs.pop('draggableFolders', None), dragTags=paletteCode, onDrag="""function(dragValues, dragInfo, treeItem) { if (treeItem.attr.child_count && treeItem.attr.child_count > 0 && !draggableFolders) { return false; } dragValues['text/plain'] = treeItem.attr.caption; dragValues['%s'] = treeItem.attr; }""" % paletteCode, condition=condition, checkbox=checkbox, **condition_kwargs) else: palette = pane.paletteGridPicker( grid=grid, table=table, relation_field=many, paletteCode=paletteCode, viewResource=viewResource, searchOn=searchOn, multiSelect=multiSelect, title=title, dockButton=dockButton, height=height, width=width, condition=condition, condition_kwargs=condition_kwargs, checkbox=checkbox, structure_field=structure_field or picker_kwargs.get('structure_field'), uniqueRow=picker_kwargs.get('uniqueRow', True), top_height=picker_kwargs.get('top_height'), structure_kwargs=dictExtract(picker_kwargs, 'structure_')) if grid is not None: grid.attributes.update( dropTargetCb_picker= 'return this.form?!this.form.isDisabled():true') grid.dragAndDrop(paletteCode) if autoInsert: method = getattr(tblobj, 'insertPicker', self._th_insertPicker) formNode = pane.parentNode.attributeOwnerNode('formId') if not one and formNode and grid.attributes.get('table'): formtblobj = self.db.table(formNode.attr.get('table')) oneJoiner = formtblobj.model.getJoiner(maintable) one = oneJoiner.get('many_relation').split('.')[-1] controller = "THPicker.onDropElement(this,data,mainpkey,rpcmethod,treepicker,tbl,one,many,grid,defaults)" if autoInsert is True else autoInsert grid.dataController( controller, data='^.dropped_%s' % paletteCode, droppedInfo='=.droppedInfo_%s' % paletteCode, mainpkey='=#FORM.pkey' if formNode else None, rpcmethod=method, treepicker=treepicker, tbl=maintable, one=one, many=many, grid=grid.js_widget, defaults=defaults) return palette
def fgr_slotbar_filterset(self, parent, filterset=None, cb=None, cb_kwargs=None, all_begin=None, all_end=None, include_inherited=False, multiButton=None, multivalue=None, mandatory=None, lbl=None, lbl_kwargs=None, frameCode=None, **kwargs): pane = parent.div(datapath='.grid.filterset.%s' % filterset) m = self.mangledHook('filterset_%s' % filterset, mangler=frameCode, defaultCb=False) filterlist = None if m: filterlist = m() dflt = getattr(m, 'default', None) multivalue = getattr(m, 'multivalue', True) mandatory = getattr(m, 'mandatory', False) multiButton = getattr(m, 'multiButton', multiButton) lbl = lbl or getattr(m, 'lbl', None) lbl_kwargs = lbl_kwargs or dictExtract( dict(m.__dict__), 'lbl_', slice_prefix=False) if filterlist: filtersetBag = Bag() dflt = [] for i, kw in enumerate(filterlist): code = kw.get('code') or 'r_%i' % i if kw.get('isDefault'): dflt.append(code) filtersetBag.setItem(code, None, **kw) pane.data('.data', filtersetBag) pane.data('.current', ','.join(dflt) if dflt else None) multiButton = multiButton is True or multiButton is None or multiButton and len( filtersetBag) <= multiButton if multiButton: mb = pane.multiButton(items='^.data', value='^.current', multivalue=multivalue, mandatory=mandatory, disabled='^.#parent.#parent.loadingData', **kwargs) else: mb = pane.formbuilder(cols=1, border_spacing='3px', **lbl_kwargs) lbl = lbl or filterset.capitalize() if multivalue: mb.checkBoxText(values='^.data', value='^.current', lbl=lbl, labelAttribute='caption', parentForm=False, disabled='^.#parent.#parent.loadingData', popup=True, cols=1) else: mb.filteringSelect(storepath='.data', value='^.current', lbl=lbl, disabled='^.#parent.#parent.loadingData', storeid='#k', parentForm=False, validate_notnull=mandatory, popup=True, cols=1)
def rpc_upload_file(self, *args ,**kwargs): onUploadingMethod= kwargs.get('onUploadingMethod') if onUploadingMethod: onUploading = self.page.getPublicMethod('rpc', onUploadingMethod) onUploading(kwargs) file_handle = kwargs.get('file_handle') dataUrl = kwargs.get('dataUrl') uploadPath = kwargs.get('uploadPath') uploaderId = kwargs.get('uploaderId') onUploadedMethod = kwargs.get('onUploadedMethod') filename = kwargs.get('filename') site = self.page.site #kwargs = site.parse_kwargs(kwargs) it's provided by gnrwsgisite file_actions = dictExtract(kwargs, 'process_') or {} if not uploadPath: uploadPath = 'site:uploaded_files' if uploaderId: uploadPath = '%s/%s' % (uploadPath, uploaderId) if uploadPath is None: return if file_handle is not None: f = file_handle.file content = f.read() original_filename = os.path.basename(file_handle.filename) original_ext = os.path.splitext(original_filename)[1] filename = filename or original_filename elif dataUrl: dataUrlPattern = re.compile('data:(.*);base64,(.*)$') g= dataUrlPattern.match(dataUrl)#.group(2) mimetype,base64Content = g.groups() original_ext = mimetypes.guess_extension(mimetype) content = base64.b64decode(base64Content) else: return file_ext = os.path.splitext(filename)[1] if not file_ext: filename = '%s%s' %(filename,original_ext) file_ext = original_ext file_path = site.getStaticPath(uploadPath, filename,autocreate=-1) file_url = site.getStaticUrl(uploadPath, filename) dirname = os.path.dirname(file_path) if not os.path.exists(dirname): os.makedirs(dirname) with file(file_path, 'wb') as outfile: outfile.write(content) action_results = dict() for action_name, action_params in file_actions.items(): if action_params == True: action_params = getattr(self.page, 'process_%s' % action_name)() command_name = action_params.pop('fileaction', None) if not command_name: continue action_runner = getattr(self.page, 'fileaction_%s' % command_name) if action_runner: for action_param in action_params: action_params[str(action_param)] = action_params.pop(action_param) action_results[action_name] = action_runner(file_url=file_url, file_path=file_path, file_ext=file_ext, action_name=action_name, **action_params) if onUploadedMethod: handler = self.page.getPublicMethod('rpc', onUploadedMethod) if handler: return handler(file_url=file_url, file_path=file_path, file_ext=file_ext, action_results=action_results, **kwargs) elif uploaderId: handler = getattr(self.page, 'onUploading_%s' % uploaderId,None) if handler: return handler(file_url=file_url, file_path=file_path, file_ext=file_ext, action_results=action_results, **kwargs) return file_url
def dropFileGrid_uploader_grid(self, bc, uploaderId=None, label=None, footer=None, enabled=True, onResult=None, onFileUploaded=None, uploadPath=None, preview=False, **kwargs): uploadPath = uploadPath or 'site:uploaded_files' metacol_dict = dictExtract(kwargs, 'metacol_') external_dict = dictExtract(kwargs, 'external_') or {} process_dict = dictExtract(kwargs, 'process_', slice_prefix=False) or {} external_dict.update(process_dict) datapath = '.uploader' gridId = '%s_uploader' % uploaderId def _struct(struct): r = struct.view().rows() r.cell('_name', name='!!File name', width='10em') r.cell('_size', name='!!Size', width='5em') r.cell('_type', name='!!Type', width='5em') for k, v in metacol_dict.items(): r.cell(k, **v) r.cell('_status', name='Status', width='6em') if preview: self._dropFileGrid_preview(bc, datapath=datapath) iv = self.includedViewBox( bc.borderContainer(region='center'), label=label, storepath='.uploading_data', nodeId=gridId, struct=_struct, datamode='bag', datapath=datapath, footer=footer, del_action=True, del_enabled=enabled, editorEnabled=enabled, autoWidth=True, onDrop="FIRE .prepare_files=files;FIRE .on_drop = 1000;", dropTarget_grid='Files', dropTarget=True, dropTypes='Files') gridEditor = iv.gridEditor() for k, v in metacol_dict.items(): _tag = 'textbox' dtype = v.get('dtype') widget = v.get('widget') if widget: _tag = widget elif dtype: if (dtype == 'I' or dtype == 'R' or dtype == 'N'): _tag = 'numberTextBox' elif (dtype == 'D'): _tag = 'dateTextBox' elif (dtype == 'B'): _tag = 'checkbox' gridEditor.child(_tag, gridcell=k) bc.dataController("""genro.wdgById(gridId).editBagRow(null,fired);""", fired='^.on_drop', gridId=gridId, datapath=datapath) bc.dataController(""" dojo.forEach(files, function(f){ var row = objectUpdate({_name:f.name,_size:f.size,_type:f.type,_file:f,_uploaderId:uploaderId},external_params); var label = (f.name+'_'+f.size+'_'+f.type).replace(/\W/g,'_'); if(filebag.index(label)<0){ var r = new gnr.GnrBag(row); filebag.setItem(label,r); } }); """, filebag="=.uploading_data", files='^.prepare_files', datapath=datapath, external_params=external_dict, uploaderId=uploaderId) bc.dataController(""" genro.rpc.uploadMultipartFiles(filebag,{onResult:funcCreate(onResult,'result',this), onFileUploaded:funcCreate(onFileUploaded,'node',this), uploadPath:uploadPath,uploaderId:uploaderId}); """, filebag='=.uploading_data', datapath=datapath, uploaderId=uploaderId, onResult=onResult or '', onFileUploaded=onFileUploaded or '', uploadPath=uploadPath, **{'subscribe_%s_upload' % uploaderId: True})
def _th_applyOnForm(self,form,options=None,mangler=None): if not self.th_checkPermission(form): form.attributes['_notallowed'] = True parent = form.parent if hasattr(parent,'view'): th_attributes = parent.attributes th_class = th_attributes.get('_class') or '' th_attributes['_class'] = '%s th_form_not_allowed' %th_class table = form.getInheritedAttributes()['table'] form.dataController("""var title = newrecord?( newTitleTemplate? dataTemplate(newTitleTemplate,record): caption ): (titleTemplate? dataTemplate(titleTemplate,record) : tablename+': '+caption); SET #FORM.controller.title = title; this.form.publish('onChangedTitle',{title:title}); """, tablename=self.db.table(table).name_long, caption='=#FORM.record?caption', newrecord='=#FORM.record?_newrecord', record='=#FORM.record',titleTemplate=options.pop('titleTemplate',False), newTitleTemplate=options.pop('newTitleTemplate',False), _fired='^#FORM.controller.loaded') if form.attributes.get('form_isRootForm'): form.data('gnr.rootform.size',Bag(height=options.pop('dialog_height','500px'),width=options.pop('dialog_width','600px'))) if 'lazyBuild' in options: form.attributes['_lazyBuild'] = options.pop('lazyBuild') showtoolbar = boolean(options.pop('showtoolbar',True)) navigation = options.pop('navigation',None) hierarchical = options.pop('hierarchical',None) tree_kwargs = dictExtract(options,'tree_',pop=True) readOnly = options.pop('readOnly',False) modal = options.pop('modal',False) autoSave = options.pop('autoSave',False) draftIfInvalid= options.pop('draftIfInvalid',False) allowSaveInvalid= options.pop('allowSaveInvalid',draftIfInvalid) form_add = options.pop('form_add',True) form_delete = options.pop('form_delete',True) selector = options.pop('selector',False) form.attributes.update(form_draftIfInvalid=draftIfInvalid,form_allowSaveInvalid=allowSaveInvalid) if autoSave: form.store.attributes.update(autoSave=autoSave) form.dataController(""" if(reason=='nochange' && modal){return;} genro.dlg.alert(msg+' '+this.form.getRecordCaption()+': '+(reason=='invalid'?invalid:nochange),titledialog);""", reason="^.controller.save_failed",_if='reason', titledialog='!!Save failed', msg='!!You cannot save', invalid='!!Invalid record', nochange='!!No change to save',modal=modal) box_kwargs = dictExtract(options,'box_',pop=True) extra_slots = [] if hierarchical: box_kwargs['sidebar'] = True box_kwargs['persist'] = True if box_kwargs: sidebar = box_kwargs.pop('sidebar') if sidebar: box_kwargs['design'] = 'sidebar' form.attributes.update(**box_kwargs) if form.store.attributes.get('storeType') == 'Collection': if navigation is not False: navigation = True if readOnly: form.attributes.update(form_readOnly=True) if options.get('saveOnChange'): form.attributes.update(form_saveOnChange=options.pop('saveOnChange')) showtoolbar = False if 'parentLock' in options: form.attributes.update(form_parentLock=options.pop('parentLock')) if modal: slots='revertbtn,*,cancel,savebtn' bar = form.bottom.slotBar(slots,margin_bottom='2px',_class='slotbar_dialog_footer') bar.revertbtn.button('!!Revert',action='this.form.publish("reload")',disabled='^.controller.changed?=!#v',hidden=readOnly) bar.cancel.button('!!Cancel',action='this.form.abort();') bar.savebtn.button('!!Save',iconClass='fh_semaphore',action='this.form.publish("save",{destPkey:"*dismiss*"})',hidden=readOnly) elif showtoolbar: default_slots = '*,semaphore,5' if readOnly else '*,form_delete,form_add,form_revert,form_save,semaphore,locker' if form_add is False: default_slots.replace('form_add','') if form_delete is False: default_slots.replace('form_delete','') if options.pop('duplicate',False): default_slots= default_slots.replace('form_add','form_add,form_duplicate') if hierarchical: default_slots = 'dismiss,hbreadcrumb,%s' %default_slots elif navigation: default_slots = 'navigation,%s' %default_slots if selector: default_slots = default_slots.replace('*','5,form_selectrecord,*') if isinstance(selector,dict): options['form_selectrecord_pars'] = selector if options.pop('printMenu',False): #default_slots = default_slots.replace('form_delete','form_print,100,form_delete') extra_slots.append('form_print') if options.pop('copypaste',False): extra_slots.append('form_copypaste') if options.pop('linker',False): default_slots = default_slots.replace('form_delete',','.join(extra_slots) if extra_slots else '') default_slots = default_slots.replace('form_add','') #default_slots = default_slots.replace('locker','') table = form.getInheritedAttributes()['table'] if extra_slots: default_slots = default_slots.replace('form_delete','%s,10,form_delete' %(','.join(extra_slots))) slots = options.pop('slots',default_slots) if table == self.maintable: slots = 'logicalDeleter,%s' %slots form.top.slotToolbar(slots,form_add_defaults=form_add if form_add and form_add is not True else None,**options) if hierarchical: form.left.attributes.update(splitter=True) leftkw = dict() if hierarchical is True or hierarchical=='open': form.store.attributes.setdefault('startKey','*norecord*') form.attributes.update(form_deleted_destPkey='*norecord*') if hierarchical=='open': leftkw['closable'] = 'open' elif hierarchical=='closed': leftkw['closable'] = 'close' bar = form.left.slotBar('0,htreeSlot,0',width=tree_kwargs.pop('width','200px'),border_right='1px solid silver',**leftkw) bar.htreeSlot.treeViewer(**tree_kwargs) for side in ('top','bottom','left','right'): hooks = self._th_hook(side,mangler=mangler,asDict=True) for hook in hooks.values(): hook(getattr(form,side)) form.store.handler('load',onLoadingHandler=self._th_hook('onLoading',mangler=mangler)) form.store.handler('save',onSavingHandler=self._th_hook('onSaving',mangler=mangler), onSavedHandler=self._th_hook('onSaved',mangler=mangler))
def includedViewBox( self, parentBC, nodeId=None, table=None, datapath=None, storepath=None, selectionPars=None, formPars=None, label=None, caption=None, footer=None, add_action=None, add_class="buttonIcon icnBaseAdd", add_enable="^form.canWrite", del_action=None, del_class="buttonIcon icnBaseDelete", del_enable="^form.canWrite", upd_action=None, upd_class="buttonIcon icnBaseEdit", upd_enable="^form.canWrite", close_action=None, close_class="buttonIcon icnTabClose", print_action=None, print_class="buttonIcon icnBasePrinter", pdf_action=None, pdf_class="buttonIcon icnBasePdf", pdf_name=None, export_action=None, export_class="buttonIcon icnBaseExport", tools_action=None, tools_class="buttonIcon icnBaseAction", tools_enable="^form.canWrite", tools_lbl=None, lock_action=False, tools_menu=None, _onStart=False, filterOn=None, pickerPars=None, centerPaneCb=None, editorEnabled=None, parentLock="^status.locked", reloader=None, externalChanges=None, addOnCb=None, zoom=True, hasToolbar=False, canSort=True, configurable=None, dropCodes=None, **kwargs ): """ This method returns a grid (includedView) for viewing and selecting rows from a many to many table related to the main table, and the widget that allow to edit data. You can edit data of a single row (record) using a form (formPars), or pick some rows from another table with the picker widget (pickerPars). The form can be contained inside a dialog or a contentPane and is useful to edit a single record. If the data is stored inside another table you should use the picker to select the rows from that table. * `parentBC`: MANDATORY - parentBC is a :ref:`genro-bordercontainer` that you must pass to the includedViewBox. .. note:: The includedViewBox and its sons (for example, the :ref:`genro-selectionhandler`) can only accept borderContainer and doesn't accept contentPane. * `nodeId`: the includedViewbox's Id. For more information, check :ref:`genro_nodeid` page. Default value is ``None``. * `table`: the includedViewbox's reference :ref:`genro-database_table`. Default value is ``None``. * `datapath`: allow to create a hierarchy of your data’s addresses into the datastore. Default value is ``None``. For more information, check the :ref:`genro-datapath` and the :ref:`genro-datastore` pages. * `storepath`: <#NISO ??? Add description! /> Default value is ``None``. * `selectionPars`: <#NISO ??? Add description! /> Default value is ``None``. * `formPars`: (dict) it contains all the params of the widget who hosts the form. Default value is ``None``. formPars parameters: * mode: `dialog` / `pane`. Default value is `dialog`. * height: the dialog's height. * width: the dialog's width. * formCb: MANDATORY - callback method used to create the form. formCb parameters: * formBorderCont: a :ref:`genro-bordercontainer` used as root for the formCb's construction. * datapath: allow to create a hierarchy of your data’s addresses into the datastore. For more information, check the :ref:`genro-datapath` and the :ref:`genro-datastore` pages. * region: 'center' of the pane/borderContainer where you place it into. * toolbarHandler: OPTIONAL - a callback for the form toolbar. * title: MANDATORY - for dialog mode. * pane: OPTIONAL - pane of the form input. * `label`: (string) allow to create a label for the includedView. Default value is ``None``. * `caption`: <#NISO ??? Add description! />. Default value is ``None``. * `footer`: <#NISO ??? Add description! />. Default value is ``None``. * `add_action`: (boolean) allow the insertion of a row in the includedView. Default value is ``None``. * `add_class`: the css class of the add button. Default value is ``buttonIcon icnBaseAdd``. * `add_enable`: a path to enable/disable add action. Default value is ``^form.canWrite``. * `del_action`: (boolean) allow the deleting of a row in the includedView. Default value is ``None``. * `del_class`: the css class of the delete button. Default value is ``buttonIcon icnBaseDelete``. * `del_enable`: a path to enable/disable del action. Default value is ``^form.canWrite``. * `upd_action`: <#NISO ??? Add description! />. Default value is ``None``. * `upd_class`: <#NISO ??? Add description! />. Default value is ``buttonIcon icnBaseEdit``. * `upd_enable`: <#NISO ??? Add description! />. Default value is ``^form.canWrite``. * `close_action`: (boolean) adding closing button in tooltipDialog. Default value is ``None``. * `close_class`: css class of close button. Default value is ``None``. * `print_action`: <#NISO ??? Add description! />. Default value is ``None``. * `print_class`: <#NISO ??? Add description! />. Default value is ``None``. * `pdf_action`: <#NISO ??? Add description! />. Default value is ``None``. * `pdf_class`: <#NISO ??? Add description! />. Default value is ``None``. * `pdf_name`: <#NISO ??? Add description! />. Default value is ``None``. * `export_action`: <#NISO ??? Add description! />. Default value is ``None``. * `export_class`: <#NISO ??? Add description! />. Default value is ``None``. * `tools_action`: <#NISO ??? Add description! />. Default value is ``None``. * `tools_class`: <#NISO ??? Add description! />. Default value is ``None``. * `tools_enable`: <#NISO ??? Add description! />. Default value is ``None``. * `tools_lbl`: <#NISO ??? Add description! />. Default value is ``None``. * `lock_action`: an optional parameter; <#NISO ??? Add description! />. Default value is ``False``. * `tools_menu`: <#NISO ??? Add description! />. Default value is ``None``. * `_onStart`: an optional parameter; (Boolean) if True, the controller is executed only after that all the line codes are read. Default value is ``False``. * `filterOn`: (boolean, only for picker) allow the filter into the picker grid. Default value is ``None``. * `pickerPars`: (dict) it contains all the params of the tooltip dialog which host the picker grid. Default value is ``None``. Parameters: - height: height of the tooltipdialog. - width: width of the tooltipdialog. - label: label of the tooltipdialog. - table: MANDATORY - the table of the picker grid. From this table you can pick a row for the many to many table you handle. - columns: MANDATORY - columns of the picker grid. - nodeId: MANDATORY - id for the picker. - autowidth, storepath, etc grid params. - filterOn: the columns on which to apply filter. * `centerPaneCb`: <#NISO ??? Add description! />. Default value is ``None``. * `editorEnabled`: <#NISO ??? Add description! />. Default value is ``None``. * `parentLock`: <#NISO ??? Add description! />. Default value is ``None``. * `reloader`: <#NISO ??? Add description! />. Default value is ``None``. * `externalChanges`: <#NISO ??? Add description! />. Default value is ``None``. * `addOnCb`: <#NISO ??? Add description! />. Default value is ``None``. * `zoom`: It allows to open the linked record in its :ref:`genro-database_table`. For further details, check :ref:`genro_zoom`. Default value is ``True``. * `hasToolbar`: <#NISO ??? Add description! />. Default value is ``False``. * `canSort`: <#NISO ??? Add description! />. Default value is ``True``. * `fromPicker_target_fields`: allow to bind the picker's table. columns to the includedView columns of the many to many table. * `fromPicker_nodup_field`: if this column value is present in the includedView it allows to replace that row instead of adding a duplicate row. * `**kwargs`: you have to put the includedView params: autowidth, storepath, etc. """ if storepath: assert not storepath.startswith("^") and not storepath.startswith( "=" ), "storepath should be a plain datapath, no ^ or =" if not datapath: if storepath.startswith("."): inherited_attributes = parentBC.parentNode.getInheritedAttributes() # assert inherited_attributes.has_key('sqlContextRoot'),\ #'please specify an absolute storepath, if sqlContextRoot is not available' # storepath = '%s%s' % (inherited_attributes['sqlContextRoot'], storepath) storepath = "#%s%s" % (inherited_attributes["formId"], storepath) viewPars = dict(kwargs) if nodeId and table and configurable is not False: configurable = True gridId = nodeId or self.getUuid() viewPars["nodeId"] = gridId if dropCodes: for dropCode in dropCodes.split(","): mode = "grid" if ":" in dropCode: dropCode, mode = dropCode.split(":") dropmode = "dropTarget_%s" % mode viewPars[dropmode] = "%s,%s" % (viewPars[dropmode], dropCode) if dropmode in viewPars else dropCode viewPars["onDrop_%s" % dropCode] = "FIRE .dropped_%s = data" % dropCode viewPars["onCreated"] = ( """dojo.connect(widget,'_onFocus',function(){genro.publish("show_palette_%s")})""" % dropCode ) # provo?si # controllerPath = datapath or "grids.%s" % gridId storepath = storepath or ".selection" viewPars["configurable"] = configurable viewPars["storepath"] = storepath viewPars["controllerPath"] = controllerPath controller = parentBC.dataController(datapath=controllerPath) assert not "selectedIndex" in viewPars viewPars["selectedIndex"] = "^.selectedIndex" assert not "selectedLabel" in viewPars if not viewPars.get("selectedId"): viewPars["selectedId"] = "^.selectedId" viewPars["selectedLabel"] = "^.selectedLabel" label_pars = dict([(k[6:], kwargs.pop(k)) for k in kwargs.keys() if k.startswith("label_")]) label_pars["_class"] = label_pars.pop("class", None) or (not hasToolbar and "pbl_viewBoxLabel") box_pars = dict([(k[4:], kwargs.pop(k)) for k in kwargs.keys() if k.startswith("box_")]) box_pars["_class"] = box_pars.pop("class", None) or "pbl_viewBox" if label is not False: gridtop = parentBC.contentPane( region="top", datapath=controllerPath, overflow="hidden", _attachname="top", nodeId="%s_top" % gridId, **label_pars ) if hasToolbar is True: gridtop = gridtop.toolbar(_class="pbl_viewBoxToolbar") gridtop_left = gridtop.div(float="left") if callable(label): label(gridtop_left) else: gridtop_left.div(label, margin_top="2px", float="left") gridtop_right = gridtop.div(float="right", _attachname="right") if filterOn: gridtop_filter = gridtop_right.div(float="left", margin_right="5px") self.gridFilterBox(gridtop_filter, gridId=gridId, filterOn=filterOn, table=table) if print_action or export_action or tools_menu or tools_action or pdf_action: gridtop_actions = gridtop_right.div(float="left", margin_right="5px") self._iv_gridAction( gridtop_actions, print_action=print_action, export_action=export_action, export_class=export_class, print_class=print_class, tools_class=tools_class, tools_menu=tools_menu, tools_action=tools_action, pdf_action=pdf_action, pdf_class=pdf_class, pdf_name=pdf_name, table=table, gridId=gridId, tools_enable=tools_enable, tools_lbl=tools_lbl, ) if add_action or del_action or upd_action: gridtop_add_del = gridtop_right.div(float="left", margin_right="5px", _attachname="add_del") self._iv_gridAddDel( gridtop_add_del, add_action=add_action, del_action=del_action, upd_action=upd_action, upd_class=upd_class, upd_enable=upd_enable, add_class=add_class, add_enable=add_enable, del_class=del_class, del_enable=del_enable, pickerPars=pickerPars, formPars=formPars, gridId=gridId, ) if lock_action: gridtop_lock = gridtop_right.div(float="left", margin_right="5px") self._iv_gridLock(gridtop_lock, lock_action=lock_action) if footer: assert callable(footer), "footer param must be a callable" footerPars = dict([(k[7:], v) for k, v in kwargs.items() if k.startswith("footer_")]) if not "height" in footerPars: footerPars["height"] = "18px" if not "_class" in footerPars: footerPars["_class"] = "pbl_roundedGroupBottom" gridbottom = parentBC.contentPane(region="bottom", datapath=controllerPath, **footerPars) footer(gridbottom) self._iv_IncludedViewController(controller, gridId, controllerPath, table=table) if centerPaneCb: gridcenter = getattr(self, centerPaneCb)(parentBC, region="center", datapath=controllerPath, **box_pars) else: gridcenter = parentBC.contentPane(region="center", datapath=controllerPath, **box_pars) viewPars["structpath"] = viewPars.get("structpath") or ".struct" or "grids.%s.struct" % nodeId if filterOn is True: gridcenter.dataController( """var colsMenu = new gnr.GnrBag(); struct.forEach(function(n){ colsMenu.setItem(n.label, null, {col:n.attr.field, caption:n.attr.name}) }); SET .flt.colsMenu = colsMenu;""", struct="^%s.view_0.row_0" % viewPars["structpath"], ) if parentLock: gridcenter.dataFormula(".editorEnabled", "parentLock==null?false:!parentLock", parentLock=parentLock) elif parentLock is False: editorEnabled = True if caption: innerbc = gridcenter.borderContainer() caption_pars = dictExtract(viewPars, "caption_", pop=True) innerbc.contentPane(region="top").div(caption, **caption_pars) gridcenter = innerbc.contentPane(region="center") view = gridcenter.includedView( extension="includedViewPicker", table=table, editorEnabled=editorEnabled or "^.editorEnabled", reloader=reloader, **viewPars ) if addOnCb: addOnCb(gridcenter) if _onStart: controller.dataController("FIRE .reload", _onStart=True) if externalChanges: externalChangesTypes = "" if isinstance(externalChanges, basestring): if ":" in externalChanges: externalChanges, externalChangesTypes = externalChanges.split(":") if externalChanges == "*": externalChanges = True subscribed_tables = [t for t in getattr(self, "subscribed_tables", "").split(",") if t] assert table in subscribed_tables, "table %s must be subscribed to get externalChanges" % table event_path = "gnr.dbevent.%s" % table.replace(".", "_") pars = dict() conditions = list() if isinstance(externalChanges, basestring): for fld in externalChanges.split(","): fldname, fldpath = fld.split("=") conditions.append("genro.isEqual(curr_%s,event_%s)" % (fldname, fldname)) pars["event_%s" % fldname] = "=%s.%s" % (event_path, fldname) pars["curr_%s" % fldname] = "=%s" % fldpath if externalChangesTypes: conditions.append("evtypes.indexOf(evtype)>=0") pars["evtypes"] = externalChangesTypes pars["evtype"] = "=%s?dbevent" % event_path gridcenter.dataController("FIRE .reload;", _if=" && ".join(conditions), _fired="^%s" % event_path, **pars) if selectionPars: self._iv_includedViewSelection(gridcenter, gridId, table, storepath, selectionPars, controllerPath) if formPars: formPars.setdefault("pane", gridcenter) self._includedViewForm(controller, controllerPath, view, formPars) if pickerPars: pickerPars.setdefault("pane", gridcenter) self._iv_Picker(controller, controllerPath, view, pickerPars) return view
def includedViewBox(self, parentBC, nodeId=None, table=None, datapath=None, storepath=None, selectionPars=None, formPars=None, label=None, caption=None, footer=None, add_action=None, add_class='buttonIcon icnBaseAdd', add_enable='^form.canWrite', del_action=None, del_class='buttonIcon icnBaseDelete', del_enable='^form.canWrite', upd_action=None, upd_class='buttonIcon icnBaseEdit', upd_enable='^form.canWrite', close_action=None, close_class='buttonIcon icnTabClose', print_action=None, print_class='buttonIcon icnBasePrinter', pdf_action=None, pdf_class='buttonIcon icnBasePdf', pdf_name=None, export_action=None, export_class='buttonIcon icnBaseExport', tools_action=None, tools_class='buttonIcon icnBaseAction', tools_enable='^form.canWrite', tools_lbl=None, lock_action=False, tools_menu=None, _onStart=False, filterOn=None, pickerPars=None, centerPaneCb=None, editorEnabled=None, parentLock='^status.locked', reloader=None, externalChanges=None, addOnCb=None, zoom=True, hasToolbar=False, canSort=True, configurable=None, dropCodes=None, **kwargs): """This method returns a grid (includedView) for viewing and selecting rows from a many to many table related to the main table, and it returns the widget that allows to edit data. You can edit data of a single row (record) using a form (formPars), or picking some rows from another table with the picker widget (pickerPars). The form can be contained inside a dialog or a contentPane and is useful to edit a single record. If the data is stored inside another table you should use the picker to select the rows from that table. :param parentBC: MANDATORY - parentBC is a :ref:`bordercontainer` .. note:: The includedViewBox and its sons can only accept the borderContainer layout container :param nodeId: the includedViewbox's Id. For more information, check :ref:`nodeid` page :param table: the :ref:`database table <table>` name on which the query will be executed, in the form ``packageName.tableName`` (packageName is the name of the :ref:`package <packages>` to which the table belongs to) :param datapath: allow to create a hierarchy of your data’s addresses into the datastore. For more information, check the :ref:`datapath` and the :ref:`datastore` pages :param storepath: the path of the data of the includedViewBox :param selectionPars: TODO **selectionPars parameters**: * applymethod: TODO * where: the sql "WHERE" clause. For more information check the :ref:`sql_where` section. :param formPars: (dict) it contains all the params of the widget who hosts the form. . **formPars parameters:** * mode: `dialog` / `pane` * height: the dialog's height * width: the dialog's width * formCb: MANDATORY - callback method used to create the form **formCb parameters:** * formBorderCont: a :ref:`bordercontainer` used as root for the formCb's construction. * datapath: allow to create a hierarchy of your data’s addresses into the datastore. For more information, check the :ref:`datapath` and the :ref:`datastore` pages. * region: 'center' of the pane/borderContainer where you place it into * toolbarHandler: OPTIONAL - a callback for the form toolbar * title: MANDATORY - for dialog mode * pane: OPTIONAL - pane of the form input :param label: (string) allow to create a label for the includedView :param caption: TODO :param footer: TODO :param add_action: (boolean) allow the insertion of a row in the includedView :param add_class: the css class of the add button :param add_enable: a path to enable/disable add action :param del_action: (boolean) allow the deleting of a row in the includedView :param del_class: the css class of the delete button :param del_enable: a path to enable/disable del action :param upd_action: TODO :param upd_class: TODO :param upd_enable: TODO :param close_action: (boolean) adding closing button in tooltipDialog :param close_class: css class of close button :param print_action: TODO :param print_class: TODO :param pdf_action: TODO :param pdf_class: TODO :param pdf_name: TODO :param export_action: TODO :param export_class: TODO :param tools_action: TODO :param tools_class: TODO :param tools_enable: TODO :param tools_lbl: TODO :param lock_action: an optional parameter; TODO :param tools_menu: TODO :param _onStart: boolean. If ``True``, the controller is executed only after that all the line codes are read :param filterOn: (boolean, only for picker) allow the filter into the picker grid :param pickerPars: (dict) it contains all the params of the tooltip dialog which host the picker grid **Parameters:** * height: height of the tooltipdialog * width: width of the tooltipdialog * label: label of the tooltipdialog * table: MANDATORY - the table of the picker grid. From this table you can pick a row for the many to many table you handle * columns: MANDATORY - columns of the picker grid * nodeId: MANDATORY - id for the picker * filterOn: the columns on which to apply filter :param centerPaneCb: TODO :param editorEnabled: TODO :param parentLock: TODO :param reloader: TODO :param externalChanges: TODO :param addOnCb: TODO :param zoom: It allows to open the linked record in a :ref:`dialog`. For further details, check the :ref:`zoom` documentation page :param hasToolbar: TODO :param canSort: TODO :param fromPicker_target_fields: allow to bind the picker's table. columns to the includedView columns of the many to many table. :param fromPicker_nodup_field: if this column value is present in the includedView it allows to replace that row instead of adding a duplicate row :param \*\*kwargs: **autowidth**, **storepath**, etc""" if storepath: assert not storepath.startswith('^') and not storepath.startswith('='),\ "storepath should be a plain datapath, no ^ or =" if not datapath: if storepath.startswith('.'): inherited_attributes = parentBC.parentNode.getInheritedAttributes( ) #assert inherited_attributes.has_key('sqlContextRoot'),\ #'please specify an absolute storepath, if sqlContextRoot is not available' #storepath = '%s%s' % (inherited_attributes['sqlContextRoot'], storepath) storepath = '#FORM.record%s' % storepath viewPars = dict(kwargs) gridId = nodeId or self.getUuid() viewPars['nodeId'] = gridId if dropCodes: for dropCode in dropCodes.split(','): mode = 'grid' if ':' in dropCode: dropCode, mode = dropCode.split(':') dropmode = 'dropTarget_%s' % mode viewPars[dropmode] = '%s,%s' % ( viewPars[dropmode], dropCode) if dropmode in viewPars else dropCode viewPars['onDrop_%s' % dropCode] = 'FIRE .dropped_%s = data' % dropCode viewPars[ 'onCreated'] = """dojo.connect(widget,'_onFocus',function(){genro.publish("show_palette_%s")})""" % dropCode #provo?si # controllerPath = datapath or 'grids.%s' % gridId storepath = storepath or '.selection' viewPars['storepath'] = storepath viewPars['controllerPath'] = controllerPath controller = parentBC.dataController(datapath=controllerPath) assert not 'selectedIndex' in viewPars viewPars['selectedIndex'] = '^.selectedIndex' assert not 'selectedLabel' in viewPars if not viewPars.get('selectedId'): viewPars['selectedId'] = '^.selectedId' viewPars['selectedLabel'] = '^.selectedLabel' label_pars = dict([(k[6:], kwargs.pop(k)) for k in kwargs.keys() if k.startswith('label_')]) label_pars['_class'] = label_pars.pop( 'class', None) or (not hasToolbar and 'pbl_viewBoxLabel') box_pars = dict([(k[4:], kwargs.pop(k)) for k in kwargs.keys() if k.startswith('box_')]) box_pars['_class'] = (box_pars.pop('class', None) or 'pbl_viewBox') if label is not False: gridtop = parentBC.contentPane(region='top', datapath=controllerPath, overflow='hidden', childname='top', nodeId='%s_top' % gridId, **label_pars) if hasToolbar is True: gridtop = gridtop.toolbar(_class='pbl_viewBoxToolbar') gridtop_left = gridtop.div(float='left') if callable(label): label(gridtop_left) else: gridtop_left.div(label, margin_top='2px', float='left') gridtop_right = gridtop.div(float='right', childname='right') if filterOn: gridtop_filter = gridtop_right.div(float='left', margin_right='5px') self.gridFilterBox(gridtop_filter, gridId=gridId, filterOn=filterOn, table=table) if print_action or export_action or tools_menu or tools_action or pdf_action: gridtop_actions = gridtop_right.div(float='left', margin_right='5px') self._iv_gridAction(gridtop_actions, print_action=print_action, export_action=export_action, export_class=export_class, print_class=print_class, tools_class=tools_class, tools_menu=tools_menu, tools_action=tools_action, pdf_action=pdf_action, pdf_class=pdf_class, pdf_name=pdf_name, table=table, gridId=gridId, tools_enable=tools_enable, tools_lbl=tools_lbl) if add_action or del_action or upd_action: gridtop_add_del = gridtop_right.div(float='left', margin_right='5px', childname='add_del') self._iv_gridAddDel(gridtop_add_del, add_action=add_action, del_action=del_action, upd_action=upd_action, upd_class=upd_class, upd_enable=upd_enable, add_class=add_class, add_enable=add_enable, del_class=del_class, del_enable=del_enable, pickerPars=pickerPars, formPars=formPars, gridId=gridId) if lock_action: gridtop_lock = gridtop_right.div(float='left', margin_right='5px') self._iv_gridLock(gridtop_lock, lock_action=lock_action) if footer: assert callable(footer), 'footer param must be a callable' footerPars = dict([(k[7:], v) for k, v in kwargs.items() if k.startswith('footer_')]) if not 'height' in footerPars: footerPars['height'] = '18px' if not '_class' in footerPars: footerPars['_class'] = 'pbl_roundedGroupBottom' gridbottom = parentBC.contentPane(region='bottom', datapath=controllerPath, **footerPars) footer(gridbottom) self._iv_IncludedViewController(controller, gridId, controllerPath, table=table) if centerPaneCb: gridcenter = getattr(self, centerPaneCb)(parentBC, region='center', datapath=controllerPath, **box_pars) else: gridcenter = parentBC.contentPane(region='center', datapath=controllerPath, **box_pars) viewPars['structpath'] = viewPars.get( 'structpath') or '.struct' or 'grids.%s.struct' % nodeId if filterOn is True: gridcenter.dataController("""var colsMenu = new gnr.GnrBag(); struct.forEach(function(n){ colsMenu.setItem(n.label, null, {col:n.attr.field, caption:n.attr.name}) }); SET .flt.colsMenu = colsMenu;""", struct='^%s.view_0.row_0' % viewPars['structpath']) if parentLock: gridcenter.dataFormula(".editorEnabled", "parentLock==null?false:!parentLock", parentLock=parentLock) elif parentLock is False: editorEnabled = True if caption: innerbc = gridcenter.borderContainer() caption_pars = dictExtract(viewPars, 'caption_', pop=True) innerbc.contentPane(region='top').div(caption, **caption_pars) gridcenter = innerbc.contentPane(region='center') view = gridcenter.includedView(extension='includedViewPicker', table=table, editorEnabled=editorEnabled or '^.editorEnabled', reloader=reloader, **viewPars) if addOnCb: addOnCb(gridcenter) if _onStart: controller.dataController("FIRE .reload", _onStart=True) if externalChanges: externalChangesTypes = '' if isinstance(externalChanges, basestring): if ':' in externalChanges: externalChanges, externalChangesTypes = externalChanges.split( ':') if externalChanges == '*': externalChanges = True subscribed_tables = [ t for t in getattr(self, 'subscribed_tables', '').split(',') if t ] assert table in subscribed_tables, "table %s must be subscribed to get externalChanges" % table event_path = 'gnr.dbevent.%s' % table.replace('.', '_') pars = dict() conditions = list() if isinstance(externalChanges, basestring): for fld in externalChanges.split(','): fldname, fldpath = fld.split('=') conditions.append('genro.isEqual(curr_%s,event_%s)' % (fldname, fldname)) pars['event_%s' % fldname] = '=%s.%s' % (event_path, fldname) pars['curr_%s' % fldname] = '=%s' % fldpath if externalChangesTypes: conditions.append('evtypes.indexOf(evtype)>=0') pars['evtypes'] = externalChangesTypes pars['evtype'] = '=%s?dbevent' % event_path gridcenter.dataController("FIRE .reload;", _if=' && '.join(conditions), _fired='^%s' % event_path, **pars) if selectionPars: self._iv_includedViewSelection(gridcenter, gridId, table, storepath, selectionPars, controllerPath) if formPars: formPars.setdefault('pane', gridcenter) self._includedViewForm(controller, controllerPath, view, formPars) if pickerPars: pickerPars.setdefault('pane', gridcenter) self._iv_Picker(controller, controllerPath, view, pickerPars) return view
def pk_palettePicker(self,pane,grid=None,table=None,relation_field=None,paletteCode=None, viewResource=None,searchOn=True,multiSelect=True, title=None,autoInsert=None,dockButton=True,picker_kwargs=None, height=None,width=None,**kwargs): one = False picker_kwargs = picker_kwargs or dict() condition=picker_kwargs.pop('condition',None) condition_kwargs = dictExtract(picker_kwargs,'condition_',pop=True,slice_prefix=True) many = relation_field or picker_kwargs.get('relation_field',None) table = table or picker_kwargs.get('table',None) height = height or picker_kwargs.get('height') width = width or picker_kwargs.get('width') if autoInsert is None: autoInsert = picker_kwargs.get('autoInsert',True) title = title or picker_kwargs.get('title') viewResource = viewResource or picker_kwargs.get('viewResource') if viewResource is True: viewResource = ':ViewPicker' searchOn = searchOn or picker_kwargs.get('searchOn') paletteCode = paletteCode or picker_kwargs.get('paletteCode') maintable = None if grid: maintable = grid.getInheritedAttributes()['table'] if not table: tblobj = self.db.table(maintable).column(many).relatedTable().dbtable table = tblobj.fullname else: tblobj = self.db.table(table) elif table: tblobj = self.db.table(table) paletteCode = paletteCode or '%s_picker' %table.replace('.','_') title = title or tblobj.name_long oldtreePicker = hasattr(tblobj,'htableFields') and not viewResource treepicker = tblobj.attributes.get('hierarchical') and not viewResource if oldtreePicker: self.mixinComponent('gnrcomponents/htablehandler:HTableHandlerBase') palette = pane.paletteTree(paletteCode=paletteCode,dockButton=dockButton,title=title, tree_dragTags=paletteCode,searchOn=searchOn,width=width,height=height).htableStore(table=table) elif treepicker: palette = pane.paletteTree(paletteCode=paletteCode,dockButton=dockButton,title=title, tree_dragTags=paletteCode,searchOn=searchOn,width=width,height=height).htableViewStore(table=table) elif viewResource: palette = pane.palettePane(paletteCode=paletteCode,dockButton=dockButton, title=title,width=width,height=height) paletteth = palette.plainTableHandler(table=table,viewResource=viewResource, grid_onDrag='dragValues["%s"]=dragValues.gridrow.rowset;' %paletteCode, grid_multiSelect=multiSelect, title=title,searchOn=searchOn,configurable=False, childname='picker_tablehandler') if condition: paletteth.view.store.attributes.update(where=condition,**condition_kwargs) if not condition_kwargs: paletteth.view.store.attributes.update(_onStart=True) if grid: paletteth.view.grid.attributes.update(filteringGrid=grid.js_sourceNode(),filteringColumn='_pkey:%s' %many) elif tblobj.attributes.get('caption_field'): def struct(struct): r = struct.view().rows() r.fieldcell(tblobj.attributes['caption_field'], name=tblobj.name_long, width='100%') sortedBy = tblobj.attributes.get('caption_field') paletteGridKwargs = dict(paletteCode=paletteCode,struct=struct,dockButton=dockButton, grid_multiSelect=multiSelect, title=title,searchOn=searchOn, width=width,height=height) if grid: paletteGridKwargs['grid_filteringGrid']=grid paletteGridKwargs['grid_filteringColumn'] = '_pkey:%s' %many condition_kwargs.setdefault('_onStart',True) palette = pane.paletteGrid(**paletteGridKwargs).selectionStore(table=table,sortedBy=sortedBy or 'pkey',condition=condition,**condition_kwargs) if grid: grid.dragAndDrop(paletteCode) if autoInsert: method = getattr(tblobj,'insertPicker',self._th_insertPicker) formNode = pane.parentNode.attributeOwnerNode('formId') if formNode: formtblobj = self.db.table(formNode.attr.get('table')) oneJoiner = formtblobj.model.getJoiner(maintable) one = oneJoiner.get('many_relation').split('.')[-1] grid.dataController(""" var kw = {dropPkey:mainpkey,tbl:tbl,one:one,many:many}; if(treepicker){ kw.dragPkeys = [data['pkey']]; }else{ var pkeys = []; dojo.forEach(data,function(n){pkeys.push(n['_pkey'])}); kw.dragPkeys = pkeys; } kw['_sourceNode'] = this; if(grid.gridEditor && grid.gridEditor.editorPars){ var rows = []; dojo.forEach(kw.dragPkeys,function(fkey){ var r = {}; r[many] = fkey; rows.push(r); }); grid.gridEditor.addNewRows(rows); }else if(mainpkey){ genro.serverCall(rpcmethod,kw,function(){},null,'POST'); } """,data='^.dropped_%s' %paletteCode,mainpkey='=#FORM.pkey', rpcmethod=method,treepicker=oldtreePicker or treepicker or False,tbl=maintable, one=one,many=many,grid=grid.js_widget) return palette