Exemplo n.º 1
0
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))
Exemplo n.º 2
0
  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)
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
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
Exemplo n.º 5
0
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
Exemplo n.º 6
0
    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()
Exemplo n.º 7
0
    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()
Exemplo n.º 8
0
    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
Exemplo n.º 9
0
    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
Exemplo n.º 10
0
    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)
Exemplo n.º 11
0
    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)
Exemplo n.º 12
0
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.")
Exemplo n.º 13
0
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)
Exemplo n.º 14
0
    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)
Exemplo n.º 15
0
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
Exemplo n.º 16
0
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)
Exemplo n.º 17
0
Arquivo: cfg.py Projeto: gijs/nltk
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)
Exemplo n.º 18
0
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)