Example #1
0
 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()
Example #2
0
    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)
Example #3
0
    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))
Example #4
0
    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'])
Example #5
0
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)
Example #7
0
 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)
Example #9
0
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)
Example #11
0
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))
Example #12
0
    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'
                )
Example #14
0
    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'
                )
Example #15
0
    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)
Example #16
0
    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()
Example #17
0
    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)
Example #18
0
    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)