コード例 #1
0
class VennGUI(object):
    def __init__(self, argv):
        """
        :param argv: arguments for running the program
                     Usage: venn_gui.py <-f filename>
        """
        # Arguments
        parser = argparse.ArgumentParser()
        parser.add_argument("-f",
                            "--filename",
                            help="Read premises from local file",
                            type=str)
        parser.add_argument("-e",
                            "--eval",
                            help="The argument being validated",
                            type=str)
        parser.add_argument("--no_window",
                            help="Get the result immediately without"
                            " showing the interactive window "
                            "(Need -f argument)",
                            action="store_true")
        parser.add_argument("--export",
                            help="Export the result to an image file "
                            "(Need -f and --no_window argument)",
                            type=str)
        self.args = parser.parse_args(argv[1:])
        # Basic components
        self.filename = ""
        self.filepath = ""
        self.collect = None
        self.root = None
        self.fig = None
        self.msg_text = None
        self.msg_label = None
        self.premises_box = None
        self.show_btn = None
        self.is_possible_highlight = None
        self.show_exp_in_diagram = None
        self.eval_box = None
        if not self.args.no_window:
            self.set_up()

    # ===============================================================================
    #                         Basic GUI related operations
    # ===============================================================================
    def run(self):
        """
        Start the GUI window
        """
        if self.args.no_window:
            s = ExpressionSet()
            if self.args.filename:
                with open(self.args.filename, 'r', encoding='utf8') as f:
                    premises = f.read()
                s.add_premises(premises)
                s.parse_premises()
                s.display_diagram()
                if self.args.eval:
                    ret = s.evaluate(Expression(self.args.eval), show=True)
                if self.args.export:
                    plt.savefig(self.args.export)
                else:
                    plt.show(block=True)
            else:
                print("ERROR: No premises found.", file=sys.stderr)
        else:
            if self.args.filename:
                self.filepath = self.args.filename
                self.load(new_file=False)
            if self.args.eval:
                self.eval_box.delete(0, tk.END)
                self.eval_box.insert(0, self.args.eval)
                self.evaluate_exp()
            self.root.update()
            self.root.deiconify()
            self.root.mainloop()

    def clear(self):
        """ Empty the diagram, premises box and evaluation box """
        self.premises_box.delete('1.0', tk.END)
        self.msg_text.set("")
        self.eval_box.delete(0, tk.END)
        plt.clf()

    def quit(self):
        """ Quit the program """
        if self.premises_box.edit_modified():
            save_before_exit = tk.messagebox.askyesnocancel(
                "Venn Diagram Interpreter", "Do you want to save the changes?")
            if save_before_exit is None:
                return
            if save_before_exit:
                self.save()
        self.root.quit()

    # ===============================================================================
    #                            GUI preparation
    # ===============================================================================
    def set_up(self):
        """ Set up all GUI components """
        # Set up the venn
        self.collect = ExpressionSet()

        # Set up GUI
        self.root = tk.Tk()
        self.root.title("Venn Diagram Interpreter")
        self.root.withdraw()
        tk.Grid.rowconfigure(self.root, 0, weight=1)
        tk.Grid.columnconfigure(self.root, 0, weight=1)
        self.fig = plt.figure(1)

        canvas = FigureCanvasTkAgg(self.fig, master=self.root)
        plot_widget = canvas.get_tk_widget()

        # The main panel
        plot_widget.grid(row=0,
                         column=0,
                         columnspan=2,
                         sticky=tk.N + tk.S + tk.E + tk.W)

        # ---------------------------- Premises --------------------------------
        # Message
        self.msg_text = tk.StringVar()
        self.msg_label = tk.Label(self.root, textvariable=self.msg_text)
        self.msg_label.grid(row=1, sticky="w", columnspan=2)

        # Premises input box
        tk.Label(self.root,
                 text="Sytnax: (Use quote or a newline to separate)").grid(
                     row=2, sticky="w", columnspan=2)
        tk.Label(self.root,
                 text="\tSet (total 3 at most): The name of the set, "
                 "use a quote(\"\") if it contains multiple words").grid(
                     row=3, sticky="w", columnspan=2)
        tk.Label(self.root,
                 text="\tExpression: <All/Some> A's are <(not)> B's").grid(
                     row=4, sticky="w", columnspan=2)
        tk.Label(self.root, text="Enter the premises:").grid(row=6,
                                                             sticky="w",
                                                             columnspan=2)

        PREMISE_BOX_HEIGHT = 4
        FIRST_ROW_OF_PREMISE_BOX = 3 + PREMISE_BOX_HEIGHT
        self.premises_box = ScrolledText(self.root, height=PREMISE_BOX_HEIGHT)
        self.premises_box.grid(row=FIRST_ROW_OF_PREMISE_BOX,
                               column=0,
                               sticky="nsew",
                               rowspan=PREMISE_BOX_HEIGHT)

        def premises_modified(event):
            curr_title = self.root.title()
            if self.premises_box.edit_modified():
                if not curr_title.startswith("*"):
                    self.root.title("*" + curr_title)
            else:
                curr_title = curr_title[1:] if curr_title[
                    0] == '*' else curr_title
                self.root.title(curr_title)

        self.premises_box.bind("<<Modified>>", premises_modified)

        def focus_next_widget(event):
            event.widget.tk_focusNext().focus()
            return "break"

        self.premises_box.bind("<Tab>", focus_next_widget)

        self.show_btn = tk.Button(self.root,
                                  text="Show diagram",
                                  command=self.show_diagram)
        self.show_btn.grid(row=FIRST_ROW_OF_PREMISE_BOX + 1,
                           column=1,
                           sticky=tk.W + tk.E,
                           rowspan=1)
        self.show_btn.bind("<Return>", lambda e: self.show_btn.invoke())
        self.premises_box.bind("<Control-Return>",
                               lambda e: self.show_btn.invoke())

        clear_btn = tk.Button(self.root, text="Clear", command=self.clear)
        clear_btn.grid(row=FIRST_ROW_OF_PREMISE_BOX + 2,
                       column=1,
                       sticky=tk.W + tk.E,
                       rowspan=1)
        clear_btn.bind("<Return>", lambda e: clear_btn.invoke())

        self.is_possible_highlight = tk.IntVar()
        poss_check = tk.Checkbutton(
            self.root,
            text="Use color shadow to highlight \"Some\" statements.",
            variable=self.is_possible_highlight)
        poss_check.grid(row=FIRST_ROW_OF_PREMISE_BOX + PREMISE_BOX_HEIGHT,
                        column=0)
        poss_check.toggle()

        self.show_exp_in_diagram = tk.IntVar()
        show_exp_check = tk.Checkbutton(
            self.root,
            text="Display the argument in the diagram",
            variable=self.show_exp_in_diagram)
        show_exp_check.grid(row=FIRST_ROW_OF_PREMISE_BOX + PREMISE_BOX_HEIGHT +
                            1,
                            column=0)
        show_exp_check.toggle()

        # Input box
        tk.Label(self.root,
                 text="Enter the expression you want to evaluate:").grid(
                     row=FIRST_ROW_OF_PREMISE_BOX + PREMISE_BOX_HEIGHT + 2,
                     sticky="w",
                     columnspan=2)

        self.eval_box = tk.Entry(self.root)
        self.eval_box.grid(row=FIRST_ROW_OF_PREMISE_BOX + PREMISE_BOX_HEIGHT +
                           3,
                           column=0,
                           sticky="ew")
        self.eval_box.bind("<Return>", lambda e: self.evaluate_exp())

        eval_btn = tk.Button(self.root,
                             text="Evaluate",
                             command=self.evaluate_exp)
        eval_btn.grid(row=FIRST_ROW_OF_PREMISE_BOX + PREMISE_BOX_HEIGHT + 3,
                      column=1)
        eval_btn.bind("<Return>", lambda e: eval_btn.invoke())

        # Menu bar
        menubar = tk.Menu(self.root)
        filemenu = tk.Menu(menubar, tearoff=0)
        filemenu.add_command(label="\tNew         ",
                             accelerator="        Ctrl+N",
                             command=self.new_file)
        self.root.bind('<Control-n>', lambda e: self.new_file())
        filemenu.add_command(label="\tOpen...     ",
                             accelerator="        Ctrl+O",
                             command=self.load)
        self.root.bind('<Control-o>', lambda e: self.load())
        filemenu.add_command(label="\tSave        ",
                             accelerator="        Ctrl+S",
                             command=self.save)
        self.root.bind('<Control-s>', lambda e: self.save())
        filemenu.add_command(label="\tSave As...  ",
                             accelerator="Ctrl+Shift+S",
                             command=self.save_as)
        self.root.bind('<Control-Shift-s>', lambda e: self.save_as())
        filemenu.add_separator()
        filemenu.add_command(label="\tExit", command=quit)
        menubar.add_cascade(label="File", menu=filemenu)

        editmenu = tk.Menu(menubar, tearoff=0)
        editmenu.add_command(
            label="\tUndo",
            accelerator="Ctrl+Z",
            command=lambda: self.root.focus_get().event_generate('<<Undo>>'))
        editmenu.add_separator()
        editmenu.add_command(
            label="\tCut",
            accelerator="Ctrl+X",
            command=lambda: self.root.focus_get().event_generate('<<Cut>>'))
        editmenu.add_command(
            label="\tCopy",
            accelerator="Ctrl+C",
            command=lambda: self.root.focus_get().event_generate('<<Copy>>'))
        editmenu.add_command(
            label="\tPaste",
            accelerator="Ctrl+V",
            command=lambda: self.root.focus_get().event_generate('<<Paste>>'))
        editmenu.add_separator()
        editmenu.add_command(label="\tSelect All",
                             accelerator="Ctrl+A",
                             command=lambda: self.root.focus_get().
                             event_generate('<<SelectAll>>'))
        menubar.add_cascade(label="Edit", menu=editmenu)

        helpmenu = tk.Menu(menubar, tearoff=0)
        helpmenu.add_command(label="Help Index")
        helpmenu.add_command(label="About...")
        menubar.add_cascade(label="Help", menu=helpmenu)

        self.root.config(menu=menubar)
        self.root.protocol("WM_DELETE_WINDOW", quit)

    # ===============================================================================
    #                          Diagram display operations
    # ===============================================================================
    # "Show" button
    def show_diagram(self):
        """ Displays the diagram with existing premises """
        plt.clf()
        self.msg_text.set("")
        # Create the ExpressionSet object
        self.collect = ExpressionSet()
        if self.premises_box.get("1.0", tk.END) == "":
            return
        # Add all premises
        try:
            self.collect.add_premises(
                self.premises_box.get("1.0", tk.END).replace(';', '\n'))
        except NameError as e:
            self.msg_text.set(str(e))
            self.msg_label.configure(foreground="red")
        except TypeError as e:
            print(e, file=sys.stderr)
            pass
        except ValueError as e:
            self.msg_text.set(str(e))
            self.msg_label.configure(foreground="red")
            return
        except SyntaxError as e:
            self.msg_text.set(str(e))
            self.msg_label.configure(foreground="red")
            return
        if self.collect.empty() or len(self.collect) == 1:
            return
        # Parse premises
        try:
            self.collect.parse_premises()
        except ValueError as e:
            self.msg_text.set(str(e))
            self.msg_label.configure(foreground="red")
            return
        self.collect.display_diagram(
            highlight_some=bool(self.is_possible_highlight.get()))
        if not self.args.no_window:
            self.fig.canvas.flush_events()
            self.fig.canvas.draw()

    # "Update" button
    def evaluate_exp(self):
        """ Evaluate an argument and displays the result """
        self.show_diagram()
        if self.collect.empty():
            self.msg_text.set("The diagram is empty!")
            self.msg_label.configure(foreground="red")
            return
        if self.eval_box.get() == "":
            return
        try:
            ret, must, reason = self.collect.evaluate(
                Expression(self.eval_box.get()),
                show=True,
                show_exp=self.show_exp_in_diagram.get())
            self.msg_text.set(reason)
            if ret:
                if must:
                    self.msg_label.configure(foreground="green")
                else:
                    self.msg_label.configure(foreground="yellowgreen")
            else:
                if must:
                    self.msg_label.configure(foreground="red")
                else:
                    self.msg_label.configure(foreground="darkorange")
            if self.args.no_window:
                plt.show(block=True)
            else:
                self.fig.canvas.flush_events()
                self.fig.canvas.draw()
        except SyntaxError as e:
            self.msg_text.set(str(e))
            self.msg_label.configure(foreground="red")

    # ===============================================================================
    #                         Local file operations
    # ===============================================================================
    filetypes = (("Venn Diagram file (*.venn)", "*.venn"),
                 ("Normal text file (*.txt)", "*.txt"), ("All types (*.*)",
                                                         "*.*"))

    def load(self, new_file=True):
        """ Load premises from local file """
        if new_file:
            self.filepath = tk.filedialog.askopenfilename(
                defaultextension=".venn", filetypes=VennGUI.filetypes)
        if self.filepath == "":
            return
        if not os.path.exists(self.filepath):
            print("ERROR File \"{}\" does not exist.".format(self.filepath),
                  file=sys.stderr)
            return
        self.filename = os.path.basename(self.filepath)
        with open(self.filepath, 'r', encoding='utf8') as f:
            text = f.read()
        self.premises_box.delete('1.0', tk.END)
        self.premises_box.insert(tk.INSERT, text)
        self.premises_box.edit_modified(False)
        self.show_btn.invoke()
        self.msg_text.set("Successfully load from file \"{}\"".format(
            self.filename))
        self.msg_label.configure(foreground="green")
        self.root.title(self.filename + " - Venn Diagram Interpreter")

    def save_as(self, new_file=True):
        """ Save premises to local file """
        if new_file or self.filepath == "" or self.filename == "":
            self.filepath = tk.filedialog.asksaveasfilename(
                defaultextension=".venn", filetypes=VennGUI.filetypes)
            if self.filepath == "":
                return
            self.filename = os.path.basename(self.filepath)
        with open(self.filepath, "w", encoding='utf8') as text_file:
            text_file.write(self.premises_box.get("1.0", tk.END))
        self.msg_text.set("Successfully saved file \"{}\"".format(
            self.filename))
        self.msg_label.configure(foreground="green")
        self.root.title(self.filename + " - Venn Diagram Interpreter")

    def save(self):
        """ Save premises to current file """
        if self.filename == "":
            self.save_as()
        self.save_as(new_file=False)

    def new_file(self):
        """ Create a new file """
        if self.premises_box.edit_modified():
            save_before_new = tk.messagebox.askyesnocancel(
                "Venn Diagram Interpreter", "Do you want to save the changes?")
            if save_before_new is None:
                return
            if save_before_new:
                self.save()
        self.clear()
        self.premises_box.edit_modified(False)
        self.filename = ""
        self.filepath = ""
        self.root.title("Venn Diagram Interpreter")
