207 lines
6.0 KiB
Python
207 lines
6.0 KiB
Python
import os
|
|
from Tkinter import *
|
|
import tkMessageBox
|
|
|
|
from EditorWindow import EditorWindow, fixwordbreaks
|
|
from IOBinding import IOBinding
|
|
|
|
|
|
class MultiIOBinding(IOBinding):
|
|
|
|
def open(self, event):
|
|
filename = self.askopenfile()
|
|
if filename:
|
|
self.flist.open(filename, self.edit)
|
|
return "break"
|
|
|
|
|
|
class MultiEditorWindow(EditorWindow):
|
|
|
|
IOBinding = MultiIOBinding
|
|
|
|
# Override menu bar specs
|
|
menu_specs = EditorWindow.menu_specs[:]
|
|
menu_specs.insert(len(menu_specs)-1, ("windows", "_Windows"))
|
|
|
|
def __init__(self, flist, filename, key):
|
|
self.flist = flist
|
|
flist.inversedict[self] = key
|
|
if key:
|
|
flist.dict[key] = self
|
|
EditorWindow.__init__(self, flist.root, filename)
|
|
self.io.flist = flist
|
|
self.io.edit = self
|
|
self.text.bind("<<open-new-window>>", self.flist.new_callback)
|
|
self.text.bind("<<close-all-windows>>", self.flist.close_all_callback)
|
|
self.text.bind("<<open-class-browser>>", self.open_class_browser)
|
|
|
|
def close_hook(self):
|
|
self.flist.close_edit(self)
|
|
|
|
def filename_change_hook(self):
|
|
self.flist.filename_changed_edit(self)
|
|
EditorWindow.filename_change_hook(self)
|
|
|
|
def wakeup(self):
|
|
self.top.tkraise()
|
|
self.top.wm_deiconify()
|
|
self.text.focus_set()
|
|
|
|
def createmenubar(self):
|
|
EditorWindow.createmenubar(self)
|
|
self.menudict['windows'].configure(postcommand=self.postwindowsmenu)
|
|
|
|
def postwindowsmenu(self):
|
|
wmenu = self.menudict['windows']
|
|
wmenu.delete(0, 'end')
|
|
self.fixedwindowsmenu(wmenu)
|
|
files = self.flist.dict.keys()
|
|
files.sort()
|
|
for file in files:
|
|
def openit(self=self, file=file):
|
|
self.flist.open(file)
|
|
wmenu.add_command(label=file, command=openit)
|
|
|
|
def open_class_browser(self, event=None):
|
|
filename = self.io.filename
|
|
if not filename:
|
|
tkMessageBox.showerror(
|
|
"No filename",
|
|
"This buffer has no associated filename",
|
|
master=self.text)
|
|
return None
|
|
head, tail = os.path.split(filename)
|
|
base, ext = os.path.splitext(tail)
|
|
import pyclbr
|
|
if pyclbr._modules.has_key(base):
|
|
del pyclbr._modules[base]
|
|
import ClassBrowser
|
|
ClassBrowser.ClassBrowser(self.flist, base)
|
|
|
|
|
|
class FileList:
|
|
|
|
EditorWindow = MultiEditorWindow
|
|
|
|
def __init__(self, root):
|
|
self.root = root
|
|
self.dict = {}
|
|
self.inversedict = {}
|
|
|
|
def new(self):
|
|
return self.open(None)
|
|
|
|
def open(self, filename, edit=None):
|
|
if filename:
|
|
filename = self.canonize(filename)
|
|
if os.path.isdir(filename):
|
|
tkMessageBox.showerror(
|
|
"Is A Directory",
|
|
"The path %s is a directory." % `filename`,
|
|
master=self.root)
|
|
return None
|
|
key = os.path.normcase(filename)
|
|
if self.dict.has_key(key):
|
|
edit = self.dict[key]
|
|
edit.wakeup()
|
|
return edit
|
|
if not os.path.exists(filename):
|
|
tkMessageBox.showinfo(
|
|
"New File",
|
|
"Opening non-existent file %s" % `filename`,
|
|
master=self.root)
|
|
if edit and not edit.io.filename and edit.undo.get_saved():
|
|
# Reuse existing Untitled window for new file
|
|
edit.io.loadfile(filename)
|
|
self.dict[key] = edit
|
|
self.inversedict[edit] = key
|
|
edit.wakeup()
|
|
return edit
|
|
else:
|
|
key = None
|
|
edit = self.EditorWindow(self, filename, key)
|
|
return edit
|
|
|
|
def new_callback(self, event):
|
|
self.new()
|
|
return "break"
|
|
|
|
def close_all_callback(self, event):
|
|
for edit in self.inversedict.keys():
|
|
reply = edit.close()
|
|
if reply == "cancel":
|
|
break
|
|
return "break"
|
|
|
|
def close_edit(self, edit):
|
|
try:
|
|
key = self.inversedict[edit]
|
|
except KeyError:
|
|
print "Don't know this EditorWindow object. (close)"
|
|
return
|
|
if key:
|
|
del self.dict[key]
|
|
del self.inversedict[edit]
|
|
if not self.inversedict:
|
|
self.root.quit()
|
|
|
|
def filename_changed_edit(self, edit):
|
|
edit.saved_change_hook()
|
|
try:
|
|
key = self.inversedict[edit]
|
|
except KeyError:
|
|
print "Don't know this EditorWindow object. (rename)"
|
|
return
|
|
filename = edit.io.filename
|
|
if not filename:
|
|
if key:
|
|
del self.dict[key]
|
|
self.inversedict[edit] = None
|
|
return
|
|
filename = self.canonize(filename)
|
|
newkey = os.path.normcase(filename)
|
|
if newkey == key:
|
|
return
|
|
if self.dict.has_key(newkey):
|
|
conflict = self.dict[newkey]
|
|
self.inversedict[conflict] = None
|
|
tkMessageBox.showerror(
|
|
"Name Conflict",
|
|
"You now have multiple edit windows open for %s" % `filename`,
|
|
master=self.root)
|
|
self.dict[newkey] = edit
|
|
self.inversedict[edit] = newkey
|
|
if key:
|
|
try:
|
|
del self.dict[key]
|
|
except KeyError:
|
|
pass
|
|
|
|
def canonize(self, filename):
|
|
if not os.path.isabs(filename):
|
|
try:
|
|
pwd = os.getcwd()
|
|
except os.error:
|
|
pass
|
|
else:
|
|
filename = os.path.join(pwd, filename)
|
|
return os.path.normpath(filename)
|
|
|
|
|
|
def test():
|
|
import sys
|
|
root = Tk()
|
|
fixwordbreaks(root)
|
|
root.withdraw()
|
|
flist = FileList(root)
|
|
if sys.argv[1:]:
|
|
for filename in sys.argv[1:]:
|
|
flist.open(filename)
|
|
else:
|
|
flist.new()
|
|
if flist.inversedict:
|
|
root.mainloop()
|
|
|
|
if __name__ == '__main__':
|
|
test()
|