EditorWindow.py revision 83118c6cb36cf9a424bec1b9a2ef8c8760bae8f5
17aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport sys 27aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport os 37aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport string 47aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport re 57aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport imp 67aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererfrom Tkinter import * 77aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport tkSimpleDialog 87aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport tkMessageBox 9fd182cd9d36adefba00d86542eb3134119cdc804Kurt B. Kaiser 10fd182cd9d36adefba00d86542eb3134119cdc804Kurt B. Kaiserimport webbrowser 117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport idlever 127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport WindowList 13c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gavaimport SearchDialog 14c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gavaimport GrepDialog 15c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gavaimport ReplaceDialog 16dc72f48e262a7aaf177a37676c79ced4ddce0fffSteven M. Gava#from IdleConf import idleconf 17dc72f48e262a7aaf177a37676c79ced4ddce0fffSteven M. Gavafrom configHandler import idleConf 183b55a891a197212b34b0c077f72cb3af752468ecSteven M. Gavaimport aboutDialog, textView, configDialog 197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer# The default tab setting for a Text widget, in average-width characters. 217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David SchererTK_TABWIDTH_DEFAULT = 8 227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer# File menu 247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ event <<open-module>> 267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ win <Alt-m> 277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ unix <Control-x><Control-m> 287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ event <<open-class-browser>> 307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ win <Alt-c> 317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ unix <Control-x><Control-b> 327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ event <<open-path-browser>> 347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ event <<close-window>> 36afdf71b9eefdfb5904e40602984836b28318bad0Kurt B. Kaiser 377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ unix <Control-x><Control-0> 387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ unix <Control-x><Key-0> 397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ win <Alt-F4> 407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer# Edit menu 427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ event <<Copy>> 447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ win <Control-c> 457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ unix <Alt-w> 467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ event <<Cut>> 487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ win <Control-x> 497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ unix <Control-w> 507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ event <<Paste>> 527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ win <Control-v> 537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ unix <Control-y> 547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ event <<select-all>> 567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ win <Alt-a> 577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ unix <Alt-a> 587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer# Help menu 607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ event <<help>> 627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ win <F1> 637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ unix <F1> 647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ event <<about-idle>> 667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer# Events without menu entries 687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ event <<remove-selection>> 707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ win <Escape> 717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ event <<center-insert>> 737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ win <Control-l> 747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ unix <Control-l> 757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ event <<do-nothing>> 777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer#$ unix <Control-x> 787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass EditorWindow: 807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer from Percolator import Percolator 817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer from ColorDelegator import ColorDelegator 827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer from UndoDelegator import UndoDelegator 837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer from IOBinding import IOBinding 847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer import Bindings 857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer from Tkinter import Toplevel 867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer from MultiStatusBar import MultiStatusBar 877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer vars = {} 897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def __init__(self, flist=None, filename=None, key=None, root=None): 91dc72f48e262a7aaf177a37676c79ced4ddce0fffSteven M. Gava currentTheme=idleConf.CurrentTheme() 927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.flist = flist 937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer root = root or flist.root 947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.root = root 957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.menubar = Menu(root) 967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.top = top = self.Toplevel(root, menu=self.menubar) 970c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava if flist: 980c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava self.vars = flist.vars 990c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava #self.top.instanceDict makes flist.inversedict avalable to 1000c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava #configDialog.py so it can access all EditorWindow instaces 1010c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava self.top.instanceDict=flist.inversedict 1021d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava self.recentFilesPath=os.path.join(idleConf.GetUserCfgDir(), 1031d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava 'recent-files.lst') 1047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.vbar = vbar = Scrollbar(top, name='vbar') 1057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text_frame = text_frame = Frame(top) 106dc72f48e262a7aaf177a37676c79ced4ddce0fffSteven M. Gava self.text = text = Text(text_frame, name='text', padx=5, wrap=None, 107dc72f48e262a7aaf177a37676c79ced4ddce0fffSteven M. Gava foreground=idleConf.GetHighlight(currentTheme, 108dc72f48e262a7aaf177a37676c79ced4ddce0fffSteven M. Gava 'normal',fgBg='fg'), 109dc72f48e262a7aaf177a37676c79ced4ddce0fffSteven M. Gava background=idleConf.GetHighlight(currentTheme, 110dc72f48e262a7aaf177a37676c79ced4ddce0fffSteven M. Gava 'normal',fgBg='bg'), 111dc72f48e262a7aaf177a37676c79ced4ddce0fffSteven M. Gava highlightcolor=idleConf.GetHighlight(currentTheme, 112dc72f48e262a7aaf177a37676c79ced4ddce0fffSteven M. Gava 'hilite',fgBg='fg'), 113dc72f48e262a7aaf177a37676c79ced4ddce0fffSteven M. Gava highlightbackground=idleConf.GetHighlight(currentTheme, 114dc72f48e262a7aaf177a37676c79ced4ddce0fffSteven M. Gava 'hilite',fgBg='bg'), 115dc72f48e262a7aaf177a37676c79ced4ddce0fffSteven M. Gava insertbackground=idleConf.GetHighlight(currentTheme, 116dc72f48e262a7aaf177a37676c79ced4ddce0fffSteven M. Gava 'cursor',fgBg='fg'), 117dc72f48e262a7aaf177a37676c79ced4ddce0fffSteven M. Gava width=idleConf.GetOption('main','EditorWindow','width'), 118dc72f48e262a7aaf177a37676c79ced4ddce0fffSteven M. Gava height=idleConf.GetOption('main','EditorWindow','height') ) 1197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.createmenubar() 1217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.apply_bindings() 1227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.top.protocol("WM_DELETE_WINDOW", self.close) 1247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.top.bind("<<close-window>>", self.close_event) 1257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<<center-insert>>", self.center_insert_event) 1267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<<help>>", self.help_dialog) 1277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<<good-advice>>", self.good_advice) 128abdfc4147d1f1334bb4dbaf5d9dd66af1db175adSteven M. Gava text.bind("<<view-readme>>", self.view_readme) 1297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<<python-docs>>", self.python_docs) 1307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<<about-idle>>", self.about_dialog) 1313b55a891a197212b34b0c077f72cb3af752468ecSteven M. Gava text.bind("<<open-config-dialog>>", self.config_dialog) 1327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<<open-module>>", self.open_module) 1337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<<do-nothing>>", lambda event: "break") 1347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<<select-all>>", self.select_all) 1357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<<remove-selection>>", self.remove_selection) 136c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava text.bind("<<find>>", self.find_event) 137c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava text.bind("<<find-again>>", self.find_again_event) 138c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava text.bind("<<find-in-files>>", self.find_in_files_event) 139c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava text.bind("<<find-selection>>", self.find_selection_event) 140c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava text.bind("<<replace>>", self.replace_event) 141c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava text.bind("<<goto-line>>", self.goto_line_event) 1427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<3>", self.right_menu_event) 1437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if flist: 1447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer flist.inversedict[self] = key 1457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if key: 1467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer flist.dict[key] = self 1477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<<open-new-window>>", self.flist.new_callback) 1487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<<close-all-windows>>", self.flist.close_all_callback) 1497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<<open-class-browser>>", self.open_class_browser) 1507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.bind("<<open-path-browser>>", self.open_path_browser) 1517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 152898a365c276951ab2471afe2e24bbc910666d361Steven M. Gava self.set_status_bar() 153898a365c276951ab2471afe2e24bbc910666d361Steven M. Gava 1547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer vbar['command'] = text.yview 1557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer vbar.pack(side=RIGHT, fill=Y) 1567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text['yscrollcommand'] = vbar.set 158b1585417d1f7ae8984ca72b16fd5a21746949ae5Steven M. Gava fontWeight='normal' 159b1585417d1f7ae8984ca72b16fd5a21746949ae5Steven M. Gava if idleConf.GetOption('main','EditorWindow','font-bold',type='bool'): 160b1585417d1f7ae8984ca72b16fd5a21746949ae5Steven M. Gava fontWeight='bold' 161dc72f48e262a7aaf177a37676c79ced4ddce0fffSteven M. Gava text.config(font=(idleConf.GetOption('main','EditorWindow','font'), 162b1585417d1f7ae8984ca72b16fd5a21746949ae5Steven M. Gava idleConf.GetOption('main','EditorWindow','font-size'), 163b1585417d1f7ae8984ca72b16fd5a21746949ae5Steven M. Gava fontWeight)) 1647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text_frame.pack(side=LEFT, fill=BOTH, expand=1) 1657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.pack(side=TOP, fill=BOTH, expand=1) 1667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.focus_set() 1677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.per = per = self.Percolator(text) 1697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.ispythonsource(filename): 1707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.color = color = self.ColorDelegator(); per.insertfilter(color) 1717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer ##print "Initial colorizer" 1727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 1737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer ##print "No initial colorizer" 1747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.color = None 1757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.undo = undo = self.UndoDelegator(); per.insertfilter(undo) 1767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.io = io = self.IOBinding(self) 1771d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava #create the Recent Files submenu 1781d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava self.menuRecentFiles=Menu(self.menubar) 1791d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava self.menudict['file'].insert_cascade(3,label='Recent Files', 1801d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava underline=0,menu=self.menuRecentFiles) 1811d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava self.UpdateRecentFilesList() 1827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.undo_block_start = undo.undo_block_start 1847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.undo_block_stop = undo.undo_block_stop 1857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer undo.set_saved_change_hook(self.saved_change_hook) 1867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer io.set_filename_change_hook(self.filename_change_hook) 1877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if filename: 1897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if os.path.exists(filename): 1907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer io.loadfile(filename) 1917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 1927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer io.set_filename(filename) 1937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.saved_change_hook() 1957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.load_extensions() 1977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer menu = self.menudict.get('windows') 1997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if menu: 2007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer end = menu.index("end") 2017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if end is None: 2027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer end = -1 2037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if end >= 0: 2047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer menu.add_separator() 2057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer end = end + 1 2067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.wmenu_end = end 2077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer WindowList.register_callback(self.postwindowsmenu) 2087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 2097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # Some abstractions so IDLE extensions are cross-IDE 2107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.askyesno = tkMessageBox.askyesno 2117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.askinteger = tkSimpleDialog.askinteger 2127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.showerror = tkMessageBox.showerror 2137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 2147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.extensions.has_key('AutoIndent'): 2157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.extensions['AutoIndent'].set_indentation_params( 2167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.ispythonsource(filename)) 2170c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava 2187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def set_status_bar(self): 219898a365c276951ab2471afe2e24bbc910666d361Steven M. Gava self.status_bar = self.MultiStatusBar(self.top) 2207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.status_bar.set_label('column', 'Col: ?', side=RIGHT) 2217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.status_bar.set_label('line', 'Ln: ?', side=RIGHT) 2227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.status_bar.pack(side=BOTTOM, fill=X) 2237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.bind('<KeyRelease>', self.set_line_and_column) 2247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.bind('<ButtonRelease>', self.set_line_and_column) 2257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.after_idle(self.set_line_and_column) 2267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 2277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def set_line_and_column(self, event=None): 2287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer line, column = string.split(self.text.index(INSERT), '.') 2297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.status_bar.set_label('column', 'Col: %s' % column) 2307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.status_bar.set_label('line', 'Ln: %s' % line) 2317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 2327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def wakeup(self): 2337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.top.wm_state() == "iconic": 2347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.top.wm_deiconify() 2357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 2367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.top.tkraise() 2377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.focus_set() 2387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 2397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer menu_specs = [ 2407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer ("file", "_File"), 2417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer ("edit", "_Edit"), 2427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer ("format", "F_ormat"), 2437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer ("run", "_Run"), 24482c6682bb776bb59e10a522897534af69938194fSteven M. Gava ("settings", "_Settings"), 2457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer ("windows", "_Windows"), 2467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer ("help", "_Help"), 2477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer ] 2487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 2497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def createmenubar(self): 2507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer mbar = self.menubar 2517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.menudict = menudict = {} 2527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer for name, label in self.menu_specs: 2537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer underline, label = prepstr(label) 2547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer menudict[name] = menu = Menu(mbar, name=name) 2557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer mbar.add_cascade(label=label, menu=menu, underline=underline) 2567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.fill_menus() 2571d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava #create the ExtraHelp menu, if required 2580c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava self.ResetExtraHelpMenu() 2597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 2607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def postwindowsmenu(self): 2617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # Only called when Windows menu exists 2627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # XXX Actually, this Just-In-Time updating interferes badly 2637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # XXX with the tear-off feature. It would be better to update 2647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # XXX all Windows menus whenever the list of windows changes. 2657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer menu = self.menudict['windows'] 2667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer end = menu.index("end") 2677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if end is None: 2687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer end = -1 2697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if end > self.wmenu_end: 2707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer menu.delete(self.wmenu_end+1, end) 2717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer WindowList.add_windows_to_menu(menu) 2727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 2737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer rmenu = None 2747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 2757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def right_menu_event(self, event): 2767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.tag_remove("sel", "1.0", "end") 2777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.mark_set("insert", "@%d,%d" % (event.x, event.y)) 2787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if not self.rmenu: 2797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.make_rmenu() 2807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer rmenu = self.rmenu 2817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.event = event 2827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer iswin = sys.platform[:3] == 'win' 2837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if iswin: 2847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.config(cursor="arrow") 2857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer rmenu.tk_popup(event.x_root, event.y_root) 2867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if iswin: 2877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.config(cursor="ibeam") 2887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 2897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer rmenu_specs = [ 2907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # ("Label", "<<virtual-event>>"), ... 2917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer ("Close", "<<close-window>>"), # Example 2927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer ] 2937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 2947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def make_rmenu(self): 2957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer rmenu = Menu(self.text, tearoff=0) 2967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer for label, eventname in self.rmenu_specs: 2977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def command(text=self.text, eventname=eventname): 2987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.event_generate(eventname) 2997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer rmenu.add_command(label=label, command=command) 3007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.rmenu = rmenu 3017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 3027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def about_dialog(self, event=None): 3037d9ed726fb6ec15dbfb8e922d35aa8816cbd0b0cSteven M. Gava aboutDialog.AboutDialog(self.top,'About IDLEfork') 3047d9ed726fb6ec15dbfb8e922d35aa8816cbd0b0cSteven M. Gava 3053b55a891a197212b34b0c077f72cb3af752468ecSteven M. Gava def config_dialog(self, event=None): 3063b55a891a197212b34b0c077f72cb3af752468ecSteven M. Gava configDialog.ConfigDialog(self.top,'Settings') 3073b55a891a197212b34b0c077f72cb3af752468ecSteven M. Gava 3087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def good_advice(self, event=None): 3097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer tkMessageBox.showinfo('Advice', "Don't Panic!", master=self.text) 3107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 311abdfc4147d1f1334bb4dbaf5d9dd66af1db175adSteven M. Gava def view_readme(self, event=None): 312abdfc4147d1f1334bb4dbaf5d9dd66af1db175adSteven M. Gava fn=os.path.join(os.path.abspath(os.path.dirname(__file__)),'README.txt') 313abdfc4147d1f1334bb4dbaf5d9dd66af1db175adSteven M. Gava textView.TextViewer(self.top,'IDLEfork - README',fn) 314abdfc4147d1f1334bb4dbaf5d9dd66af1db175adSteven M. Gava 3157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def help_dialog(self, event=None): 316b9d07b5a8b8b70268ffa520895e7843ab594a486Steven M. Gava fn=os.path.join(os.path.abspath(os.path.dirname(__file__)),'help.txt') 317b9d07b5a8b8b70268ffa520895e7843ab594a486Steven M. Gava textView.TextViewer(self.top,'Help',fn) 318b9d07b5a8b8b70268ffa520895e7843ab594a486Steven M. Gava 3197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer help_url = "http://www.python.org/doc/current/" 320afdf71b9eefdfb5904e40602984836b28318bad0Kurt B. Kaiser if sys.platform[:3] == "win": 321afdf71b9eefdfb5904e40602984836b28318bad0Kurt B. Kaiser fn = os.path.dirname(__file__) 322931625dc77cfd527b059e579615d517d8d994110Steven M. Gava fn = os.path.join(fn, os.pardir, os.pardir, "pythlp.chm") 323afdf71b9eefdfb5904e40602984836b28318bad0Kurt B. Kaiser fn = os.path.normpath(fn) 324afdf71b9eefdfb5904e40602984836b28318bad0Kurt B. Kaiser if os.path.isfile(fn): 325afdf71b9eefdfb5904e40602984836b28318bad0Kurt B. Kaiser help_url = fn 326931625dc77cfd527b059e579615d517d8d994110Steven M. Gava else: 327931625dc77cfd527b059e579615d517d8d994110Steven M. Gava fn = os.path.dirname(__file__) 328931625dc77cfd527b059e579615d517d8d994110Steven M. Gava fn = os.path.join(fn, os.pardir, os.pardir, "Doc", "index.html") 329931625dc77cfd527b059e579615d517d8d994110Steven M. Gava fn = os.path.normpath(fn) 330931625dc77cfd527b059e579615d517d8d994110Steven M. Gava if os.path.isfile(fn): 331931625dc77cfd527b059e579615d517d8d994110Steven M. Gava help_url = fn 332afdf71b9eefdfb5904e40602984836b28318bad0Kurt B. Kaiser del fn 333931625dc77cfd527b059e579615d517d8d994110Steven M. Gava def python_docs(self, event=None): 334931625dc77cfd527b059e579615d517d8d994110Steven M. Gava os.startfile(self.help_url) 335931625dc77cfd527b059e579615d517d8d994110Steven M. Gava else: 336931625dc77cfd527b059e579615d517d8d994110Steven M. Gava def python_docs(self, event=None): 337931625dc77cfd527b059e579615d517d8d994110Steven M. Gava self.display_docs(self.help_url) 3380c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava 3390c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava def display_docs(self, url): 3400c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava webbrowser.open(url) 3417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 3427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def select_all(self, event=None): 3437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.tag_add("sel", "1.0", "end-1c") 3447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.mark_set("insert", "1.0") 3457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.see("insert") 3467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "break" 3477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 3487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def remove_selection(self, event=None): 3497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.tag_remove("sel", "1.0", "end") 3507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.see("insert") 3517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 352c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava def find_event(self, event): 353c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava SearchDialog.find(self.text) 354c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava return "break" 355c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava 356c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava def find_again_event(self, event): 357c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava SearchDialog.find_again(self.text) 358c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava return "break" 359c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava 360c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava def find_selection_event(self, event): 361c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava SearchDialog.find_selection(self.text) 362c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava return "break" 363c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava 364c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava def find_in_files_event(self, event): 365c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava GrepDialog.grep(self.text, self.io, self.flist) 366c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava return "break" 367c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava 368c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava def replace_event(self, event): 369c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava ReplaceDialog.replace(self.text) 370c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava return "break" 371c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava 372c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava def goto_line_event(self, event): 373c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava text = self.text 374c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava lineno = tkSimpleDialog.askinteger("Goto", 375c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava "Go to line number:",parent=text) 376c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava if lineno is None: 377c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava return "break" 378c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava if lineno <= 0: 379c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava text.bell() 380c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava return "break" 381c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava text.mark_set("insert", "%d.0" % lineno) 382c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava text.see("insert") 383c597640515a9ca3aa1807cc633b8d7bf2aa4a4e6Steven M. Gava 3847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def open_module(self, event=None): 3857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # XXX Shouldn't this be in IOBinding or in FileList? 3867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 3877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer name = self.text.get("sel.first", "sel.last") 3887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer except TclError: 3897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer name = "" 3907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 3917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer name = string.strip(name) 3927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if not name: 3937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer name = tkSimpleDialog.askstring("Module", 3947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer "Enter the name of a Python module\n" 3957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer "to search on sys.path and open:", 3967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer parent=self.text) 3977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if name: 3987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer name = string.strip(name) 3997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if not name: 4007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return 4017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # XXX Ought to support package syntax 4027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # XXX Ought to insert current file's directory in front of path 4037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 4047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer (f, file, (suffix, mode, type)) = imp.find_module(name) 4057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer except (NameError, ImportError), msg: 4067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer tkMessageBox.showerror("Import error", str(msg), parent=self.text) 4077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return 4087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if type != imp.PY_SOURCE: 4097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer tkMessageBox.showerror("Unsupported type", 4107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer "%s is not a source module" % name, parent=self.text) 4117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return 4127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if f: 4137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer f.close() 4147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.flist: 4157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.flist.open(file) 4167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 4177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.io.loadfile(file) 4187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 4197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def open_class_browser(self, event=None): 4207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer filename = self.io.filename 4217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if not filename: 4227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer tkMessageBox.showerror( 4237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer "No filename", 4247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer "This buffer has no associated filename", 4257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer master=self.text) 4267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.focus_set() 4277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return None 4287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer head, tail = os.path.split(filename) 4297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer base, ext = os.path.splitext(tail) 4307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer import ClassBrowser 4317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer ClassBrowser.ClassBrowser(self.flist, base, [head]) 4327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 4337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def open_path_browser(self, event=None): 4347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer import PathBrowser 4357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer PathBrowser.PathBrowser(self.flist) 4367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 4377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def gotoline(self, lineno): 4387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if lineno is not None and lineno > 0: 4397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.mark_set("insert", "%d.0" % lineno) 4407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.tag_remove("sel", "1.0", "end") 4417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.tag_add("sel", "insert", "insert +1l") 4427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.center() 4437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 4447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def ispythonsource(self, filename): 4457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if not filename: 4467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return 1 4477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer base, ext = os.path.splitext(os.path.basename(filename)) 4487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if os.path.normcase(ext) in (".py", ".pyw"): 4497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return 1 4507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 4517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer f = open(filename) 4527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer line = f.readline() 4537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer f.close() 4547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer except IOError: 4557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return 0 4567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return line[:2] == '#!' and string.find(line, 'python') >= 0 4577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 4587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def close_hook(self): 4597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.flist: 4607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.flist.close_edit(self) 4617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 4627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def set_close_hook(self, close_hook): 4637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.close_hook = close_hook 4647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 4657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def filename_change_hook(self): 4667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.flist: 4677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.flist.filename_changed_edit(self) 4687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.saved_change_hook() 4697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.ispythonsource(self.io.filename): 4707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.addcolorizer() 4717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 4727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.rmcolorizer() 4737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 4747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def addcolorizer(self): 4757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.color: 4767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return 4777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer ##print "Add colorizer" 4787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.per.removefilter(self.undo) 4797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.color = self.ColorDelegator() 4807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.per.insertfilter(self.color) 4817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.per.insertfilter(self.undo) 4827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 4837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def rmcolorizer(self): 4847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if not self.color: 4857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return 4867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer ##print "Remove colorizer" 4877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.per.removefilter(self.undo) 4887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.per.removefilter(self.color) 4897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.color = None 4907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.per.insertfilter(self.undo) 491b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava 492b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava def ResetColorizer(self): 49383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Update the colour theme if it is changed" 49483118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser # Called from configDialog.py 495b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava if self.color: 496b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava self.color = self.ColorDelegator() 497b77d343bc846c2049a4cffb1dfd65eb49d1728b4Steven M. Gava self.per.insertfilter(self.color) 4987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 499b1585417d1f7ae8984ca72b16fd5a21746949ae5Steven M. Gava def ResetFont(self): 50083118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Update the text widgets' font if it is changed" 50183118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser # Called from configDialog.py 502b1585417d1f7ae8984ca72b16fd5a21746949ae5Steven M. Gava fontWeight='normal' 503b1585417d1f7ae8984ca72b16fd5a21746949ae5Steven M. Gava if idleConf.GetOption('main','EditorWindow','font-bold',type='bool'): 504b1585417d1f7ae8984ca72b16fd5a21746949ae5Steven M. Gava fontWeight='bold' 505b1585417d1f7ae8984ca72b16fd5a21746949ae5Steven M. Gava self.text.config(font=(idleConf.GetOption('main','EditorWindow','font'), 506b1585417d1f7ae8984ca72b16fd5a21746949ae5Steven M. Gava idleConf.GetOption('main','EditorWindow','font-size'), 507b1585417d1f7ae8984ca72b16fd5a21746949ae5Steven M. Gava fontWeight)) 508b1585417d1f7ae8984ca72b16fd5a21746949ae5Steven M. Gava 509dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava def ResetKeybindings(self): 51083118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Update the keybindings if they are changed" 51183118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser # Called from configDialog.py 512dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava self.Bindings.default_keydefs=idleConf.GetCurrentKeySet() 513dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava keydefs = self.Bindings.default_keydefs 514dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava for event, keylist in keydefs.items(): 515dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava self.text.event_delete(event) 516dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava self.apply_bindings() 517dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava #update menu accelerators 518dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava menuEventDict={} 519dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava for menu in self.Bindings.menudefs: 520dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava menuEventDict[menu[0]]={} 521dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava for item in menu[1]: 522dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava if item: 523dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava menuEventDict[menu[0]][prepstr(item[0])[1]]=item[1] 524dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava for menubarItem in self.menudict.keys(): 525dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava menu=self.menudict[menubarItem] 526dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava end=menu.index(END)+1 527dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava for index in range(0,end): 528dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava if menu.type(index)=='command': 529dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava accel=menu.entrycget(index,'accelerator') 530dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava if accel: 531dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava itemName=menu.entrycget(index,'label') 532dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava event='' 533dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava if menuEventDict.has_key(menubarItem): 534dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava if menuEventDict[menubarItem].has_key(itemName): 535dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava event=menuEventDict[menubarItem][itemName] 536dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava if event: 537dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava #print 'accel was:',accel 538dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava accel=get_accelerator(keydefs, event) 539dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava menu.entryconfig(index,accelerator=accel) 540dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava #print 'accel now:',accel,'\n' 541dbfe92cd27f08d38cc8a2882c147c4289b6b5db1Steven M. Gava 5420c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava def ResetExtraHelpMenu(self): 54383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Load or update the Extra Help menu if required" 5440c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava menuList=idleConf.GetAllExtraHelpSourcesList() 5450c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava helpMenu=self.menudict['help'] 5460c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava cascadeIndex=helpMenu.index(END)-1 5470c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava if menuList: 5480c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava if not hasattr(self,'menuExtraHelp'): 5490c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava self.menuExtraHelp=Menu(self.menubar) 5500c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava helpMenu.insert_cascade(cascadeIndex,label='Extra Help', 5510c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava underline=1,menu=self.menuExtraHelp) 5520c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava self.menuExtraHelp.delete(1,END) 5530c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava for menuItem in menuList: 5540c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava self.menuExtraHelp.add_command(label=menuItem[0], 5551d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava command=self.__DisplayExtraHelpCallback(menuItem[1])) 5560c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava else: #no extra help items 5570c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava if hasattr(self,'menuExtraHelp'): 5580c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava helpMenu.delete(cascadeIndex-1) 5590c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava del(self.menuExtraHelp) 5601d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava 5611d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava def __DisplayExtraHelpCallback(self,helpFile): 5621d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava def DisplayExtraHelp(helpFile=helpFile): 5631d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava self.display_docs(helpFile) 5641d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava return DisplayExtraHelp 5650c5bc8c9518fd18d41aedede536c4a9aa8dfa619Steven M. Gava 5661d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava def UpdateRecentFilesList(self,newFile=None): 56783118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser "Load or update the recent files list, and menu if required" 5681d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava rfList=[] 5691d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava if os.path.exists(self.recentFilesPath): 5701d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava RFfile=open(self.recentFilesPath,'r') 5711d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava try: 5721d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava rfList=RFfile.readlines() 5731d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava finally: 5741d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava RFfile.close() 5751d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava if newFile: 5761d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava newFile=os.path.abspath(newFile)+'\n' 5771d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava if newFile in rfList: 5781d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava rfList.remove(newFile) 5791d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava rfList.insert(0,newFile) 5801d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava rfList=self.__CleanRecentFiles(rfList) 58183118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser #print self.flist.inversedict 58283118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser #print self.top.instanceDict 58383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser #print self 5841d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava if rfList: 5851d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava for instance in self.top.instanceDict.keys(): 5861d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava instance.menuRecentFiles.delete(1,END) 5871d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava for file in rfList: 5881d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava fileName=file[0:-1] 5891d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava instance.menuRecentFiles.add_command(label=fileName, 5901d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava command=instance.__RecentFileCallback(fileName)) 5911d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava 5921d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava def __CleanRecentFiles(self,rfList): 5931d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava origRfList=rfList[:] 5941d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava count=0 5951d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava nonFiles=[] 5961d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava for path in rfList: 5971d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava if not os.path.exists(path[0:-1]): 5981d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava nonFiles.append(count) 5991d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava count=count+1 6001d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava if nonFiles: 6011d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava nonFiles.reverse() 6021d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava for index in nonFiles: 6031d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava del(rfList[index]) 6041d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava if len(rfList)>19: 6051d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava rfList=rfList[0:19] 6061d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava #if rfList != origRfList: 6071d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava RFfile=open(self.recentFilesPath,'w') 6081d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava try: 6091d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava RFfile.writelines(rfList) 6101d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava finally: 6111d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava RFfile.close() 6121d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava return rfList 6131d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava 6141d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava def __RecentFileCallback(self,fileName): 6151d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava def OpenRecentFile(fileName=fileName): 6161d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava self.io.open(editFile=fileName) 6171d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava return OpenRecentFile 6181d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava 6197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def saved_change_hook(self): 6207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer short = self.short_title() 6217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer long = self.long_title() 6227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if short and long: 6237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer title = short + " - " + long 6247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer elif short: 6257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer title = short 6267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer elif long: 6277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer title = long 6287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 6297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer title = "Untitled" 6307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer icon = short or long or title 6317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if not self.get_saved(): 6327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer title = "*%s*" % title 6337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer icon = "*%s" % icon 6347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.top.wm_title(title) 6357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.top.wm_iconname(icon) 6367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 6377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def get_saved(self): 6387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return self.undo.get_saved() 6397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 6407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def set_saved(self, flag): 6417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.undo.set_saved(flag) 6427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 6437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def reset_undo(self): 6447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.undo.reset_undo() 6457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 6467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def short_title(self): 6477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer filename = self.io.filename 6487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if filename: 6497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer filename = os.path.basename(filename) 6507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return filename 6517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 6527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def long_title(self): 6537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return self.io.filename or "" 6547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 6557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def center_insert_event(self, event): 6567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.center() 6577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 6587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def center(self, mark="insert"): 6597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text = self.text 6607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer top, bot = self.getwindowlines() 6617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer lineno = self.getlineno(mark) 6627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer height = bot - top 6637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer newtop = max(1, lineno - height/2) 6647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.yview(float(newtop)) 6657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 6667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def getwindowlines(self): 6677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text = self.text 6687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer top = self.getlineno("@0,0") 6697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer bot = self.getlineno("@0,65535") 6707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if top == bot and text.winfo_height() == 1: 6717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # Geometry manager hasn't run yet 6727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer height = int(text['height']) 6737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer bot = top + height - 1 6747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return top, bot 6757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 6767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def getlineno(self, mark="insert"): 6777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text = self.text 6787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return int(float(text.index(mark))) 6797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 6807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def close_event(self, event): 6817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.close() 6827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 6837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def maybesave(self): 6847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.io: 68567716b5f53715e57d147cde9539b8d76a5a56e11Steven M. Gava if not self.get_saved(): 68667716b5f53715e57d147cde9539b8d76a5a56e11Steven M. Gava if self.top.state()!='normal': 68767716b5f53715e57d147cde9539b8d76a5a56e11Steven M. Gava self.top.deiconify() 68867716b5f53715e57d147cde9539b8d76a5a56e11Steven M. Gava self.top.lower() 68967716b5f53715e57d147cde9539b8d76a5a56e11Steven M. Gava self.top.lift() 6907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return self.io.maybesave() 6917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 6927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def close(self): 6937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer reply = self.maybesave() 6947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if reply != "cancel": 6957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self._close() 6967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return reply 6977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 6987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def _close(self): 69983118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser #print self.io.filename 7001d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava if self.io.filename: 7011d46e40f58b21dd6c30e21a841d65e9bcbc899b1Steven M. Gava self.UpdateRecentFilesList(newFile=self.io.filename) 70283118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser shell = self.flist.pyshell 70383118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser if shell and shell.interp.debugger: 70483118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser shell.interp.debugger.clear_file_breaks(self) 7057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer WindowList.unregister_callback(self.postwindowsmenu) 7067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.close_hook: 7077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.close_hook() 7087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.flist = None 7097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer colorizing = 0 7107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.unload_extensions() 7117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.io.close(); self.io = None 7127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.undo = None # XXX 7137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.color: 7147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer colorizing = self.color.colorizing 7157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer doh = colorizing and self.top 7167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.color.close(doh) # Cancel colorization 7177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text = None 7187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.vars = None 7197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.per.close(); self.per = None 7207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if not colorizing: 7217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.top.destroy() 7227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 7237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def load_extensions(self): 7247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.extensions = {} 7257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.load_standard_extensions() 7267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 7277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def unload_extensions(self): 7287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer for ins in self.extensions.values(): 7297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if hasattr(ins, "close"): 7307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer ins.close() 7317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.extensions = {} 7327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 7337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def load_standard_extensions(self): 7347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer for name in self.get_standard_extension_names(): 7357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 7367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.load_extension(name) 7377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer except: 7387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer print "Failed to load extension", `name` 7397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer import traceback 7407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer traceback.print_exc() 7417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 7427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def get_standard_extension_names(self): 743dc72f48e262a7aaf177a37676c79ced4ddce0fffSteven M. Gava return idleConf.GetExtensions() 7447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 7457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def load_extension(self, name): 7467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer mod = __import__(name, globals(), locals(), []) 7477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer cls = getattr(mod, name) 7487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer ins = cls(self) 7497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.extensions[name] = ins 75072c3bf076f785aaf54d63a7e8cae29bc8282920eSteven M. Gava keydefs=idleConf.GetExtensionBindings(name) 7517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if keydefs: 7527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.apply_bindings(keydefs) 7537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer for vevent in keydefs.keys(): 7547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer methodname = string.replace(vevent, "-", "_") 7557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer while methodname[:1] == '<': 7567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer methodname = methodname[1:] 7577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer while methodname[-1:] == '>': 7587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer methodname = methodname[:-1] 7597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer methodname = methodname + "_event" 7607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if hasattr(ins, methodname): 7617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.text.bind(vevent, getattr(ins, methodname)) 7627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if hasattr(ins, "menudefs"): 7637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.fill_menus(ins.menudefs, keydefs) 7647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return ins 7657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 7667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def apply_bindings(self, keydefs=None): 7677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if keydefs is None: 7687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer keydefs = self.Bindings.default_keydefs 7697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text = self.text 7707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.keydefs = keydefs 7717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer for event, keylist in keydefs.items(): 7727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if keylist: 7737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer apply(text.event_add, (event,) + tuple(keylist)) 7747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 7757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def fill_menus(self, defs=None, keydefs=None): 77683118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser """Add appropriate entries to the menus and submenus 77783118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser 77883118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser Menus that are absent or None in self.menudict are ignored. 77983118c6cb36cf9a424bec1b9a2ef8c8760bae8f5Kurt B. Kaiser """ 7807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if defs is None: 7817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer defs = self.Bindings.menudefs 7827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if keydefs is None: 7837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer keydefs = self.Bindings.default_keydefs 7847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer menudict = self.menudict 7857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text = self.text 7867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer for mname, itemlist in defs: 7877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer menu = menudict.get(mname) 7887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if not menu: 7897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer continue 7907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer for item in itemlist: 7917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if not item: 7927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer menu.add_separator() 7937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 7947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer label, event = item 7957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer checkbutton = (label[:1] == '!') 7967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if checkbutton: 7977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer label = label[1:] 7987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer underline, label = prepstr(label) 7997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer accelerator = get_accelerator(keydefs, event) 8007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def command(text=text, event=event): 8017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.event_generate(event) 8027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if checkbutton: 8037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer var = self.getrawvar(event, BooleanVar) 8047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer menu.add_checkbutton(label=label, underline=underline, 8057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer command=command, accelerator=accelerator, 8067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer variable=var) 8077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 8087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer menu.add_command(label=label, underline=underline, 8097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer command=command, accelerator=accelerator) 8107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 8117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def getvar(self, name): 8127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer var = self.getrawvar(name) 8137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if var: 8147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return var.get() 8157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 8167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def setvar(self, name, value, vartype=None): 8177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer var = self.getrawvar(name, vartype) 8187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if var: 8197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer var.set(value) 8207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 8217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def getrawvar(self, name, vartype=None): 8227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer var = self.vars.get(name) 8237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if not var and vartype: 8247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.vars[name] = var = vartype(self.text) 8257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return var 8267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 8277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # Tk implementations of "virtual text methods" -- each platform 8287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # reusing IDLE's support code needs to define these for its GUI's 8297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # flavor of widget. 8307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 8317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # Is character at text_index in a Python string? Return 0 for 8327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # "guaranteed no", true for anything else. This info is expensive 8337aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # to compute ab initio, but is probably already known by the 8347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # platform's colorizer. 8357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 8367aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def is_char_in_string(self, text_index): 8377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.color: 8387aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # Return true iff colorizer hasn't (re)gotten this far 8397aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # yet, or the character is tagged as being in a string 8407aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return self.text.tag_prevrange("TODO", text_index) or \ 8417aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer "STRING" in self.text.tag_names(text_index) 8427aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 8437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # The colorizer is missing: assume the worst 8447aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return 1 8457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 8467aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # If a selection is defined in the text widget, return (start, 8477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # end) as Tkinter text indices, otherwise return (None, None) 8487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def get_selection_indices(self): 8497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 8507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer first = self.text.index("sel.first") 8517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer last = self.text.index("sel.last") 8527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return first, last 8537aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer except TclError: 8547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return None, None 8557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 8567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # Return the text widget's current view of what a tab stop means 8577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # (equivalent width in spaces). 8587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 8597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def get_tabwidth(self): 8607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer current = self.text['tabs'] or TK_TABWIDTH_DEFAULT 8617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return int(current) 8627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 8637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # Set the text widget's current view of what a tab stop means. 8647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 8657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def set_tabwidth(self, newtabwidth): 8667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text = self.text 8677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if self.get_tabwidth() != newtabwidth: 8687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer pixels = text.tk.call("font", "measure", text["font"], 8697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer "-displayof", text.master, 870afdf71b9eefdfb5904e40602984836b28318bad0Kurt B. Kaiser "n" * newtabwidth) 8717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer text.configure(tabs=pixels) 8727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 8737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererdef prepstr(s): 8747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # Helper to extract the underscore from a string, e.g. 8757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # prepstr("Co_py") returns (2, "Copy"). 8767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer i = string.find(s, '_') 8777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if i >= 0: 8787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer s = s[:i] + s[i+1:] 8797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return i, s 8807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 8817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 8827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererkeynames = { 8837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 'bracketleft': '[', 8847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 'bracketright': ']', 8857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 'slash': '/', 8867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer} 8877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 8887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererdef get_accelerator(keydefs, event): 8897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer keylist = keydefs.get(event) 8907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if not keylist: 8917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "" 8927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer s = keylist[0] 8937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer s = re.sub(r"-[a-z]\b", lambda m: string.upper(m.group()), s) 8947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer s = re.sub(r"\b\w+\b", lambda m: keynames.get(m.group(), m.group()), s) 8957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer s = re.sub("Key-", "", s) 8967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer s = re.sub("Cancel","Ctrl-Break",s) # dscherer@cmu.edu 8977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer s = re.sub("Control-", "Ctrl-", s) 8987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer s = re.sub("-", "+", s) 8997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer s = re.sub("><", " ", s) 9007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer s = re.sub("<", "", s) 9017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer s = re.sub(">", "", s) 9027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return s 9037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 9047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 9057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererdef fixwordbreaks(root): 9067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # Make sure that Tk's double-click and next/previous word 9077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer # operations use our definition of a word (i.e. an identifier) 9087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer tk = root.tk 9097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer tk.call('tcl_wordBreakAfter', 'a b', 0) # make sure word.tcl is loaded 9107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer tk.call('set', 'tcl_wordchars', '[a-zA-Z0-9_]') 9117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer tk.call('set', 'tcl_nonwordchars', '[^a-zA-Z0-9_]') 9127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 9137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 9147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererdef test(): 9157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer root = Tk() 9167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer fixwordbreaks(root) 9177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer root.withdraw() 9187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if sys.argv[1:]: 9197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer filename = sys.argv[1] 9207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 9217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer filename = None 9227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer edit = EditorWindow(root=root, filename=filename) 9237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer edit.set_close_hook(root.quit) 9247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer root.mainloop() 9257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer root.destroy() 9267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 9277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererif __name__ == '__main__': 9287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer test() 929