class searchDialog(Toplevel): def __init__(self, parent, title): self.top = Toplevel(parent) self.top.wm_title(title) self.top.wm_minsize(width=300, height=400) self.top.bind("<Return>", self.searchThreader) self.top.bind("<Escape>", self.close) self.searchy = Text(self.top) self.searchy.config(wrap=WORD) self.search_entry = Entry(self.top) self.close = Button(self.top, text="Close", command=self.close) self.search_button = Button(self.top, text="Search", command=self.searchThreader) self.scrollbar = Scrollbar(self.top) self.scrollbar.pack(side=RIGHT, fill=Y, expand=0) self.searchy.config(yscrollcommand=self.scrollbar.set, state=DISABLED) self.searchy.pack(side=TOP, fill=BOTH, expand=1) self.search_entry.pack(side=LEFT, fill=X, expand=1) self.close.pack(side=RIGHT, fill=BOTH, expand=0) self.search_button.pack(side=RIGHT, fill=BOTH, expand=0) self.linker = HyperlinkManager(self.searchy) def close(self, event=None): global SEARCH SEARCH = None self.top.destroy() def putText(self, text): updateDisplay(text, self.searchy, self.linker) def clearSearch(self): self.searchy.config(state=NORMAL) self.searchy.delete(1.0, END) self.searchy.config(state=DISABLED) def searchThreader(self, event=None, text=None): self.sear = upThread(6, 'search', (self, text)) self.sear.start() def search(self, toSearch=None): if toSearch is None: keyword = self.search_entry.get() self.search_entry.delete(0, END) else: keyword = toSearch self.clearSearch() self.top.wm_title("Search - " + keyword) if keyword.split('@')[0] == '': self.putText( API.GetUserTimeline( screen_name=keyword.split('@')[1] ) ) else: self.putText(API.GetSearch(term=keyword))
def select_start_options(self): ''' popup box to select side and difficulty levels ''' print 'select game start options' popup = Toplevel(self.gui, width=300, height=110) popup.title('Choose Game Side and Level') # stays on top of the game canvass popup.transient(self.gui) popup.grab_set() # bind window close events popup.bind('<Escape>', lambda e: self.not_selected_start_options(popup)) popup.protocol("WM_DELETE_WINDOW", lambda : self.not_selected_start_options(popup)) # choose side label1 = Label(popup, text="Side", height=30, width=50) label1.place(x=10, y=5, height=30, width=50) val1 = IntVar() bt_north = Radiobutton(popup, text="White", variable=val1, value=1) bt_north.place(x=60, y=10) bt_south = Radiobutton(popup, text="Black", variable=val1, value=2) bt_south.place(x=120, y=10) # by default, human plays first, meaning play the north side if self.choose_side == 'north': bt_north.select() else: bt_south.select() # choose difficulty level label2 = Label(popup, text="Level", height=30, width=50) label2.place(x=10, y=35, height=30, width=50) val2 = IntVar() bt_level1 = Radiobutton(popup, text="Dumb", variable=val2, value=1) bt_level1.place(x=60, y=40) bt_level2 = Radiobutton(popup, text="Smart", variable=val2, value=2) bt_level2.place(x=120, y=40) bt_level3 = Radiobutton(popup, text="Genius", variable=val2, value=3) bt_level3.place(x=180, y=40) # by default, the game is medium level if self.choose_level == 1: bt_level1.select() elif self.choose_level == 2: bt_level2.select() elif self.choose_level == 3: bt_level3.select() button = Button(popup, text='SET', \ command=lambda: self.selected_start_options(popup, val1, val2)) button.place(x=70, y=70)
def popupControls(self, tl = None): from direct.showbase import TkGlobal import math from Tkinter import Toplevel, Frame, Button, LEFT, X import Pmw from direct.tkwidgets import EntryScale if tl == None: tl = Toplevel() tl.title('Interval Controls') outerFrame = Frame(tl) def entryScaleCommand(t, s = self): s.setT(t) s.pause() self.es = es = EntryScale.EntryScale(outerFrame, text=self.getName(), min=0, max=math.floor(self.getDuration() * 100) / 100, command=entryScaleCommand) es.set(self.getT(), fCommand=0) es.pack(expand=1, fill=X) bf = Frame(outerFrame) def toStart(s = self, es = es): s.clearToInitial() es.set(0, fCommand=0) def toEnd(s = self): s.pause() s.setT(s.getDuration()) es.set(s.getDuration(), fCommand=0) s.pause() jumpToStart = Button(bf, text='<<', command=toStart) def doPlay(s = self, es = es): s.resume(es.get()) stop = Button(bf, text='Stop', command=lambda s = self: s.pause()) play = Button(bf, text='Play', command=doPlay) jumpToEnd = Button(bf, text='>>', command=toEnd) jumpToStart.pack(side=LEFT, expand=1, fill=X) play.pack(side=LEFT, expand=1, fill=X) stop.pack(side=LEFT, expand=1, fill=X) jumpToEnd.pack(side=LEFT, expand=1, fill=X) bf.pack(expand=1, fill=X) outerFrame.pack(expand=1, fill=X) def update(t, es = es): es.set(t, fCommand=0) if not hasattr(self, 'setTHooks'): self.setTHooks = [] self.setTHooks.append(update) def onDestroy(e, s = self, u = update): if u in s.setTHooks: s.setTHooks.remove(u) tl.bind('<Destroy>', onDestroy) return
class LBChoice(object): '''This is a listbox for returning projects to be unarchived.''' def __init__(self, list_=None, master=None, title=None): '''Must have master, title is optional, li is too.''' self.master = master if self.master is not None: self.top = Toplevel(self.master) else: return self.v = None if list_ is None or not isinstance(list_, list): self.list = [] else: self.list = list_[:] self.top.transient(self.master) self.top.grab_set() self.top.bind("<Return>", self._choose) self.top.bind("<Escape>", self._cancel) if title: self.top.title(title) lf = Frame(self.top) #Sets up the list. lf.pack(side=TOP) scroll_bar = Scrollbar(lf) scroll_bar.pack(side=RIGHT, fill=Y) self.lb = Listbox(lf, selectmode=SINGLE) self.lb.pack(side=LEFT, fill=Y) scroll_bar.config(command=self.lb.yview) self.lb.config(yscrollcommand=scroll_bar.set) self.list.sort() for item in self.list: self.lb.insert(END, item) #Inserts items into the list. bf = Frame(self.top) bf.pack(side=BOTTOM) Button(bf, text="Select", command=self._choose).pack(side=LEFT) Button(bf, text="New", command=self._new).pack(side=LEFT) Button(bf, text="Cancel", command=self._cancel).pack(side=LEFT) def _choose(self, event=None): try: first = self.lb.curselection()[0] self.v = self.list[int(first)] except IndexError: self.v = None self.top.destroy() def _new(self, event=None): self.v = "NEW" self.top.destroy() def _cancel(self, event=None): self.top.destroy() def return_value(self): self.master.wait_window(self.top) return self.v
class LBChoice(object): '''This is a listbox for returning projects to be unarchived.''' def __init__(self, list_=None, master=None, title=None): '''Must have master, title is optional, li is too.''' self.master = master if self.master is not None: self.top = Toplevel(self.master) else: return self.v = None if list_ is None or not isinstance(list_, list): self.list = [] else: self.list = list_[:] self.top.transient(self.master) self.top.grab_set() self.top.bind("<Return>", self._choose) self.top.bind("<Escape>", self._cancel) if title: self.top.title(title) lf = Frame(self.top) #Sets up the list. lf.pack(side=TOP) scroll_bar = Scrollbar(lf) scroll_bar.pack(side=RIGHT, fill=Y) self.lb = Listbox(lf, selectmode=SINGLE) self.lb.pack(side=LEFT, fill=Y) scroll_bar.config(command=self.lb.yview) self.lb.config(yscrollcommand=scroll_bar.set) self.list.sort() for item in self.list: self.lb.insert(END, item) #Inserts items into the list. bf = Frame(self.top) bf.pack(side=BOTTOM) Button(bf, text="Select", command=self._choose).pack(side=LEFT) Button(bf, text="New", command=self._new).pack(side=LEFT) Button(bf, text="Cancel", command=self._cancel).pack(side=LEFT) def _choose(self, event=None): try: first = self.lb.curselection()[0] self.v = self.list[int(first)] except IndexError: self.v = None self.top.destroy() def _new(self, event=None): self.v = "NEW" self.top.destroy() def _cancel(self, event=None): self.top.destroy() def return_value(self): self.master.wait_window(self.top) return self.v
def create_widgets(self): top = Toplevel(self.root) top.bind("<Return>", self.default_command) top.bind("<Escape>", self.close) top.protocol("WM_DELETE_WINDOW", self.close) top.wm_title(self.title) top.wm_iconname(self.icon) top.resizable(height=False, width=False) self.ttop = top self.top = Frame(top) self.row = 0 self.top.grid(sticky='news') self.create_entries() self.create_option_buttons() self.create_other_buttons() self.create_command_buttons()
def create_widgets(self): top = Toplevel(self.root) top.bind("<Return>", self.default_command) top.bind("<Escape>", self.close) top.protocol("WM_DELETE_WINDOW", self.close) top.wm_title(self.title) top.wm_iconname(self.icon) top.resizable(height=False, width=False) self.ttop = top self.top = Frame(top) self.row = 0 self.top.grid(sticky='news') self.create_entries() self.create_option_buttons() self.create_other_buttons() self.create_command_buttons()
def create_widgets(self): '''Create basic 3 row x 3 col search (find) dialog. Other dialogs override subsidiary create_x methods as needed. Replace and Find-in-Files add another entry row. ''' top = Toplevel(self.root) top.bind("<Return>", self.default_command) top.bind("<Escape>", self.close) top.protocol("WM_DELETE_WINDOW", self.close) top.wm_title(self.title) top.wm_iconname(self.icon) self.top = top self.row = 0 self.top.grid_columnconfigure(0, pad=2, weight=0) self.top.grid_columnconfigure(1, pad=2, minsize=100, weight=100) self.create_entries() # row 0 (and maybe 1), cols 0, 1 self.create_option_buttons() # next row, cols 0, 1 self.create_other_buttons() # next row, cols 0, 1 self.create_command_buttons() # col 2, all rows
def create_widgets(self): '''Create basic 3 row x 3 col search (find) dialog. Other dialogs override subsidiary create_x methods as needed. Replace and Find-in-Files add another entry row. ''' top = Toplevel(self.root) top.bind("<Return>", self.default_command) top.bind("<Escape>", self.close) top.protocol("WM_DELETE_WINDOW", self.close) top.wm_title(self.title) top.wm_iconname(self.icon) self.top = top self.row = 0 self.top.grid_columnconfigure(0, pad=2, weight=0) self.top.grid_columnconfigure(1, pad=2, minsize=100, weight=100) self.create_entries() # row 0 (and maybe 1), cols 0, 1 self.create_option_buttons() # next row, cols 0, 1 self.create_other_buttons() # next row, cols 0, 1 self.create_command_buttons() # col 2, all rows
def popupControls(self, tl = None): """ Popup control panel for interval. """ from direct.showbase import TkGlobal import math # I moved this here because Toontown does not ship Tk from Tkinter import Toplevel, Frame, Button, LEFT, X import Pmw from direct.tkwidgets import EntryScale if tl == None: tl = Toplevel() tl.title('Interval Controls') outerFrame = Frame(tl) def entryScaleCommand(t, s=self): s.setT(t) s.pause() self.es = es = EntryScale.EntryScale( outerFrame, text = self.getName(), min = 0, max = math.floor(self.getDuration() * 100) / 100, command = entryScaleCommand) es.set(self.getT(), fCommand = 0) es.pack(expand = 1, fill = X) bf = Frame(outerFrame) # Jump to start and end def toStart(s=self, es=es): s.clearToInitial() es.set(0, fCommand = 0) def toEnd(s=self): s.pause() s.setT(s.getDuration()) es.set(s.getDuration(), fCommand = 0) s.pause() jumpToStart = Button(bf, text = '<<', command = toStart) # Stop/play buttons def doPlay(s=self, es=es): s.resume(es.get()) stop = Button(bf, text = 'Stop', command = lambda s=self: s.pause()) play = Button( bf, text = 'Play', command = doPlay) jumpToEnd = Button(bf, text = '>>', command = toEnd) jumpToStart.pack(side = LEFT, expand = 1, fill = X) play.pack(side = LEFT, expand = 1, fill = X) stop.pack(side = LEFT, expand = 1, fill = X) jumpToEnd.pack(side = LEFT, expand = 1, fill = X) bf.pack(expand = 1, fill = X) outerFrame.pack(expand = 1, fill = X) # Add function to update slider during setT calls def update(t, es=es): es.set(t, fCommand = 0) if not hasattr(self, "setTHooks"): self.setTHooks = [] self.setTHooks.append(update) # Clear out function on destroy def onDestroy(e, s=self, u=update): if u in s.setTHooks: s.setTHooks.remove(u) tl.bind('<Destroy>', onDestroy)
def select_start_options(self): ''' popup box to select side and difficulty levels ''' print 'select game start options' popup = Toplevel(self.gui, width=300, height=110) popup.title('Choose Game Side and Level') # stays on top of the game canvass popup.transient(self.gui) popup.grab_set() # bind window close events popup.bind('<Escape>', lambda e: self.not_selected_start_options(popup)) popup.protocol("WM_DELETE_WINDOW", lambda: self.not_selected_start_options(popup)) # choose side label1 = Label(popup, text="Side", height=30, width=50) label1.place(x=10, y=5, height=30, width=50) val1 = IntVar() bt_north = Radiobutton(popup, text="White", variable=val1, value=1) bt_north.place(x=60, y=10) bt_south = Radiobutton(popup, text="Black", variable=val1, value=2) bt_south.place(x=120, y=10) # by default, human plays first, meaning play the north side if self.choose_side == 'north': bt_north.select() else: bt_south.select() # choose difficulty level label2 = Label(popup, text="Level", height=30, width=50) label2.place(x=10, y=35, height=30, width=50) val2 = IntVar() bt_level1 = Radiobutton(popup, text="Dumb", variable=val2, value=1) bt_level1.place(x=60, y=40) bt_level2 = Radiobutton(popup, text="Smart", variable=val2, value=2) bt_level2.place(x=120, y=40) bt_level3 = Radiobutton(popup, text="Genius", variable=val2, value=3) bt_level3.place(x=180, y=40) # by default, the game is medium level if self.choose_level == 1: bt_level1.select() elif self.choose_level == 2: bt_level2.select() elif self.choose_level == 3: bt_level3.select() button = Button(popup, text='SET', \ command=lambda: self.selected_start_options(popup, val1, val2)) button.place(x=70, y=70)
class App(Frame): results_window = False def __init__(self, *args, **kwargs): Frame.__init__(self, *args, **kwargs) self.__init_main(*args, **kwargs) def __init_main(self, *args, **kwargs): self.root = args[0] self.root.filename = "" self.root.wm_title("RSTool") self.root.protocol("WM_DELETE_WINDOW", self.__delete_root_window) self.root.bind("<Destroy>", self.__destroy_root_window) self.menubar = Menu(self.root) self.filemenu = Menu(self.menubar) self.filemenu.add_command(label="Save as...", command=self.save_to_file) self.filemenu.add_separator() self.filemenu.add_command(label="Exit", command=self.root.destroy) self.menubar.add_cascade(label="File", menu=self.filemenu) self.root.config(menu=self.menubar) self.tests = [ Frequency, BlockFrequency, Runs, LongestRunOfOnes, Rank, DiscreteFourierTransform, Universal, Serial, ApproximateEntropy, CumulativeSums, RandomExcursions, RandomExcursionsVariant, ] self.slowtests = [ NonOverlappingTemplateMatching, # Slow OverlappingTemplateMatching, # Slow LinearComplexity # Slow ] # self.run_RandomWalkPlot = IntVar(self.root) rcounter = 0 # Create and pack the title row: title = "NYUAD\nCenter for Cyber Security\nRandomness Testing Tool\nv0.9.0" self.l1 = Label(self.root, text=title) self.l1.grid(column=0, row=rcounter, columnspan=2, sticky=N) # self.l1.pack() rcounter += 1 # Create and pack the "Open File" button and bind the loadFile method: self.b1 = Button(self.root, text="Open File", command=self.loadFile) self.b1.grid(column=0, row=rcounter, columnspan=1, pady=5) # rcounter += 1 # self.b1.pack() # Create and pack the filename: self.l2 = Label(self.root, text=self.root.filename) self.l2.grid(column=1, row=rcounter, columnspan=2, sticky=W, padx=(5, 10)) # self.l1.pack() rcounter += 1 # Create textbox for bit-limit self.nl = Label(self.root, text="Number of bits to test: (0 to test all)") self.nl.grid(column=0, row=rcounter, columnspan=1) rcounter += 1 self.nt = Text(self.root, state="normal", width="15", height="1") self.nt.insert(END, "0") self.nt.grid(column=0, row=rcounter, columnspan=1, padx=10, pady=(0, 5)) rcounter += 1 # Create and pack the "Select/Deselect All" button and bind the checkAll method: self.b2 = Button(self.root, text="Select/Deselect All Tests", command=self.checkAll) self.b2.grid(column=0, row=rcounter, columnspan=1, pady=(0, 5)) rcounter += 1 # self.b2.pack() # Create and pack the "Select/Deselect Fast" button and bind the checkFast method: self.b3 = Button(self.root, text="Select/Deselect Fast Tests", command=self.checkFast) self.b3.grid(column=0, row=rcounter, columnspan=1, pady=(0, 5)) rcounter += 1 # self.b2.pack() # Create and pack the "Select/Deselect Slow" button and bind the checkSlow method: self.b4 = Button(self.root, text="Select/Deselect Slow Tests", command=self.checkSlow) self.b4.grid(column=0, row=rcounter, columnspan=1, pady=(0, 5)) rcounter += 1 # self.b2.pack() # Set IntVars for each test to check if it is selected to run: for test in self.tests + self.slowtests: setvar = "self.run_%s = IntVar(self.root)" % (test.__name__) exec(setvar) setvar = "" for i in range(func_data[test.__name__][1]): setvar = "self.%s_arg_%s = IntVar(self.root)" % ( test.__name__, func_data[test.__name__][2][i]) # Example: # self.run_Frequency = IntVar(self.root) # Create and pack the checkbutton for each test and bind its IntVar to it: for test in self.tests + self.slowtests: make = [ "self.cb_%s = " % (test.__name__), "Checkbutton(self.root, ", "text='%s ', " % (func_data[test.__name__][0]), "variable=self.run_%s)" % (test.__name__) ] make = "".join(make) grid = [ "self.cb_%s.grid(" % (test.__name__), "column=0, row=%d, sticky=W)" % rcounter ] grid = "".join(grid) # args stuff rcounter += 1 # pack = "self.cb_%s.pack()" % (test.__name__) exec(make) exec(grid) # exec(pack) # Example: # self.cb1 = Checkbutton(self.root, text="Frequency", # variable=self.run_Frequency) # self.cb1.pack() # Create and pack the "Run Tests" button and bind the runTests method: self.rb = Button(self.root, text="Run Tests", command=self.runTests) self.rb.grid(column=0, row=rcounter, columnspan=2) rcounter += 1 # self.rb.pack() self.root.resizable(0, 0) self.root.lift() self.root.attributes('-topmost', True) self.root.after_idle(self.root.attributes, '-topmost', False) def __delete_root_window(self): # print "delete_root_window" try: self.root.destroy() except: pass def __destroy_root_window(self, event): # print "destroy_root_window", event pass def __delete_results_window(self): # print "delete_results_window" try: self.results_window.destroy() except: pass def __destroy_results_window(self, event): # print "destroy_results_window", event self.results_window = False def __make_results_window(self): # wname = "results_window" self.results_window = Toplevel(self, name="results_window") self.results_window.protocol("WM_DELETE_WINDOW", self.__delete_results_window) self.results_window.bind("<Destroy>", self.__destroy_results_window) self.results_window.wm_title("Test Results") self.results_window.config(menu=self.menubar) self.results_save_button = Button(self.results_window, text="Save to File", command=self.save_to_file) self.results_save_button.pack() self.results_text = Text(self.results_window, state="normal", width="70", height="50") self.results_text.pack(fill="both", expand=True, padx=10) def loadFile(self): # print "loadFile called!" self.root.filename = tkFileDialog.askopenfilename( initialdir=".", title="Select file...") # print (self.root.filename) # self.l2.config(text=self.root.filename) def save_to_file(self): if self.results_window: self.root.outfile = tkFileDialog.asksaveasfile( mode='w', defaultextension=".txt", initialdir=".", initialfile="output", title="Save as...") data = str(self.results_text.get(0.0, END)) self.root.outfile.write(data) self.root.outfile.close() def checkAll(self): all_checked = 1 for test in self.tests + self.slowtests: if not eval('self.run_' + test.__name__ + '.get()'): all_checked = 0 val = 1 - all_checked for test in self.tests + self.slowtests: eval('self.run_' + test.__name__).set(val) def checkFast(self): all_checked = 1 for test in self.tests: if not eval('self.run_' + test.__name__ + '.get()'): all_checked = 0 val = 1 - all_checked for test in self.tests: eval('self.run_' + test.__name__).set(val) def checkSlow(self): all_checked = 1 for test in self.slowtests: if not eval('self.run_' + test.__name__ + '.get()'): all_checked = 0 val = 1 - all_checked for test in self.slowtests: eval('self.run_' + test.__name__).set(val) def text_insert(self, text, noret=False): if not self.results_window: self.__make_results_window() place = 'end' if not self.results_text: raise Exception("results_text does not exist") if type(text) != str: raise TypeError("Expected str, got %s: %s" % (type(text), text)) # self.results_text.configure(state="normal") # enables changing content self.results_text.insert(place, text + ["\n", ""][noret]) self.update_idletasks() # self.results_text.configure(state="disabled") # relocks the content def getn(self): return int(self.nt.get("1.0", END)) def setn(self, n): self.nt.delete(1.0, END) self.nt.insert(END, str(int(n))) def runTests(self): if self.results_window: self.__delete_results_window() cont = True try: n = self.getn() if n < 0: raise ValueError except Exception as e: print 'Error:', e self.setn("0") cont = False if cont: try: if self.root.filename == "": raise ValueError("No file selected") e = read_data(self.root.filename) if n == 0: n = len(e) e = e[:n] if len(e) == 0: raise LengthError("No data in file") out = "Data read:\n" out += "e = " out += "".join([str(i) for i in e][:min(32, len(e))]) out += ["", "..."][len(e) > 32] + "\n" out += "See test_results folder for detailed results\n" self.text_insert(out) except: self.text_insert("Failed to read data.") cont = False if cont: # for test in self.tests: # self.text_insert("self.run_" + test.__name__ + " = " + str(eval( # "self.run_" + test.__name__ + ".get()"))) test_dir = "./test_results" if not os.path.exists(test_dir): os.makedirs(test_dir) for test in self.tests + self.slowtests: try: if eval("self.run_" + test.__name__ + ".get()"): self.text_insert("Running " + test.__name__ + ":") output = test(e) self.text_insert(["Non-Random", "Random"][output]) self.text_insert("\n") except Exception as e: self.text_insert("\nError in %s: %s\n" % (test.__name__, e.__str__())) self.text_insert("Tests completed.")
class CFGEditor(object): """ A dialog window for creating and editing context free grammars. ``CFGEditor`` imposes the following restrictions: - All nonterminals must be strings consisting of word characters. - All terminals must be strings consisting of word characters and space characters. """ # Regular expressions used by _analyze_line. Precompile them, so # we can process the text faster. ARROW = SymbolWidget.SYMBOLS['rightarrow'] _LHS_RE = re.compile(r"(^\s*\w+\s*)(->|(" + ARROW + "))") _ARROW_RE = re.compile("\s*(->|(" + ARROW + "))\s*") _PRODUCTION_RE = re.compile(r"(^\s*\w+\s*)" + # LHS "(->|(" + ARROW + "))\s*" + # arrow r"((\w+|'[\w ]*'|\"[\w ]*\"|\|)\s*)*$") # RHS _TOKEN_RE = re.compile("\\w+|->|'[\\w ]+'|\"[\\w ]+\"|(" + ARROW + ")") _BOLD = ('helvetica', -12, 'bold') def __init__(self, parent, cfg=None, set_cfg_callback=None): self._parent = parent if cfg is not None: self._cfg = cfg else: self._cfg = ContextFreeGrammar(Nonterminal('S'), []) self._set_cfg_callback = set_cfg_callback self._highlight_matching_nonterminals = 1 # Create the top-level window. self._top = Toplevel(parent) self._init_bindings() self._init_startframe() self._startframe.pack(side='top', fill='x', expand=0) self._init_prodframe() self._prodframe.pack(side='top', fill='both', expand=1) self._init_buttons() self._buttonframe.pack(side='bottom', fill='x', expand=0) self._textwidget.focus() def _init_startframe(self): frame = self._startframe = Frame(self._top) self._start = Entry(frame) self._start.pack(side='right') Label(frame, text='Start Symbol:').pack(side='right') Label(frame, text='Productions:').pack(side='left') self._start.insert(0, self._cfg.start().symbol()) def _init_buttons(self): frame = self._buttonframe = Frame(self._top) Button(frame, text='Ok', command=self._ok, underline=0, takefocus=0).pack(side='left') Button(frame, text='Apply', command=self._apply, underline=0, takefocus=0).pack(side='left') Button( frame, text='Reset', command=self._reset, underline=0, takefocus=0, ).pack(side='left') Button(frame, text='Cancel', command=self._cancel, underline=0, takefocus=0).pack(side='left') Button(frame, text='Help', command=self._help, underline=0, takefocus=0).pack(side='right') def _init_bindings(self): self._top.title('CFG Editor') self._top.bind('<Control-q>', self._cancel) self._top.bind('<Alt-q>', self._cancel) self._top.bind('<Control-d>', self._cancel) #self._top.bind('<Control-x>', self._cancel) self._top.bind('<Alt-x>', self._cancel) self._top.bind('<Escape>', self._cancel) #self._top.bind('<Control-c>', self._cancel) self._top.bind('<Alt-c>', self._cancel) self._top.bind('<Control-o>', self._ok) self._top.bind('<Alt-o>', self._ok) self._top.bind('<Control-a>', self._apply) self._top.bind('<Alt-a>', self._apply) self._top.bind('<Control-r>', self._reset) self._top.bind('<Alt-r>', self._reset) self._top.bind('<Control-h>', self._help) self._top.bind('<Alt-h>', self._help) self._top.bind('<F1>', self._help) def _init_prodframe(self): self._prodframe = Frame(self._top) # Create the basic Text widget & scrollbar. self._textwidget = Text(self._prodframe, background='#e0e0e0', exportselection=1) self._textscroll = Scrollbar(self._prodframe, takefocus=0, orient='vertical') self._textwidget.config(yscrollcommand=self._textscroll.set) self._textscroll.config(command=self._textwidget.yview) self._textscroll.pack(side='right', fill='y') self._textwidget.pack(expand=1, fill='both', side='left') # Initialize the colorization tags. Each nonterminal gets its # own tag, so they aren't listed here. self._textwidget.tag_config('terminal', foreground='#006000') self._textwidget.tag_config('arrow', font='symbol') self._textwidget.tag_config('error', background='red') # Keep track of what line they're on. We use that to remember # to re-analyze a line whenever they leave it. self._linenum = 0 # Expand "->" to an arrow. self._top.bind('>', self._replace_arrows) # Re-colorize lines when appropriate. self._top.bind('<<Paste>>', self._analyze) self._top.bind('<KeyPress>', self._check_analyze) self._top.bind('<ButtonPress>', self._check_analyze) # Tab cycles focus. (why doesn't this work??) def cycle(e, textwidget=self._textwidget): textwidget.tk_focusNext().focus() self._textwidget.bind('<Tab>', cycle) prod_tuples = [(p.lhs(), [p.rhs()]) for p in self._cfg.productions()] for i in range(len(prod_tuples) - 1, 0, -1): if (prod_tuples[i][0] == prod_tuples[i - 1][0]): if () in prod_tuples[i][1]: continue if () in prod_tuples[i - 1][1]: continue print prod_tuples[i - 1][1] print prod_tuples[i][1] prod_tuples[i - 1][1].extend(prod_tuples[i][1]) del prod_tuples[i] for lhs, rhss in prod_tuples: print lhs, rhss s = '%s ->' % lhs for rhs in rhss: for elt in rhs: if isinstance(elt, Nonterminal): s += ' %s' % elt else: s += ' %r' % elt s += ' |' s = s[:-2] + '\n' self._textwidget.insert('end', s) self._analyze() # # Add the producitons to the text widget, and colorize them. # prod_by_lhs = {} # for prod in self._cfg.productions(): # if len(prod.rhs()) > 0: # prod_by_lhs.setdefault(prod.lhs(),[]).append(prod) # for (lhs, prods) in prod_by_lhs.items(): # self._textwidget.insert('end', '%s ->' % lhs) # self._textwidget.insert('end', self._rhs(prods[0])) # for prod in prods[1:]: # print '\t|'+self._rhs(prod), # self._textwidget.insert('end', '\t|'+self._rhs(prod)) # print # self._textwidget.insert('end', '\n') # for prod in self._cfg.productions(): # if len(prod.rhs()) == 0: # self._textwidget.insert('end', '%s' % prod) # self._analyze() # def _rhs(self, prod): # s = '' # for elt in prod.rhs(): # if isinstance(elt, Nonterminal): s += ' %s' % elt.symbol() # else: s += ' %r' % elt # return s def _clear_tags(self, linenum): """ Remove all tags (except ``arrow`` and ``sel``) from the given line of the text widget used for editing the productions. """ start = '%d.0' % linenum end = '%d.end' % linenum for tag in self._textwidget.tag_names(): if tag not in ('arrow', 'sel'): self._textwidget.tag_remove(tag, start, end) def _check_analyze(self, *e): """ Check if we've moved to a new line. If we have, then remove all colorization from the line we moved to, and re-colorize the line that we moved from. """ linenum = int(self._textwidget.index('insert').split('.')[0]) if linenum != self._linenum: self._clear_tags(linenum) self._analyze_line(self._linenum) self._linenum = linenum def _replace_arrows(self, *e): """ Replace any ``'->'`` text strings with arrows (char \\256, in symbol font). This searches the whole buffer, but is fast enough to be done anytime they press '>'. """ arrow = '1.0' while 1: arrow = self._textwidget.search('->', arrow, 'end+1char') if arrow == '': break self._textwidget.delete(arrow, arrow + '+2char') self._textwidget.insert(arrow, self.ARROW, 'arrow') self._textwidget.insert(arrow, '\t') arrow = '1.0' while 1: arrow = self._textwidget.search(self.ARROW, arrow + '+1char', 'end+1char') if arrow == '': break self._textwidget.tag_add('arrow', arrow, arrow + '+1char') def _analyze_token(self, match, linenum): """ Given a line number and a regexp match for a token on that line, colorize the token. Note that the regexp match gives us the token's text, start index (on the line), and end index (on the line). """ # What type of token is it? if match.group()[0] in "'\"": tag = 'terminal' elif match.group() in ('->', self.ARROW): tag = 'arrow' else: # If it's a nonterminal, then set up new bindings, so we # can highlight all instances of that nonterminal when we # put the mouse over it. tag = 'nonterminal_' + match.group() if tag not in self._textwidget.tag_names(): self._init_nonterminal_tag(tag) start = '%d.%d' % (linenum, match.start()) end = '%d.%d' % (linenum, match.end()) self._textwidget.tag_add(tag, start, end) def _init_nonterminal_tag(self, tag, foreground='blue'): self._textwidget.tag_config(tag, foreground=foreground, font=CFGEditor._BOLD) if not self._highlight_matching_nonterminals: return def enter(e, textwidget=self._textwidget, tag=tag): textwidget.tag_config(tag, background='#80ff80') def leave(e, textwidget=self._textwidget, tag=tag): textwidget.tag_config(tag, background='') self._textwidget.tag_bind(tag, '<Enter>', enter) self._textwidget.tag_bind(tag, '<Leave>', leave) def _analyze_line(self, linenum): """ Colorize a given line. """ # Get rid of any tags that were previously on the line. self._clear_tags(linenum) # Get the line line's text string. line = self._textwidget.get( ` linenum ` + '.0', ` linenum ` + '.end') # If it's a valid production, then colorize each token. if CFGEditor._PRODUCTION_RE.match(line): # It's valid; Use _TOKEN_RE to tokenize the production, # and call analyze_token on each token. def analyze_token(match, self=self, linenum=linenum): self._analyze_token(match, linenum) return '' CFGEditor._TOKEN_RE.sub(analyze_token, line) elif line.strip() != '': # It's invalid; show the user where the error is. self._mark_error(linenum, line) def _mark_error(self, linenum, line): """ Mark the location of an error in a line. """ arrowmatch = CFGEditor._ARROW_RE.search(line) if not arrowmatch: # If there's no arrow at all, highlight the whole line. start = '%d.0' % linenum end = '%d.end' % linenum elif not CFGEditor._LHS_RE.match(line): # Otherwise, if the LHS is bad, highlight it. start = '%d.0' % linenum end = '%d.%d' % (linenum, arrowmatch.start()) else: # Otherwise, highlight the RHS. start = '%d.%d' % (linenum, arrowmatch.end()) end = '%d.end' % linenum # If we're highlighting 0 chars, highlight the whole line. if self._textwidget.compare(start, '==', end): start = '%d.0' % linenum end = '%d.end' % linenum self._textwidget.tag_add('error', start, end) def _analyze(self, *e): """ Replace ``->`` with arrows, and colorize the entire buffer. """ self._replace_arrows() numlines = int(self._textwidget.index('end').split('.')[0]) for linenum in range(1, numlines + 1): # line numbers start at 1. self._analyze_line(linenum) def _parse_productions(self): """ Parse the current contents of the textwidget buffer, to create a list of productions. """ productions = [] # Get the text, normalize it, and split it into lines. text = self._textwidget.get('1.0', 'end') text = re.sub(self.ARROW, '->', text) text = re.sub('\t', ' ', text) lines = text.split('\n') # Convert each line to a CFG production for line in lines: line = line.strip() if line == '': continue productions += parse_cfg_production(line) #if line.strip() == '': continue #if not CFGEditor._PRODUCTION_RE.match(line): # raise ValueError('Bad production string %r' % line) # #(lhs_str, rhs_str) = line.split('->') #lhs = Nonterminal(lhs_str.strip()) #rhs = [] #def parse_token(match, rhs=rhs): # token = match.group() # if token[0] in "'\"": rhs.append(token[1:-1]) # else: rhs.append(Nonterminal(token)) # return '' #CFGEditor._TOKEN_RE.sub(parse_token, rhs_str) # #productions.append(Production(lhs, *rhs)) return productions def _destroy(self, *e): if self._top is None: return self._top.destroy() self._top = None def _ok(self, *e): self._apply() self._destroy() def _apply(self, *e): productions = self._parse_productions() start = Nonterminal(self._start.get()) cfg = ContextFreeGrammar(start, productions) if self._set_cfg_callback is not None: self._set_cfg_callback(cfg) def _reset(self, *e): self._textwidget.delete('1.0', 'end') for production in self._cfg.productions(): self._textwidget.insert('end', '%s\n' % production) self._analyze() if self._set_cfg_callback is not None: self._set_cfg_callback(self._cfg) def _cancel(self, *e): try: self._reset() except: pass self._destroy() def _help(self, *e): # The default font's not very legible; try using 'fixed' instead. try: ShowText(self._parent, 'Help: Chart Parser Demo', (_CFGEditor_HELP).strip(), width=75, font='fixed') except: ShowText(self._parent, 'Help: Chart Parser Demo', (_CFGEditor_HELP).strip(), width=75)
def popupControls(self, tl = None): """ Popup control panel for interval. """ from direct.showbase import TkGlobal import math # I moved this here because Toontown does not ship Tk from Tkinter import Toplevel, Frame, Button, LEFT, X import Pmw from direct.tkwidgets import EntryScale if tl == None: tl = Toplevel() tl.title('Interval Controls') outerFrame = Frame(tl) def entryScaleCommand(t, s=self): s.setT(t) s.pause() self.es = es = EntryScale.EntryScale( outerFrame, text = self.getName(), min = 0, max = math.floor(self.getDuration() * 100) / 100, command = entryScaleCommand) es.set(self.getT(), fCommand = 0) es.pack(expand = 1, fill = X) bf = Frame(outerFrame) # Jump to start and end def toStart(s=self, es=es): s.clearToInitial() es.set(0, fCommand = 0) def toEnd(s=self): s.pause() s.setT(s.getDuration()) es.set(s.getDuration(), fCommand = 0) s.pause() jumpToStart = Button(bf, text = '<<', command = toStart) # Stop/play buttons def doPlay(s=self, es=es): s.resume(es.get()) stop = Button(bf, text = 'Stop', command = lambda s=self: s.pause()) play = Button( bf, text = 'Play', command = doPlay) jumpToEnd = Button(bf, text = '>>', command = toEnd) jumpToStart.pack(side = LEFT, expand = 1, fill = X) play.pack(side = LEFT, expand = 1, fill = X) stop.pack(side = LEFT, expand = 1, fill = X) jumpToEnd.pack(side = LEFT, expand = 1, fill = X) bf.pack(expand = 1, fill = X) outerFrame.pack(expand = 1, fill = X) # Add function to update slider during setT calls def update(t, es=es): es.set(t, fCommand = 0) if not hasattr(self, "setTHooks"): self.setTHooks = [] self.setTHooks.append(update) # Clear out function on destroy def onDestroy(e, s=self, u=update): if u in s.setTHooks: s.setTHooks.remove(u) tl.bind('<Destroy>', onDestroy)
class ListBoxChoice(object): def __init__(self, master=None, title=None, message=None, clist=[], newmessage=None): self.master = master self.value = None self.newmessage = newmessage self.list = clist[:] self.modalPane = Toplevel(self.master) self.modalPane.transient(self.master) self.modalPane.grab_set() self.modalPane.bind("<Return>", self._choose) self.modalPane.bind("<Escape>", self._cancel) if title: self.modalPane.title(title) if message: Label(self.modalPane, text=message).pack(padx=5, pady=5) listFrame = Frame(self.modalPane) listFrame.pack(side=TOP, padx=5, pady=5) scrollBar = Scrollbar(listFrame) scrollBar.pack(side=RIGHT, fill=Y) self.listBox = Listbox(listFrame, selectmode=SINGLE) self.listBox.pack(side=LEFT, fill=Y) scrollBar.config(command=self.listBox.yview) self.listBox.config(yscrollcommand=scrollBar.set) self.list.sort() for item in self.list: self.listBox.insert(END, item) if newmessage is not None: newFrame = Frame(self.modalPane) newFrame.pack(side=TOP, padx=5) Label(newFrame, text=newmessage).pack(padx=5, pady=5) self.entry = Entry(newFrame, width=30) self.entry.pack(side=TOP, padx=5) self.entry.bind("<Return>", self._choose_entry) buttonFrame = Frame(self.modalPane) buttonFrame.pack(side=BOTTOM) chooseButton = Button(buttonFrame, text="Choose", command=self._choose_entry) chooseButton.pack() cancelButton = Button(buttonFrame, text="Cancel", command=self._cancel) cancelButton.pack(side=RIGHT) def _choose_entry(self, event=None): if self.newmessage is None: self._choose() return v = self.entry.get().strip() if v == None or v == "": self._choose() return self.value = v self.modalPane.destroy() def _choose(self, event=None): try: firstIndex = self.listBox.curselection()[0] self.value = self.list[int(firstIndex)] except IndexError: self.value = None self.modalPane.destroy() def _cancel(self, event=None): self.modalPane.destroy() def returnValue(self): self.master.wait_window(self.modalPane) return self.value
class PypeTkPad(object): def __init__(self, master, queue, pypeOutput): self.queue = queue self.pypeOutput = pypeOutput self.master = master self.master.title('PypePad') self.master.geometry("%dx%d%+d%+d" % (700, 500, 0, 0)) self.master.minsize(300, 100) self.output_file_name = None self.BuildMainFrame() self.UpdateOutput() def NewCommand(self): self.ClearAllCommand() def OpenCommand(self): import tkFileDialog from Tkinter import END openfile = tkFileDialog.askopenfile() if not openfile: return for line in openfile.readlines(): self.text_input.insert(END, line) def SaveCommand(self): import tkFileDialog from Tkinter import END saveasfile = tkFileDialog.asksaveasfile() if not saveasfile: return alltext = self.text_input.get("1.0", END) saveasfile.write(alltext) def QuitCommand(self): self.master.quit() def ClearInputCommand(self): from Tkinter import END self.text_input.delete("1.0", END) def ClearOutputCommand(self): from Tkinter import NORMAL, END, DISABLED self.text_output["state"] = NORMAL self.text_output.delete("1.0", END) self.text_output["state"] = DISABLED self.text_output.see(END) self.text_output.update() def ClearAllCommand(self): self.ClearInputCommand() self.ClearOutputCommand() def OutputFileCommand(self): import tkFileDialog outputfilename = tkFileDialog.asksaveasfilename() if sys.platform == 'win32' and len(outputfilename.split()) > 1: outputfilename = '"%s"' % outputfilename self.output_file_name = outputfilename def AboutCommand(self): self.OutputText('\n') self.OutputText( '* PypePad, Copyright (c) Luca Antiga, David Steinman. *\n') self.OutputText('\n') def UpdateOutput(self): if self.pypeOutput: text = self.pypeOutput.pop(0) self.output_stream.write(text) self.master.after(10, self.UpdateOutput) def RunPype(self, arguments): if not arguments: return if self.output_to_file.get() is not 'n' and self.output_file_name: self.output_stream.output_to_file = True self.output_stream.output_file = open(self.output_file_name, self.output_to_file.get()) else: self.output_stream.output_to_file = False self.queue.append(arguments) def GetWordUnderCursor(self): from Tkinter import CURRENT splitindex = self.text_input.index(CURRENT).split('.') line = self.text_input.get(splitindex[0] + ".0", splitindex[0] + ".end") wordstart = line.rfind(' ', 0, int(splitindex[1]) - 1) + 1 wordend = line.find(' ', int(splitindex[1])) if wordend == -1: wordend = len(line) word = line[wordstart:wordend] return word def GetWordIndex(self): startindex = self.text_input.index("insert-1c wordstart") endindex = self.text_input.index("insert-1c wordend") if self.text_input.get(startindex + '-1c') == '-' and self.text_input.get( startindex + '-2c') == '-': startindex = self.text_input.index("insert-1c wordstart -2c") elif self.text_input.get(startindex + '-1c') == '-' and self.text_input.get( startindex + '-2c') == ' ': startindex = self.text_input.index("insert-1c wordstart -1c") self.wordIndex[0] = startindex self.wordIndex[1] = endindex word = self.text_input.get(self.wordIndex[0], self.wordIndex[1]) return word def GetLogicalLine(self, physicallineid): indexes, lines = self.GetLogicalLines() return lines[indexes[physicallineid]] def GetLogicalLineRange(self, physicallinefirstid, physicallinelastid): indexes, lines = self.GetLogicalLines() return lines[indexes[physicallinefirstid]:indexes[physicallinelastid] + 1] def GetAllLogicalLines(self): return self.GetLogicalLines()[1] def GetLogicalLines(self): from Tkinter import END physicallines = self.text_input.get("1.0", END).split('\n') lines = [] indexes = [0] * len(physicallines) lineid = 0 previousline = "" join = 0 for line in physicallines: if line.startswith('#'): if join: indexes[lineid] = indexes[lineid - 1] elif join: if line.endswith('\\'): lines[-1] = lines[-1] + " " + line[:-1] join = 1 else: lines[-1] = lines[-1] + " " + line join = 0 indexes[lineid] = indexes[lineid - 1] else: if line.endswith('\\'): join = 1 lines.append(line[:-1]) else: lines.append(line) join = 0 if lineid > 0: indexes[lineid] = indexes[lineid - 1] + 1 lineid += 1 return indexes, lines def GetLineUnderCursor(self): from Tkinter import INSERT currentlineid = int(self.text_input.index(INSERT).split('.')[0]) - 1 return self.GetLogicalLine(currentlineid) def RunAllCommand(self): lines = self.GetAllLogicalLines() for line in lines: if line and line.strip(): self.RunPype(line) def RunLineCommand(self): line = self.GetLineUnderCursor() if line and line.strip(): self.RunPype(line) def RunSelectionCommand(self): from Tkinter import TclError, SEL_FIRST, SEL_LAST try: firstlineid = int( self.text_input.index(SEL_FIRST).split('.')[0]) - 1 lastlineid = int(self.text_input.index(SEL_LAST).split('.')[0]) - 1 lines = self.GetLogicalLineRange(firstlineid, lastlineid) for line in lines: self.RunPype(line) except TclError: pass def GetSuggestionsList(self, word): list = [] try: exec('import vmtkscripts') except ImportError: return None if word.startswith('--'): list = ['--pipe', '--help'] elif word.startswith('-'): optionlist = [] scriptindex = self.text_input.search('vmtk', self.wordIndex[0], backwards=1) moduleName = self.text_input.get(scriptindex, scriptindex + ' wordend') try: exec('import ' + moduleName) exec('scriptObjectClassName = ' + moduleName + '.' + moduleName) exec('scriptObject = ' + moduleName + '.' + scriptObjectClassName + '()') members = scriptObject.InputMembers + scriptObject.OutputMembers for member in members: optionlist.append('-' + member.OptionName) exec( 'list = [option for option in optionlist if option.count(word)]' ) except: return list else: exec( 'list = [scriptname for scriptname in vmtkscripts.__all__ if scriptname.count(word) ]' ) return list def FillSuggestionsList(self, word): from Tkinter import END self.suggestionslist.delete(0, END) suggestions = self.GetSuggestionsList(word) for suggestion in suggestions: self.suggestionslist.insert(END, suggestion) def ReplaceTextCommand(self, word): self.text_input.delete(self.wordIndex[0], self.wordIndex[1]) self.text_input.insert(self.wordIndex[0], word) self.text_input.focus_set() def ShowHelpCommand(self): word = self.GetWordUnderCursor() self.OutputText(word) if word: self.RunPype(word + ' --help') else: self.OutputText('Enter your vmtk Pype above and Run.\n') def AutoCompleteCommand(self): word = self.GetWordIndex() self.suggestionswindow.withdraw() if word: self.FillSuggestionsList(word) self.suggestionswindow.geometry( "%dx%d%+d%+d" % (400, 150, self.text_output.winfo_rootx(), self.text_output.winfo_rooty())) self.suggestionswindow.deiconify() self.suggestionswindow.lift() def InsertScriptName(self, scriptname): from Tkinter import INSERT self.text_input.insert(INSERT, scriptname + ' ') def InsertFileName(self): from Tkinter import INSERT import tkFileDialog openfilename = tkFileDialog.askopenfilename() if not openfilename: return if len(openfilename.split()) > 1: openfilename = '"%s"' % openfilename self.text_input.insert(INSERT, openfilename + ' ') def KeyPressHandler(self, event): if event.keysym == "Tab": self.AutoCompleteCommand() self.suggestionslist.focus_set() self.suggestionslist.selection_set(0) return "break" else: self.text_input.focus_set() def TopKeyPressHandler(self, event): from Tkinter import ACTIVE, INSERT if event.keysym in ['Down', 'Up']: self.suggestionslist.focus_set() elif event.keysym == "Return": word = self.suggestionslist.get(ACTIVE) self.ReplaceTextCommand(word) self.suggestionswindow.withdraw() self.text_input.focus_set() elif len(event.keysym) == 1: self.suggestionswindow.withdraw() self.text_input.insert(INSERT, event.keysym) self.text_input.focus_set() else: self.suggestionswindow.withdraw() self.text_input.focus_set() def NewHandler(self, event): self.NewCommand() def OpenHandler(self, event): self.OpenCommand() def SaveHandler(self, event): self.SaveCommand() def InsertFileNameHandler(self, event): self.InsertFileName() return "break" def QuitHandler(self, event): self.QuitCommand() def ShowHelpHandler(self, event): self.ShowHelpCommand() def RunKeyboardHandler(self, event): from Tkinter import SEL_FIRST, TclError try: self.text_input.index(SEL_FIRST) self.RunSelectionCommand() except TclError: self.RunLineCommand() return "break" def RunAllHandler(self, event): self.RunAllCommand() def PopupHandler(self, event): try: self.popupmenu.tk_popup(event.x_root, event.y_root, 0) finally: self.popupmenu.grab_release() def OutputText(self, text): from Tkinter import NORMAL, END, DISABLED self.text_output["state"] = NORMAL self.text_output.insert(END, text) self.text_output["state"] = DISABLED def BuildScriptMenu(self, parentmenu, modulename): from Tkinter import Menu menu = Menu(parentmenu, bd=1, activeborderwidth=0) try: exec('import ' + modulename) except ImportError: return None scriptnames = [] exec('scriptnames = [scriptname for scriptname in ' + modulename + '.__all__]') menulength = 20 for i in range(len(scriptnames) / menulength + 1): subscriptnames = scriptnames[i * menulength:(i + 1) * menulength] if not subscriptnames: break submenu = Menu(menu, bd=1, activeborderwidth=0) menu.add_cascade(label=subscriptnames[0] + "...", menu=submenu) for scriptname in subscriptnames: callback = CallbackShim(self.InsertScriptName, scriptname) submenu.add_command(label=scriptname, command=callback) return menu def BuildMainFrame(self): from Tkinter import Menu, IntVar, StringVar, Toplevel, Listbox, Frame, PanedWindow, Text, Scrollbar, Entry from Tkinter import X, N, S, W, E, VERTICAL, TOP, END, DISABLED, RAISED menu = Menu(self.master, activeborderwidth=0, bd=0) self.master.config(menu=menu) filemenu = Menu(menu, tearoff=0, bd=1, activeborderwidth=0) menu.add_cascade(label="File", underline=0, menu=filemenu) filemenu.add_command(label="New", accelerator='Ctrl+N', command=self.NewCommand) filemenu.add_command(label="Open...", accelerator='Ctrl+O', command=self.OpenCommand) filemenu.add_command(label="Save as...", accelerator='Ctrl+S', command=self.SaveCommand) filemenu.add_separator() filemenu.add_command(label="Quit", accelerator='Ctrl+Q', command=self.QuitCommand) self.log_on = IntVar() self.log_on.set(1) self.output_to_file = StringVar() self.output_to_file.set('n') scriptmenu = Menu(menu, tearoff=0, bd=1, activeborderwidth=0) modulenames = ['vmtkscripts'] for modulename in modulenames: scriptsubmenu = self.BuildScriptMenu(menu, modulename) if scriptsubmenu: scriptmenu.add_cascade(label=modulename, menu=scriptsubmenu) editmenu = Menu(menu, tearoff=0, bd=1, activeborderwidth=0) menu.add_cascade(label="Edit", underline=0, menu=editmenu) editmenu.add_cascade(label="Insert script", menu=scriptmenu) editmenu.add_command(label="Insert file name", accelerator='Ctrl+F', command=self.InsertFileName) editmenu.add_separator() editmenu.add_command(label="Clear input", command=self.ClearInputCommand) editmenu.add_command(label="Clear output", command=self.ClearOutputCommand) editmenu.add_command(label="Clear all", command=self.ClearAllCommand) editmenu.add_separator() editmenu.add_checkbutton(label="Log", variable=self.log_on) editmenu.add_separator() editmenu.add_radiobutton(label="No output to file", variable=self.output_to_file, value='n') editmenu.add_radiobutton(label="Write output to file", variable=self.output_to_file, value='w') editmenu.add_radiobutton(label="Append output to file", variable=self.output_to_file, value='a') editmenu.add_command(label="Output file...", command=self.OutputFileCommand) runmenu = Menu(menu, tearoff=0, bd=1, activeborderwidth=0) menu.add_cascade(label="Run", underline=0, menu=runmenu) runmenu.add_command(label="Run all", command=self.RunAllCommand) runmenu.add_command(label="Run current line", command=self.RunLineCommand) runmenu.add_command(label="Run selection", command=self.RunSelectionCommand) helpmenu = Menu(menu, tearoff=0, bd=1, activeborderwidth=0) menu.add_cascade(label="Help", underline=0, menu=helpmenu) helpmenu.add_command(label="Help", underline=0, accelerator='F1', command=self.ShowHelpCommand) helpmenu.add_command(label="About", underline=0, command=self.AboutCommand) self.master.bind("<Control-KeyPress-q>", self.QuitHandler) self.master.bind("<Control-KeyPress-n>", self.NewHandler) self.master.bind("<Control-KeyPress-o>", self.OpenHandler) self.master.bind("<Control-KeyPress-s>", self.SaveHandler) self.master.bind("<Control-KeyPress-f>", self.InsertFileNameHandler) self.master.bind("<KeyPress-F1>", self.ShowHelpHandler) self.master.bind("<KeyPress>", self.KeyPressHandler) self.wordIndex = ['1.0', '1.0'] self.suggestionswindow = Toplevel(bg='#ffffff', bd=0, height=50, width=600, highlightthickness=0, takefocus=True) self.suggestionswindow.overrideredirect(1) self.suggestionslist = Listbox(self.suggestionswindow, bg='#ffffff', bd=1, fg='#336699', activestyle='none', highlightthickness=0, height=9) self.suggestionslist.insert(END, "foo") self.suggestionslist.pack(side=TOP, fill=X) self.suggestionswindow.bind("<KeyPress>", self.TopKeyPressHandler) self.suggestionswindow.withdraw() self.master.rowconfigure(0, weight=1) self.master.columnconfigure(0, weight=1) content = Frame(self.master, bd=0, padx=2, pady=2) content.grid(row=0, column=0, sticky=N + S + W + E) content.rowconfigure(0, weight=1, minsize=50) content.rowconfigure(1, weight=0) content.columnconfigure(0, weight=1) panes = PanedWindow(content, orient=VERTICAL, bd=1, sashwidth=8, sashpad=0, sashrelief=RAISED, showhandle=True) panes.grid(row=0, column=0, sticky=N + S + W + E) frame1 = Frame(panes, bd=0) frame1.grid(row=0, column=0, sticky=N + S + W + E) frame1.columnconfigure(0, weight=1) frame1.columnconfigure(1, weight=0) frame1.rowconfigure(0, weight=1) panes.add(frame1, height=300, minsize=20) frame2 = Frame(panes, bd=0) frame2.grid(row=1, column=0, sticky=N + S + W + E) frame2.columnconfigure(0, weight=1) frame2.columnconfigure(1, weight=0) frame2.rowconfigure(0, weight=1) panes.add(frame2, minsize=20) self.text_input = Text(frame1, bg='#ffffff', bd=1, highlightthickness=0) self.text_input.bind("<KeyPress>", self.KeyPressHandler) self.text_input.bind("<Button-3>", self.PopupHandler) self.text_input.bind("<Control-Return>", self.RunKeyboardHandler) self.input_scrollbar = Scrollbar(frame1, orient=VERTICAL, command=self.text_input.yview) self.text_input["yscrollcommand"] = self.input_scrollbar.set self.text_output = Text(frame2, state=DISABLED, bd=1, bg='#ffffff', highlightthickness=0) self.output_scrollbar = Scrollbar(frame2, orient=VERTICAL, command=self.text_output.yview) self.text_output["yscrollcommand"] = self.output_scrollbar.set self.text_entry = Entry(content, bd=1, bg='#ffffff', state=DISABLED, highlightthickness=0) self.text_input.focus_set() self.text_input.grid(row=0, column=0, sticky=N + S + W + E) self.input_scrollbar.grid(row=0, column=1, sticky=N + S + W + E) self.text_output.grid(row=0, column=0, sticky=N + S + W + E) self.output_scrollbar.grid(row=0, column=1, sticky=N + S + W + E) self.text_entry.grid(row=1, column=0, sticky=N + S + W + E) self.popupmenu = Menu(self.text_input, tearoff=1, bd=0) self.popupmenu.add_command(label="Context help", command=self.ShowHelpCommand) self.popupmenu.add_cascade(label="Insert script", menu=scriptmenu) self.popupmenu.add_command(label="Insert file name...", command=self.InsertFileName) self.popupmenu.add_separator() self.popupmenu.add_command(label="Run all", command=self.RunAllCommand) self.popupmenu.add_command(label="Run current line", command=self.RunLineCommand) self.popupmenu.add_command(label="Run selection", command=self.RunSelectionCommand) self.output_stream = TkPadOutputStream(self.text_output) self.input_stream = TkPadInputStream(self.text_entry, self.output_stream)
class CFGEditor(object): """ A dialog window for creating and editing context free grammars. C{CFGEditor} places the following restrictions on what C{CFG}s can be edited: - All nonterminals must be strings consisting of word characters. - All terminals must be strings consisting of word characters and space characters. """ # Regular expressions used by _analyze_line. Precompile them, so # we can process the text faster. ARROW = SymbolWidget.SYMBOLS['rightarrow'] _LHS_RE = re.compile(r"(^\s*\w+\s*)(->|("+ARROW+"))") _ARROW_RE = re.compile("\s*(->|("+ARROW+"))\s*") _PRODUCTION_RE = re.compile(r"(^\s*\w+\s*)" + # LHS "(->|("+ARROW+"))\s*" + # arrow r"((\w+|'[\w ]*'|\"[\w ]*\"|\|)\s*)*$") # RHS _TOKEN_RE = re.compile("\\w+|->|'[\\w ]+'|\"[\\w ]+\"|("+ARROW+")") _BOLD = ('helvetica', -12, 'bold') def __init__(self, parent, cfg=None, set_cfg_callback=None): self._parent = parent if cfg is not None: self._cfg = cfg else: self._cfg = ContextFreeGrammar(Nonterminal('S'), []) self._set_cfg_callback = set_cfg_callback self._highlight_matching_nonterminals = 1 # Create the top-level window. self._top = Toplevel(parent) self._init_bindings() self._init_startframe() self._startframe.pack(side='top', fill='x', expand=0) self._init_prodframe() self._prodframe.pack(side='top', fill='both', expand=1) self._init_buttons() self._buttonframe.pack(side='bottom', fill='x', expand=0) self._textwidget.focus() def _init_startframe(self): frame = self._startframe = Frame(self._top) self._start = Entry(frame) self._start.pack(side='right') Label(frame, text='Start Symbol:').pack(side='right') Label(frame, text='Productions:').pack(side='left') self._start.insert(0, self._cfg.start().symbol()) def _init_buttons(self): frame = self._buttonframe = Frame(self._top) Button(frame, text='Ok', command=self._ok, underline=0, takefocus=0).pack(side='left') Button(frame, text='Apply', command=self._apply, underline=0, takefocus=0).pack(side='left') Button(frame, text='Reset', command=self._reset, underline=0, takefocus=0,).pack(side='left') Button(frame, text='Cancel', command=self._cancel, underline=0, takefocus=0).pack(side='left') Button(frame, text='Help', command=self._help, underline=0, takefocus=0).pack(side='right') def _init_bindings(self): self._top.title('CFG Editor') self._top.bind('<Control-q>', self._cancel) self._top.bind('<Alt-q>', self._cancel) self._top.bind('<Control-d>', self._cancel) #self._top.bind('<Control-x>', self._cancel) self._top.bind('<Alt-x>', self._cancel) self._top.bind('<Escape>', self._cancel) #self._top.bind('<Control-c>', self._cancel) self._top.bind('<Alt-c>', self._cancel) self._top.bind('<Control-o>', self._ok) self._top.bind('<Alt-o>', self._ok) self._top.bind('<Control-a>', self._apply) self._top.bind('<Alt-a>', self._apply) self._top.bind('<Control-r>', self._reset) self._top.bind('<Alt-r>', self._reset) self._top.bind('<Control-h>', self._help) self._top.bind('<Alt-h>', self._help) self._top.bind('<F1>', self._help) def _init_prodframe(self): self._prodframe = Frame(self._top) # Create the basic Text widget & scrollbar. self._textwidget = Text(self._prodframe, background='#e0e0e0', exportselection=1) self._textscroll = Scrollbar(self._prodframe, takefocus=0, orient='vertical') self._textwidget.config(yscrollcommand = self._textscroll.set) self._textscroll.config(command=self._textwidget.yview) self._textscroll.pack(side='right', fill='y') self._textwidget.pack(expand=1, fill='both', side='left') # Initialize the colorization tags. Each nonterminal gets its # own tag, so they aren't listed here. self._textwidget.tag_config('terminal', foreground='#006000') self._textwidget.tag_config('arrow', font='symbol') self._textwidget.tag_config('error', background='red') # Keep track of what line they're on. We use that to remember # to re-analyze a line whenever they leave it. self._linenum = 0 # Expand "->" to an arrow. self._top.bind('>', self._replace_arrows) # Re-colorize lines when appropriate. self._top.bind('<<Paste>>', self._analyze) self._top.bind('<KeyPress>', self._check_analyze) self._top.bind('<ButtonPress>', self._check_analyze) # Tab cycles focus. (why doesn't this work??) def cycle(e, textwidget=self._textwidget): textwidget.tk_focusNext().focus() self._textwidget.bind('<Tab>', cycle) prod_tuples = [(p.lhs(),[p.rhs()]) for p in self._cfg.productions()] for i in range(len(prod_tuples)-1,0,-1): if (prod_tuples[i][0] == prod_tuples[i-1][0]): if () in prod_tuples[i][1]: continue if () in prod_tuples[i-1][1]: continue print prod_tuples[i-1][1] print prod_tuples[i][1] prod_tuples[i-1][1].extend(prod_tuples[i][1]) del prod_tuples[i] for lhs, rhss in prod_tuples: print lhs, rhss s = '%s ->' % lhs for rhs in rhss: for elt in rhs: if isinstance(elt, Nonterminal): s += ' %s' % elt else: s += ' %r' % elt s += ' |' s = s[:-2] + '\n' self._textwidget.insert('end', s) self._analyze() # # Add the producitons to the text widget, and colorize them. # prod_by_lhs = {} # for prod in self._cfg.productions(): # if len(prod.rhs()) > 0: # prod_by_lhs.setdefault(prod.lhs(),[]).append(prod) # for (lhs, prods) in prod_by_lhs.items(): # self._textwidget.insert('end', '%s ->' % lhs) # self._textwidget.insert('end', self._rhs(prods[0])) # for prod in prods[1:]: # print '\t|'+self._rhs(prod), # self._textwidget.insert('end', '\t|'+self._rhs(prod)) # print # self._textwidget.insert('end', '\n') # for prod in self._cfg.productions(): # if len(prod.rhs()) == 0: # self._textwidget.insert('end', '%s' % prod) # self._analyze() # def _rhs(self, prod): # s = '' # for elt in prod.rhs(): # if isinstance(elt, Nonterminal): s += ' %s' % elt.symbol() # else: s += ' %r' % elt # return s def _clear_tags(self, linenum): """ Remove all tags (except C{arrow} and C{sel}) from the given line of the text widget used for editing the productions. """ start = '%d.0'%linenum end = '%d.end'%linenum for tag in self._textwidget.tag_names(): if tag not in ('arrow', 'sel'): self._textwidget.tag_remove(tag, start, end) def _check_analyze(self, *e): """ Check if we've moved to a new line. If we have, then remove all colorization from the line we moved to, and re-colorize the line that we moved from. """ linenum = int(self._textwidget.index('insert').split('.')[0]) if linenum != self._linenum: self._clear_tags(linenum) self._analyze_line(self._linenum) self._linenum = linenum def _replace_arrows(self, *e): """ Replace any C{'->'} text strings with arrows (char \\256, in symbol font). This searches the whole buffer, but is fast enough to be done anytime they press '>'. """ arrow = '1.0' while 1: arrow = self._textwidget.search('->', arrow, 'end+1char') if arrow == '': break self._textwidget.delete(arrow, arrow+'+2char') self._textwidget.insert(arrow, self.ARROW, 'arrow') self._textwidget.insert(arrow, '\t') arrow = '1.0' while 1: arrow = self._textwidget.search(self.ARROW, arrow+'+1char', 'end+1char') if arrow == '': break self._textwidget.tag_add('arrow', arrow, arrow+'+1char') def _analyze_token(self, match, linenum): """ Given a line number and a regexp match for a token on that line, colorize the token. Note that the regexp match gives us the token's text, start index (on the line), and end index (on the line). """ # What type of token is it? if match.group()[0] in "'\"": tag = 'terminal' elif match.group() in ('->', self.ARROW): tag = 'arrow' else: # If it's a nonterminal, then set up new bindings, so we # can highlight all instances of that nonterminal when we # put the mouse over it. tag = 'nonterminal_'+match.group() if tag not in self._textwidget.tag_names(): self._init_nonterminal_tag(tag) start = '%d.%d' % (linenum, match.start()) end = '%d.%d' % (linenum, match.end()) self._textwidget.tag_add(tag, start, end) def _init_nonterminal_tag(self, tag, foreground='blue'): self._textwidget.tag_config(tag, foreground=foreground, font=CFGEditor._BOLD) if not self._highlight_matching_nonterminals: return def enter(e, textwidget=self._textwidget, tag=tag): textwidget.tag_config(tag, background='#80ff80') def leave(e, textwidget=self._textwidget, tag=tag): textwidget.tag_config(tag, background='') self._textwidget.tag_bind(tag, '<Enter>', enter) self._textwidget.tag_bind(tag, '<Leave>', leave) def _analyze_line(self, linenum): """ Colorize a given line. """ # Get rid of any tags that were previously on the line. self._clear_tags(linenum) # Get the line line's text string. line = self._textwidget.get(`linenum`+'.0', `linenum`+'.end') # If it's a valid production, then colorize each token. if CFGEditor._PRODUCTION_RE.match(line): # It's valid; Use _TOKEN_RE to tokenize the production, # and call analyze_token on each token. def analyze_token(match, self=self, linenum=linenum): self._analyze_token(match, linenum) return '' CFGEditor._TOKEN_RE.sub(analyze_token, line) elif line.strip() != '': # It's invalid; show the user where the error is. self._mark_error(linenum, line) def _mark_error(self, linenum, line): """ Mark the location of an error in a line. """ arrowmatch = CFGEditor._ARROW_RE.search(line) if not arrowmatch: # If there's no arrow at all, highlight the whole line. start = '%d.0' % linenum end = '%d.end' % linenum elif not CFGEditor._LHS_RE.match(line): # Otherwise, if the LHS is bad, highlight it. start = '%d.0' % linenum end = '%d.%d' % (linenum, arrowmatch.start()) else: # Otherwise, highlight the RHS. start = '%d.%d' % (linenum, arrowmatch.end()) end = '%d.end' % linenum # If we're highlighting 0 chars, highlight the whole line. if self._textwidget.compare(start, '==', end): start = '%d.0' % linenum end = '%d.end' % linenum self._textwidget.tag_add('error', start, end) def _analyze(self, *e): """ Replace C{->} with arrows, and colorize the entire buffer. """ self._replace_arrows() numlines = int(self._textwidget.index('end').split('.')[0]) for linenum in range(1, numlines+1): # line numbers start at 1. self._analyze_line(linenum) def _parse_productions(self): """ Parse the current contents of the textwidget buffer, to create a list of productions. """ productions = [] # Get the text, normalize it, and split it into lines. text = self._textwidget.get('1.0', 'end') text = re.sub(self.ARROW, '->', text) text = re.sub('\t', ' ', text) lines = text.split('\n') # Convert each line to a CFG production for line in lines: line = line.strip() if line=='': continue productions += parse_cfg_production(line) #if line.strip() == '': continue #if not CFGEditor._PRODUCTION_RE.match(line): # raise ValueError('Bad production string %r' % line) # #(lhs_str, rhs_str) = line.split('->') #lhs = Nonterminal(lhs_str.strip()) #rhs = [] #def parse_token(match, rhs=rhs): # token = match.group() # if token[0] in "'\"": rhs.append(token[1:-1]) # else: rhs.append(Nonterminal(token)) # return '' #CFGEditor._TOKEN_RE.sub(parse_token, rhs_str) # #productions.append(Production(lhs, *rhs)) return productions def _destroy(self, *e): if self._top is None: return self._top.destroy() self._top = None def _ok(self, *e): self._apply() self._destroy() def _apply(self, *e): productions = self._parse_productions() start = Nonterminal(self._start.get()) cfg = ContextFreeGrammar(start, productions) if self._set_cfg_callback is not None: self._set_cfg_callback(cfg) def _reset(self, *e): self._textwidget.delete('1.0', 'end') for production in self._cfg.productions(): self._textwidget.insert('end', '%s\n' % production) self._analyze() if self._set_cfg_callback is not None: self._set_cfg_callback(self._cfg) def _cancel(self, *e): try: self._reset() except: pass self._destroy() def _help(self, *e): # The default font's not very legible; try using 'fixed' instead. try: ShowText(self._parent, 'Help: Chart Parser Demo', (_CFGEditor_HELP).strip(), width=75, font='fixed') except: ShowText(self._parent, 'Help: Chart Parser Demo', (_CFGEditor_HELP).strip(), width=75)
class PypeTkPad(object): def __init__(self, master, queue, pypeOutput): self.queue = queue self.pypeOutput = pypeOutput self.master = master self.master.title('PypePad') self.master.geometry("%dx%d%+d%+d" % (700, 500, 0, 0)) self.master.minsize(300, 100) self.output_file_name = None self.BuildMainFrame() self.UpdateOutput() def NewCommand(self): self.ClearAllCommand() def OpenCommand(self): import tkFileDialog from Tkinter import END openfile = tkFileDialog.askopenfile() if not openfile: return for line in openfile.readlines(): self.text_input.insert(END,line) def SaveCommand(self): import tkFileDialog from Tkinter import END saveasfile = tkFileDialog.asksaveasfile() if not saveasfile: return alltext = self.text_input.get("1.0",END) saveasfile.write(alltext) def QuitCommand(self): self.master.quit() def ClearInputCommand(self): from Tkinter import END self.text_input.delete("1.0",END) def ClearOutputCommand(self): from Tkinter import NORMAL, END, DISABLED self.text_output["state"] = NORMAL self.text_output.delete("1.0",END) self.text_output["state"] = DISABLED self.text_output.see(END) self.text_output.update() def ClearAllCommand(self): self.ClearInputCommand() self.ClearOutputCommand() def OutputFileCommand(self): import tkFileDialog outputfilename = tkFileDialog.asksaveasfilename() if sys.platform == 'win32' and len(outputfilename.split()) > 1: outputfilename = '"%s"' % outputfilename self.output_file_name = outputfilename def AboutCommand(self): self.OutputText('\n') self.OutputText('* PypePad, Copyright (c) Luca Antiga, David Steinman. *\n') self.OutputText('\n') def UpdateOutput(self): if self.pypeOutput: text = self.pypeOutput.pop(0) self.output_stream.write(text) self.master.after(10,self.UpdateOutput) def RunPype(self,arguments): if not arguments: return if self.output_to_file.get() is not 'n' and self.output_file_name: self.output_stream.output_to_file = True self.output_stream.output_file = open(self.output_file_name,self.output_to_file.get()) else: self.output_stream.output_to_file = False self.queue.append(arguments) def GetWordUnderCursor(self): from Tkinter import CURRENT splitindex = self.text_input.index(CURRENT).split('.') line = self.text_input.get(splitindex[0]+".0",splitindex[0]+".end") wordstart = line.rfind(' ',0,int(splitindex[1])-1)+1 wordend = line.find(' ',int(splitindex[1])) if wordend == -1: wordend = len(line) word = line[wordstart:wordend] return word def GetWordIndex(self): startindex = self.text_input.index("insert-1c wordstart") endindex = self.text_input.index("insert-1c wordend") if self.text_input.get(startindex+'-1c') == '-' and self.text_input.get(startindex+'-2c') == '-': startindex = self.text_input.index("insert-1c wordstart -2c") elif self.text_input.get(startindex+'-1c') == '-' and self.text_input.get(startindex+'-2c') == ' ': startindex = self.text_input.index("insert-1c wordstart -1c") self.wordIndex[0] = startindex self.wordIndex[1] = endindex word = self.text_input.get(self.wordIndex[0],self.wordIndex[1]) return word def GetLogicalLine(self,physicallineid): indexes, lines = self.GetLogicalLines() return lines[indexes[physicallineid]] def GetLogicalLineRange(self,physicallinefirstid,physicallinelastid): indexes, lines = self.GetLogicalLines() return lines[indexes[physicallinefirstid]:indexes[physicallinelastid]+1] def GetAllLogicalLines(self): return self.GetLogicalLines()[1] def GetLogicalLines(self): from Tkinter import END physicallines = self.text_input.get("1.0",END).split('\n') lines = [] indexes = [0] * len(physicallines) lineid = 0 previousline = "" join = 0 for line in physicallines: if line.startswith('#'): if join: indexes[lineid] = indexes[lineid-1] elif join: if line.endswith('\\'): lines[-1] = lines[-1] + " " + line[:-1] join = 1 else: lines[-1] = lines[-1] + " " + line join = 0 indexes[lineid] = indexes[lineid-1] else: if line.endswith('\\'): join = 1 lines.append(line[:-1]) else: lines.append(line) join = 0 if lineid > 0: indexes[lineid] = indexes[lineid-1]+1 lineid += 1 return indexes, lines def GetLineUnderCursor(self): from Tkinter import INSERT currentlineid = int(self.text_input.index(INSERT).split('.')[0]) - 1 return self.GetLogicalLine(currentlineid) def RunAllCommand(self): lines = self.GetAllLogicalLines() for line in lines: if line and line.strip(): self.RunPype(line) def RunLineCommand(self): line = self.GetLineUnderCursor() if line and line.strip(): self.RunPype(line) def RunSelectionCommand(self): from Tkinter import TclError, SEL_FIRST, SEL_LAST try: firstlineid = int(self.text_input.index(SEL_FIRST).split('.')[0]) - 1 lastlineid = int(self.text_input.index(SEL_LAST).split('.')[0]) - 1 lines = self.GetLogicalLineRange(firstlineid,lastlineid) for line in lines: self.RunPype(line) except TclError: pass def GetSuggestionsList(self,word): list = [] try: exec('import vmtkscripts') except ImportError: return None if word.startswith('--'): list = ['--pipe','--help'] elif word.startswith('-'): optionlist = [] scriptindex = self.text_input.search('vmtk',self.wordIndex[0],backwards=1) moduleName = self.text_input.get( scriptindex,scriptindex+' wordend' ) try: exec('import '+moduleName) exec('scriptObjectClassName = '+moduleName+'.'+moduleName) exec ('scriptObject = '+moduleName+'.'+scriptObjectClassName +'()') members = scriptObject.InputMembers + scriptObject.OutputMembers for member in members: optionlist.append('-'+member.OptionName) exec('list = [option for option in optionlist if option.count(word)]') except: return list else: exec('list = [scriptname for scriptname in vmtkscripts.__all__ if scriptname.count(word) ]') return list def FillSuggestionsList(self,word): from Tkinter import END self.suggestionslist.delete(0,END) suggestions = self.GetSuggestionsList(word) for suggestion in suggestions: self.suggestionslist.insert(END,suggestion) def ReplaceTextCommand(self,word): self.text_input.delete(self.wordIndex[0],self.wordIndex[1]) self.text_input.insert(self.wordIndex[0],word) self.text_input.focus_set() def ShowHelpCommand(self): word = self.GetWordUnderCursor() self.OutputText(word) if word: self.RunPype(word+' --help') else: self.OutputText('Enter your vmtk Pype above and Run.\n') def AutoCompleteCommand(self): word = self.GetWordIndex() self.suggestionswindow.withdraw() if word: self.FillSuggestionsList(word) self.suggestionswindow.geometry("%dx%d%+d%+d" % (400, 150, self.text_output.winfo_rootx(),self.text_output.winfo_rooty())) self.suggestionswindow.deiconify() self.suggestionswindow.lift() def InsertScriptName(self,scriptname): from Tkinter import INSERT self.text_input.insert(INSERT,scriptname+' ') def InsertFileName(self): from Tkinter import INSERT import tkFileDialog openfilename = tkFileDialog.askopenfilename() if not openfilename: return if len(openfilename.split()) > 1: openfilename = '"%s"' % openfilename self.text_input.insert(INSERT,openfilename+' ') def KeyPressHandler(self,event): if event.keysym == "Tab" : self.AutoCompleteCommand() self.suggestionslist.focus_set() self.suggestionslist.selection_set(0) return "break" else: self.text_input.focus_set() def TopKeyPressHandler(self,event): from Tkinter import ACTIVE, INSERT if event.keysym in ['Down','Up'] : self.suggestionslist.focus_set() elif event.keysym == "Return": word = self.suggestionslist.get(ACTIVE) self.ReplaceTextCommand(word) self.suggestionswindow.withdraw() self.text_input.focus_set() elif len(event.keysym) == 1 : self.suggestionswindow.withdraw() self.text_input.insert(INSERT,event.keysym) self.text_input.focus_set() else : self.suggestionswindow.withdraw() self.text_input.focus_set() def NewHandler(self,event): self.NewCommand() def OpenHandler(self,event): self.OpenCommand() def SaveHandler(self,event): self.SaveCommand() def InsertFileNameHandler(self,event): self.InsertFileName() return "break" def QuitHandler(self,event): self.QuitCommand() def ShowHelpHandler(self,event): self.ShowHelpCommand() def RunKeyboardHandler(self,event): from Tkinter import SEL_FIRST, TclError try: self.text_input.index(SEL_FIRST) self.RunSelectionCommand() except TclError: self.RunLineCommand() return "break" def RunAllHandler(self,event): self.RunAllCommand() def PopupHandler(self,event): try: self.popupmenu.tk_popup(event.x_root, event.y_root, 0) finally: self.popupmenu.grab_release() def OutputText(self,text): from Tkinter import NORMAL, END, DISABLED self.text_output["state"] = NORMAL self.text_output.insert(END,text) self.text_output["state"] = DISABLED def BuildScriptMenu(self,parentmenu,modulename): from Tkinter import Menu menu = Menu(parentmenu,bd=1,activeborderwidth=0) try: exec('import '+ modulename) except ImportError: return None scriptnames = [] exec ('scriptnames = [scriptname for scriptname in '+modulename+'.__all__]') menulength = 20 for i in range(len(scriptnames)/menulength+1): subscriptnames = scriptnames[i*menulength:(i+1)*menulength] if not subscriptnames: break submenu = Menu(menu,bd=1,activeborderwidth=0) menu.add_cascade(label=subscriptnames[0]+"...",menu=submenu) for scriptname in subscriptnames: callback = CallbackShim(self.InsertScriptName,scriptname) submenu.add_command(label=scriptname,command=callback) return menu def BuildMainFrame(self): from Tkinter import Menu, IntVar, StringVar, Toplevel, Listbox, Frame, PanedWindow, Text, Scrollbar, Entry from Tkinter import X, N, S, W, E, VERTICAL, TOP, END, DISABLED, RAISED menu = Menu(self.master,activeborderwidth=0,bd=0) self.master.config(menu=menu) filemenu = Menu(menu,tearoff=0,bd=1,activeborderwidth=0) menu.add_cascade(label="File", underline=0, menu=filemenu) filemenu.add_command(label="New", accelerator='Ctrl+N',command=self.NewCommand) filemenu.add_command(label="Open...",accelerator='Ctrl+O', command=self.OpenCommand) filemenu.add_command(label="Save as...",accelerator='Ctrl+S', command=self.SaveCommand) filemenu.add_separator() filemenu.add_command(label="Quit",accelerator='Ctrl+Q', command=self.QuitCommand) self.log_on = IntVar() self.log_on.set(1) self.output_to_file = StringVar() self.output_to_file.set('n') scriptmenu = Menu(menu,tearoff=0,bd=1,activeborderwidth=0) modulenames = ['vmtkscripts'] for modulename in modulenames: scriptsubmenu = self.BuildScriptMenu(menu,modulename) if scriptsubmenu: scriptmenu.add_cascade(label=modulename,menu=scriptsubmenu) editmenu = Menu(menu,tearoff=0,bd=1,activeborderwidth=0) menu.add_cascade(label="Edit",underline=0, menu=editmenu) editmenu.add_cascade(label="Insert script",menu=scriptmenu) editmenu.add_command(label="Insert file name", accelerator='Ctrl+F',command=self.InsertFileName) editmenu.add_separator() editmenu.add_command(label="Clear input", command=self.ClearInputCommand) editmenu.add_command(label="Clear output", command=self.ClearOutputCommand) editmenu.add_command(label="Clear all", command=self.ClearAllCommand) editmenu.add_separator() editmenu.add_checkbutton(label="Log", variable=self.log_on) editmenu.add_separator() editmenu.add_radiobutton(label="No output to file", variable=self.output_to_file,value='n') editmenu.add_radiobutton(label="Write output to file", variable=self.output_to_file,value='w') editmenu.add_radiobutton(label="Append output to file", variable=self.output_to_file,value='a') editmenu.add_command(label="Output file...", command=self.OutputFileCommand) runmenu = Menu(menu,tearoff=0,bd=1,activeborderwidth=0) menu.add_cascade(label="Run", underline=0, menu=runmenu) runmenu.add_command(label="Run all", command=self.RunAllCommand) runmenu.add_command(label="Run current line", command=self.RunLineCommand) runmenu.add_command(label="Run selection", command=self.RunSelectionCommand) helpmenu = Menu(menu,tearoff=0,bd=1,activeborderwidth=0) menu.add_cascade(label="Help", underline=0, menu=helpmenu) helpmenu.add_command(label="Help", underline=0, accelerator='F1',command=self.ShowHelpCommand) helpmenu.add_command(label="About", underline=0, command=self.AboutCommand) self.master.bind("<Control-KeyPress-q>", self.QuitHandler) self.master.bind("<Control-KeyPress-n>", self.NewHandler) self.master.bind("<Control-KeyPress-o>", self.OpenHandler) self.master.bind("<Control-KeyPress-s>", self.SaveHandler) self.master.bind("<Control-KeyPress-f>", self.InsertFileNameHandler) self.master.bind("<KeyPress-F1>", self.ShowHelpHandler) self.master.bind("<KeyPress>", self.KeyPressHandler) self.wordIndex = ['1.0','1.0'] self.suggestionswindow = Toplevel(bg='#ffffff',bd=0,height=50,width=600,highlightthickness=0,takefocus=True) self.suggestionswindow.overrideredirect(1) self.suggestionslist = Listbox(self.suggestionswindow,bg='#ffffff',bd=1,fg='#336699',activestyle='none',highlightthickness=0,height=9) self.suggestionslist.insert(END,"foo") self.suggestionslist.pack(side=TOP,fill=X) self.suggestionswindow.bind("<KeyPress>", self.TopKeyPressHandler) self.suggestionswindow.withdraw() self.master.rowconfigure(0,weight=1) self.master.columnconfigure(0,weight=1) content = Frame(self.master,bd=0,padx=2,pady=2) content.grid(row=0,column=0,sticky=N+S+W+E) content.rowconfigure(0,weight=1,minsize=50) content.rowconfigure(1,weight=0) content.columnconfigure(0,weight=1) panes = PanedWindow(content,orient=VERTICAL,bd=1,sashwidth=8,sashpad=0,sashrelief=RAISED,showhandle=True) panes.grid(row=0,column=0,sticky=N+S+W+E) frame1 = Frame(panes,bd=0) frame1.grid(row=0,column=0,sticky=N+S+W+E) frame1.columnconfigure(0,weight=1) frame1.columnconfigure(1,weight=0) frame1.rowconfigure(0,weight=1) panes.add(frame1,height=300,minsize=20) frame2 = Frame(panes,bd=0) frame2.grid(row=1,column=0,sticky=N+S+W+E) frame2.columnconfigure(0,weight=1) frame2.columnconfigure(1,weight=0) frame2.rowconfigure(0,weight=1) panes.add(frame2,minsize=20) self.text_input = Text(frame1, bg='#ffffff',bd=1,highlightthickness=0) self.text_input.bind("<KeyPress>", self.KeyPressHandler) self.text_input.bind("<Button-3>", self.PopupHandler) self.text_input.bind("<Control-Return>", self.RunKeyboardHandler) self.input_scrollbar = Scrollbar(frame1,orient=VERTICAL,command=self.text_input.yview) self.text_input["yscrollcommand"] = self.input_scrollbar.set self.text_output = Text(frame2,state=DISABLED,bd=1,bg='#ffffff',highlightthickness=0) self.output_scrollbar = Scrollbar(frame2,orient=VERTICAL,command=self.text_output.yview) self.text_output["yscrollcommand"] = self.output_scrollbar.set self.text_entry = Entry(content,bd=1,bg='#ffffff',state=DISABLED,highlightthickness=0) self.text_input.focus_set() self.text_input.grid(row=0,column=0,sticky=N+S+W+E) self.input_scrollbar.grid(row=0,column=1,sticky=N+S+W+E) self.text_output.grid(row=0,column=0,sticky=N+S+W+E) self.output_scrollbar.grid(row=0,column=1,sticky=N+S+W+E) self.text_entry.grid(row=1,column=0,sticky=N+S+W+E) self.popupmenu = Menu(self.text_input, tearoff=1, bd=0) self.popupmenu.add_command(label="Context help", command=self.ShowHelpCommand) self.popupmenu.add_cascade(label="Insert script",menu=scriptmenu) self.popupmenu.add_command(label="Insert file name...", command=self.InsertFileName) self.popupmenu.add_separator() self.popupmenu.add_command(label="Run all", command=self.RunAllCommand) self.popupmenu.add_command(label="Run current line", command=self.RunLineCommand) self.popupmenu.add_command(label="Run selection", command=self.RunSelectionCommand) self.output_stream = TkPadOutputStream(self.text_output) self.input_stream = TkPadInputStream(self.text_entry,self.output_stream)