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(

`