diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index b88b1e3cbff..3a4873b624f 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,9 @@ Released on 2020-10-05? ====================================== +bpo-27115: For 'Go to Line', use a Query entry box subclass with +IDLE standard behavior and improved error checking. + bpo-39885: Since clicking to get an IDLE context menu moves the cursor, any text selection should be and now is cleared. diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index 51941900d5c..b0f88b5463d 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -672,18 +672,16 @@ class EditorWindow(object): def goto_line_event(self, event): text = self.text - lineno = tkSimpleDialog.askinteger("Goto", - "Go to line number:",parent=text) - if lineno is None: - return "break" - if lineno <= 0: - text.bell() - return "break" - - text.tag_remove("sel", "1.0", "end") - text.mark_set("insert", f'{lineno}.0') - text.see("insert") - self.set_line_and_column() + lineno = query.Goto( + text, "Go To Line", + "Enter a positive integer\n" + "('big' = end of file):" + ).result + if lineno is not None: + text.tag_remove("sel", "1.0", "end") + text.mark_set("insert", f'{lineno}.0') + text.see("insert") + self.set_line_and_column() return "break" def open_module(self): diff --git a/Lib/idlelib/idle_test/test_query.py b/Lib/idlelib/idle_test/test_query.py index f957585190d..6d026cb5320 100644 --- a/Lib/idlelib/idle_test/test_query.py +++ b/Lib/idlelib/idle_test/test_query.py @@ -138,6 +138,33 @@ class ModuleNameTest(unittest.TestCase): self.assertEqual(dialog.entry_error['text'], '') +class GotoTest(unittest.TestCase): + "Test Goto subclass of Query." + + class Dummy_ModuleName: + entry_ok = query.Goto.entry_ok # Function being tested. + def __init__(self, dummy_entry): + self.entry = Var(value=dummy_entry) + self.entry_error = {'text': ''} + def showerror(self, message): + self.entry_error['text'] = message + + def test_bogus_goto(self): + dialog = self.Dummy_ModuleName('a') + self.assertEqual(dialog.entry_ok(), None) + self.assertIn('not a base 10 integer', dialog.entry_error['text']) + + def test_bad_goto(self): + dialog = self.Dummy_ModuleName('0') + self.assertEqual(dialog.entry_ok(), None) + self.assertIn('not a positive integer', dialog.entry_error['text']) + + def test_good_goto(self): + dialog = self.Dummy_ModuleName('1') + self.assertEqual(dialog.entry_ok(), 1) + self.assertEqual(dialog.entry_error['text'], '') + + # 3 HelpSource test classes each test one method. class HelpsourceBrowsefileTest(unittest.TestCase): @@ -363,6 +390,22 @@ class ModulenameGuiTest(unittest.TestCase): root.destroy() +class GotoGuiTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + + def test_click_module_name(self): + root = Tk() + root.withdraw() + dialog = query.Goto(root, 'T', 't', _utest=True) + dialog.entry.insert(0, '22') + dialog.button_ok.invoke() + self.assertEqual(dialog.result, 22) + root.destroy() + + class HelpsourceGuiTest(unittest.TestCase): @classmethod diff --git a/Lib/idlelib/query.py b/Lib/idlelib/query.py index 57616de4fe0..2a88530b4d0 100644 --- a/Lib/idlelib/query.py +++ b/Lib/idlelib/query.py @@ -223,6 +223,22 @@ class ModuleName(Query): return file_path +class Goto(Query): + "Get a positive line number for editor Go To Line." + # Used in editor.EditorWindow.goto_line_event. + + def entry_ok(self): + try: + lineno = int(self.entry.get()) + except ValueError: + self.showerror('not a base 10 integer.') + return None + if lineno <= 0: + self.showerror('not a positive integer.') + return None + return lineno + + class HelpSource(Query): "Get menu name and help source for Help menu." # Used in ConfigDialog.HelpListItemAdd/Edit, (941/9) diff --git a/Misc/NEWS.d/next/IDLE/2020-03-09-02-45-12.bpo-27115.8hSHMo.rst b/Misc/NEWS.d/next/IDLE/2020-03-09-02-45-12.bpo-27115.8hSHMo.rst new file mode 100644 index 00000000000..76af19e6014 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2020-03-09-02-45-12.bpo-27115.8hSHMo.rst @@ -0,0 +1,2 @@ +For 'Go to Line', use a Query box subclass with IDLE standard behavior +and improved error checking.