#!/usr/bin/python # Brian Malloy # Assignment #3, CpSc 372, June 2006 # This program uses the optimized Tkinter tree control moduels # by Charles E. "Gene" Cash import os import Tree from Tkinter import * import tkSimpleDialog from tkMessageBox import askquestion, showerror def getfiles(node): path=apply(os.path.join, node.full_id()) for filename in os.listdir(path): full=os.path.join(path, filename) name=filename folder=0 if os.path.isdir(full): # it's a directory folder=1 elif not os.path.isfile(full): # but it's not a file name=name+' (special)' if os.path.islink(full): # it's a link name=name+' (link to '+os.readlink(full)+')' tree.add_node(name=name, id=filename, flag=folder) class FileManager: def __init__(self, t): self.tree = t self.commandStack = [] def doDelete(self): cmd = DeleteCommand(self.tree) if cmd.execute(): self.commandStack = [cmd] + self.commandStack def doFind(self): cmd = FindCommand(self.tree) self.commandStack = [cmd] + self.commandStack cmd.execute() def doUndo(self): if len(self.commandStack) == 0: return cmd = self.commandStack[0] #print "Undoing...", cmd.getName() self.commandStack.pop(0) cmd.undo() def doQuit(self): filesToDelete = [] #print "LENGTH OF STACK: ", len(self.commandStack) for index in self.commandStack: if index.getName() == 'Delete': filesToDelete += [index.getDeletedNodeName()] if os.path.isdir('TreeTrash') or os.path.isfile('TreeTrash'): print "TreeTrash ALREADY EXISTS!" else: print "Creating directory TreeTrash..." os.mkdir('TreeTrash') for index in filesToDelete: print "Moving: ", index, " to TreeTrash" root.quit() class Command: def __init__(self, n): self.__name = n def getName(self): return self.__name def execute(self): pass def undo(self): pass def __repr__(self): return self.name class DeleteCommand(Command): def __init__(self, t): Command.__init__(self, "Delete") self.tree = t self.deletedNode = None def getDeletedNodeName(self): return self.deletedNode.id def undo(self): #print "DELETED NODE: ", self.deletedNode.id #print "INSERTING UNDER: ", self.parentNode.id n=self.tree.add_list(name=self.deletedNode.id, id=self.deletedNode.id, flag=self.deletedNode.expandable_flag, expanded_icon=self.deletedNode.expanded_icon, collapsed_icon=self.deletedNode.collapsed_icon) #print "INSERTING NODE: ", n[0].id self.parentNode.insert_children(n) def execute(self): self.deletedNode = self.tree.cursor_node([]) if self.deletedNode.expandable(): showerror("Oops...", "Can't delete a directory.") return 0 #print "DELETED NODE: ", self.deletedNode.id self.parentNode = self.deletedNode.parent() self.deletedNode.delete() return 1 class FindCommand(Command): def __init__(self, t): Command.__init__(self, "Find") self.tree = t self.oldCursor = self.tree.cursor_node([]) self.oldName = self.oldCursor.id def undo(self): tree.first() rootNode = tree.cursor_node([]) foundNode = [] self.findNode(rootNode, self.oldName, foundNode) if foundNode: self.tree.move_cursor(foundNode[0]) else: #print "Going back to root!" tree.first() rootNode = tree.cursor_node([]) self.tree.move_cursor(rootNode) # I wrote my own findNode, 'cuz I don't # believe that find_full_id works on Earth!! def findNode(self, dir, name, foundNode): temp = dir.children() for file in temp: #print "LOOKING AT: ", file.id, " and ", name if file.id == name: foundNode.append(file) if file.expandable(): self.findNode(file, name, foundNode) def execute(self): name = tkSimpleDialog.askstring('filename', 'Type filename: ') if name == "" or name == None: return tree.first() rootNode = tree.cursor_node([]) foundNode = [] self.findNode(rootNode, name, foundNode) if foundNode: #print "FOUND: ", foundNode[0].id self.tree.move_cursor(foundNode[0]) else: showerror("Oops...", name+" not found.") if __name__ == '__main__': root=Tk() root.title("File System Manager") # create the control tree=Tree.Tree(master=root, #root_id=os.sep, root_id=os.getcwd(), #root_label=os.sep, root_label=os.path.join(os.getcwd()), get_contents_callback=getfiles, width=300) tree.grid(row=0, column=0, sticky='nsew') root.grid_rowconfigure(0, weight=1) root.grid_columnconfigure(0, weight=1) sb=Scrollbar(root) sb.grid(row=0, column=1, sticky='ns') tree.configure(yscrollcommand=sb.set) sb.configure(command=tree.yview) sb=Scrollbar(root, orient=HORIZONTAL) sb.grid(row=1, column=0, sticky='ew') tree.configure(xscrollcommand=sb.set) sb.configure(command=tree.xview) man = FileManager(tree) frm = Frame() Button(frm, text='Quit', command=man.doQuit).pack(side=LEFT) Button(frm, text='Undo', command=man.doUndo).pack(side=RIGHT) Button(frm, text='Delete', command=man.doDelete).pack(side=RIGHT) findBut = Button(frm, text='Find', command=man.doFind,underline=0) findBut.pack(side=RIGHT) root.bind('', lambda e:man.doFind()) frm.grid(row=2, column=0, columnspan=2) tree.focus_set() tree.root.expand() root.mainloop()