def on_macro(self, ed_self, mcr_record): ''' Finish for macro-recording. Params mcr_record "\n"-separated list of number number,string py:string_module,string_method,string_param ''' pass; LOG and log('mcr_record={}',mcr_record) if ''==mcr_record: return app.msg_status('Empty record') def_nm = '' nms = [mcr['nm'] for mcr in self.macros] for num in range(1,1000): def_nm = 'Macro{}'.format(num) if def_nm not in nms: break #for num while True: mcr_nm = app.dlg_input('Macro name. Tricks: "!NM" overwrite NM, "=NM" show NM in dialog', def_nm) if mcr_nm is None: return mcr_nm = mcr_nm.strip() if ''==mcr_nm: continue #while if mcr_nm[0]=='=': self.need_dlg = True mcr_nm = mcr_nm[1:] use_old = False if ''==mcr_nm: continue #while if mcr_nm[0]=='!': use_old = True mcr_nm = mcr_nm[1:] if ''!=mcr_nm: break #while pass; LOG and log('self.need_dlg, use_old, mcr_nm={}',(self.need_dlg, use_old, mcr_nm)) if use_old and mcr_nm in nms: mcr_ind = nms.index(mcr_nm) self.macros[mcr_ind]['rec'] = mcr_record self.macros[mcr_ind]['evl'] = self._record_data_to_cmds(mcr_record) id4mcr = self.macros[mcr_ind]['id'] else: while mcr_nm in nms: app.msg_box('Select other name.\nMacros names now:\n\n'+'\n'.join(nms), app.MB_OK) mcr_nm = app.dlg_input('Macro name', mcr_nm) if mcr_nm is None: return id4mcr = random.randint(10000, 99999) while id4mcr in self.mcr4id: id4mcr = random.randint(10000, 99999) self.macros += [{'id' :id4mcr ##?? conflicts? ,'nm' :mcr_nm ,'rec':mcr_record ,'evl':self._record_data_to_cmds(mcr_record) }] self._do_acts() if self.need_dlg: self.need_dlg = False self.last_mcr_id= id4mcr self.dlg_config()
def _create_group(self, id_dlg, id_ctl, data='', info=''): pkg = self._get_sel_pkg() if not pkg: return #pass; print(' ~~~ create new B:Group ===') lex = ct.ed.get_prop(ct.PROP_LEXER_FILE) name = lex if lex else 'snippets' name = ct.dlg_input(_('New snippet group filename:'), name) #pass; print('new group name:{0}'.format(name)) if name: if not name.endswith('.json'): name += '.json' # checking for file in case of case-insensitive filesystem if os.path.exists(os.path.join(pkg['path'], 'snippets', name)): print(_('"{0}" - group already exists.').format(name)) return pkg['files'][name] = [lex] self.file_snippets[(pkg['path'], name)] = {} self.modified.append((TYPE_PKG, pkg['path'])) self.modified.append((TYPE_GROUP, pkg['path'], name)) # select new group self._fill_forms(sel_pkg_path=pkg['path'], sel_group=name)
def _create_snip(self, id_dlg, id_ctl, data='', info=''): pkg = self._get_sel_pkg() snips_fn, lexers = self._get_sel_group(pkg) if not pkg or not snips_fn: return #pass; print(' ~~~ new C:snip ~~~: {0}; group:{1}'.format(pkg["path"], snips_fn)) name = ct.dlg_input(_('New snippet name:'), '') #pass; print(' snip name: {0}'.format(name)) if name: snips = self.file_snippets.get( (pkg['path'], snips_fn)) # snippets of selected group will be loaded if snips is not None: if name not in snips: snips[name] = {'prefix': name, 'body': ''} self.modified.append( (TYPE_GROUP, pkg['path'], snips_fn, name)) # select new snip self._fill_forms(sel_pkg_path=pkg['path'], sel_group=snips_fn, sel_snip=name) else: print(_('"{0}" - snippet already exists.').format(name))
def _create_pkg(self, id_dlg, id_ctl, data='', info=''): #pass; print(' ~~~ create new package ===') lex = ct.ed.get_prop(ct.PROP_LEXER_FILE) name = 'New_' + lex if lex else 'NewPackage' name = ct.dlg_input( _('New package name (should be a valid directory name):'), name) #pass; print('new pkg name:{0}'.format(name)) if name: newpkg = { 'name': name, 'files': {}, 'path': os.path.join(MAIN_SNIP_DIR, name) } if os.path.exists(os.path.join(MAIN_SNIP_DIR, name, 'config.json')): print( _('"{0}" - package already exists.').format( os.path.join(MAIN_SNIP_DIR, name, 'config.json'))) return self.packages.append(newpkg) # update packages and select new self._sort_pkgs() self.modified.append((TYPE_PKG, newpkg['path'])) # select new package self._fill_forms(sel_pkg_path=newpkg['path'])
def input_name(caption, name): while True: s = ct.dlg_input(caption, name) if not s: return if (s != name) and s.isidentifier(): return s
def add_ibm(self): lxr = ed.get_prop(app.PROP_LEXER_FILE) lxr = lxr if lxr else NO_LXR_SIGN # if lxr not in self.lxr2cmnt: return app.msg_status(f(_('Cannot add in-text bookmark into document with Lexer {}. No to-end-of-line comment.'), lxr)) if lxr not in self.lxr2cmnt: return app.msg_status(f(_('Cannot add in-text bookmark: no line-comments defined for lexer {}.'), lxr)) cmnt = self.lxr2cmnt[lxr] bm_msg = app.dlg_input(_('Enter message for in-text bookmark. Empty is good.'), '') if bm_msg is None: return (cCrt, rCrt ,cEnd, rEnd)= ed.get_carets()[0] line_s = ed.get_text_line( rCrt) ed.set_text_line( rCrt, line_s + cmnt + self.bm_sign + ' ' + bm_msg)
def _dlg_del_pkg(self, *args, **vargs): ''' show directory path to delete with OK|Cancel + remove from 'self.packages' if confirmed ''' #pass; print('del pkg {0};; {1}'.format(args, vargs)) pkg = self._get_sel_pkg() if not pkg: return res = ct.dlg_input( _('To delete package "{}" - delete the following directory:'). format(pkg['name']), pkg['path']) if res is not None: # removeing #pass; print('* confirmed package deletion') self.packages.remove(pkg) self._fill_forms()
def add_ibm(self): lxr = ed.get_prop(app.PROP_LEXER_FILE) lxr = lxr if lxr else NO_LXR_SIGN # if lxr not in self.lxr2cmnt: return app.msg_status(f(_('Cannot add in-text bookmark into document with Lexer {}. No to-end-of-line comment.'), lxr)) if lxr not in self.lxr2cmnt: return app.msg_status( f( _('Cannot add in-text bookmark: no line-comments defined for lexer {}.' ), lxr)) cmnt = self.lxr2cmnt[lxr] bm_msg = app.dlg_input( _('Enter message for in-text bookmark. Empty is good.'), '') if bm_msg is None: return (cCrt, rCrt, cEnd, rEnd) = ed.get_carets()[0] line_s = ed.get_text_line(rCrt) ed.set_text_line(rCrt, line_s + cmnt + self.bm_sign + ' ' + bm_msg)
def to_tab_ask_num(): while True: grp_num = app.dlg_input( _('What tab number to activate? Input: [group:]number'), '') if grp_num is None: return if re.match(r'(\d:)?\d+', grp_num): break me_grp = ed.get_prop(app.PROP_INDEX_GROUP) grp = int(grp_num.split(':')[0]) - 1 if ':' in grp_num else me_grp num = int( grp_num.split(':')[1]) - 1 if ':' in grp_num else int(grp_num) - 1 for h in app.ed_handles(): ed_ = app.Editor(h) if grp == ed_.get_prop(app.PROP_INDEX_GROUP) and \ num == ed_.get_prop(app.PROP_INDEX_TAB): ed_.focus() app.msg_status(f(_('No tab "{}"'), grp_num))
def set_sep(self): sep = self.get_sep(ct.ed) s = ct.dlg_input('Separator char:', sep) if s is None: return if s == '\\t': s = '\t' if len(s) != 1: msg('Incorrect separator: ' + s) return ct.ed.set_prop(ct.PROP_TAG, 'sep:' + s) self.update() ct.ed.action(ct.EDACTION_UPDATE)
def move_tab(how=''): group = ed.get_prop(app.PROP_INDEX_GROUP) gr_cnt = 0 for h in app.ed_handles(): edH = app.Editor(h) if (group == edH.get_prop(app.PROP_INDEX_GROUP) and gr_cnt < edH.get_prop(app.PROP_INDEX_TAB)): gr_cnt = edH.get_prop(app.PROP_INDEX_TAB) gr_cnt += 1 old_pos = ed.get_prop(app.PROP_INDEX_TAB) new_pos = None if how == '': new_pos = app.dlg_input(_(f'New position (max={gr_cnt})'), str(old_pos + 1)) if new_pos is None: return new_pos = max(0, min(gr_cnt, int(new_pos) - 1)) else: step = -1 if how == 'l' else 1 new_pos = (old_pos + step) % gr_cnt if new_pos == old_pos: return ed.set_prop(app.PROP_INDEX_TAB, str(new_pos))
def _dlg_del_group(self, *args, **vargs): ''' show group file to delete with OK|Cancel + remove from package cfg + queue save of package cfg file ''' #pass; print(' del group') pkg = self._get_sel_pkg() snips_fn, lexers = self._get_sel_group(pkg) if pkg and snips_fn: fstr = _( 'To delete snippet group "{0}" from package "{1}" - delete the following file:' ) group_filepath = os.path.join(pkg['path'], 'snippets', snips_fn) res = ct.dlg_input(fstr.format(snips_fn, pkg['name']), group_filepath) if res is not None: #pass; print('* confirmed group deletion') del pkg['files'][snips_fn] self.modified.append( (TYPE_PKG, pkg['path'])) # package config is modified self._fill_forms(sel_pkg_path=pkg['path'])
def do_work(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] if False:pass elif aid in ('del1', 'del2'): # Delete the hotkeys cmd_nkk = m.id2nkks[m.cmd_id] del_i = 1 if aid=='del1' else 2 if not cmd_nkk[del_i]: return [] #continue#while cmd_nkk[del_i] = '' if cmd_nkk[2]: cmd_nkk[1] = cmd_nkk[2] cmd_nkk[2] = '' set_ok = app.app_proc(app.PROC_SET_HOTKEY, f('{}|{}|{}', m.cmd_id, cmd_nkk[1], cmd_nkk[2])) if not set_ok: log('Fail to use PROC_SET_HOTKEY for cmd "{}"', m.cmd_id) m.nkki_l, \ m.id2nkks, \ m.ks2id = M.prep_keys_info() elif aid in ('add1', 'add2'): ext_k = app.dlg_hotkey() pass; #LOG and log('ext_k={}',(ext_k,)) if ext_k is None: return [] #continue#while cmd_nkk = m.id2nkks[m.cmd_id] add_i = 1 if aid=='add1' else 2 old_k = cmd_nkk[add_i] new_k = old_k + ' * ' + ext_k if old_k else ext_k pass; #LOG and log('cmd_nkk,old_k,new_k={}',(cmd_nkk,old_k,new_k)) if new_k in m.ks2id: dbl_id = m.ks2id[new_k] dbl_nkk = m.id2nkks[dbl_id] if app.msg_box(f(_('Hotkey "{}" is already assigned ' '\nto command "{}".' '\n' '\nDo you want to reassign the hotkey ' '\nto selected command "{}"?') , new_k, dbl_nkk[0], cmd_nkk[0]), app.MB_OKCANCEL)==app.ID_CANCEL: return [] #continue#while dbl_i = 1 if dbl_nkk[1]==new_k else 2 pass; #LOG and log('dbl_id, dbl_nkk={}',(dbl_id, dbl_nkk)) dbl_nkk[dbl_i] = '' if dbl_nkk[2]: dbl_nkk[1], dbl_nkk[2] = dbl_nkk[2], '' pass; #LOG and log('dbl_id, dbl_nkk={}',(dbl_id, dbl_nkk)) set_ok = app.app_proc(app.PROC_SET_HOTKEY, f('{}|{}|{}', dbl_id, dbl_nkk[1], dbl_nkk[2])) if not set_ok: log('Fail to use PROC_SET_HOTKEY for cmd "{}"', dbl_id) cmd_nkk[add_i] = new_k pass; #LOG and log('cmd_id, cmd_nkk={}',(cmd_id, cmd_nkk)) set_ok = app.app_proc(app.PROC_SET_HOTKEY, f('{}|{}|{}', m.cmd_id, cmd_nkk[1], cmd_nkk[2])) if not set_ok: log('Fail to use PROC_SET_HOTKEY for cmd "{}"', m.cmd_id) m.nkki_l, \ m.id2nkks, \ m.ks2id = M.prep_keys_info() elif aid=='asnp' and sndt: cnm = sndt.get_name(m.cmd_id) new_sn = app.dlg_input(f(_('Add snip for "{}"'), cnm), '') if not new_sn: return [] #continue#while while not SnipData.is_snip(new_sn): app.msg_status(SnipData.msg_correct_snip) new_sn = app.dlg_input(f(_('Snip for "{}"'), cnm), new_sn) if not new_sn: break if not new_sn: return [] #continue#while pre_cid = sndt.get_cmdid(new_sn) if pre_cid: pre_cnm = sndt.get_name(pre_cid) if app.msg_box(f(_('Snip "{}" is already assigned ' '\nto command "{}".' '\n' '\nDo you want to reassign the snip ' '\nto command "{}"?') , new_sn, pre_cnm, cnm), app.MB_OKCANCEL)==app.ID_CANCEL: return [] #continue#while sndt.set(new_sn, cmd_id) elif aid=='rsnp' and sndt: cnm = sndt.get_name(m.cmd_id) snp_l = sndt.get_snips(m.cmd_id) snps = ', '.join(snp_l) if app.msg_box(f(_('Do you want to remove snip(s) ' '\n {}' '\nfor command "{}"?') , snps, cnm), app.MB_OKCANCEL)==app.ID_CANCEL: return [] #continue#while for snp in snp_l: sndt.free(snp) return dict(ctrls=self.get_cnts('lwks') , vals =self.get_vals('lwks') , fid ='lwks' )
def do_work(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] if False:pass elif aid in ('del1', 'del2'): # Delete the hotkeys cmd_nkk = m.id2nkks[m.cmd_id] del_i = 1 if aid=='del1' else 2 if not cmd_nkk[del_i]: return [] #continue#while cmd_nkk[del_i] = '' if cmd_nkk[2]: cmd_nkk[1] = cmd_nkk[2] cmd_nkk[2] = '' set_ok = app.app_proc(app.PROC_SET_HOTKEY, f('{}|{}|{}', m.cmd_id, cmd_nkk[1], cmd_nkk[2])) if not set_ok: log('Fail to use PROC_SET_HOTKEY for cmd "{}"', m.cmd_id) m.nkki_l, \ m.id2nkks, \ m.ks2id = M.prep_keys_info() elif aid in ('add1', 'add2'): ext_k = app.dlg_hotkey() pass; #LOG and log('ext_k={}',(ext_k,)) if ext_k is None: return [] #continue#while cmd_nkk = m.id2nkks[m.cmd_id] add_i = 1 if aid=='add1' else 2 old_k = cmd_nkk[add_i] new_k = old_k + ' * ' + ext_k if old_k else ext_k pass; #LOG and log('cmd_nkk,old_k,new_k={}',(cmd_nkk,old_k,new_k)) if new_k in m.ks2id: dbl_id = m.ks2id[new_k] dbl_nkk = m.id2nkks[dbl_id] if app.msg_box(f(_('Hotkey "{}" is already assigned ' '\nto command "{}".' '\n' '\nDo you want to reassign the hotkey ' '\nto selected command "{}"?') , new_k, dbl_nkk[0], cmd_nkk[0]), app.MB_OKCANCEL)==app.ID_CANCEL: return [] #continue#while dbl_i = 1 if dbl_nkk[1]==new_k else 2 pass; #LOG and log('dbl_id, dbl_nkk={}',(dbl_id, dbl_nkk)) dbl_nkk[dbl_i] = '' if dbl_nkk[2]: dbl_nkk[1], dbl_nkk[2] = dbl_nkk[2], '' pass; #LOG and log('dbl_id, dbl_nkk={}',(dbl_id, dbl_nkk)) set_ok = app.app_proc(app.PROC_SET_HOTKEY, f('{}|{}|{}', dbl_id, dbl_nkk[1], dbl_nkk[2])) if not set_ok: log('Fail to use PROC_SET_HOTKEY for cmd "{}"', dbl_id) cmd_nkk[add_i] = new_k pass; #LOG and log('cmd_id, cmd_nkk={}',(cmd_id, cmd_nkk)) set_ok = app.app_proc(app.PROC_SET_HOTKEY, f('{}|{}|{}', m.cmd_id, cmd_nkk[1], cmd_nkk[2])) if not set_ok: log('Fail to use PROC_SET_HOTKEY for cmd "{}"', m.cmd_id) m.nkki_l, \ m.id2nkks, \ m.ks2id = M.prep_keys_info() elif aid=='asnp' and sndt: cnm = sndt.get_name(m.cmd_id) new_sn = app.dlg_input(f(_('Add snip for "{}"'), cnm), '') if not new_sn: return [] #continue#while while not SnipData.is_snip(new_sn): app.msg_status(SnipData.msg_correct_snip) new_sn = app.dlg_input(f(_('Snip for "{}"'), cnm), new_sn) if not new_sn: break if not new_sn: return [] #continue#while pre_cid = sndt.get_cmdid(new_sn) if pre_cid: pre_cnm = sndt.get_name(pre_cid) if app.msg_box(f(_('Snippet "{}" is already assigned' '\nto command "{}".' '\n' '\nDo you want to reassign the snippet' '\nto command "{}"?') , new_sn, pre_cnm, cnm), app.MB_OKCANCEL)==app.ID_CANCEL: return [] #continue#while sndt.set(new_sn, cmd_id) elif aid=='rsnp' and sndt: cnm = sndt.get_name(m.cmd_id) snp_l = sndt.get_snips(m.cmd_id) snps = ', '.join(snp_l) if app.msg_box(f(_('Do you want to remove snip(s) ' '\n {}' '\nfor command "{}"?') , snps, cnm), app.MB_OKCANCEL)==app.ID_CANCEL: return [] #continue#while for snp in snp_l: sndt.free(snp) return dict(ctrls=self.get_cnts('lwks') , vals =self.get_vals('lwks') , fid ='lwks' )
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 on_macro(self, ed_self, mcr_record): ''' Finish for macro-recording. Params mcr_record "\n"-separated list of number number,string py:string_module,string_method,string_param ''' pass LOG and log('mcr_record={}', mcr_record) if '' == mcr_record: return app.msg_status('Empty record') def_nm = '' nms = [mcr['nm'] for mcr in self.macros] for num in range(1, 1000): def_nm = 'Macro{}'.format(num) if def_nm not in nms: break #for num while True: mcr_nm = app.dlg_input( 'Macro name. Tricks: "!NM" overwrite NM, "=NM" show NM in dialog', def_nm) if mcr_nm is None: return mcr_nm = mcr_nm.strip() if '' == mcr_nm: continue #while if mcr_nm[0] == '=': self.need_dlg = True mcr_nm = mcr_nm[1:] use_old = False if '' == mcr_nm: continue #while if mcr_nm[0] == '!': use_old = True mcr_nm = mcr_nm[1:] if '' != mcr_nm: break #while pass LOG and log('self.need_dlg, use_old, mcr_nm={}', (self.need_dlg, use_old, mcr_nm)) if use_old and mcr_nm in nms: mcr_ind = nms.index(mcr_nm) self.macros[mcr_ind]['rec'] = mcr_record self.macros[mcr_ind]['evl'] = self._record_data_to_cmds(mcr_record) id4mcr = self.macros[mcr_ind]['id'] else: while mcr_nm in nms: app.msg_box( 'Select other name.\nMacros names now:\n\n' + '\n'.join(nms), app.MB_OK) mcr_nm = app.dlg_input('Macro name', mcr_nm) if mcr_nm is None: return id4mcr = random.randint(10000, 99999) while id4mcr in self.mcr4id: id4mcr = random.randint(10000, 99999) self.macros += [{ 'id': id4mcr ##?? conflicts? , 'nm': mcr_nm, 'rec': mcr_record, 'evl': self._record_data_to_cmds(mcr_record) }] self._do_acts() if self.need_dlg: self.need_dlg = False self.last_mcr_id = id4mcr self.dlg_config()
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 dlg(self): if app.app_api_version()<'1.0.212': # depr PROC_GET_COMMAND, PROC_GET_COMMAND_PLUGIN return app.msg_status(_('Need update CudaText')) sndt = self.sndt reND = re.compile(r'\W') def is_cond4name(cond, text): if not cond: return True if '_' in cond: text = '·' + reND.sub('·', text) + '·' cond = ' ' + cond + ' ' cond = cond.replace(' _', ' ·').replace('_ ', '· ') pass; #LOG and log('cond, text={}',(cond, text)) return all(map(lambda cw: cw in text, cond.split())) def is_cond4snps(cond, sns_l): if not cond: return True if not sns_l: return False return any(map(lambda sn:fnmatch(sn, cond), sns_l)) def bmix(val1, bor2, val2): return val1 or val2 if bor2 else val1 and val2 cmds_l = [(cid, sndt.get_name(cid)) for cid in sndt.cmd_ids()] ccnd_h = _('Suitable command names will contain all specified words.' '\r · Case is ignored.' '\r · Use "_" for word boundary.' '\r "_up" selects "upper" but not "group".') scnd_h = _('Suitable command snips will match specified string.' '\r · Case is important.' '\r · Use ? for any character and * for any fragment.') cmd_id = '' ccnd = '' scnd = '' orcn = False focused = 'ccnd' while True: pass; #LOG and log('ccnd, scnd={}',(ccnd, scnd)) cins_l = [ (cid, cnm, sndt.get_snips(cid)) for cid, cnm in cmds_l] fcins_l = [ (cid, cnm, sns) for (cid, cnm, sns) in cins_l if bmix( not ccnd or is_cond4name(ccnd.upper(), cnm.upper()) ,orcn, not scnd or is_cond4snps(scnd, sns) ) ] fi_l = [ cid for (cid, cnm, sn) in fcins_l] stat = f(' ({}/{})',len(fcins_l), len(cmds_l)) itms = (zip([_('Command')+stat, _('Snip(s)')], map(str, [350, 150])) , [ (cnm, ', '.join(sns)) for (cid, cnm, sns) in fcins_l ]) cnts =[dict(cid='fltr',tp='bt' ,tid='scnd' ,l=5+520+5 ,w=110 ,cap=_('&Filter') ,props='1' ) # &f default ,dict(cid='drop',tp='bt' ,t=5+50 ,l=5+520+5 ,w=110 ,cap=_('&All') ) # &a ,dict(cid='orcn',tp='ch' ,t=5 ,l=5+300 ,w=40 ,cap=_('&OR') ,act='1' ) # &o ,dict( tp='lb' ,tid='orcn' ,l=5+5 ,w=90 ,cap=_('In &Command:') ,hint=ccnd_h) # &c ,dict(cid='ccnd',tp='ed' ,t=5+20 ,l=5+5 ,w=150 ) # ,dict( tp='lb' ,tid='orcn' ,l=5+350+5 ,w=50 ,cap=_('In &Snip(s):') ,hint=scnd_h) # &s ,dict(cid='shlp',tp='bt' ,tid='orcn' ,l=5+350+5+80,w=20 ,cap=_('&?') ) # &? ,dict(cid='scnd',tp='ed' ,t=5+20 ,l=5+350+5 ,w=100 ) # ,dict(cid='lwcs',tp='lvw' ,t=5+50 ,l=5 ,w=520,h=535 ,items=itms ,props='1' ) # grid ,dict(cid='asnp',tp='bt' ,t=200 ,l=5+520+5 ,w=110 ,cap=_('A&dd Snip') ) # &d ,dict(cid='rsnp',tp='bt' ,t=200+30 ,l=5+520+5 ,w=110 ,cap=_('F&ree Snip(s)') ) # &r ,dict(cid='help',tp='bt' ,t=600-65 ,l=5+520+5 ,w=110 ,cap=_('Hel&p') ) # &p ,dict(cid='-' ,tp='bt' ,t=600-35 ,l=5+520+5 ,w=110 ,cap=_('Close') ) # ] lwcs_n = -1 if 0==len(fi_l) else \ 0 if cmd_id not in fi_l else \ fi_l.index(cmd_id) pass; # LOG and log('stat, lwcs_n={}',(stat, lwcs_n)) vals = dict(ccnd=ccnd ,scnd=scnd ,orcn=orcn ,lwcs=lwcs_n) pass; #LOG and log('in-vals={}',(vals)) btn, vals, chds = dlg_wrapper(_('Configure "SnipToCall"'), 650-5, 600, cnts, vals, focus_cid=focused) pass; #LOG and log('an-vals={}',(vals)) pass; #LOG and log('chds={}',(chds)) if btn is None or btn=='-': return#while True focused = chds[0] if 1==len(chds) else focused ccnd = vals['ccnd'].strip() scnd = vals['scnd'].strip() orcn = vals['orcn'] lwcs_n = vals['lwcs'] cmd_id = '' if lwcs_n==-1 else fi_l[lwcs_n] if False:pass elif btn in 'fltr': focused = 'lwcs' elif btn=='drop': ccnd = '' scnd = '' focused = 'ccnd' elif btn=='shlp': app.msg_box(sndt.snip_help, app.MB_OK) elif btn=='help': dlg_wrapper(_('Help for "Config SnipToCall"'), 410, 310, [dict(cid='htxt',tp='me' ,t=5 ,h=300-28,l=5 ,w=400 ,props='1,0,1' ) # ro,mono,border ,dict(cid='-' ,tp='bt' ,t=5+300-23 ,l=5+400-80 ,w=80 ,cap=_('&Close')) ], dict(htxt=f(_('• In Command.' '\r{ccnd_h}' '\r ' '\r• In Snip. ' '\r{scnd_h}' '\r '), ccnd_h=ccnd_h, scnd_h=scnd_h) ), focus_cid='htxt') elif btn=='rsnp' and cmd_id: cnm = sndt.get_name(cmd_id) snp_l = sndt.get_snips(cmd_id) snps = ', '.join(snp_l) if app.msg_box(f(_('Do you want to remove snip(s) ' '\n {}' '\nfor command "{}"?') , snps, cnm), app.MB_OKCANCEL)==app.ID_CANCEL: continue#while for snp in snp_l: sndt.free(snp) elif btn=='asnp' and cmd_id: cnm = sndt.get_name(cmd_id) new_sn = app.dlg_input(f(_('Add snip for "{}"'), cnm), '') if not new_sn: continue#while while not SnipData.is_snip(new_sn): app.msg_status(SnipData.msg_correct_snip) new_sn = app.dlg_input(f(_('Snip for "{}"'), cnm), new_sn) if not new_sn: break if not new_sn: continue#while pre_cid = sndt.get_cmdid(new_sn) if pre_cid: pre_cnm = sndt.get_name(pre_cid) if app.msg_box(f(_('Snip "{}" is already assigned ' '\nto command "{}".' '\n' '\nDo you want to reassign the snip ' '\nto command "{}"?') , new_sn, pre_cnm, cnm), app.MB_OKCANCEL)==app.ID_CANCEL: continue#while sndt.set(new_sn, cmd_id)