1import os
2from cudatext import *
3import cudatext_cmd
4
5from cudax_lib import get_translation
6_   = get_translation(__file__)  # I18N
7
8fn_config = os.path.join(app_path(APP_DIR_SETTINGS), 'cuda_tabs_list.ini')
9fn_icon = 'tabs.png'
10
11def bool_to_str(v): return '1' if v else '0'
12def str_to_bool(s): return s=='1'
13
14THEME = app_proc(PROC_THEME_UI_DICT_GET, '')
15
16class Command:
17    title = 'Tabs'    # No _(), the translation is offered in "translation template.ini".
18    h_dlg = None
19    h_list = None
20    h_menu = None
21    busy_update = False
22    show_index_group = False
23    show_index_tab = False
24    show_index_aligned = False
25    font_name = 'default'
26    font_size = 10
27    column_name = 170
28    column_folder = 0
29    column_lexer = 80
30    show_column_folder = False
31    show_column_lexer = False
32
33    def __init__(self):
34        self.load_ops()
35
36    def load_ops(self):
37        self.show_index_group = str_to_bool(ini_read(fn_config, 'op', 'show_index_group', '0'))
38        self.show_index_tab = str_to_bool(ini_read(fn_config, 'op', 'show_index_tab', '0'))
39        self.show_index_aligned = str_to_bool(ini_read(fn_config, 'op', 'show_index_aligned', '0'))
40        self.font_name = ini_read(fn_config, 'op', 'font_name', self.font_name)
41        self.font_size = int(ini_read(fn_config, 'op', 'font_size', str(self.font_size)))
42        self.column_name = int(ini_read(fn_config, 'columns', 'width_name', str(self.column_name)))
43        self.column_folder = int(ini_read(fn_config, 'columns', 'width_folder', str(self.column_folder)))
44        self.column_lexer = int(ini_read(fn_config, 'columns', 'width_lexer', str(self.column_lexer)))
45        self.show_column_folder = str_to_bool(ini_read(fn_config, 'columns', 'show_folder', bool_to_str(self.show_column_folder)))
46        self.show_column_lexer = str_to_bool(ini_read(fn_config, 'columns', 'show_lexer', bool_to_str(self.show_column_lexer)))
47
48    def save_ops(self):
49        ini_write(fn_config, 'op', 'show_index_group', bool_to_str(self.show_index_group))
50        ini_write(fn_config, 'op', 'show_index_tab', bool_to_str(self.show_index_tab))
51        ini_write(fn_config, 'op', 'show_index_aligned', bool_to_str(self.show_index_aligned))
52        ini_write(fn_config, 'op', 'font_name', self.font_name)
53        ini_write(fn_config, 'op', 'font_size', str(self.font_size))
54
55        ini_write(fn_config, 'columns', '; width_ values: >0 - in pixels, <0 - in percents, =0 - auto-stretched', '')
56        ini_write(fn_config, 'columns', '; show_ values: boolean, 0 or 1', '')
57        ini_write(fn_config, 'columns', 'width_name', str(self.column_name))
58        ini_write(fn_config, 'columns', 'width_folder', str(self.column_folder))
59        ini_write(fn_config, 'columns', 'width_lexer', str(self.column_lexer))
60        ini_write(fn_config, 'columns', 'show_folder', bool_to_str(self.show_column_folder))
61        ini_write(fn_config, 'columns', 'show_lexer', bool_to_str(self.show_column_lexer))
62
63    def open(self):
64
65        if not self.h_dlg:
66            self.init_form()
67        and_focus = True
68        app_proc(PROC_SIDEPANEL_ACTIVATE, (self.title, and_focus))
69        self.update()
70
71    def init_form(self):
72
73        self.h_dlg = dlg_proc(0, DLG_CREATE)
74
75        dlg_proc(self.h_dlg, DLG_PROP_SET, prop={
76            'keypreview': True,
77            'on_key_down': self.form_key_down,
78        })
79
80        n = dlg_proc(self.h_dlg, DLG_CTL_ADD, prop='listbox_ex')
81
82        self.h_list = dlg_proc(self.h_dlg, DLG_CTL_HANDLE, index=n)
83        listbox_proc(self.h_list, LISTBOX_SET_SHOW_X, index=2)
84        listbox_proc(self.h_list, LISTBOX_SET_HOTTRACK, index=1)
85        listbox_proc(self.h_list, LISTBOX_SET_COLUMN_SEP, text='|')
86
87        sizes = [self.column_name]
88        if self.show_column_folder:
89            sizes.append(self.column_folder)
90        if self.show_column_lexer:
91            sizes.append(self.column_lexer)
92        listbox_proc(self.h_list, LISTBOX_SET_COLUMNS, text=sizes)
93
94        dlg_proc(self.h_dlg, DLG_CTL_PROP_SET, index=n, prop={
95            'name':'list',
96            'a_r':('',']'), #anchor to entire form: l,r,t,b
97            'a_b':('',']'),
98            'on_select': 'cuda_tabs_list.list_on_sel',
99            'on_menu': 'cuda_tabs_list.list_on_menu',
100            'on_click': 'cuda_tabs_list.list_on_click',
101            'on_click_x': 'cuda_tabs_list.list_on_click_x',
102            'font_name': self.font_name,
103            'font_size': self.font_size,
104            #'font_color': self.get_color_font(),
105            #'color': self.get_color_back(),
106            } )
107
108        app_proc(PROC_SIDEPANEL_ADD_DIALOG, (self.title, self.h_dlg, fn_icon))
109
110        self.h_menu = menu_proc(0, MENU_CREATE)
111        menu_proc(self.h_menu, MENU_CLEAR)
112        menu_proc(self.h_menu, MENU_ADD, caption=_('Close'), command='cuda_tabs_list.menu_close_sel')
113        menu_proc(self.h_menu, MENU_ADD, caption=_('Close others'), command='cuda_tabs_list.menu_close_others')
114        menu_proc(self.h_menu, MENU_ADD, caption='-', command='')
115        menu_proc(self.h_menu, MENU_ADD, caption=_('Copy filename only'), command='cuda_tabs_list.menu_copy_file_name')
116        menu_proc(self.h_menu, MENU_ADD, caption=_('Copy full filepath'), command='cuda_tabs_list.menu_copy_file_path')
117
118    def on_focus(self, ed_self):
119        self.update()
120
121    def on_open(self, ed_self):
122        self.update()
123
124    def on_tab_move(self, ed_self):
125        self.update()
126
127    def clear_list(self):
128        listbox_proc(self.h_list, LISTBOX_DELETE_ALL)
129
130    def update(self):
131        if self.h_list is None: return
132        self.busy_update = True
133        self.clear_list()
134
135        ed.set_prop(PROP_TAG, 'tag')
136        handles = ed_handles()
137
138        hh = list(handles)
139        count = hh[-1]-hh[0]+1
140        format_len = 1 if count<10 else 2 if count<100 else 3 if count<1000 else 4
141
142        for h in handles:
143            edit = Editor(h)
144            image_index = h-handles[0]
145
146            prefix = ''
147            show_g = self.show_index_group
148            show_t = self.show_index_tab
149
150            if show_g or show_t:
151                n_group = edit.get_prop(PROP_INDEX_GROUP)+1
152                if n_group<=6:
153                    s_group = str(n_group)
154                else:
155                    s_group = 'f'+str(n_group-6)
156                n_tab = edit.get_prop(PROP_INDEX_TAB)+1
157                s_tab = str(n_tab)
158                if self.show_index_aligned:
159                    if len(s_tab)<format_len:
160                        s_tab = ' '*(format_len-len(s_tab))+s_tab
161
162                if show_g and show_t:
163                    prefix = '%s:%s. '%(s_group, s_tab)
164                elif show_g:
165                    prefix = '%s: '%s_group
166                elif show_t:
167                    prefix = '%s. '%s_tab
168
169            name = prefix + edit.get_prop(PROP_TAB_TITLE).lstrip('*')
170            if self.show_column_folder:
171                name += '|' + os.path.dirname(edit.get_filename())
172            if self.show_column_lexer:
173                name += '|' + edit.get_prop(PROP_LEXER_FILE)
174
175            mod = edit.get_prop(PROP_MODIFIED)
176            cnt = listbox_proc(self.h_list, LISTBOX_ADD_PROP, index=-1,
177                text=name, tag={'modified': mod} )
178            if edit.get_prop(PROP_TAG)=='tag':
179                listbox_proc(self.h_list, LISTBOX_SET_SEL, index=cnt-1)
180
181        ed.set_prop(PROP_TAG, '')
182
183        self.busy_update = False
184
185
186    def on_state_ed(self, ed_self, state):
187        if state in [EDSTATE_TAB_TITLE, EDSTATE_MODIFIED]:
188            self.update()
189
190    def ed_of_sel(self):
191        sel = listbox_proc(self.h_list, LISTBOX_GET_SEL)
192        if sel<0: return
193        h = ed_handles()[sel]
194        return Editor(h)
195
196    def menu_close_sel(self):
197        e = self.ed_of_sel()
198        if e:
199            e.cmd(cudatext_cmd.cmd_FileClose)
200
201    def menu_close_others(self):
202        e = self.ed_of_sel()
203        if e:
204            e.cmd(cudatext_cmd.cmd_FileCloseOtherAll)
205
206    def menu_copy_file_path(self):
207        e = self.ed_of_sel()
208        if e:
209            e.cmd(cudatext_cmd.cmd_CopyFilenameFull)
210
211    def menu_copy_file_name(self):
212        e = self.ed_of_sel()
213        if e:
214            e.cmd(cudatext_cmd.cmd_CopyFilenameName)
215
216
217    def list_on_sel(self, id_dlg, id_ctl, data='', info=''):
218        if self.h_list is None: return
219        if self.busy_update: return
220
221        e = self.ed_of_sel()
222        if e:
223            e.focus()
224
225    def list_on_menu(self, id_dlg, id_ctl, data='', info=''):
226        if self.h_menu is None: return
227        e = self.ed_of_sel()
228        if e:
229            e.focus()
230        menu_proc(self.h_menu, MENU_SHOW, command='')
231
232    def list_on_click_x(self, id_dlg, id_ctl, data='', info=''):
233        e = self.ed_of_sel()
234        if e:
235            e.focus()
236        self.menu_close_sel()
237
238    def list_on_click(self, id_dlg, id_ctl, data='', info=''):
239        e = self.ed_of_sel()
240        if e:
241            e.focus()
242
243    def config(self):
244        self.save_ops()
245        file_open(fn_config)
246
247    def get_color_font(self):
248        return THEME['ListFont']['color']
249
250    def get_color_back(self):
251        return THEME['ListBg']['color']
252
253    def form_key_down(self, id_dlg, id_ctl, data='', info=''):
254
255        key = id_ctl
256        state = data
257
258        #handle Enter and Space
259        if (key in [13, 32]) and (state==''):
260            self.list_on_click(id_dlg, id_ctl)
261            return False
262