コード例 #2
0
class OptimizerMainWindow():
    '''
    classdocs
    '''
    
    #TODO: change that name
    def reactToClick(self, event):
        a = AddRestrictionDialog(self)

    def __init__(self, optimizer):
        
        # always have a reference to model/controller
        self.optimizer = optimizer
        
        # setup main GUI and make stretchable
        self.guiRoot = Tk()
        self.guiRoot.title("OPTIMIZR")
        self.guiRoot.columnconfigure(1, weight=1)
        self.guiRoot.rowconfigure(0, weight=1)
        
        # left (settings) and right (sequences) part
        self.frameLeft = Frame(self.guiRoot)
        self.frameLeft.grid(row=0, column=0, sticky=W+E+N+S)
        self.frameLeft.columnconfigure(0, weight=1)
        self.frameRight = Frame(self.guiRoot)
        self.frameRight.grid(row=0, column=1, sticky=W+E+N+S)
        self.frameRight.columnconfigure(0, weight=1)
        self.frameRight.rowconfigure(0, weight=1)
        self.frameRight.rowconfigure(1, weight=1)
        
        
        self.frameSpeciesControll = LabelFrame(self.frameLeft, text="Species", pady=10, padx=10)
        self.frameSpeciesControll.columnconfigure(1, weight=1)
        self.frameOptimizationControll = LabelFrame(self.frameLeft, text="Optimization", pady=10, padx=10)
        self.frameRestrictionControll = LabelFrame(self.frameLeft, text="Restriction Enzymes", pady=10, padx=10)
        self.frameSpeciesControll.grid(row=0, column=0, sticky=W+E, padx=10, pady=10)
        self.frameOptimizationControll.grid(row=1, column=0, sticky=W+E, padx=10, pady=10)
        self.frameRestrictionControll.grid(row=2, column=0, sticky=W+E, padx=10, pady=10)
        
        # Species Controll
        Label(self.frameSpeciesControll, text="Source:").grid(row=0, column=0)
        Label(self.frameSpeciesControll, text="Target:").grid(row=1, column=0)
        
        self.comboSourceSpecies = Combobox(self.frameSpeciesControll, state="readonly")
        self.comboSourceSpecies.grid(row=0, column=1, pady=5, sticky="ew")
        self.comboTargetSpecies = Combobox(self.frameSpeciesControll, state="readonly")
        self.comboTargetSpecies.grid(row=1, column=1, pady=5, sticky="we")        
        self.buttonSpeciesList = Button(self.frameSpeciesControll, text="Edit Species List")
        self.buttonSpeciesList.grid(row=2, column=1, pady=5, sticky="e")
        
        self.comboSourceSpecies.bind("<<ComboboxSelected>>", self.actionOptimizerSettingsChanged)
        self.comboTargetSpecies.bind("<<ComboboxSelected>>", self.actionOptimizerSettingsChanged)
        
        # Optimization Controll
        Label(self.frameOptimizationControll, text="Optimization Strategy:").grid(row=0, column=0)
        self.comboOptimizationStrategy = Combobox(self.frameOptimizationControll, state="readonly")
        self.comboOptimizationStrategy.grid(row=0, column=1)
        self.comboOptimizationStrategy["values"] = self.optimizer.possibleOptimizationStrategies
        self.comboOptimizationStrategy.bind("<<ComboboxSelected>>", self.actionOptimizerSettingsChanged)
        
        # Restriction Enzymes
        self.listRestriction = Listbox(self.frameRestrictionControll)
        self.listRestriction.grid(row=0, column=0, columnspan=3, pady=5, sticky=W+E)
        self.frameRestrictionControll.columnconfigure(0, weight=1)
        self.buttonRestricionAdd = Button(self.frameRestrictionControll, text=" + ")
        self.buttonRestricionDel = Button(self.frameRestrictionControll, text=" - ")
        self.buttonRestricionAdd.grid(row=1, column=1, padx=5)
        self.buttonRestricionDel.grid(row=1, column=2, padx=5)
        
        # Source Sequence Frame
        self.frameSourceSequence = LabelFrame(self.frameRight, text="Source Sequence", padx=10, pady=10)
        self.frameResultSequence = LabelFrame(self.frameRight, text="Result Sequence", padx=10, pady=10)
        self.frameSourceSequence.grid(row=0, column=0, sticky="wens", padx=10, pady=10)
        self.frameResultSequence.grid(row=1, column=0, sticky="wens", padx=10, pady=10)
        
        
        self.buttonSourceLoad = Button(self.frameSourceSequence, text=" Load ")
        self.textSourceSeq = ScrolledText(self.frameSourceSequence, height=10)
        self.buttonSourceLoad.grid(row=0, column=1, sticky="e", pady=5)
        self.textSourceSeq.grid(row=1, column=0, columnspan=2, sticky="wens")
        self.frameSourceSequence.columnconfigure(0, weight=1)
        self.frameSourceSequence.rowconfigure(1, weight=1)
        self.textSourceSeq.frame.columnconfigure(1, weight=1)
        self.textSourceSeq.frame.rowconfigure(0, weight=1)
        
        self.buttonOptimize = Button(self.frameResultSequence, text=" OPTIMIZE! ")
        self.buttonOptimize.bind("<ButtonRelease>", self.actionOptimize)
        
        self.buttonRemoveRestriction = Button(self.frameResultSequence, text=" RESTRICTION-B-GONE! ")
        self.buttonRemoveRestriction.bind("<ButtonRelease>", self.actionRemoveRestricion)
        
        self.buttonSaveResult = Button(self.frameResultSequence, text=" Save ")
        self.textResultSequence = ScrolledText(self.frameResultSequence, height=10)
        self.buttonOptimize.grid(column=0, row=0, pady=5, sticky="w")
        self.buttonRemoveRestriction.grid(column=1, row=0, pady=5, padx=10, sticky="w")
        self.textResultSequence.grid(row=1, column=0, columnspan=4, sticky="wens")
        self.buttonSaveResult.grid(row=2, column=3, pady=5, sticky="e")
        self.frameResultSequence.columnconfigure(2, weight=1)
        self.frameResultSequence.rowconfigure(1, weight=1)
        self.textResultSequence.frame.columnconfigure(1, weight=1)
        self.textResultSequence.frame.rowconfigure(0, weight=1)
        
        self.textSourceSeq.bind("<<Modified>>", self.actionSequenceModified)
        self.textResultSequence.bind("<<Modified>>", self.actionSequenceModified)
        
        #generate color tags for textboxes
        for i in range(101):
            
            #green for normal codons
            (r,g,b) = colorsys.hsv_to_rgb(210/360, i/100, 1.0)            
            colorHex = "#%02x%02x%02x" % (int(r*255), int(g*255), int(b*255))
            
            self.textSourceSeq.tag_config("normal"+str(i), background=colorHex)
            self.textResultSequence.tag_config("normal"+str(i), background=colorHex)
            
            #red for codons with restriction sites
            (r,g,b) = colorsys.hsv_to_rgb(5/360, i/100, 1.0)            
            colorHex = "#%02x%02x%02x" % (int(r*255), int(g*255), int(b*255))
            
            self.textSourceSeq.tag_config("restrict"+str(i), background=colorHex)
            self.textResultSequence.tag_config("restrict"+str(i), background=colorHex)
        
        
        # Set (minimum + max) Window size 
        self.guiRoot.update()
        self.guiRoot.minsize(self.guiRoot.winfo_width(), self.guiRoot.winfo_height())
        
        self.buttonRestricionAdd.bind("<ButtonRelease>", self.reactToClick)
        self.buttonRestricionDel.bind("<ButtonRelease>", self.actionRestrictionEnzymeDelete)
        self.buttonSpeciesList.bind("<ButtonRelease>", self.actionEditSpeciesButton)
        
        self.buttonSourceLoad.bind("<ButtonRelease>", self.actionLoadSequence)
        self.buttonSaveResult.bind("<ButtonRelease>", self.actionSaveSequence)
        
        # TEST
#         self.listRestriction.insert("end", "EcoRI")
#         self.listRestriction.insert("end", "BamHI")
#         
        
        # dummy event to manually trigger update
        self.guiRoot.bind("<<Update>>", self.actionUpdate)
        
        self.actionUpdate(None)
        
        self.guiRoot.mainloop()
    
    def actionRestrictionEnzymeDelete(self, event):
        try:
            selectedEnzyme = self.listRestriction.selection_get()
            self.optimizer.restrictionEnzymeList.remove(selectedEnzyme)
            self.guiRoot.event_generate("<<Update>>")
        except tkinter.TclError :
            # no selection
            pass    
        
    def actionUpdate(self, event):
#         print("update called")

        # clear list of restriction enzymes
        self.listRestriction.delete(0, "end")        
        for r in self.optimizer.restrictionEnzymeList:
            self.listRestriction.insert("end", r)
            
        self.comboSourceSpecies.delete(0, "end")
        self.comboTargetSpecies.delete(0, "end")
        
        speciesValues = list()        
        for (taxid, name) in self.optimizer.speciesList:
            speciesValues.append(taxid + ": " + name)
            
        self.comboSourceSpecies["values"] = speciesValues
        self.comboTargetSpecies["values"] = speciesValues
        
        if self.comboSourceSpecies.get() not in speciesValues:
            self.comboSourceSpecies.set("")
        if self.comboTargetSpecies.get() not in speciesValues:
            self.comboTargetSpecies.set("")
            
        self.textSourceSeq.edit_modified(True)
        self.textResultSequence.edit_modified(True)
        
        self.optimizer.saveConfig("config.ini")
            
    def actionEditSpeciesButton(self, event):
        speciesListDialog = SpeciesListDialog(self)
        
    def actionOptimizerSettingsChanged(self, event=None):
#         print("Something happened")
        strategy = self.comboOptimizationStrategy.get()
        sourceString = self.comboSourceSpecies.get()
        targetString = self.comboTargetSpecies.get()
        
        if not (strategy and sourceString and targetString):
            return
        
        sourceTaxid = sourceString.split(":")[0]
        targetTaxid = targetString.split(":")[0]
        
        self.optimizer.setOptimizer(sourceTaxid, targetTaxid, strategy)
        
        self.textSourceSeq.edit_modified(True)
        self.textResultSequence.edit_modified(True)
#         self.optimizer.testPrint()

    def actionOptimize(self, event=None):
        self.optimizer.runOptimization()
        self.textSourceSeq.edit_modified(True)
        self.textResultSequence.edit_modified(True)
        
    def actionRemoveRestricion(self, event=None):
        self.optimizer.runRestricionRemoval()
        self.textSourceSeq.edit_modified(True)
        self.textResultSequence.edit_modified(True)
        
    def actionSequenceModified(self, event=None):
        # necessary if, otherwise -> infinite loop
        if self.textSourceSeq.edit_modified():
            
            seq = self.textSourceSeq.get("1.0", "end").strip()
            seq = stripCharsNotInList(seq.upper(), ['A', 'C', 'G', 'T'])
            self.optimizer.setSourceSeq(seq)
            
            oldInsert = self.textSourceSeq.index("insert")
            self.textSourceSeq.delete("1.0", "end")
            
            sourceCodons = self.optimizer.getCodonsForPrint(True)
            if not sourceCodons:
                self.textSourceSeq.insert("end", self.optimizer.sourceSequence)
            else:
                for (co, sc, r) in sourceCodons:
                    if sc:
                        if not r:
                            self.textSourceSeq.insert("end", co, "normal"+str(int(sc*100)))
                            #print("normal"+str(int(sc*100)))
                        else:
                            self.textSourceSeq.insert("end", co, "restrict"+str(int(sc*100)))
                    else:
                        # remainder without color
                        self.textSourceSeq.insert("end", co)
                    
                
            self.textSourceSeq.mark_set("insert", oldInsert)

            # reset the modified status at the very end
            self.textSourceSeq.edit_modified(False)

        if self.textResultSequence.edit_modified():
            
            seq = self.textResultSequence.get("1.0", "end").strip()
