]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Issue #1207589: Add Cut/Copy/Paste items to IDLE right click Context Menu
authorAndrew Svetlov <andrew.svetlov@gmail.com>
Thu, 1 Nov 2012 20:41:19 +0000 (22:41 +0200)
committerAndrew Svetlov <andrew.svetlov@gmail.com>
Thu, 1 Nov 2012 20:41:19 +0000 (22:41 +0200)
 Patch by Todd Rovito.

Doc/library/idle.rst
Lib/idlelib/EditorWindow.py
Lib/idlelib/OutputWindow.py
Lib/idlelib/PyShell.py
Lib/idlelib/help.txt
Misc/NEWS

index 5f28a99e21c8e0ffa6dc3aac50b1e8b85ee54385..b40e470153616843fddd1409e0571a017ad36825 100644 (file)
@@ -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.
 
index bec2191f5ae073bbc80e9c1683d2024e196c66c4..ab62f917c9568d6bc606088b92e4c87cdbfa8153 100644 (file)
@@ -464,7 +464,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()
@@ -473,23 +472,53 @@ 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", "<<virtual-event>>"), ...
-        ("Close", "<<close-window>>"), # Example
+        # ("Label", "<<virtual-event>>", "statefuncname"), ...
+        ("Close", "<<close-window>>", 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')
 
index cba9013997660dc161521816ba01bbe5dceb9e46..745ccd26135653dfae936cfb786deaa36ed365fb 100644 (file)
@@ -52,7 +52,11 @@ class OutputWindow(EditorWindow):
     # Our own right-button menu
 
     rmenu_specs = [
-        ("Go to file/line", "<<goto-file-line>>"),
+        ("Cut", "<<cut>>", "rmenu_check_cut"),
+        ("Copy", "<<copy>>", "rmenu_check_copy"),
+        ("Paste", "<<paste>>", "rmenu_check_paste"),
+        (None, None, None),
+        ("Go to file/line", "<<goto-file-line>>", None),
     ]
 
     file_line_pats = [
index 88c0390ba59920e0886c597d30b6ede6e66e65cc..fb47b994d1f18d537406803186bdc7b98480b444 100644 (file)
@@ -117,8 +117,14 @@ class PyShellEditorWindow(EditorWindow):
             old_hook()
         self.io.set_filename_change_hook(filename_changed_hook)
 
-    rmenu_specs = [("Set Breakpoint", "<<set-breakpoint-here>>"),
-                   ("Clear Breakpoint", "<<clear-breakpoint-here>>")]
+    rmenu_specs = [
+        ("Cut", "<<cut>>", "rmenu_check_cut"),
+        ("Copy", "<<copy>>", "rmenu_check_copy"),
+        ("Paste", "<<paste>>", "rmenu_check_paste"),
+        (None, None, None),
+        ("Set Breakpoint", "<<set-breakpoint-here>>", None),
+        ("Clear Breakpoint", "<<clear-breakpoint-here>>", None)
+    ]
 
     def set_breakpoint(self, lineno):
         text = self.text
@@ -1240,6 +1246,19 @@ class PyShell(OutputWindow):
                 raise KeyboardInterrupt
         return count
 
+    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().rmenu_check_cut()
+
+    def rmenu_check_paste(self):
+        if self.text.compare('insert','<','iomark'):
+            return 'disabled'
+        return super().rmenu_check_paste()
+
 class PseudoFile(object):
 
     def __init__(self, shell, tags, encoding=None):
index c179555f1acc562235ff043eec0d297efd832983..815ee403da09f5e4efd5bf7185ac76b39e709329 100644 (file)
@@ -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 **
index 4708e3f35a4bc9629254be63325b94d7a3f4a6eb..307522523375d048e46b687a8f87d7ddfb9ce188 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -143,6 +143,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.