class FilePickEdit(Frame): def __init__(self, master, file_mask, default_file, edit_height = None, user_onChange = None, rename_on_edit=0, font = None, coloring=True, allowNone=False, highlighter=None, directory='.'): """ file_mask: file mask (e.g. "*.foo") or list of file masks (e.g. ["*.foo", "*.abl"]) """ self.master = master self.directory = directory self.user_onChange = user_onChange Frame.__init__(self, master) row = 0 self.unmodified = True self.allowNone = allowNone self.file_extension = "" if type(file_mask) != list: file_mask = [file_mask] if "." in file_mask[0]: self.file_extension = file_mask[0][file_mask[0].rfind('.'):] # read filenames self.file_mask = file_mask self.updateList() # filename frame self.list_frame = Frame(self) self.list_frame.grid(row=row, column=0, sticky="WE") self.list_frame.columnconfigure(0, weight=1) # create list self.picked_name = StringVar() self.makelist() # refresh button self.refresh_button = Button(self.list_frame, text='<- refresh', command=self.refresh, height=1) self.refresh_button.grid(row=0, column=1, sticky='E') # save button self.save_button = Button(self.list_frame, text="save", command=self.save, height=1) self.save_button.grid(row=0, column=2, sticky="E") # editor row += 1 if coloring: self.editor = SyntaxHighlightingText(self, self.onEdit, highlighter=highlighter) else: self.editor = ScrolledText2(self, self.onEdit) if font is not None: self.editor.configure(font=font) if edit_height is not None: self.editor.configure(height=edit_height) self.editor.grid(row=row, column=0, sticky="NEWS") self.rowconfigure(row, weight=1) self.columnconfigure(0, weight=1) # option to change filename on edit row += 1 self.options_frame = Frame(self) self.options_frame.grid(row=row, column=0, sticky=W) self.rename_on_edit = IntVar() self.cb = Checkbutton(self.options_frame, text="rename on edit", variable=self.rename_on_edit) self.cb.pack(side=LEFT) self.cb.configure(command=self.onChangeRename) self.rename_on_edit.set(rename_on_edit) # filename frame row += 1 self.filename_frame = Frame(self) self.filename_frame.grid(row=row, column=0, sticky="WE") self.filename_frame.columnconfigure(0, weight=1) # save as filename self.save_name = StringVar() self.save_edit = Entry(self.filename_frame, textvariable = self.save_name) self.save_edit.grid(row=0, column=0, sticky="WE") self.save_name.trace("w", self.onSaveChange) # pick default if applicableButton self.select(default_file) self.row = row def setDirectory(self, directory, keep=False): self.directory = directory self.updateList() self.makelist() # menu = self.list["menu"] scrolledlist # menu = self.list.listbox#["scrolledlist"] # menu.delete(0, 'end') # add the new ones # for filename in self.files: # menu.add_command(label=filename, command=_setit(self.picked_name, filename, None)) # if keep is true, only the files list will be updated but the content of the # text area will not be altered/removed if not keep: self.select("") def refresh(self): sel = self.get() self.updateList() self.select(sel, notify=False) def reloadFile(self): self.editor.delete("1.0", END) filename = self.picked_name.get() if os.path.exists(os.path.join(self.directory, filename)): new_text = open(os.path.join(self.directory, filename)).read() if new_text.strip() == "": new_text = "// %s is empty\n" % filename new_text = new_text.replace("\r", "") else: new_text = "" self.editor.insert(INSERT, new_text) def setText(self, txt): """ Replaces the text in the edit field as by typing into it. """ self.select("") if txt.strip() == "": txt = "// empty database\n" self.editor.insert(INSERT, txt) self.onEdit() def onSelChange(self): self.reloadFile() filename = self.picked_name.get() self.save_name.set(filename) self.save_edit.configure(state=DISABLED) self.unmodified = True if self.user_onChange is not None: self.user_onChange(filename) def onSaveChange(self, name, index, mode): pass def autoRename(self): # modify "save as" name filename = self.picked_name.get() if filename == "": filename = "new" + self.file_extension # if no file selected, create new filename ext = "" extpos = filename.rfind(".") if extpos != -1: ext = filename[extpos:] base = filename[:extpos] hpos = base.rfind("-") num = 0 if hpos != -1: try: num = int(base[hpos+1:]) base = base[:hpos] except: pass while True: num += 1 filename = "%s-%d%s" % (base, num, ext) if not os.path.exists(filename): break self.save_name.set(filename) # user callback if self.user_onChange is not None: self.user_onChange(filename) def onEdit(self): if self.unmodified: self.unmodified = False # do auto rename if it's enabled or there is no file selected (editing new file) if self.rename_on_edit.get() == 1 or self.picked_name.get() == "": self.autoRename() # enable editing of save as name self.save_edit.configure(state=NORMAL) def onChangeRename(self): # called when clicking on "rename on edit" checkbox if self.rename_on_edit.get() == 1: if (not self.unmodified) and self.save_name.get() == self.picked_name.get(): self.autoRename() else: self.save_name.set(self.picked_name.get()) def updateList(self): self.files = [] if self.allowNone: self.files.append("") if os.path.exists(self.directory): for filename in os.listdir(self.directory): for fm in self.file_mask: if fnmatch(filename, fm): self.files.append(filename) self.files.sort() if len(self.files) == 0 and not self.allowNone: self.files.append("(no %s files found)" % str(self.file_mask)) def select(self, filename, notify=True): """ selects the item given by filename """ if filename in self.files: if not havePMW: self.picked_name.set(filename) else: self.list.selectitem(self.files.index(filename)) if notify: self.onSelChange(filename) else: self.editor.delete("1.0", END) def makelist(self): if havePMW: self.list = ComboBox(self.list_frame, selectioncommand = self.onSelChange, scrolledlist_items = self.files, ) self.list.grid(row=0, column=0, padx=0, pady=0, sticky="NEWS") self.list.component('entryfield').component('entry').configure(state = 'readonly', relief = 'raised') self.picked_name = self.list else: self.list = OptionMenu(*(self.list_frame, self.picked_name) + tuple(self.files)) self.list.grid(row=0, column=0, sticky="NEW") self.picked_name.trace("w", self.onSelChange) def save(self): self.get() def set(self, selected_item): self.select(selected_item) def get(self): """ gets the name of the currently selected file, saving it first if necessary """ filename = self.save_name.get() if self.unmodified == False: self.unmodified = True # save the file f = open(os.path.join(self.directory, filename), "w") f.write(self.editor.get("1.0", END).encode('utf-8')) f.close() # add it to the list of files # if not filename in self.files: # self.files.append(filename) # self.files.sort() # self.list.destroy() # self.makelist() # set it as the new pick #if havePMW: # self.picked_name.selectitem(self.files.index(filename), 1) #else: # self.picked_name.set(filename) # self.select(filename) self.refresh() self.select(filename, notify=False) self.save_edit.configure(state=DISABLED) return filename def get_text(self): return self.editor.get("1.0", END) def get_filename(self): return self.save_name.get() def set_enabled(self, state): self.editor.configure(state=state) if havePMW: self.list.component('entryfield_entry').configure(state=state) # self.list.component('arrowbutton').configure(state=state) self.list.component('arrowbutton').bind('<1>', (lambda a: 'break') if state==DISABLED else self.list._postList) else: self.list.configure(state=state) self.save_button.configure(state=state) self.cb.configure(state=state) self.save_edit.configure(state=state)
class FilePick(Frame): def __init__(self, master, file_mask, default_file, user_onChange = None, font = None, dirs = (".", ), allowNone = False): """ file_mask: file mask or list of file masks """ self.master = master self.user_onChange = user_onChange Frame.__init__(self, master) self.columnconfigure(0, weight=1) self.unmodified = True self.file_extension = "" if "." in file_mask: self.file_extension = file_mask[file_mask.rfind('.'):] if type(file_mask) != list: file_mask = [file_mask] self.file_masks = file_mask self.allowNone = allowNone self.dirs = dirs # create list of files self.updateList() # pick default if applicable self.set(default_file) def onSelChange(self, name, index=0, mode=0): filename = self.picked_name.get() if self.user_onChange != None: self.user_onChange(filename) def updateList(self): prev_sel = self.get() # get list of files (paths) self.files = [] if self.allowNone: self.files.append("") for fm in self.file_masks: for dir in self.dirs: try: for filename in os.listdir(dir): if fnmatch(filename, fm): if dir != ".": path = os.path.join(dir, filename) else: path = filename self.files.append(path) except: pass self.files.sort() if len(self.files) == 0: self.files.append("(no %s files found)" % self.file_masks) # create list object self._makelist() # reselect self.set(prev_sel) def getList(self): """ returns the current list of files """ return self.files def _makelist(self): if havePMW: self.list = ComboBox(self, selectioncommand = self.onSelChange, scrolledlist_items = self.files, ) self.list.grid(row=0, column=0, padx=0, sticky="NEWS") self.list.component('entryfield').component('entry').configure(state = 'readonly', relief = 'raised') self.picked_name = self.list else: self.picked_name = StringVar() self.list = OptionMenu(*(self, self.picked_name) + tuple(self.files)) self.list.grid(row=0, column=0, sticky="NEW") self.picked_name.trace("w", self.onSelChange) def set(self, filename): default_file = filename if default_file in self.files: if not havePMW: self.picked_name.set(default_file) # default value else: self.list.selectitem(self.files.index(default_file)) self.onSelChange(default_file) pass def get(self): if not hasattr(self, 'picked_name'): return None return self.picked_name.get()
class DropdownList: def __init__(self, master, filemask='*.mln', default=None, allowNone=False, onselchange=None, directory='.'): self.allowNone = allowNone self.directory = directory self.list_frame = master self.onchange = onselchange if type(filemask) != list: filemask = [filemask] self.file_mask = filemask self.updateList() if havePMW: self.list = ComboBox(master, selectioncommand=onselchange, scrolledlist_items = self.files) self.list.component('entryfield').component('entry').configure(state = 'readonly', relief = 'raised') self.picked_name = self.list else: self.picked_name = StringVar() self.list = OptionMenu(*(master, self.picked_name) + tuple(self.files)) if onselchange is not None: self.picked_name.trace("w", self.onchange) if default is not None: self.select(default) else: self.select(self.files[0]) def __getattr__(self, name): return getattr(self.list, name) def get(self): return self.picked_name.get() def select(self, item): if item in self.files: if not havePMW: self.picked_name.set(item) else: self.list.selectitem(item) def updateList(self): self.files = [] if self.allowNone: self.files.append("") if os.path.exists(self.directory): for filename in os.listdir(self.directory): for fm in self.file_mask: if fnmatch(filename, fm): self.files.append(filename) self.files.sort() if len(self.files) == 0 and not self.allowNone: self.files.append("(no %s files found)" % str(self.file_mask)) def makelist(self): if havePMW: self.list = ComboBox(self.list_frame, selectioncommand = self.onSelChange, scrolledlist_items = self.files, ) self.list.grid(row=0, column=0, padx=0, pady=0, sticky="NEWS") self.list.component('entryfield').component('entry').configure(state = 'readonly', relief = 'raised') self.picked_name = self.list else: self.list = OptionMenu(*(self.list_frame, self.picked_name) + tuple(self.files)) self.list.grid(row=0, column=0, sticky="NEW") self.picked_name.trace("w", self.onSelChange) self.select(self.files[0]) def setDirectory(self, directory, keep=False): self.directory = directory self.updateList() self.makelist() # if keep is true, only the files list will be updated but the content of the # text area will not be altered/removed if not keep: self.select("") def onSelChange(self, name, index=0, mode=0): filename = self.picked_name.get() if self.onchange != None: self.onchange(filename)