10a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom Tkinter import * 20a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom idlelib.EditorWindow import EditorWindow 30a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport re 40a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport tkMessageBox 50a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom idlelib import IOBinding 60a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 70a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass OutputWindow(EditorWindow): 80a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 90a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """An editor window that can serve as an output file. 100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Also the future base class for the Python shell window. 120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao This class has no input facilities. 130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """ 140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __init__(self, *args): 160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao EditorWindow.__init__(self, *args) 170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.text.bind("<<goto-file-line>>", self.goto_file_line) 180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Customize EditorWindow 200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def ispythonsource(self, filename): 220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # No colorization needed 230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return 0 240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def short_title(self): 260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return "Output" 270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def maybesave(self): 290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Override base class method -- don't ask any questions 300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self.get_saved(): 310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return "yes" 320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return "no" 340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Act as output file 360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def write(self, s, tags=(), mark="insert"): 380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Tk assumes that byte strings are Latin-1; 390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # we assume that they are in the locale's encoding 400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if isinstance(s, str): 410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao s = unicode(s, IOBinding.encoding) 430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except UnicodeError: 440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # some other encoding; let Tcl deal with it 450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao pass 460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.text.insert(mark, s, tags) 470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.text.see(mark) 480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.text.update() 490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def writelines(self, lines): 510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for line in lines: 520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.write(line) 530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def flush(self): 550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao pass 560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Our own right-button menu 580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao rmenu_specs = [ 600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("Cut", "<<cut>>", "rmenu_check_cut"), 610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("Copy", "<<copy>>", "rmenu_check_copy"), 620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("Paste", "<<paste>>", "rmenu_check_paste"), 630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao (None, None, None), 640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ("Go to file/line", "<<goto-file-line>>", None), 650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ] 660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao file_line_pats = [ 680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # order of patterns matters 690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao r'file "([^"]*)", line (\d+)', 700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao r'([^\s]+)\((\d+)\)', 710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao r'^(\s*\S.*?):\s*(\d+):', # Win filename, maybe starting with spaces 720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao r'([^\s]+):\s*(\d+):', # filename or path, ltrim 730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao r'^\s*(\S.*?):\s*(\d+):', # Win abs path with embedded spaces, ltrim 740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ] 750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao file_line_progs = None 770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def goto_file_line(self, event=None): 790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self.file_line_progs is None: 800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao l = [] 810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for pat in self.file_line_pats: 820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao l.append(re.compile(pat, re.IGNORECASE)) 830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.file_line_progs = l 840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # x, y = self.event.x, self.event.y 850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # self.text.mark_set("insert", "@%d,%d" % (x, y)) 860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao line = self.text.get("insert linestart", "insert lineend") 870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao result = self._file_line_helper(line) 880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not result: 890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Try the previous line. This is handy e.g. in tracebacks, 900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # where you tend to right-click on the displayed source line 910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao line = self.text.get("insert -1line linestart", 920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao "insert -1line lineend") 930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao result = self._file_line_helper(line) 940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not result: 950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao tkMessageBox.showerror( 960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao "No special line", 970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao "The line you point at doesn't look like " 980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao "a valid file name followed by a line number.", 990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao master=self.text) 1000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return 1010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao filename, lineno = result 1020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao edit = self.flist.open(filename) 1030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao edit.gotoline(lineno) 1040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def _file_line_helper(self, line): 1060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for prog in self.file_line_progs: 1070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao match = prog.search(line) 1080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if match: 1090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao filename, lineno = match.group(1, 2) 1100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 1110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao f = open(filename, "r") 1120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao f.close() 1130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao break 1140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except IOError: 1150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao continue 1160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 1170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return None 1180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 1190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return filename, int(lineno) 1200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except TypeError: 1210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return None 1220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# These classes are currently not used but might come in handy 1240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1250a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass OnDemandOutputWindow: 1260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao tagdefs = { 1280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # XXX Should use IdlePrefs.ColorPrefs 1290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao "stdout": {"foreground": "blue"}, 1300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao "stderr": {"foreground": "#007700"}, 1310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao } 1320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __init__(self, flist): 1340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.flist = flist 1350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.owin = None 1360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def write(self, s, tags, mark): 1380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if not self.owin: 1390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.setup() 1400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.owin.write(s, tags, mark) 1410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def setup(self): 1430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.owin = owin = OutputWindow(self.flist) 1440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao text = owin.text 1450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for tag, cnf in self.tagdefs.items(): 1460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if cnf: 1470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao text.tag_configure(tag, **cnf) 1480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao text.tag_raise('sel') 1490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.write = self.owin.write 150