#             self.optimizer.setOptimizedSeq(seq)
            
            oldInsert = self.textResultSequence.index("insert")
            self.textResultSequence.delete("1.0", "end")
            
            targetCodons = self.optimizer.getCodonsForPrint(False)
            if not targetCodons:
                self.textSourceSeq.insert("end", self.optimizer.optimizedSequence)
            else:
                for (co, sc, r) in targetCodons:
                    if sc:
                        if not r:
                            self.textResultSequence.insert("end", co, "normal"+str(int(sc*100)))
                            #print("normal"+str(int(sc*100)))
                        else:
                            self.textResultSequence.insert("end", co, "restrict"+str(int(sc*100)))
                    else:
                        # remainder without color
                        self.textResultSequence.insert("end", co)
                    
                
            self.textSourceSeq.mark_set("insert", oldInsert)
            
            self.textResultSequence.edit_modified(False)

    def actionLoadSequence(self, event=None):
        filename = tkinter.filedialog.askopenfilename()
        if filename:
            seq = sequenceIO.readFile(filename)
            self.textSourceSeq.delete("1.0", "end")
            self.textSourceSeq.insert("end", seq)            
            self.textSourceSeq.edit_modified(True)
            
    def actionSaveSequence(self, event=None):
        filename = tkinter.filedialog.asksaveasfilename()
        if filename:
#             print("file is " + filename)
            with open(filename, mode='w') as fd:
                fd.write(self.optimizer.optimizedSequence)
コード例 #3
0
class Gui():
    def __init__(self):
        self.file_path = None
        self.simulation_data = None  # A ScriptOutput object

        self.root = tk.Tk()
        self.root.protocol("WM_DELETE_WINDOW", self.file_quit)

        self.set_title()

        self.scriptLabel = None
        self.scriptField = None
        self._create_widgets()
        self._assign_accelerators()

        self.root.mainloop()

    def _create_widgets(self):
        # The frame containing the widgets
        frame = tk.Frame(self.root)

        # The menu bar
        menu_bar = tk.Menu(self.root, tearoff=0)

        # The File menu
        file_menu = tk.Menu(
            menu_bar, tearoff=0)  # tearoff = 0: can't be seperated from window
        file_menu.add_command(label="New", underline=0,
                              command=self.file_new)  # , accelerator="Ctrl+N")
        file_menu.add_command(
            label="Open...", underline=0,
            command=self.file_open)  # , accelerator="Ctrl+O")
        file_menu.add_command(
            label="Save", underline=0,
            command=self.file_save)  # , accelerator="Ctrl+S")
        file_menu.add_command(label="Save As...",
                              underline=1,
                              command=self.file_save_as)
        file_menu.add_separator()
        file_menu.add_command(label="Exit",
                              underline=1,
                              command=self.file_quit)
        menu_bar.add_cascade(label="File", underline=0, menu=file_menu)

        # The Run menu
        run_menu = tk.Menu(
            menu_bar, tearoff=0)  # tearoff = 0: can't be seperated from window
        run_menu.add_command(label="Simulate and Plot",
                             underline=0,
                             command=self.simulate,
                             accelerator="F5")
        run_menu.add_command(label="Plot", underline=0, command=self.plot)
        menu_bar.add_cascade(label="Run", underline=0, menu=run_menu)

        # The Edit menu
        edit_menu = tk.Menu(
            menu_bar, tearoff=0)  # tearoff = 0: can't be seperated from window
        edit_menu.add_command(label="Undo",
                              underline=0,
                              command=self.undo,
                              accelerator="Ctrl+Z")
        edit_menu.add_command(label="Redo",
                              underline=0,
                              command=self.redo,
                              accelerator="Ctrl+Y")
        menu_bar.add_cascade(label="Edit", underline=0, menu=edit_menu)

        self.root.config(menu=menu_bar)

        # The label
        lbltxt = "Place your script in the box below or open a text file"
        # lbltxt = "Simulate: F5, Open: Ctrl+O, Save: Ctrl+S, New: Ctrl+N"
        scriptLabel = tk.Label(frame, text=lbltxt)
        scriptLabel.pack(side="top", anchor="w")

        # The Text widget
        self.scriptField = ScrolledText(frame)
        self.scriptField.pack(side="top", fill=BOTH, expand=YES)

        self.scriptField.config(undo=True)
        self.scriptField.focus_set()

        # self.scriptField.config(
        #     borderwidth=0,
        #     font="{Lucida Sans Typewriter} 12",
        #     foreground="green",
        #     background="black",
        #     insertbackground="white",  # cursor
        #     selectforeground="green",  # selection
        #     selectbackground="#008000",
        #     wrap=tk.WORD,  # use word wrapping
        #     width=64,
        #     undo=True,  # Tk 8.4
        # )

        # The Quit button
        # quitButton = tk.Button(frame, text="Quit", command=self.quit)
        # quitButton.pack(side="right")

        # The Close All button
        closefigButton = tk.Button(frame,
                                   text="Close All Figures",
                                   command=self.close_figs)
        closefigButton.pack(side="right")

        # The Simulate button
        simButton = tk.Button(frame,
                              text="Simulate and Plot",
                              command=self.simulate)
        simButton.pack(side="left")

        # The Plot button
        plotButton = tk.Button(frame, text="Plot", command=self.plot)
        plotButton.pack(side="left")

        frame.pack(fill=BOTH, expand=YES)

    def simulate(self, event=None):
        try:
            script = self.scriptField.get("1.0", "end-1c")
            script_obj = LsScript.LsScript(script)
            self.simulation_data = script_obj.run()
            script_obj.postproc(self.simulation_data)
        except Exception as ex:
            self.handle_exception(ex)

    def plot(self):
        try:
            if self.simulation_data is None:
                raise LsGuiException("No simulation data to plot.")
            script = self.scriptField.get("1.0", "end-1c")
            script_obj = LsScript.LsScript(script)
            script_obj.postproc(self.simulation_data)
        except Exception as ex:
            self.handle_exception(ex)

    def close_figs(self):
        plt.close("all")

    def handle_exception(self, ex):
        # err_msg = ex.args[0]
        err_msg = str(ex)
        # if len(ex.args) == 2:
        #     err_msg = "{0} {1}".format(err_msg, ex.args[1])
        #     # err_msg = err_msg + ex.args[1]
        messagebox.showerror("Error", err_msg)
        print(traceback.format_exc())

    # def file_open(self):
    #     filename = filedialog.askopenfilename()
    #     # filename = "C:/Python/Python36-32/_Markus/scriptexempel2.txt"  # XXX
    #     file = open(filename, "r")
    #     self.scriptField.delete("1.0", "end-1c")
    #     self.scriptField.insert("1.0", file.read())
    #     self.scriptField.mark_set("insert", "1.0")
    #     file.close()  # Make sure you close the file when done

    def save_changes(self):
        if self.scriptField.edit_modified():
            msg = "This document has been modified. Do you want to save changes?"
            save_changes = messagebox.askyesnocancel("Save?", msg)
            if save_changes is None:  # Cancel
                return False
            elif save_changes is True:  # Yes
                self.file_save()
        return True

    def file_new(self, event=None):
        save_changes = self.save_changes()
        if not save_changes:
            return
        self.scriptField.delete(1.0, "end")
        self.scriptField.edit_modified(False)
        self.scriptField.edit_reset()
        self.file_path = None
        self.set_title()

    def file_open(self, event=None):  # , filepath=None):
        save_changes = self.save_changes()
        if not save_changes:
            return

        # XXX
        initialdir = '.'
        if os.path.isdir('/home/markus/Dropbox/'):
            initialdir = '/home/markus/Dropbox/LearningSimulator/Scripts'

        filepath = filedialog.askopenfilename(filetypes=FILETYPES,
                                              initialdir=initialdir)
        if filepath is not None and len(filepath) != 0:
            with open(filepath, encoding="utf-8") as f:
                file_contents = f.read()
            # Set current text to file contents
            self.scriptField.delete(1.0, "end")
            self.scriptField.insert(1.0, file_contents)
            self.scriptField.edit_modified(False)
            self.scriptField.mark_set("insert", "1.0")
            self.file_path = filepath
            self.set_title()

    def file_save(self, event=None):
        self.file_save_as(filepath=self.file_path)

    def file_save_as(self, filepath=None, event=None):
        if filepath is None:
            filepath = filedialog.asksaveasfilename(filetypes=FILETYPES)
            if len(
                    filepath
            ) == 0:  # Empty tuple or empty string is returned if cancelled
                return  # "cancelled"
        try:
            with open(filepath, 'wb') as f:
                text = self.scriptField.get(1.0, "end-1c")
                f.write(bytes(text, 'UTF-8'))
                self.scriptField.edit_modified(False)
                self.file_path = filepath
                self.set_title()
                return  # "saved"
        except IOError as e:
            self.handle_exception(e)
            return  # "cancelled"

    def file_quit(self, event=None):
        save_changes = self.save_changes()
        if not save_changes:
            return
        self.close_figs()
        self.root.destroy()  # sys.exit(0)

    def set_title(self, event=None):
        if self.file_path is not None:
            # title = os.path.basename(self.file_path)
            title = os.path.abspath(self.file_path)
        else:
            title = "Untitled"
        self.root.title(title + " - " + TITLE)

    def undo(self, event=None):
        try:
            self.scriptField.edit_undo()
        except Exception as e:
            self.handle_exception(e)
        return "break"

    def redo(self, event=None):
        self.scriptField.edit_redo()
        return "break"

    def _assign_accelerators(self):
        # self.scriptField.bind("<Control-n>", self.file_new)
        # self.scriptField.bind("<Control-N>", self.file_new)
        # self.scriptField.bind("<Control-o>", self.file_open)
        # self.scriptField.bind("<Control-O>", self.file_open)
        # self.scriptField.bind("<Control-S>", self.file_save)
        # self.scriptField.bind("<Control-s>", self.file_save)
        self.scriptField.bind("<Control-y>", self.redo)
        self.scriptField.bind("<Control-Y>", self.redo)
        self.scriptField.bind("<Control-z>", self.undo)
        self.scriptField.bind("<Control-Z>", self.undo)

        # self.root.bind_class("Text", ",<Control-z>", self.undo)
        # self.root.bind_class("Text", ",<Control-Z>", self.undo)
        # self.root.bind_class("Text", ",<Control-y>", self.redo)
        # self.root.bind_class("Text", ",<Control-Y>", self.redo)

        self.scriptField.bind("<F5>", self.simulate)
