From 5018db76aa433430e1bdb0826086df1c025a1f70 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Thu, 1 Nov 2012 22:39:14 +0200 Subject: [PATCH] Issue #1207589: Add Cut/Copy/Paste items to IDLE right click Context Menu Patch by Todd Rovito. --- Doc/library/idle.rst | 21 +++++++++++++++++++ Lib/idlelib/EditorWindow.py | 42 ++++++++++++++++++++++++++++++------- Lib/idlelib/OutputWindow.py | 6 +++++- Lib/idlelib/PyShell.py | 22 +++++++++++++++++-- Lib/idlelib/help.txt | 15 ++++++++++--- Misc/NEWS | 3 +++ 6 files changed, 96 insertions(+), 13 deletions(-) diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 5f28a99e21c..b40e4701536 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -183,6 +183,15 @@ Edit context menu * Right-click in Edit window (Control-click on OS X) +Cut + Copy selection into system-wide clipboard; then delete selection + +Copy + Copy selection into system-wide clipboard + +Paste + Insert system-wide clipboard into window + Set Breakpoint Sets a breakpoint. Breakpoints are only enabled when the debugger is open. @@ -190,6 +199,9 @@ Clear Breakpoint Clears the breakpoint on that line. .. index:: + single: Cut + single: Copy + single: Paste single: Set Breakpoint single: Clear Breakpoint single: breakpoints @@ -200,6 +212,15 @@ Shell context menu * Right-click in Python Shell window (Control-click on OS X) +Cut + Copy selection into system-wide clipboard; then delete selection + +Copy + Copy selection into system-wide clipboard + +Paste + Insert system-wide clipboard into window + Go to file/line Same as in Debug menu. diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py index 68b51e68683..241bd38ff9c 100644 --- a/Lib/idlelib/EditorWindow.py +++ b/Lib/idlelib/EditorWindow.py @@ -470,7 +470,6 @@ class EditorWindow(object): rmenu = None def right_menu_event(self, event): - self.text.tag_remove("sel", "1.0", "end") self.text.mark_set("insert", "@%d,%d" % (event.x, event.y)) if not self.rmenu: self.make_rmenu() @@ -479,23 +478,52 @@ class EditorWindow(object): iswin = sys.platform[:3] == 'win' if iswin: self.text.config(cursor="arrow") + + for label, eventname, verify_state in self.rmenu_specs: + if verify_state is None: + continue + state = getattr(self, verify_state)() + rmenu.entryconfigure(label, state=state) + rmenu.tk_popup(event.x_root, event.y_root) if iswin: self.text.config(cursor="ibeam") rmenu_specs = [ - # ("Label", "<>"), ... - ("Close", "<>"), # Example + # ("Label", "<>", "statefuncname"), ... + ("Close", "<>", None), # Example ] def make_rmenu(self): rmenu = Menu(self.text, tearoff=0) - for label, eventname in self.rmenu_specs: - def command(text=self.text, eventname=eventname): - text.event_generate(eventname) - rmenu.add_command(label=label, command=command) + for label, eventname, _ in self.rmenu_specs: + if label is not None: + def command(text=self.text, eventname=eventname): + text.event_generate(eventname) + rmenu.add_command(label=label, command=command) + else: + rmenu.add_separator() self.rmenu = rmenu + def rmenu_check_cut(self): + return self.rmenu_check_copy() + + def rmenu_check_copy(self): + try: + indx = self.text.index('sel.first') + except TclError: + return 'disabled' + else: + return 'normal' if indx else 'disabled' + + def rmenu_check_paste(self): + try: + self.text.tk.call('tk::GetSelection', self.text, 'CLIPBOARD') + except TclError: + return 'disabled' + else: + return 'normal' + def about_dialog(self, event=None): aboutDialog.AboutDialog(self.top,'About IDLE') diff --git a/Lib/idlelib/OutputWindow.py b/Lib/idlelib/OutputWindow.py index 60d09c0cac0..e18d846d8de 100644 --- a/Lib/idlelib/OutputWindow.py +++ b/Lib/idlelib/OutputWindow.py @@ -57,7 +57,11 @@ class OutputWindow(EditorWindow): # Our own right-button menu rmenu_specs = [ - ("Go to file/line", "<>"), + ("Cut", "<>", "rmenu_check_cut"), + ("Copy", "<>", "rmenu_check_copy"), + ("Paste", "<>", "rmenu_check_paste"), + (None, None, None), + ("Go to file/line", "<>", None), ] file_line_pats = [ diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py index d6f3ce3f64b..15ca392ca24 100644 --- a/Lib/idlelib/PyShell.py +++ b/Lib/idlelib/PyShell.py @@ -122,8 +122,13 @@ class PyShellEditorWindow(EditorWindow): old_hook() self.io.set_filename_change_hook(filename_changed_hook) - rmenu_specs = [("Set Breakpoint", "<>"), - ("Clear Breakpoint", "<>")] + rmenu_specs = [ + ("Cut", "<>", "rmenu_check_cut"), + ("Copy", "<>", "rmenu_check_copy"), + ("Paste", "<>", "rmenu_check_paste"), + ("Set Breakpoint", "<>", None), + ("Clear Breakpoint", "<>", None) + ] def set_breakpoint(self, lineno): text = self.text @@ -1261,6 +1266,19 @@ class PyShell(OutputWindow): if not use_subprocess: raise KeyboardInterrupt + def rmenu_check_cut(self): + try: + if self.text.compare('sel.first', '<', 'iomark'): + return 'disabled' + except TclError: # no selection, so the index 'sel.first' doesn't exist + return 'disabled' + return super(PyShell, self).rmenu_check_cut() + + def rmenu_check_paste(self): + if self.text.compare('insert', '<', 'iomark'): + return 'disabled' + return super(PyShell, self).rmenu_check_paste() + class PseudoFile(object): def __init__(self, shell, tags, encoding=None): diff --git a/Lib/idlelib/help.txt b/Lib/idlelib/help.txt index c179555f1ac..2ebf8bf02a5 100644 --- a/Lib/idlelib/help.txt +++ b/Lib/idlelib/help.txt @@ -120,14 +120,23 @@ Help Menu: --- (Additional Help Sources may be added here) -Edit context menu (Right-click / Control-click in Edit window): +Edit context menu (Right-click / Control-click on OS X in Edit window): + Cut -- Copy a selection into system-wide clipboard, + then delete the selection + Copy -- Copy selection into system-wide clipboard + Paste -- Insert system-wide clipboard into window Set Breakpoint -- Sets a breakpoint (when debugger open) Clear Breakpoint -- Clears the breakpoint on that line -Shell context menu (Right-click / Control-click in Shell window): +Shell context menu (Right-click / Control-click on OS X in Shell window): - Go to file/line -- Same as in Debug menu + Cut -- Copy a selection into system-wide clipboard, + then delete the selection + Copy -- Copy selection into system-wide clipboard + Paste -- Insert system-wide clipboard into window + --- + Go to file/line -- Same as in Debug menu ** TIPS ** diff --git a/Misc/NEWS b/Misc/NEWS index 139216f83b5..da211014ac3 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -130,6 +130,9 @@ Core and Builtins Library ------- +- Issue #1207589: Add Cut/Copy/Paste items to IDLE right click Context Menu + Patch by Todd Rovito. + - Issue #16230: Fix a crash in select.select() when one the lists changes size while iterated on. Patch by Serhiy Storchaka.