17aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport os 2bfbaa6b206abdb8b1c3861926f4334b879ec91ccTerry Jan Reedy 314fc4270da5db43574d46d055a5f794ed33b271fGeorg Brandlfrom tkinter import * 414fc4270da5db43574d46d055a5f794ed33b271fGeorg Brandlimport tkinter.messagebox as tkMessageBox 57aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 67aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 77aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass FileList: 87aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 92d7f6a079df2b4582d7ccc32a7a2a7287d0bf175Kurt B. Kaiser # N.B. this import overridden in PyShellFileList. 106fa5bdc6e85ec48925bc0d856b134f59d01c300fTerry Jan Reedy from idlelib.editor import EditorWindow 117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def __init__(self, root): 137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.root = root 147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.dict = {} 157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.inversedict = {} 167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.vars = {} # For EditorWindow.getrawvar (shared Tcl variables) 177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def open(self, filename, action=None): 197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer assert filename 207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer filename = self.canonize(filename) 217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if os.path.isdir(filename): 22183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser # This can happen when bad filename is passed on command line: 237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer tkMessageBox.showerror( 24183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser "File Error", 25183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser "%r is a directory." % (filename,), 267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer master=self.root) 277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return None 287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer key = os.path.normcase(filename) 29811c4e0b7cb1a3b43cda8dab0b1587983b44c58dGuido van Rossum if key in self.dict: 307aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer edit = self.dict[key] 31183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser edit.top.wakeup() 327aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return edit 33183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser if action: 34183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser # Don't create window, perform 'action', e.g. open in same window 357aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return action(filename) 36183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser else: 37105f60ee628842a20f70526f9e994bc8acfaa9c7Kurt B. Kaiser edit = self.EditorWindow(self, filename, key) 38105f60ee628842a20f70526f9e994bc8acfaa9c7Kurt B. Kaiser if edit.good_load: 39105f60ee628842a20f70526f9e994bc8acfaa9c7Kurt B. Kaiser return edit 40105f60ee628842a20f70526f9e994bc8acfaa9c7Kurt B. Kaiser else: 41105f60ee628842a20f70526f9e994bc8acfaa9c7Kurt B. Kaiser edit._close() 42105f60ee628842a20f70526f9e994bc8acfaa9c7Kurt B. Kaiser return None 437aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 44df8a40fbf57b7dd794803365a856b1f0f235d915Kurt B. Kaiser def gotofileline(self, filename, lineno=None): 45df8a40fbf57b7dd794803365a856b1f0f235d915Kurt B. Kaiser edit = self.open(filename) 46df8a40fbf57b7dd794803365a856b1f0f235d915Kurt B. Kaiser if edit is not None and lineno is not None: 47df8a40fbf57b7dd794803365a856b1f0f235d915Kurt B. Kaiser edit.gotoline(lineno) 48df8a40fbf57b7dd794803365a856b1f0f235d915Kurt B. Kaiser 49d2f4861a0b52a2af5ea3395267a5c56541352f8fKurt B. Kaiser def new(self, filename=None): 50d2f4861a0b52a2af5ea3395267a5c56541352f8fKurt B. Kaiser return self.EditorWindow(self, filename) 517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 5210e05e17a3e7657ecdc4c7986d35275d76c6d603Ronald Oussoren def close_all_callback(self, *args, **kwds): 53b5a755e46c66c7e7d709431399f1781ea9e582dfGuido van Rossum for edit in list(self.inversedict): 547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer reply = edit.close() 557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if reply == "cancel": 567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer break 577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return "break" 587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 598ce8a784bd672ba42975dec752848392ff9a7797Guido van Rossum def unregister_maybe_terminate(self, edit): 607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer key = self.inversedict[edit] 627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer except KeyError: 63be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum print("Don't know this EditorWindow object. (close)") 647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return 657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if key: 667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer del self.dict[key] 677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer del self.inversedict[edit] 687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if not self.inversedict: 697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.root.quit() 707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def filename_changed_edit(self, edit): 727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer edit.saved_change_hook() 737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer key = self.inversedict[edit] 757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer except KeyError: 76be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum print("Don't know this EditorWindow object. (rename)") 777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return 787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer filename = edit.io.filename 797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if not filename: 807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if key: 817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer del self.dict[key] 827aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.inversedict[edit] = None 837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return 847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer filename = self.canonize(filename) 857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer newkey = os.path.normcase(filename) 867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if newkey == key: 877aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return 88811c4e0b7cb1a3b43cda8dab0b1587983b44c58dGuido van Rossum if newkey in self.dict: 897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer conflict = self.dict[newkey] 907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.inversedict[conflict] = None 917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer tkMessageBox.showerror( 927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer "Name Conflict", 9370a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald "You now have multiple edit windows open for %r" % (filename,), 947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer master=self.root) 957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.dict[newkey] = edit 967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer self.inversedict[edit] = newkey 977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if key: 987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer del self.dict[key] 1007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer except KeyError: 1017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer pass 1027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer def canonize(self, filename): 1047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if not os.path.isabs(filename): 1057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer try: 1067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer pwd = os.getcwd() 107786fbd8db707c7cb302a1adf2b57a0b3f8ba078cAndrew Svetlov except OSError: 1087aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer pass 1097aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 1107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer filename = os.path.join(pwd, filename) 1117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer return os.path.normpath(filename) 1127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 114df8a40fbf57b7dd794803365a856b1f0f235d915Kurt B. Kaiserdef _test(): 1156fa5bdc6e85ec48925bc0d856b134f59d01c300fTerry Jan Reedy from idlelib.editor import fixwordbreaks 1167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer import sys 1177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer root = Tk() 1187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer fixwordbreaks(root) 1197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer root.withdraw() 1207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer flist = FileList(root) 1217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if sys.argv[1:]: 1227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer for filename in sys.argv[1:]: 1237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer flist.open(filename) 1247aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer else: 1257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer flist.new() 1267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer if flist.inversedict: 1277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer root.mainloop() 1287aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer 1297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererif __name__ == '__main__': 130df8a40fbf57b7dd794803365a856b1f0f235d915Kurt B. Kaiser _test() 131