コード例 #4
0
ファイル: THAT_IDE.py プロジェクト: TheRealSAP36/That_IDE
class main:
    def __init__(self, master, lexer):
        self.master = master
        self.master.title("PyDE - Untitled")
        self.filename = None
        self.lexer = lexer
        self.x, self.y = 0, 10
        self.ftsize = 15
        self.end = ""

        self.img = PhotoImage(file="C:/Users/shiven/Desktop/anime.png")
        self.__anime__ = self.img.subsample(3, 3)

        self.mario1 = PhotoImage(
            file="C:/Users/shiven/Desktop/C++/mariofinal1.png")
        self.mario2 = PhotoImage(
            file="C:/Users/shiven/Desktop/C++/mariofinal2.png")

        self.mario1 = self.mario1.subsample(2, 2)

        self.types = [("All Files", "*.*"), ("Text Files", "*.txt")]

        self.draw()
        self.text.bind("<Control-N>", self.newfile)
        self.text.bind("<Control-n>", self.newfile)
        self.text.bind("<Control-S>", self.savefile)
        self.text.bind("<Control-s>", self.savefile)
        self.text.bind("<Control-o>", self.openfile)
        self.text.bind("<Control-O>", self.openfile)

        self.text.bind("<Control-d>", self.copy_cur_line)
        self.text.bind("<Control-D>", self.copy_cur_line)

        self.text.bind("<Tab>", self.spaces)
        self.text.bind("<KeyRelease>", self.cur_line_col)
        self.text.bind("<Button-1>", self.cur_line_col)
        self.text.bind("<Button-3>", self.cur_line_col)
        self.text.bind("<Button-2>", self.cur_line_col)
        self.text.bind("<Motion>", self.cur_line_col)
        self.text.bind("<Configure>", self.cur_line_col)

        self.master.bind("<Control-[>", self.indent)
        self.master.bind("<Control-]>", self.dedent)
        self.master.bind("<Control-/>", self.comment)
        self.master.bind("<Alt-s>", self.uncomment)

        self.master.bind("<Alt-Up>", self.zoom_in)
        self.master.bind("<F3>", self.zoom_out)

        self.master.bind("<Shift-(>", self.insert_paren)
        self.master.bind("<[>", self.insert_paren)
        self.master.bind("<Shift-{>", self.insert_paren)

        self.master.bind("<Control-b>", self.runscript)

        self.animation()
        self.display_time()
        self.__styles()

        self.master.bind("<KeyRelease>", self.highlight)
        self.master.bind("<Key>", self.highlight)

    def highlight(self, e):
        self.recolor()

    def highlight_(self):
        self.recolor()
        self.master.after(1000, self.highlight_())

    def __styles(self):
        self.bdfont = font.Font(self.text, self.text.cget("font"))
        self.bdfont.config(weight=font.BOLD)

        self.itfont = font.Font(self.text, self.text.cget("font"))
        self.itfont.config(slant=font.ITALIC)

        self.style = __get__('default')

        for ttype, ndef in self.style:
            self.tag_font = None
            if ndef['bold']:
                self.tag_font = self.bdfont
            elif ndef['italic']:
                self.tag_font = self.itfont

            if ndef['color']:
                self.fg = "#%s" % ndef['color']

            else:
                self.fg = None

            self.text.tag_configure(str(ttype),
                                    foreground=self.fg,
                                    font=self.tag_font)

    def recolor(self):
        self.code = self.text.get("1.0", "end-1c")
        self.tokensource = self.lexer.get_tokens(self.code)
        self.start_line = 1
        self.start_index = 0

        self.end_line = 1
        self.end_index = 0

        for ttype, value in self.tokensource:
            if "\n" in value:
                self.end_line += value.count("\n")
                self.end_index = len(value.rsplit("\n", 1)[1])

            else:
                self.end_index += len(value)

            if value not in (" ", "\n"):
                idx1 = "%s.%s" % (self.start_line, self.start_index)
                idx2 = "%s.%s" % (self.end_line, self.end_index)

                for tagname in self.text.tag_names(idx1):
                    self.text.tag_remove(tagname, idx1, idx2)

                self.text.tag_add(str(ttype), idx1, idx2)
            self.start_line = self.end_line
            self.start_index = self.end_index

    def draw(self):
        self.filename = None
        self.path = None
        self.master.title("PyDE - {}".format("Untitled"))
        self.master.config(bg="Gray")

        self.anime__ = Canvas(self.master,
                              width=1200,
                              height=25,
                              bg="Gray",
                              relief=RAISED,
                              highlightbackground='Gray')
        self.anime__.pack(anchor=NE)

        self.__display = Label(self.master,
                               text="",
                               bg="Gray",
                               fg="White",
                               padx=55,
                               pady=10,
                               justify=RIGHT,
                               font=("8514oem", 1, 'normal'))
        self.__display.place(x=0, y=0)

        self.lcol = Label(self.master, bg="Gray")
        self.lcol.pack(side=BOTTOM, fill=X)

        self.scrollx = Scrollbar(self.master, orient=HORIZONTAL)
        self.scrollx.pack(side=BOTTOM, fill=X)

        self.text = ST(self.master,
                       xscrollcommand=self.scrollx.set,
                       selectbackground="Gray",
                       fg="Gray",
                       height=400,
                       bg="Black",
                       width=500,
                       wrap=NONE,
                       blockcursor=True)
        self.text.pack(side=TOP)

        self.scrollx.config(command=self.text.xview)

        self.text.config(fg="White",
                         font=("8514oem", self.ftsize, 'bold'),
                         insertbackground="Red")

        self.l_c = Label(self.lcol, bg="Gray")
        self.l_c.pack(side=RIGHT)

        self.timelabel = Label(self.lcol,
                               text="",
                               bg=self.anime__['bg'],
                               font=("8514oem", self.ftsize, "bold"))
        self.timelabel.place(x=0, y=self.master.winfo_height() - 3)

    def newfile(self, e):
        self.filename = None
        self.path = None
        self.curname = "Untitled"
        if len(self.text.get(0.0, END)) > 1:
            self.asknew = askyesno("File changed", "Save file?")
            if self.asknew == True:
                self.savefile_()
            else:
                self.text.delete(1.0, END)
                self.master.title("PyDE - {}".format(self.curname))
                self.__display.config(text="Untitled.py")
        else:
            self.__display.config(text="Untitled.py")

    def savefile_(self):
        if self.filename == None:
            self.s = asksaveasfile(defaultextension=self.types,
                                   filetypes=self.types)
            self.path = self.s.name
            self.curname = self.s.name.split("/")[-1]
            self.master.title("PyDE - {}".format(self.curname))
            self.__display.config(text=self.curname)
        else:
            self.s.write(self.text.get(1.0, END))

    def savefile(self, e):
        if self.filename == None:
            self.s = asksaveasfile(defaultextension=self.types,
                                   filetypes=self.types)
            self.path = self.s.name
            self.curname = self.s.name.split("/")[-1]
            self.master.title("PyDE - {}".format(self.curname))
            self.__display.config(text=self.curname)
        else:
            self.s.write(self.text.get(1.0, END))

    def openfile(self, e):
        try:
            self.o = askopenfile(filetypes=self.types,
                                 defaultextension=self.types)
            self.curname = self.o.name.split("/")[-1]
            self.path = self.o.name
            self.master.title("PyDE - {}".format(self.curname))
            self.__display.config(text=self.curname)
            if self.text.edit_modified():
                self.a_open = askyesno("save this thing?", "Save file?")
                if self.a_open == True:
                    self.savefile_()
                else:
                    pass
            else:
                self.text.delete(0.0, END)
                self.op = self.o.read()
                self.text.insert(END, self.op)
        except UnicodeDecodeError:
            self.unable = showerror("Invalid file", "Invalid file")

    def openfile_(self):
        try:
            if self.text.edit_modified():
                self.savefile_()
            else:
                self.o = askopenfile(filetypes=self.types,
                                     defaultextension=self.types)
                self.op = self.o.read()
                self.path = self.o.name
                self.text.insert(END, self.op)
        except UnicodeDecodeError:
            self.unable = showerror("Invalid file", "Invalid file")

    def animation(self):
        self.x += 5
        self.anime__.delete(ALL)
        self.anime__.create_image(self.x * 2, self.y + 5, image=self.mario1)
        if (self.x - 10) >= self.anime__.winfo_width():
            self.x = 0
        self.master.after(100, self.animation)


#          self.y-=5

    def cur_line_col(self, e):
        self.l_raw = self.text.index(INSERT)
        self.lines = self.l_raw.split(".")[0]
        self.cols = self.l_raw.split(".")[1]
        self.binder_ = int(self.cols)
        self.l_c.config(text="lines:{0}  columns:{1}".format(
            self.lines, self.cols),
                        font=("8514oem", 9, 'bold'))

    def spaces(self, e):
        self.text.insert(INSERT, " " * 4)
        return 'break'

    def indent(self, e):
        self.tab = "    "
        self.untabbed = self.text.get("sel.first", "sel.last")
        self.splitted = self.untabbed.split("\n")
        self.text.delete("sel.first", "sel.last")
        self.conts = []
        for self.conts in list(self.splitted):
            self.conts = self.tab + self.conts + "\n"
            self.text.insert(INSERT, self.conts)

    def dedent(self, e):
        self.tab = "    "
        self.tabbed = self.text.get("sel.first", "sel.last")
        self.splitted = self.tabbed.split("\n")
        self.text.delete("sel.first", "sel.last")
        self.conts = []
        for self.conts in list(self.splitted):
            self.conts = self.conts.replace(self.tab, "") + "\n"
            self.text.insert(INSERT, self.conts)

    def comment(self, e):
        self.comment = "#"
        self.uncommented = self.text.get("sel.first", "sel.last")
        self.split_comment = self.uncommented.split("\n")
        self.split_comment = list(self.split_comment)
        self.text.delete("sel.first", "sel.last")
        self.commconts = []
        for self.commconts in self.split_comment:
            self.commconts = self.comment + self.commconts + "\n"
            self.text.insert(INSERT, self.commconts)

    def uncomment(self, e):
        self.comment = "#"
        self.commented = self.text.get("sel.first", "sel.last")
        self.split_uncomm = self.commented.split("\n")
        self.split_uncomm = list(self.split_uncomm)
        self.text.delete("sel.first", "sel.last")
        self.unconts = []
        for self.unconts in self.split_uncomm:
            self.unconts = self.unconts.replace(self.comment, "") + "\n"
            self.text.insert(INSERT, self.unconts)

    def runscript(self, e):
        if self.path == None:
            self.asksave = askyesno("Save this file?", "Save?")
            if self.asksave == True:
                self.savefile()
                os.system("python {}".format(self.path))
                self.result = str(
                    subprocess.check_output(['python', self.path]))
                self.output = showinfo("Output", "%s" % (self.result))

            else:
                showinfo("Cant run before saving..",
                         "Cant run before saving..")
        else:
            os.system("python {}".format(self.path))
            self.result = str(subprocess.check_output(['python', self.path]))
            self.output = showinfo("Output", "%s" % (self.result))

    def zoom_in(self, event):
        self.ftsize += 2
        self.bdfont.config(size=self.ftsize)
        self.itfont.config(size=self.ftsize)
        self.text.config(font=("8514oem", self.ftsize, 'bold'))

    def zoom_out(self, e):
        self.ftsize -= 2
        self.bdfont.config(size=self.ftsize)
        self.itfont.config(size=self.ftsize)
        self.text.config(font=("8514oem", self.ftsize, "bold"))

    def display_time(self):
        self.curtime = strftime("%H : %M : %S")
        self.timelabel.config(text=self.curtime)
        self.master.after(1000, self.display_time)

    def insert_paren(self, e):
        self.startparams = "([{"
        self.endparams = ")]}"
        self.cursor = self.text.index(INSERT)
        self.linecur = str(self.cursor.split(".")[0])
        self.colcur = int(self.cursor.split(".")[1])
        if e.char == self.startparams[0]:
            self.text.insert(INSERT, self.endparams[0])
            self.text.mark_set(INSERT, self.linecur + "." + str(self.colcur))
        elif e.char == self.startparams[1]:
            self.text.insert(INSERT, self.endparams[1])
            self.text.mark_set(INSERT, self.linecur + "." + str(self.colcur))
        elif e.char == self.startparams[2]:
            self.text.insert(INSERT, self.endparams[2])
            self.text.mark_set(INSERT, self.linecur + "." + str(self.colcur))
        else:
            pass

    def copy_cur_line(self, e):
        self.linetext = self.text.get("insert linestart", "insert lineend")
        self.newidx = float(self.text.index(INSERT)) + 1.1
        self.text.insert(INSERT, "\n")
        self.text.insert(self.newidx, self.linetext + "\n")
        self.text.mark_set("insert", self.newidx)

        return 'break'
コード例 #5
0
class Main(object):
    def __init__(self, root_):
        self.root = root_
        self.file_path = None
        self.root.title("Proyecto final Inteligencia Artifical II")

        # Images and title
        self.title_label = Label(
            root, text="UNIVERSIDAD DE LAS FUERZAS ARMADAS ESPE")
        self.title_label.grid(row=0, column=0, columnspan=2)
        img = Image.open("logo.png")
        img = img.resize((250, 70), Image.ANTIALIAS)
        self.image = ImageTk.PhotoImage(img)
        self.image_label = Label(root, image=self.image)
        self.image_label.grid(row=1, column=0, columnspan=2)

        self.rule_editor_label = Label(root, text="Hechos: ", padx=10, pady=1)
        self.rule_editor_label.grid(sticky="W",
                                    row=2,
                                    column=0,
                                    columnspan=2,
                                    pady=3)

        # Create rule editor where we can edit the rules we want to enter:

        self.rule_editor = ScrolledText(root,
                                        width=100,
                                        height=30,
                                        padx=10,
                                        pady=10)

        self.rule_editor.grid(sticky=W + E,
                              row=3,
                              column=0,
                              columnspan=2,
                              padx=10)

        self.rule_editor.config(wrap="word", undo=True)

        self.rule_editor.focus()

        # Create a query label:

        self.query_label = Label(root, text="Prolog Query:", padx=10, pady=1)

        self.query_label.grid(sticky=W, row=4, column=0, columnspan=2, pady=3)

        # Create the Prolog query editor we'll use to query our rules:

        self.query_editor = Text(root, width=77, height=2, padx=10, pady=10)

        self.query_editor.grid(sticky=W, row=5, column=0, pady=3, padx=10)

        self.query_editor.config(wrap="word", undo=True)

        # Create a run button which runs the query against our rules and outputs the
        # results in our solutions text box / editor.

        self.run_button = Button(
            root,
            text="Find Query Solutions",
            height=2,
            width=20,
            command=self.run_query,
        )

        self.run_button.grid(sticky=E, row=5, column=1, pady=3, padx=10)

        # Create a solutions label

        self.solutions_label = Label(root,
                                     text="Query Solutions:",
                                     padx=10,
                                     pady=1)

        self.solutions_label.grid(sticky="W",
                                  row=6,
                                  column=0,
                                  columnspan=2,
                                  padx=10,
                                  pady=3)

        # Create a text box which we'll use to display our Prolog query solutions:

        self.solutions_display = ScrolledText(root,
                                              width=100,
                                              height=5,
                                              padx=10,
                                              pady=10)

        self.solutions_display.grid(row=7,
                                    column=0,
                                    columnspan=2,
                                    padx=10,
                                    pady=7)

        # Finally, let's create the file menu
        self.menu_bar = self.create_file_menu()

    def add_new_fact(self):
        pass

    def load_exercise_two(self):
        pass

    def load_exercise_five(self):
        pass

    def create_file_menu(self):
        """Create a menu which will allow us to open / save our Prolog rules, run our
		query, and exit our editor interface """

        menu_bar = Menu(root)

        file_menu = Menu(menu_bar, tearoff=0)

        file_menu.add_command(label="Abrir",
                              underline=1,
                              command=self.open_file)
        file_menu.add_separator()
        file_menu.add_command(label="Save",
                              underline=1,
                              command=self.save_file)
        file_menu.add_command(label="Save As...",
                              underline=5,
                              command=self.save_file_as)
        file_menu.add_separator()
        file_menu.add_command(label="Run", underline=1, command=self.run_query)
        file_menu.add_separator()
        file_menu.add_command(label="Exit",
                              underline=2,
                              command=self.root.destroy)

        menu_bar.add_cascade(label="File", underline=0, menu=file_menu)

        self.root.config(menu=menu_bar)
        return menu_bar

    def run_query(self):
        """Interpret the entered rules and query and display the results in the
		solutions text box """
        # Delete all of the text in our solutions display text box
        self.solutions_display.delete("1.0", END)
        self.set_busy()

        # Fetch the raw rule / query text entered by the user
        rules_text = self.rule_editor.get(1.0, "end-1c")
        query_text = self.query_editor.get(1.0, "end-1c")

        # Create a new solver so we can try to query for solutions.
        try:
            solver = Solver(rules_text)
        except Exception as e:
            self.handle_exception("Error processing prolog rules.", str(e))
            return

        # Attempt to find the solutions and handle any exceptions gracefully
        try:
            solutions = solver.find_solutions(query_text)
        except Exception as e:
            self.handle_exception("Error processing prolog query.", str(e))
            return

        # If our query returns a boolean, we simply display a 'Yes' or a 'No'
        # depending on its value
        if isinstance(solutions, bool):
            self.solutions_display.insert(END, "Yes." if solutions else "No.")

        # Our solver returned a map, so we display the variable name to value mappings
        elif isinstance(solutions, dict):
            self.solutions_display.insert(
             END,
             "\n".join(
              "{} = {}"
               # If our solution is a list contining one item, we show that
               # item, otherwise we display the entire list
               .format(variable, value[0] if len(value) == 1 else value)
              for variable, value in solutions.items()
             ),
            )
        else:

            # We know we have no matching solutions in this instance so we provide
            # relevant feedback
            self.solutions_display.insert(END, "No solutions found.")

        self.set_not_busy()

    def handle_exception(self, error_message, exception=""):
        """Handle the exception by printing an error message as well as exception in
		our solution text editor / display """
        self.solutions_display.insert(END, error_message + "\n")
        self.solutions_display.insert(END, str(exception) + "\n")
        self.set_not_busy()

    def set_rule_editor_text(self, text):
        self.rule_editor.delete(1.0, "end")
        self.rule_editor.insert(1.0, text)
        self.rule_editor.edit_modified(False)

    def set_busy(self):
        # Show a busy cursor and update the UI
        self.root.config(cursor="watch")
        self.root.update()

    def set_not_busy(self):
        # Show a regular cursor
        self.root.config(cursor="")

    def open_file(self, file_path=None):
        # Open a a new file dialog which allows the user to select a file to open
        if file_path is None:
            file_path = filedialog.askopenfilename()

        if is_file_path_selected(file_path):
            file_contents = get_file_contents(file_path)

            # Set the rule editor text to contain the selected file contents
            self.set_rule_editor_text(file_contents)
            self.file_path = file_path

    def save_file(self):
        """If we have specified a file path, save the file - otherwise, prompt the
		user to specify the file location prior to saving the file """
        if self.file_path is None:
            result = self.save_file_as()
        else:
            result = self.save_file_as(file_path=self.file_path)

        return result

    def write_editor_text_to_file(self, file):
        editor_text = self.rule_editor.get(1.0, "end-1c")
        file.write(bytes(editor_text, "UTF-8"))
        self.rule_editor.edit_modified(False)

    def save_file_as(self, file_path=None):
        # If there is no file path specified, prompt the user with a dialog which
        # allows him/her to select where they want to save the file
        if file_path is None:
            file_path = filedialog.asksaveasfilename(filetypes=(
                ("Text files", "*.txt"),
                ("Prolog files", "*.pl *.pro"),
                ("All files", "*.*"),
            ))

        try:

            # Write the Prolog rule editor contents to the file location
            with open(file_path, "wb") as file:
                self.write_editor_text_to_file(file)
                self.file_path = file_path
                return "saved"

        except FileNotFoundError:
            return "cancelled"

    def undo(self):
        self.rule_editor.edit_undo()

    def redo(self):
        self.rule_editor.edit_redo()
