Changeset 391 for python/trunk/Lib/idlelib
- Timestamp:
- Mar 19, 2014, 11:31:01 PM (11 years ago)
- Location:
- python/trunk
- Files:
-
- 56 edited
- 17 copied
Legend:
- Unmodified
- Added
- Removed
-
python/trunk
-
Property svn:mergeinfo
set to
/python/vendor/Python-2.7.6 merged eligible /python/vendor/current merged eligible
-
Property svn:mergeinfo
set to
-
python/trunk/Lib/idlelib/AutoComplete.py
r2 r391 8 8 import string 9 9 10 from configHandler import idleConf 11 12 import AutoCompleteWindow 13 from HyperParser import HyperParser 14 15 import __main__ 10 from idlelib.configHandler import idleConf 16 11 17 12 # This string includes all chars that may be in a file name (without a path … … 23 18 # These constants represent the two different types of completions 24 19 COMPLETE_ATTRIBUTES, COMPLETE_FILES = range(1, 2+1) 20 21 from idlelib import AutoCompleteWindow 22 from idlelib.HyperParser import HyperParser 23 24 import __main__ 25 25 26 26 SEPS = os.sep … … 157 157 return 158 158 self.autocompletewindow = self._make_autocomplete_window() 159 self.autocompletewindow.show_window(comp_lists, 160 "insert-%dc" % len(comp_start), 161 complete, 162 mode, 163 userWantsWin) 164 return True 159 return not self.autocompletewindow.show_window( 160 comp_lists, "insert-%dc" % len(comp_start), 161 complete, mode, userWantsWin) 165 162 166 163 def fetch_completions(self, what, mode): … … 191 188 bigl.sort() 192 189 if "__all__" in bigl: 193 smalll = eval("__all__", namespace) 194 smalll.sort() 190 smalll = sorted(eval("__all__", namespace)) 195 191 else: 196 smalll = filter(lambda s: s[:1] != '_', bigl)192 smalll = [s for s in bigl if s[:1] != '_'] 197 193 else: 198 194 try: … … 201 197 bigl.sort() 202 198 if "__all__" in bigl: 203 smalll = entity.__all__ 204 smalll.sort() 199 smalll = sorted(entity.__all__) 205 200 else: 206 smalll = filter(lambda s: s[:1] != '_', bigl)201 smalll = [s for s in bigl if s[:1] != '_'] 207 202 except: 208 203 return [], [] … … 215 210 bigl = os.listdir(expandedpath) 216 211 bigl.sort() 217 smalll = filter(lambda s: s[:1] != '.', bigl)212 smalll = [s for s in bigl if s[:1] != '.'] 218 213 except OSError: 219 214 return [], [] -
python/trunk/Lib/idlelib/AutoCompleteWindow.py
r2 r391 3 3 """ 4 4 from Tkinter import * 5 from MultiCall import MC_SHIFT6 import AutoComplete 5 from idlelib.MultiCall import MC_SHIFT 6 from idlelib.AutoComplete import COMPLETE_FILES, COMPLETE_ATTRIBUTES 7 7 8 8 HIDE_VIRTUAL_EVENT_NAME = "<<autocompletewindow-hide>>" … … 158 158 if complete: 159 159 completed = self._complete_string(self.start) 160 start = self.start 160 161 self._change_start(completed) 161 162 i = self._binary_search(completed) … … 164 165 self.completions[i+1][:len(completed)] != completed): 165 166 # There is exactly one matching completion 166 return 167 return completed == start 167 168 self.userwantswindow = userWantsWin 168 169 self.lasttypedstart = self.start … … 265 266 self.lastkey_was_tab = False 266 267 if (len(keysym) == 1 or keysym in ("underscore", "BackSpace") 267 or (self.mode ==AutoComplete.COMPLETE_FILES and keysym in268 or (self.mode == COMPLETE_FILES and keysym in 268 269 ("period", "minus"))) \ 269 270 and not (state & ~MC_SHIFT): … … 293 294 return 294 295 295 elif (self.mode == AutoComplete.COMPLETE_ATTRIBUTES and keysym in296 elif (self.mode == COMPLETE_ATTRIBUTES and keysym in 296 297 ("period", "space", "parenleft", "parenright", "bracketleft", 297 298 "bracketright")) or \ 298 (self.mode == AutoComplete.COMPLETE_FILES and keysym in299 (self.mode == COMPLETE_FILES and keysym in 299 300 ("slash", "backslash", "quotedbl", "apostrophe")) \ 300 301 and not (state & ~MC_SHIFT): … … 304 305 cursel = int(self.listbox.curselection()[0]) 305 306 if self.completions[cursel][:len(self.start)] == self.start \ 306 and (self.mode ==AutoComplete.COMPLETE_ATTRIBUTES or self.start):307 and (self.mode == COMPLETE_ATTRIBUTES or self.start): 307 308 self._change_start(self.completions[cursel]) 308 309 self.hide_window() … … 350 351 return 351 352 352 elif reduce(lambda x, y: x or y, 353 [keysym.find(s) != -1 for s in ("Shift", "Control", "Alt", 354 "Meta", "Command", "Option") 355 ]): 353 elif any(s in keysym for s in ("Shift", "Control", "Alt", 354 "Meta", "Command", "Option")): 356 355 # A modifier key, so ignore 357 356 return -
python/trunk/Lib/idlelib/Bindings.py
r2 r391 10 10 """ 11 11 import sys 12 from configHandler import idleConf13 import macosxSupport12 from idlelib.configHandler import idleConf 13 from idlelib import macosxSupport 14 14 15 15 menudefs = [ 16 16 # underscore prefixes character to underscore 17 17 ('file', [ 18 ('_New Window', '<<open-new-window>>'),18 ('_New File', '<<open-new-window>>'), 19 19 ('_Open...', '<<open-window-from-file>>'), 20 20 ('Open _Module...', '<<open-module>>'), … … 99 99 del menudefs[-1][1][0:2] 100 100 101 menudefs.insert(0, 102 ('application', [ 103 ('About IDLE', '<<about-idle>>'), 104 None, 105 ('_Preferences....', '<<open-config-dialog>>'), 106 ])) 107 101 # Remove the 'Configure' entry from the options menu, it is in the 102 # application menu as 'Preferences' 103 del menudefs[-2][1][0:2] 108 104 109 105 default_keydefs = idleConf.GetCurrentKeySet() -
python/trunk/Lib/idlelib/CREDITS.txt
r2 r391 26 26 Scott David Daniels, Tal Einat, Hernan Foffani, Christos Georgiou, 27 27 Jim Jewett, Martin v. Löwis, Jason Orendorff, Guilherme Polo, Josh Robb, 28 Nigel Rowe, Bruce Sherwood, and Jeff Shute have submitted useful patches.29 Thanks, guys!28 Nigel Rowe, Bruce Sherwood, Jeff Shute, and Weeble have submitted useful 29 patches. Thanks, guys! 30 30 31 31 For additional details refer to NEWS.txt and Changelog. -
python/trunk/Lib/idlelib/CallTipWindow.py
r2 r391 23 23 self.lastline = None 24 24 self.hideid = self.checkhideid = None 25 self.checkhide_after_id = None 25 26 26 27 def position_window(self): … … 103 104 else: 104 105 self.position_window() 105 self.widget.after(CHECKHIDE_TIME, self.checkhide_event) 106 if self.checkhide_after_id is not None: 107 self.widget.after_cancel(self.checkhide_after_id) 108 self.checkhide_after_id = \ 109 self.widget.after(CHECKHIDE_TIME, self.checkhide_event) 106 110 107 111 def hide_event(self, event): -
python/trunk/Lib/idlelib/CallTips.py
r2 r391 10 10 import types 11 11 12 import CallTipWindow13 from HyperParser import HyperParser12 from idlelib import CallTipWindow 13 from idlelib.HyperParser import HyperParser 14 14 15 15 import __main__ … … 72 72 return 73 73 hp.set_index(sur_paren[0]) 74 name= hp.get_expression()75 if not name or (not evalfuncs and name.find('(') != -1):76 return 77 arg_text = self.fetch_tip( name)74 expression = hp.get_expression() 75 if not expression or (not evalfuncs and expression.find('(') != -1): 76 return 77 arg_text = self.fetch_tip(expression) 78 78 if not arg_text: 79 79 return … … 81 81 self.calltip.showtip(arg_text, sur_paren[0], sur_paren[1]) 82 82 83 def fetch_tip(self, name):83 def fetch_tip(self, expression): 84 84 """Return the argument list and docstring of a function or class 85 85 … … 97 97 try: 98 98 rpcclt = self.editwin.flist.pyshell.interp.rpcclt 99 except :99 except AttributeError: 100 100 rpcclt = None 101 101 if rpcclt: 102 102 return rpcclt.remotecall("exec", "get_the_calltip", 103 ( name,), {})103 (expression,), {}) 104 104 else: 105 entity = self.get_entity( name)105 entity = self.get_entity(expression) 106 106 return get_arg_text(entity) 107 107 108 def get_entity(self, name): 109 "Lookup name in a namespace spanning sys.modules and __main.dict__" 110 if name: 108 def get_entity(self, expression): 109 """Return the object corresponding to expression evaluated 110 in a namespace spanning sys.modules and __main.dict__. 111 """ 112 if expression: 111 113 namespace = sys.modules.copy() 112 114 namespace.update(__main__.__dict__) 113 115 try: 114 return eval(name, namespace) 115 except (NameError, AttributeError): 116 return eval(expression, namespace) 117 except BaseException: 118 # An uncaught exception closes idle, and eval can raise any 119 # exception, especially if user classes are involved. 116 120 return None 117 121 … … 128 132 129 133 def get_arg_text(ob): 130 """Get a string describing the arguments for the given object""" 134 """Get a string describing the arguments for the given object, 135 only if it is callable.""" 131 136 arg_text = "" 132 if ob is not None :137 if ob is not None and hasattr(ob, '__call__'): 133 138 arg_offset = 0 134 139 if type(ob) in (types.ClassType, types.TypeType): … … 159 164 items.append("***") 160 165 arg_text = ", ".join(items) 161 arg_text = "(%s)" % re.sub(" \.\d+", "<tuple>", arg_text)166 arg_text = "(%s)" % re.sub("(?<!\d)\.\d+", "<tuple>", arg_text) 162 167 # See if we can use the docstring 163 168 doc = getattr(ob, "__doc__", "") … … 219 224 TC, tc.t1, tc.t2, tc.t3, tc.t4, tc.t5, tc.t6, tc.t7) 220 225 221 test(tests) 226 # test(tests) 227 from unittest import main 228 main('idlelib.idle_test.test_calltips', verbosity=2, exit=False) -
python/trunk/Lib/idlelib/ClassBrowser.py
r2 r391 15 15 import pyclbr 16 16 17 import PyShell18 from WindowList import ListedToplevel19 from TreeWidget import TreeNode, TreeItem, ScrolledCanvas20 from configHandler import idleConf17 from idlelib import PyShell 18 from idlelib.WindowList import ListedToplevel 19 from idlelib.TreeWidget import TreeNode, TreeItem, ScrolledCanvas 20 from idlelib.configHandler import idleConf 21 21 22 22 class ClassBrowser: -
python/trunk/Lib/idlelib/CodeContext.py
r2 r391 12 12 import Tkinter 13 13 from Tkconstants import TOP, LEFT, X, W, SUNKEN 14 from configHandler import idleConf15 14 import re 16 15 from sys import maxint as INFINITY 16 from idlelib.configHandler import idleConf 17 17 18 18 BLOCKOPENERS = set(["class", "def", "elif", "else", "except", "finally", "for", -
python/trunk/Lib/idlelib/ColorDelegator.py
r2 r391 4 4 import __builtin__ 5 5 from Tkinter import * 6 from Delegator import Delegator7 from configHandler import idleConf6 from idlelib.Delegator import Delegator 7 from idlelib.configHandler import idleConf 8 8 9 9 DEBUG = False … … 21 21 builtin = r"([^.'\"\\#]\b|^)" + any("BUILTIN", builtinlist) + r"\b" 22 22 comment = any("COMMENT", [r"#[^\n]*"]) 23 sqstring = r"(\b[rRuU])?'[^'\\\n]*(\\.[^'\\\n]*)*'?" 24 dqstring = r'(\b[rRuU])?"[^"\\\n]*(\\.[^"\\\n]*)*"?' 25 sq3string = r"(\b[rRuU])?'''[^'\\]*((\\.|'(?!''))[^'\\]*)*(''')?" 26 dq3string = r'(\b[rRuU])?"""[^"\\]*((\\.|"(?!""))[^"\\]*)*(""")?' 23 stringprefix = r"(\br|u|ur|R|U|UR|Ur|uR|b|B|br|Br|bR|BR)?" 24 sqstring = stringprefix + r"'[^'\\\n]*(\\.[^'\\\n]*)*'?" 25 dqstring = stringprefix + r'"[^"\\\n]*(\\.[^"\\\n]*)*"?' 26 sq3string = stringprefix + r"'''[^'\\]*((\\.|'(?!''))[^'\\]*)*(''')?" 27 dq3string = stringprefix + r'"""[^"\\]*((\\.|"(?!""))[^"\\]*)*(""")?' 27 28 string = any("STRING", [sq3string, dq3string, sqstring, dqstring]) 28 29 return kw + "|" + builtin + "|" + comment + "|" + string +\ … … 50 51 self.bind("<<toggle-auto-coloring>>", self.toggle_colorize_event) 51 52 self.notify_range("1.0", "end") 53 else: 54 # No delegate - stop any colorizing 55 self.stop_colorizing = True 56 self.allow_colorizing = False 52 57 53 58 def config_colors(self): … … 249 254 250 255 def main(): 251 from Percolator import Percolator256 from idlelib.Percolator import Percolator 252 257 root = Tk() 253 258 root.wm_protocol("WM_DELETE_WINDOW", root.quit) -
python/trunk/Lib/idlelib/Debugger.py
r2 r391 3 3 import types 4 4 from Tkinter import * 5 from WindowList import ListedToplevel6 from ScrolledList import ScrolledList7 import macosxSupport5 from idlelib.WindowList import ListedToplevel 6 from idlelib.ScrolledList import ScrolledList 7 from idlelib import macosxSupport 8 8 9 9 -
python/trunk/Lib/idlelib/Delegator.py
r2 r391 5 5 def __init__(self, delegate=None): 6 6 self.delegate = delegate 7 self.__cache = {}7 self.__cache = set() 8 8 9 9 def __getattr__(self, name): 10 10 attr = getattr(self.delegate, name) # May raise AttributeError 11 11 setattr(self, name, attr) 12 self.__cache [name] = attr12 self.__cache.add(name) 13 13 return attr 14 14 15 15 def resetcache(self): 16 for key in self.__cache .keys():16 for key in self.__cache: 17 17 try: 18 18 delattr(self, key) … … 21 21 self.__cache.clear() 22 22 23 def cachereport(self):24 keys = self.__cache.keys()25 keys.sort()26 print keys27 28 23 def setdelegate(self, delegate): 29 24 self.resetcache() 30 25 self.delegate = delegate 31 32 def getdelegate(self):33 return self.delegate -
python/trunk/Lib/idlelib/EditorWindow.py
r2 r391 3 3 import re 4 4 import imp 5 from itertools import count6 5 from Tkinter import * 7 6 import tkSimpleDialog 8 7 import tkMessageBox 9 from MultiCall import MultiCallCreator10 11 8 import webbrowser 12 import idlever 13 import WindowList 14 import SearchDialog 15 import GrepDialog 16 import ReplaceDialog 17 import PyParse 18 from configHandler import idleConf 19 import aboutDialog, textView, configDialog 20 import macosxSupport 9 10 from idlelib.MultiCall import MultiCallCreator 11 from idlelib import idlever 12 from idlelib import WindowList 13 from idlelib import SearchDialog 14 from idlelib import GrepDialog 15 from idlelib import ReplaceDialog 16 from idlelib import PyParse 17 from idlelib.configHandler import idleConf 18 from idlelib import aboutDialog, textView, configDialog 19 from idlelib import macosxSupport 21 20 22 21 # The default tab setting for a Text widget, in average-width characters. … … 28 27 release = '%s%s' % (major, minor) 29 28 if micro: 30 release += '%s' % micro 31 if level != 'final': 29 release += '%s' % (micro,) 30 if level == 'candidate': 31 release += 'rc%s' % (serial,) 32 elif level != 'final': 32 33 release += '%s%s' % (level[0], serial) 33 34 return release … … 48 49 except AttributeError: 49 50 raise ImportError, 'No source for module ' + module.__name__ 51 if descr[2] != imp.PY_SOURCE: 52 # If all of the above fails and didn't raise an exception,fallback 53 # to a straight import which can find __init__.py in a package. 54 m = __import__(fullname) 55 try: 56 filename = m.__file__ 57 except AttributeError: 58 pass 59 else: 60 file = None 61 base, ext = os.path.splitext(filename) 62 if ext == '.pyc': 63 ext = '.py' 64 filename = base + ext 65 descr = filename, None, imp.PY_SOURCE 50 66 return file, filename, descr 51 67 68 69 class HelpDialog(object): 70 71 def __init__(self): 72 self.parent = None # parent of help window 73 self.dlg = None # the help window iteself 74 75 def display(self, parent, near=None): 76 """ Display the help dialog. 77 78 parent - parent widget for the help window 79 80 near - a Toplevel widget (e.g. EditorWindow or PyShell) 81 to use as a reference for placing the help window 82 """ 83 if self.dlg is None: 84 self.show_dialog(parent) 85 if near: 86 self.nearwindow(near) 87 88 def show_dialog(self, parent): 89 self.parent = parent 90 fn=os.path.join(os.path.abspath(os.path.dirname(__file__)),'help.txt') 91 self.dlg = dlg = textView.view_file(parent,'Help',fn, modal=False) 92 dlg.bind('<Destroy>', self.destroy, '+') 93 94 def nearwindow(self, near): 95 # Place the help dialog near the window specified by parent. 96 # Note - this may not reposition the window in Metacity 97 # if "/apps/metacity/general/disable_workarounds" is enabled 98 dlg = self.dlg 99 geom = (near.winfo_rootx() + 10, near.winfo_rooty() + 10) 100 dlg.withdraw() 101 dlg.geometry("=+%d+%d" % geom) 102 dlg.deiconify() 103 dlg.lift() 104 105 def destroy(self, ev=None): 106 self.dlg = None 107 self.parent = None 108 109 helpDialog = HelpDialog() # singleton instance 110 111 52 112 class EditorWindow(object): 53 from Percolator import Percolator54 from ColorDelegator import ColorDelegator55 from UndoDelegator import UndoDelegator56 from IOBinding import IOBinding, filesystemencoding, encoding57 import Bindings113 from idlelib.Percolator import Percolator 114 from idlelib.ColorDelegator import ColorDelegator 115 from idlelib.UndoDelegator import UndoDelegator 116 from idlelib.IOBinding import IOBinding, filesystemencoding, encoding 117 from idlelib import Bindings 58 118 from Tkinter import Toplevel 59 from MultiStatusBar import MultiStatusBar119 from idlelib.MultiStatusBar import MultiStatusBar 60 120 61 121 help_url = None … … 102 162 if flist: 103 163 self.tkinter_vars = flist.vars 104 #self.top.instance_dict makes flist.inversedict ava lable to105 #configDialog.py so it can access all EditorWindow insta ces164 #self.top.instance_dict makes flist.inversedict available to 165 #configDialog.py so it can access all EditorWindow instances 106 166 self.top.instance_dict = flist.inversedict 107 167 else: … … 113 173 self.text_frame = text_frame = Frame(top) 114 174 self.vbar = vbar = Scrollbar(text_frame, name='vbar') 115 self.width = idleConf.GetOption('main','EditorWindow','width' )175 self.width = idleConf.GetOption('main','EditorWindow','width', type='int') 116 176 text_options = { 117 177 'name': 'text', … … 119 179 'wrap': 'none', 120 180 'width': self.width, 121 'height': idleConf.GetOption('main', 'EditorWindow', 'height' )}181 'height': idleConf.GetOption('main', 'EditorWindow', 'height', type='int')} 122 182 if TkVersion >= 8.5: 123 183 # Starting with tk 8.5 we have to set the new tabstyle option … … 136 196 # Command-W on editorwindows doesn't work without this. 137 197 text.bind('<<close-window>>', self.close_event) 198 # Some OS X systems have only one mouse button, 199 # so use control-click for pulldown menus there. 200 # (Note, AquaTk defines <2> as the right button if 201 # present and the Tk Text widget already binds <2>.) 202 text.bind("<Control-Button-1>",self.right_menu_event) 203 else: 204 # Elsewhere, use right-click for pulldown menus. 205 text.bind("<3>",self.right_menu_event) 138 206 text.bind("<<cut>>", self.cut) 139 207 text.bind("<<copy>>", self.copy) … … 154 222 text.bind("<<replace>>", self.replace_event) 155 223 text.bind("<<goto-line>>", self.goto_line_event) 156 text.bind("<3>", self.right_menu_event)157 224 text.bind("<<smart-backspace>>",self.smart_backspace_event) 158 225 text.bind("<<newline-and-indent>>",self.newline_and_indent_event) … … 189 256 fontWeight='bold' 190 257 text.config(font=(idleConf.GetOption('main', 'EditorWindow', 'font'), 191 idleConf.GetOption('main', 'EditorWindow', 'font-size'), 258 idleConf.GetOption('main', 'EditorWindow', 259 'font-size', type='int'), 192 260 fontWeight)) 193 261 text_frame.pack(side=LEFT, fill=BOTH, expand=1) … … 279 347 self.showerror = tkMessageBox.showerror 280 348 349 self._highlight_workaround() # Fix selection tags on Windows 350 351 def _highlight_workaround(self): 352 # On Windows, Tk removes painting of the selection 353 # tags which is different behavior than on Linux and Mac. 354 # See issue14146 for more information. 355 if not sys.platform.startswith('win'): 356 return 357 358 text = self.text 359 text.event_add("<<Highlight-FocusOut>>", "<FocusOut>") 360 text.event_add("<<Highlight-FocusIn>>", "<FocusIn>") 361 def highlight_fix(focus): 362 sel_range = text.tag_ranges("sel") 363 if sel_range: 364 if focus == 'out': 365 HILITE_CONFIG = idleConf.GetHighlight( 366 idleConf.CurrentTheme(), 'hilite') 367 text.tag_config("sel_fix", HILITE_CONFIG) 368 text.tag_raise("sel_fix") 369 text.tag_add("sel_fix", *sel_range) 370 elif focus == 'in': 371 text.tag_remove("sel_fix", "1.0", "end") 372 373 text.bind("<<Highlight-FocusOut>>", 374 lambda ev: highlight_fix("out")) 375 text.bind("<<Highlight-FocusIn>>", 376 lambda ev: highlight_fix("in")) 377 378 281 379 def _filename_to_unicode(self, filename): 282 380 """convert filename to unicode in order to display it in Tk""" … … 300 398 301 399 def home_callback(self, event): 302 if (event.state & 12) != 0 and event.keysym == "Home": 303 # state&1==shift, state&4==control, state&8==alt 304 return # <Modifier-Home>; fall back to class binding 305 400 if (event.state & 4) != 0 and event.keysym == "Home": 401 # state&4==Control. If <Control-Home>, use the Tk binding. 402 return 306 403 if self.text.index("iomark") and \ 307 404 self.text.compare("iomark", "<=", "insert lineend") and \ 308 405 self.text.compare("insert linestart", "<=", "iomark"): 406 # In Shell on input line, go to just after prompt 309 407 insertpt = int(self.text.index("iomark").split(".")[1]) 310 408 else: … … 315 413 else: 316 414 insertpt=len(line) 317 318 415 lineat = int(self.text.index("insert").split('.')[1]) 319 320 416 if insertpt == lineat: 321 417 insertpt = 0 322 323 418 dest = "insert linestart+"+str(insertpt)+"c" 324 325 419 if (event.state&1) == 0: 326 # shift not pressed420 # shift was not pressed 327 421 self.text.tag_remove("sel", "1.0", "end") 328 422 else: 329 423 if not self.text.index("sel.first"): 330 self.text.mark_set("anchor","insert") 331 424 self.text.mark_set("my_anchor", "insert") # there was no previous selection 425 else: 426 if self.text.compare(self.text.index("sel.first"), "<", self.text.index("insert")): 427 self.text.mark_set("my_anchor", "sel.first") # extend back 428 else: 429 self.text.mark_set("my_anchor", "sel.last") # extend forward 332 430 first = self.text.index(dest) 333 last = self.text.index("anchor") 334 431 last = self.text.index("my_anchor") 335 432 if self.text.compare(first,">",last): 336 433 first,last = last,first 337 338 434 self.text.tag_remove("sel", "1.0", "end") 339 435 self.text.tag_add("sel", first, last) 340 341 436 self.text.mark_set("insert", dest) 342 437 self.text.see("insert") … … 373 468 374 469 if macosxSupport.runningAsOSXApp(): 375 del menu_specs[-3]376 470 menu_specs[-2] = ("windows", "_Window") 377 471 … … 385 479 mbar.add_cascade(label=label, menu=menu, underline=underline) 386 480 387 if macosxSupport. runningAsOSXApp():481 if macosxSupport.isCarbonAquaTk(self.root): 388 482 # Insert the application menu 389 483 menudict['application'] = menu = Menu(mbar, name='apple') … … 407 501 408 502 def right_menu_event(self, event): 409 self.text.tag_remove("sel", "1.0", "end")410 503 self.text.mark_set("insert", "@%d,%d" % (event.x, event.y)) 411 504 if not self.rmenu: … … 416 509 if iswin: 417 510 self.text.config(cursor="arrow") 511 512 for item in self.rmenu_specs: 513 try: 514 label, eventname, verify_state = item 515 except ValueError: # see issue1207589 516 continue 517 518 if verify_state is None: 519 continue 520 state = getattr(self, verify_state)() 521 rmenu.entryconfigure(label, state=state) 522 418 523 rmenu.tk_popup(event.x_root, event.y_root) 419 524 if iswin: … … 421 526 422 527 rmenu_specs = [ 423 # ("Label", "<<virtual-event>>" ), ...424 ("Close", "<<close-window>>" ), # Example528 # ("Label", "<<virtual-event>>", "statefuncname"), ... 529 ("Close", "<<close-window>>", None), # Example 425 530 ] 426 531 427 532 def make_rmenu(self): 428 533 rmenu = Menu(self.text, tearoff=0) 429 for label, eventname in self.rmenu_specs: 430 def command(text=self.text, eventname=eventname): 431 text.event_generate(eventname) 432 rmenu.add_command(label=label, command=command) 534 for item in self.rmenu_specs: 535 label, eventname = item[0], item[1] 536 if label is not None: 537 def command(text=self.text, eventname=eventname): 538 text.event_generate(eventname) 539 rmenu.add_command(label=label, command=command) 540 else: 541 rmenu.add_separator() 433 542 self.rmenu = rmenu 543 544 def rmenu_check_cut(self): 545 return self.rmenu_check_copy() 546 547 def rmenu_check_copy(self): 548 try: 549 indx = self.text.index('sel.first') 550 except TclError: 551 return 'disabled' 552 else: 553 return 'normal' if indx else 'disabled' 554 555 def rmenu_check_paste(self): 556 try: 557 self.text.tk.call('tk::GetSelection', self.text, 'CLIPBOARD') 558 except TclError: 559 return 'disabled' 560 else: 561 return 'normal' 434 562 435 563 def about_dialog(self, event=None): … … 440 568 441 569 def help_dialog(self, event=None): 442 fn=os.path.join(os.path.abspath(os.path.dirname(__file__)),'help.txt') 443 textView.view_file(self.top,'Help',fn) 570 if self.root: 571 parent = self.root 572 else: 573 parent = self.top 574 helpDialog.display(parent, near=self.top) 444 575 445 576 def python_docs(self, event=None): 446 577 if sys.platform[:3] == 'win': 447 os.startfile(self.help_url) 578 try: 579 os.startfile(self.help_url) 580 except WindowsError as why: 581 tkMessageBox.showerror(title='Document Start Failure', 582 message=str(why), parent=self.text) 448 583 else: 449 584 webbrowser.open(self.help_url) … … 555 690 try: 556 691 (f, file, (suffix, mode, type)) = _find_module(name) 557 except (NameError, ImportError) ,msg:692 except (NameError, ImportError) as msg: 558 693 tkMessageBox.showerror("Import error", str(msg), parent=self.text) 559 694 return … … 580 715 head, tail = os.path.split(filename) 581 716 base, ext = os.path.splitext(tail) 582 import ClassBrowser717 from idlelib import ClassBrowser 583 718 ClassBrowser.ClassBrowser(self.flist, base, [head]) 584 719 585 720 def open_path_browser(self, event=None): 586 import PathBrowser721 from idlelib import PathBrowser 587 722 PathBrowser.PathBrowser(self.flist) 588 723 … … 665 800 fontWeight='bold' 666 801 self.text.config(font=(idleConf.GetOption('main','EditorWindow','font'), 667 idleConf.GetOption('main','EditorWindow','font-size'), 802 idleConf.GetOption('main','EditorWindow','font-size', 803 type='int'), 668 804 fontWeight)) 669 805 … … 698 834 for menubarItem in self.menudict.keys(): 699 835 menu = self.menudict[menubarItem] 700 end = menu.index(END) + 1 836 end = menu.index(END) 837 if end is None: 838 # Skip empty menus 839 continue 840 end += 1 701 841 for index in range(0, end): 702 842 if menu.type(index) == 'command': … … 705 845 itemName = menu.entrycget(index, 'label') 706 846 event = '' 707 if menu EventDict.has_key(menubarItem):708 if menuEventDict[menubarItem].has_key(itemName):847 if menubarItem in menuEventDict: 848 if itemName in menuEventDict[menubarItem]: 709 849 event = menuEventDict[menubarItem][itemName] 710 850 if event: … … 740 880 def display_extra_help(helpfile=helpfile): 741 881 if not helpfile.startswith(('www', 'http')): 742 url= os.path.normpath(helpfile)882 helpfile = os.path.normpath(helpfile) 743 883 if sys.platform[:3] == 'win': 744 os.startfile(helpfile) 884 try: 885 os.startfile(helpfile) 886 except WindowsError as why: 887 tkMessageBox.showerror(title='Document Start Failure', 888 message=str(why), parent=self.text) 745 889 else: 746 890 webbrowser.open(helpfile) … … 751 895 rf_list = [] 752 896 if os.path.exists(self.recent_files_path): 753 rf_list_file = open(self.recent_files_path,'r') 754 try: 897 with open(self.recent_files_path, 'r') as rf_list_file: 755 898 rf_list = rf_list_file.readlines() 756 finally:757 rf_list_file.close()758 899 if new_file: 759 900 new_file = os.path.abspath(new_file) + '\n' … … 769 910 ulchars = "1234567890ABCDEFGHIJK" 770 911 rf_list = rf_list[0:len(ulchars)] 771 rf_file = open(self.recent_files_path, 'w')772 912 try: 773 rf_file.writelines(rf_list) 774 finally: 775 rf_file.close() 913 with open(self.recent_files_path, 'w') as rf_file: 914 rf_file.writelines(rf_list) 915 except IOError as err: 916 if not getattr(self.root, "recentfilelist_error_displayed", False): 917 self.root.recentfilelist_error_displayed = True 918 tkMessageBox.showerror(title='IDLE Error', 919 message='Unable to update Recent Files list:\n%s' 920 % str(err), 921 parent=self.text) 776 922 # for each edit window instance, construct the recent files menu 777 923 for instance in self.top.instance_dict.keys(): 778 924 menu = instance.recent_files_menu 779 menu.delete( 1, END) # clear, and rebuild:780 for i, file in zip(count(),rf_list):781 file_name = file [0:-1]# zap \n925 menu.delete(0, END) # clear, and rebuild: 926 for i, file_name in enumerate(rf_list): 927 file_name = file_name.rstrip() # zap \n 782 928 # make unicode string to display non-ASCII chars correctly 783 929 ufile_name = self._filename_to_unicode(file_name) … … 1103 1249 want = ((have - 1) // self.indentwidth) * self.indentwidth 1104 1250 # Debug prompt is multilined.... 1105 last_line_of_prompt = sys.ps1.split('\n')[-1] 1251 if self.context_use_ps1: 1252 last_line_of_prompt = sys.ps1.split('\n')[-1] 1253 else: 1254 last_line_of_prompt = '' 1106 1255 ncharsdeleted = 0 1107 1256 while 1: … … 1194 1343 for context in self.num_context_lines: 1195 1344 startat = max(lno - context, 1) 1196 startatindex = `startat`+ ".0"1345 startatindex = repr(startat) + ".0" 1197 1346 rawtext = text.get(startatindex, "insert") 1198 1347 y.set_str(rawtext) … … 1313 1462 head, tail, chars, lines = self.get_region() 1314 1463 tabwidth = self._asktabwidth() 1464 if tabwidth is None: return 1315 1465 for pos in range(len(lines)): 1316 1466 line = lines[pos] … … 1324 1474 head, tail, chars, lines = self.get_region() 1325 1475 tabwidth = self._asktabwidth() 1476 if tabwidth is None: return 1326 1477 for pos in range(len(lines)): 1327 1478 lines[pos] = lines[pos].expandtabs(tabwidth) … … 1417 1568 initialvalue=self.indentwidth, 1418 1569 minvalue=2, 1419 maxvalue=16) or self.tabwidth1570 maxvalue=16) 1420 1571 1421 1572 # Guess indentwidth from text content. … … 1499 1650 try: 1500 1651 _tokenize.tokenize(self.readline, self.tokeneater) 1501 except _tokenize.TokenError:1652 except (_tokenize.TokenError, SyntaxError): 1502 1653 # since we cut off the tokenizer early, we can trigger 1503 1654 # spurious errors … … 1526 1677 def get_accelerator(keydefs, eventname): 1527 1678 keylist = keydefs.get(eventname) 1528 if not keylist: 1679 # issue10940: temporary workaround to prevent hang with OS X Cocoa Tk 8.5 1680 # if not keylist: 1681 if (not keylist) or (macosxSupport.runningAsOSXApp() and eventname in { 1682 "<<open-module>>", 1683 "<<goto-line>>", 1684 "<<change-indentwidth>>"}): 1529 1685 return "" 1530 1686 s = keylist[0] -
python/trunk/Lib/idlelib/FileList.py
r2 r391 6 6 class FileList: 7 7 8 from EditorWindow import EditorWindow # class variable, may be overridden9 # e.g. by PyShellFileList8 # N.B. this import overridden in PyShellFileList. 9 from idlelib.EditorWindow import EditorWindow 10 10 11 11 def __init__(self, root): … … 26 26 return None 27 27 key = os.path.normcase(filename) 28 if self.dict.has_key(key):28 if key in self.dict: 29 29 edit = self.dict[key] 30 30 edit.top.wakeup() … … 44 44 return self.EditorWindow(self, filename) 45 45 46 def close_all_callback(self, event):46 def close_all_callback(self, *args, **kwds): 47 47 for edit in self.inversedict.keys(): 48 48 reply = edit.close() … … 80 80 if newkey == key: 81 81 return 82 if self.dict.has_key(newkey):82 if newkey in self.dict: 83 83 conflict = self.dict[newkey] 84 84 self.inversedict[conflict] = None … … 107 107 108 108 def _test(): 109 from EditorWindow import fixwordbreaks109 from idlelib.EditorWindow import fixwordbreaks 110 110 import sys 111 111 root = Tk() -
python/trunk/Lib/idlelib/FormatParagraph.py
r2 r391 1 # Extension to format a paragraph 1 """Extension to format a paragraph or selection to a max width. 2 2 3 #Does basic, standard text formatting, and also understands Python4 # comment blocks.Thus, for editing Python source code, this5 #extension is really only suitable for reformatting these comment6 #blocks or triple-quoted strings.3 Does basic, standard text formatting, and also understands Python 4 comment blocks. Thus, for editing Python source code, this 5 extension is really only suitable for reformatting these comment 6 blocks or triple-quoted strings. 7 7 8 # Known problems with comment reformatting: 9 # * If there is a selection marked, and the first line of the 10 # selection is not complete, the block will probably not be detected 11 # as comments, and will have the normal "text formatting" rules 12 # applied. 13 # * If a comment block has leading whitespace that mixes tabs and 14 # spaces, they will not be considered part of the same block. 15 # * Fancy comments, like this bulleted list, arent handled :-) 8 Known problems with comment reformatting: 9 * If there is a selection marked, and the first line of the 10 selection is not complete, the block will probably not be detected 11 as comments, and will have the normal "text formatting" rules 12 applied. 13 * If a comment block has leading whitespace that mixes tabs and 14 spaces, they will not be considered part of the same block. 15 * Fancy comments, like this bulleted list, aren't handled :-) 16 """ 16 17 17 18 import re 18 from configHandler import idleConf19 from idlelib.configHandler import idleConf 19 20 20 21 class FormatParagraph: … … 33 34 34 35 def format_paragraph_event(self, event): 35 maxformatwidth = int(idleConf.GetOption('main','FormatParagraph','paragraph')) 36 """Formats paragraph to a max width specified in idleConf. 37 38 If text is selected, format_paragraph_event will start breaking lines 39 at the max width, starting from the beginning selection. 40 41 If no text is selected, format_paragraph_event uses the current 42 cursor location to determine the paragraph (lines of text surrounded 43 by blank lines) and formats it. 44 """ 45 maxformatwidth = idleConf.GetOption( 46 'main', 'FormatParagraph', 'paragraph', type='int') 36 47 text = self.editwin.text 37 48 first, last = self.editwin.get_selection_indices() 38 49 if first and last: 39 50 data = text.get(first, last) 40 comment_header = ''51 comment_header = get_comment_header(data) 41 52 else: 42 53 first, last, comment_header, data = \ 43 54 find_paragraph(text, text.index("insert")) 44 55 if comment_header: 45 # Reformat the comment lines - convert to text sans header. 46 lines = data.split("\n") 47 lines = map(lambda st, l=len(comment_header): st[l:], lines) 48 data = "\n".join(lines) 49 # Reformat to maxformatwidth chars or a 20 char width, whichever is greater. 50 format_width = max(maxformatwidth - len(comment_header), 20) 51 newdata = reformat_paragraph(data, format_width) 52 # re-split and re-insert the comment header. 53 newdata = newdata.split("\n") 54 # If the block ends in a \n, we dont want the comment 55 # prefix inserted after it. (Im not sure it makes sense to 56 # reformat a comment block that isnt made of complete 57 # lines, but whatever!) Can't think of a clean soltution, 58 # so we hack away 59 block_suffix = "" 60 if not newdata[-1]: 61 block_suffix = "\n" 62 newdata = newdata[:-1] 63 builder = lambda item, prefix=comment_header: prefix+item 64 newdata = '\n'.join(map(builder, newdata)) + block_suffix 56 newdata = reformat_comment(data, maxformatwidth, comment_header) 65 57 else: 66 # Just a normal text format67 58 newdata = reformat_paragraph(data, maxformatwidth) 68 59 text.tag_remove("sel", "1.0", "end") 60 69 61 if newdata != data: 70 62 text.mark_set("insert", first) … … 79 71 80 72 def find_paragraph(text, mark): 73 """Returns the start/stop indices enclosing the paragraph that mark is in. 74 75 Also returns the comment format string, if any, and paragraph of text 76 between the start/stop indices. 77 """ 81 78 lineno, col = map(int, mark.split(".")) 82 line = text.get("%d.0" % lineno, "%d.0 lineend" % lineno) 79 line = text.get("%d.0" % lineno, "%d.end" % lineno) 80 81 # Look for start of next paragraph if the index passed in is a blank line 83 82 while text.compare("%d.0" % lineno, "<", "end") and is_all_white(line): 84 83 lineno = lineno + 1 85 line = text.get("%d.0" % lineno, "%d. 0 lineend" % lineno)84 line = text.get("%d.0" % lineno, "%d.end" % lineno) 86 85 first_lineno = lineno 87 86 comment_header = get_comment_header(line) 88 87 comment_header_len = len(comment_header) 88 89 # Once start line found, search for end of paragraph (a blank line) 89 90 while get_comment_header(line)==comment_header and \ 90 91 not is_all_white(line[comment_header_len:]): 91 92 lineno = lineno + 1 92 line = text.get("%d.0" % lineno, "%d. 0 lineend" % lineno)93 line = text.get("%d.0" % lineno, "%d.end" % lineno) 93 94 last = "%d.0" % lineno 94 # Search back to beginning of paragraph 95 96 # Search back to beginning of paragraph (first blank line before) 95 97 lineno = first_lineno - 1 96 line = text.get("%d.0" % lineno, "%d. 0 lineend" % lineno)98 line = text.get("%d.0" % lineno, "%d.end" % lineno) 97 99 while lineno > 0 and \ 98 100 get_comment_header(line)==comment_header and \ 99 101 not is_all_white(line[comment_header_len:]): 100 102 lineno = lineno - 1 101 line = text.get("%d.0" % lineno, "%d. 0 lineend" % lineno)103 line = text.get("%d.0" % lineno, "%d.end" % lineno) 102 104 first = "%d.0" % (lineno+1) 105 103 106 return first, last, comment_header, text.get(first, last) 104 107 108 # This should perhaps be replaced with textwrap.wrap 105 109 def reformat_paragraph(data, limit): 110 """Return data reformatted to specified width (limit).""" 106 111 lines = data.split("\n") 107 112 i = 0 … … 126 131 continue # Can happen when line ends in whitespace 127 132 if len((partial + word).expandtabs()) > limit and \ 128 partial != indent1:133 partial != indent1: 129 134 new.append(partial.rstrip()) 130 135 partial = indent2 … … 138 143 return "\n".join(new) 139 144 145 def reformat_comment(data, limit, comment_header): 146 """Return data reformatted to specified width with comment header.""" 147 148 # Remove header from the comment lines 149 lc = len(comment_header) 150 data = "\n".join(line[lc:] for line in data.split("\n")) 151 # Reformat to maxformatwidth chars or a 20 char width, 152 # whichever is greater. 153 format_width = max(limit - len(comment_header), 20) 154 newdata = reformat_paragraph(data, format_width) 155 # re-split and re-insert the comment header. 156 newdata = newdata.split("\n") 157 # If the block ends in a \n, we dont want the comment prefix 158 # inserted after it. (Im not sure it makes sense to reformat a 159 # comment block that is not made of complete lines, but whatever!) 160 # Can't think of a clean solution, so we hack away 161 block_suffix = "" 162 if not newdata[-1]: 163 block_suffix = "\n" 164 newdata = newdata[:-1] 165 return '\n'.join(comment_header+line for line in newdata) + block_suffix 166 140 167 def is_all_white(line): 168 """Return True if line is empty or all whitespace.""" 169 141 170 return re.match(r"^\s*$", line) is not None 142 171 143 172 def get_indent(line): 144 return re.match(r"^(\s*)", line).group() 173 """Return the initial space or tab indent of line.""" 174 return re.match(r"^([ \t]*)", line).group() 145 175 146 176 def get_comment_header(line): 147 m = re.match(r"^(\s*#*)", line) 177 """Return string with leading whitespace and '#' from line or ''. 178 179 A null return indicates that the line is not a comment line. A non- 180 null return, such as ' #', will be used to find the other lines of 181 a comment block with the same indent. 182 """ 183 m = re.match(r"^([ \t]*#*)", line) 148 184 if m is None: return "" 149 185 return m.group(1) 186 187 if __name__ == "__main__": 188 from test import support; support.use_resources = ['gui'] 189 import unittest 190 unittest.main('idlelib.idle_test.test_formatparagraph', 191 verbosity=2, exit=False) -
python/trunk/Lib/idlelib/GrepDialog.py
r2 r391 3 3 import sys 4 4 from Tkinter import * 5 import SearchEngine6 from SearchDialogBase import SearchDialogBase5 from idlelib import SearchEngine 6 from idlelib.SearchDialogBase import SearchDialogBase 7 7 8 8 def grep(text, io=None, flist=None): … … 64 64 self.top.bell() 65 65 return 66 from OutputWindow import OutputWindow66 from idlelib.OutputWindow import OutputWindow 67 67 save = sys.stdout 68 68 try: … … 82 82 for fn in list: 83 83 try: 84 f = open(fn) 85 except IOError, msg: 84 with open(fn) as f: 85 for lineno, line in enumerate(f, 1): 86 if line[-1:] == '\n': 87 line = line[:-1] 88 if prog.search(line): 89 sys.stdout.write("%s: %s: %s\n" % 90 (fn, lineno, line)) 91 hits += 1 92 except IOError as msg: 86 93 print msg 87 continue 88 lineno = 0 89 while 1: 90 block = f.readlines(100000) 91 if not block: 92 break 93 for line in block: 94 lineno = lineno + 1 95 if line[-1:] == '\n': 96 line = line[:-1] 97 if prog.search(line): 98 sys.stdout.write("%s: %s: %s\n" % (fn, lineno, line)) 99 hits = hits + 1 100 if hits: 101 if hits == 1: 102 s = "" 103 else: 104 s = "s" 105 print "Found", hits, "hit%s." % s 106 print "(Hint: right-click to open locations.)" 107 else: 108 print "No hits." 94 print(("Hits found: %s\n" 95 "(Hint: right-click to open locations.)" 96 % hits) if hits else "No hits.") 109 97 110 98 def findfiles(self, dir, base, rec): 111 99 try: 112 100 names = os.listdir(dir or os.curdir) 113 except os.error ,msg:101 except os.error as msg: 114 102 print msg 115 103 return [] … … 132 120 self.top.grab_release() 133 121 self.top.withdraw() 122 123 if __name__ == "__main__": 124 # A human test is a bit tricky since EditorWindow() imports this module. 125 # Hence Idle must be restarted after editing this file for a live test. 126 import unittest 127 unittest.main('idlelib.idle_test.test_grep', verbosity=2, exit=False) -
python/trunk/Lib/idlelib/HISTORY.txt
r2 r391 14 14 project. 15 15 16 - This release requires python 2.1 or better. Compat ability with earlier16 - This release requires python 2.1 or better. Compatibility with earlier 17 17 versions of python (especially ancient ones like 1.5x) is no longer a 18 18 priority in IDLEfork development. -
python/trunk/Lib/idlelib/HyperParser.py
r2 r391 11 11 import string 12 12 import keyword 13 import PyParse13 from idlelib import PyParse 14 14 15 15 class HyperParser: … … 32 32 for context in editwin.num_context_lines: 33 33 startat = max(lno - context, 1) 34 startatindex = `startat`+ ".0"34 startatindex = repr(startat) + ".0" 35 35 stopatindex = "%d.end" % lno 36 36 # We add the newline because PyParse requires a newline at end. … … 233 233 else: 234 234 # We can't continue after other types of brackets 235 if rawtext[pos] in "'\"": 236 # Scan a string prefix 237 while pos > 0 and rawtext[pos - 1] in "rRbBuU": 238 pos -= 1 239 last_identifier_pos = pos 235 240 break 236 241 -
python/trunk/Lib/idlelib/IOBinding.py
r2 r391 8 8 import os 9 9 import types 10 import pipes 10 11 import sys 11 12 import codecs … … 17 18 from SimpleDialog import SimpleDialog 18 19 19 from configHandler import idleConf20 from idlelib.configHandler import idleConf 20 21 21 22 try: … … 71 72 encoding = encoding.lower() 72 73 73 coding_re = re.compile( "coding[:=]\s*([-\w_.]+)")74 coding_re = re.compile(r'^[ \t\f]*#.*coding[:=][ \t]*([-\w.]+)') 74 75 75 76 class EncodingMessage(SimpleDialog): … … 125 126 """ 126 127 # Only consider the first two lines 127 str = str.split("\n")[:2] 128 str = "\n".join(str) 129 130 match = coding_re.search(str) 131 if not match: 128 lst = str.split("\n", 2)[:2] 129 for line in lst: 130 match = coding_re.match(line) 131 if match is not None: 132 break 133 else: 132 134 return None 133 135 name = match.group(1) … … 197 199 198 200 def open(self, event=None, editFile=None): 199 if self.editwin.flist: 201 flist = self.editwin.flist 202 # Save in case parent window is closed (ie, during askopenfile()). 203 if flist: 200 204 if not editFile: 201 205 filename = self.askopenfile() … … 203 207 filename=editFile 204 208 if filename: 205 # If the current window has no filename and hasn't been 206 # modified, we replace its contents (no loss). Otherwise 207 # we open a new window. But we won't replace the 208 # shell window (which has an interp(reter) attribute), which 209 # gets set to "not modified" at every new prompt. 210 try: 211 interp = self.editwin.interp 212 except AttributeError: 213 interp = None 214 if not self.filename and self.get_saved() and not interp: 215 self.editwin.flist.open(filename, self.loadfile) 209 # If editFile is valid and already open, flist.open will 210 # shift focus to its existing window. 211 # If the current window exists and is a fresh unnamed, 212 # unmodified editor window (not an interpreter shell), 213 # pass self.loadfile to flist.open so it will load the file 214 # in the current window (if the file is not already open) 215 # instead of a new window. 216 if (self.editwin and 217 not getattr(self.editwin, 'interp', None) and 218 not self.filename and 219 self.get_saved()): 220 flist.open(filename, self.loadfile) 216 221 else: 217 self.editwin.flist.open(filename)222 flist.open(filename) 218 223 else: 219 self.text.focus_set() 224 if self.text: 225 self.text.focus_set() 220 226 return "break" 221 # 227 222 228 # Code for use outside IDLE: 223 229 if self.get_saved(): … … 244 250 # open the file in binary mode so that we can handle 245 251 # end-of-line convention ourselves. 246 f = open(filename,'rb') 247 chars = f.read() 248 f.close() 249 except IOError, msg: 252 with open(filename, 'rb') as f: 253 chars = f.read() 254 except IOError as msg: 250 255 tkMessageBox.showerror("I/O Error", str(msg), master=self.text) 251 256 return False … … 267 272 self.set_filename(filename) 268 273 self.text.mark_set("insert", "1.0") 269 self.text. see("insert")274 self.text.yview("insert") 270 275 self.updaterecentfileslist(filename) 271 276 return True … … 290 295 try: 291 296 enc = coding_spec(chars) 292 except LookupError ,name:297 except LookupError as name: 293 298 tkMessageBox.showerror( 294 299 title="Error loading the file", … … 321 326 message = "Do you want to save %s before closing?" % ( 322 327 self.filename or "this untitled document") 323 m = tkMessageBox.Message( 324 title="Save On Close", 325 message=message, 326 icon=tkMessageBox.QUESTION, 327 type=tkMessageBox.YESNOCANCEL, 328 master=self.text) 329 reply = m.show() 330 if reply == "yes": 328 confirm = tkMessageBox.askyesnocancel( 329 title="Save On Close", 330 message=message, 331 default=tkMessageBox.YES, 332 master=self.text) 333 if confirm: 334 reply = "yes" 331 335 self.save(None) 332 336 if not self.get_saved(): 333 337 reply = "cancel" 338 elif confirm is None: 339 reply = "cancel" 340 else: 341 reply = "no" 334 342 self.text.focus_set() 335 343 return reply … … 340 348 else: 341 349 if self.writefile(self.filename): 342 self.set_saved( 1)350 self.set_saved(True) 343 351 try: 344 352 self.editwin.store_file_breaks() … … 376 384 chars = chars.replace("\n", self.eol_convention) 377 385 try: 378 f = open(filename, "wb") 379 f.write(chars) 380 f.flush() 381 f.close() 386 with open(filename, "wb") as f: 387 f.write(chars) 382 388 return True 383 except IOError ,msg:389 except IOError as msg: 384 390 tkMessageBox.showerror("I/O Error", str(msg), 385 391 master=self.text) … … 401 407 enc = coding_spec(chars) 402 408 failed = None 403 except LookupError ,msg:409 except LookupError as msg: 404 410 failed = msg 405 411 enc = None … … 466 472 467 473 def print_window(self, event): 468 m = tkMessageBox.Message( 469 title="Print", 470 message="Print to Default Printer", 471 icon=tkMessageBox.QUESTION, 472 type=tkMessageBox.OKCANCEL, 473 default=tkMessageBox.OK, 474 master=self.text) 475 reply = m.show() 476 if reply != tkMessageBox.OK: 474 confirm = tkMessageBox.askokcancel( 475 title="Print", 476 message="Print to Default Printer", 477 default=tkMessageBox.OK, 478 master=self.text) 479 if not confirm: 477 480 self.text.focus_set() 478 481 return "break" … … 489 492 os.unlink(tempfilename) 490 493 return "break" 491 platform =os.name492 printPlatform =1494 platform = os.name 495 printPlatform = True 493 496 if platform == 'posix': #posix platform 494 497 command = idleConf.GetOption('main','General', … … 498 501 command = idleConf.GetOption('main','General','print-command-win') 499 502 else: #no printing for this platform 500 printPlatform =0503 printPlatform = False 501 504 if printPlatform: #we can try to print for this platform 502 command = command % filename505 command = command % pipes.quote(filename) 503 506 pipe = os.popen(command, "r") 504 507 # things can get ugly on NT if there is no printer available. … … 512 515 tkMessageBox.showerror("Print status", output, master=self.text) 513 516 else: #no printing for this platform 514 message ="Printing is not enabled for this platform: %s" % platform517 message = "Printing is not enabled for this platform: %s" % platform 515 518 tkMessageBox.showinfo("Print status", message, master=self.text) 516 519 if tempfilename: … … 522 525 523 526 filetypes = [ 524 ("Python and text files", "*.py *.pyw *.txt", "TEXT"),525 (" All text files", "*", "TEXT"),527 ("Python files", "*.py *.pyw", "TEXT"), 528 ("Text files", "*.txt", "TEXT"), 526 529 ("All files", "*"), 527 530 ] -
python/trunk/Lib/idlelib/IdleHistory.py
r2 r391 1 from configHandler import idleConf 1 "Implement Idle Shell history mechanism with History class" 2 3 from idlelib.configHandler import idleConf 2 4 3 5 class History: 6 ''' Implement Idle Shell history mechanism. 4 7 5 def __init__(self, text, output_sep = "\n"): 8 store - Store source statement (called from PyShell.resetoutput). 9 fetch - Fetch stored statement matching prefix already entered. 10 history_next - Bound to <<history-next>> event (default Alt-N). 11 history_prev - Bound to <<history-prev>> event (default Alt-P). 12 ''' 13 def __init__(self, text): 14 '''Initialize data attributes and bind event methods. 15 16 .text - Idle wrapper of tk Text widget, with .bell(). 17 .history - source statements, possibly with multiple lines. 18 .prefix - source already entered at prompt; filters history list. 19 .pointer - index into history. 20 .cyclic - wrap around history list (or not). 21 ''' 6 22 self.text = text 7 23 self.history = [] 8 self.history_prefix = None 9 self.history_pointer = None 10 self.output_sep = output_sep 24 self.prefix = None 25 self.pointer = None 11 26 self.cyclic = idleConf.GetOption("main", "History", "cyclic", 1, "bool") 12 27 text.bind("<<history-previous>>", self.history_prev) … … 14 29 15 30 def history_next(self, event): 16 self.history_do(0) 31 "Fetch later statement; start with ealiest if cyclic." 32 self.fetch(reverse=False) 17 33 return "break" 18 34 19 35 def history_prev(self, event): 20 self.history_do(1) 36 "Fetch earlier statement; start with most recent." 37 self.fetch(reverse=True) 21 38 return "break" 22 39 23 def _get_source(self, start, end): 24 # Get source code from start index to end index. Lines in the 25 # text control may be separated by sys.ps2 . 26 lines = self.text.get(start, end).split(self.output_sep) 27 return "\n".join(lines) 40 def fetch(self, reverse): 41 '''Fetch statememt and replace current line in text widget. 28 42 29 def _put_source(self, where, source):30 output = self.output_sep.join(source.split("\n"))31 self.text.insert(where, output)32 33 def history_do(self, reverse):43 Set prefix and pointer as needed for successive fetches. 44 Reset them to None, None when returning to the start line. 45 Sound bell when return to start line or cannot leave a line 46 because cyclic is False. 47 ''' 34 48 nhist = len(self.history) 35 pointer = self. history_pointer36 prefix = self. history_prefix49 pointer = self.pointer 50 prefix = self.prefix 37 51 if pointer is not None and prefix is not None: 38 52 if self.text.compare("insert", "!=", "end-1c") or \ 39 self._get_source("iomark", "end-1c") != self.history[pointer]:53 self.text.get("iomark", "end-1c") != self.history[pointer]: 40 54 pointer = prefix = None 55 self.text.mark_set("insert", "end-1c") # != after cursor move 41 56 if pointer is None or prefix is None: 42 prefix = self. _get_source("iomark", "end-1c")57 prefix = self.text.get("iomark", "end-1c") 43 58 if reverse: 44 pointer = nhist 59 pointer = nhist # will be decremented 45 60 else: 46 61 if self.cyclic: 47 pointer = -1 48 else: 62 pointer = -1 # will be incremented 63 else: # abort history_next 49 64 self.text.bell() 50 65 return 51 66 nprefix = len(prefix) 52 67 while 1: 53 if reverse: 54 pointer = pointer - 1 55 else: 56 pointer = pointer + 1 68 pointer += -1 if reverse else 1 57 69 if pointer < 0 or pointer >= nhist: 58 70 self.text.bell() 59 if not self.cyclic and pointer < 0: 71 if not self.cyclic and pointer < 0: # abort history_prev 60 72 return 61 73 else: 62 if self. _get_source("iomark", "end-1c") != prefix:74 if self.text.get("iomark", "end-1c") != prefix: 63 75 self.text.delete("iomark", "end-1c") 64 self. _put_source("iomark", prefix)76 self.text.insert("iomark", prefix) 65 77 pointer = prefix = None 66 78 break … … 68 80 if item[:nprefix] == prefix and len(item) > nprefix: 69 81 self.text.delete("iomark", "end-1c") 70 self. _put_source("iomark", item)82 self.text.insert("iomark", item) 71 83 break 72 self.text.mark_set("insert", "end-1c")73 84 self.text.see("insert") 74 85 self.text.tag_remove("sel", "1.0", "end") 75 self. history_pointer = pointer76 self. history_prefix = prefix86 self.pointer = pointer 87 self.prefix = prefix 77 88 78 def history_store(self, source): 89 def store(self, source): 90 "Store Shell input statement into history list." 79 91 source = source.strip() 80 92 if len(source) > 2: … … 85 97 pass 86 98 self.history.append(source) 87 self.history_pointer = None 88 self.history_prefix = None 99 self.pointer = None 100 self.prefix = None 101 102 if __name__ == "__main__": 103 from test import test_support as support 104 support.use_resources = ['gui'] 105 from unittest import main 106 main('idlelib.idle_test.test_idlehistory', verbosity=2, exit=False) -
python/trunk/Lib/idlelib/MultiCall.py
r2 r391 34 34 import re 35 35 import Tkinter 36 import macosxSupport36 from idlelib import macosxSupport 37 37 38 38 # the event type constants, which define the meaning of mc_type … … 108 108 # number of modifiers is the state - the most specific state comes first. 109 109 _states = range(1 << len(_modifiers)) 110 _state_names = [reduce(lambda x, y: x + y, 111 [_modifiers[i][0]+'-' for i in range(len(_modifiers)) 112 if (1 << i) & s], 113 "") 110 _state_names = [''.join(m[0]+'-' 111 for i, m in enumerate(_modifiers) 112 if (1 << i) & s) 114 113 for s in _states] 115 _state_subsets = map(lambda i: filter(lambda j: not (j & (~i)), _states), 116 _states) 117 for l in _state_subsets: 118 l.sort(lambda a, b, nummod = lambda x: len(filter(lambda i: (1<<i) & x, 119 range(len(_modifiers)))): 120 nummod(b) - nummod(a)) 114 115 def expand_substates(states): 116 '''For each item of states return a list containing all combinations of 117 that item with individual bits reset, sorted by the number of set bits. 118 ''' 119 def nbits(n): 120 "number of bits set in n base 2" 121 nb = 0 122 while n: 123 n, rem = divmod(n, 2) 124 nb += rem 125 return nb 126 statelist = [] 127 for state in states: 128 substates = list(set(state & x for x in states)) 129 substates.sort(key=nbits, reverse=True) 130 statelist.append(substates) 131 return statelist 132 133 _state_subsets = expand_substates(_states) 134 121 135 # _state_codes gives for each state, the portable code to be passed as mc_state 122 _state_codes = [reduce(lambda x, y: x | y, 123 [_modifier_masks[i] for i in range(len(_modifiers)) 124 if (1 << i) & s], 125 0) 126 for s in _states] 136 _state_codes = [] 137 for s in _states: 138 r = 0 139 for i in range(len(_modifiers)): 140 if (1 << i) & s: 141 r |= _modifier_masks[i] 142 _state_codes.append(r) 127 143 128 144 class _ComplexBinder: … … 156 172 ishandlerrunning[:] = [] 157 173 # Call all functions in doafterhandler and remove them from list 158 while doafterhandler: 159 doafterhandler.pop()() 174 for f in doafterhandler: 175 f() 176 doafterhandler[:] = [] 160 177 if r: 161 178 return r … … 186 203 187 204 def bind(self, triplet, func): 188 if not self.bindedfuncs.has_key(triplet[2]):205 if triplet[2] not in self.bindedfuncs: 189 206 self.bindedfuncs[triplet[2]] = [[] for s in _states] 190 207 for s in _states: … … 297 314 298 315 def __init__(self, *args, **kwargs): 299 apply(widget.__init__, (self,)+args,kwargs)316 widget.__init__(self, *args, **kwargs) 300 317 # a dictionary which maps a virtual event to a tuple with: 301 318 # 0. the function binded -
python/trunk/Lib/idlelib/MultiStatusBar.py
r2 r391 10 10 11 11 def set_label(self, name, text='', side=LEFT): 12 if n ot self.labels.has_key(name):12 if name not in self.labels: 13 13 label = Label(self, bd=1, relief=SUNKEN, anchor=W) 14 14 label.pack(side=side) -
python/trunk/Lib/idlelib/NEWS.txt
r2 r391 1 What's New in Python 2.6.4rc1 2 ============================= 3 4 *Release date: 07-Oct-2009* 1 What's New in IDLE 2.7.5? 2 ========================= 3 4 - Issue #17390: Display Python version on Idle title bar. 5 Initial patch by Edmond Burnett. 6 7 8 What's New in IDLE 2.7.4? 9 ========================= 10 11 - Issue #15318: Prevent writing to sys.stdin. 12 13 - Issue #13532, #15319: Check that arguments to sys.stdout.write are strings. 14 15 - Issue # 12510: Attempt to get certain tool tips no longer crashes IDLE. 16 17 - Issue10365: File open dialog now works instead of crashing even when 18 parent window is closed while dialog is open. 19 20 - Issue 14876: use user-selected font for highlight configuration. 21 22 - Issue #14018: Update checks for unstable system Tcl/Tk versions on OS X 23 to include versions shipped with OS X 10.7 and 10.8 in addition to 10.6. 24 25 - Issue #15853: Prevent IDLE crash on OS X when opening Preferences menu 26 with certain versions of Tk 8.5. Initial patch by Kevin Walzer. 27 28 29 What's New in IDLE 2.7.3? 30 ========================= 31 32 - Issue #14409: IDLE now properly executes commands in the Shell window 33 when it cannot read the normal config files on startup and 34 has to use the built-in default key bindings. 35 There was previously a bug in one of the defaults. 36 37 - Issue #3573: IDLE hangs when passing invalid command line args 38 (directory(ies) instead of file(s)). 39 40 41 What's New in IDLE 2.7.2? 42 ========================= 43 44 *Release date: 29-May-2011* 45 46 - Issue #6378: Further adjust idle.bat to start associated Python 47 48 - Issue #11896: Save on Close failed despite selecting "Yes" in dialog. 49 50 - <Home> toggle failing on Tk 8.5, causing IDLE exits and strange selection 51 behavior. Issue 4676. Improve selection extension behaviour. 52 53 - <Home> toggle non-functional when NumLock set on Windows. Issue 3851. 54 55 56 What's New in IDLE 2.7? 57 ======================= 58 59 *Release date: 07-03-2010* 60 61 - idle.py modified and simplified to better support developing experimental 62 versions of IDLE which are not installed in the standard location. 5 63 6 64 - OutputWindow/PyShell right click menu "Go to file/line" wasn't working with 7 65 file paths containing spaces. Bug 5559. 8 66 9 What's New in Python 2.6.310 ==========================11 12 *Release date: 02-Oct-2009*13 14 What's New in IDLE 2.6.3rc1?15 ============================16 17 *Release date: 28-Sep-2009*18 19 - On OS X IDLE 2.6 shows two Preference menu items. Issue6951.20 21 67 - Windows: Version string for the .chm help file changed, file not being 22 68 accessed Patch 5783 Guilherme Polo 23 69 70 - Allow multiple IDLE GUI/subprocess pairs to exist simultaneously. Thanks to 71 David Scherer for suggesting the use of an ephemeral port for the GUI. 72 Patch 1529142 Weeble. 73 74 - Remove port spec from run.py and fix bug where subprocess fails to 75 extract port from command line when warnings are present. 76 24 77 - Tk 8.5 Text widget requires 'wordprocessor' tabstyle attr to handle 25 78 mixed space/tab properly. Issue 5129, patch by Guilherme Polo. 26 79 27 What's New in IDLE 2.6.2rc1?28 ============================29 30 *Release date: 06-Apr-2009*31 32 80 - Issue #3549: On MacOS the preferences menu was not present 81 33 82 34 83 What's New in IDLE 2.6? … … 57 106 were Python source; improve use of ColorDelagator. Patch 1334. Tal Einat. 58 107 59 - ScriptBinding event handlers weren't returning 'break'. Patch 2050, Tal Einat 108 - ScriptBinding event handlers weren't returning 'break'. Patch 2050, Tal Einat. 60 109 61 110 - There was an error on exit if no sys.exitfunc was defined. Issue 1647. -
python/trunk/Lib/idlelib/ObjectBrowser.py
r2 r391 10 10 # - for classes/modules, add "open source" to object browser 11 11 12 from TreeWidget import TreeItem, TreeNode, ScrolledCanvas12 from idlelib.TreeWidget import TreeItem, TreeNode, ScrolledCanvas 13 13 14 14 from repr import Repr … … 127 127 def make_objecttreeitem(labeltext, object, setfunction=None): 128 128 t = type(object) 129 if dispatch.has_key(t):129 if t in dispatch: 130 130 c = dispatch[t] 131 131 else: -
python/trunk/Lib/idlelib/OutputWindow.py
r2 r391 1 1 from Tkinter import * 2 from EditorWindow import EditorWindow2 from idlelib.EditorWindow import EditorWindow 3 3 import re 4 4 import tkMessageBox 5 import IOBinding5 from idlelib import IOBinding 6 6 7 7 class OutputWindow(EditorWindow): … … 48 48 self.text.update() 49 49 50 def writelines(self, l): 51 map(self.write, l) 50 def writelines(self, lines): 51 for line in lines: 52 self.write(line) 52 53 53 54 def flush(self): … … 57 58 58 59 rmenu_specs = [ 59 ("Go to file/line", "<<goto-file-line>>"), 60 ("Cut", "<<cut>>", "rmenu_check_cut"), 61 ("Copy", "<<copy>>", "rmenu_check_copy"), 62 ("Paste", "<<paste>>", "rmenu_check_paste"), 63 (None, None, None), 64 ("Go to file/line", "<<goto-file-line>>", None), 60 65 ] 61 66 -
python/trunk/Lib/idlelib/ParenMatch.py
r2 r391 6 6 """ 7 7 8 from HyperParser import HyperParser9 from configHandler import idleConf8 from idlelib.HyperParser import HyperParser 9 from idlelib.configHandler import idleConf 10 10 11 11 _openers = {')':'(',']':'[','}':'{'} -
python/trunk/Lib/idlelib/PathBrowser.py
r2 r391 3 3 import imp 4 4 5 from TreeWidget import TreeItem6 from ClassBrowser import ClassBrowser, ModuleBrowserTreeItem5 from idlelib.TreeWidget import TreeItem 6 from idlelib.ClassBrowser import ClassBrowser, ModuleBrowserTreeItem 7 7 8 8 class PathBrowser(ClassBrowser): … … 79 79 if normed_name[i:] == suff: 80 80 mod_name = name[:i] 81 if not modules.has_key(mod_name):81 if mod_name not in modules: 82 82 modules[mod_name] = None 83 83 sorted.append((normed_name, name)) … … 87 87 88 88 def main(): 89 import PyShell89 from idlelib import PyShell 90 90 PathBrowser(PyShell.flist) 91 91 if sys.stdin is sys.__stdin__: … … 93 93 94 94 if __name__ == "__main__": 95 main() 95 from unittest import main 96 main('idlelib.idle_test.test_pathbrowser', verbosity=2, exit=False) -
python/trunk/Lib/idlelib/Percolator.py
r2 r391 1 from WidgetRedirector import WidgetRedirector2 from Delegator import Delegator1 from idlelib.WidgetRedirector import WidgetRedirector 2 from idlelib.Delegator import Delegator 3 3 4 4 class Percolator: -
python/trunk/Lib/idlelib/PyShell.py
r2 r391 12 12 import traceback 13 13 import types 14 import macosxSupport14 import io 15 15 16 16 import linecache 17 17 from code import InteractiveInterpreter 18 from platform import python_version 18 19 19 20 try: … … 25 26 import tkMessageBox 26 27 27 from EditorWindow import EditorWindow, fixwordbreaks28 from FileList import FileList29 from ColorDelegator import ColorDelegator30 from UndoDelegator import UndoDelegator31 from OutputWindow import OutputWindow32 from configHandler import idleConf33 import idlever34 35 import rpc 36 importDebugger37 import RemoteDebugger 28 from idlelib.EditorWindow import EditorWindow, fixwordbreaks 29 from idlelib.FileList import FileList 30 from idlelib.ColorDelegator import ColorDelegator 31 from idlelib.UndoDelegator import UndoDelegator 32 from idlelib.OutputWindow import OutputWindow 33 from idlelib.configHandler import idleConf 34 from idlelib import idlever 35 from idlelib import rpc 36 from idlelib import Debugger 37 from idlelib import RemoteDebugger 38 from idlelib import macosxSupport 38 39 39 40 IDENTCHARS = string.ascii_letters + string.digits + "_" 40 LOCALHOST = '127.0.0.1' 41 HOST = '127.0.0.1' # python execution server on localhost loopback 42 PORT = 0 # someday pass in host, port for remote debug capability 41 43 42 44 try: … … 49 51 # temporarily redirect the stream to the shell window to display warnings when 50 52 # checking user's code. 51 global warning_stream 52 warning_stream = sys.__stderr__ 53 try: 54 import warnings 55 except ImportError: 56 pass 57 else: 58 def idle_showwarning(message, category, filename, lineno, 59 file=None, line=None): 53 warning_stream = sys.__stderr__ # None, at least on Windows, if no console. 54 import warnings 55 56 def idle_formatwarning(message, category, filename, lineno, line=None): 57 """Format warnings the IDLE way.""" 58 59 s = "\nWarning (from warnings module):\n" 60 s += ' File \"%s\", line %s\n' % (filename, lineno) 61 if line is None: 62 line = linecache.getline(filename, lineno) 63 line = line.strip() 64 if line: 65 s += " %s\n" % line 66 s += "%s: %s\n" % (category.__name__, message) 67 return s 68 69 def idle_showwarning( 70 message, category, filename, lineno, file=None, line=None): 71 """Show Idle-format warning (after replacing warnings.showwarning). 72 73 The differences are the formatter called, the file=None replacement, 74 which can be None, the capture of the consequence AttributeError, 75 and the output of a hard-coded prompt. 76 """ 77 if file is None: 60 78 file = warning_stream 61 try: 62 file.write(warnings.formatwarning(message, category, filename,\ 63 lineno, file=file, line=line)) 64 except IOError: 65 pass ## file (probably __stderr__) is invalid, warning dropped. 66 warnings.showwarning = idle_showwarning 67 def idle_formatwarning(message, category, filename, lineno, 68 file=None, line=None): 69 """Format warnings the IDLE way""" 70 s = "\nWarning (from warnings module):\n" 71 s += ' File \"%s\", line %s\n' % (filename, lineno) 72 line = linecache.getline(filename, lineno).strip() \ 73 if line is None else line 74 if line: 75 s += " %s\n" % line 76 s += "%s: %s\n>>> " % (category.__name__, message) 77 return s 78 warnings.formatwarning = idle_formatwarning 79 try: 80 file.write(idle_formatwarning( 81 message, category, filename, lineno, line=line)) 82 file.write(">>> ") 83 except (AttributeError, IOError): 84 pass # if file (probably __stderr__) is invalid, skip warning. 85 86 _warnings_showwarning = None 87 88 def capture_warnings(capture): 89 "Replace warning.showwarning with idle_showwarning, or reverse." 90 91 global _warnings_showwarning 92 if capture: 93 if _warnings_showwarning is None: 94 _warnings_showwarning = warnings.showwarning 95 warnings.showwarning = idle_showwarning 96 else: 97 if _warnings_showwarning is not None: 98 warnings.showwarning = _warnings_showwarning 99 _warnings_showwarning = None 100 101 capture_warnings(True) 79 102 80 103 def extended_linecache_checkcache(filename=None, … … 84 107 Rather than repeating the linecache code, patch it to save the 85 108 <pyshell#...> entries, call the original linecache.checkcache() 86 ( which destroysthem), and then restore the saved entries.109 (skipping them), and then restore the saved entries. 87 110 88 111 orig_checkcache is bound at definition time to the original 89 112 method, allowing it to be patched. 90 91 113 """ 92 114 cache = linecache.cache 93 115 save = {} 94 for filename in cache.keys():95 if filename[:1] + filename[-1:] == '<>':96 save[ filename] = cache[filename]97 orig_checkcache( )116 for key in list(cache): 117 if key[:1] + key[-1:] == '<>': 118 save[key] = cache.pop(key) 119 orig_checkcache(filename) 98 120 cache.update(save) 99 121 … … 115 137 'breakpoints.lst') 116 138 # whenever a file is changed, restore breakpoints 117 if self.io.filename: self.restore_file_breaks()118 139 def filename_changed_hook(old_hook=self.io.filename_change_hook, 119 140 self=self): … … 121 142 old_hook() 122 143 self.io.set_filename_change_hook(filename_changed_hook) 123 124 rmenu_specs = [("Set Breakpoint", "<<set-breakpoint-here>>"), 125 ("Clear Breakpoint", "<<clear-breakpoint-here>>")] 144 if self.io.filename: 145 self.restore_file_breaks() 146 147 rmenu_specs = [ 148 ("Cut", "<<cut>>", "rmenu_check_cut"), 149 ("Copy", "<<copy>>", "rmenu_check_copy"), 150 ("Paste", "<<paste>>", "rmenu_check_paste"), 151 ("Set Breakpoint", "<<set-breakpoint-here>>", None), 152 ("Clear Breakpoint", "<<clear-breakpoint-here>>", None) 153 ] 126 154 127 155 def set_breakpoint(self, lineno): … … 208 236 filename = self.io.filename 209 237 try: 210 lines = open(self.breakpointPath,"r").readlines() 238 with open(self.breakpointPath,"r") as old_file: 239 lines = old_file.readlines() 211 240 except IOError: 212 241 lines = [] 213 new_file = open(self.breakpointPath,"w") 214 for line in lines: 215 if not line.startswith(filename + '='): 216 new_file.write(line) 217 self.update_breakpoints() 218 breaks = self.breakpoints 219 if breaks: 220 new_file.write(filename + '=' + str(breaks) + '\n') 221 new_file.close() 242 try: 243 with open(self.breakpointPath,"w") as new_file: 244 for line in lines: 245 if not line.startswith(filename + '='): 246 new_file.write(line) 247 self.update_breakpoints() 248 breaks = self.breakpoints 249 if breaks: 250 new_file.write(filename + '=' + str(breaks) + '\n') 251 except IOError as err: 252 if not getattr(self.root, "breakpoint_error_displayed", False): 253 self.root.breakpoint_error_displayed = True 254 tkMessageBox.showerror(title='IDLE Error', 255 message='Unable to update breakpoint list:\n%s' 256 % str(err), 257 parent=self.text) 222 258 223 259 def restore_file_breaks(self): 224 260 self.text.update() # this enables setting "BREAK" tags to be visible 261 if self.io is None: 262 # can happen if IDLE closes due to the .update() call 263 return 225 264 filename = self.io.filename 226 265 if filename is None: … … 244 283 lines = [] 245 284 for index in range(0, len(ranges), 2): 246 lineno = int(float(ranges[index] ))247 end = int(float(ranges[index+1] ))285 lineno = int(float(ranges[index].string)) 286 end = int(float(ranges[index+1].string)) 248 287 while lineno < end: 249 288 lines.append(lineno) … … 306 345 }) 307 346 347 def removecolors(self): 348 # Don't remove shell color tags before "iomark" 349 for tag in self.tagdefs: 350 self.tag_remove(tag, "iomark", "end") 351 308 352 class ModifiedUndoDelegator(UndoDelegator): 309 353 "Extend base class: forbid insert/delete before the I/O mark" … … 343 387 self.save_warnings_filters = None 344 388 self.restarting = False 345 self.subprocess_arglist = self.build_subprocess_arglist() 346 347 port = 8833 389 self.subprocess_arglist = None 390 self.port = PORT 391 self.original_compiler_flags = self.compile.compiler.flags 392 393 _afterid = None 348 394 rpcclt = None 349 395 rpcpid = None 350 396 351 397 def spawn_subprocess(self): 398 if self.subprocess_arglist is None: 399 self.subprocess_arglist = self.build_subprocess_arglist() 352 400 args = self.subprocess_arglist 353 401 self.rpcpid = os.spawnv(os.P_NOWAIT, sys.executable, args) 354 402 355 403 def build_subprocess_arglist(self): 404 assert (self.port!=0), ( 405 "Socket should have been assigned a port number.") 356 406 w = ['-W' + s for s in sys.warnoptions] 357 407 if 1/2 > 0: # account for new division … … 374 424 375 425 def start_subprocess(self): 376 # spawning first avoids passing a listening socket to the subprocess 377 self.spawn_subprocess() 378 #time.sleep(20) # test to simulate GUI not accepting connection 379 addr = (LOCALHOST, self.port) 380 # Idle starts listening for connection on localhost 426 addr = (HOST, self.port) 427 # GUI makes several attempts to acquire socket, listens for connection 381 428 for i in range(3): 382 429 time.sleep(i) … … 384 431 self.rpcclt = MyRPCClient(addr) 385 432 break 386 except socket.error ,err:433 except socket.error as err: 387 434 pass 388 435 else: 389 436 self.display_port_binding_error() 390 437 return None 438 # if PORT was 0, system will assign an 'ephemeral' port. Find it out: 439 self.port = self.rpcclt.listening_sock.getsockname()[1] 440 # if PORT was not 0, probably working with a remote execution server 441 if PORT != 0: 442 # To allow reconnection within the 2MSL wait (cf. Stevens TCP 443 # V1, 18.6), set SO_REUSEADDR. Note that this can be problematic 444 # on Windows since the implementation allows two active sockets on 445 # the same address! 446 self.rpcclt.listening_sock.setsockopt(socket.SOL_SOCKET, 447 socket.SO_REUSEADDR, 1) 448 self.spawn_subprocess() 449 #time.sleep(20) # test to simulate GUI not accepting connection 391 450 # Accept the connection from the Python execution server 392 451 self.rpcclt.listening_sock.settimeout(10) 393 452 try: 394 453 self.rpcclt.accept() 395 except socket.timeout ,err:454 except socket.timeout as err: 396 455 self.display_no_subprocess_error() 397 456 return None 398 self.rpcclt.register("stdin", self.tkconsole) 457 self.rpcclt.register("console", self.tkconsole) 458 self.rpcclt.register("stdin", self.tkconsole.stdin) 399 459 self.rpcclt.register("stdout", self.tkconsole.stdout) 400 460 self.rpcclt.register("stderr", self.tkconsole.stderr) … … 402 462 self.rpcclt.register("linecache", linecache) 403 463 self.rpcclt.register("interp", self) 404 self.transfer_path( )464 self.transfer_path(with_cwd=True) 405 465 self.poll_subprocess() 406 466 return self.rpcclt 407 467 408 def restart_subprocess(self ):468 def restart_subprocess(self, with_cwd=False): 409 469 if self.restarting: 410 470 return self.rpcclt … … 427 487 try: 428 488 self.rpcclt.accept() 429 except socket.timeout ,err:489 except socket.timeout as err: 430 490 self.display_no_subprocess_error() 431 491 return None 432 self.transfer_path() 492 self.transfer_path(with_cwd=with_cwd) 493 console.stop_readline() 433 494 # annotate restart in shell window and mark it 434 495 console.text.delete("iomark", "end-1c") … … 447 508 # reload remote debugger breakpoints for all PyShellEditWindows 448 509 debug.load_breakpoints() 510 self.compile.compiler.flags = self.original_compiler_flags 449 511 self.restarting = False 450 512 return self.rpcclt … … 457 519 458 520 def kill_subprocess(self): 521 if self._afterid is not None: 522 self.tkconsole.text.after_cancel(self._afterid) 459 523 try: 460 524 self.rpcclt.close() … … 479 543 return 480 544 481 def transfer_path(self): 545 def transfer_path(self, with_cwd=False): 546 if with_cwd: # Issue 13506 547 path = [''] # include Current Working Directory 548 path.extend(sys.path) 549 else: 550 path = sys.path 551 482 552 self.runcommand("""if 1: 483 553 import sys as _sys 484 554 _sys.path = %r 485 555 del _sys 486 \n""" % ( sys.path,))556 \n""" % (path,)) 487 557 488 558 active_seq = None … … 523 593 # Reschedule myself 524 594 if not self.tkconsole.closing: 525 self. tkconsole.text.after(self.tkconsole.pollinterval,526 595 self._afterid = self.tkconsole.text.after( 596 self.tkconsole.pollinterval, self.poll_subprocess) 527 597 528 598 debugger = None … … 540 610 method we allow the subprocess to unblock. After a bit the shell 541 611 requests the subprocess to open the remote stack viewer which returns a 542 static object looking at the last exceptio pn. It is queried through612 static object looking at the last exception. It is queried through 543 613 the RPC mechanism. 544 614 … … 548 618 549 619 def remote_stack_viewer(self): 550 import RemoteObjectBrowser620 from idlelib import RemoteObjectBrowser 551 621 oid = self.rpcclt.remotequeue("exec", "stackviewer", ("flist",), {}) 552 622 if oid is None: … … 554 624 return 555 625 item = RemoteObjectBrowser.StubObjectTreeItem(self.rpcclt, oid) 556 from TreeWidget import ScrolledCanvas, TreeNode626 from idlelib.TreeWidget import ScrolledCanvas, TreeNode 557 627 top = Toplevel(self.tkconsole.root) 558 628 theme = idleConf.GetOption('main','Theme','name') … … 594 664 warnings.filterwarnings(action="error", category=SyntaxWarning) 595 665 if isinstance(source, types.UnicodeType): 596 import IOBinding666 from idlelib import IOBinding 597 667 try: 598 668 source = source.encode(IOBinding.encoding) … … 755 825 tkMessageBox.showerror( 756 826 "Port Binding Error", 757 "IDLE can't bind TCP/IP port 8833, which is necessary to " 758 "communicate with its Python execution server. Either " 759 "no networking is installed on this computer or another " 760 "process (another IDLE?) is using the port. Run IDLE with the -n " 761 "command line switch to start without a subprocess and refer to " 762 "Help/IDLE Help 'Running without a subprocess' for further " 763 "details.", 827 "IDLE can't bind to a TCP/IP port, which is necessary to " 828 "communicate with its Python execution server. This might be " 829 "because no networking is installed on this computer. " 830 "Run IDLE with the -n command line switch to start without a " 831 "subprocess and refer to Help/IDLE Help 'Running without a " 832 "subprocess' for further details.", 764 833 master=self.tkconsole.text) 765 834 … … 782 851 class PyShell(OutputWindow): 783 852 784 shell_title = "Python Shell"853 shell_title = "Python " + python_version() + " Shell" 785 854 786 855 # Override classes … … 799 868 800 869 if macosxSupport.runningAsOSXApp(): 801 del menu_specs[-3]802 870 menu_specs[-2] = ("windows", "_Window") 803 871 804 872 805 873 # New classes 806 from IdleHistory import History874 from idlelib.IdleHistory import History 807 875 808 876 def __init__(self, flist=None): … … 842 910 self.save_stderr = sys.stderr 843 911 self.save_stdin = sys.stdin 844 import IOBinding 845 self.stdout = PseudoFile(self, "stdout", IOBinding.encoding) 846 self.stderr = PseudoFile(self, "stderr", IOBinding.encoding) 847 self.console = PseudoFile(self, "console", IOBinding.encoding) 912 from idlelib import IOBinding 913 self.stdin = PseudoInputFile(self, "stdin", IOBinding.encoding) 914 self.stdout = PseudoOutputFile(self, "stdout", IOBinding.encoding) 915 self.stderr = PseudoOutputFile(self, "stderr", IOBinding.encoding) 916 self.console = PseudoOutputFile(self, "console", IOBinding.encoding) 848 917 if not use_subprocess: 849 918 sys.stdout = self.stdout 850 919 sys.stderr = self.stderr 851 sys.stdin = self 920 sys.stdin = self.stdin 852 921 # 853 922 self.history = self.History(self.text) … … 863 932 endoffile = False 864 933 closing = False 934 _stop_readline_flag = False 865 935 866 936 def set_warning_stream(self, stream): … … 938 1008 if response is False: 939 1009 return "cancel" 940 if self.reading: 941 self.top.quit() 1010 self.stop_readline() 942 1011 self.canceled = True 943 1012 self.closing = True 944 # Wait for poll_subprocess() rescheduling to stop945 self.text.after(2 * self.pollinterval, self.close2)946 947 def close2(self):948 1013 return EditorWindow.close(self) 949 1014 … … 974 1039 'Type "copyright", "credits" or "license()" for more information.' 975 1040 976 firewallmessage = """977 ****************************************************************978 Personal firewall software may warn about the connection IDLE979 makes to its subprocess using this computer's internal loopback980 interface. This connection is not visible on any external981 interface and no data is sent to or received from the Internet.982 ****************************************************************983 """984 985 1041 def begin(self): 986 1042 self.resetoutput() … … 993 1049 else: 994 1050 nosub = "==== No Subprocess ====" 995 self.write("Python %s on %s\n%s\n%s\nIDLE %s %s\n" % 996 (sys.version, sys.platform, self.COPYRIGHT, 997 self.firewallmessage, idlever.IDLE_VERSION, nosub)) 1051 self.write("Python %s on %s\n%s\n%s" % 1052 (sys.version, sys.platform, self.COPYRIGHT, nosub)) 998 1053 self.showprompt() 999 1054 import Tkinter … … 1001 1056 return True 1002 1057 1058 def stop_readline(self): 1059 if not self.reading: # no nested mainloop to exit. 1060 return 1061 self._stop_readline_flag = True 1062 self.top.quit() 1063 1003 1064 def readline(self): 1004 1065 save = self.reading … … 1008 1069 finally: 1009 1070 self.reading = save 1071 if self._stop_readline_flag: 1072 self._stop_readline_flag = False 1073 return "" 1010 1074 line = self.text.get("iomark", "end-1c") 1011 1075 if len(line) == 0: # may be EOF if we quit our mainloop with Ctrl-C 1012 1076 line = "\n" 1013 1077 if isinstance(line, unicode): 1014 import IOBinding1078 from idlelib import IOBinding 1015 1079 try: 1016 1080 line = line.encode(IOBinding.encoding) … … 1190 1254 master=self.text) 1191 1255 return 1192 from StackViewer import StackBrowser1256 from idlelib.StackViewer import StackBrowser 1193 1257 sv = StackBrowser(self.root, self.flist) 1194 1258 … … 1198 1262 1199 1263 def restart_shell(self, event=None): 1200 self.interp.restart_subprocess() 1264 "Callback for Run/Restart Shell Cntl-F6" 1265 self.interp.restart_subprocess(with_cwd=True) 1201 1266 1202 1267 def showprompt(self): … … 1214 1279 source = self.text.get("iomark", "end-1c") 1215 1280 if self.history: 1216 self.history. history_store(source)1281 self.history.store(source) 1217 1282 if self.text.get("end-2c") != "\n": 1218 1283 self.text.insert("end-1c", "\n") … … 1233 1298 raise KeyboardInterrupt 1234 1299 1235 class PseudoFile(object): 1300 def rmenu_check_cut(self): 1301 try: 1302 if self.text.compare('sel.first', '<', 'iomark'): 1303 return 'disabled' 1304 except TclError: # no selection, so the index 'sel.first' doesn't exist 1305 return 'disabled' 1306 return super(PyShell, self).rmenu_check_cut() 1307 1308 def rmenu_check_paste(self): 1309 if self.text.compare('insert', '<', 'iomark'): 1310 return 'disabled' 1311 return super(PyShell, self).rmenu_check_paste() 1312 1313 class PseudoFile(io.TextIOBase): 1236 1314 1237 1315 def __init__(self, shell, tags, encoding=None): … … 1239 1317 self.tags = tags 1240 1318 self.softspace = 0 1241 self.encoding = encoding 1242 1243 def write(self, s): 1244 self.shell.write(s, self.tags) 1245 1246 def writelines(self, l): 1247 map(self.write, l) 1248 1249 def flush(self): 1250 pass 1319 self._encoding = encoding 1320 1321 @property 1322 def encoding(self): 1323 return self._encoding 1324 1325 @property 1326 def name(self): 1327 return '<%s>' % self.tags 1251 1328 1252 1329 def isatty(self): 1253 1330 return True 1331 1332 1333 class PseudoOutputFile(PseudoFile): 1334 1335 def writable(self): 1336 return True 1337 1338 def write(self, s): 1339 if self.closed: 1340 raise ValueError("write to closed file") 1341 if not isinstance(s, (basestring, bytearray)): 1342 raise TypeError('must be string, not ' + type(s).__name__) 1343 return self.shell.write(s, self.tags) 1344 1345 1346 class PseudoInputFile(PseudoFile): 1347 1348 def __init__(self, shell, tags, encoding=None): 1349 PseudoFile.__init__(self, shell, tags, encoding) 1350 self._line_buffer = '' 1351 1352 def readable(self): 1353 return True 1354 1355 def read(self, size=-1): 1356 if self.closed: 1357 raise ValueError("read from closed file") 1358 if size is None: 1359 size = -1 1360 elif not isinstance(size, int): 1361 raise TypeError('must be int, not ' + type(size).__name__) 1362 result = self._line_buffer 1363 self._line_buffer = '' 1364 if size < 0: 1365 while True: 1366 line = self.shell.readline() 1367 if not line: break 1368 result += line 1369 else: 1370 while len(result) < size: 1371 line = self.shell.readline() 1372 if not line: break 1373 result += line 1374 self._line_buffer = result[size:] 1375 result = result[:size] 1376 return result 1377 1378 def readline(self, size=-1): 1379 if self.closed: 1380 raise ValueError("read from closed file") 1381 if size is None: 1382 size = -1 1383 elif not isinstance(size, int): 1384 raise TypeError('must be int, not ' + type(size).__name__) 1385 line = self._line_buffer or self.shell.readline() 1386 if size < 0: 1387 size = len(line) 1388 self._line_buffer = line[size:] 1389 return line[:size] 1390 1391 def close(self): 1392 self.shell.close() 1254 1393 1255 1394 … … 1310 1449 global flist, root, use_subprocess 1311 1450 1451 capture_warnings(True) 1312 1452 use_subprocess = True 1313 1453 enable_shell = False … … 1319 1459 try: 1320 1460 opts, args = getopt.getopt(sys.argv[1:], "c:deihnr:st:") 1321 except getopt.error ,msg:1461 except getopt.error as msg: 1322 1462 sys.stderr.write("Error: %s\n" % str(msg)) 1323 1463 sys.stderr.write(usage_msg) … … 1372 1512 for dir in pathx: 1373 1513 dir = os.path.abspath(dir) 1374 if not dirin sys.path:1514 if dir not in sys.path: 1375 1515 sys.path.insert(0, dir) 1376 1516 else: … … 1382 1522 'editor-on-startup', type='bool') 1383 1523 enable_edit = enable_edit or edit_start 1384 enable_shell = enable_shell or not e dit_start1524 enable_shell = enable_shell or not enable_edit 1385 1525 # start editor and/or shell windows: 1386 1526 root = Tk(className="Idle") … … 1393 1533 if enable_edit: 1394 1534 if not (cmd or script): 1395 for filename in args: 1396 flist.open(filename) 1535 for filename in args[:]: 1536 if flist.open(filename) is None: 1537 # filename is a directory actually, disconsider it 1538 args.remove(filename) 1397 1539 if not args: 1398 1540 flist.new() … … 1430 1572 shell.interp.execfile(script) 1431 1573 1432 root.mainloop() 1574 # Check for problematic OS X Tk versions and print a warning message 1575 # in the IDLE shell window; this is less intrusive than always opening 1576 # a separate window. 1577 tkversionwarning = macosxSupport.tkVersionWarning(root) 1578 if tkversionwarning: 1579 shell.interp.runcommand(''.join(("print('", tkversionwarning, "')"))) 1580 1581 while flist.inversedict: # keep IDLE running while files are open. 1582 root.mainloop() 1433 1583 root.destroy() 1584 capture_warnings(False) 1434 1585 1435 1586 if __name__ == "__main__": 1436 1587 sys.modules['PyShell'] = sys.modules['__main__'] 1437 1588 main() 1589 1590 capture_warnings(False) # Make sure turned off; see issue 18081 -
python/trunk/Lib/idlelib/RemoteDebugger.py
r2 r391 22 22 23 23 import types 24 import rpc25 import Debugger24 from idlelib import rpc 25 from idlelib import Debugger 26 26 27 27 debugging = 0 … … 231 231 232 232 def _get_dict_proxy(self, did): 233 if self._dictcache.has_key(did):233 if did in self._dictcache: 234 234 return self._dictcache[did] 235 235 dp = DictProxy(self._conn, self._oid, did) -
python/trunk/Lib/idlelib/RemoteObjectBrowser.py
r2 r391 1 import rpc1 from idlelib import rpc 2 2 3 3 def remote_object_tree_item(item): -
python/trunk/Lib/idlelib/ReplaceDialog.py
r2 r391 1 1 from Tkinter import * 2 import SearchEngine 3 from SearchDialogBase import SearchDialogBase 2 3 from idlelib import SearchEngine 4 from idlelib.SearchDialogBase import SearchDialogBase 5 import re 6 4 7 5 8 def replace(text): … … 10 13 dialog = engine._replacedialog 11 14 dialog.open(text) 15 12 16 13 17 class ReplaceDialog(SearchDialogBase): … … 55 59 def default_command(self, event=None): 56 60 if self.do_find(self.ok): 57 self.do_replace() 58 self.do_find(0) 61 if self.do_replace(): # Only find next match if replace succeeded. 62 # A bad re can cause a it to fail. 63 self.do_find(0) 64 65 def _replace_expand(self, m, repl): 66 """ Helper function for expanding a regular expression 67 in the replace field, if needed. """ 68 if self.engine.isre(): 69 try: 70 new = m.expand(repl) 71 except re.error: 72 self.engine.report_error(repl, 'Invalid Replace Expression') 73 new = None 74 else: 75 new = repl 76 return new 59 77 60 78 def replace_all(self, event=None): … … 86 104 chars = text.get("%d.0" % line, "%d.0" % (line+1)) 87 105 orig = m.group() 88 new = m.expand(repl) 106 new = self._replace_expand(m, repl) 107 if new is None: 108 break 89 109 i, j = m.span() 90 110 first = "%d.%d" % (line, i) … … 138 158 if not prog: 139 159 return False 140 new = m.expand(self.replvar.get()) 160 new = self._replace_expand(m, self.replvar.get()) 161 if new is None: 162 return False 141 163 text.mark_set("insert", first) 142 164 text.undo_block_start() -
python/trunk/Lib/idlelib/ScriptBinding.py
r2 r391 24 24 import tokenize 25 25 import tkMessageBox 26 import PyShell 27 28 from configHandler import idleConf 26 from idlelib import PyShell 27 28 from idlelib.configHandler import idleConf 29 from idlelib import macosxSupport 29 30 30 31 IDENTCHARS = string.ascii_letters + string.digits + "_" … … 54 55 self.root = self.editwin.root 55 56 57 if macosxSupport.runningAsOSXApp(): 58 self.editwin.text_frame.bind('<<run-module-event-2>>', self._run_module_event) 59 56 60 def check_module_event(self, event): 57 61 filename = self.getfilename() … … 67 71 try: 68 72 tabnanny.process_tokens(tokenize.generate_tokens(f.readline)) 69 except tokenize.TokenError ,msg:73 except tokenize.TokenError as msg: 70 74 msgtxt, (lineno, start) = msg 71 75 self.editwin.gotoline(lineno) … … 73 77 "Token Error: %s" % msgtxt) 74 78 return False 75 except tabnanny.NannyNag ,nag:79 except tabnanny.NannyNag as nag: 76 80 # The error messages from tabnanny are too confusing... 77 81 self.editwin.gotoline(nag.get_lineno()) … … 84 88 saved_stream = shell.get_warning_stream() 85 89 shell.set_warning_stream(shell.stderr) 86 f = open(filename, 'r') 87 source = f.read() 88 f.close() 90 with open(filename, 'r') as f: 91 source = f.read() 89 92 if '\r' in source: 90 93 source = re.sub(r"\r\n", "\n", source) … … 98 101 # If successful, return the compiled code 99 102 return compile(source, filename, "exec") 100 except (SyntaxError, OverflowError ),err:103 except (SyntaxError, OverflowError, ValueError) as err: 101 104 try: 102 105 msg, (errorfilename, lineno, offset, line) = err … … 143 146 if not self.tabnanny(filename): 144 147 return 'break' 145 shell = self.shell 146 interp = shell.interp 148 interp = self.shell.interp 147 149 if PyShell.use_subprocess: 148 shell.restart_shell()150 interp.restart_subprocess(with_cwd=False) 149 151 dirname = os.path.dirname(filename) 150 152 # XXX Too often this discards arguments the user just set... 151 153 interp.runcommand("""if 1: 152 _ filename = %r154 __file__ = {filename!r} 153 155 import sys as _sys 154 156 from os.path import basename as _basename 155 157 if (not _sys.argv or 156 _basename(_sys.argv[0]) != _basename(_ filename)):157 _sys.argv = [_ filename]158 _basename(_sys.argv[0]) != _basename(__file__)): 159 _sys.argv = [__file__] 158 160 import os as _os 159 _os.chdir( %r)160 del _ filename, _sys, _basename, _os161 \n""" % (filename,dirname))161 _os.chdir({dirname!r}) 162 del _sys, _basename, _os 163 \n""".format(filename=filename, dirname=dirname)) 162 164 interp.prepend_syspath(filename) 163 165 # XXX KBK 03Jul04 When run w/o subprocess, runtime warnings still … … 166 168 interp.runcode(code) 167 169 return 'break' 170 171 if macosxSupport.runningAsOSXApp(): 172 # Tk-Cocoa in MacOSX is broken until at least 173 # Tk 8.5.9, and without this rather 174 # crude workaround IDLE would hang when a user 175 # tries to run a module using the keyboard shortcut 176 # (the menu item works fine). 177 _run_module_event = run_module_event 178 179 def run_module_event(self, event): 180 self.editwin.text_frame.after(200, 181 lambda: self.editwin.text_frame.event_generate('<<run-module-event-2>>')) 182 return 'break' 168 183 169 184 def getfilename(self): … … 185 200 self.editwin.io.save(None) 186 201 else: 187 reply= self.ask_save_dialog()202 confirm = self.ask_save_dialog() 188 203 self.editwin.text.focus_set() 189 if reply == "ok":204 if confirm: 190 205 self.editwin.io.save(None) 191 206 filename = self.editwin.io.filename … … 196 211 def ask_save_dialog(self): 197 212 msg = "Source Must Be Saved\n" + 5*' ' + "OK to Save?" 198 mb = tkMessageBox.Message(title="Save Before Run or Check", 199 message=msg, 200 icon=tkMessageBox.QUESTION, 201 type=tkMessageBox.OKCANCEL, 202 default=tkMessageBox.OK, 203 master=self.editwin.text) 204 return mb.show() 213 confirm = tkMessageBox.askokcancel(title="Save Before Run or Check", 214 message=msg, 215 default=tkMessageBox.OK, 216 master=self.editwin.text) 217 return confirm 205 218 206 219 def errorbox(self, title, message): -
python/trunk/Lib/idlelib/SearchDialog.py
r2 r391 1 1 from Tkinter import * 2 import SearchEngine3 from SearchDialogBase import SearchDialogBase4 2 3 from idlelib import SearchEngine 4 from idlelib.SearchDialogBase import SearchDialogBase 5 5 6 6 def _setup(text): … … 25 25 def create_widgets(self): 26 26 f = SearchDialogBase.create_widgets(self) 27 self.make_button("Find ", self.default_command, 1)27 self.make_button("Find Next", self.default_command, 1) 28 28 29 29 def default_command(self, event=None): 30 30 if not self.engine.getprog(): 31 31 return 32 if self.find_again(self.text): 33 self.close() 32 self.find_again(self.text) 34 33 35 34 def find_again(self, text): -
python/trunk/Lib/idlelib/SearchDialogBase.py
r2 r391 1 '''Define SearchDialogBase used by Search, Replace, and Grep dialogs.''' 1 2 from Tkinter import * 2 3 3 4 class SearchDialogBase: 5 '''Create most of a modal search dialog (make_frame, create_widgets). 6 7 The wide left column contains: 8 1 or 2 text entry lines (create_entries, make_entry); 9 a row of standard radiobuttons (create_option_buttons); 10 a row of dialog specific radiobuttons (create_other_buttons). 11 12 The narrow right column contains command buttons 13 (create_command_buttons, make_button). 14 These are bound to functions that execute the command. 15 16 Except for command buttons, this base class is not limited to 17 items common to all three subclasses. Rather, it is the Find dialog 18 minus the "Find Next" command and its execution function. 19 The other dialogs override methods to replace and add widgets. 20 ''' 4 21 5 22 title = "Search Dialog" -
python/trunk/Lib/idlelib/SearchEngine.py
r2 r391 1 '''Define SearchEngine for search dialogs.''' 1 2 import re 2 from Tkinter import *3 from Tkinter import StringVar, BooleanVar, TclError 3 4 import tkMessageBox 4 5 5 6 def get(root): 7 '''Return the singleton SearchEngine instance for the process. 8 9 The single SearchEngine saves settings between dialog instances. 10 If there is not a SearchEngine already, make one. 11 ''' 6 12 if not hasattr(root, "_searchengine"): 7 13 root._searchengine = SearchEngine(root) 8 # XXX This will never garbage-collect -- who cares14 # This creates a cycle that persists until root is deleted. 9 15 return root._searchengine 10 16 11 17 class SearchEngine: 18 """Handles searching a text widget for Find, Replace, and Grep.""" 12 19 13 20 def __init__(self, root): 14 self.root = root 15 # State shared by search, replace, and grep; 16 # the search dialogs bind these to UI elements. 17 self.patvar = StringVar(root) # search pattern 18 self.revar = BooleanVar(root) # regular expression? 19 self.casevar = BooleanVar(root) # match case? 20 self.wordvar = BooleanVar(root) # match whole word? 21 self.wrapvar = BooleanVar(root) # wrap around buffer? 22 self.wrapvar.set(1) # (on by default) 23 self.backvar = BooleanVar(root) # search backwards? 21 '''Initialize Variables that save search state. 22 23 The dialogs bind these to the UI elements present in the dialogs. 24 ''' 25 self.root = root # need for report_error() 26 self.patvar = StringVar(root, '') # search pattern 27 self.revar = BooleanVar(root, False) # regular expression? 28 self.casevar = BooleanVar(root, False) # match case? 29 self.wordvar = BooleanVar(root, False) # match whole word? 30 self.wrapvar = BooleanVar(root, True) # wrap around buffer? 31 self.backvar = BooleanVar(root, False) # search backwards? 24 32 25 33 # Access methods … … 48 56 # Higher level access methods 49 57 58 def setcookedpat(self, pat): 59 "Set pattern after escaping if re." 60 # called only in SearchDialog.py: 66 61 if self.isre(): 62 pat = re.escape(pat) 63 self.setpat(pat) 64 50 65 def getcookedpat(self): 51 66 pat = self.getpat() 52 if not self.isre(): 67 if not self.isre(): # if True, see setcookedpat 53 68 pat = re.escape(pat) 54 69 if self.isword(): … … 57 72 58 73 def getprog(self): 74 "Return compiled cooked search pattern." 59 75 pat = self.getpat() 60 76 if not pat: … … 67 83 try: 68 84 prog = re.compile(pat, flags) 69 except re.error ,what:85 except re.error as what: 70 86 try: 71 87 msg, col = what … … 78 94 79 95 def report_error(self, pat, msg, col=-1): 80 # Derived class could overrid this with something fancier96 # Derived class could override this with something fancier 81 97 msg = "Error: " + str(msg) 82 98 if pat: 83 msg = msg + "\n p\Pattern: " + str(pat)99 msg = msg + "\nPattern: " + str(pat) 84 100 if col >= 0: 85 101 msg = msg + "\nOffset: " + str(col) … … 87 103 msg, master=self.root) 88 104 89 def setcookedpat(self, pat):90 if self.isre():91 pat = re.escape(pat)92 self.setpat(pat)93 94 105 def search_text(self, text, prog=None, ok=0): 95 """Search a text widget for the pattern. 96 97 If prog is given, it should be the precompiled pattern. 98 Return a tuple (lineno, matchobj); None if not found. 99 100 This obeys the wrap and direction (back) settings. 101 102 The search starts at the selection (if there is one) or 103 at the insert mark (otherwise). If the search is forward, 104 it starts at the right of the selection; for a backward 105 search, it starts at the left end. An empty match exactly 106 at either end of the selection (or at the insert mark if 107 there is no selection) is ignored unless the ok flag is true 108 -- this is done to guarantee progress. 109 110 If the search is allowed to wrap around, it will return the 111 original selection if (and only if) it is the only match. 112 113 """ 106 '''Return (lineno, matchobj) or None for forward/backward search. 107 108 This function calls the right function with the right arguments. 109 It directly return the result of that call. 110 111 Text is a text widget. Prog is a precompiled pattern. 112 The ok parameteris a bit complicated as it has two effects. 113 114 If there is a selection, the search begin at either end, 115 depending on the direction setting and ok, with ok meaning that 116 the search starts with the selection. Otherwise, search begins 117 at the insert mark. 118 119 To aid progress, the search functions do not return an empty 120 match at the starting position unless ok is True. 121 ''' 122 114 123 if not prog: 115 124 prog = self.getprog() … … 180 189 return None 181 190 182 # Helper to search backwards in a string.183 # (Optimized for the case where the pattern isn't found.)184 185 191 def search_reverse(prog, chars, col): 192 '''Search backwards and return an re match object or None. 193 194 This is done by searching forwards until there is no match. 195 Prog: compiled re object with a search method returning a match. 196 Chars: line of text, without \n. 197 Col: stop index for the search; the limit for match.end(). 198 ''' 186 199 m = prog.search(chars) 187 200 if not m: 188 201 return None 189 202 found = None 190 i, j = m.span() 203 i, j = m.span() # m.start(), m.end() == match slice indexes 191 204 while i < col and j <= col: 192 205 found = m … … 199 212 return found 200 213 201 # Helper to get selection end points, defaulting to insert mark.202 # Return a tuple of indices ("line.col" strings).203 204 214 def get_selection(text): 215 '''Return tuple of 'line.col' indexes from selection or insert mark. 216 ''' 205 217 try: 206 218 first = text.index("sel.first") … … 214 226 return first, last 215 227 216 # Helper to parse a text index into a (line, col) tuple.217 218 228 def get_line_col(index): 229 '''Return (line, col) tuple of ints from 'line.col' string.''' 219 230 line, col = map(int, index.split(".")) # Fails on invalid index 220 231 return line, col 232 233 if __name__ == "__main__": 234 from test import support; support.use_resources = ['gui'] 235 import unittest 236 unittest.main('idlelib.idle_test.test_searchengine', verbosity=2, exit=False) -
python/trunk/Lib/idlelib/StackViewer.py
r2 r391 3 3 import linecache 4 4 5 from TreeWidget import TreeNode, TreeItem, ScrolledCanvas6 from ObjectBrowser import ObjectTreeItem, make_objecttreeitem5 from idlelib.TreeWidget import TreeNode, TreeItem, ScrolledCanvas 6 from idlelib.ObjectBrowser import ObjectTreeItem, make_objecttreeitem 7 7 8 8 def StackBrowser(root, flist=None, tb=None, top=None): -
python/trunk/Lib/idlelib/TreeWidget.py
r2 r391 19 19 import imp 20 20 21 import ZoomHeight22 from configHandler import idleConf21 from idlelib import ZoomHeight 22 from idlelib.configHandler import idleConf 23 23 24 24 ICONDIR = "Icons" … … 398 398 except os.error: 399 399 return [] 400 names.sort( lambda a, b: cmp(os.path.normcase(a), os.path.normcase(b)))400 names.sort(key = os.path.normcase) 401 401 sublist = [] 402 402 for name in names: … … 410 410 class ScrolledCanvas: 411 411 def __init__(self, master, **opts): 412 if not opts.has_key('yscrollincrement'):412 if 'yscrollincrement' not in opts: 413 413 opts['yscrollincrement'] = 17 414 414 self.master = master … … 453 453 454 454 def test(): 455 import PyShell455 from idlelib import PyShell 456 456 root = Toplevel(PyShell.root) 457 457 root.configure(bd=0, bg="yellow") -
python/trunk/Lib/idlelib/UndoDelegator.py
r2 r391 1 1 import string 2 2 from Tkinter import * 3 from Delegator import Delegator 3 4 from idlelib.Delegator import Delegator 4 5 5 6 #$ event <<redo>> … … 337 338 338 339 def main(): 339 from Percolator import Percolator340 from idlelib.Percolator import Percolator 340 341 root = Tk() 341 342 root.wm_protocol("WM_DELETE_WINDOW", root.quit) -
python/trunk/Lib/idlelib/ZoomHeight.py
r2 r391 3 3 import re 4 4 import sys 5 import macosxSupport 5 6 from idlelib import macosxSupport 6 7 7 8 class ZoomHeight: -
python/trunk/Lib/idlelib/aboutDialog.py
r2 r391 5 5 from Tkinter import * 6 6 import os 7 import os.path 8 import textView9 import idlever7 8 from idlelib import textView 9 from idlelib import idlever 10 10 11 11 class AboutDialog(Toplevel): … … 67 67 sys.version.split()[0], fg=self.fg, bg=self.bg) 68 68 labelPythonVer.grid(row=9, column=0, sticky=W, padx=10, pady=0) 69 # handle weird tk version num in windoze python >= 1.6 (?!?) 70 tkVer = repr(TkVersion).split('.') 71 tkVer[len(tkVer)-1] = str('%.3g' % (float('.'+tkVer[len(tkVer)-1])))[2:] 72 if tkVer[len(tkVer)-1] == '': 73 tkVer[len(tkVer)-1] = '0' 74 tkVer = '.'.join(tkVer) 69 tkVer = self.tk.call('info', 'patchlevel') 75 70 labelTkVer = Label(frameBg, text='Tk version: '+ 76 71 tkVer, fg=self.fg, bg=self.bg) … … 145 140 root = Tk() 146 141 def run(): 147 import aboutDialog142 from idlelib import aboutDialog 148 143 aboutDialog.AboutDialog(root, 'About') 149 144 Button(root, text='Dialog', command=run).pack() -
python/trunk/Lib/idlelib/config-extensions.def
r2 r391 47 47 [ScriptBinding] 48 48 enable=1 49 enable_shell=0 50 enable_editor=1 49 51 [ScriptBinding_cfgBindings] 50 52 run-module=<Key-F5> … … 87 89 [CodeContext_bindings] 88 90 toggle-code-context= 91 92 [RstripExtension] 93 enable=1 94 enable_shell=0 95 enable_editor=1 96 -
python/trunk/Lib/idlelib/config-keys.def
r2 r391 177 177 close-window = <Command-Key-w> 178 178 restart-shell = <Control-Key-F6> 179 save-window-as-file = < Command-Key-S>179 save-window-as-file = <Shift-Command-Key-S> 180 180 close-all-windows = <Command-Key-q> 181 181 view-restart = <Key-F6> … … 209 209 find-selection = <Shift-Command-Key-F3> 210 210 python-context-help = <Shift-Key-F1> 211 save-copy-of-window-as-file = < Shift-Command-Key-s>211 save-copy-of-window-as-file = <Option-Command-Key-s> 212 212 open-window-from-file = <Command-Key-o> 213 213 python-docs = <Key-F1> -
python/trunk/Lib/idlelib/configDialog.py
r2 r391 14 14 import string 15 15 16 from configHandler import idleConf17 from dynOptionMenuWidget import DynOptionMenu18 from tabbedpages import TabbedPageSet19 from keybindingDialog import GetKeysDialog20 from configSectionNameDialog import GetCfgSectionNameDialog21 from configHelpSourceEdit import GetHelpSourceDialog22 import macosxSupport16 from idlelib.configHandler import idleConf 17 from idlelib.dynOptionMenuWidget import DynOptionMenu 18 from idlelib.tabbedpages import TabbedPageSet 19 from idlelib.keybindingDialog import GetKeysDialog 20 from idlelib.configSectionNameDialog import GetCfgSectionNameDialog 21 from idlelib.configHelpSourceEdit import GetHelpSourceDialog 22 from idlelib import macosxSupport 23 23 24 24 class ConfigDialog(Toplevel): … … 29 29 30 30 self.configure(borderwidth=5) 31 self.title('IDLE Preferences') 31 32 self.geometry("+%d+%d" % (parent.winfo_rootx()+20, 32 33 parent.winfo_rooty()+30)) … … 183 184 #frameCustom 184 185 self.textHighlightSample=Text(frameCustom,relief=SOLID,borderwidth=1, 185 font=('courier',12,''),cursor='hand2',width=21,height=1 0,186 font=('courier',12,''),cursor='hand2',width=21,height=11, 186 187 takefocus=FALSE,highlightthickness=0,wrap=NONE) 187 188 text=self.textHighlightSample … … 562 563 def AddChangedItem(self,type,section,item,value): 563 564 value=str(value) #make sure we use a string 564 if not self.changedItems[type].has_key(section):565 if section not in self.changedItems[type]: 565 566 self.changedItems[type][section]={} 566 567 self.changedItems[type][section][item]=value … … 709 710 #remove key set from config 710 711 idleConf.userCfg['keys'].remove_section(keySetName) 711 if self.changedItems['keys'].has_key(keySetName):712 if keySetName in self.changedItems['keys']: 712 713 del(self.changedItems['keys'][keySetName]) 713 714 #write changes … … 736 737 #remove theme from config 737 738 idleConf.userCfg['highlight'].remove_section(themeName) 738 if self.changedItems['highlight'].has_key(themeName):739 if themeName in self.changedItems['highlight']: 739 740 del(self.changedItems['highlight'][themeName]) 740 741 #write changes … … 832 833 else: 833 834 fontWeight=tkFont.NORMAL 834 self.editFont.config(size=self.fontSize.get(), 835 weight=fontWeight,family=fontName) 835 newFont = (fontName, self.fontSize.get(), fontWeight) 836 self.labelFontSample.config(font=newFont) 837 self.textHighlightSample.configure(font=newFont) 836 838 837 839 def SetHighlightTarget(self): … … 871 873 if theme in self.changedItems['highlight'].keys(): 872 874 themeDict=self.changedItems['highlight'][theme] 873 if themeDict.has_key(element+'-foreground'):875 if element+'-foreground' in themeDict: 874 876 colours['foreground']=themeDict[element+'-foreground'] 875 if themeDict.has_key(element+'-background'):877 if element+'-background' in themeDict: 876 878 colours['background']=themeDict[element+'-background'] 877 879 self.textHighlightSample.tag_config(element, **colours) … … 946 948 ##font size dropdown 947 949 fontSize=idleConf.GetOption('main','EditorWindow','font-size', 948 default='10')950 type='int', default='10') 949 951 self.optMenuFontSize.SetMenu(('7','8','9','10','11','12','13','14', 950 952 '16','18','20','22'),fontSize ) … … 989 991 ##load theme element option menu 990 992 themeNames=self.themeElements.keys() 991 themeNames.sort( self.__ThemeNameIndexCompare)993 themeNames.sort(key=lambda x: self.themeElements[x][1]) 992 994 self.optMenuHighlightTarget.SetMenu(themeNames,themeNames[0]) 993 995 self.PaintThemeSample() 994 996 self.SetHighlightTarget() 995 996 def __ThemeNameIndexCompare(self,a,b):997 if self.themeElements[a][1]<self.themeElements[b][1]: return -1998 elif self.themeElements[a][1]==self.themeElements[b][1]: return 0999 else: return 11000 997 1001 998 def LoadKeyCfg(self): … … 1037 1034 default=0, type='bool')) 1038 1035 #initial window size 1039 self.winWidth.set(idleConf.GetOption('main','EditorWindow','width')) 1040 self.winHeight.set(idleConf.GetOption('main','EditorWindow','height')) 1036 self.winWidth.set(idleConf.GetOption('main','EditorWindow','width', 1037 type='int')) 1038 self.winHeight.set(idleConf.GetOption('main','EditorWindow','height', 1039 type='int')) 1041 1040 #initial paragraph reformat size 1042 self.paraWidth.set(idleConf.GetOption('main','FormatParagraph','paragraph')) 1041 self.paraWidth.set(idleConf.GetOption('main','FormatParagraph','paragraph', 1042 type='int')) 1043 1043 # default source encoding 1044 1044 self.encoding.set(idleConf.GetOption('main', 'EditorWindow', -
python/trunk/Lib/idlelib/configHandler.py
r2 r391 21 21 import sys 22 22 import string 23 import macosxSupport23 from idlelib import macosxSupport 24 24 from ConfigParser import ConfigParser, NoOptionError, NoSectionError 25 25 … … 238 238 239 239 """ 240 if self.userCfg[configType].has_option(section,option): 241 return self.userCfg[configType].Get(section, option, 242 type=type, raw=raw) 243 elif self.defaultCfg[configType].has_option(section,option): 244 return self.defaultCfg[configType].Get(section, option, 245 type=type, raw=raw) 246 else: #returning default, print warning 247 if warn_on_default: 248 warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n' 249 ' problem retrieving configration option %r\n' 250 ' from section %r.\n' 251 ' returning default value: %r\n' % 252 (option, section, default)) 253 try: 254 sys.stderr.write(warning) 255 except IOError: 256 pass 257 return default 240 try: 241 if self.userCfg[configType].has_option(section,option): 242 return self.userCfg[configType].Get(section, option, 243 type=type, raw=raw) 244 except ValueError: 245 warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n' 246 ' invalid %r value for configuration option %r\n' 247 ' from section %r: %r\n' % 248 (type, option, section, 249 self.userCfg[configType].Get(section, option, 250 raw=raw))) 251 try: 252 sys.stderr.write(warning) 253 except IOError: 254 pass 255 try: 256 if self.defaultCfg[configType].has_option(section,option): 257 return self.defaultCfg[configType].Get(section, option, 258 type=type, raw=raw) 259 except ValueError: 260 pass 261 #returning default, print warning 262 if warn_on_default: 263 warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n' 264 ' problem retrieving configuration option %r\n' 265 ' from section %r.\n' 266 ' returning default value: %r\n' % 267 (option, section, default)) 268 try: 269 sys.stderr.write(warning) 270 except IOError: 271 pass 272 return default 258 273 259 274 def SetOption(self, configType, section, option, value): … … 596 611 '<<goto-line>>': ['<Alt-g>'], 597 612 '<<smart-backspace>>': ['<Key-BackSpace>'], 598 '<<newline-and-indent>>': ['<Key-Return> 613 '<<newline-and-indent>>': ['<Key-Return>', '<Key-KP_Enter>'], 599 614 '<<smart-indent>>': ['<Key-Tab>'], 600 615 '<<indent-region>>': ['<Control-Key-bracketright>'], … … 655 670 if menuItem and helpPath: #neither are empty strings 656 671 helpSources.append( (menuItem,helpPath,option) ) 657 helpSources.sort( self.__helpsort)672 helpSources.sort(key=lambda x: int(x[2])) 658 673 return helpSources 659 660 def __helpsort(self, h1, h2):661 if int(h1[2]) < int(h2[2]):662 return -1663 elif int(h1[2]) > int(h2[2]):664 return 1665 else:666 return 0667 674 668 675 def GetAllExtraHelpSourcesList(self): -
python/trunk/Lib/idlelib/configSectionNameDialog.py
r2 r391 2 2 Dialog that allows user to specify a new config file section name. 3 3 Used to get new highlight theme and keybinding set names. 4 The 'return value' for the dialog, used two placed in configDialog.py, 5 is the .result attribute set in the Ok and Cancel methods. 4 6 """ 5 7 from Tkinter import * 6 8 import tkMessageBox 7 8 9 class GetCfgSectionNameDialog(Toplevel): 9 def __init__(self, parent,title,message,usedNames):10 def __init__(self, parent, title, message, used_names): 10 11 """ 11 12 message - string, informational message to display 12 used Names - list, list ofnames already in use for validity check13 used_names - string collection, names already in use for validity check 13 14 """ 14 15 Toplevel.__init__(self, parent) 15 16 self.configure(borderwidth=5) 16 self.resizable(height=FALSE, width=FALSE)17 self.resizable(height=FALSE, width=FALSE) 17 18 self.title(title) 18 19 self.transient(parent) … … 20 21 self.protocol("WM_DELETE_WINDOW", self.Cancel) 21 22 self.parent = parent 22 self.message=message 23 self.usedNames=usedNames 24 self.result='' 25 self.CreateWidgets() 26 self.withdraw() #hide while setting geometry 23 self.message = message 24 self.used_names = used_names 25 self.create_widgets() 26 self.withdraw() #hide while setting geometry 27 27 self.update_idletasks() 28 28 #needs to be done here so that the winfo_reqwidth is valid 29 29 self.messageInfo.config(width=self.frameMain.winfo_reqwidth()) 30 self.geometry("+%d+%d" % 31 ((parent.winfo_rootx()+((parent.winfo_width()/2) 32 -(self.winfo_reqwidth()/2)), 33 parent.winfo_rooty()+((parent.winfo_height()/2) 34 -(self.winfo_reqheight()/2)) )) ) #centre dialog over parent 35 self.deiconify() #geometry set, unhide 30 self.geometry( 31 "+%d+%d" % ( 32 parent.winfo_rootx() + 33 (parent.winfo_width()/2 - self.winfo_reqwidth()/2), 34 parent.winfo_rooty() + 35 (parent.winfo_height()/2 - self.winfo_reqheight()/2) 36 ) ) #centre dialog over parent 37 self.deiconify() #geometry set, unhide 36 38 self.wait_window() 39 def create_widgets(self): 40 self.name = StringVar(self.parent) 41 self.fontSize = StringVar(self.parent) 42 self.frameMain = Frame(self, borderwidth=2, relief=SUNKEN) 43 self.frameMain.pack(side=TOP, expand=TRUE, fill=BOTH) 44 self.messageInfo = Message(self.frameMain, anchor=W, justify=LEFT, 45 padx=5, pady=5, text=self.message) #,aspect=200) 46 entryName = Entry(self.frameMain, textvariable=self.name, width=30) 47 entryName.focus_set() 48 self.messageInfo.pack(padx=5, pady=5) #, expand=TRUE, fill=BOTH) 49 entryName.pack(padx=5, pady=5) 50 frameButtons = Frame(self, pady=2) 51 frameButtons.pack(side=BOTTOM) 52 self.buttonOk = Button(frameButtons, text='Ok', 53 width=8, command=self.Ok) 54 self.buttonOk.pack(side=LEFT, padx=5) 55 self.buttonCancel = Button(frameButtons, text='Cancel', 56 width=8, command=self.Cancel) 57 self.buttonCancel.pack(side=RIGHT, padx=5) 37 58 38 def CreateWidgets(self): 39 self.name=StringVar(self) 40 self.fontSize=StringVar(self) 41 self.frameMain = Frame(self,borderwidth=2,relief=SUNKEN) 42 self.frameMain.pack(side=TOP,expand=TRUE,fill=BOTH) 43 self.messageInfo=Message(self.frameMain,anchor=W,justify=LEFT,padx=5,pady=5, 44 text=self.message)#,aspect=200) 45 entryName=Entry(self.frameMain,textvariable=self.name,width=30) 46 entryName.focus_set() 47 self.messageInfo.pack(padx=5,pady=5)#,expand=TRUE,fill=BOTH) 48 entryName.pack(padx=5,pady=5) 49 frameButtons=Frame(self) 50 frameButtons.pack(side=BOTTOM,fill=X) 51 self.buttonOk = Button(frameButtons,text='Ok', 52 width=8,command=self.Ok) 53 self.buttonOk.grid(row=0,column=0,padx=5,pady=5) 54 self.buttonCancel = Button(frameButtons,text='Cancel', 55 width=8,command=self.Cancel) 56 self.buttonCancel.grid(row=0,column=1,padx=5,pady=5) 57 58 def NameOk(self): 59 #simple validity check for a sensible 60 #ConfigParser file section name 61 nameOk=1 62 name=self.name.get() 63 name.strip() 59 def name_ok(self): 60 ''' After stripping entered name, check that it is a sensible 61 ConfigParser file section name. Return it if it is, '' if not. 62 ''' 63 name = self.name.get().strip() 64 64 if not name: #no name specified 65 65 tkMessageBox.showerror(title='Name Error', 66 66 message='No name specified.', parent=self) 67 nameOk=068 67 elif len(name)>30: #name too long 69 68 tkMessageBox.showerror(title='Name Error', 70 69 message='Name too long. It should be no more than '+ 71 70 '30 characters.', parent=self) 72 name Ok=073 elif name in self.used Names:71 name = '' 72 elif name in self.used_names: 74 73 tkMessageBox.showerror(title='Name Error', 75 74 message='This name is already in use.', parent=self) 76 nameOk=0 77 return nameOk 75 name = '' 76 return name 77 def Ok(self, event=None): 78 name = self.name_ok() 79 if name: 80 self.result = name 81 self.destroy() 82 def Cancel(self, event=None): 83 self.result = '' 84 self.destroy() 85 if __name__ == '__main__': 86 import unittest 87 unittest.main('idlelib.idle_test.test_config_name', verbosity=2, exit=False) 78 88 79 def Ok(self, event=None): 80 if self.NameOk(): 81 self.result=self.name.get().strip() 82 self.destroy() 83 84 def Cancel(self, event=None): 85 self.result='' 86 self.destroy() 87 88 if __name__ == '__main__': 89 #test the dialog 90 root=Tk() 89 # also human test the dialog 90 root = Tk() 91 91 def run(): 92 keySeq=''93 92 dlg=GetCfgSectionNameDialog(root,'Get Name', 94 'The information here should need to be word wrapped. Test.') 93 "After the text entered with [Ok] is stripped, <nothing>, " 94 "'abc', or more that 30 chars are errors. " 95 "Close with a valid entry (printed), [Cancel], or [X]", 96 {'abc'}) 95 97 print dlg.result 96 Button(root,text='Dialog',command=run).pack() 98 Message(root, text='').pack() # will be needed for oher dialog tests 99 Button(root, text='Click to begin dialog test', command=run).pack() 97 100 root.mainloop() -
python/trunk/Lib/idlelib/extend.txt
r2 r391 19 19 An IDLE extension class is instantiated with a single argument, 20 20 `editwin', an EditorWindow instance. The extension cannot assume much 21 about this argument, but it is guara teed to have the following instance21 about this argument, but it is guaranteed to have the following instance 22 22 variables: 23 23 … … 55 55 case there must be empty bindings in cofig-extensions.def) 56 56 57 Here is a complete example example:57 Here is a complete example: 58 58 59 59 class ZoomHeight: … … 73 73 74 74 The final piece of the puzzle is the file "config-extensions.def", which is 75 used to toconfigure the loading of extensions and to establish key (or, more75 used to configure the loading of extensions and to establish key (or, more 76 76 generally, event) bindings to the virtual events defined in the extensions. 77 77 -
python/trunk/Lib/idlelib/help.txt
r2 r391 6 6 File Menu: 7 7 8 New Window-- Create a new editing window8 New File -- Create a new editing window 9 9 Open... -- Open an existing file 10 10 Recent Files... -- Open a list of recent files … … 81 81 82 82 Go to File/Line -- look around the insert point for a filename 83 and line number, open the file, and show the line83 and line number, open the file, and show the line 84 84 Debugger (toggle) -- Run commands in the shell under the debugger 85 85 Stack Viewer -- Show the stack traceback of the last exception … … 93 93 Sources can be specified. 94 94 95 On MacOS X this menu is not present, use95 On OS X this menu is not present, use 96 96 menu 'IDLE -> Preferences...' instead. 97 97 --- … … 120 120 --- 121 121 (Additional Help Sources may be added here) 122 123 Edit context menu (Right-click / Control-click on OS X in Edit window): 124 125 Cut -- Copy a selection into system-wide clipboard, 126 then delete the selection 127 Copy -- Copy selection into system-wide clipboard 128 Paste -- Insert system-wide clipboard into window 129 Set Breakpoint -- Sets a breakpoint (when debugger open) 130 Clear Breakpoint -- Clears the breakpoint on that line 131 132 Shell context menu (Right-click / Control-click on OS X in Shell window): 133 134 Cut -- Copy a selection into system-wide clipboard, 135 then delete the selection 136 Copy -- Copy selection into system-wide clipboard 137 Paste -- Insert system-wide clipboard into window 138 --- 139 Go to file/line -- Same as in Debug menu 122 140 123 141 … … 216 234 217 235 Control-c interrupts executing command. 218 Control-d sends end-of-file; closes window if typed at >>> prompt 219 (this is Control-z on Windows). 236 Control-d sends end-of-file; closes window if typed at >>> prompt. 220 237 221 238 Command history: … … 223 240 Alt-p retrieves previous command matching what you have typed. 224 241 Alt-n retrieves next. 225 (These are Control-p, Control-n on the Mac)242 (These are Control-p, Control-n on OS X) 226 243 Return while cursor is on a previous command retrieves that command. 227 244 Expand word is also useful to reduce typing. -
python/trunk/Lib/idlelib/idle.bat
r2 r391 1 1 @echo off 2 rem Working IDLE bat for Windows - uses start instead of absolute pathname 3 start idle.pyw %1 %2 %3 %4 %5 %6 %7 %8 %9 2 rem Start IDLE using the appropriate Python interpreter 3 set CURRDIR=%~dp0 4 start "IDLE" "%CURRDIR%..\..\pythonw.exe" "%CURRDIR%idle.pyw" %1 %2 %3 %4 %5 %6 %7 %8 %9 -
python/trunk/Lib/idlelib/idle.py
r2 r391 1 try: 2 import idlelib.PyShell 3 except ImportError: 4 # IDLE is not installed, but maybe PyShell is on sys.path: 5 try: 6 import PyShell 7 except ImportError: 8 raise 9 else: 10 import os 11 idledir = os.path.dirname(os.path.abspath(PyShell.__file__)) 12 if idledir != os.getcwd(): 13 # We're not in the IDLE directory, help the subprocess find run.py 14 pypath = os.environ.get('PYTHONPATH', '') 15 if pypath: 16 os.environ['PYTHONPATH'] = pypath + ':' + idledir 17 else: 18 os.environ['PYTHONPATH'] = idledir 19 PyShell.main() 20 else: 21 idlelib.PyShell.main() 1 import os.path 2 import sys 3 4 # If we are working on a development version of IDLE, we need to prepend the 5 # parent of this idlelib dir to sys.path. Otherwise, importing idlelib gets 6 # the version installed with the Python used to call this module: 7 idlelib_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 8 sys.path.insert(0, idlelib_dir) 9 10 import idlelib.PyShell 11 idlelib.PyShell.main() -
python/trunk/Lib/idlelib/idlever.py
r2 r391 1 IDLE_VERSION = "2. 6.5"1 IDLE_VERSION = "2.7.6" -
python/trunk/Lib/idlelib/keybindingDialog.py
r2 r391 133 133 config-keys.def must use the same ordering. 134 134 """ 135 import macosxSupport135 from idlelib import macosxSupport 136 136 if macosxSupport.runningAsOSXApp(): 137 137 self.modifiers = ['Shift', 'Control', 'Option', 'Command'] … … 168 168 def GetModifiers(self): 169 169 modList = [variable.get() for variable in self.modifier_vars] 170 return filter(None, modList)170 return [mod for mod in modList if mod] 171 171 172 172 def ClearKeySeq(self): -
python/trunk/Lib/idlelib/macosxSupport.py
r2 r391 5 5 import sys 6 6 import Tkinter 7 from os import path 8 9 10 _appbundle = None 7 11 8 12 def runningAsOSXApp(): … … 10 14 Returns True if Python is running from within an app on OSX. 11 15 If so, assume that Python was built with Aqua Tcl/Tk rather than 12 X11 Tc k/Tk.16 X11 Tcl/Tk. 13 17 """ 14 return (sys.platform == 'darwin' and '.app' in sys.executable) 18 global _appbundle 19 if _appbundle is None: 20 _appbundle = (sys.platform == 'darwin' and '.app' in sys.executable) 21 return _appbundle 22 23 _carbonaquatk = None 24 25 def isCarbonAquaTk(root): 26 """ 27 Returns True if IDLE is using a Carbon Aqua Tk (instead of the 28 newer Cocoa Aqua Tk). 29 """ 30 global _carbonaquatk 31 if _carbonaquatk is None: 32 _carbonaquatk = (runningAsOSXApp() and 33 'aqua' in root.tk.call('tk', 'windowingsystem') and 34 'AppKit' not in root.tk.call('winfo', 'server', '.')) 35 return _carbonaquatk 36 37 def tkVersionWarning(root): 38 """ 39 Returns a string warning message if the Tk version in use appears to 40 be one known to cause problems with IDLE. 41 1. Apple Cocoa-based Tk 8.5.7 shipped with Mac OS X 10.6 is unusable. 42 2. Apple Cocoa-based Tk 8.5.9 in OS X 10.7 and 10.8 is better but 43 can still crash unexpectedly. 44 """ 45 46 if (runningAsOSXApp() and 47 ('AppKit' in root.tk.call('winfo', 'server', '.')) ): 48 patchlevel = root.tk.call('info', 'patchlevel') 49 if patchlevel not in ('8.5.7', '8.5.9'): 50 return False 51 return (r"WARNING: The version of Tcl/Tk ({0}) in use may" 52 r" be unstable.\n" 53 r"Visit http://www.python.org/download/mac/tcltk/" 54 r" for current information.".format(patchlevel)) 55 else: 56 return False 15 57 16 58 def addOpenEventSupport(root, flist): 17 59 """ 18 This ensures that the application will respon tto open AppleEvents, which19 makes is feas eable to use IDLE as the default application for python files.60 This ensures that the application will respond to open AppleEvents, which 61 makes is feasible to use IDLE as the default application for python files. 20 62 """ 21 63 def doOpenFile(*args): … … 52 94 # menu. 53 95 from Tkinter import Menu, Text, Text 54 from EditorWindow import prepstr, get_accelerator55 import Bindings56 import WindowList57 from MultiCall import MultiCallCreator96 from idlelib.EditorWindow import prepstr, get_accelerator 97 from idlelib import Bindings 98 from idlelib import WindowList 99 from idlelib.MultiCall import MultiCallCreator 58 100 59 101 menubar = Menu(root) … … 74 116 WindowList.register_callback(postwindowsmenu) 75 117 76 menudict['application'] = menu = Menu(menubar, name='apple')77 menubar.add_cascade(label='IDLE', menu=menu)78 79 118 def about_dialog(event=None): 80 import aboutDialog119 from idlelib import aboutDialog 81 120 aboutDialog.AboutDialog(root, 'About IDLE') 82 121 83 122 def config_dialog(event=None): 84 import configDialog123 from idlelib import configDialog 85 124 root.instance_dict = flist.inversedict 86 125 configDialog.ConfigDialog(root, 'Settings') 87 126 127 def help_dialog(event=None): 128 from idlelib import textView 129 fn = path.join(path.abspath(path.dirname(__file__)), 'help.txt') 130 textView.view_file(root, 'Help', fn) 88 131 89 132 root.bind('<<about-idle>>', about_dialog) 90 133 root.bind('<<open-config-dialog>>', config_dialog) 134 root.createcommand('::tk::mac::ShowPreferences', config_dialog) 91 135 if flist: 92 136 root.bind('<<close-all-windows>>', flist.close_all_callback) 93 137 138 # The binding above doesn't reliably work on all versions of Tk 139 # on MacOSX. Adding command definition below does seem to do the 140 # right thing for now. 141 root.createcommand('exit', flist.close_all_callback) 94 142 95 ###check if Tk version >= 8.4.14; if so, use hard-coded showprefs binding96 tkversion = root.tk.eval('info patchlevel')97 # Note: we cannot check if the string tkversion >= '8.4.14', because98 # the string '8.4.7' is greater than the string '8.4.14'.99 if tuple(map(int, tkversion.split('.'))) >= (8, 4, 14):100 Bindings.menudefs[0] =('application', [143 if isCarbonAquaTk(root): 144 # for Carbon AquaTk, replace the default Tk apple menu 145 menudict['application'] = menu = Menu(menubar, name='apple') 146 menubar.add_cascade(label='IDLE', menu=menu) 147 Bindings.menudefs.insert(0, 148 ('application', [ 101 149 ('About IDLE', '<<about-idle>>'), 102 None, 103 ]) 104 root.createcommand('::tk::mac::ShowPreferences', config_dialog) 150 None, 151 ])) 152 tkversion = root.tk.eval('info patchlevel') 153 if tuple(map(int, tkversion.split('.'))) < (8, 4, 14): 154 # for earlier AquaTk versions, supply a Preferences menu item 155 Bindings.menudefs[0][1].append( 156 ('_Preferences....', '<<open-config-dialog>>'), 157 ) 105 158 else: 106 for mname, entrylist in Bindings.menudefs: 107 menu = menudict.get(mname) 108 if not menu: 109 continue 110 else: 111 for entry in entrylist: 112 if not entry: 113 menu.add_separator() 114 else: 115 label, eventname = entry 116 underline, label = prepstr(label) 117 accelerator = get_accelerator(Bindings.default_keydefs, 118 eventname) 119 def command(text=root, eventname=eventname): 120 text.event_generate(eventname) 121 menu.add_command(label=label, underline=underline, 122 command=command, accelerator=accelerator) 159 # assume Cocoa AquaTk 160 # replace default About dialog with About IDLE one 161 root.createcommand('tkAboutDialog', about_dialog) 162 # replace default "Help" item in Help menu 163 root.createcommand('::tk::mac::ShowHelp', help_dialog) 164 # remove redundant "IDLE Help" from menu 165 del Bindings.menudefs[-1][1][0] 123 166 124 167 def setupApp(root, flist): -
python/trunk/Lib/idlelib/rpc.py
r2 r391 3 3 For security reasons, GvR requested that Idle's Python execution server process 4 4 connect to the Idle process, which listens for the connection. Since Idle has 5 hasonly one client per server, this was not a limitation.5 only one client per server, this was not a limitation. 6 6 7 7 +---------------------------------+ +-------------+ … … 145 145 def exithook(self): 146 146 "override for specific exit action" 147 os._exit( )147 os._exit(0) 148 148 149 149 def debug(self, *args): … … 170 170 except TypeError: 171 171 return ("ERROR", "Bad request format") 172 if not self.objtable.has_key(oid):172 if oid not in self.objtable: 173 173 return ("ERROR", "Unknown object id: %r" % (oid,)) 174 174 obj = self.objtable[oid] … … 305 305 cvar = self.cvars[myseq] 306 306 cvar.acquire() 307 while not self.responses.has_key(myseq):307 while myseq not in self.responses: 308 308 cvar.wait() 309 309 response = self.responses[myseq] … … 519 519 def __init__(self, address, family=socket.AF_INET, type=socket.SOCK_STREAM): 520 520 self.listening_sock = socket.socket(family, type) 521 self.listening_sock.setsockopt(socket.SOL_SOCKET,522 socket.SO_REUSEADDR, 1)523 521 self.listening_sock.bind(address) 524 522 self.listening_sock.listen(1) … … 553 551 if self.__attributes is None: 554 552 self.__getattributes() 555 if self.__attributes.has_key(name):553 if name in self.__attributes: 556 554 value = self.sockio.remotecall(self.oid, '__getattribute__', 557 555 (name,), {}) … … 573 571 for name in dir(obj): 574 572 attr = getattr(obj, name) 575 if callable(attr):573 if hasattr(attr, '__call__'): 576 574 methods[name] = 1 577 575 if type(obj) == types.InstanceType: … … 584 582 for name in dir(obj): 585 583 attr = getattr(obj, name) 586 if not callable(attr):584 if not hasattr(attr, '__call__'): 587 585 attributes[name] = 1 588 586 … … 600 598 601 599 # XXX KBK 09Sep03 We need a proper unit test for this module. Previously 602 # existing test code was removed at Rev 1.27 .600 # existing test code was removed at Rev 1.27 (r34098). -
python/trunk/Lib/idlelib/run.py
r2 r391 1 1 import sys 2 import io 2 3 import linecache 3 4 import time … … 8 9 import Queue 9 10 10 import CallTips 11 import AutoComplete 12 13 import RemoteDebugger 14 import RemoteObjectBrowser 15 import StackViewer 16 import rpc 11 from idlelib import CallTips 12 from idlelib import AutoComplete 13 14 from idlelib import RemoteDebugger 15 from idlelib import RemoteObjectBrowser 16 from idlelib import StackViewer 17 from idlelib import rpc 18 from idlelib import PyShell 19 from idlelib import IOBinding 17 20 18 21 import __main__ … … 20 23 LOCALHOST = '127.0.0.1' 21 24 22 try: 23 import warnings 24 except ImportError: 25 pass 26 else: 27 def idle_formatwarning_subproc(message, category, filename, lineno, 28 file=None, line=None): 29 """Format warnings the IDLE way""" 30 s = "\nWarning (from warnings module):\n" 31 s += ' File \"%s\", line %s\n' % (filename, lineno) 32 line = linecache.getline(filename, lineno).strip() \ 33 if line is None else line 34 if line: 35 s += " %s\n" % line 36 s += "%s: %s\n" % (category.__name__, message) 37 return s 38 warnings.formatwarning = idle_formatwarning_subproc 25 import warnings 26 27 def idle_showwarning_subproc( 28 message, category, filename, lineno, file=None, line=None): 29 """Show Idle-format warning after replacing warnings.showwarning. 30 31 The only difference is the formatter called. 32 """ 33 if file is None: 34 file = sys.stderr 35 try: 36 file.write(PyShell.idle_formatwarning( 37 message, category, filename, lineno, line)) 38 except IOError: 39 pass # the file (probably stderr) is invalid - this warning gets lost. 40 41 _warnings_showwarning = None 42 43 def capture_warnings(capture): 44 "Replace warning.showwarning with idle_showwarning_subproc, or reverse." 45 46 global _warnings_showwarning 47 if capture: 48 if _warnings_showwarning is None: 49 _warnings_showwarning = warnings.showwarning 50 warnings.showwarning = idle_showwarning_subproc 51 else: 52 if _warnings_showwarning is not None: 53 warnings.showwarning = _warnings_showwarning 54 _warnings_showwarning = None 55 56 capture_warnings(True) 39 57 40 58 # Thread shared globals: Establish a queue between a subthread (which handles … … 68 86 global no_exitfunc 69 87 no_exitfunc = del_exitfunc 70 port = 883371 88 #time.sleep(15) # test subprocess not responding 72 if sys.argv[1:]: 73 port = int(sys.argv[1]) 89 try: 90 assert(len(sys.argv) > 1) 91 port = int(sys.argv[-1]) 92 except: 93 print>>sys.stderr, "IDLE Subprocess: no IP port passed in sys.argv." 94 return 95 96 capture_warnings(True) 74 97 sys.argv[:] = [""] 75 98 sockthread = threading.Thread(target=manage_socket, … … 98 121 continue 99 122 except SystemExit: 123 capture_warnings(False) 100 124 raise 101 125 except: … … 117 141 server = MyRPCServer(address, MyHandler) 118 142 break 119 except socket.error ,err:143 except socket.error as err: 120 144 print>>sys.__stderr__,"IDLE Subprocess: socket error: "\ 121 + err [1] + ", retrying...."145 + err.args[1] + ", retrying...." 122 146 else: 123 147 print>>sys.__stderr__, "IDLE Subprocess: Connection to "\ … … 134 158 root = Tkinter.Tk() 135 159 root.withdraw() 136 if err [0] == 61: # connection refused160 if err.args[0] == 61: # connection refused 137 161 msg = "IDLE's subprocess can't connect to %s:%d. This may be due "\ 138 162 "to your personal firewall configuration. It is safe to "\ … … 141 165 tkMessageBox.showerror("IDLE Subprocess Error", msg, parent=root) 142 166 else: 143 tkMessageBox.showerror("IDLE Subprocess Error", "Socket Error: %s" % err[1]) 167 tkMessageBox.showerror("IDLE Subprocess Error", 168 "Socket Error: %s" % err.args[1]) 144 169 root.destroy() 145 170 … … 212 237 except AttributeError: 213 238 pass 239 capture_warnings(False) 214 240 sys.exit(0) 215 241 … … 244 270 thread.interrupt_main() 245 271 246 247 272 class MyHandler(rpc.RPCHandler): 248 273 … … 251 276 executive = Executive(self) 252 277 self.register("exec", executive) 253 sys.stdin = self.console = self.get_remote_proxy("stdin") 254 sys.stdout = self.get_remote_proxy("stdout") 255 sys.stderr = self.get_remote_proxy("stderr") 256 import IOBinding 257 sys.stdin.encoding = sys.stdout.encoding = \ 258 sys.stderr.encoding = IOBinding.encoding 278 self.console = self.get_remote_proxy("console") 279 sys.stdin = PyShell.PseudoInputFile(self.console, "stdin", 280 IOBinding.encoding) 281 sys.stdout = PyShell.PseudoOutputFile(self.console, "stdout", 282 IOBinding.encoding) 283 sys.stderr = PyShell.PseudoOutputFile(self.console, "stderr", 284 IOBinding.encoding) 285 286 # Keep a reference to stdin so that it won't try to exit IDLE if 287 # sys.stdin gets changed from within IDLE's shell. See issue17838. 288 self._keep_stdin = sys.stdin 289 259 290 self.interp = self.get_remote_proxy("interp") 260 291 rpc.RPCHandler.getresponse(self, myseq=None, wait=0.05) … … 294 325 finally: 295 326 interruptable = False 327 except SystemExit: 328 # Scripts that raise SystemExit should just 329 # return to the interactive prompt 330 pass 296 331 except: 297 332 self.usr_exc_info = sys.exc_info() 298 333 if quitting: 299 334 exit() 300 # even print a user code SystemExit exception, continue301 335 print_exception() 302 336 jit = self.rpchandler.console.getvar("<<toggle-jit-stack-viewer>>") … … 337 371 item = StackViewer.StackTreeItem(flist, tb) 338 372 return RemoteObjectBrowser.remote_object_tree_item(item) 373 374 capture_warnings(False) # Make sure turned off; see issue 18081 -
python/trunk/Lib/idlelib/textView.py
r2 r391 10 10 11 11 """ 12 def __init__(self, parent, title, text ):12 def __init__(self, parent, title, text, modal=True): 13 13 """Show the given text in a scrollable window with a 'close' button 14 14 … … 25 25 self.CreateWidgets() 26 26 self.title(title) 27 self.transient(parent)28 self.grab_set()29 27 self.protocol("WM_DELETE_WINDOW", self.Ok) 30 28 self.parent = parent … … 35 33 self.textView.insert(0.0, text) 36 34 self.textView.config(state=DISABLED) 37 self.wait_window() 35 36 if modal: 37 self.transient(parent) 38 self.grab_set() 39 self.wait_window() 38 40 39 41 def CreateWidgets(self): … … 58 60 59 61 60 def view_text(parent, title, text ):61 TextViewer(parent, title, text)62 def view_text(parent, title, text, modal=True): 63 return TextViewer(parent, title, text, modal) 62 64 63 def view_file(parent, title, filename, encoding=None ):65 def view_file(parent, title, filename, encoding=None, modal=True): 64 66 try: 65 67 if encoding: … … 74 76 parent=parent) 75 77 else: 76 return view_text(parent, title, textFile.read() )78 return view_text(parent, title, textFile.read(), modal) 77 79 78 80 … … 84 86 text = file(filename, 'r').read() 85 87 btn1 = Button(root, text='view_text', 86 command=lambda:view_text(root, 'view_text', text))88 command=lambda:view_text(root, 'view_text', text)) 87 89 btn1.pack(side=LEFT) 88 90 btn2 = Button(root, text='view_file', 89 91 command=lambda:view_file(root, 'view_file', filename)) 90 92 btn2.pack(side=LEFT) 93 btn3 = Button(root, text='nonmodal view_text', 94 command=lambda:view_text(root, 'nonmodal view_text', text, 95 modal=False)) 96 btn3.pack(side=LEFT) 91 97 close = Button(root, text='Close', command=root.destroy) 92 98 close.pack(side=RIGHT)
Note:
See TracChangeset
for help on using the changeset viewer.