17aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererimport os
26634bf2919d855ccd821e878b8cc00c7209f1cbeGeorg Brandlfrom Tkinter import *
36634bf2919d855ccd821e878b8cc00c7209f1cbeGeorg Brandlimport tkMessageBox
47aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
57aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
67aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererclass FileList:
77aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
8d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna    # N.B. this import overridden in PyShellFileList.
9d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna    from idlelib.EditorWindow import EditorWindow
107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def __init__(self, root):
127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.root = root
137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.dict = {}
147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.inversedict = {}
157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.vars = {} # For EditorWindow.getrawvar (shared Tcl variables)
167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def open(self, filename, action=None):
187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        assert filename
197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        filename = self.canonize(filename)
207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if os.path.isdir(filename):
21183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser            # This can happen when bad filename is passed on command line:
227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            tkMessageBox.showerror(
23183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser                "File Error",
24183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser                "%r is a directory." % (filename,),
257aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                master=self.root)
267aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return None
277aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        key = os.path.normcase(filename)
286e3dbbdf39f3b4eb6f18c0165e446df17218b7dcBenjamin Peterson        if key in self.dict:
297aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            edit = self.dict[key]
30183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser            edit.top.wakeup()
317aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return edit
32183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser        if action:
33183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser            # Don't create window, perform 'action', e.g. open in same window
347aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return action(filename)
35183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser        else:
36183403a271977a26c0b77dbcf62e19395c007288Kurt B. Kaiser            return self.EditorWindow(self, filename, key)
377aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
38df8a40fbf57b7dd794803365a856b1f0f235d915Kurt B. Kaiser    def gotofileline(self, filename, lineno=None):
39df8a40fbf57b7dd794803365a856b1f0f235d915Kurt B. Kaiser        edit = self.open(filename)
40df8a40fbf57b7dd794803365a856b1f0f235d915Kurt B. Kaiser        if edit is not None and lineno is not None:
41df8a40fbf57b7dd794803365a856b1f0f235d915Kurt B. Kaiser            edit.gotoline(lineno)
42df8a40fbf57b7dd794803365a856b1f0f235d915Kurt B. Kaiser
43d2f4861a0b52a2af5ea3395267a5c56541352f8fKurt B. Kaiser    def new(self, filename=None):
44d2f4861a0b52a2af5ea3395267a5c56541352f8fKurt B. Kaiser        return self.EditorWindow(self, filename)
457aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
468ec374cc93aed86c270dd3729295748683744d19Ronald Oussoren    def close_all_callback(self, *args, **kwds):
477aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        for edit in self.inversedict.keys():
487aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            reply = edit.close()
497aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if reply == "cancel":
507aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                break
517aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return "break"
527aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
530b634efcbcd10d9364796e9b048f18cd4a08b88bKurt B. Kaiser    def unregister_maybe_terminate(self, edit):
547aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
557aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            key = self.inversedict[edit]
567aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except KeyError:
577aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            print "Don't know this EditorWindow object.  (close)"
587aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return
597aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if key:
607aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            del self.dict[key]
617aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        del self.inversedict[edit]
627aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if not self.inversedict:
637aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.root.quit()
647aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
657aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def filename_changed_edit(self, edit):
667aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        edit.saved_change_hook()
677aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        try:
687aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            key = self.inversedict[edit]
697aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        except KeyError:
707aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            print "Don't know this EditorWindow object.  (rename)"
717aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return
727aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        filename = edit.io.filename
737aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if not filename:
747aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            if key:
757aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                del self.dict[key]
767aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.inversedict[edit] = None
777aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return
787aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        filename = self.canonize(filename)
797aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        newkey = os.path.normcase(filename)
807aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if newkey == key:
817aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            return
826e3dbbdf39f3b4eb6f18c0165e446df17218b7dcBenjamin Peterson        if newkey in self.dict:
837aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            conflict = self.dict[newkey]
847aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            self.inversedict[conflict] = None
857aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            tkMessageBox.showerror(
867aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                "Name Conflict",
8770a6b49821a3226f55e9716f32d802d06640cb89Walter Dörwald                "You now have multiple edit windows open for %r" % (filename,),
887aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                master=self.root)
897aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.dict[newkey] = edit
907aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        self.inversedict[edit] = newkey
917aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if key:
927aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            try:
937aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                del self.dict[key]
947aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            except KeyError:
957aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                pass
967aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
977aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    def canonize(self, filename):
987aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        if not os.path.isabs(filename):
997aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            try:
1007aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                pwd = os.getcwd()
1017aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            except os.error:
1027aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                pass
1037aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            else:
1047aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer                filename = os.path.join(pwd, filename)
1057aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        return os.path.normpath(filename)
1067aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1077aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
108df8a40fbf57b7dd794803365a856b1f0f235d915Kurt B. Kaiserdef _test():
109d630c04ab1ab35e2ec6eeeaba9bdcb9f8e730e78Florent Xicluna    from idlelib.EditorWindow import fixwordbreaks
1107aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    import sys
1117aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    root = Tk()
1127aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    fixwordbreaks(root)
1137aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    root.withdraw()
1147aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    flist = FileList(root)
1157aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    if sys.argv[1:]:
1167aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        for filename in sys.argv[1:]:
1177aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer            flist.open(filename)
1187aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    else:
1197aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        flist.new()
1207aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer    if flist.inversedict:
1217aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer        root.mainloop()
1227aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Scherer
1237aced17437a6b05bc4b0b5ff93aa6a5d3a374d68David Schererif __name__ == '__main__':
124df8a40fbf57b7dd794803365a856b1f0f235d915Kurt B. Kaiser    _test()
125