コード例 #6
0
class EditorTab(tk.Frame):
    def __init__(self, master, filepath: str, new_file=False):
        tk.Frame.__init__(self, master)
        self.new_file = new_file
        self.filepath = filepath
        self.filename = get_filename(filepath) if not new_file else filepath
        self.master = master
        self.modified = False
        self.text_editor = ScrolledText(self,
                                        font=("", 15),
                                        undo=True,
                                        maxundo=-1,
                                        wrap="none")
        self.text_editor.config(highlightthickness=0, bd=0)
        self.text_editor.grid(row=0, column=1, sticky=tk.NSEW)
        self.scrollbar_x = tk.Scrollbar(self,
                                        orient=tk.HORIZONTAL,
                                        command=self.text_editor.xview)
        self.scrollbar_x.grid(row=1, column=0, columnspan=2, stick=tk.EW)
        self.text_editor.configure(xscrollcommand=self.scrollbar_x.set)
        self.line_nb_canvas = tk.Canvas(self,
                                        bg=self.text_editor.cget("bg"),
                                        bd=0,
                                        highlightthickness=0)
        self.line_nb_canvas.grid_propagate(False)
        self.line_nb_canvas.grid(row=0, column=0, sticky=tk.NS)
        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(1, weight=1)
        self.default_file_content = str()

    @property
    def id(self) -> str:
        return str(self)

    def get(self) -> str:
        return self.text_editor.get("1.0", "end-1c")

    @property
    def lines(self):
        return self.get().splitlines()

    def update_lines(self):
        self.line_nb_canvas.delete("all")
        font = self.text_editor.cget("font")
        i = 1
        y = 0
        while self.text_editor.compare(f"{i}.0", "<", tk.END):
            dline = self.text_editor.dlineinfo(f"{i}.0")
            if dline:
                y = dline[1]
            else:
                y = -20
            self.line_nb_canvas.create_text(1,
                                            y,
                                            anchor="ne",
                                            text=str(i),
                                            font=font,
                                            fill=Color(175, 175, 175).hex)
            i += 1
        all_boxes = [
            self.line_nb_canvas.bbox(item)
            for item in self.line_nb_canvas.find_all()
        ]
        max_width = (min(box[2] - box[0] for box in all_boxes)) * 4
        self.line_nb_canvas.configure(width=max_width + 20)
        for item in self.line_nb_canvas.find_all():
            self.line_nb_canvas.move(item, max_width, 0)

    def get_filename_from_champion_name(self) -> (str, None):
        content = self.lines
        for line in content:
            if line.startswith(".name"):
                first_quote = line.find('"')
                if first_quote == -1:
                    break
                second_quote = line.find('"', first_quote + 1)
                if second_quote == -1:
                    break
                name = line[first_quote + 1:second_quote]
                if len(name) == 0:
                    break
                return name.replace(" ", "_").lower() + ".s"
        return None

    def open(self) -> bool:
        if not os.path.isfile(self.filepath):
            showwarning("An error occurs...", f"Can't open '{self.filepath}'")
            return False
        with open(self.filepath, "r") as file:
            self.default_file_content = file.read()
            self.text_editor.insert("1.0", self.default_file_content)
            self.text_editor.edit_reset()
            self.text_editor.edit_modified(False)
        self.set_modified_status(False, on_opening=True)
        return True

    def save(self) -> bool:
        if self.new_file:
            return self.master.save_file_as()
        self.default_file_content = self.text_editor.get("1.0", "end-1c")
        with open(self.filepath, "w") as file:
            file.write(self.default_file_content)
        self.set_modified_status(False)
        self.text_editor.edit_modified(False)
        return True

    def save_as(self, filepath: str) -> bool:
        self.master.files_opened[filepath] = self.master.files_opened[
            self.filepath]
        self.master.files_opened.pop(self.filepath)
        self.filepath = filepath
        self.filename = get_filename(filepath)
        self.new_file = False
        return self.save()

    def close(self) -> bool:
        if self.modified:
            save_file = askyesnocancel(
                f"{self.filename} - Modifications not saved",
                "This file was modified and was not saved.\nDo you want to save this file ?"
            )
            if save_file is None:
                return False
            if save_file and not self.save():
                return False
        self.master.forget(self.id)
        self.master.files_opened.pop(self.filepath)
        return True

    def undo(self) -> None:
        try:
            self.text_editor.edit_undo()
        except tk.TclError:
            pass

    def redo(self) -> None:
        try:
            self.text_editor.edit_redo()
        except tk.TclError:
            pass

    def copy_to_clipboard(self, remove_from_editor=False) -> bool:
        try:
            txt = self.text_editor.get("sel.first", "sel.last")
            self.clipboard_clear()
            self.clipboard_append(txt)
            if remove_from_editor:
                self.text_editor.delete("sel.first", "sel.last")
        except tk.TclError:
            return False
        return True

    def paste_from_clipboard(self) -> None:
        try:
            self.text_editor.get("sel.first", "sel.last")
        except tk.TclError:
            pass
        else:
            self.text_editor.mark_set("insert", "sel.first")
            self.text_editor.delete("sel.first", "sel.last")
        self.text_editor.insert("insert", self.clipboard_get())

    def check_file_status(self) -> None:
        actual = self.text_editor.get("1.0", "end-1c")
        if self.text_editor.edit_modified():
            self.text_editor.edit_separator()
            self.text_editor.edit_modified(False)
        self.set_modified_status(actual != self.default_file_content)

    def set_modified_status(self, status: bool, on_opening=False) -> None:
        self.modified = status
        if not on_opening:
            if self.modified and not self.new_file:
                self.master.tab(self.id, text=self.filename + " - Modified")
            else:
                self.master.tab(self.id, text=self.filename)

    def add(self) -> None:
        self.master.add(self, text=self.filename)

    def select(self) -> None:
        self.master.select(self.id)
        self.text_editor.focus_set()

    def set_template(self, name: str, comment: str, author: str) -> None:
        content = [
            line for line in self.lines
            if not line.startswith(".name") and not line.startswith(".comment")
        ]
        header = [
            "#", "# {name} champion for CoreWar".format(name=name), "#",
            "# By {author}".format(author=author), "#",
            "# {date}".format(date=date.today().strftime("%c")), "#", ""
            ".name \"{name}\"".format(name=name),
            ".comment \"{comment}\"".format(comment=comment), ""
        ]
        content = header + content
        self.text_editor.delete("1.0", "end")
        self.text_editor.insert("1.0", "\n".join(content))

    def insert_command(self, cmd: str) -> None:
        insert = self.text_editor.index(tk.INSERT).split(".")
        end_of_line = insert[0] + "." + tk.END
        self.text_editor.insert(end_of_line, "\n" + cmd)
