bpo-33962: Use ttk spinbox for IDLE indent space config (GH-22954) · python/cpython@42d5a4f (original) (raw)
`@@ -15,9 +15,10 @@
`
15
15
`StringVar, BooleanVar, IntVar, TRUE, FALSE,
`
16
16
`TOP, BOTTOM, RIGHT, LEFT, SOLID, GROOVE,
`
17
17
`NONE, BOTH, X, Y, W, E, EW, NS, NSEW, NW,
`
18
``
`-
HORIZONTAL, VERTICAL, ANCHOR, ACTIVE, END)
`
``
18
`+
HORIZONTAL, VERTICAL, ANCHOR, ACTIVE, END, TclError)
`
19
19
`from tkinter.ttk import (Frame, LabelFrame, Button, Checkbutton, Entry, Label,
`
20
``
`-
OptionMenu, Notebook, Radiobutton, Scrollbar, Style)
`
``
20
`+
OptionMenu, Notebook, Radiobutton, Scrollbar, Style,
`
``
21
`+
Spinbox, Combobox)
`
21
22
`from tkinter import colorchooser
`
22
23
`import tkinter.font as tkfont
`
23
24
`from tkinter import messagebox
`
`@@ -101,8 +102,9 @@ def create_widgets(self):
`
101
102
` highpage: HighPage
`
102
103
` fontpage: FontPage
`
103
104
` keyspage: KeysPage
`
104
``
`-
genpage: GenPage
`
105
``
`-
extpage: self.create_page_extensions
`
``
105
`+
winpage: WinPage
`
``
106
`+
shedpage: ShedPage
`
``
107
`+
extpage: ExtPage
`
106
108
``
107
109
` Methods:
`
108
110
` create_action_buttons
`
`@@ -170,26 +172,15 @@ def create_action_buttons(self):
`
170
172
`return outer
`
171
173
``
172
174
`def ok(self):
`
173
``
`-
"""Apply config changes, then dismiss dialog.
`
174
``
-
175
``
`-
Methods:
`
176
``
`-
apply
`
177
``
`-
destroy: inherited
`
178
``
`-
"""
`
``
175
`+
"""Apply config changes, then dismiss dialog."""
`
179
176
`self.apply()
`
180
177
`self.destroy()
`
181
178
``
182
179
`def apply(self):
`
183
``
`-
"""Apply config changes and leave dialog open.
`
184
``
-
185
``
`-
Methods:
`
186
``
`-
deactivate_current_config
`
187
``
`-
save_all_changed_extensions
`
188
``
`-
activate_config_changes
`
189
``
`-
"""
`
``
180
`+
"""Apply config changes and leave dialog open."""
`
190
181
`self.deactivate_current_config()
`
191
182
`changes.save_all()
`
192
``
`-
self.save_all_changed_extensions()
`
``
183
`+
self.extpage.save_all_changed_extensions()
`
193
184
`self.activate_config_changes()
`
194
185
``
195
186
`def cancel(self):
`
`@@ -299,12 +290,11 @@ class FontPage(Frame):
`
299
290
`def init(self, master, highpage):
`
300
291
`super().init(master)
`
301
292
`self.highlight_sample = highpage.highlight_sample
`
302
``
`-
self.create_page_font_tab()
`
``
293
`+
self.create_page_font()
`
303
294
`self.load_font_cfg()
`
304
``
`-
self.load_tab_cfg()
`
305
295
``
306
``
`-
def create_page_font_tab(self):
`
307
``
`-
"""Return frame of widgets for Font/Tabs tab.
`
``
296
`+
def create_page_font(self):
`
``
297
`+
"""Return frame of widgets for Font tab.
`
308
298
``
309
299
` Fonts: Enable users to provisionally change font face, size, or
`
310
300
` boldness and to see the consequence of proposed choices. Each
`
`@@ -328,11 +318,6 @@ def create_page_font_tab(self):
`
328
318
` Set_samples applies a new font constructed from the font vars to
`
329
319
` font_sample and to highlight_sample on the highlight page.
`
330
320
``
331
``
`-
Tabs: Enable users to change spaces entered for indent tabs.
`
332
``
`-
Changing indent_scale value with the mouse sets Var space_num,
`
333
``
`-
which invokes the default callback to add an entry to
`
334
``
`-
changes. Load_tab_cfg initializes space_num to default.
`
335
``
-
336
321
` Widgets for FontPage(Frame): (*) widgets bound to self
`
337
322
` frame_font: LabelFrame
`
338
323
` frame_font_name: Frame
`
`@@ -345,23 +330,16 @@ def create_page_font_tab(self):
`
345
330
` (*)bold_toggle: Checkbutton - font_bold
`
346
331
` frame_sample: LabelFrame
`
347
332
` (*)font_sample: Label
`
348
``
`-
frame_indent: LabelFrame
`
349
``
`-
indent_title: Label
`
350
``
`-
(*)indent_scale: Scale - space_num
`
351
333
` """
`
352
334
`self.font_name = tracers.add(StringVar(self), self.var_changed_font)
`
353
335
`self.font_size = tracers.add(StringVar(self), self.var_changed_font)
`
354
336
`self.font_bold = tracers.add(BooleanVar(self), self.var_changed_font)
`
355
``
`-
self.space_num = tracers.add(IntVar(self), ('main', 'Indent', 'num-spaces'))
`
356
337
``
357
338
`# Define frames and widgets.
`
358
``
`-
frame_font = LabelFrame(
`
359
``
`-
self, borderwidth=2, relief=GROOVE, text=' Shell/Editor Font ')
`
360
``
`-
frame_sample = LabelFrame(
`
361
``
`-
self, borderwidth=2, relief=GROOVE,
`
362
``
`-
text=' Font Sample (Editable) ')
`
363
``
`-
frame_indent = LabelFrame(
`
364
``
`-
self, borderwidth=2, relief=GROOVE, text=' Indentation Width ')
`
``
339
`+
frame_font = LabelFrame(self, borderwidth=2, relief=GROOVE,
`
``
340
`+
text=' Shell/Editor Font ')
`
``
341
`+
frame_sample = LabelFrame(self, borderwidth=2, relief=GROOVE,
`
``
342
`+
text=' Font Sample (Editable) ')
`
365
343
`# frame_font.
`
366
344
`frame_font_name = Frame(frame_font)
`
367
345
`frame_font_param = Frame(frame_font)
`
`@@ -385,21 +363,13 @@ def create_page_font_tab(self):
`
385
363
`self.font_sample = font_sample_frame.text
`
386
364
`self.font_sample.config(wrap=NONE, width=1, height=1)
`
387
365
`self.font_sample.insert(END, font_sample_text)
`
388
``
`-
frame_indent.
`
389
``
`-
indent_title = Label(
`
390
``
`-
frame_indent, justify=LEFT,
`
391
``
`-
text='Python Standard: 4 Spaces!')
`
392
``
`-
self.indent_scale = Scale(
`
393
``
`-
frame_indent, variable=self.space_num,
`
394
``
`-
orient='horizontal', tickinterval=2, from_=2, to=16)
`
395
366
``
396
367
`# Grid and pack widgets:
`
397
368
`self.columnconfigure(1, weight=1)
`
398
369
`self.rowconfigure(2, weight=1)
`
399
370
`frame_font.grid(row=0, column=0, padx=5, pady=5)
`
400
371
`frame_sample.grid(row=0, column=1, rowspan=3, padx=5, pady=5,
`
401
372
`sticky='nsew')
`
402
``
`-
frame_indent.grid(row=1, column=0, padx=5, pady=5, sticky='ew')
`
403
373
`# frame_font.
`
404
374
`frame_font_name.pack(side=TOP, padx=5, pady=5, fill=X)
`
405
375
`frame_font_param.pack(side=TOP, padx=5, pady=5, fill=X)
`
`@@ -411,9 +381,6 @@ def create_page_font_tab(self):
`
411
381
`self.bold_toggle.pack(side=LEFT, anchor=W, padx=20)
`
412
382
`# frame_sample.
`
413
383
`font_sample_frame.pack(expand=TRUE, fill=BOTH)
`
414
``
`-
frame_indent.
`
415
``
`-
indent_title.pack(side=TOP, anchor=W, padx=5)
`
416
``
`-
self.indent_scale.pack(side=TOP, padx=5, fill=X)
`
417
384
``
418
385
`def load_font_cfg(self):
`
419
386
`"""Load current configuration settings for the font options.
`
`@@ -487,22 +454,6 @@ def set_samples(self, event=None):
`
487
454
`self.font_sample['font'] = new_font
`
488
455
`self.highlight_sample['font'] = new_font
`
489
456
``
490
``
`-
def load_tab_cfg(self):
`
491
``
`-
"""Load current configuration settings for the tab options.
`
492
``
-
493
``
`-
Attributes updated:
`
494
``
`-
space_num: Set to value from idleConf.
`
495
``
`-
"""
`
496
``
`-
Set indent sizes.
`
497
``
`-
space_num = idleConf.GetOption(
`
498
``
`-
'main', 'Indent', 'num-spaces', default=4, type='int')
`
499
``
`-
self.space_num.set(space_num)
`
500
``
-
501
``
`-
def var_changed_space_num(self, *params):
`
502
``
`-
"Store change to indentation size."
`
503
``
`-
value = self.space_num.get()
`
504
``
`-
changes.add_option('main', 'Indent', 'num-spaces', value)
`
505
``
-
506
457
``
507
458
`class HighPage(Frame):
`
508
459
``
`@@ -515,7 +466,7 @@ def init(self, master, extpage):
`
515
466
`self.load_theme_cfg()
`
516
467
``
517
468
`def create_page_highlight(self):
`
518
``
`-
"""Return frame of widgets for Highlighting tab.
`
``
469
`+
"""Return frame of widgets for Highlights tab.
`
519
470
``
520
471
` Enable users to provisionally change foreground and background
`
521
472
` colors applied to textual tags. Color mappings are stored in
`
`@@ -1617,40 +1568,41 @@ def create_page_windows(self):
`
1617
1568
`"""Return frame of widgets for Windows tab.
`
1618
1569
``
1619
1570
` Enable users to provisionally change general window options.
`
1620
``
`-
Function load_windows_cfg initializes tk variables idleConf.
`
``
1571
`+
Function load_windows_cfg initializes tk variable idleConf.
`
1621
1572
` Radiobuttons startup_shell_on and startup_editor_on set var
`
1622
1573
` startup_edit. Entry boxes win_width_int and win_height_int set var
`
1623
1574
` win_width and win_height. Setting var_name invokes the default
`
1624
1575
` callback that adds option to changes.
`
1625
1576
``
1626
``
`-
Widgets for WinPage(Frame): (*) widgets bound to self
`
``
1577
`+
Widgets for WinPage(Frame): > vars, bound to self
`
1627
1578
` frame_window: LabelFrame
`
1628
1579
` frame_run: Frame
`
1629
1580
` startup_title: Label
`
1630
``
`-
(*)startup_editor_on: Radiobutton - startup_edit
`
1631
``
`-
(*)startup_shell_on: Radiobutton - startup_edit
`
``
1581
`+
startup_editor_on: Radiobutton > startup_edit
`
``
1582
`+
startup_shell_on: Radiobutton > startup_edit
`
1632
1583
` frame_win_size: Frame
`
1633
1584
` win_size_title: Label
`
1634
1585
` win_width_title: Label
`
1635
``
`-
(*)win_width_int: Entry - win_width
`
``
1586
`+
win_width_int: Entry > win_width
`
1636
1587
` win_height_title: Label
`
1637
``
`-
(*)win_height_int: Entry - win_height
`
1638
``
`-
frame_cursor_blink: Frame
`
1639
``
`-
cursor_blink_title: Label
`
1640
``
`-
(*)cursor_blink_bool: Checkbutton - cursor_blink
`
``
1588
`+
win_height_int: Entry > win_height
`
``
1589
`+
frame_cursor: Frame
`
``
1590
`+
indent_title: Label
`
``
1591
`+
indent_chooser: Spinbox (Combobox < 8.5.9) > indent_spaces
`
``
1592
`+
blink_on: Checkbutton > cursor_blink
`
1641
1593
` frame_autocomplete: Frame
`
1642
1594
` auto_wait_title: Label
`
1643
``
`-
(*)auto_wait_int: Entry - autocomplete_wait
`
``
1595
`+
auto_wait_int: Entry > autocomplete_wait
`
1644
1596
` frame_paren1: Frame
`
1645
1597
` paren_style_title: Label
`
1646
``
`-
(*)paren_style_type: OptionMenu - paren_style
`
``
1598
`+
paren_style_type: OptionMenu > paren_style
`
1647
1599
` frame_paren2: Frame
`
1648
1600
` paren_time_title: Label
`
1649
``
`-
(*)paren_flash_time: Entry - flash_delay
`
1650
``
`-
(*)bell_on: Checkbutton - paren_bell
`
``
1601
`+
paren_flash_time: Entry > flash_delay
`
``
1602
`+
bell_on: Checkbutton > paren_bell
`
1651
1603
` frame_format: Frame
`
1652
1604
` format_width_title: Label
`
1653
``
`-
(*)format_width_int: Entry - format_width
`
``
1605
`+
format_width_int: Entry > format_width
`
1654
1606
` """
`
1655
1607
`# Integer values need StringVar because int('') raises.
`
1656
1608
`self.startup_edit = tracers.add(
`
`@@ -1659,6 +1611,8 @@ def create_page_windows(self):
`
1659
1611
`StringVar(self), ('main', 'EditorWindow', 'width'))
`
1660
1612
`self.win_height = tracers.add(
`
1661
1613
`StringVar(self), ('main', 'EditorWindow', 'height'))
`
``
1614
`+
self.indent_spaces = tracers.add(
`
``
1615
`+
StringVar(self), ('main', 'Indent', 'num-spaces'))
`
1662
1616
`self.cursor_blink = tracers.add(
`
1663
1617
`BooleanVar(self), ('main', 'EditorWindow', 'cursor-blink'))
`
1664
1618
`self.autocomplete_wait = tracers.add(
`
`@@ -1699,18 +1653,28 @@ def create_page_windows(self):
`
1699
1653
`validatecommand=self.digits_only, validate='key',
`
1700
1654
` )
`
1701
1655
``
1702
``
`-
frame_cursor_blink = Frame(frame_window, borderwidth=0)
`
1703
``
`-
cursor_blink_title = Label(frame_cursor_blink, text='Cursor Blink')
`
1704
``
`-
self.cursor_blink_bool = Checkbutton(frame_cursor_blink,
`
1705
``
`-
variable=self.cursor_blink, width=1)
`
``
1656
`+
frame_cursor = Frame(frame_window, borderwidth=0)
`
``
1657
`+
indent_title = Label(frame_cursor,
`
``
1658
`+
text='Indent spaces (4 is standard)')
`
``
1659
`+
try:
`
``
1660
`+
self.indent_chooser = Spinbox(
`
``
1661
`+
frame_cursor, textvariable=self.indent_spaces,
`
``
1662
`+
from_=1, to=10, width=2,
`
``
1663
`+
validatecommand=self.digits_only, validate='key')
`
``
1664
`+
except TclError:
`
``
1665
`+
self.indent_chooser = Combobox(
`
``
1666
`+
frame_cursor, textvariable=self.indent_spaces,
`
``
1667
`+
state="readonly", values=list(range(1,11)), width=3)
`
``
1668
`+
cursor_blink_title = Label(frame_cursor, text='Cursor Blink')
`
``
1669
`+
self.cursor_blink_bool = Checkbutton(frame_cursor, text="Cursor blink",
`
``
1670
`+
variable=self.cursor_blink)
`
1706
1671
``
1707
1672
`frame_autocomplete = Frame(frame_window, borderwidth=0,)
`
1708
1673
`auto_wait_title = Label(frame_autocomplete,
`
1709
``
`-
text='Completions Popup Wait (milliseconds)')
`
1710
``
`-
self.auto_wait_int = Entry(frame_autocomplete, width=6,
`
1711
``
`-
textvariable=self.autocomplete_wait,
`
1712
``
`-
validatecommand=self.digits_only,
`
1713
``
`-
validate='key')
`
``
1674
`+
text='Completions Popup Wait (milliseconds)')
`
``
1675
`+
self.auto_wait_int = Entry(
`
``
1676
`+
frame_autocomplete, textvariable=self.autocomplete_wait,
`
``
1677
`+
width=6, validatecommand=self.digits_only, validate='key')
`
1714
1678
``
1715
1679
`frame_paren1 = Frame(frame_window, borderwidth=0)
`
1716
1680
`paren_style_title = Label(frame_paren1, text='Paren Match Style')
`
`@@ -1722,7 +1686,8 @@ def create_page_windows(self):
`
1722
1686
`frame_paren2, text='Time Match Displayed (milliseconds)\n'
`
1723
1687
`'(0 is until next input)')
`
1724
1688
`self.paren_flash_time = Entry(
`
1725
``
`-
frame_paren2, textvariable=self.flash_delay, width=6)
`
``
1689
`+
frame_paren2, textvariable=self.flash_delay, width=6,
`
``
1690
`+
validatecommand=self.digits_only, validate='key')
`
1726
1691
`self.bell_on = Checkbutton(
`
1727
1692
`frame_paren2, text="Bell on Mismatch", variable=self.paren_bell)
`
1728
1693
`frame_format = Frame(frame_window, borderwidth=0)
`
`@@ -1747,10 +1712,11 @@ def create_page_windows(self):
`
1747
1712
`win_height_title.pack(side=RIGHT, anchor=E, pady=5)
`
1748
1713
`self.win_width_int.pack(side=RIGHT, anchor=E, padx=10, pady=5)
`
1749
1714
`win_width_title.pack(side=RIGHT, anchor=E, pady=5)
`
1750
``
`-
frame_cursor_blink.
`
1751
``
`-
frame_cursor_blink.pack(side=TOP, padx=5, pady=0, fill=X)
`
1752
``
`-
cursor_blink_title.pack(side=LEFT, anchor=W, padx=5, pady=5)
`
1753
``
`-
self.cursor_blink_bool.pack(side=LEFT, padx=5, pady=5)
`
``
1715
`+
frame_cursor.
`
``
1716
`+
frame_cursor.pack(side=TOP, padx=5, pady=0, fill=X)
`
``
1717
`+
indent_title.pack(side=LEFT, anchor=W, padx=5)
`
``
1718
`+
self.indent_chooser.pack(side=LEFT, anchor=W, padx=10)
`
``
1719
`+
self.cursor_blink_bool.pack(side=RIGHT, anchor=E, padx=15, pady=5)
`
1754
1720
`# frame_autocomplete.
`
1755
1721
`frame_autocomplete.pack(side=TOP, padx=5, pady=0, fill=X)
`
1756
1722
`auto_wait_title.pack(side=LEFT, anchor=W, padx=5, pady=5)
`
`@@ -1776,6 +1742,8 @@ def load_windows_cfg(self):
`
1776
1742
`'main', 'EditorWindow', 'width', type='int'))
`
1777
1743
`self.win_height.set(idleConf.GetOption(
`
1778
1744
`'main', 'EditorWindow', 'height', type='int'))
`
``
1745
`+
self.indent_spaces.set(idleConf.GetOption(
`
``
1746
`+
'main', 'Indent', 'num-spaces', type='int'))
`
1779
1747
`self.cursor_blink.set(idleConf.GetOption(
`
1780
1748
`'main', 'EditorWindow', 'cursor-blink', type='bool'))
`
1781
1749
`self.autocomplete_wait.set(idleConf.GetOption(
`