1import os
2
3from tkinter import *
4import tkinter.messagebox as tkMessageBox
5
6
7class FileList:
8
9    # N.B. this import overridden in PyShellFileList.
10    from idlelib.editor import EditorWindow
11
12    def __init__(self, root):
13        self.root = root
14        self.dict = {}
15        self.inversedict = {}
16        self.vars = {} # For EditorWindow.getrawvar (shared Tcl variables)
17
18    def open(self, filename, action=None):
19        assert filename
20        filename = self.canonize(filename)
21        if os.path.isdir(filename):
22            # This can happen when bad filename is passed on command line:
23            tkMessageBox.showerror(
24                "File Error",
25                "%r is a directory." % (filename,),
26                master=self.root)
27            return None
28        key = os.path.normcase(filename)
29        if key in self.dict:
30            edit = self.dict[key]
31            edit.top.wakeup()
32            return edit
33        if action:
34            # Don't create window, perform 'action', e.g. open in same window
35            return action(filename)
36        else:
37            edit = self.EditorWindow(self, filename, key)
38            if edit.good_load:
39                return edit
40            else:
41                edit._close()
42                return None
43
44    def gotofileline(self, filename, lineno=None):
45        edit = self.open(filename)
46        if edit is not None and lineno is not None:
47            edit.gotoline(lineno)
48
49    def new(self, filename=None):
50        return self.EditorWindow(self, filename)
51
52    def close_all_callback(self, *args, **kwds):
53        for edit in list(self.inversedict):
54            reply = edit.close()
55            if reply == "cancel":
56                break
57        return "break"
58
59    def unregister_maybe_terminate(self, edit):
60        try:
61            key = self.inversedict[edit]
62        except KeyError:
63            print("Don't know this EditorWindow object.  (close)")
64            return
65        if key:
66            del self.dict[key]
67        del self.inversedict[edit]
68        if not self.inversedict:
69            self.root.quit()
70
71    def filename_changed_edit(self, edit):
72        edit.saved_change_hook()
73        try:
74            key = self.inversedict[edit]
75        except KeyError:
76            print("Don't know this EditorWindow object.  (rename)")
77            return
78        filename = edit.io.filename
79        if not filename:
80            if key:
81                del self.dict[key]
82            self.inversedict[edit] = None
83            return
84        filename = self.canonize(filename)
85        newkey = os.path.normcase(filename)
86        if newkey == key:
87            return
88        if newkey in self.dict:
89            conflict = self.dict[newkey]
90            self.inversedict[conflict] = None
91            tkMessageBox.showerror(
92                "Name Conflict",
93                "You now have multiple edit windows open for %r" % (filename,),
94                master=self.root)
95        self.dict[newkey] = edit
96        self.inversedict[edit] = newkey
97        if key:
98            try:
99                del self.dict[key]
100            except KeyError:
101                pass
102
103    def canonize(self, filename):
104        if not os.path.isabs(filename):
105            try:
106                pwd = os.getcwd()
107            except OSError:
108                pass
109            else:
110                filename = os.path.join(pwd, filename)
111        return os.path.normpath(filename)
112
113
114def _test():
115    from idlelib.editor import fixwordbreaks
116    import sys
117    root = Tk()
118    fixwordbreaks(root)
119    root.withdraw()
120    flist = FileList(root)
121    if sys.argv[1:]:
122        for filename in sys.argv[1:]:
123            flist.open(filename)
124    else:
125        flist.new()
126    if flist.inversedict:
127        root.mainloop()
128
129if __name__ == '__main__':
130    _test()
131