コード例 #7
0
class OptimizerMainWindow:
    """
    classdocs
    """

    # TODO: change that name
    def reactToClick(self, event):
        a = AddRestrictionDialog(self)

    def __init__(self, optimizer):

        # always have a reference to model/controller
        self.optimizer = optimizer

        # setup main GUI and make stretchable
        self.guiRoot = Tk()
        self.guiRoot.title("OPTIMIZR")
        self.guiRoot.columnconfigure(1, weight=1)
        self.guiRoot.rowconfigure(0, weight=1)

        # left (settings) and right (sequences) part
        self.frameLeft = Frame(self.guiRoot)
        self.frameLeft.grid(row=0, column=0, sticky=W + E + N + S)
        self.frameLeft.columnconfigure(0, weight=1)
        self.frameRight = Frame(self.guiRoot)
        self.frameRight.grid(row=0, column=1, sticky=W + E + N + S)
        self.frameRight.columnconfigure(0, weight=1)
        self.frameRight.rowconfigure(0, weight=1)
        self.frameRight.rowconfigure(1, weight=1)

        self.frameSpeciesControll = LabelFrame(self.frameLeft, text="Species", pady=10, padx=10)
        self.frameSpeciesControll.columnconfigure(1, weight=1)
        self.frameOptimizationControll = LabelFrame(self.frameLeft, text="Optimization", pady=10, padx=10)
        self.frameRestrictionControll = LabelFrame(self.frameLeft, text="Restriction Enzymes", pady=10, padx=10)
        self.frameSpeciesControll.grid(row=0, column=0, sticky=W + E, padx=10, pady=10)
        self.frameOptimizationControll.grid(row=1, column=0, sticky=W + E, padx=10, pady=10)
        self.frameRestrictionControll.grid(row=2, column=0, sticky=W + E, padx=10, pady=10)

        # Species Controll
        Label(self.frameSpeciesControll, text="Source:").grid(row=0, column=0)
        Label(self.frameSpeciesControll, text="Target:").grid(row=1, column=0)

        self.comboSourceSpecies = Combobox(self.frameSpeciesControll, state="readonly")
        self.comboSourceSpecies.grid(row=0, column=1, pady=5, sticky="ew")
        self.comboTargetSpecies = Combobox(self.frameSpeciesControll, state="readonly")
        self.comboTargetSpecies.grid(row=1, column=1, pady=5, sticky="we")
        self.buttonSpeciesList = Button(self.frameSpeciesControll, text="Edit Species List")
        self.buttonSpeciesList.grid(row=2, column=1, pady=5, sticky="e")

        self.comboSourceSpecies.bind("<<ComboboxSelected>>", self.actionOptimizerSettingsChanged)
        self.comboTargetSpecies.bind("<<ComboboxSelected>>", self.actionOptimizerSettingsChanged)

        # Optimization Controll
        Label(self.frameOptimizationControll, text="Optimization Strategy:").grid(row=0, column=0)
        self.comboOptimizationStrategy = Combobox(self.frameOptimizationControll, state="readonly")
        self.comboOptimizationStrategy.grid(row=0, column=1)
        self.comboOptimizationStrategy["values"] = self.optimizer.possibleOptimizationStrategies
        self.comboOptimizationStrategy.bind("<<ComboboxSelected>>", self.actionOptimizerSettingsChanged)

        # Restriction Enzymes
        self.listRestriction = Listbox(self.frameRestrictionControll)
        self.listRestriction.grid(row=0, column=0, columnspan=3, pady=5, sticky=W + E)
        self.frameRestrictionControll.columnconfigure(0, weight=1)
        self.buttonRestricionAdd = Button(self.frameRestrictionControll, text=" + ")
        self.buttonRestricionDel = Button(self.frameRestrictionControll, text=" - ")
        self.buttonRestricionAdd.grid(row=1, column=1, padx=5)
        self.buttonRestricionDel.grid(row=1, column=2, padx=5)

        # Source Sequence Frame
        self.frameSourceSequence = LabelFrame(self.frameRight, text="Source Sequence", padx=10, pady=10)
        self.frameResultSequence = LabelFrame(self.frameRight, text="Result Sequence", padx=10, pady=10)
        self.frameSourceSequence.grid(row=0, column=0, sticky="wens", padx=10, pady=10)
        self.frameResultSequence.grid(row=1, column=0, sticky="wens", padx=10, pady=10)

        self.buttonSourceLoad = Button(self.frameSourceSequence, text=" Load ")
        self.textSourceSeq = ScrolledText(self.frameSourceSequence, height=10)
        self.buttonSourceLoad.grid(row=0, column=1, sticky="e", pady=5)
        self.textSourceSeq.grid(row=1, column=0, columnspan=2, sticky="wens")
        self.frameSourceSequence.columnconfigure(0, weight=1)
        self.frameSourceSequence.rowconfigure(1, weight=1)
        self.textSourceSeq.frame.columnconfigure(1, weight=1)
        self.textSourceSeq.frame.rowconfigure(0, weight=1)

        self.buttonOptimize = Button(self.frameResultSequence, text=" OPTIMIZE! ")
        self.buttonOptimize.bind("<ButtonRelease>", self.actionOptimize)

        self.buttonRemoveRestriction = Button(self.frameResultSequence, text=" RESTRICTION-B-GONE! ")
        self.buttonRemoveRestriction.bind("<ButtonRelease>", self.actionRemoveRestricion)

        self.buttonSaveResult = Button(self.frameResultSequence, text=" Save ")
        self.textResultSequence = ScrolledText(self.frameResultSequence, height=10)
        self.buttonOptimize.grid(column=0, row=0, pady=5, sticky="w")
        self.buttonRemoveRestriction.grid(column=1, row=0, pady=5, padx=10, sticky="w")
        self.textResultSequence.grid(row=1, column=0, columnspan=4, sticky="wens")
        self.buttonSaveResult.grid(row=2, column=3, pady=5, sticky="e")
        self.frameResultSequence.columnconfigure(2, weight=1)
        self.frameResultSequence.rowconfigure(1, weight=1)
        self.textResultSequence.frame.columnconfigure(1, weight=1)
        self.textResultSequence.frame.rowconfigure(0, weight=1)

        self.textSourceSeq.bind("<<Modified>>", self.actionSequenceModified)
        self.textResultSequence.bind("<<Modified>>", self.actionSequenceModified)

        # generate color tags for textboxes
        for i in range(101):

            # green for normal codons
            (r, g, b) = colorsys.hsv_to_rgb(210 / 360, i / 100, 1.0)
            colorHex = "#%02x%02x%02x" % (int(r * 255), int(g * 255), int(b * 255))

            self.textSourceSeq.tag_config("normal" + str(i), background=colorHex)
            self.textResultSequence.tag_config("normal" + str(i), background=colorHex)

            # red for codons with restriction sites
            (r, g, b) = colorsys.hsv_to_rgb(5 / 360, i / 100, 1.0)
            colorHex = "#%02x%02x%02x" % (int(r * 255), int(g * 255), int(b * 255))

            self.textSourceSeq.tag_config("restrict" + str(i), background=colorHex)
            self.textResultSequence.tag_config("restrict" + str(i), background=colorHex)

        # Set (minimum + max) Window size
        self.guiRoot.update()
        self.guiRoot.minsize(self.guiRoot.winfo_width(), self.guiRoot.winfo_height())

        self.buttonRestricionAdd.bind("<ButtonRelease>", self.reactToClick)
        self.buttonRestricionDel.bind("<ButtonRelease>", self.actionRestrictionEnzymeDelete)
        self.buttonSpeciesList.bind("<ButtonRelease>", self.actionEditSpeciesButton)

        self.buttonSourceLoad.bind("<ButtonRelease>", self.actionLoadSequence)
        self.buttonSaveResult.bind("<ButtonRelease>", self.actionSaveSequence)

        # TEST
        #         self.listRestriction.insert("end", "EcoRI")
        #         self.listRestriction.insert("end", "BamHI")
        #

        # dummy event to manually trigger update
        self.guiRoot.bind("<<Update>>", self.actionUpdate)

        self.actionUpdate(None)

        self.guiRoot.mainloop()

    def actionRestrictionEnzymeDelete(self, event):
        try:
            selectedEnzyme = self.listRestriction.selection_get()
            self.optimizer.restrictionEnzymeList.remove(selectedEnzyme)
            self.guiRoot.event_generate("<<Update>>")
        except tkinter.TclError:
            # no selection
            pass

    def actionUpdate(self, event):
        #         print("update called")

        # clear list of restriction enzymes
        self.listRestriction.delete(0, "end")
        for r in self.optimizer.restrictionEnzymeList:
            self.listRestriction.insert("end", r)

        self.comboSourceSpecies.delete(0, "end")
        self.comboTargetSpecies.delete(0, "end")

        speciesValues = list()
        for (taxid, name) in self.optimizer.speciesList:
            speciesValues.append(taxid + ": " + name)

        self.comboSourceSpecies["values"] = speciesValues
        self.comboTargetSpecies["values"] = speciesValues

        if self.comboSourceSpecies.get() not in speciesValues:
            self.comboSourceSpecies.set("")
        if self.comboTargetSpecies.get() not in speciesValues:
            self.comboTargetSpecies.set("")

        self.textSourceSeq.edit_modified(True)
        self.textResultSequence.edit_modified(True)

        self.optimizer.saveConfig("config.ini")

    def actionEditSpeciesButton(self, event):
        speciesListDialog = SpeciesListDialog(self)

    def actionOptimizerSettingsChanged(self, event=None):
        #         print("Something happened")
        strategy = self.comboOptimizationStrategy.get()
        sourceString = self.comboSourceSpecies.get()
        targetString = self.comboTargetSpecies.get()

        if not (strategy and sourceString and targetString):
            return

        sourceTaxid = sourceString.split(":")[0]
        targetTaxid = targetString.split(":")[0]

        self.optimizer.setOptimizer(sourceTaxid, targetTaxid, strategy)

        self.textSourceSeq.edit_modified(True)
        self.textResultSequence.edit_modified(True)

    #         self.optimizer.testPrint()

    def actionOptimize(self, event=None):
        self.optimizer.runOptimization()
        self.textSourceSeq.edit_modified(True)
        self.textResultSequence.edit_modified(True)

    def actionRemoveRestricion(self, event=None):
        self.optimizer.runRestricionRemoval()
        self.textSourceSeq.edit_modified(True)
        self.textResultSequence.edit_modified(True)

    def actionSequenceModified(self, event=None):
        # necessary if, otherwise -> infinite loop
        if self.textSourceSeq.edit_modified():

            seq = self.textSourceSeq.get("1.0", "end").strip()
            seq = stripCharsNotInList(seq.upper(), ["A", "C", "G", "T"])
            self.optimizer.setSourceSeq(seq)

            oldInsert = self.textSourceSeq.index("insert")
            self.textSourceSeq.delete("1.0", "end")

            sourceCodons = self.optimizer.getCodonsForPrint(True)
            if not sourceCodons:
                self.textSourceSeq.insert("end", self.optimizer.sourceSequence)
            else:
                for (co, sc, r) in sourceCodons:
                    if sc:
                        if not r:
                            self.textSourceSeq.insert("end", co, "normal" + str(int(sc * 100)))
                            # print("normal"+str(int(sc*100)))
                        else:
                            self.textSourceSeq.insert("end", co, "restrict" + str(int(sc * 100)))
                    else:
                        # remainder without color
                        self.textSourceSeq.insert("end", co)

            self.textSourceSeq.mark_set("insert", oldInsert)

            # reset the modified status at the very end
            self.textSourceSeq.edit_modified(False)

        if self.textResultSequence.edit_modified():

            seq = self.textResultSequence.get("1.0", "end").strip()
            #             self.optimizer.setOptimizedSeq(seq)

            oldInsert = self.textResultSequence.index("insert")
            self.textResultSequence.delete("1.0", "end")

            targetCodons = self.optimizer.getCodonsForPrint(False)
            if not targetCodons:
                self.textSourceSeq.insert("end", self.optimizer.optimizedSequence)
            else:
                for (co, sc, r) in targetCodons:
                    if sc:
                        if not r:
                            self.textResultSequence.insert("end", co, "normal" + str(int(sc * 100)))
                            # print("normal"+str(int(sc*100)))
                        else:
                            self.textResultSequence.insert("end", co, "restrict" + str(int(sc * 100)))
                    else:
                        # remainder without color
                        self.textResultSequence.insert("end", co)

            self.textSourceSeq.mark_set("insert", oldInsert)

            self.textResultSequence.edit_modified(False)

    def actionLoadSequence(self, event=None):
        filename = tkinter.filedialog.askopenfilename()
        if filename:
            seq = sequenceIO.readFile(filename)
            self.textSourceSeq.delete("1.0", "end")
            self.textSourceSeq.insert("end", seq)
            self.textSourceSeq.edit_modified(True)

    def actionSaveSequence(self, event=None):
        filename = tkinter.filedialog.asksaveasfilename()
        if filename:
            #             print("file is " + filename)
            with open(filename, mode="w") as fd:
                fd.write(self.optimizer.optimizedSequence)
コード例 #8
0
class Editor():
    def __init__(self, root):

        self.root = root
        self.file_path = None
        self.root.title('Prolog Interpreter')

        # Create a rule label

        self.rule_editor_label = Label(root,
                                       text="Prolog Rules: ",
                                       padx=10,
                                       pady=1)

        self.rule_editor_label.grid(sticky="W",
                                    row=0,
                                    column=0,
                                    columnspan=2,
                                    pady=3)

        # Create rule editor where we can edit the rules we want to enter:

        self.rule_editor = ScrolledText(root,
                                        width=100,
                                        height=30,
                                        padx=10,
                                        pady=10)

        self.rule_editor.grid(sticky=W + E,
                              row=1,
                              column=0,
                              columnspan=2,
                              padx=10)

        self.rule_editor.config(wrap="word", undo=True)

        self.rule_editor.focus()

        # Create a query label:

        self.query_label = Label(root, text="Prolog Query:", padx=10, pady=1)

        self.query_label.grid(sticky=W, row=2, column=0, columnspan=2, pady=3)

        # Create the Prolog query editor we'll use to query our rules:

        self.query_editor = Text(root, width=77, height=2, padx=10, pady=10)

        self.query_editor.grid(sticky=W, row=3, column=0, pady=3, padx=10)

        self.query_editor.config(wrap="word", undo=True)

        # Create a run button which runs the query against our rules and outputs the results in our
        # solutions text box / editor.

        self.run_button = Button(root,
                                 text='Find Query Solutions',
                                 height=2,
                                 width=20,
                                 command=self.run_query)

        self.run_button.grid(sticky=E, row=3, column=1, pady=3, padx=10)

        # Create a solutions label

        self.solutions_label = Label(root,
                                     text="Query Solutions:",
                                     padx=10,
                                     pady=1)

        self.solutions_label.grid(sticky="W",
                                  row=4,
                                  column=0,
                                  columnspan=2,
                                  padx=10,
                                  pady=3)

        # Create a text box which we'll use to display our Prolog query solutions:

        self.solutions_display = ScrolledText(root,
                                              width=100,
                                              height=5,
                                              padx=10,
                                              pady=10)

        self.solutions_display.grid(row=5,
                                    column=0,
                                    columnspan=2,
                                    padx=10,
                                    pady=7)

        # Finally, let's create the file menu
        self.create_file_menu()

    # Create a menu which will allow us to open / save our Prolog rules, run our query,
    # and exit our editor interface
    def create_file_menu(self):

        self.menu_bar = Menu(root)

        file_menu = Menu(self.menu_bar, tearoff=0)

        file_menu.add_command(label="Open...",
                              underline=1,
                              command=self.open_file)
        file_menu.add_separator()
        file_menu.add_command(label="Save",
                              underline=1,
                              command=self.save_file)
        file_menu.add_command(label="Save As...",
                              underline=5,
                              command=self.save_file_as)
        file_menu.add_separator()
        file_menu.add_command(label="Run", underline=1, command=self.run_query)
        file_menu.add_separator()
        file_menu.add_command(label="Exit",
                              underline=2,
                              command=self.root.destroy)

        self.menu_bar.add_cascade(label="File", underline=0, menu=file_menu)

        self.root.config(menu=self.menu_bar)

    # Show a busy cursor and update the UI
    def set_busy(self):
        self.root.config(cursor="watch")
        self.root.update()

    # Show a regular cursor
    def set_not_busy(self):
        self.root.config(cursor="")

    # Interpret the entered rules and query and display the results in the solutions text box
    def run_query(self):

        # Delete all of the text in our solutions display text box
        self.solutions_display.delete('1.0', END)

        self.set_busy()

        # Fetch the raw rule / query text entered by the user
        rules_text = self.rule_editor.get(1.0, "end-1c")
        query_text = self.query_editor.get(1.0, "end-1c")

        # Create a new solver so we can try to query for solutions.
        try:
            solver = Solver(rules_text)
        except Exception as exception:
            self.handle_exception("Error processing prolog rules.", exception)
            return

        # Attempt to find the solutions and handle any exceptions gracefully
        try:
            solutions = solver.find_solutions(query_text)
        except Exception as exception:
            self.handle_exception("Error processing prolog query.", exception)
            return

        # If our query returns a boolean, we simply display a 'Yes' or a 'No' depending on its value
        if isinstance(solutions, bool):
            self.solutions_display.insert(END, 'Yes.' if solutions else 'No.')

        # Our solver returned a map, so we display the variable name to value mappings
        elif isinstance(solutions, dict):
            self.solutions_display.insert( END, "\n".join("{} = {}"
                                                        # If our solution is a list contining one item, we show that
                                                        # item, otherwise we display the entire list
                                                         .format(variable, value[0] if len(value) == 1 else value)
                                                         for variable, value
                                                         in solutions.items())
                                          )
        else:

            # We know we have no matching solutions in this instance so we provide relevant feedback
            self.solutions_display.insert(END, "No solutions found.")

        self.set_not_busy()

    # Handle the exception by printing an error message as well as exception in our solution text editor / display
    def handle_exception(self, error_message, exception=''):
        self.solutions_display.insert(END, error_message + "\n")
        self.solutions_display.insert(END, str(exception) + '\n')
        self.set_not_busy()

    def is_file_path_selected(self, file_path):
        return file_path != None and file_path != ''

    # Return a string containing the file contents of the file located at the specified file path
    def get_file_contents(self, file_path):
        with open(file_path, encoding="utf-8") as f:
            file_contents = f.read()

        return file_contents

    def set_rule_editor_text(self, text):
        self.rule_editor.delete(1.0, "end")
        self.rule_editor.insert(1.0, text)
        self.rule_editor.edit_modified(False)

    def open_file(self, file_path=None):

        # Open a a new file dialog which allows the user to select a file to open
        if file_path == None:
            file_path = filedialog.askopenfilename()

        if self.is_file_path_selected(file_path):
            file_contents = self.get_file_contents(file_path)

            # Set the rule editor text to contain the selected file contents
            self.set_rule_editor_text(file_contents)
            self.file_path = file_path

    # If we have specified a file path, save the file - otherwise, prompt the user to specify the file location
    # prior to saving the file
    def save_file(self):
        if self.file_path == None:
            result = self.save_file_as()
        else:
            result = self.save_file_as(file_path=self.file_path)

        return result

    def write_editor_text_to_file(self, file):
        editor_text = self.rule_editor.get(1.0, "end-1c")
        file.write(bytes(editor_text, 'UTF-8'))
        self.rule_editor.edit_modified(False)

    def save_file_as(self, file_path=None):
        # If there is no file path specified, prompt the user with a dialog which allows him/her to select
        # where they want to save the file
        if file_path == None:
            file_path = filedialog.asksaveasfilename(
                filetypes=(('Text files', '*.txt'),
                           ('Prolog files', '*.pl *.pro'), ('All files',
                                                            '*.*')))

        try:

            # Write the Prolog rule editor contents to the file location
            with open(file_path, 'wb') as file:
                self.write_editor_text_to_file(file)
                self.file_path = file_path
                return "saved"

        except FileNotFoundError:
            return "cancelled"

    def undo(self, event=None):
        self.rule_editor.edit_undo()

    def redo(self, event=None):
        self.rule_editor.edit_redo()
