Commit 3b6a5325 authored by Terry Jan Reedy's avatar Terry Jan Reedy

Issue #5124: Paste with selection should always replace.

This is how paste work on Windows, Mac, modern Linux apps, and ttk widgets.
The exception was X11 tk widgets.  Original patch by Serhiy Storchake.
parent a0f2295e
...@@ -1408,6 +1408,17 @@ class PseudoInputFile(PseudoFile): ...@@ -1408,6 +1408,17 @@ class PseudoInputFile(PseudoFile):
self.shell.close() self.shell.close()
def fix_x11_paste(root):
"Make paste replace selection on x11. See issue #5124."
if root._windowingsystem == 'x11':
for cls in 'Text', 'Entry', 'Spinbox':
root.bind_class(
cls,
'<<Paste>>',
'catch {%W delete sel.first sel.last}\n' +
root.bind_class(cls, '<<Paste>>'))
usage_msg = """\ usage_msg = """\
USAGE: idle [-deins] [-t title] [file]* USAGE: idle [-deins] [-t title] [file]*
...@@ -1537,8 +1548,10 @@ def main(): ...@@ -1537,8 +1548,10 @@ def main():
'editor-on-startup', type='bool') 'editor-on-startup', type='bool')
enable_edit = enable_edit or edit_start enable_edit = enable_edit or edit_start
enable_shell = enable_shell or not enable_edit enable_shell = enable_shell or not enable_edit
# start editor and/or shell windows: # start editor and/or shell windows:
root = Tk(className="Idle") root = Tk(className="Idle")
root.withdraw()
# set application icon # set application icon
icondir = os.path.join(os.path.dirname(__file__), 'Icons') icondir = os.path.join(os.path.dirname(__file__), 'Icons')
...@@ -1553,7 +1566,7 @@ def main(): ...@@ -1553,7 +1566,7 @@ def main():
root.tk.call('wm', 'iconphoto', str(root), "-default", *icons) root.tk.call('wm', 'iconphoto', str(root), "-default", *icons)
fixwordbreaks(root) fixwordbreaks(root)
root.withdraw() fix_x11_paste(root)
flist = PyShellFileList(root) flist = PyShellFileList(root)
macosxSupport.setupApp(root, flist) macosxSupport.setupApp(root, flist)
......
'''Test (selected) IDLE Edit menu items.
Edit modules have their own test files files
'''
from test.test_support import requires
requires('gui')
import Tkinter as tk
import unittest
from idlelib import PyShell
class PasteTest(unittest.TestCase):
'''Test pasting into widgets that allow pasting.
On X11, replacing selections requires tk fix.
'''
@classmethod
def setUpClass(cls):
cls.root = root = tk.Tk()
PyShell.fix_x11_paste(root)
cls.text = tk.Text(root)
cls.entry = tk.Entry(root)
cls.spin = tk.Spinbox(root)
root.clipboard_clear()
root.clipboard_append('two')
@classmethod
def tearDownClass(cls):
del cls.text, cls.entry, cls.spin
cls.root.clipboard_clear()
cls.root.update_idletasks()
cls.root.update()
cls.root.destroy()
del cls.root
def test_paste_text_no_selection(self):
"Test pasting into text without a selection."
text = self.text
tag, ans = '', 'onetwo\n'
text.delete('1.0', 'end')
text.insert('1.0', 'one', tag)
text.event_generate('<<Paste>>')
self.assertEqual(text.get('1.0', 'end'), ans)
def test_paste_text_selection(self):
"Test pasting into text with a selection."
text = self.text
tag, ans = 'sel', 'two\n'
text.delete('1.0', 'end')
text.insert('1.0', 'one', tag)
text.event_generate('<<Paste>>')
self.assertEqual(text.get('1.0', 'end'), ans)
def test_paste_entry_no_selection(self):
"Test pasting into an entry without a selection."
# On 3.6, generated <<Paste>> fails without empty select range
# for 'no selection'. Live widget works fine.
entry = self.entry
end, ans = 0, 'onetwo'
entry.delete(0, 'end')
entry.insert(0, 'one')
entry.select_range(0, end) # see note
entry.event_generate('<<Paste>>')
self.assertEqual(entry.get(), ans)
def test_paste_entry_selection(self):
"Test pasting into an entry with a selection."
entry = self.entry
end, ans = 'end', 'two'
entry.delete(0, 'end')
entry.insert(0, 'one')
entry.select_range(0, end)
entry.event_generate('<<Paste>>')
self.assertEqual(entry.get(), ans)
def test_paste_spin_no_selection(self):
"Test pasting into a spinbox without a selection."
# See note above for entry.
spin = self.spin
end, ans = 0, 'onetwo'
spin.delete(0, 'end')
spin.insert(0, 'one')
spin.selection('range', 0, end) # see note
spin.event_generate('<<Paste>>')
self.assertEqual(spin.get(), ans)
def test_paste_spin_selection(self):
"Test pasting into a spinbox with a selection."
spin = self.spin
end, ans = 'end', 'two'
spin.delete(0, 'end')
spin.insert(0, 'one')
spin.selection('range', 0, end)
spin.event_generate('<<Paste>>')
self.assertEqual(spin.get(), ans)
if __name__ == '__main__':
unittest.main(verbosity=2)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment