def _subst(self, which, wdex): """ Do completion. Params which Which variant to use 'next' / 'prev' / '#N' wdex What list to use 'word' / 'expr' / 'curr' """ pass #LOG and log('which, wdex={}',(which, wdex)) if wdex!='curr' and \ not self._prep_sess(wdex): return if not self.sess.bids: return app.msg_status(_('No in-text completions')) shft = 1 if which == 'next' else -1 if which == 'prev' else 0 bids_i = int(which) if which.isdigit() else \ self.sess.bids_i + shft if self.incr_bfr else \ self.sess.bids_i bids_i = bids_i % len(self.sess.bids) sub_s = self.sess.bids[bids_i] add_s = sub_s[len(self.sess.src_what):] pass #LOG and log('i, sub_s, add_s={}',(bids_i, sub_s, add_s)) if self.sess.added: ed.cmd(cmds.cCommand_Undo) pass #LOG and log('undo mod_ver, line={}',(ed.get_prop(app.PROP_MODIFIED_VERSION), ed.get_text_line(self.sess.row))) ed.delete(self.sess.src_kill_b, self.sess.row, self.sess.src_kill_e, self.sess.row) pass #LOG and log('kill mod_ver, line={}',(ed.get_prop(app.PROP_MODIFIED_VERSION), ed.get_text_line(self.sess.row))) ed.insert(self.sess.src_what_e, self.sess.row, add_s) pass #LOG and log('insr mod_ver, line={}',(ed.get_prop(app.PROP_MODIFIED_VERSION), ed.get_text_line(self.sess.row))) self.sess.added = True if False: pass elif self.sess.sel_sub == 'be': ed.set_caret(self.sess.src_what_e + len(add_s), self.sess.row, self.sess.src_what_b, self.sess.row) elif self.sess.sel_sub == 'eb': ed.set_caret(self.sess.src_what_b, self.sess.row, self.sess.src_what_e + len(add_s), self.sess.row) else: ed.set_caret(self.sess.src_what_e + len(add_s), self.sess.row) # ed.set_caret(self.sess.src_crt, self.sess.row) self.sess.pre_mver = ed.get_prop(app.PROP_MODIFIED_VERSION) self.sess.pre_crt0 = ed.get_carets()[0] # next_i = (self.sess.bids_i+shft) % len(self.sess.bids) # next_info = '' if 1==len(self.sess.bids) else \ # f(_('. Next #{}: "{}"'), next_i, self.sess.bids[next_i][:50]) # app.msg_status(f(_('In-text completion #{} ({}){}'), 1+self.sess.bids_i, len(self.sess.bids), next_info)) app.msg_status( f(_('In-text completion #{} ({})'), 1 + self.sess.bids_i, len(self.sess.bids))) # shft = 1 if which=='next' or which[0]=='#' else -1 self.sess.bids_i = bids_i self.incr_bfr = True
def _subst(self, which, wdex): """ Do completion. Params which Which variant to use 'next' / 'prev' / '#N' wdex What list to use 'word' / 'expr' / 'curr' """ pass; #LOG and log('which, wdex={}',(which, wdex)) if wdex!='curr' and \ not self._prep_sess(wdex): return if not self.sess.bids: return app.msg_status(_('No in-text completions')) shft = 1 if which=='next' else -1 if which=='prev' else 0 bids_i = int(which) if which.isdigit() else \ self.sess.bids_i + shft if self.incr_bfr else \ self.sess.bids_i bids_i = bids_i % len(self.sess.bids) sub_s = self.sess.bids[bids_i] add_s = sub_s[len(self.sess.src_what):] pass; #LOG and log('i, sub_s, add_s={}',(bids_i, sub_s, add_s)) if self.sess.added: ed.cmd(cmds.cCommand_Undo) pass; #LOG and log('undo mod_ver, line={}',(ed.get_prop(app.PROP_MODIFIED_VERSION), ed.get_text_line(self.sess.row))) ed.delete( self.sess.src_kill_b, self.sess.row ,self.sess.src_kill_e, self.sess.row) pass; #LOG and log('kill mod_ver, line={}',(ed.get_prop(app.PROP_MODIFIED_VERSION), ed.get_text_line(self.sess.row))) ed.insert( self.sess.src_what_e, self.sess.row, add_s) pass; #LOG and log('insr mod_ver, line={}',(ed.get_prop(app.PROP_MODIFIED_VERSION), ed.get_text_line(self.sess.row))) self.sess.added = True if False:pass elif self.sess.sel_sub=='be': ed.set_caret(self.sess.src_what_e+len(add_s), self.sess.row ,self.sess.src_what_b, self.sess.row) elif self.sess.sel_sub=='eb': ed.set_caret(self.sess.src_what_b, self.sess.row ,self.sess.src_what_e+len(add_s), self.sess.row) else: ed.set_caret(self.sess.src_what_e+len(add_s), self.sess.row) # ed.set_caret(self.sess.src_crt, self.sess.row) self.sess.pre_mver = ed.get_prop(app.PROP_MODIFIED_VERSION) self.sess.pre_crt0 = ed.get_carets()[0] # next_i = (self.sess.bids_i+shft) % len(self.sess.bids) # next_info = '' if 1==len(self.sess.bids) else \ # f(_('. Next #{}: "{}"'), next_i, self.sess.bids[next_i][:50]) # app.msg_status(f(_('In-text completion #{} ({}){}'), 1+self.sess.bids_i, len(self.sess.bids), next_info)) app.msg_status(f(_('In-text completion #{} ({})'), 1+self.sess.bids_i, len(self.sess.bids))) # shft = 1 if which=='next' or which[0]=='#' else -1 self.sess.bids_i = bids_i self.incr_bfr = True
def do_code(self, aid, ag): m,M = self,CfgKeysDlg lwks_n = ag.cval('lwks') if lwks_n==-1: return [] #continue#while m.cmd_id = m.fl_Is[lwks_n] pass; #LOG and log('m.fl_Is={}',(m.fl_Is)) pass; #LOG and log('lwks_n,m.cmd_id={}',(lwks_n,m.cmd_id)) if False:pass elif aid=='cpnm': cmd_nkk = m.id2nkks[m.cmd_id] app.app_proc(app.PROC_SET_CLIP, cmd_nkk[0]) elif aid=='open': pass; LOG and log('m.cmd_id={}',(m.cmd_id)) if type(m.cmd_id)!=str: return [] #continue#while plug_mdl, \ plug_mth = m.cmd_id.split(',')[0:2] plug_mth = 'def '+ plug_mth + '(self):' plug_dir = app.app_path(app.APP_DIR_PY)+os.sep+plug_mdl plug_py = plug_dir+os.sep+'__init__.py' plug_body = open(plug_py, encoding='UTF-8').read() pass; LOG and log('plug_mdl,plug_mth,plug_dir,plug_py={}',(plug_mdl,plug_mth,plug_dir,plug_py)) mch = re.search(r'from\s+\.(\w+)\s+import\s+Command', plug_body) if mch: # from .other_py import Command plug_py = plug_dir+os.sep+mch.group(1)+'.py' pass; LOG and log('plug_py={}',(plug_py)) plug_body=open(plug_py, encoding='UTF-8').read() if plug_mth not in plug_body: return [] #continue#while # Open app.file_open(plug_py) # Locate user_opt= app.app_proc(app.PROC_GET_FINDER_PROP, '') \ if app.app_api_version()>='1.0.248' else \ app.app_proc(app.PROC_GET_FIND_OPTIONS, '') # Deprecated ed.cmd(cmds.cmd_FinderAction, chr(1).join([] +['findnext'] +[plug_mth] +[''] +['fa'] )) if app.app_api_version()>='1.0.248': app.app_proc(app.PROC_SET_FINDER_PROP, user_opt) else: app.app_proc(app.PROC_SET_FIND_OPTIONS, user_opt) # Deprecated return None #break#while return []
def do_code(self, aid, ag, data=''): m,M = self,self.__class__ lwks_n = ag.cval('lwks') if lwks_n==-1: return [] #continue#while m.cmd_id = m.fl_Is[lwks_n] pass; #LOG and log('m.fl_Is={}',(m.fl_Is)) pass; #LOG and log('lwks_n,m.cmd_id={}',(lwks_n,m.cmd_id)) if False:pass elif aid=='cpnm': cmd_nkk = m.id2nkks[m.cmd_id] app.app_proc(app.PROC_SET_CLIP, cmd_nkk[0]) elif aid=='open': pass; LOG and log('m.cmd_id={}',(m.cmd_id)) if type(m.cmd_id)!=str: return [] #continue#while plug_mdl, \ plug_mth = m.cmd_id.split(',')[0:2] plug_mth = 'def '+ plug_mth + '(self):' plug_dir = app.app_path(app.APP_DIR_PY)+os.sep+plug_mdl plug_py = plug_dir+os.sep+'__init__.py' plug_body = open(plug_py, encoding='UTF-8').read() pass; LOG and log('plug_mdl,plug_mth,plug_dir,plug_py={}',(plug_mdl,plug_mth,plug_dir,plug_py)) mch = re.search(r'from\s+\.(\w+)\s+import\s+Command', plug_body) if mch: # from .other_py import Command plug_py = plug_dir+os.sep+mch.group(1)+'.py' pass; LOG and log('plug_py={}',(plug_py)) plug_body=open(plug_py, encoding='UTF-8').read() if plug_mth not in plug_body: return [] #continue#while # Open app.file_open(plug_py) # Locate user_opt= app.app_proc(app.PROC_GET_FINDER_PROP, '') \ if app.app_api_version()>='1.0.248' else \ app.app_proc(app.PROC_GET_FIND_OPTIONS, '') # Deprecated ed.cmd(cmds.cmd_FinderAction, chr(1).join([] +['findnext'] +[plug_mth] +[''] +['fa'] )) if app.app_api_version()>='1.0.248': app.app_proc(app.PROC_SET_FINDER_PROP, user_opt) else: app.app_proc(app.PROC_SET_FIND_OPTIONS, user_opt) # Deprecated return None #break#while return []
def do_setv(self, aid, ag, data): M,m = self.__class__,self pass; #LOG and log('aid,m.cur_op={}',(aid,m.cur_op)) if not m.cur_op: return [] #m.col_ws= [ci['wd'] for ci in m.ag.cattr('lvls', 'cols')] cur_val = data trg = 'lexer '+m.lexr+'.json' if m.for_ulf=='l' else 'user.join' key4v = m.for_ulf+'val' op = m.cur_op oi = m.opts_full[op] frm = oi['frm'] dval = oi.get( 'def') uval = oi.get('uval') lval = oi.get('lval') fval = oi.get('fval') ulfvl = oi.get(key4v ) #fval if m.for_ulf=='f' else lval if m.for_ulf=='l' else uval jval = oi['jlvl'] if m.for_ulf=='l' else \ oi['juvl'] if m.for_ulf=='u' else \ oi['jfvl'] # Get new value newv = None erpt_s = '' if False:pass elif aid=='setd' and m.for_ulf=='f' and op in apx.OPT2PROP: # Remove from file - set over def/user/lex val newv = oi.get('lval', oi.get('uval', oi.get('def'))) if newv==ulfvl: #m.stbr_act(M.STBR_MSG, _('No need changes')) return [] erpt_s = 'reset-f' m.ed.set_prop(apx.OPT2PROP[op], newv) elif aid=='setd' and ulfvl is not None and m.for_ulf!='f': # Remove from user/lexer newv= None elif aid=='setv': # Add/Set opt for user/lexer/file # Enter from edit. Need parse some string #newv = m.ag.cval('eded') newv = cur_val try: newv = int(newv) if frm=='int' else \ float(newv) if frm=='float' else \ newv except Exception as ex: app.msg_box(f(_('Incorrect value. It\'s needed in format: {}'), frm) , app.MB_OK+app.MB_ICONWARNING) return d(form=d(fid='eded')) if frm=='#rgb' or frm=='#rgb-e' and newv: # Testing new val try: apx.html_color_to_int(newv) except Exception as ex: app.msg_box(f(_('Incorrect value. It\'s needed in format: {}'), '#RGB or #RRGGBB') , app.MB_OK+app.MB_ICONWARNING) return d(form=d(fid='eded')) ### Use new value to change env if newv is not None and newv==ulfvl: #m.stbr_act(M.STBR_MSG, _('No need changes')) return [] if m.for_ulf=='f' and newv is not None and op in apx.OPT2PROP: # Change for file erpt_s = 'set-f' ed.set_prop(apx.OPT2PROP[op], newv) if m.for_ulf!='f': # Change target file pass; #LOG and log('?? do_erpt',()) erpt_s =('reset-u' if newv is None and m.for_ulf=='u' else 'reset-l' if newv is None and m.for_ulf=='l' else 'add-u' if ulfvl is None and m.for_ulf=='u' else 'add-l' if ulfvl is None and m.for_ulf=='l' else 'set-u' if m.for_ulf=='u' else 'set-l' if m.for_ulf=='l' else '') pass; #LOG and log('?? set_opt',()) apx.set_opt(op ,newv ,apx.CONFIG_LEV_LEX if m.for_ulf=='l' else apx.CONFIG_LEV_USER ,ed_cfg =None ,lexer =m.lexr if m.for_ulf=='l' else None ,user_json=m.how.get('stor_json', 'user.json') ) if not m.apply_one: pass; #LOG and log('?? OpsReloadAndApply',()) ed.cmd(cmds.cmd_OpsReloadAndApply) else: m.apply_need = True # Use new value to change dlg data pass; #LOG and log('?? oi={}',(oi)) pass; #LOG and log('?? m.opts_full={}',pf(m.opts_full)) if False:pass elif aid=='setd': oi.pop(key4v, None) if m.for_ulf!='f' else 0 else: pass; #LOG and log('key4v, newv={}',(key4v, newv)) oi[key4v] = newv pass; #LOG and log('oi={}',(oi)) upd_cald_vals(m.opts_full) pass; #LOG and log('oi={}',(oi)) jnewv = oi['jlvl'] if m.for_ulf=='l' else oi['juvl'] if m.for_ulf=='u' else oi['jfvl'] #m.do_erpt(erpt_s, jnewv, jval) pass; #LOG and log('ok oi={}',(oi)) pass; #LOG and log('ok m.opts_full={}',pf(m.opts_full)) pass; #LOG and log('?? get_cnts',()) if m.for_ulf!='f' and m.auto4file and op in apx.OPT2PROP: # Change FILE to over (("over" - override?)) newv = oi.get('lval', oi.get('uval', oi.get('def'))) if newv!=oi.get('fval'): erpt_s = 'reset-f' m.ed.set_prop(apx.OPT2PROP[op], newv) oi['fval'] = newv jval = oi['jfvl'] upd_cald_vals(m.opts_full) jnewv = oi['jfvl'] #m.do_erpt('auset-f', jnewv, jval) pass; #LOG and log('m.get_vals(lvls-cur)={}',(m.get_vals('lvls-cur')))
def add_indented_line_below(self): ed.cmd(cmds.cCommand_KeyEnd) ed.cmd(cmds.cCommand_KeyEnter)
def add_indented_line_above(self): ed.cmd(cmds.cCommand_KeyUp) ed.cmd(cmds.cCommand_KeyEnd) ed.cmd(cmds.cCommand_KeyEnter)
def dlg_config(self): ''' Show dlg for change macros list. ''' if app.app_api_version()<FROM_API_VERSION: return app.msg_status('Need update CudaText') keys_json = app.app_path(app.APP_DIR_SETTINGS)+os.sep+'keys.json' keys = apx._json_loads(open(keys_json).read()) if os.path.exists(keys_json) else {} GAP = 5 ids = [mcr['id'] for mcr in self.macros] mcr_ind = ids.index(self.last_mcr_id) if self.last_mcr_id in ids else -1 pass; LOG and log('self.last_mcr_id, mcr_ind={}',(self.last_mcr_id,mcr_ind)) times = 1 waits = 5 chngs = '0' endln = '0' while True: (WD_LST ,HT_LST)= (self.dlg_prs.get('w_list', 300) ,self.dlg_prs.get('h_list', 500)) (WD_ACTS ,HT_ACTS)=(self.dlg_prs.get('w_acts', 300) ,self.dlg_prs.get('h_acts', 500)) (WD_BTN ,HT_BTN)= (self.dlg_prs.get('w_btn', 150), 24) l_btn = GAP+WD_LST+GAP vw_acts = (WD_ACTS>0) WD_ACTS = max(0, WD_ACTS) rec_on = ed.get_prop(app.PROP_MACRO_REC) lmcrs = len(self.macros) pass; LOG and log('mcr_ind,vw_acts,rec_on={}',(mcr_ind,vw_acts,rec_on)) nmkys = [] for mcr in self.macros: mcr_cid = 'cuda_macros,run,{}'.format(mcr['id']) mcr_keys= keys.get(mcr_cid, {}) kys = '/'.join([' * '.join(mcr_keys.get('s1', [])) ,' * '.join(mcr_keys.get('s2', [])) ]).strip('/') nmkys += [mcr['nm'] + (' ['+kys+']' if kys else '')] mcr_acts= '' if vw_acts and mcr_ind in range(lmcrs): mcr = self.macros[mcr_ind] mcr_acts= '\t'.join(['# '+nmkys[mcr_ind]] + mcr['evl']) ans = app.dlg_custom('Macros' ,GAP+WD_LST+GAP+WD_BTN+GAP+WD_ACTS+GAP,GAP+HT_LST+GAP, '\n'.join([] +[C1.join(['type=listbox' ,POS_FMT(l=GAP, t=GAP, r=GAP+WD_LST, b=GAP+HT_LST) ,'items=' +'\t'.join(nmkys) ,'val=' +str(mcr_ind) # start sel ,'en=' +str(0 if rec_on else 1) # enabled ] # i=0 )] +([C1.join(['type=button' ,POS_FMT(l=l_btn, t=GAP*1+HT_BTN*0, r=l_btn+WD_BTN, b=0) ,'cap=&View actions...' ,'props=' +str(0 if rec_on or 0==lmcrs else 1) # default ,'en=' +str(0 if rec_on or 0==lmcrs else 1) # enabled ] # i=1 )] if vw_acts else []) +[C1.join(['type=button' ,POS_FMT(l=l_btn, t=GAP*2+HT_BTN*1, r=l_btn+WD_BTN, b=0) ,'cap=Hot&keys...' ,'en=' +str(0 if rec_on or 0==lmcrs else 1) # enabled ] # i=2 if vw_acts else i=1 )] +[C1.join(['type=button' ,POS_FMT(l=l_btn, t=GAP*3+HT_BTN*2, r=l_btn+WD_BTN, b=0) ,'cap=Re&name...' ,'en=' +str(0 if rec_on or 0==lmcrs else 1) # enabled ] # i=3 if vw_acts else i=2 )] +[C1.join(['type=button' ,POS_FMT(l=l_btn, t=GAP*4+HT_BTN*3, r=l_btn+WD_BTN, b=0) ,'cap=&Delete...' ,'en=' +str(0 if rec_on or 0==lmcrs else 1) # enabled ] # i=4 if vw_acts else i=3 )] +[C1.join(['type=button' ,POS_FMT(l=l_btn, t=GAP*6+HT_BTN*5, r=l_btn+WD_BTN, b=0) ,'cap=&Run!' ,'props=' +str(1 if not vw_acts and not rec_on else 0) # default ,'en=' +str(0 if rec_on or 0==lmcrs else 1) # enabled ] # i=5 if vw_acts else i=4 )] +[C1.join(['type=label' ,POS_FMT(l=l_btn, t=GAP*7+HT_BTN*6+3, r=l_btn+int(WD_BTN/3),b=0) ,'cap=&Times' ] # i=6 if vw_acts else i=5 )] +[C1.join(['type=spinedit' ,POS_FMT(l=l_btn+int(WD_BTN/3)+GAP, t=GAP*7+HT_BTN*6, r=l_btn+WD_BTN, b=0) ,'val=' +str(times) ,'props=0,{},1'.format(self.dlg_prs.get('times', 1000)) ,'en=' +str(0 if rec_on else 1) # enabled ] # i=7 if vw_acts else i=6 )] +[C1.join(['type=label' ,POS_FMT(l=l_btn, t=GAP*8+HT_BTN*7+3, r=l_btn+int(WD_BTN/3),b=0) ,'cap=&Wait' ] # i=8 if vw_acts else i=7 )] +[C1.join(['type=spinedit' ,POS_FMT(l=l_btn+int(WD_BTN/3)+GAP, t=GAP*8+HT_BTN*7, r=l_btn+WD_BTN-40, b=0) ,'val=' +str(waits) ,'props=1,3600,1' ,'en=' +str(0 if rec_on else 1) # enabled ] # i=9 if vw_acts else i=8 )] +[C1.join(['type=label' ,POS_FMT(l=l_btn+WD_BTN-40+GAP, t=GAP*8+HT_BTN*7+3, r=l_btn+WD_BTN,b=0) ,'cap=sec' ] # i=10 if vw_acts else i=9 )] +[C1.join(['type=check' ,POS_FMT(l=l_btn, t=GAP*9+HT_BTN*8, r=l_btn+WD_BTN,b=0) ,'cap=While text c&hanges' ,'val=' +chngs ] # i=11 if vw_acts else i=10 )] +[C1.join(['type=check' ,POS_FMT(l=l_btn, t=GAP*10+HT_BTN*9, r=l_btn+WD_BTN,b=0) ,'cap=Until c&aret on last line' ,'val=' +endln ] # i=12 if vw_acts else i=11 )] +[C1.join(['type=button' ,POS_FMT(l=l_btn, t=GAP*12+HT_BTN*11, r=l_btn+WD_BTN, b=0) ,'cap={}'.format('&Stop record' if rec_on else '&Start record') ,'props=' +str(1 if rec_on or 0==lmcrs else 0) # default ] # i=13 if vw_acts else i=12 )] +[C1.join(['type=button' ,POS_FMT(l=l_btn, t=GAP*13+HT_BTN*12, r=l_btn+WD_BTN, b=0) ,'cap=Canc&el record' ,'en=' +str(1 if rec_on else 0) # enabled ] # i=14 if vw_acts else i=13 )] +[C1.join(['type=button' ,POS_FMT(l=l_btn, t= HT_LST-HT_BTN*2, r=l_btn+WD_BTN, b=0) ,'cap=C&ustom...' ,'en=' +str(0 if rec_on else 1) # enabled ] # i=15 if vw_acts else i=14 )] +[C1.join(['type=button' ,POS_FMT(l=l_btn, t=GAP+HT_LST-HT_BTN*1, r=l_btn+WD_BTN, b=0) ,'cap=&Close' ] # i=16 if vw_acts else i=15 )] +([C1.join(['type=memo' ,POS_FMT(l=GAP+WD_LST+GAP+WD_BTN+GAP, t=GAP, r=GAP+WD_LST+GAP+WD_BTN+GAP+WD_ACTS, b=GAP+HT_ACTS) ,'val='+mcr_acts ,'props=1,1,1' # ro,mono,border ] # i=17 )] if vw_acts else []) ), apx.icase( vw_acts and not rec_on, 0 # View ,not vw_acts and not rec_on, 0 # View , vw_acts and rec_on, 11 ,not vw_acts and rec_on, 10 )) # start focus pass; LOG and log('ans={}',ans) if ans is None: break #while (ans_i ,vals) = ans ans_s = apx.icase(False,'' ,vw_acts and ans_i==1, 'view' ,vw_acts and ans_i==2, 'hotkeys' ,not vw_acts and ans_i==1, 'hotkeys' ,vw_acts and ans_i==3, 'rename' ,not vw_acts and ans_i==2, 'rename' ,vw_acts and ans_i==4, 'delete' ,not vw_acts and ans_i==3, 'delete' ,vw_acts and ans_i==5, 'run' ,not vw_acts and ans_i==4, 'run' ,vw_acts and ans_i==12,'rec' ,not vw_acts and ans_i==7, 'rec' ,vw_acts and ans_i==14,'cancel' ,not vw_acts and ans_i==13,'cancel' ,vw_acts and ans_i==15,'custom' ,not vw_acts and ans_i==14,'custom' ,vw_acts and ans_i==16,'close' ,not vw_acts and ans_i==15,'close' ,'?') mcr_ind = int(vals.splitlines()[0]) times = int(vals.splitlines()[ 7 if vw_acts else 6]) waits = int(vals.splitlines()[ 9 if vw_acts else 8]) chngs = vals.splitlines()[11 if vw_acts else 10] endln = vals.splitlines()[12 if vw_acts else 11] pass; LOG and log('mcr_ind,times,waits,chngs,endln={}',(mcr_ind,times,waits,chngs,endln)) if 0!=lmcrs and mcr_ind in range(lmcrs): mcr = self.macros[mcr_ind] self.last_mcr_id = mcr['id'] if ans_s=='close': break #while if ans_s=='custom': #Custom custs = app.dlg_input_ex(5, 'Custom dialog Macros' , 'Height of macro list (min 450)' , str(self.dlg_prs.get('h_list', 400)) , 'Width of macro list (min 200)' , str(self.dlg_prs.get('w_list', 500)) , 'Width of action list (min 200, <=0-hide)', str(self.dlg_prs.get('w_acts', 500)) , 'Width of buttons (min 150)' , str(self.dlg_prs.get('w_btn', 150)) , 'Max run times (min 100)' , str(self.dlg_prs.get('times', 1000)) ) if custs is not None: self.dlg_prs['h_list'] = max(450, int(custs[0])); self.dlg_prs['h_acts'] = self.dlg_prs['h_list'] self.dlg_prs['w_list'] = max(200, int(custs[1])) self.dlg_prs['w_acts'] = max(200, int(custs[2])) if int(custs[2])>0 else int(custs[2]) self.dlg_prs['w_btn'] = max(150, int(custs[3])) self.dlg_prs['times'] = max(100, int(custs[4])) open(MACROS_JSON, 'w').write(json.dumps({'ver':JSON_FORMAT_VER, 'list':self.macros, 'dlg_prs':self.dlg_prs}, indent=4)) continue #while if mcr_ind not in range(lmcrs): app.msg_box('Select macro', app.MB_OK) continue #while what = '' changed = False if False:pass elif ans_s=='view': #View continue #while elif ans_s=='rename': #Rename mcr_nm = app.dlg_input('New name for: {}'.format(nmkys[mcr_ind]) ,mcr['nm']) if mcr_nm is None or mcr_nm==mcr['nm']: continue #while while mcr_nm in [mcr['nm'] for mcr in self.macros]: app.msg_box('Select other name.\nMacro names now are:\n\n'+'\n'.join(nmkys), app.MB_OK) mcr_nm = app.dlg_input('New name for: {}'.format(nmkys[mcr_ind]) ,mcr_nm) if mcr_nm is None or mcr_nm==mcr['nm']: break #while mcr_nm if mcr_nm is None or mcr_nm==mcr['nm']: continue #while what = 'rename' mcr['nm'] = mcr_nm changed = True elif ans_s=='delete': #Del if app.msg_box( 'Delete macro\n {}'.format(nmkys[mcr_ind]) , app.MB_YESNO)!=app.ID_YES: continue #while what = 'delete:'+str(mcr['id']) del self.macros[mcr_ind] mcr_ind = min(mcr_ind, len(self.macros)-1) changed = True elif ans_s=='hotkeys': #Hotkeys app.dlg_hotkeys('cuda_macros,run,'+str(mcr['id'])) keys = apx._json_loads(open(keys_json).read()) if os.path.exists(keys_json) else {} changed = True elif ans_s=='run': #Run if (times==0 and waits==0 and chngs=='0' and endln=='0'): app.msg_box('Select stop condition', app.MB_OK) continue self.run(mcr['id'], max(0, times), max(0, waits), chngs=='1', endln=='1') return elif ans_s=='rec' and not rec_on: #Start record return ed.cmd(cmds.cmd_MacroStart) elif ans_s=='rec' and rec_on: #Stop record self.need_dlg = True return ed.cmd(cmds.cmd_MacroStop) # Return for clear rec-mode in StatusBar, will recall from on_macro elif ans_s=='cancel' and rec_on: #Cancel record return ed.cmd(cmds.cmd_MacroCancel) # Return for clear rec-mode in StatusBar if changed: self._do_acts(what)
def dlg_config(self): ''' Show dlg for change macros list. ''' if app.app_api_version()<FROM_API_VERSION: return app.msg_status(_('Need update CudaText')) keys_json = app.app_path(app.APP_DIR_SETTINGS)+os.sep+'keys.json' keys = apx._json_loads(open(keys_json).read()) if os.path.exists(keys_json) else {} ids = [mcr['id'] for mcr in self.macros] mcr_ind = ids.index(self.last_mcr_id) if self.last_mcr_id in ids else -1 pass; LOG and log('self.last_mcr_id, mcr_ind={}',(self.last_mcr_id,mcr_ind)) times = 1 waits = 5 chngs = '0' endln = '0' while True: WD_LST, \ HT_LST = (self.dlg_prs.get('w_list', 300) ,self.dlg_prs.get('h_list', 500)) WD_ACTS,\ HT_ACTS = (self.dlg_prs.get('w_acts', 300) ,self.dlg_prs.get('h_acts', 500)) WD_BTN, \ HT_BTN = (self.dlg_prs.get('w_btn', 150), 24) WD_BTN_3= int(WD_BTN/3) l_btn = GAP+WD_LST+GAP l_acts = GAP+WD_LST+GAP+WD_BTN+GAP vw_acts = (WD_ACTS>0) WD_ACTS = max(0, WD_ACTS) rec_on = ed.get_prop(app.PROP_MACRO_REC) lmcrs = len(self.macros) pass; LOG and log('mcr_ind,vw_acts,rec_on={}',(mcr_ind,vw_acts,rec_on)) nmkys = [] for mcr in self.macros: mcr_cid = 'cuda_macros,run,{}'.format(mcr['id']) mcr_keys= keys.get(mcr_cid, {}) kys = '/'.join([' * '.join(mcr_keys.get('s1', [])) ,' * '.join(mcr_keys.get('s2', [])) ]).strip('/') nmkys += [mcr['nm'] + (' ['+kys+']' if kys else '')] mcr_acts= [''] # mcr_acts= '' if vw_acts and mcr_ind in range(lmcrs): mcr = self.macros[mcr_ind] mcr_acts= ['# '+nmkys[mcr_ind]] + mcr['evl'] # mcr_acts= '\t'.join(['# '+nmkys[mcr_ind]] + mcr['evl']) def_stst = '1' if rec_on or 0==lmcrs else '0' n_edable = '0' if rec_on or 0==lmcrs else '1' n_vwable = '1' if not vw_acts and not rec_on else '0' only_rec_off= '0' if rec_on else '1' only_rec_on = '1' if rec_on else '0' tims_props = '0,{},1'.format(self.dlg_prs.get('times', 1000)) stst_cap = _('&Stop record') if rec_on else _('&Start record') cnts = ([] +[dict(cid='mrcs' ,tp='lbx' ,t=GAP ,h=HT_LST ,l=GAP ,w=WD_LST ,items=nmkys ,en=only_rec_off )] +( [dict(cid='view' ,tp='bt' ,t=GAP* 1+HT_BTN* 0 ,l=l_btn ,w=WD_BTN ,cap=_('&View actions') ,props=n_edable,en=n_edable )] # default if vw_acts else []) +[dict(cid='keys' ,tp='bt' ,t=GAP* 2+HT_BTN* 1 ,l=l_btn ,w=WD_BTN ,cap=_('Hot&keys...') ,en=n_edable )] +[dict(cid='renm' ,tp='bt' ,t=GAP* 3+HT_BTN* 2 ,l=l_btn ,w=WD_BTN ,cap=_('Re&name...') ,en=n_edable )] +[dict(cid='del' ,tp='bt' ,t=GAP* 4+HT_BTN* 3 ,l=l_btn ,w=WD_BTN ,cap=_('&Delete...') ,en=n_edable )] +[dict(cid='run' ,tp='bt' ,t=GAP* 6+HT_BTN* 5 ,l=l_btn ,w=WD_BTN ,cap=_('&Run!') ,props=n_vwable ,en=n_edable )] # default +[dict( tp='lb' ,tid='times' ,l=l_btn ,w=WD_BTN_3 ,cap=_('&Times') )] +[dict(cid='times' ,tp='sp-ed',t=GAP* 7+HT_BTN* 6 ,l=l_btn+WD_BTN_3+GAP ,r=l_btn+WD_BTN ,props=tims_props,en=only_rec_off )] # min,max,step +[dict( tp='lb' ,tid='waits' ,l=l_btn ,w=WD_BTN_3 ,cap=_('&Wait') )] +[dict(cid='waits' ,tp='sp-ed',t=GAP* 8+HT_BTN* 7 ,l=l_btn+WD_BTN_3+GAP ,r=l_btn+WD_BTN-40 ,props='1,3600,1',en=only_rec_off )] # min,max,step +[dict( tp='lb' ,tid='waits' ,l=l_btn+WD_BTN-40+GAP ,w=WD_BTN ,cap=_('sec') )] +[dict(cid='chngs' ,tp='ch' ,t=GAP* 9+HT_BTN* 8 ,l=l_btn ,w=WD_BTN ,cap=_('While text c&hanges') )] +[dict(cid='endln' ,tp='ch' ,t=GAP*10+HT_BTN* 9 ,l=l_btn ,w=WD_BTN ,cap=_('Until c&aret on last line') )] +[dict(cid='stst' ,tp='bt' ,t=GAP*12+HT_BTN*11 ,l=l_btn ,w=WD_BTN ,cap=stst_cap ,props=def_stst )] +[dict(cid='canc' ,tp='bt' ,t=GAP*13+HT_BTN*12 ,l=l_btn ,w=WD_BTN ,cap=_('Canc&el record') ,en=only_rec_on )] +[dict(cid='adju' ,tp='bt' ,t= HT_LST-HT_BTN*2 ,l=l_btn ,w=WD_BTN ,cap=_('Ad&just...') ,en=only_rec_off )] +[dict(cid='-' ,tp='bt' ,t=GAP+HT_LST-HT_BTN*1 ,l=l_btn ,w=WD_BTN ,cap=_('Close') )] +( [dict(cid='acts' ,tp='me' ,t=GAP ,h=HT_ACTS ,l=l_acts ,w=WD_ACTS ,props='1,1,1' )] # ro,mono,border if vw_acts else []) ) vals = dict( mrcs=mcr_ind ,times=times ,waits=waits ,chngs=chngs ,endln=endln ) if vw_acts: vals.update( dict( acts=mcr_acts )) btn, \ vals, \ chds = dlg_wrapper(_('Macros'), GAP+WD_LST+GAP+WD_BTN+GAP+WD_ACTS+GAP,GAP+HT_LST+GAP, cnts, vals, focus_cid='mrcs') if btn is None or btn=='-': return mcr_ind = vals['mrcs'] times = vals['times'] waits = vals['waits'] chngs = vals['chngs'] endln = vals['endln'] pass; LOG and log('mcr_ind,times,waits,chngs,endln={}',(mcr_ind,times,waits,chngs,endln)) if 0!=lmcrs and mcr_ind in range(lmcrs): mcr = self.macros[mcr_ind] self.last_mcr_id = mcr['id'] # if ans_s=='close': break #while if btn=='adju': #ans_s=='custom': #Custom custs = app.dlg_input_ex(5, _('Custom dialog Macros') , _('Height of macro list (min 450)') , str(self.dlg_prs.get('h_list', 400)) , _('Width of macro list (min 200)') , str(self.dlg_prs.get('w_list', 500)) , _('Width of action list (min 200, <=0-hide)'), str(self.dlg_prs.get('w_acts', 500)) , _('Width of buttons (min 150)') , str(self.dlg_prs.get('w_btn', 150)) , _('Max run times (min 100)') , str(self.dlg_prs.get('times', 1000)) ) if custs is not None: self.dlg_prs['h_list'] = max(450, int(custs[0])); self.dlg_prs['h_acts'] = self.dlg_prs['h_list'] self.dlg_prs['w_list'] = max(200, int(custs[1])) self.dlg_prs['w_acts'] = max(200, int(custs[2])) if int(custs[2])>0 else int(custs[2]) self.dlg_prs['w_btn'] = max(150, int(custs[3])) self.dlg_prs['times'] = max(100, int(custs[4])) open(MACROS_JSON, 'w').write(json.dumps({'ver':JSON_FORMAT_VER, 'list':self.macros, 'dlg_prs':self.dlg_prs}, indent=4)) continue #while if mcr_ind not in range(lmcrs): app.msg_box(_('Select macro'), app.MB_OK) continue #while what = '' changed = False if False:pass elif btn=='view': #ans_s=='view': #View continue #while elif btn=='renm': #ans_s=='rename': #Rename mcr_nm = app.dlg_input(_('New name for: {}').format(nmkys[mcr_ind]) ,mcr['nm']) if mcr_nm is None or mcr_nm==mcr['nm']: continue #while while mcr_nm in [mcr['nm'] for mcr in self.macros]: app.msg_box(_('Select other name.\nMacro names now are:\n\n')+'\n'.join(nmkys), app.MB_OK) mcr_nm = app.dlg_input(_('New name for: {}').format(nmkys[mcr_ind]) ,mcr_nm) if mcr_nm is None or mcr_nm==mcr['nm']: break #while mcr_nm if mcr_nm is None or mcr_nm==mcr['nm']: continue #while what = 'rename' mcr['nm'] = mcr_nm changed = True elif btn=='del': #ans_s=='delete': #Del if app.msg_box( _('Delete macro\n {}').format(nmkys[mcr_ind]) , app.MB_YESNO)!=app.ID_YES: continue #while what = 'delete:'+str(mcr['id']) del self.macros[mcr_ind] mcr_ind = min(mcr_ind, len(self.macros)-1) changed = True elif btn=='keys': #ans_s=='hotkeys': #Hotkeys app.dlg_hotkeys('cuda_macros,run,'+str(mcr['id'])) keys = apx._json_loads(open(keys_json).read()) if os.path.exists(keys_json) else {} changed = True elif btn=='run': #ans_s=='run': #Run if (times==0 and waits==0 and chngs=='0' and endln=='0'): app.msg_box(_('Select stop condition'), app.MB_OK) continue self.run(mcr['id'], max(0, times), max(0, waits), chngs=='1', endln=='1') return elif btn=='stst' and not rec_on: #Start record # elif ans_s=='rec' and not rec_on: #Start record return ed.cmd(cmds.cmd_MacroStart) elif btn=='stst' and rec_on: #Stop record # elif ans_s=='rec' and rec_on: #Stop record self.need_dlg = True return ed.cmd(cmds.cmd_MacroStop) # Return for clear rec-mode in StatusBar, will recall from on_macro elif btn=='canc' and rec_on: #Cancel record # elif ans_s=='cancel' and rec_on: #Cancel record return ed.cmd(cmds.cmd_MacroCancel) # Return for clear rec-mode in StatusBar if changed: self._do_acts(what)
def dlg_config(self): ''' Show dlg for change macros list. ''' if app.app_api_version() < FROM_API_VERSION: return app.msg_status('Need update CudaText') keys_json = app.app_path(app.APP_DIR_SETTINGS) + os.sep + 'keys.json' keys = apx._json_loads( open(keys_json).read()) if os.path.exists(keys_json) else {} GAP = 5 ids = [mcr['id'] for mcr in self.macros] mcr_ind = ids.index( self.last_mcr_id) if self.last_mcr_id in ids else -1 pass LOG and log('self.last_mcr_id, mcr_ind={}', (self.last_mcr_id, mcr_ind)) times = 1 waits = 5 chngs = '0' endln = '0' while True: (WD_LST, HT_LST) = (self.dlg_prs.get('w_list', 300), self.dlg_prs.get('h_list', 500)) (WD_ACTS, HT_ACTS) = (self.dlg_prs.get('w_acts', 300), self.dlg_prs.get('h_acts', 500)) (WD_BTN, HT_BTN) = (self.dlg_prs.get('w_btn', 150), 24) l_btn = GAP + WD_LST + GAP vw_acts = (WD_ACTS > 0) WD_ACTS = max(0, WD_ACTS) rec_on = ed.get_prop(app.PROP_MACRO_REC) lmcrs = len(self.macros) pass LOG and log('mcr_ind,vw_acts,rec_on={}', (mcr_ind, vw_acts, rec_on)) nmkys = [] for mcr in self.macros: mcr_cid = 'cuda_macros,run,{}'.format(mcr['id']) mcr_keys = keys.get(mcr_cid, {}) kys = '/'.join([ ' * '.join(mcr_keys.get('s1', [])), ' * '.join(mcr_keys.get('s2', [])) ]).strip('/') nmkys += [mcr['nm'] + (' [' + kys + ']' if kys else '')] mcr_acts = '' if vw_acts and mcr_ind in range(lmcrs): mcr = self.macros[mcr_ind] mcr_acts = '\t'.join(['# ' + nmkys[mcr_ind]] + mcr['evl']) ans = app.dlg_custom( 'Macros', GAP + WD_LST + GAP + WD_BTN + GAP + WD_ACTS + GAP, GAP + HT_LST + GAP, '\n'.join([] + [ C1.join([ 'type=listbox', POS_FMT(l=GAP, t=GAP, r=GAP + WD_LST, b=GAP + HT_LST), 'items=' + '\t'.join(nmkys), 'val=' + str(mcr_ind) # start sel , 'en=' + str(0 if rec_on else 1) # enabled ] # i=0 ) ] + ([ C1.join([ 'type=button', POS_FMT(l=l_btn, t=GAP * 1 + HT_BTN * 0, r=l_btn + WD_BTN, b=0), 'cap=&View actions...', 'props=' + str(0 if rec_on or 0 == lmcrs else 1) # default , 'en=' + str(0 if rec_on or 0 == lmcrs else 1) # enabled ] # i=1 ) ] if vw_acts else []) + [ C1.join([ 'type=button', POS_FMT(l=l_btn, t=GAP * 2 + HT_BTN * 1, r=l_btn + WD_BTN, b=0), 'cap=Hot&keys...', 'en=' + str(0 if rec_on or 0 == lmcrs else 1) # enabled ] # i=2 if vw_acts else i=1 ) ] + [ C1.join([ 'type=button', POS_FMT(l=l_btn, t=GAP * 3 + HT_BTN * 2, r=l_btn + WD_BTN, b=0), 'cap=Re&name...', 'en=' + str(0 if rec_on or 0 == lmcrs else 1) # enabled ] # i=3 if vw_acts else i=2 ) ] + [ C1.join([ 'type=button', POS_FMT(l=l_btn, t=GAP * 4 + HT_BTN * 3, r=l_btn + WD_BTN, b=0), 'cap=&Delete...', 'en=' + str(0 if rec_on or 0 == lmcrs else 1) # enabled ] # i=4 if vw_acts else i=3 ) ] + [ C1.join([ 'type=button', POS_FMT(l=l_btn, t=GAP * 6 + HT_BTN * 5, r=l_btn + WD_BTN, b=0), 'cap=&Run!', 'props=' + str(1 if not vw_acts and not rec_on else 0) # default , 'en=' + str(0 if rec_on or 0 == lmcrs else 1) # enabled ] # i=5 if vw_acts else i=4 ) ] + [ C1.join([ 'type=label', POS_FMT(l=l_btn, t=GAP * 7 + HT_BTN * 6 + 3, r=l_btn + int(WD_BTN / 3), b=0), 'cap=&Times' ] # i=6 if vw_acts else i=5 ) ] + [ C1.join([ 'type=spinedit', POS_FMT(l=l_btn + int(WD_BTN / 3) + GAP, t=GAP * 7 + HT_BTN * 6, r=l_btn + WD_BTN, b=0), 'val=' + str(times), 'props=0,{},1'.format(self.dlg_prs.get('times', 1000)), 'en=' + str(0 if rec_on else 1) # enabled ] # i=7 if vw_acts else i=6 ) ] + [ C1.join([ 'type=label', POS_FMT(l=l_btn, t=GAP * 8 + HT_BTN * 7 + 3, r=l_btn + int(WD_BTN / 3), b=0), 'cap=&Wait' ] # i=8 if vw_acts else i=7 ) ] + [ C1.join([ 'type=spinedit', POS_FMT(l=l_btn + int(WD_BTN / 3) + GAP, t=GAP * 8 + HT_BTN * 7, r=l_btn + WD_BTN - 40, b=0), 'val=' + str(waits), 'props=1,3600,1', 'en=' + str(0 if rec_on else 1) # enabled ] # i=9 if vw_acts else i=8 ) ] + [ C1.join([ 'type=label', POS_FMT(l=l_btn + WD_BTN - 40 + GAP, t=GAP * 8 + HT_BTN * 7 + 3, r=l_btn + WD_BTN, b=0), 'cap=sec' ] # i=10 if vw_acts else i=9 ) ] + [ C1.join([ 'type=check', POS_FMT(l=l_btn, t=GAP * 9 + HT_BTN * 8, r=l_btn + WD_BTN, b=0), 'cap=While text c&hanges', 'val=' + chngs ] # i=11 if vw_acts else i=10 ) ] + [ C1.join([ 'type=check', POS_FMT(l=l_btn, t=GAP * 10 + HT_BTN * 9, r=l_btn + WD_BTN, b=0), 'cap=Until c&aret on last line', 'val=' + endln ] # i=12 if vw_acts else i=11 ) ] + [ C1.join([ 'type=button', POS_FMT(l=l_btn, t=GAP * 12 + HT_BTN * 11, r=l_btn + WD_BTN, b=0), 'cap={}'.format( '&Stop record' if rec_on else '&Start record'), 'props=' + str(1 if rec_on or 0 == lmcrs else 0) # default ] # i=13 if vw_acts else i=12 ) ] + [ C1.join([ 'type=button', POS_FMT(l=l_btn, t=GAP * 13 + HT_BTN * 12, r=l_btn + WD_BTN, b=0), 'cap=Canc&el record', 'en=' + str(1 if rec_on else 0) # enabled ] # i=14 if vw_acts else i=13 ) ] + [ C1.join([ 'type=button', POS_FMT(l=l_btn, t=HT_LST - HT_BTN * 2, r=l_btn + WD_BTN, b=0), 'cap=C&ustom...', 'en=' + str(0 if rec_on else 1) # enabled ] # i=15 if vw_acts else i=14 ) ] + [ C1.join([ 'type=button', POS_FMT(l=l_btn, t=GAP + HT_LST - HT_BTN * 1, r=l_btn + WD_BTN, b=0), 'cap=&Close' ] # i=16 if vw_acts else i=15 ) ] + ([ C1.join([ 'type=memo', POS_FMT(l=GAP + WD_LST + GAP + WD_BTN + GAP, t=GAP, r=GAP + WD_LST + GAP + WD_BTN + GAP + WD_ACTS, b=GAP + HT_ACTS), 'val=' + mcr_acts, 'props=1,1,1' # ro,mono,border ] # i=17 ) ] if vw_acts else [])), apx.icase( vw_acts and not rec_on, 0 # View , not vw_acts and not rec_on, 0 # View , vw_acts and rec_on, 11, not vw_acts and rec_on, 10)) # start focus pass LOG and log('ans={}', ans) if ans is None: break #while (ans_i, vals) = ans ans_s = apx.icase( False, '', vw_acts and ans_i == 1, 'view', vw_acts and ans_i == 2, 'hotkeys', not vw_acts and ans_i == 1, 'hotkeys', vw_acts and ans_i == 3, 'rename', not vw_acts and ans_i == 2, 'rename', vw_acts and ans_i == 4, 'delete', not vw_acts and ans_i == 3, 'delete', vw_acts and ans_i == 5, 'run', not vw_acts and ans_i == 4, 'run', vw_acts and ans_i == 12, 'rec', not vw_acts and ans_i == 7, 'rec', vw_acts and ans_i == 14, 'cancel', not vw_acts and ans_i == 13, 'cancel', vw_acts and ans_i == 15, 'custom', not vw_acts and ans_i == 14, 'custom', vw_acts and ans_i == 16, 'close', not vw_acts and ans_i == 15, 'close', '?') mcr_ind = int(vals.splitlines()[0]) times = int(vals.splitlines()[7 if vw_acts else 6]) waits = int(vals.splitlines()[9 if vw_acts else 8]) chngs = vals.splitlines()[11 if vw_acts else 10] endln = vals.splitlines()[12 if vw_acts else 11] pass LOG and log('mcr_ind,times,waits,chngs,endln={}', (mcr_ind, times, waits, chngs, endln)) if 0 != lmcrs and mcr_ind in range(lmcrs): mcr = self.macros[mcr_ind] self.last_mcr_id = mcr['id'] if ans_s == 'close': break #while if ans_s == 'custom': #Custom custs = app.dlg_input_ex( 5, 'Custom dialog Macros', 'Height of macro list (min 450)', str(self.dlg_prs.get('h_list', 400)), 'Width of macro list (min 200)', str(self.dlg_prs.get('w_list', 500)), 'Width of action list (min 200, <=0-hide)', str(self.dlg_prs.get('w_acts', 500)), 'Width of buttons (min 150)', str(self.dlg_prs.get('w_btn', 150)), 'Max run times (min 100)', str(self.dlg_prs.get('times', 1000))) if custs is not None: self.dlg_prs['h_list'] = max(450, int(custs[0])) self.dlg_prs['h_acts'] = self.dlg_prs['h_list'] self.dlg_prs['w_list'] = max(200, int(custs[1])) self.dlg_prs['w_acts'] = max(200, int( custs[2])) if int(custs[2]) > 0 else int(custs[2]) self.dlg_prs['w_btn'] = max(150, int(custs[3])) self.dlg_prs['times'] = max(100, int(custs[4])) open(MACROS_JSON, 'w').write( json.dumps( { 'ver': JSON_FORMAT_VER, 'list': self.macros, 'dlg_prs': self.dlg_prs }, indent=4)) continue #while if mcr_ind not in range(lmcrs): app.msg_box('Select macro', app.MB_OK) continue #while what = '' changed = False if False: pass elif ans_s == 'view': #View continue #while elif ans_s == 'rename': #Rename mcr_nm = app.dlg_input( 'New name for: {}'.format(nmkys[mcr_ind]), mcr['nm']) if mcr_nm is None or mcr_nm == mcr['nm']: continue #while while mcr_nm in [mcr['nm'] for mcr in self.macros]: app.msg_box( 'Select other name.\nMacro names now are:\n\n' + '\n'.join(nmkys), app.MB_OK) mcr_nm = app.dlg_input( 'New name for: {}'.format(nmkys[mcr_ind]), mcr_nm) if mcr_nm is None or mcr_nm == mcr['nm']: break #while mcr_nm if mcr_nm is None or mcr_nm == mcr['nm']: continue #while what = 'rename' mcr['nm'] = mcr_nm changed = True elif ans_s == 'delete': #Del if app.msg_box('Delete macro\n {}'.format(nmkys[mcr_ind]), app.MB_YESNO) != app.ID_YES: continue #while what = 'delete:' + str(mcr['id']) del self.macros[mcr_ind] mcr_ind = min(mcr_ind, len(self.macros) - 1) changed = True elif ans_s == 'hotkeys': #Hotkeys app.dlg_hotkeys('cuda_macros,run,' + str(mcr['id'])) keys = apx._json_loads(open( keys_json).read()) if os.path.exists(keys_json) else {} changed = True elif ans_s == 'run': #Run if (times == 0 and waits == 0 and chngs == '0' and endln == '0'): app.msg_box('Select stop condition', app.MB_OK) continue self.run(mcr['id'], max(0, times), max(0, waits), chngs == '1', endln == '1') return elif ans_s == 'rec' and not rec_on: #Start record return ed.cmd(cmds.cmd_MacroStart) elif ans_s == 'rec' and rec_on: #Stop record self.need_dlg = True return ed.cmd( cmds.cmd_MacroStop ) # Return for clear rec-mode in StatusBar, will recall from on_macro elif ans_s == 'cancel' and rec_on: #Cancel record return ed.cmd(cmds.cmd_MacroCancel ) # Return for clear rec-mode in StatusBar if changed: self._do_acts(what)
def symbol_menu_levels(levels=0): pass; log4fun=-1== 1 # Order log in the function if app.app_api_version() >= '1.0.277' and \ ed.get_prop(app.PROP_CODETREE_MODIFIED_VERSION) < ed.get_prop(app.PROP_MODIFIED_VERSION): ed.cmd(cmds.cmd_TreeUpdate) h_tree = app.app_proc(app.PROC_GET_CODETREE, '') def tree_items_to_list(props=None, id_node=0, prefix='', more_levels=1000): '''Get all tree nodes to "props" starting from id_node (e.g. 0)''' props = [] if props is None else props nodes = app.tree_proc(h_tree, app.TREE_ITEM_ENUM, id_node) if not nodes: nodes = app.tree_proc(h_tree, app.TREE_ITEM_ENUM, id_node) if not nodes: return for id_kid, cap in nodes: prop = app.tree_proc(h_tree, app.TREE_ITEM_GET_PROPS, id_kid) rng = app.tree_proc(h_tree, app.TREE_ITEM_GET_RANGE, id_kid) subs = prop['sub_items'] if rng[0]>=0: prop['rng'] = rng prop['_t'] = f('{}{}\t{}' , prefix , prop['text'] , f('{}:{}', 1+rng[1], 1+rng[3])) props.append(prop) if subs and more_levels: # need items with sub_items too tree_items_to_list(props, id_kid, prefix+' '*4, more_levels-1) return props #def tree_items_to_list old_api = app.app_api_version() < '1.0.277' w = get_hist('symbols.w', 600) h = get_hist('symbols.h', 550) while True: props = tree_items_to_list(more_levels=(levels-1 if levels else 1000)) if not props: ed.cmd(cmds.cmd_TreeUpdate) props = tree_items_to_list() if not props: return app.msg_status(_('No items in Code Tree')) items = [p['_t'] for p in props] crt_row = ed.get_carets()[0][1] covers = [(p['rng'][3]-p['rng'][1], n) for n,p in enumerate(props) if p['rng'][1] <= crt_row <= p['rng'][3]] start_item = min(covers)[1] if covers else 0 res = dlg_menu(app.MENU_LIST+app.MENU_NO_FULLFILTER+app.MENU_EDITORFONT , w=w, h=h , sel=start_item , cap=_('Code Tree symbols') + f(' ({})' , len(items)) +(f(' (up {})' , levels ) if levels else '') , its=items + ([_('<Update Code Tree>')] if old_api else []) + [_(' <All levels>')] + [_(' <Only 1 up level>')] + [_(' <Only 2 up levels>')] + [_(' <Only 3 up levels>')] ) if res is None: return if res==len(props) and old_api: ed.cmd(cmds.cmd_TreeUpdate) continue#while if res==0+len(props) + (1 if old_api else 0): levels = 0 continue#while if res==1+len(props) + (1 if old_api else 0): levels = 1 continue#while if res==2+len(props) + (1 if old_api else 0): levels = 2 continue#while if res==3+len(props) + (1 if old_api else 0): levels = 3 continue#while break #while x, y, x1, y1 = props[res]['rng'] ed.set_caret(x, y)
def _get_best_tree_path(row): """ Find node-path nearext to row: all nodes cover row or are all above/below nearest. Return [(widest_node_id,cap), (node_id,cap), ..., (smallest_node_id,cap)], gap list can be empty gap: 0 if row is covered >0 if nearest node below <0 if nearest node above """ ed.cmd(cmds.cmd_TreeUpdate) ID_TREE = app.app_proc(app.PROC_SIDEPANEL_GET_CONTROL, 'Code tree') INF = 0xFFFFFFFF if not ID_TREE: return [], INF NO_ID = -1 def best_path(id_prnt, prnt_cap=''): rsp_l = [] kids = app.tree_proc(ID_TREE, app.TREE_ITEM_ENUM, id_prnt) pass; #log('>>id_prnt, prnt_cap, kids={}',(id_prnt, prnt_cap, len(kids) if kids else 0)) if kids is None: pass; #log('<<no kids',()) return [], INF row_bfr, kid_bfr, cap_bfr = -INF, NO_ID, '' row_aft, kid_aft, cap_aft = +INF, NO_ID, '' for kid, cap in kids: pass; #log('kid, cap={}',(kid, cap)) cMin, rMin, \ cMax, rMax = app.tree_proc(ID_TREE, app.TREE_ITEM_GET_SYNTAX_RANGE , kid) \ if app.app_api_version() < '1.0.226' else \ app.tree_proc(ID_TREE, app.TREE_ITEM_GET_RANGE , kid) pass; #log('? kid,cap, rMin,rMax,row={}',(kid,cap, rMin,rMax,row)) if False:pass elif rMin<=row<=rMax: # Cover! sub_l, gap_sub = best_path(kid, cap) pass; #log('? sub_l, gap_sub={}',(sub_l, gap_sub)) if gap_sub == 0: # Sub-kid also covers pass; #log('+ sub_l={}',(sub_l)) rsp_l = [(kid, cap)] + sub_l else: # The kid is best pass; #log('0 ',()) rsp_l = [(kid, cap)] pass; #log('<<! rsp_l={}',(rsp_l)) return rsp_l, 0 elif row_bfr < rMax < row: row_bfr, kid_bfr, cap_bfr = rMax, kid, cap pass; #log('< row_bfr, kid_bfr, cap_bfr={}',(row_bfr, kid_bfr, cap_bfr)) elif row_aft > rMin > row: row_aft, kid_aft, cap_aft = rMin, kid, cap pass; #log('> row_aft, kid_aft, cap_aft={}',(row_aft, kid_aft, cap_aft)) #for kid pass; #log('? row_bfr, kid_bfr, cap_bfr={}',(row_bfr, kid_bfr, cap_bfr)) pass; #log('? row_aft, kid_aft, cap_aft={}',(row_aft, kid_aft, cap_aft)) pass; #log('? abs(row_bfr-row), abs(row_aft-row)={}',(abs(row_bfr-row), abs(row_aft-row))) kid_x, cap_x, gap_x = (kid_bfr, cap_bfr, row_bfr-row) \ if abs(row_bfr-row) <= abs(row_aft-row) else \ (kid_aft, cap_aft, row_aft-row) pass; #log('kid_x, cap_x, gap_x={}',(kid_x, cap_x, gap_x)) sub_l, gap_sub = best_path(kid_x, cap_x) pass; #log('? sub_l,gap_sub ?? gap_x={}',(sub_l, gap_sub, gap_x)) if abs(gap_sub) <= abs(gap_x): # Sub-kid better rsp_l = [(kid_x, cap_x)] + sub_l pass; #log('<<sub bt: rsp_l, gap_sub={}',(rsp_l, gap_sub)) return rsp_l, gap_sub # The kid is best rsp_l = [(kid_x, cap_x)] pass; #log('<<bst: rsp_l, gap_x={}',(rsp_l, gap_x)) return rsp_l, gap_x #def best_path lst, gap= best_path(0) pass; #log('lst, gap={}',(lst, gap)) return lst, gap
def find_tree_node(): pass; log4fun=-1==-1 # Order log in the function HELP_C = _(''' Search starts on Enter. • A found node after current one will be selected. • All found nodes are remembered and dialog can jump over them by [Shift+]Enter or by menu commands. • If option "O" (wrapped search) is tuned on: - Search continues from the start, when end of the tree is reached - Jumps to previous/next nodes are looped too • Option ".*" (regular expression) allows to use Python reg.ex. See "docs.python.org/3/library/re.html". • Option "w" (whole words) is ignored if entered string contains not a word. • If option "Close on success" (in menu) is tuned on, dialog will close after successful search. • Option "Show full tree path" (in menu) shows in the statusbar the path of the found node (names of all parents). • Command "Restore initial selection" (in menu) restores only first of initial carets. ''').strip() ed_crts = ed.get_carets() # Carets at start opts = d(reex=False,case=False,word=False,wrap=False,hist=[],clos=False,fpth=False) opts.update(get_hist('tree.find_node', opts)) # Scan Tree ID_TREE = app.app_proc(app.PROC_SIDEPANEL_GET_CONTROL, 'Code tree') if not ID_TREE: return app.msg_status(_('No CodeTree')) if not app.tree_proc(ID_TREE, app.TREE_ITEM_ENUM, 0): # 0 is root ed.cmd(cmds.cmd_TreeUpdate) # Try to build tree tree_t = [] # [{nid:ID, sub:[{nid:ID, sub:{}, cap:'smth', path:['rt','smth']},], cap:'rt', path:[]},] tree_p = [] # [,(ID, 'smth',['rt','smth']),] def scan_tree(id_prnt, tree_nds, path_prnt): nonlocal tree_p kids = app.tree_proc(ID_TREE, app.TREE_ITEM_ENUM, id_prnt) if kids is None: return None for nid, cap in kids: path = path_prnt + [cap] tree_p += [(nid, cap, path)] sub = scan_tree(nid, [], path) return tree_nds #def scan_tree scan_tree(0, tree_t, []) # 0 is root pass; #log('tree_t={}',pfrm100(tree_t)) if iflog(log4fun,_log4mod) else 0 pass; #log('tree_p={}',pfrm100(tree_p)) if iflog(log4fun,_log4mod) else 0 # How to select node def select_node(nid): app.tree_proc(ID_TREE, app.TREE_ITEM_SELECT, nid) c_min, r_min, \ c_max, r_max = app.tree_proc(ID_TREE, app.TREE_ITEM_GET_RANGE, nid) ed.set_caret(c_min, r_min) #def select_node # Ask MAX_HIST= apx.get_opt('ui_max_history_edits', 20) stbr = None status = lambda msg: app.statusbar_proc(stbr, app.STATUSBAR_SET_CELL_TEXT, tag=1, value=msg) def add_to_hist(val, lst): """ Add/Move val to list head. """ if val in lst: if 0 == lst.index(val): return lst lst.remove(val) lst.insert(0, val) if len(lst)>MAX_HIST: del lst[MAX_HIST:] return lst #def add_to_hist compile_pttn= lambda pttn_s, reex, case, word: re.compile( pttn_s if reex else r'\b'+pttn_s+r'\b' if word and re.match('^\w+$', pttn_s) else re.escape(pttn_s) , 0 if case else re.I) prev_wt = None # Prev what ready_l = [] # [(nid,cap|path,ndn)] ready_p = -1 # pos in ready_l nfnd_st = lambda: status(_('No suitable nodes')) ready_st= lambda: status(f('{pos}/{all}: {cap}', pos=1+ready_p, all=len(ready_l), cap=ready_l[ready_p][1])) ready_er= lambda: status(_('Error')) def do_attr(ag, aid, data=''): nonlocal prev_wt prev_wt = '' return d(fid='what') def do_menu(ag, aid, data=''): def wnen_menu(ag, tag): nonlocal opts, prev_wt if tag in ('prev','next'): return do_next(ag, tag) if tag in ('fpth','clos'): prev_wt = ''; opts[tag] = not opts[tag] elif tag=='help': app.msg_box(HELP_C, app.MB_OK) elif tag=='rest': ed.set_caret(*ed_crts[0]); return None return [] #def wnen_menu ag.show_menu( [ d( tag='help' ,cap=_('&Help...') ),d( cap='-' ),d( tag='prev' ,cap=_('Find &previous') ,key='Shift+Enter' ),d( tag='next' ,cap=_('F&ind next') ,key='Enter' ),d( cap='-' ),d( cap=_('&Options') ,sub= [ d(tag='fpth' ,cap=_('Show full tree path') ,ch=opts['fpth'] ),d(tag='clos' ,cap=_('Close on success') ,ch=opts['clos'] )]),d( cap='-' ),d( tag='rest' ,cap=_('Restore initial selection and close dialog &=') ,key='Shift+Esc' )] , aid , cmd4all=wnen_menu # Set cmd=wnen_menu for all nodes ) return d(fid='what') #def do_menu def do_next(ag, aid, data=''): if not ready_l: return d(fid='what') nonlocal ready_p ready_n = ready_p + (-1 if aid=='prev' else 1) ready_n = ready_n % len(ready_l) if opts['wrap'] else max(0, min(len(ready_l)-1, ready_n), 0) pass; #log('ready_n,ready_p={}',(ready_n,ready_p)) if iflog(log4fun,_log4mod) else 0 if ready_p == ready_n: return d(fid='what') ready_p = ready_n ready_st() select_node(ready_l[ready_p][0]) return d(fid='what') #def do_next def do_find(ag, aid, data=''): nonlocal opts, tree_p, prev_wt, ready_l, ready_p # What/how/where will search what = ag.val('what') if prev_wt==what and ready_l: return do_next(ag, 'next') prev_wt = what pass; #log('what={}',(what)) if iflog(log4fun,_log4mod) else 0 if not what: ready_l, ready_p = [], -1 return d(fid='what') opts['hist']= add_to_hist(what, opts['hist']) opts.update(ag.vals(['reex','case','word','wrap'])) pass; #log('opts={}',(opts)) if iflog(log4fun,_log4mod) else 0 tree_sid = app.tree_proc(ID_TREE, app.TREE_ITEM_GET_SELECTED) # cur nodes = tree_p # To find from top if tree_sid and opts['clos']: # To find from cur # Trick: [..,i,sid]+[j,..] switch to [j,..] or [j,..]+[..,i] to search first after cur nids = [nid for nid, cap, path in tree_p] pos = nids.index(tree_sid) nodes = tree_p[pos+1:] + (tree_p[:pos] if opts['wrap'] else []) # Search ready_l = [] tree_ndn= -1 try: pttn_r = compile_pttn(what, opts['reex'], opts['case'], opts['word']) except: ready_er() return d(ctrls=[('what',d(items=opts['hist']))] ,fid='what') for ndn, (nid, cap, path) in enumerate(nodes): if not pttn_r.search(cap): continue if opts['clos']: select_node(nid) return None # Close dlg ready_l+= [(nid, ' / '.join(path) if opts['fpth'] else cap, ndn)] tree_ndn= ndn if ndn==tree_sid else tree_ndn pass; #log('ready_l={}',(ready_l)) if iflog(log4fun,_log4mod) else 0 ready_p = -1 if not ready_l else \ 0 if not tree_sid else \ first_true(enumerate(ready_l), 0, (lambda n_nid_cap_ndn: n_nid_cap_ndn[1][2]>tree_ndn))[0] pass; #log('ready_p={}',(ready_p)) if iflog(log4fun,_log4mod) else 0 # Show results if ready_p!=-1: select_node(ready_l[ready_p][0]) if opts['clos']: return None # Close dlg ready_st() else: nfnd_st() return d(ctrls=[('what',d(items=opts['hist']))] ,fid='what') #def do_find def do_key_down(ag, key, data=''): scam = data if data else app.app_proc(app.PROC_GET_KEYSTATE, '') pass; #log('key,data,scam={}',(key,data,scam)) if iflog(log4fun,_log4mod) else 0 if 0:pass elif (scam,key)==('s',VK_ENTER): # Shift+Enter ag.update(do_next(ag, 'prev')) elif (scam,key)==('s',VK_ESCAPE): # Shift+Esc ed.set_caret(*ed_crts[0]) return None else: return [] # Nothing return False # Stop event #def do_key_down ag = DlgAg( form =dict(cap=_('Find tree node'), w=365, h=58, h_max=58 ,on_key_down=do_key_down ,border=app.DBORDER_TOOLSIZE # ,resize=True ) , ctrls =[0 ,('find',d(tp='bttn',y=0 ,x=-99 ,w=44 ,cap='' ,sto=False ,def_bt=T ,on=do_find )) # Enter ,('reex',d(tp='chbt',tid='what' ,x=5+38*0 ,w=39 ,cap='.&*' ,hint=_('Regular expression') ,on=do_attr )) # &* ,('case',d(tp='chbt',tid='what' ,x=5+38*1 ,w=39 ,cap='&aA' ,hint=_('Case sensitive') ,on=do_attr )) # &a ,('word',d(tp='chbt',tid='what' ,x=5+38*2 ,w=39 ,cap='"&w"' ,hint=_('Whole words') ,on=do_attr )) # &w ,('wrap',d(tp='chbt',tid='what' ,x=5+38*3 ,w=39 ,cap='&O' ,hint=_('Wrapped search') ,on=do_attr )) # &/ ,('what',d(tp='cmbx',y =5 ,x=5+38*4+5 ,w=155 ,items=opts['hist'] ,a='r>' )) # ,('menu',d(tp='bttn',tid='what' ,x=320 ,w=40 ,cap='&=' ,on=do_menu ,a='>>' )) # &= ,('stbr',d(tp='stbr' ,x=0 ,r=365 ,ali=ALI_BT ,a='r>' )) # ][1:] , fid ='what' , vals = {k:opts[k] for k in ('reex','case','word','wrap')} #,options={'gen_repro_to_file':'repro_dlg_find_tree_node.py'} ) stbr = ag.chandle('stbr') app.statusbar_proc(stbr, app.STATUSBAR_ADD_CELL , tag=1) app.statusbar_proc(stbr, app.STATUSBAR_SET_CELL_AUTOSTRETCH , tag=1, value=True) ag.show(lambda ag: set_hist('tree.find_node', upd_dict(opts, ag.vals(['reex','case','word','wrap']))))