コード例 #9
0
class NoteEditor:
    def __init__(self):
        self.id = None
        self.page_name = None
        self.font_name = 'arial'
        self.font_size = 12
        self.font_weight = tk.NORMAL
        self.editor = None
        self.file_io = FileIO()
        self.syntax_file_io = FileIO()

    def create_editor(self, master):
        self.editor = ScrolledText(master,
                                   undo=True,
                                   autoseparators=True,
                                   maxundo=-1)

        # Styling of text area
        self.set_editor_font(None, None)

        self.editor.pack(side="left")
        self.editor.focus()
        self.editor.pack(fill="both", expand=True)

        # Configuring style tags
        self.editor.tag_config("BACKGROUND", background="yellow")
        self.editor.tag_configure("HIGHLIGHT", foreground="red")
        self.editor['wrap'] = tk.NONE

        self.editor.bind('<Button-3>', self.rClicker, add='')

    def set_editor_font(self, font_name, font_size, font_weight=None):
        if font_name is not None:
            self.font_name = font_name

        if font_size is not None and int(font_size) > 0:
            self.font_size = font_size

        if font_weight is not None:
            self.font_weight = font_weight

        self.editor['font'] = Font(family=self.font_name,
                                   size=self.font_size,
                                   weight=self.font_weight)

    def set_editor_bgcolor(self, hex_color):
        self.editor['background'] = hex_color

    def set_editor_fgcolor(self, hex_color):
        self.editor['foreground'] = hex_color

    def set_emphasis(self, on):
        if on == 1:
            bold_font = Font(family=self.font_name,
                             size=self.font_size,
                             weight="bold")
            self.editor.tag_configure("BOLDFONT", font=bold_font)
            if self.editor.tag_ranges(tk.SEL):
                self.editor.tag_add("BOLDFONT", tk.SEL_FIRST, tk.SEL_LAST)
            else:
                self.editor.tag_add("BOLDFONT", "1.0", tk.END)
        else:
            self.editor.tag_remove("BOLDFONT", "1.0", tk.END)

    def toggle_wrap(self, on):
        if on == 1:
            self.editor['wrap'] = tk.WORD
        else:
            self.editor['wrap'] = tk.NONE

    def search_forward(self, text):
        located_start = self.editor.search(text,
                                           tk.INSERT,
                                           stopindex=tk.END,
                                           forwards=True,
                                           nocase=True)
        located_end = '{}+{}c'.format(located_start, len(text))
        if located_start is '' or located_end is '':
            return False

        self.select_editor_location(located_start, located_end)

        # Start position is moved after current found location.
        self.editor.mark_set(tk.INSERT, located_end)
        return True

    def search_backward(self, text):
        located_start = self.editor.search(text,
                                           tk.INSERT,
                                           stopindex='1.0',
                                           backwards=True,
                                           nocase=True)
        located_end = '{}+{}c'.format(located_start, len(text))
        if located_start is '' or located_end is '':
            return False

        self.select_editor_location(located_start, located_end)

        # Start position is moved after current found location.
        self.editor.mark_set(tk.INSERT, located_start)
        return True

    def replace_selected_text(self, new_text):
        self.editor.delete('sel.first', 'sel.last')
        self.editor.insert('insert', new_text)

    def select_editor_location(self, selection_start, selection_end):
        print('Found location start: ', selection_start)
        print('Found location end: ', selection_end)
        selection_start_float = float(selection_start)
        self.editor.tag_remove(tk.SEL, "1.0", 'end')
        self.editor.tag_add(tk.SEL, selection_start, selection_end)
        self.editor.focus_force()
        self.editor.see(selection_start_float)

    def is_dirty(self):
        return self.editor.edit_modified()

    def rClicker(self, e):
        ''' right click context menu for all Tk Entry and Text widgets
        '''

        try:

            def rClick_Copy(e, apnd=0):
                e.widget.event_generate('<Control-c>')

            def rClick_Cut(e):
                e.widget.event_generate('<Control-x>')

            def rClick_Paste(e):
                e.widget.event_generate('<Control-v>')

            def rClick_Highlight_Keyword(e):
                self.highlight_syntax(True)

            e.widget.focus()

            nclst = [
                (' Cut', lambda e=e: rClick_Cut(e)),
                (' Copy', lambda e=e: rClick_Copy(e)),
                (' Paste', lambda e=e: rClick_Paste(e)),
                (' Highlight Keyword',
                 lambda e=e: rClick_Highlight_Keyword(e)),
            ]

            rmenu = tk.Menu(None, tearoff=0, takefocus=0)

            for (txt, cmd) in nclst:
                rmenu.add_command(label=txt, command=cmd)

            rmenu.tk_popup(e.x_root + 40, e.y_root + 10, entry="0")

        except tk.TclError:
            print
            ' - rClick menu, something wrong'
            pass

        return "break"

    def highlight_syntax(self, enable=True):
        syntax_file = Path(Path(
            self.file_io.file_name).suffix[1:]).with_suffix('.hs')
        hs_config_data = Configuration.get_hs_configuration(syntax_file)
        if hs_config_data is None:
            print('No syntax file ', syntax_file)
            return
        #print(hs_config_data)
        keywords = hs_config_data['keyword']['tags']
        keyword_fgcolor = hs_config_data['keyword']['color']
        constant_fgcolor = hs_config_data['constant']['color']

        numbers = re.findall(r'\d{1,3}', self.file_io.file_data)
        self.editor.tag_config('tg_kw', foreground=keyword_fgcolor)
        self.editor.tag_config('tg_num', foreground=constant_fgcolor)
        #keywords = ['package', 'public', 'private', 'abstract', 'internal', 'new', 'static', 'final', 'long', 'extends',
        #            'class', 'import', 'null', 'for', 'if', 'return', 'int', 'char', 'float', 'double', 'implements']
        for keyword in keywords:
            self.editor.mark_set(tk.INSERT, '1.0')
            while True:
                located_end = self.highlight_keyword(keyword + ' ', 'tg_kw')
                if located_end == 0:
                    break
                self.editor.mark_set(tk.INSERT, located_end)

        self.editor.mark_set(tk.INSERT, '1.0')
        for each_number in numbers:
            located_end = self.highlight_keyword(each_number, 'tg_num')
            if located_end != 0:
                self.editor.mark_set(tk.INSERT, located_end)

        print("Syntax highlight executed.")

    def highlight_keyword(self, text, tag):
        located_start = self.editor.search(text,
                                           tk.INSERT,
                                           stopindex=tk.END,
                                           forwards=True,
                                           nocase=False)
        located_end = '{}+{}c'.format(located_start, len(text))
        print(located_start, ',', located_end)
        print('keyword', text)
        if located_start is '' or located_end is '':
            return 0

        self.editor.tag_add(tag, located_start, located_end)
        return located_end
コード例 #10
0
class TitlerApp:
    def __init__(self, root):
        self.file = open('title.html', 'w')
        self.ready = False

        self.root = root

        frame = Frame(root)
        frame.pack(fill=BOTH, expand=True)

        notebook = Notebook(frame)
        notebook.pack(fill=BOTH, expand=True)

        textFrame = Frame()
        notebook.add(textFrame, text="Text")

        Grid.columnconfigure(textFrame, 0, weight=1)

        textTopPanel = Frame(textFrame)
        textTopPanel.grid(row=0, sticky=W)

        openBrowserButton = Button(textTopPanel,
                                   text="Open Browser",
                                   command=self._openBrowser)
        openBrowserButton.grid(row=0, column=0)

        self.previewVar = IntVar()
        previewCheckbutton = Checkbutton(textTopPanel,
                                         text="Preview",
                                         command=self.updateFile,
                                         variable=self.previewVar)
        previewCheckbutton.grid(row=0, column=1)
        self.previewVar.set(1)

        self.statusLabel = Label(textTopPanel)
        self.statusLabel.grid(row=0, column=2)

        self.textBox = ScrolledText(textFrame, width=40, height=10)
        self.textBox.grid(row=1, sticky=N + S + E + W)
        self.textBox.bind_all('<<Modified>>', self._textboxCallback)

        propertiesFrame = Frame(textFrame)
        propertiesFrame.grid(row=2, sticky=E + W)
        self._makePropertiesFrame(propertiesFrame)

        layoutFrame = Frame()
        notebook.add(layoutFrame, text="Layout")

        layoutTopPanel = Frame(layoutFrame)
        layoutTopPanel.grid(row=0, sticky=W)

        getFromClipboardButton = Button(layoutTopPanel,
                                        text="Get from clipboard",
                                        command=self._getImageFromClipboard)
        getFromClipboardButton.grid(row=0, column=0)

        saveButton = Button(layoutTopPanel,
                            text="Save Image",
                            command=self._saveImage)
        saveButton.grid(row=0, column=1)

        self.imageLabel = Label(layoutFrame)
        self.imageLabel.grid(row=1, column=0)

        self.processedImage = None
        self.imageLabelPhoto = None  # thumbnail

    def _makePropertiesFrame(self, frame):
        #Grid.columnconfigure(frame, 0, weight=1)
        Grid.columnconfigure(frame, 1, weight=1)

        row = 0

        self.textColor = "#ffffff"
        self.backgroundColor = "#000000"

        textColorLabel = Label(frame, text="Text color:")
        textColorLabel.grid(row=row, column=0, sticky=E)

        self.textColorButton = tkinter.Button(frame,
                                              width=5,
                                              command=self._pickTextColor)
        self.textColorButton.grid(row=row, column=1, sticky=W)
        row += 1

        backgroundColorLabel = Label(frame, text="Background color:")
        backgroundColorLabel.grid(row=row, column=0, sticky=E)

        self.backgroundColorButton = tkinter.Button(
            frame, width=5, command=self._pickBackgroundColor)
        self.backgroundColorButton.grid(row=row, column=1, sticky=W)
        row += 1

        fontLabel = Label(frame, text="Font:")
        fontLabel.grid(row=row, column=0, sticky=E)

        self.fontModeVar = StringVar()

        websafeFontFrame = Frame(frame)
        websafeFontFrame.grid(row=row, column=1, sticky=W)
        row += 1

        Radiobutton(websafeFontFrame, text="Web Safe:",
                    variable=self.fontModeVar, value="websafe",
                    command=self.updateFile) \
            .grid(row=0, column=0)

        self.websafeFontVar = StringVar()
        self.websafeFontVar.set(fonts[0])
        fontOptionMenu = \
            OptionMenu(*([websafeFontFrame, self.websafeFontVar]
                         + fonts))
        fontOptionMenu.grid(row=0, column=1)
        self.websafeFontVar.trace(mode="w", callback=self.updateFile)

        googleFontFrame = Frame(frame)
        googleFontFrame.grid(row=row, column=1, sticky=W)
        row += 1

        Radiobutton(googleFontFrame, text="Google:",
                    variable=self.fontModeVar, value="google",
                    command=self.updateFile) \
            .grid(row=0, column=0)

        self.googleFontVar = StringVar()
        googleFontEntry = Entry(googleFontFrame,
                                width=22,
                                textvariable=self.googleFontVar)
        googleFontEntry.grid(row=0, column=1)
        self.googleFontVar.set("")
        self.googleFontVar.trace(mode="w", callback=self.updateFile)

        self.fontModeVar.set("websafe")

        fontSizeLabel = Label(frame, text="Font size:")
        fontSizeLabel.grid(row=row, column=0, sticky=E)

        # has to be self. , otherwise it will be garbage collected
        self.fontSizeVar = StringVar()
        fontSizeBox = Spinbox(frame,
                              from_=0,
                              to=65536,
                              width=5,
                              textvariable=self.fontSizeVar)
        fontSizeBox.grid(row=row, column=1, sticky=W)
        self.fontSizeVar.set('12')
        self.fontSizeVar.trace(mode="w", callback=self.updateFile)
        row += 1

        letterSpacingLabel = Label(frame, text="Letter spacing:")
        letterSpacingLabel.grid(row=row, column=0, sticky=E)

        self.letterSpacingVar = StringVar()
        letterSpacingBox = Spinbox(frame,
                                   from_=-999,
                                   to=999,
                                   width=5,
                                   textvariable=self.letterSpacingVar)
        letterSpacingBox.grid(row=row, column=1, sticky=W)
        self.letterSpacingVar.set('0')
        self.letterSpacingVar.trace(mode="w", callback=self.updateFile)
        row += 1

        wordSpacingLabel = Label(frame, text="Word spacing:")
        wordSpacingLabel.grid(row=row, column=0, sticky=E)

        self.wordSpacingVar = StringVar()
        wordSpacingBox = Spinbox(frame,
                                 from_=-999,
                                 to=999,
                                 width=5,
                                 textvariable=self.wordSpacingVar)
        wordSpacingBox.grid(row=row, column=1, sticky=W)
        self.wordSpacingVar.set('0')
        self.wordSpacingVar.trace(mode="w", callback=self.updateFile)
        row += 1

        lineHeightLabel = Label(frame, text="Line height:")
        lineHeightLabel.grid(row=row, column=0, sticky=E)

        self.lineHeightVar = StringVar()
        lineHeightBox = Spinbox(frame,
                                from_=0,
                                to=9999,
                                width=5,
                                textvariable=self.lineHeightVar)
        lineHeightBox.grid(row=row, column=1, sticky=W)
        self.lineHeightVar.set('100')
        self.lineHeightVar.trace(mode="w", callback=self.updateFile)
        row += 1

        paragraphMarginLabel = Label(frame, text="Paragraph break height:")
        paragraphMarginLabel.grid(row=row, column=0, sticky=E)

        self.paragraphMarginVar = StringVar()
        paragraphMarginBox = Spinbox(frame,
                                     from_=0,
                                     to=9999,
                                     width=5,
                                     textvariable=self.paragraphMarginVar)
        paragraphMarginBox.grid(row=row, column=1, sticky=W)
        self.paragraphMarginVar.set('0')
        self.paragraphMarginVar.trace(mode="w", callback=self.updateFile)
        row += 1

        wrapWidthLabel = Label(frame, text="Wrap width:")
        wrapWidthLabel.grid(row=row, column=0, sticky=E)

        self.wrapWidthVar = StringVar()
        wrapWidthBox = Spinbox(frame,
                               from_=0,
                               to=9999,
                               width=5,
                               textvariable=self.wrapWidthVar)
        wrapWidthBox.grid(row=row, column=1, sticky=W)
        self.wrapWidthVar.set('0')
        self.wrapWidthVar.trace(mode="w", callback=self.updateFile)
        row += 1

        textAlignLabel = Label(frame, text="Text align:")
        textAlignLabel.grid(row=row, column=0, sticky=E)

        self.textAlignVar = StringVar()
        Radiobutton(frame, text="Left", variable=self.textAlignVar,
                    value="left", command=self.updateFile)\
            .grid(row=row, column=1, sticky=W)
        row += 1
        Radiobutton(frame, text="Center", variable=self.textAlignVar,
                    value="center", command=self.updateFile)\
            .grid(row=row, column=1, sticky=W)
        row += 1
        Radiobutton(frame, text="Right", variable=self.textAlignVar,
                    value="right", command=self.updateFile)\
            .grid(row=row, column=1, sticky=W)
        row += 1
        Radiobutton(frame, text="Justify", variable=self.textAlignVar,
                    value="justify", command=self.updateFile)\
            .grid(row=row, column=1, sticky=W)
        row += 1
        self.textAlignVar.set('left')

        fontWeightLabel = Label(frame, text="Font weight:")
        fontWeightLabel.grid(row=row, column=0, sticky=E)

        fontWeightFrame = Frame(frame)
        fontWeightFrame.grid(row=row, column=1, sticky=W)

        self.fontWeightVar = StringVar()
        self.fontWeightBox = Spinbox(fontWeightFrame,
                                     from_=1,
                                     to=9,
                                     width=5,
                                     textvariable=self.fontWeightVar)
        self.fontWeightBox.pack(side=LEFT)
        self.fontWeightVar.set('4')
        self.fontWeightVar.trace(mode="w", callback=self.updateFile)

        fontWeightValuesLabel = Label(fontWeightFrame,
                                      text="1 - 9; 4: Normal, 7: Bold")
        fontWeightValuesLabel.pack(side=LEFT)
        row += 1

        self.italicsVar = IntVar()
        italicsLabel = Label(frame, text="Italics:")
        italicsLabel.grid(row=row, column=0, sticky=E)
        italicsCheckbutton = Checkbutton(frame,
                                         command=self.updateFile,
                                         variable=self.italicsVar)
        italicsCheckbutton.grid(row=row, column=1, sticky=W)
        row += 1

        self.underlineVar = IntVar()
        underlineLabel = Label(frame, text="Underline:")
        underlineLabel.grid(row=row, column=0, sticky=E)
        underlineCheckbutton = Checkbutton(frame,
                                           command=self.updateFile,
                                           variable=self.underlineVar)
        underlineCheckbutton.grid(row=row, column=1, sticky=W)
        row += 1

        self.strikethroughVar = IntVar()
        strikethroughLabel = Label(frame, text="Strikethrough:")
        strikethroughLabel.grid(row=row, column=0, sticky=E)
        strikethroughCheckbutton = Checkbutton(frame,
                                               command=self.updateFile,
                                               variable=self.strikethroughVar)
        strikethroughCheckbutton.grid(row=row, column=1, sticky=W)
        row += 1

        capsModeLabel = Label(frame, text="Caps:")
        capsModeLabel.grid(row=row, column=0, sticky=E)

        self.capsModeVar = StringVar()
        Radiobutton(frame, text="Normal", variable=self.capsModeVar,
                    value="normal", command=self.updateFile) \
            .grid(row=row, column=1, sticky=W)
        row += 1
        Radiobutton(frame, text="ALL CAPS", variable=self.capsModeVar,
                    value="upper", command=self.updateFile) \
            .grid(row=row, column=1, sticky=W)
        row += 1
        Radiobutton(frame, text="all lowercase", variable=self.capsModeVar,
                    value="lower", command=self.updateFile) \
            .grid(row=row, column=1, sticky=W)
        row += 1
        Radiobutton(frame, text="Small Caps", variable=self.capsModeVar,
                    value="small", command=self.updateFile) \
            .grid(row=row, column=1, sticky=W)
        row += 1
        self.capsModeVar.set("normal")

        self.ready = True
        self.updateFile()

    def _pickTextColor(self):
        color = colorchooser.askcolor()[1]
        if color is not None:
            self.textColor = color
            self.updateFile()

    def _pickBackgroundColor(self):
        color = colorchooser.askcolor()[1]
        if color is not None:
            self.backgroundColor = color
            self.updateFile()

    def _openBrowser(self):
        webbrowser.open(self.file.name)

    def _textboxCallback(self, *args, **kwargs):
        self.textBox.edit_modified(0)  # allow <<Modified>> event to run again
        self.updateFile()

    def updateFile(self, *args, **kwargs):
        if not self.ready:
            return

        # update gui
        self.textColorButton.configure(background=self.textColor)
        self.backgroundColorButton.configure(background=self.backgroundColor)

        try:
            text = self._generateHTML()
        except BaseException:
            self.statusLabel.config(text="ERROR", foreground="#FF0000")
            return

        self._writeFile(text)
        self.statusLabel.config(text="Updated", foreground="#000000")

    def _generateHTML(self):
        preview = self.previewVar.get() == 1

        fontName = ""
        fontLink = ""
        fontMode = self.fontModeVar.get()
        if fontMode == 'websafe':
            fontName = self.websafeFontVar.get()
        elif fontMode == 'google':
            fontName = self.googleFontVar.get()
            fontLink = '<link rel="stylesheet" type="text/css" ' \
                'href="https://fonts.googleapis.com/css?family=' \
                + (fontName.replace(' ', '+')) + ':' \
                + self.fontWeightVar.get() + '00' \
                + ('i' if self.italicsVar.get()==1 else '') \
                + '">'
            fontName = "'" + fontName + "'"

        rules = [
            ('*', {
                'margin': '0pt',
                'padding': '0pt'
            }),
            ('body', {
                'background-color': self.backgroundColor if preview \
                    else "#000000"
            }),
            ('pre', {
                'display': 'table',
                'border-style': 'none' if preview else 'solid',
                'border-color': "#FF0000",
                'border-width': '1px',
                'color': self.textColor if preview else "#FFFFFF",
                'font-family': fontName,
                'font-size': self.fontSizeVar.get() + 'pt',
                'letter-spacing': self.letterSpacingVar.get() + 'pt',
                'word-spacing': self.wordSpacingVar.get() + 'pt',
                'line-height': self.lineHeightVar.get() + '%',
                'margin-bottom': self.paragraphMarginVar.get() + 'pt',
                'width': 'auto' if float(self.wrapWidthVar.get()) == 0 \
                    else (self.wrapWidthVar.get() + 'pt'),
                'white-space': 'normal' if self.textAlignVar.get() == 'justify'\
                    else ('pre' if float(self.wrapWidthVar.get()) == 0
                    else 'pre-wrap'),
                'text-align': self.textAlignVar.get(),
                'font-weight': int(self.fontWeightVar.get()) * 100,
                'font-style': "italic" if self.italicsVar.get()==1 \
                    else "normal",
                'text-decoration':
                    ("underline " if self.underlineVar.get()==1 else "") \
                  + ("line-through " if self.strikethroughVar.get()==1 else ""),
                'font-variant': \
                    "small-caps" if self.capsModeVar.get() == "small" \
                    else "normal"
            })
        ]

        styleStr = generateCSS(rules)

        htmlStr = \
"""<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
{link}
<style>
{style}
</style>
</head>
<body>
<pre>
{text}
</pre>
</body>
</html>
"""

        text = self.textBox.get("1.0", END)
        text = text.rstrip()
        if self.capsModeVar.get() == "upper":
            text = text.upper()
        elif self.capsModeVar.get() == "lower":
            text = text.lower()
        text = html.escape(text)
        text = text.replace('\n\n', '</pre><pre>')
        text = text.replace('\n', '<br>')
        htmlStr = htmlStr.format(link=fontLink, style=styleStr, text=text)
        return htmlStr

    def _writeFile(self, text):
        self.file.seek(0)
        self.file.truncate(0)
        self.file.write(text)
        self.file.flush()

    def _getImageFromClipboard(self):
        clipboardImage = ImageGrab.grabclipboard()
        if clipboardImage == None:
            return
        self.processedImage = clipboardImage.convert("RGB")

        bbox = self.processedImage.getbbox()
        self.processedImage = self.processedImage.crop(bbox)

        data = self.processedImage.getdata()

        textColor = struct.unpack('BBB', bytes.fromhex(self.textColor[1:]))

        newData = bytes()
        for pixel in data:
            if pixel == (255, 0, 0):
                newData += bytes([0, 0, 0, 0])
            else:
                alpha = pixel[0]
                newData += bytes(textColor + (alpha, ))

        self.processedImage = \
            Image.frombytes("RGBA", (self.processedImage.size), newData)

        thumbnail = self.processedImage.resize(
            (384,
             int(self.processedImage.height / self.processedImage.width *
                 384.0)), Image.BICUBIC)
        self.imageLabelPhoto = ImageTk.PhotoImage(thumbnail)
        self.imageLabel.config(image=self.imageLabelPhoto)

    def _saveImage(self):
        if self.processedImage == None:
            return
        file = filedialog.asksaveasfile()
        if file == None:
            return
        try:
            try:
                self.processedImage.save(file.name)
            except KeyError as e:
                self.processedImage.save(file.name + ".png")
        except BaseException as e:
            messagebox.showerror("Error saving image!", str(e))