예제 #1
0
class GraphicalApp(tk.Frame):
    """Interface graphique du jeu."""
    def __init__(self, dispatcher):
        self.dispatcher = dispatcher
        self.master = None
        self.treeview = None
        self.chats = {
        }  # contient des listes [id, treeview, entry, bouton, messageCpt]
        self.progress = None
        self.previousAngles = {}
        self.initializeGraphicalApp()

        self.dispatcher.setGraphicalApp(self)
        self.mainloop()

    def initializeGraphicalApp(self):
        """Initialise l'interface graphique."""
        self.master = tk.Tk()
        self.master.title("To the conquest of the dragon balls !")
        super().__init__(self.master)
        self.master.resizable(False, False)

        self.createWidgets()
        self.setUpBindingEvent()
        self.master.protocol("WM_DELETE_WINDOW", self.closeWindow)
        msg = "Welcome space travelers !\n\n"
        msg += "A brand new race has been created. "
        msg += "You may ask yourself : \"Why should i participate ?\" "
        msg += "Well because the reward is worth it, it's nothing more than the seven dragon balls !\n"
        msg += "Suddenly fell more excited right ?!\n"
        msg += "But watch out, you are not the only one interested...\n\n"
        msg += "In order to move your vehicle, use your keyboard's directional arrows.\n"
        msg += "You can also drop a bomb with the \"B\" button.\n\n"
        msg += "Good luck !"
        messagebox.showinfo(title="Welcome !", message=msg)

    def createWidgets(self):
        """Crée tous les widgets de l'interface."""
        tk.Label(self.master, text="Your pseudo",
                 font="-weight bold").grid(row=0, column=0, sticky=tk.W)
        self.pseudoEntry = tk.Entry(self.master)
        self.pseudoEntry.grid(row=0, column=1, sticky=tk.EW)

        self.pseudoEntry.focus_set()

        tk.Label(self.master, text="Status : ",
                 font="-weight bold").grid(row=1, column=0, sticky=tk.W)
        self.statusLabel = tk.Label(self.master, text="Not yet connected...")
        self.statusLabel.grid(row=1, column=1, sticky=tk.W)
        self.progress = Progressbar(self.master,
                                    orient=tk.HORIZONTAL,
                                    mode='indeterminate')
        self.progress.grid(row=1, column=2)

        self.exitButton = tk.Button(self.master)
        self.exitButton["text"] = "Exit"
        self.exitButton["state"] = tk.DISABLED
        self.exitButton["bg"] = "#FF0A2D"
        self.exitButton["activebackground"] = "#FF415C"
        self.exitButton["fg"] = "#FFFFFF"
        self.exitButton["activeforeground"] = "#FFFFFF"
        self.exitButton["relief"] = tk.FLAT
        self.exitButton["bd"] = 0
        self.exitButton["command"] = lambda: self.dispatcher.onExitClicked()
        self.exitButton.grid(row=2, column=1, sticky=tk.EW)

        self.connectionButton = tk.Button(self.master)
        self.connectionButton["text"] = "Connect to the server"
        self.connectionButton["bg"] = "#1296EC"
        self.connectionButton["activebackground"] = "#33A5EF"
        self.connectionButton["fg"] = "#FFFFFF"
        self.connectionButton["activeforeground"] = "#FFFFFF"
        self.connectionButton["relief"] = tk.FLAT
        self.connectionButton["bd"] = 0
        self.connectionButton["command"] = lambda: self.onConnectionClicked(
            self.connectionButton)
        self.connectionButton.grid(row=2, column=0, sticky=tk.EW)

        self.createScoreTable()
        self.createSpaceEnvironment()

        self.notebook = Notebook(self.master)
        self.notebook.grid(row=5,
                           column=3,
                           columnspan=2,
                           rowspan=3,
                           sticky=tk.NSEW)
        self.createChat("Public", enable=False)

    def setUpBindingEvent(self):
        """Met en place tous les événement permettant eu joueur de contrôler son pod."""
        # Les code de mise à jour du joueur doivent être exécutés dans un autre thread.
        # Dans le cas contraire, il y a un interblocage entre le thread de
        # l'interface graphique (celui-ci), et celui qui met à jour périodiquement les position des joueurs.
        self.master.bind('<Left>', self.dispatcher.antiClockEvent)
        self.master.bind('<Right>', self.dispatcher.clockEvent)
        self.master.bind('<Up>', self.dispatcher.thrustEvent)
        self.master.bind('b', self.dispatcher.putBomb)

    def createSpaceEnvironment(self):
        """Crée un décor spatial."""
        self.canvasLock = Lock()
        self.canvas = tk.Canvas(self.master,
                                width=dat.ARENA_L * 2,
                                height=dat.ARENA_H * 2,
                                bg="black")
        self.canvas.grid(row=5,
                         column=0,
                         columnspan=3,
                         rowspan=5,
                         pady=(10, 0))

        # Ajoute 200 étoiles
        for __ in range(0, 200):
            self.drawRandomStar()

    def drawRandomStar(self):
        """Dessine une étoile à une position aléatoire."""
        maxX = int(self.canvas["width"])
        maxY = int(self.canvas["height"])

        x = random.randint(0, maxX)
        y = random.randint(0, maxY)
        self.canvas.create_oval(x, y, x + 5, y + 5, fill="white")

    def createScoreTable(self):
        """Crée le tableau des scores."""
        tk.Label(self.master, text="Scores",
                 font="-weight bold").grid(row=3, column=0, columnspan=2)
        tv = Treeview(self.master, height=3)
        tv['columns'] = ('Score', "Bomb")
        tv.heading("#0", text='User', anchor=tk.W)
        tv.heading('Bomb', text='Bombs available', anchor=tk.W)
        tv.column('Bomb', anchor=tk.W, width=100)
        tv.heading('Score', text='Score', anchor=tk.W)
        tv.column('Score', anchor=tk.W, width=100)
        tv.grid(row=4, column=0, columnspan=3, sticky=tk.EW)
        self.treeview = tv

    def increaseBombOf(self, player):
        """Incrémente le nombre de bombe que possède un joueur dans le tableau d'affichage.
        
        Arguments:
            player - Le pseudo du joueur pour lequel on doit incrémenter son nombre de bombe.
        """
        for i in self.treeview.get_children():
            item = self.treeview.item(i)
            # Nous sommes bien sur l'item du joueur qui nous interesse
            if item["text"] == player:
                oldValue = item['values']
                oldValue[1] += 1
                self.treeview.item(i, values=oldValue)
                break

    def decreaseBombOf(self, player):
        """Décrémente le nombre de bombe que possède un joueur dans le tableau d'affichage.
        
        Arguments:
            player - Le pseudo du joueur pour lequel on doit décrémenter son nombre de bombe.
        """
        for i in self.treeview.get_children():
            item = self.treeview.item(i)
            # Nous sommes bien sur l'item du joueur qui nous interesse
            if item["text"] == player:
                oldValue = item['values']
                oldValue[1] -= 1
                self.treeview.item(i, values=oldValue)
                break

    def setBombOf(self, player, nbBomb):
        """Met à jour le nombre de bombe que possède un joueur dans le tableau d'affichage.
        
        Arguments:
            player - Le pseudo du joueur pour lequel on doit mettre à jour son nombre de bombe.
            nbBomb - Le nouveau nombre de bombe du joueur.
        """
        for i in self.treeview.get_children():
            item = self.treeview.item(i)
            # Nous sommes bien sur l'item du joueur qui nous interesse
            if item["text"] == player:
                oldValue = item['values']
                oldValue[1] = nbBomb
                self.treeview.item(i, values=oldValue)
                break

    def createChat(self, nom, enable=True):
        """Créer un nouveau chat pour un joueur donné.
        
        Arguments:
            nom - Le nom du joueur avec lequel l'utilisateur pourra parler avec ce chat
        
        Keyword Arguments:
            enable -- Est-ce que le chat doit être activer par défaut. (default: {True})
        """
        frame = tk.Frame(self.notebook)
        self.notebook.add(frame, text=nom)
        chat = Treeview(frame, height=15)
        chat['columns'] = ('Date')
        chat.heading("#0", text='Messages', anchor=tk.W)
        chat.heading('Date', text='Date', anchor=tk.W)
        chat.column('Date', anchor=tk.W, width=150)
        chat.grid(row=0, column=0, columnspan=2, rowspan=3, sticky=tk.NSEW)
        chat.tag_configure('even', background='#DAE5F4')
        chat.tag_configure('odd', background='#B8D1F3')
        chat.tag_configure('from_me', font=("Helvetica", 10, "bold"))
        chat.tag_configure('not_from_me', font=("Helvetica", 10))
        messageEntry = tk.Entry(frame)
        messageEntry.grid(row=4, column=0, sticky=tk.S)

        messageButton = tk.Button(frame)
        messageButton["text"] = "Envoyer"
        if not enable:
            messageButton["state"] = tk.DISABLED
        messageButton["bg"] = "#1296EC"
        messageButton["activebackground"] = "#33A5EF"
        messageButton["fg"] = "#FFFFFF"
        messageButton["activeforeground"] = "#FFFFFF"
        messageButton["relief"] = tk.FLAT
        messageButton["bd"] = 0
        messageButton["command"] = lambda: self.sendMessage(nom, messageEntry)
        messageButton.grid(row=4, column=1, sticky=tk.S)

        self.chats[nom] = [frame, chat, messageEntry, messageButton, 0]

    def deleteChat(self, name):
        """Supprime un chat permmetant de communiquer avec un joueur donnée.
        
        Arguments:
            name -- Le nom du joueur pour lequel on doit supprimer le chat.
        """
        self.notebook.forget(self.chats[name][0])

    def sendMessage(self, target, entry):
        """Signale au dispatcher la volonté de l'utilisateur d'envoyer un message.
        
        Arguments:
            target -- La cible à laquelle le joueur souhaite envoyer le message.
            entry -- L'entry source sur laquelle l'utilisateur a saisi son message.
        """
        message = entry.get()
        if message == "":
            messagebox.showerror(title="Empty message",
                                 message="You cannot send an empty message")
        else:
            self.dispatcher.sendMessage(target, message)
            entry.delete(0, tk.END)

    def addMessage(self, chatName, message, fromMe=False):
        """Ajout un message à un chat.
        
        Arguments:
            chatName -- Le nom du chat.
            message -- Le message.
        
        Keyword Arguments:
            fromMe -- Indique si le message vient de l'utilisateur de l'application cliente. (default: {False})
        """
        currentDate = strftime("%d/%m/%Y-%H:%M:%S", gmtime())
        fromMeTag = 'from_me' if fromMe else 'not_from_me'
        odd_even_tag = 'even' if (self.chats[chatName][4] % 2) == 0 else 'odd'

        self.chats[chatName][1].insert('',
                                       'end',
                                       text=message,
                                       values=currentDate,
                                       tags=(odd_even_tag, fromMeTag))
        self.chats[chatName][4] += 1

    def addScoreToTable(self, user, score):
        """ Ajoute un nouveau score au tableau des scores.
            Si le joueur est déjà présent, met à jour sa ligne.
        
        Arguments:
            user  -- Un pseudo.
            score -- Un score.
        """
        edited = False
        for i in self.treeview.get_children():
            item = self.treeview.item(i)
            # Nous sommes bien sur l'item du joueur qui nous interesse
            if item["text"] == user:
                oldValue = item['values']
                oldValue[0] = score
                self.treeview.item(i, values=oldValue)
                edited = True
                break

        if not edited:
            self.treeview.insert('',
                                 'end',
                                 text=str(user),
                                 values=(str(score), "0"))

    def createGraphicalPlayer(self, playerX, playerY):
        """Crée un joueur à une position spécifique.
        
        Arguments:
            playerX -- La coordonnée X du joueur.
            playerY -- La coordonnée Y du joueur.
        
        Returns:
            tuple -- Un tuple contenant le tag du joueur dans le canvas et ses images.
        """
        convertedPos = self.convertPosition(playerX, playerY)
        playerImage = Image.open('images/pod_sprite_50.png')
        podPicture = ImageTk.PhotoImage(playerImage)

        self.canvasLock.acquire()
        tagPlayer = self.canvas.create_image(convertedPos[0],
                                             convertedPos[1],
                                             image=podPicture)
        self.canvasLock.release()

        return (tagPlayer, playerImage, podPicture)

    def createGraphicalOpponent(self, playerX, playerY):
        """Crée un adversaire à une position spécifique.
        
        Arguments:
            playerX -- La coordonnée X de l'adversaire.
            playerY -- La coordonnée Y de l'adversaire.
        
        Returns:
            tuple -- Un tuple contenant le tag de l'adversaire dans le canvas et ses images.
        """
        convertedPos = self.convertPosition(playerX, playerY)
        opponentImage = Image.open('images/pod2_sprite_50.png')
        podPicture = ImageTk.PhotoImage(opponentImage)

        self.canvasLock.acquire()
        tagOpponent = self.canvas.create_image(convertedPos[0],
                                               convertedPos[1],
                                               image=podPicture)
        self.canvasLock.release()

        return (tagOpponent, opponentImage, podPicture)

    def createGraphicalObstacle(self, obstacleX, obstacleY):
        """Crée un obstacle à une position spécifique.
        
        Arguments:
            obstacleX -- La coordonnée X de l'obstacle.
            obstacleY -- La coordonnée Y de l'obstacle.
        
        Returns:
            tuple -- Un tuple contenant le tag de l'obstacle dans le canvas et sa photoImage.
        """
        convertedPos = self.convertPosition(obstacleX, obstacleY)
        obstacleImage = Image.open('images/obstacles/asteroid_sprite_55.png')
        obstaclePicture = ImageTk.PhotoImage(obstacleImage)

        self.canvasLock.acquire()
        tagOstacle = self.canvas.create_image(convertedPos[0],
                                              convertedPos[1],
                                              image=obstaclePicture)
        self.canvasLock.release()

        return (tagOstacle, obstaclePicture)

    def createGraphicalGenkidma(self, genkidamaX, genkidamaY):
        """Crée un genkidama à une position spécifique.
        
        Arguments:
            genkidamaX -- La coordonnée X du genkidama.
            genkidamaY -- La coordonnée Y du genkidama.
        
        Returns:
            tuple -- Un tuple contenant le tag du genkidama dans le canvas et sa photoImage.
        """
        convertedPos = self.convertPosition(genkidamaX, genkidamaY)
        genkidamaImage = Image.open('images/bombs/spirit_bomb_35.png')
        genkidamaPicture = ImageTk.PhotoImage(genkidamaImage)

        self.canvasLock.acquire()
        tagGenkidama = self.canvas.create_image(convertedPos[0],
                                                convertedPos[1],
                                                image=genkidamaPicture)
        self.canvasLock.release()

        return (tagGenkidama, genkidamaPicture)

    def deleteGraphicalGenkidma(self, genkidamaX, genkidamaY):
        """Enlève un genkidama situé à une position spécifique.
        
        Arguments:
            genkidamaX -- La coordonnée X du genkidama.
            genkidamaY -- La coordonnée Y du genkidama.
        
        Returns:
            tuple -- Un tuple contenant le tag du genkidama dans le canvas et sa photoImage.
        """
        convertedPos = self.convertPosition(genkidamaX, genkidamaY)

        self.canvasLock.acquire()
        tagGenki = self.canvas.find_closest(convertedPos[0], convertedPos[1])
        self.canvas.delete(tagGenki)
        self.canvasLock.release()

    def onConnectionClicked(self, button):
        """Handler du clique sur le bouton de connexion
        
        Arguments:
            button -- Le bouton source.
        """
        pseudo = self.pseudoEntry.get()
        if pseudo == "":
            msg = "No pseudo given. You have to give a pseudo in order to connect to the server."
            messagebox.showerror(title="No pseudo", message=msg)
        else:
            success = self.dispatcher.onConnectionClicked(pseudo)
            if success:
                button["state"] = tk.DISABLED
                self.exitButton["state"] = tk.NORMAL
                self.chats["Public"][3]["state"] = tk.NORMAL
                self.statusLabel["text"] = "Connection succeed !"
                self.pseudoEntry.delete(0, tk.END)
            else:
                msg = "Connection to the server failed.\nMake sure the server is running."
                messagebox.showerror(title="Connection failed", message=msg)

    def closeWindow(self):
        """Handler de la fermeture de la fenêtre.
           Signale au dispatcher que l'utilisateur souhaite quitter l'application et ferme l'interface.
        """
        self.dispatcher.onCloseWindow()
        # Il se peut qu'un thread soit bloqué en attente d'une réponse du thread de l'interface
        # En exécutant un update, on va le débloquer
        self.master.update()
        self.master.destroy()

    def updateUIPlayer(self, player):
        """Met à jour la position et l'angle de rotation d'un joueur.
        
        Arguments:
            player -- Le joueur.
        """
        self.canvasLock.acquire()
        if player.getPseudo(
        ) not in self.previousAngles or self.previousAngles[
                player.getPseudo()] != player.getAngle():
            self.rotatePlayer(player)
        self.updatePlayer(player)
        self.canvasLock.release()

    def updatePlayer(self, player):
        """Met à jour la position d'un joueur.
        
        Arguments:
            player -- Le joueur.
        """
        convertedPos = self.convertPosition(player.getPositionX(),
                                            player.getPositionY())
        self.canvas.coords(player.getCanvasTagId(),
                           (convertedPos[0], convertedPos[1]))

    def rotatePlayer(self, player):
        """Met à jour l'angle de rotation d'un joueur.
        
        Arguments:
            player -- Le joueur.
        """
        self.previousAngles[player.getPseudo()] = player.getAngle()
        self.canvas.delete(player.getCanvasTagId())
        podPicture = ImageTk.PhotoImage(player.getImage().rotate(
            player.getAngle()))
        convertedPos = self.convertPosition(player.getPositionX(),
                                            player.getPositionY())
        newId = self.canvas.create_image(convertedPos[0],
                                         convertedPos[1],
                                         image=podPicture)
        player.setCanvasTagId(newId)
        player.setPhotoImage(podPicture)

    def convertPosition(self, x, y):
        """Convertie des coordonnées pour qu'elle soit utilisable par le canvas.
        
        Arguments:
            x -- La coordonnée X.
            y -- La coordonnée Y.
        
        Returns:
            tuple(x, y) -- Un tuple contenant les positions converties.
        """
        newX = x + dat.ARENA_L
        newY = y + dat.ARENA_H

        return (newX, newY)

    def showDeniedMessage(self):
        """Affiche un message indiquant à l'utilisateur que sa tentative de connexion à été refusée."""
        msg = "The server refused the connection.\nYou may try again with an other pseudo"
        messagebox.showerror(title="Connection refused", message=msg)
        self.statusLabel["text"] = "Pseudo already used..."
        self.connectionButton["state"] = tk.NORMAL

    def showWaitingMessage(self):
        """Met à jour le label de status pour indiquer à l'utilisateur d'attendre le début de la partie."""
        print("Waiting")
        self.statusLabel["text"] = "Waiting for game to start..."
        self.progress.start(10)

    def showStartMessage(self):
        """Met à jour le label de status pour indiquer à l'utilisateur que la partie à commencé."""
        print("Good game")
        self.statusLabel["text"] = "Good game !"
        self.progress.stop()

    def showWinner(self, winnerName, iWin):
        """Affiche une fenêtre avec le nom du gagnant.
        
        Arguments:
            winnerName  -- Le nom du gagnant.
            iWin  -- Indique si le gagnant est le joueur actuel.
        """
        msg = ""
        if iWin:
            msg = "Congratulation you have won !"
        else:
            msg = winnerName + " has won !"
        messagebox.showinfo(title="We have a winner !", message=msg)

    def showObjectif(self, objectifX, objectifY, objectifNumber):
        """Ajoute un objectif (une dragon ball).
        
        Arguments:
            objectifX  -- La coordonnée X de l'objectif.
            objectifY  -- La coordonnée Y de l'objectif.
            objectifNumber  -- Le numéro de l'objectif (utiliser pour choisir quelle dragon ball utiliser).
        
        Returns:
            tuple(idTag, photoImage) -- Un tuple contenant le tag de l'objectif et son image.
        """
        converted = self.convertPosition(objectifX, objectifY)
        newImage = Image.open('images/dragon_ball/ball_' +
                              str(objectifNumber) + ".png")
        newPhotoImage = ImageTk.PhotoImage(newImage)

        self.canvasLock.acquire()
        tagImage = self.canvas.create_image(converted[0],
                                            converted[1],
                                            image=newPhotoImage)
        self.canvasLock.release()

        return (tagImage, newPhotoImage)

    def reset(self):
        """Remet à zéro l'application graphique."""
        self.resetScores()
        for (_, chat) in self.chats.items():
            self.notebook.forget(chat[0])

        self.chats = {}
        # On ajoute de nouveau le chat public
        self.createChat("Public", enable=True)

    def resetScores(self):
        """Remet à zéro le tableau des scores."""
        self.progress.stop()
        for i in self.treeview.get_children():
            self.treeview.delete(i)

    def removeOpponent(self, opponentName):
        """Supprime un adversaire dde l'interface graphique.
        
        Arguments:
            opponentName -- Le nom de l'adversaire.
        """
        for child in self.treeview.get_children():
            item = self.treeview.item(child)
            if (item["text"]) == opponentName:
                self.treeview.delete(child)

        if opponentName in self.chats:
            del self.chats[opponentName]

    def deleteFromCanvas(self, tag):
        """Supprime un élément du canavas identifié par son tag.
        
        Arguments:
            tag  -- Le tag de l'élément à supprimer.
        """
        self.canvas.delete(tag)

    def showElement(self, tag):
        self.canvas.itemconfigure(tag, state='normal')

    def hideElement(self, tag):
        self.canvas.itemconfigure(tag, state='hidden')
예제 #2
0
class Statistics(Page):
    """This class provides the statistics view, in table and graphical form"""
    def __init__(self, mainUI):
        super().__init__(mainUI)
        self.columnconfigure(0, weight=1)
        self.back_button = Button(self,
                                  text="< Back",
                                  command=lambda: self.go_to("Welcome")())
        self.back_button.grid(row=1, padx=(10, 0), pady=(10, 5), sticky="w")

        self.choose_date_label = Label(self,
                                       text="View statistics from event on: ")
        self.choose_date_label.grid(row=1, column=1)
        self.date_to_view = StringVar(name="date")

        self.choose_date_menu = OptionMenu(self, self.date_to_view,
                                           *StatsData.available_dates())
        self.date_to_view.set(StatsData.available_dates()[0])
        self.choose_date_menu.grid(row=1, column=2)
        self.date_to_view.trace("w", self.update_ui)
        # hide border
        # https://groups.google.com/forum/#!topic/comp.lang.tcl/8a6e4tfWJvo
        s = Style(self)
        s.configure('flat.TNotebook', borderwidth=0)
        self.tabbed_section = Notebook(self, style="flat.TNotebook")

        # # FIXME: padding
        self.tabbed_section.grid(row=2, columnspan="3", padx=20, sticky="n")
        #
        self.button = Button(self,
                             text="Export event statistics as CSV",
                             command=self.csv_export)
        self.button.grid(row=3, columnspan="3", pady=10, sticky="n")
        self.update_ui()

    def update_ui(self, *args):
        new_date = StatsData.dates[self.date_to_view.get()]
        for tab in self.tabbed_section.tabs():
            self.tabbed_section.forget(tab)

        for package in StatsData.packages_for_date(new_date):
            test_tab = PackageView(self.tabbed_section, new_date, package)
            self.tabbed_section.add(test_tab, text=package)

    def csv_export(self):
        date = StatsData.dates[self.date_to_view.get()]

        file_path = filedialog.asksaveasfilename(filetypes=(("CSV", ".csv"), ),
                                                 initialfile=date)

        # code taken from https://docs.python.org/3/library/csv.html
        if file_path:
            with open(file_path, 'w', newline='') as csvfile:
                csvwriter = csv.writer(csvfile,
                                       delimiter=',',
                                       quotechar='"',
                                       quoting=csv.QUOTE_MINIMAL)
                csvwriter.writerow(("package name", "quiz", "question id",
                                    "question text", "total times shown",
                                    "successful answers", "skips", "abandons"))
                for package in StatsData.packages_for_date(date):
                    for quiz in StatsData.quizzes_for_package(package, date):
                        for q in StatsData.get_data(date, package, quiz):
                            csvwriter.writerow(
                                (q.package_name, q.quiz, q.q_id, q.text,
                                 total_times_shown(q), q.successes, q.skips,
                                 q.abandons))
예제 #3
0
class LpoViewer(Frame):
    """ This class implements the window of the Lpo viewer.

    This class implements a menu and tab management for the LpoView.
    """
    
    def __init__(self, parent):
        """ Create new window. """
        Frame.__init__(self, parent)
        self.__parent = parent
        self.__initUI()

    def __initUI(self):
        """ Set up UI. """
        self.pack(fill=BOTH, expand=1)
        # notebook for LpoView tabs
        self.__notebook = Notebook(self)
        self.__notebook.pack(fill=BOTH, expand=1)
        # menu bar with file menu
        self.__menubar = Menu(self.__parent)
        self.__parent.config(menu=self.__menubar)

        self.__filemenu = Menu(self.__menubar, tearoff=0)
        self.__filemenu.add_command(label="Open", command=self.__onOpen)
        self.__filemenu.add_command(label="Close", command=self.__onClose)
        self.__filemenu.add_command(label="Exit", command=self.__onExit)
        self.__menubar.add_cascade(label="File", menu=self.__filemenu)
        # size and title
        self.__parent.geometry("300x300+300+300")
        self.__parent.title("Lpo viewer Tk")

    def __onExit(self):
        """ Close the app. """
        self.__parent.withdraw()
        self.quit()

    def __onClose(self):
        """ Close the selected LPO. """
        tab = self.__notebook.select()
        if tab != '':
            self.__notebook.forget(tab)
        

    def __onOpen(self):
        """ Open a new LPO (with file chooser). """
        ftypes = [('LPO files', '*.lpo'), ('All files', '*')]
        dialog = filedialog.Open(self, filetypes=ftypes)
        file = dialog.show()

        if file != '':
            self.openLpo(file)

    def openLpo(self, file):
        """ This method shows the LPO contained in the given file as new tab. """
        lpos = partialorder.parse_lpo_file(file) # parse LPO from file
        print(lpos[0])
        self.showLpo(lpos[0]) # show first lpo (Assumption: Only 1 LPO in a file)
    
    def showLpo(self, lpo):
        """ Show the given LPO in a new tab. """
        lpo_view = LpoView(self.__notebook)
        self.__notebook.add(lpo_view, text=lpo.name, sticky="nswe")
        lpo_view.showLpo(lpo)
예제 #4
0
class OpeningPage():
    """@summary: Widget servant à lancer la simulation après
                 avoir renseigné les persos
        """
    def __init__(self, fenetre):
        self.notebk = Notebook(fenetre)
        self.fenetre = fenetre
        self.persoViews = []
        self.caracsNotebk = []
        self.framesPersos = []

    def formSubmission(self, _):
        """@summary: Lance la simulation de combat avec les persos du notebook
        """
        persos = []
        for persoVw in self.persoViews:
            persoVw.inputsToPerso()
            persos.append(persoVw.perso)
            writeSaveFile("save.json", persos)
        launchSimu(self.persoViews)

    def addEmptyPage(self, _):
        """@summary: Ajoute un onglet avec un stub perso dans le notebook0
        """
        self.addPage(readSaveFile("./persos/empty.json"))

    def deleteActiveNotePage(self):
        """@summary: Supprime l'onglet actif et les valeurs de personnages
                     associés.
        """
        nomPanneau = self.notebk.tab(self.notebk.select())["text"]
        indPanneau = int(nomPanneau.split(" ")[1])
        self.notebk.forget(self.notebk.select())
        del self.persoViews[indPanneau - 1]

    def addPage(self, values):
        """@summary: Ajoute un onglet avec les valeurs de personnages données.
        """
        self.framesPersos.append(Frame(self.notebk))
        framePerso = self.framesPersos[-1]
        self.persoViews.append(PersoView(values))
        persoVw = self.persoViews[-1]
        self.caracsNotebk.append(Notebook(framePerso))
        caracNotebk = self.caracsNotebk[-1]
        caracNotebk.pack()
        for inputsCategory, inputValues in persoVw.perso.items():
            frameCaracs = LabelFrame(framePerso, text=inputsCategory)
            if persoVw.inputs.get(inputsCategory, None) is None:
                persoVw.inputs[inputsCategory] = dict()
            j = 0
            for inputName, inputValue in inputValues.items():
                if inputName == "Classe":
                    classesDisponibles = \
                        Combobox(frameCaracs,
                                 textvariable=StringVar(),
                                 values=["Cra", "Xelor", "Iop",
                                         "Sram", "Poutch", "Eniripsa", "Pandawa"],
                                 state='readonly')
                    persoVw.inputs[inputsCategory][
                        inputName] = classesDisponibles
                    persoVw.inputs[inputsCategory][inputName].set(inputValue)

                else:
                    persoVw.inputs[inputsCategory][inputName] = \
                        Entry(frameCaracs, textvariable=StringVar(), width=10)
                    persoVw.inputs[inputsCategory][inputName].insert(
                        END, inputValue)
                lblCarac = Label(frameCaracs, text=inputName + ":")
                lblCarac.grid(row=j, column=0)
                persoVw.inputs[inputsCategory][inputName].grid(row=j, column=1)
                j += 1
            caracNotebk.add(frameCaracs, text=inputsCategory)
        # Pack de la fenêtre, détermine la taille de la fenêtre selon la taille des composants.
        #framePerso.pack(fill="both", expand="yes")
        self.notebk.add(framePerso, text="Perso " + str(len(self.persoViews)))
        saveBtn = Button(framePerso,
                         text='Sauvegarder ce perso',
                         command=persoVw.save)
        loadBtn = Button(framePerso,
                         text='Charger un perso',
                         command=persoVw.load)
        deleteThisBtn = Button(framePerso,
                               text="Supprimer ce perso",
                               command=self.deleteActiveNotePage)
        # Mise du bouton sur la droite de la fenetre
        saveBtn.pack(side="left")
        # Mise du bouton sur la droite de la fenetre
        loadBtn.pack(side="left")
        deleteThisBtn.pack(side="left")

    def main(self):
        """@summary: Lance la création des personnages pour ensuite lancer la simulation
        """
        # Créer la fenêtre Tkinter
        values = readSaveFile("save.json")
        self.notebk.pack()

        for inputPerso in values:
            self.addPage(inputPerso)

        self.notebk.enable_traversal()
        # Ajout du bouton pour lancer la simulation
        submit = Button(self.fenetre, text='Lancer la simulation')
        # Permet au gestionnaire d'événement d'ajouter des paramètres
        # Gestionnaire d'événement pour le clic du bouton
        submit.bind("<Button-1>", self.formSubmission)
        # Mise du bouton sur la droite de la fenetre
        submit.pack(side="right")
        addPersoBtn = Button(self.fenetre, text='Ajouter un perso')
        addPersoBtn.bind("<Button-1>", self.addEmptyPage)
        addPersoBtn.pack(side="right")
예제 #5
0
파일: mainview.py 프로젝트: gokai/tim
class Main(object):
    def __init__(self, title):
        root = Tk()
        root.title(title)
        root.focus_set()
        root.rowconfigure(0, weight=0)
        root.columnconfigure(0, weight=1)
        root.rowconfigure(1, weight=1)
        self._root = root

        self.menubar = Frame(root)
        self.menubar.grid(row=0, column=0, sticky=(W, E))
        self.menubar['takefocus'] = False

        quit_button = Button(self.menubar, text='Quit', command=self.quit)
        quit_button.grid(row=0, column=0)

        self._menucolumn = 1
        self.views = list()

        self.paned_win = PanedWindow(root, orient=HORIZONTAL)
        self.paned_win.grid(row=1, column=0, sticky=(N, S, W, E))

        self._query = None
        self._accept_func = None

        self.sidebar_views = dict()
        self.sidebar_count = 0
        self.sidebar = PanedWindow(self.paned_win)
        self.paned_win.add(self.sidebar, weight=1)

        self.tabs = Notebook(self.paned_win)
        self.tabs.enable_traversal()
        self.paned_win.add(self.tabs, weight=5)
        self.root = self.tabs

    def add_menubutton(self, label, action):
        button = Button(self.menubar, text=label, command=action)
        button.grid(row=0, column=self._menucolumn)
        self._menucolumn += 1

    def add_sidebar(self, view, name):
        self.sidebar_views[name] = view
        self.sidebar.add(view.widget, weight=1)
        view.widget.focus_set()
        self.sidebar_count += 1
        if self.sidebar_count == 1:
            self.sidebar_views['main'] = view

    def remove_sidebar_view(self, name):
        self.sidebar.forget(self.sidebar_views[name].widget)
        self.sidebar_count -= 1
        del self.sidebar_views[name]
        if self.sidebar_count == 0:
            del self.sidebar_views['main']

    def get_sidebar_view(self, name):
        return self.sidebar_views.get(name)

    def focus_sidebar(self):
        if 'main' in self.sidebar_views.keys():
            self.sidebar_views['main'].widget.focus_set()

    def focus_main_view(self):
        self.get_current_view().widget.focus_set()

    def new_view(self, view):
        self.views.append(view)
        self.tabs.add(view.widget, text=" {}.".format(self.tabs.index('end')))
        self.tabs.select(view.widget)

        view.widget.focus_set()
        self.view_changed()

    def remove_view(self, view):
        self.views.remove(view)
        self.tabs.forget(view.widget)
        if len(self.views) >= 1:
            widget = self.views[-1].widget
            self.tabs.select(widget)
            widget.focus_set()
        else:
            self.sidebar_views['main'].widget.focus_set()
        self.view_changed()

    def delete_current_view(self, event):
        if self.tabs.index('end') > 0:
            self.remove_view(self.get_current_view())

    def close_query(self):
        if self._query is not None:
            self._query.event_generate('<<MainQueryClose>>')
            self._query.destroy()
            self._query = None
            self._accept_func = None
            self._menucolumn -= 1

    def accept_query(self, event):
        if self._query is not None:
            if self._accept_func is not None:
                self._accept_func(event.widget.get(),
                                  event.widget.original_value)
                self.close_query()
            else:
                event.widget.event_generate('<<MainQueryAccept>>')

    def text_query(self, query_lable, original_text=None, accept_func=None):
        if self._query is not None:
            return
        frame = Frame(self.menubar)
        label = Label(frame, text=query_lable)
        label.grid(column=0, row=0, sticky=(N, S))
        self._accept_func = accept_func

        entry = Entry(frame)
        if original_text is not None:
            entry.insert(0, original_text)
        entry.original_value = original_text
        entry.grid(column=1, row=0, sticky=(N, S, W, E))
        kb.make_bindings(kb.text_query, {
            'accept': self.accept_query,
            'cancel': lambda e: self.close_query()
        }, entry.bind)

        frame.grid(column=self._menucolumn, row=0)
        self._menucolumn += 1
        entry.focus_set()
        self._query = frame

    def get_current_view(self):
        if self.tabs.index('end') > 0:
            return self.views[self.tabs.index('current')]
        else:
            return self.sidebar_views['main']

    def view_changed(self):
        self._root.event_generate('<<MainViewChanged>>')

    def display(self):
        self._root.mainloop()

    def quit(self):
        self._root.destroy()
예제 #6
0
파일: mainview.py 프로젝트: gokai/tim
class Main(object):

    def __init__(self, title):
        root = Tk()
        root.title(title)
        root.focus_set()
        root.rowconfigure(0, weight=0)
        root.columnconfigure(0, weight=1)
        root.rowconfigure(1, weight=1)
        self._root = root

        self.menubar = Frame(root)
        self.menubar.grid(row=0, column=0, sticky=(W, E))
        self.menubar['takefocus'] = False

        quit_button = Button(self.menubar, text='Quit', command=self.quit)
        quit_button.grid(row=0, column=0)

        self._menucolumn = 1
        self.views = list()

        self.paned_win = PanedWindow(root, orient=HORIZONTAL)
        self.paned_win.grid(row=1, column=0, sticky=(N, S, W, E))

        self._query = None
        self._accept_func = None

        self.sidebar_views = dict()
        self.sidebar_count = 0
        self.sidebar = PanedWindow(self.paned_win)
        self.paned_win.add(self.sidebar, weight=1)
        
        self.tabs = Notebook(self.paned_win)
        self.tabs.enable_traversal()
        self.paned_win.add(self.tabs, weight=5)
        self.root = self.tabs

    def add_menubutton(self, label, action):
        button = Button(self.menubar, text=label, command=action)
        button.grid(row=0, column=self._menucolumn)
        self._menucolumn += 1

    def add_sidebar(self, view, name):
        self.sidebar_views[name] = view
        self.sidebar.add(view.widget, weight=1)
        view.widget.focus_set()
        self.sidebar_count += 1
        if self.sidebar_count == 1:
            self.sidebar_views['main'] = view

    def remove_sidebar_view(self, name):
        self.sidebar.forget(self.sidebar_views[name].widget)
        self.sidebar_count -= 1
        del self.sidebar_views[name]
        if self.sidebar_count == 0:
            del self.sidebar_views['main']

    def get_sidebar_view(self, name):
        return self.sidebar_views.get(name)

    def focus_sidebar(self):
        if 'main' in self.sidebar_views.keys():
            self.sidebar_views['main'].widget.focus_set()

    def focus_main_view(self):
        self.get_current_view().widget.focus_set()

    def new_view(self, view):
        self.views.append(view)
        self.tabs.add(view.widget, text=" {}.".format(self.tabs.index('end')))
        self.tabs.select(view.widget)

        view.widget.focus_set()
        self.view_changed()

    def remove_view(self, view):
        self.views.remove(view)
        self.tabs.forget(view.widget)
        if len(self.views) >= 1:
            widget = self.views[-1].widget
            self.tabs.select(widget)
            widget.focus_set()
        else:
            self.sidebar_views['main'].widget.focus_set()
        self.view_changed()

    def delete_current_view(self, event):
        if self.tabs.index('end') > 0:
            self.remove_view(self.get_current_view())

    def close_query(self):
        if self._query is not None:
            self._query.event_generate('<<MainQueryClose>>')
            self._query.destroy()
            self._query = None
            self._accept_func = None
            self._menucolumn -= 1

    def accept_query(self, event):
        if self._query is not None:
            if self._accept_func is not None:
                self._accept_func(event.widget.get(), event.widget.original_value)
                self.close_query()
            else:
                event.widget.event_generate('<<MainQueryAccept>>')

    def text_query(self, query_lable, original_text=None, accept_func=None):
        if self._query is not None:
            return
        frame = Frame(self.menubar)
        label = Label(frame, text=query_lable)
        label.grid(column=0, row=0, sticky=(N, S))
        self._accept_func = accept_func

        entry = Entry(frame)
        if original_text is not None:
            entry.insert(0, original_text)
        entry.original_value = original_text
        entry.grid(column=1, row=0, sticky=(N,S,W,E))
        kb.make_bindings(kb.text_query, 
                {'accept': self.accept_query,
                 'cancel': lambda e: self.close_query()}, entry.bind)

        frame.grid(column=self._menucolumn, row=0)
        self._menucolumn += 1
        entry.focus_set()
        self._query = frame

    def get_current_view(self):
        if self.tabs.index('end') > 0:
            return self.views[self.tabs.index('current')]
        else:
            return self.sidebar_views['main']

    def view_changed(self):
        self._root.event_generate('<<MainViewChanged>>')

    def display(self):
        self._root.mainloop()

    def quit(self):
        self._root.destroy()
예제 #7
0
class translator(Tk):
    def __init__(self):
        super().__init__()
        self.title("Translator")
        self.geometry("500x300")

        self.langname = []
        self.langcode = []
        self.langans = []
        self.langtab = []
        self.langlabel = []
        self.tab = []
        self.tfname = None
        self.tfcode = None
        self.addwin = None
        self.dialog = None
        self.proxy = None
        self.proxyentry = None
        self.proxystate = 0
        self.pwin = None

        self.menu = Menu(self, bg='lightgrey', fg='black')
        self.langmenu = Menu(self.menu, tearoff=0, bg='lightgrey', fg='black')
        self.langmenu.add_command(label="Add Language", command=self.addlang)
        self.proxymenu = Menu(self.menu, tearoff=0, bg='lightgrey', fg='black')
        self.proxymenu.add_command(label="Set Proxy", command=self.setproxy)
        self.menu.add_cascade(label='Languages', menu=self.langmenu)
        self.config(menu=self.menu)

        self.nb = Notebook(self)
        self.entab = Frame(self.nb)

        translatebutton = Button(self.entab,
                                 text='Translate',
                                 command=self.translate)
        translatebutton.pack(side=BOTTOM, fill=X)

        self.tf = Text(self.entab, bg='white', fg='black')
        self.tf.pack(side=TOP, fill=BOTH, expand=1)

        self.nb.add(self.entab, text='English')
        self.nb.pack(fill=BOTH, expand=1)
        self.delmenu = Menu(self.menu, tearoff=0, bg='lightgrey', fg='black')
        self.delmenu.add_command(label='Delete Tab', command=self.deltab)
        self.menu.add_cascade(label='Delete', menu=self.delmenu)

        self.delmenu.add_command(label='Delete Language', command=self.dellang)

        self.menu.add_cascade(label='Proxy', menu=self.proxymenu)

        if not os.path.isfile("lcodes.db"):
            self.conn = sqlite3.connect("lcodes.db")
            self.cur = self.conn.cursor()
            self.cur.execute('CREATE TABLE languages (name TEXT, code TEXT)')
        else:
            self.conn = sqlite3.connect("lcodes.db")
            self.cur = self.conn.cursor()
            self.cur.execute('SELECT * FROM languages ORDER BY name')
            self.fromdb()

        if os.path.isfile('proxy.txt'):
            f = open("proxy.txt", "rt")
            pr = f.readline()
            if len(pr) > 0:
                self.proxystate = 1
                self.proxy = {"https": "https://" + pr}
            f.close()

    def addlang(self):
        self.addwin = Toplevel()
        self.addwin.title("Add Language")
        self.addwin.geometry("300x150")

        topframe = Frame(self.addwin, pady=10, height=70)
        midframe = Frame(self.addwin, pady=10, height=70)
        bottomframe = Frame(self.addwin)

        name = Label(topframe,
                     text='Language Name',
                     bg='lightgrey',
                     fg='black',
                     font=(20))
        name.pack(side=LEFT, fill=BOTH, expand=1)

        self.tfname = Text(topframe,
                           height=1,
                           bg='white',
                           fg='black',
                           font=(20))
        self.tfname.pack(side=RIGHT, fill=BOTH, expand=1)

        code = Label(midframe,
                     text='Language Code',
                     bg='lightgrey',
                     fg='black',
                     font=(20))
        code.pack(side=LEFT, fill=BOTH, expand=1)

        self.tfcode = Text(midframe,
                           height=1,
                           bg='white',
                           fg='black',
                           font=(20))
        self.tfcode.pack(side=RIGHT, fill=BOTH, expand=1)

        submit = Button(bottomframe,
                        text='Add',
                        bg='lightgrey',
                        fg='black',
                        pady=10,
                        command=self.submitentry,
                        font=(20))
        submit.pack(fill=X)

        bottomframe.pack(side=BOTTOM, fill=X)
        midframe.pack(side=BOTTOM, fill=BOTH, expand=1)
        topframe.pack(side=TOP, fill=BOTH, expand=1, anchor=N)

    def submitentry(self):
        name = self.tfname.get(1.0, END).strip()
        code = self.tfcode.get(1.0, END).strip()
        if name and code:
            if (code in self.langcode) or (name in self.langname):
                showerror('Exists', 'Language alredy added')
                return
            self.langmenu.add_command(label=name,
                                      command=lambda: self.addtab(name))
            self.langname.append(name)
            self.langcode.append(code)
            st = "INSERT INTO languages\nVALUES ('" + name + "', '" + code + "');"
            self.cur.execute(st)
            self.conn.commit()
            self.addwin.destroy()
            showinfo("Added", name + " is added successfully")
        else:
            showerror("Missing Info", "Please add both language name and code")

    def addtab(self, txt):
        ltab = Frame(self.nb)

        ans = StringVar(ltab)
        ans.set(txt + "translation")
        self.langlabel.append(ans)

        self.langtab.append(txt)
        self.langans.append(str(txt + "translation"))
        index = self.langtab.index(txt)

        button = Button(ltab,
                        text='Copy to Clipboard',
                        bg='lightgrey',
                        fg='black',
                        pady=10,
                        command=lambda: self.copytoclip(self.langans[index]))
        button.pack(side=BOTTOM, fill=X)

        label = Label(ltab, textvar=ans, bg='lightgrey', fg='black')
        label.pack(side=TOP, fill=BOTH, expand=1)
        self.nb.add(ltab, text=txt)
        self.tab.append(ltab)

    def copytoclip(self, text):
        self.clipboard_clear()
        self.clipboard_append(text)
        showinfo('Copied', 'Message copied Successfully')

    def translate(self):
        que = self.tf.get(1.0, END)

        self.langans = []
        err = 0

        for i in self.langtab:
            index = self.langname.index(i)
            code = self.langcode[index]
            url = "https://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl={}&dt=t&q={}".format(
                code, que)
            try:
                if self.proxystate == 1:
                    r = requests.get(url, proxies=self.proxy)
                else:
                    r = requests.get(url)
                r.raise_for_status()
                self.langans.append(r.json()[0][0][0])
            except Exception as e:
                showerror("Failed", "Failed for " + i + " error: " + str(e))
                err = 1
        if err == 0:
            showinfo("Successful", "Translation Successful")

        for i in range(0, len(self.langans)):
            self.langlabel[i].set(self.langans[i])

    def deltab(self, text=None):
        if text:
            if not text in self.langtab:
                return
            index = self.langtab.index(text)
            tab = self.tab[index]
            self.nb.forget(tab)
            return
        if self.nb.select() != str(self.entab):
            target = None
            for i in self.tab:
                if self.nb.select() == str(i):
                    target = i
                    break
            index = self.tab.index(target)
            self.tab.remove(target)
            self.langlabel.pop(index)
            self.langtab.pop(index)
            self.langans.pop(index)
            self.nb.forget(self.nb.select())
        else:
            showerror("Failed", "English tab can't be deleted")

    def dellang(self):
        self.dialog = Toplevel()
        self.dialog.title("Delete Language")
        self.dialog.geometry("150x100")
        button = Button(self.dialog,
                        text='Delete',
                        bg='lightgrey',
                        fg='black',
                        pady=10,
                        font=(20),
                        command=lambda: self.removelang(entry))
        entry = Entry(self.dialog, bg='white', fg='black', font=(20))
        label = Label(self.dialog,
                      text='Language Name',
                      bg='lightgrey',
                      fg='black',
                      pady=8,
                      font=(20))
        button.pack(side=BOTTOM, fill=X)
        entry.pack(side=BOTTOM, fill=X)
        label.pack(side=TOP, fill=BOTH, anchor=N)

    def removelang(self, entry):
        text = entry.get()
        if text:
            target = None
            for name in self.langname:
                if text.lower() == name.lower():
                    target = name
                    break
            if not target:
                showerror("Not Found", "Language not found")
                return
            self.langmenu.delete(target)
            self.dialog.destroy()
            index = self.langname.index(target)
            code = self.langcode[index]
            self.langname.remove(target)
            self.langcode.remove(code)
            '''index=self.langtab.index(target)
			self.langtab.remove(target)
			self.tab.pop(index)
			self.langans.pop(index)
			self.langlabel.pop(index)'''
            st = 'DELETE FROM languages WHERE code = "' + code + '";'
            self.cur.execute(st)
            self.conn.commit()
            showinfo('Deleted', target + " deleted successfully")
        else:
            showerror('Blank', 'You had not entered anything')

    def fromdb(self):
        self.cur.execute('SELECT * FROM languages')
        data = self.cur.fetchall()
        for row in data:
            self.langname.append(row[0])
            self.langcode.append(row[1])
            self.langmenu.add_command(label=row[0],
                                      command=lambda: self.addtab(row[0]))

    def setproxy(self):
        self.pwin = Toplevel()
        self.pwin.title("Proxy")
        label = Label(self.pwin,
                      text='proxy(hostname:port)',
                      fg='black',
                      bg='lightgrey')
        self.proxyentry = Entry(self.pwin, fg='black', bg='white')
        subbutton = Button(self.pwin,
                           text='submit',
                           fg='black',
                           bg='lightgrey',
                           command=lambda: self.applyproxy(1))
        dupbutton = Button(self.pwin,
                           text="Don't use proxy",
                           fg='black',
                           bg='lightgrey',
                           command=lambda: self.applyproxy(0))
        label.grid(row=0, column=0)
        self.proxyentry.grid(row=0, column=1)
        subbutton.grid(row=1, columnspan=2)
        dupbutton.grid(row=2, columnspan=2)

    def applyproxy(self, n):
        if n == 0:
            self.proxystate = 0
            f = open("proxy.txt", "wt")
            f.write("")
            f.close()
            self.pwin.destroy()
            return
        proxy = self.proxyentry.get(1.0, END).strip()
        self.proxystate = 1
        self.proxy = {"https": "https://" + proxy}
        f = open("proxy.txt", "wt")
        f.write(proxy)
        f.close()
        self.pwin.destroy()
예제 #8
0
class translator(Tk):
    def __init__(self):
        super().__init__()
        self.title("Translator")
        self.geometry("500x300")

        self.langname = []
        self.langcode = []
        self.langans = []
        self.langtab = []
        self.langlabel = []
        self.tab = []
        self.tfname = None
        self.tfcode = None
        self.addwin = None
        self.dialog = None

        self.menu = Menu(self, bg='lightgrey', fg='black')
        self.langmenu = Menu(self.menu, tearoff=0, bg='lightgrey', fg='black')
        self.langmenu.add_command(label="Add Language", command=self.addlang)
        self.menu.add_cascade(label='Languages', menu=self.langmenu)
        self.config(menu=self.menu)

        self.nb = Notebook(self)
        self.entab = Frame(self.nb)

        translatebutton = Button(self.entab,
                                 text='Translate',
                                 command=self.translate)
        translatebutton.pack(side=BOTTOM, fill=X)

        self.tf = Text(self.entab, bg='white', fg='black')
        self.tf.pack(side=TOP, fill=BOTH, expand=1)

        self.nb.add(self.entab, text='English')
        self.nb.pack(fill=BOTH, expand=1)
        self.delmenu = Menu(self.menu, tearoff=0, bg='lightgrey', fg='black')
        self.delmenu.add_command(label='Delete Tab', command=self.deltab)
        self.menu.add_cascade(label='Delete', menu=self.delmenu)

        self.delmenu.add_command(label='Delete Language', command=self.dellang)

    def addlang(self):
        self.addwin = Toplevel()
        self.addwin.title("Add Language")
        self.addwin.geometry("300x150")

        topframe = Frame(self.addwin, pady=10, height=70)
        midframe = Frame(self.addwin, pady=10, height=70)
        bottomframe = Frame(self.addwin)

        name = Label(topframe,
                     text='Language Name',
                     bg='lightgrey',
                     fg='black',
                     font=(20))
        name.pack(side=LEFT, fill=BOTH, expand=1)

        self.tfname = Text(topframe,
                           height=1,
                           bg='white',
                           fg='black',
                           font=(20))
        self.tfname.pack(side=RIGHT, fill=BOTH, expand=1)

        code = Label(midframe,
                     text='Language Code',
                     bg='lightgrey',
                     fg='black',
                     font=(20))
        code.pack(side=LEFT, fill=BOTH, expand=1)

        self.tfcode = Text(midframe,
                           height=1,
                           bg='white',
                           fg='black',
                           font=(20))
        self.tfcode.pack(side=RIGHT, fill=BOTH, expand=1)

        submit = Button(bottomframe,
                        text='Add',
                        bg='lightgrey',
                        fg='black',
                        pady=10,
                        command=self.submitentry,
                        font=(20))
        submit.pack(fill=X)

        bottomframe.pack(side=BOTTOM, fill=X)
        midframe.pack(side=BOTTOM, fill=BOTH, expand=1)
        topframe.pack(side=TOP, fill=BOTH, expand=1, anchor=N)

    def submitentry(self):
        name = self.tfname.get(1.0, END).strip()
        code = self.tfcode.get(1.0, END).strip()
        if name and code:
            self.langmenu.add_command(label=name,
                                      command=lambda: self.addtab(name))
            self.langname.append(name)
            self.langcode.append(code)
            self.addwin.destroy()
            showinfo("Added", name + " is added successfully")
        else:
            showerror("Missing Info", "Please add both language name and code")

    def addtab(self, txt):
        ltab = Frame(self.nb)

        ans = StringVar(ltab)
        ans.set(txt + "translation")
        self.langlabel.append(ans)

        self.langtab.append(txt)
        self.langans.append(str(txt + "translation"))
        index = self.langtab.index(txt)

        button = Button(ltab,
                        text='Copy to Clipboard',
                        bg='lightgrey',
                        fg='black',
                        pady=10,
                        command=lambda: self.copytoclip(self.langans[index]))
        button.pack(side=BOTTOM, fill=X)

        label = Label(ltab, textvar=ans, bg='lightgrey', fg='black')
        label.pack(side=TOP, fill=BOTH, expand=1)
        self.nb.add(ltab, text=txt)
        self.tab.append(ltab)

    def copytoclip(self, text):
        self.clipboard_clear()
        self.clipboard_append(text)
        showinfo('Copied', 'Message copied Successfully')

    def translate(self):
        que = self.tf.get(1.0, END).strip()

        self.langans = []
        err = 0

        for i in self.langtab:
            index = self.langname.index(i)
            code = self.langcode[index]
            url = "https://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl={}&dt=t&q={}".format(
                code, que)
            try:
                r = requests.get(url)
                r.raise_for_status()
                self.langans.append(r.json()[0][0][0])
            except Exception as e:
                showerror("Failed", "Failed for " + i + " error: " + str(e))
                err = 1
        if err == 0:
            showinfo("Successful", "Translation Successful")

        for i in range(0, len(self.langans)):
            self.langlabel[i].set(self.langans[i])

    def deltab(self, text=None):
        if text:
            index = self.langtab.index(text)
            tab = self.tab[index]
            self.nb.forget(tab)
            return
        if self.nb.select() != str(self.entab):
            self.nb.forget(self.nb.select())
        else:
            showerror("Failed", "English tab can't be deleted")

    def dellang(self):
        self.dialog = Toplevel()
        self.dialog.title("Delete Language")
        self.dialog.geometry("150x100")
        button = Button(self.dialog,
                        text='Delete',
                        bg='lightgrey',
                        fg='black',
                        pady=10,
                        font=(20),
                        command=lambda: self.removelang(entry))
        entry = Entry(self.dialog, bg='white', fg='black', font=(20))
        label = Label(self.dialog,
                      text='Language Name',
                      bg='lightgrey',
                      fg='black',
                      pady=8,
                      font=(20))
        button.pack(side=BOTTOM, fill=X)
        entry.pack(side=BOTTOM, fill=X)
        label.pack(side=TOP, fill=BOTH, anchor=N)

    def removelang(self, entry):
        text = entry.get()
        if text:
            target = None
            for name in self.langname:
                if text.lower() == name.lower():
                    target = name
                    break
            if not target:
                showerror("Not Found", "Language not found")
                return
            self.langmenu.delete(target)
            self.deltab(target)
            self.dialog.destroy()
            showinfo('Deleted', target + " deleted successfully")
        else:
            showerror('Blank', 'You had not entered anything')
예제 #9
0
class App(tk.Tk):
    window = None

    def get_title(self, info):
        return "Музыка {} {} (id{})".format(info["first_name"],
                                            info["last_name"], info["id"])

    def __init__(self, audio_obj, vk_audio, info):
        #initialize self
        if (App.window is not None): return
        super().__init__()
        self.vk_audio = vk_audio
        self.geometry('733x450')
        self.columnconfigure(0, weight=1)

        self.count, self.SortDir, self.player_window = False, True, None

        #initialize notebook
        self.tabs = Notebook(self)
        self.tabs.place(x=0, y=0, relwidth=1, relheight=1)
        self.tabs.bind('<<NotebookTabChanged>>', self.tab_changed)

        self.list = []
        self.add_tab(audio_obj, info)
        App.window = self

    def add_tab(self, audio: vk_audio.Audio, info):
        if (audio in self.list):
            self.tabs.select(self.list.index(audio))
            return
        title = self.get_title(info)
        f = tk.Frame(self.tabs)
        tk.Button(f, text="Закрыть", command=self.on_close_tab_clicked).pack()
        #add_albums_frame
        if (audio.Playlists):
            AlbumsFrame(f, audio.Playlists, self.add_tab_playlist,
                        self.author_clicked).pack(side=tk.TOP,
                                                  fill=tk.BOTH,
                                                  expand=False)
        #add_audios_frame
        AudiosFrame(f, audio.Audios, True).pack(fill=tk.BOTH,
                                                expand=True,
                                                side=tk.BOTTOM)
        self.tabs.add(f, text=title)
        self.list.append(audio)
        self.focus_force()
        self.tabs.select(len(self.list) - 1)
        return self

    def on_close_tab_clicked(self):
        t = self.tabs.select()
        index = self.tabs.tabs().index(t)
        self.list.pop(index)
        if (not self.list): self.destroy()
        self.tabs.forget(t)

    def tab_changed(self, event):
        tab = self.tabs.tab(
            event.widget.index("current"
                               ) if not isinstance(event, int) else event)
        self.title(tab['text'])

    def add_tab_playlist(self, playlist: vk_audio.Playlist):
        if (playlist in self.list):
            self.tabs.select(self.list.index(playlist))
            return
        self.list.append(playlist)
        title = "Плейлист {} (id{})".format(playlist.title, playlist.owner_id)
        f = tk.Frame(self.tabs)
        tk.Button(f, text="Закрыть", command=self.on_close_tab_clicked).pack()

        #region add playlist info
        tk.Label(f, text=playlist.title, font=('times', 16)).pack()

        author = tk.Label(f,
                          text=",".join(i['name']
                                        for i in playlist.author_info),
                          font=AlbumsFrame.DEFAULT_FONT,
                          fg=AlbumsFrame.DEF_FG,
                          cursor="hand2")
        author.pack()
        author.bind("<Button-1>", lambda _: self.author_clicked(playlist))
        author.bind(
            "<Enter>", lambda _: author.config(font=AlbumsFrame.HOVER_FONT,
                                               fg=AlbumsFrame.HOVER_FG))
        author.bind(
            "<Leave>", lambda _: author.config(font=AlbumsFrame.DEFAULT_FONT,
                                               fg=AlbumsFrame.DEF_FG))

        img = tk.Canvas(f, width=160, height=160)
        img.pack(pady=5)

        AlbumsFrame.set_image_from_album(None, img, playlist)
        #endregion
        AudiosFrame(f, playlist.Audios, True).pack(fill=tk.BOTH,
                                                   expand=True,
                                                   side=tk.BOTTOM)
        self.tabs.add(f, text=title)
        self.focus_force()
        self.tabs.select(len(self.list) - 1)

    def author_clicked(self, playlist):
        if (playlist.author_hrefs):
            for i, item in enumerate(self.list):
                if (isinstance(item, vk_audio.Audio)
                        and item.owner_id == playlist.owner_id):
                    self.tabs.select(i)
                    break
            else:
                artist_music = playlist.artist_music(0)

                self.add_tab(
                    artist_music, {
                        "first_name": artist_music.nick,
                        "last_name": "",
                        "id": artist_music.owner_id
                    })
        elif (playlist.owner_id > 0):
            for i, item in enumerate(self.list):
                if (isinstance(item, vk_audio.Audio)
                        and item.owner_id == playlist.owner_id):
                    self.tabs.select(i)
                    break
            else:
                self.add_tab(self.vk_audio.load(playlist.owner_id))

        else:
            messagebox.showerror("Ошибка", "Пока брать музыку у артиста(")

    def destroy(self):
        if (App.window is self):
            App.window = None
        return super().destroy()

    @staticmethod
    def get(item=None, owner_id=None, vk_audio=None, info=None):
        if (item is None and vk_audio is not None):
            item = vk_audio.load(owner_id=owner_id)
        return App(
            audio_obj=item, info=info,
            vk_audio=vk_audio) if App.window is None else App.window.add_tab(
                item, info)
예제 #10
0
파일: cim.py 프로젝트: ZanderBrown/Tiborcim
class CimApp(Frame):
    def __init__(self):
        Frame.__init__(self)
        self.file = None;
        self.master.title("Tiborcim")
        self.master.iconphoto(True, PhotoImage(file=ICON_PNG))
        self.files = []
        self.current_tab = StringVar()
        self.pack(expand=1, fill="both")
        self.master.minsize(300,300)
        self.master.geometry("500x500")

        self.menubar = Menu(self.master)
        self.fileMenu = Menu(self.master, tearoff=0)
        self.fileMenu.add_command(label="New", command=self.new_file,
                                  underline=0, accelerator="Ctrl+N")
        self.fileMenu.add_command(label="Open...", command=self.load_file,
                                  underline=0, accelerator="Ctrl+O")
        self.fileMenu.add_command(label="Save", command=self.file_save,
                                  underline=0, accelerator="Ctrl+S")
        self.fileMenu.add_command(label="Save As...", command=self.file_save_as,
                                  underline=5, accelerator="Ctrl+Alt+S")
        self.fileMenu.add_command(label="Close", command=self.close_file,
                                  underline=0, accelerator="Ctrl+W")
        self.fileMenu.add_separator()
        self.fileMenu.add_command(label="Exit", command=self.file_quit, underline=1)
        self.menubar.add_cascade(label="File", menu=self.fileMenu, underline=0)

        self.edit_program = Menu(self.master, tearoff=0)
        self.edit_program.add_command(label="Undo", command=self.edit_undo,
                                  underline=0, accelerator="Ctrl+Z")
        self.edit_program.add_command(label="Redo", command=self.edit_redo,
                                      underline=0, accelerator="Ctrl+Y")
        self.edit_program.add_separator()
        self.edit_program.add_command(label="Cut",
                                      command=self.edit_cut,
                                      underline=2,
                                      accelerator="Ctrl+X")
        self.edit_program.add_command(label="Copy",
                                      command=self.edit_copy,
                                      underline=0,
                                      accelerator="Ctrl+C")
        self.edit_program.add_command(label="Paste",
                                      command=self.edit_paste,
                                      underline=0,
                                      accelerator="Ctrl+V")
        self.menubar.add_cascade(label="Edit", menu=self.edit_program, underline=0)

        self.menu_program = Menu(self.master, tearoff=0)
        self.menu_program.add_command(label="Convert",
                                      command=self.convert_file,
                                      underline=0,
                                      accelerator="Ctrl+T")
        self.menu_program.add_command(label="Flash",
                                      command=self.flash_file,
                                      underline=0,
                                      accelerator="Ctrl+B")
        self.menu_program.add_separator()
        self.menubar.add_cascade(label="Program", menu=self.menu_program, underline=0)

        self.menu_view = Menu(self.master,
                              tearoff=0)
        self.viewmode = StringVar()
        self.viewmode.set("tiborcim")
        self.menu_view.add_radiobutton(label="Tiborcim",
                                       command=self.view_tiborcim,
                                       variable=self.viewmode,
                                       value="tiborcim",
                                       underline=0)
        self.menu_view.add_radiobutton(label="Python",
                                       command=self.view_python,
                                       variable=self.viewmode,
                                       value="python",
                                       underline=0)
        self.menubar.add_cascade(label="View",
                                 menu=self.menu_view,
                                 underline=0)

        self.menu_help = Menu(self.master,
                              tearoff=0)
        
        self.menu_samples = Menu(self.master, tearoff=0)
        samples = tiborcim.resources.samples_list()
        def add_sample (sample):
            self.menu_samples.add_command(label=sample,
                                          command=lambda: self.help_sample(sample))
        for sample in samples:
            add_sample(sample)
    
        self.menu_help.add_cascade(label="Samples",
                                   menu=self.menu_samples,
                                   underline=0)
        self.menu_help.add_separator()
        self.menu_help.add_command(label="README",
                                   command=self.help_readme,
                                   underline=0)
        self.menu_help.add_separator()
        self.menu_help.add_command(label="About",
                                   command=self.help_about,
                                   underline=0)
        self.menubar.add_cascade(label="Help",
                                 menu=self.menu_help,
                                 underline=0)

        self.master.config(width=450,
                           height=400,
                           menu=self.menubar)

        self.bind_all("<Control-o>", self.load_file)
        self.bind_all("<Control-s>", self.file_save)
        self.bind_all("<Control-Alt-s>", self.file_save_as)
        self.bind_all("<Control-t>", self.convert_file)
        self.bind_all("<Control-b>", self.flash_file)
        self.bind_all("<Control-w>", self.close_file)
        self.master.protocol("WM_DELETE_WINDOW", self.file_quit)

        self.file_tabs = Notebook(self)
        self.file_tabs.bind_all("<<NotebookTabChanged>>", self.file_changed)
        self.file_tabs.pack(expand=1, fill="both")

    def file_changed(self, event):
        if len(self.file_tabs.tabs()) <= 0:
            self.add_file()
            return
        title = str(event.widget.tab(event.widget.index("current"),"text")).upper().strip()
        self.menu_program.delete(3, END)
        for tab in self.file_tabs.tabs():
            tabtext = self.file_tabs.tab(self.file_tabs.index(tab),"text")
            if tabtext.upper().strip() == title:
                self.current_tab.set(tab)        
            self.menu_program.add_radiobutton(label=tabtext, command=self.program_switch,
                                  underline=1, value=tab, variable=self.current_tab)
        if title != "PYTHON" or title != "TIBORCIM":
            if self.current_file().filename is not None:
                self.master.title(self.current_file().get_file() + " - Tiborcim")
            else:
                self.master.title("Tiborcim")
            if str(self.current_file().tab(self.current_file().index("current"),"text")).upper().strip() == "TIBORCIM":
                self.menubar.entryconfig("Edit", state=NORMAL)
            else:
                self.menubar.entryconfig("Edit", state=DISABLED)
            self.viewmode.set(self.current_file().viewmode)
        if title == "PYTHON":
            self.menubar.entryconfig("Edit", state=DISABLED)
            self.current_file().viewmode = "python";
            self.viewmode.set("python");
        if title == "TIBORCIM":
            self.menubar.entryconfig("Edit", state=NORMAL)
            self.current_file().viewmode = "tiborcim";
            self.viewmode.set("tiborcim");

    def add_file(self, file=None):
        filepage = CimFilePage(self.file_tabs)
        if file is None:
            self.file_tabs.add(filepage, text="Unsaved Program")
        else:
            filepage.load_file(file)
            self.file_tabs.add(filepage, text=filepage.get_file())
        self.files.append(filepage)
        self.file_tabs.select(filepage)

    def view_tiborcim(self, event=None):
        self.current_file().view_tiborcim()

    def view_python(self, event=None):
        self.current_file().view_python()

    def program_switch(self):
        self.file_tabs.select(self.current_tab.get())

    def new_file(self, event=None):
        self.add_file()

    def load_file(self, event=None):
        fname = askopenfilename(filetypes=(("Tiborcim", "*.tibas"),("All files", "*.*") ), parent=self.master)
        if fname:
            self.add_file(fname)

    def file_save(self, event=None):
        self.current_file().save_file()
        self.file_tabs.tab(self.current_file(), text=self.current_file().get_file())

    def file_save_as(self, event=None):
        self.current_file().save_file_as()
        self.file_tabs.tab(self.current_file(), text=self.current_file().get_file())

    def convert_file(self, event=None):
        self.current_file().convert_file()

    def current_file(self, event=None):
        return self.files[int(self.file_tabs.index(self.file_tabs.select()))]

    def flash_file(self, event=None):
        from tiborcim.tibc import compiler as tibc
        from tiborcim.tibc import flash
        from tiborcim.tibc import TibcStatus as status
        com = tibc(self.current_file().text_tiborcim.get("1.0", "end"))
        res = flash(''.join(com.output))
        if res is status.SUCCESS:
            showinfo(title='Success', message='File Flashed', parent=self.master)
        else:
            showerror(title='Failure', message='An Error Occured. Code: %s' % res, parent=self.master)

    def close_file(self, event=None):
        logging.debug("Close File")
        file = self.current_file()
        if file.close():
            self.file_tabs.forget(file)
            self.files.remove(file)

    def edit_cut(self, event=None):
        self.current_file().text_tiborcim.event_generate('<Control-x>')

    def edit_copy(self, event=None):
        self.current_file().text_tiborcim.event_generate('<Control-c>')

    def edit_paste(self, event=None):
        self.current_file().text_tiborcim.event_generate('<Control-v>')

    def edit_redo(self, event=None):
        self.current_file().text_tiborcim.edit_redo()
        
    def edit_undo(self, event=None):
        self.current_file().text_tiborcim.edit_undo()

    def help_about(self, event=None):
        CimAbout.show(self)

    def help_readme(self, event=None):
        CimReadme.show(self)

    def help_sample(self, sam):
        print(sam)
        filepage = CimFilePage(self.file_tabs)
        filepage.load_file(tiborcim.resources.sample_path(sam))
        filepage.filename = None
        self.file_tabs.add(filepage, text="Unsaved Program")
        self.files.append(filepage)
        self.file_tabs.select(filepage)

    def file_quit(self, event=None):
        for ndx, member in enumerate(self.files):
            logging.debug(self.files[ndx].saved)
            if not self.files[ndx].close():
                return

        self.quit()
예제 #11
0
class WorkTimer:
    def __init__(self, master):
        # initialize the master
        self.master = master
        master.title("SDL Work Timer")

        # timer counter
        self.timers = 0

        # master dictionary
        # this will contain indexed dictionaries representing instances of
        # the work timer.  Those dictionaries will contain timers so that the clocks remain separate.
        '''
		{
			'notebook1': {
				'masterframe': masterframe, # this is the frame containing the entire timer
				'timer': timerobject, # this is the timer object, holding timer
									  # functions and numbers
				'toggle_button', timer_toggler, # needs to be accessible to alter color
				'date': date_label,
				'hours': hour_label,
				'mins': min_label,
				'secs': second_label,
				'desc': short_text,

				'filename': filename_entry,
				'todo': todo_editor,
				'done': done_editor,
				'notes': notes_editor,
			},
		}
		'''
        self.timer_dict = {}

        self.timerframe = Frame(self.master, padx=10, pady=10)
        self.systemframe = Frame(self.master, padx=10, pady=10)

        self.timer_notebook = Notebook(self.timerframe)

        self.create_timer(self.timer_dict, self.timer_notebook)

        # <> system frame elements <>
        # instantiate system frame elements
        self.new_timer_button = Button(
            self.systemframe,
            width=10,
            text='New timer',
            command=lambda: self.create_timer(self.timer_dict, self.
                                              timer_notebook))
        self.system_label = Label(self.systemframe, text='System:', anchor=W)
        self.system_output = Label(self.systemframe,
                                   text='Loading...',
                                   anchor=W)
        self.system_copyright = Label(
            self.systemframe,
            text='Designed and Developed by Stardust Labs',
            anchor=E)

        # grid system frame elements

        self.system_label.grid(row=0, column=0, sticky=W)
        self.system_output.grid(row=0, column=1)
        self.new_timer_button.grid(row=0, column=2)
        self.system_copyright.grid(row=1, column=0, columnspan=3, sticky=E)

        # grid master elements
        self.timer_notebook.grid()
        self.timerframe.grid(row=0, column=0)
        self.systemframe.grid(row=1, column=0)

        self.tick()

        self.system_output.config(text='Ready')

    def create_timer(self, timer_dict, notebook):
        # name the timer and instantiate it within the master dictionary
        self.timers += 1
        name = 'notebook' + str(self.timers)
        self.timer_dict[name] = {}
        this_timer = self.timer_dict[name]
        this_timer['id'] = self.timers

        # initialize dictionary abstractions
        this_timer['masterframe'] = Frame(notebook, padx=5, pady=5)
        masterframe = this_timer['masterframe']
        this_timer['timer'] = Timer()

        # frames used to contain timer elements
        timerframe = Frame(masterframe, padx=10, pady=10)
        textframe = Frame(masterframe, padx=10, pady=10)

        # <> Timerframe Elements <>

        # instantiate timer buttons
        this_timer['toggle_button'] = Button(
            timerframe,
            width=9,
            text="Start",
            background='#f00',
            command=lambda: this_timer['timer'].toggle_timer(this_timer))
        timer_reset_button = Button(
            timerframe,
            width=9,
            text='Reset',
            command=lambda: this_timer['timer'].reset(this_timer))
        save_timelog_button = Button(
            timerframe,
            width=9,
            text='Save',
            command=lambda: self.save_timelog(this_timer))

        # container frame for output, will be inline with other items
        timer_outputframe = Frame(timerframe)

        # instantiate output items
        date_label = Label(timer_outputframe, text='Date:', anchor=W)
        this_timer['date'] = Label(timer_outputframe,
                                   text=str(this_timer['timer'].output_date))
        hour_label = Label(timer_outputframe, text='Hour:', anchor=W)
        this_timer['hours'] = Label(timer_outputframe,
                                    text=str(this_timer['timer'].output_hour))
        min_label = Label(timer_outputframe, text='Min:', anchor=W)
        this_timer['mins'] = Label(timer_outputframe,
                                   text=str(this_timer['timer'].output_min))
        sec_label = Label(timer_outputframe, text='Sec:', anchor=W)
        this_timer['secs'] = Label(timer_outputframe,
                                   text=str(this_timer['timer'].output_sec))

        # grid output items to timer_outputframe so it can be grid later
        date_label.grid(row=0, column=0, sticky=W)
        hour_label.grid(row=1, column=0, sticky=W)
        min_label.grid(row=2, column=0, sticky=W)
        sec_label.grid(row=3, column=0, sticky=W)
        this_timer['date'].grid(row=0, column=1, sticky=E)
        this_timer['hours'].grid(row=1, column=1, sticky=E)
        this_timer['mins'].grid(row=2, column=1, sticky=E)
        this_timer['secs'].grid(row=3, column=1, sticky=E)

        # instantiate description label and entry
        description_label = Label(timerframe, text='Desc:', anchor=E)
        this_timer['desc'] = Entry(timerframe)

        def change_tab(event,
                       self=self,
                       tab_id=this_timer['id'] - 1,
                       entry=this_timer['desc']):
            return self.update_tab(event, tab_id, entry)

        this_timer['desc'].bind('<KeyRelease>', change_tab)

        # grid timerframe elements
        this_timer['toggle_button'].grid(row=0, column=0, pady=5)
        timer_reset_button.grid(row=1, column=0, pady=5)
        save_timelog_button.grid(row=2, column=0, pady=5)
        timer_outputframe.grid(row=3, column=0, pady=5)
        description_label.grid(row=4, column=0, sticky=W)
        this_timer['desc'].grid(row=5, column=0)

        # <> Textframe Elements <>
        filename_frame = Frame(textframe)
        text_editor_frame = Notebook(textframe)
        text_system_frame = Frame(textframe)

        # instantiate filename_frame elements
        filename_label = Label(filename_frame, text='Filename:')
        this_timer['filename'] = Entry(filename_frame, width=50)

        # grid filename_frame elements
        filename_label.grid(row=0, column=0)
        this_timer['filename'].grid(row=0, column=1)

        # instantiate text editors
        this_timer['todo'] = Text(text_editor_frame,
                                  font=('consolas', '10'),
                                  width=75,
                                  height=17)
        this_timer['done'] = Text(text_editor_frame,
                                  font=('consolas', '10'),
                                  width=75,
                                  height=17)
        this_timer['notes'] = Text(text_editor_frame,
                                   font=('consolas', '10'),
                                   width=75,
                                   height=17)

        # grid text editors and add them to the notebook
        this_timer['todo'].grid(padx=5)
        this_timer['done'].grid(padx=5)
        this_timer['notes'].grid(padx=5)
        text_editor_frame.add(this_timer['todo'], text='TODO')
        text_editor_frame.add(this_timer['done'], text='DONE')
        text_editor_frame.add(this_timer['notes'], text='NOTES')

        # instantiate text system elements
        text_save_button = Button(text_system_frame,
                                  text='Save Report',
                                  command=lambda: self.save_report(this_timer),
                                  anchor=E)
        text_load_button = Button(text_system_frame,
                                  text='Load Report',
                                  command=lambda: self.load_report(this_timer),
                                  anchor=E)

        # grid text system elements
        text_save_button.grid(row=0, column=0, padx=5, pady=5, sticky=E)
        text_load_button.grid(row=0, column=1, padx=5, pady=5, sticky=E)

        # instantiate notebook delete button
        timer_delete_button = Button(
            text_system_frame,
            text='Delete Timer',
            command=lambda: self.destroy_timer(this_timer),
            anchor=E)

        # grid notebook delete button
        timer_delete_button.grid(row=0, column=2, padx=5, pady=5, sticky=E)

        # grid all textframe internal frames
        filename_frame.grid(row=0, column=0)
        text_editor_frame.grid(row=1, column=0)
        text_system_frame.grid(row=2, column=0)

        # grid submaster frames
        timerframe.grid(row=0, column=0)
        textframe.grid(row=0, column=1)

        # add the timer to the main notebook
        this_timer['masterframe'].grid()
        notebook.add(this_timer['masterframe'], text='New Timer')

    def destroy_timer(self, timer):
        name = timer['desc'].get()
        title = 'Deleting timer {timer_name}'.format(timer_name=name)
        message = 'Are you sure you want to delete {timer_name}?'.format(
            timer_name=name)
        destroy = messagebox.askquestion(title, message)
        if destroy:
            self.timer_notebook.forget(timer['masterframe'])

    def save_timelog(self, timer):
        self.system_update(
            'Logging {desc} time...'.format(desc=timer['desc'].get()))
        description = timer['desc'].get()

        time = '{date} {h}:{m}:{s} - {desc}\r\n'.format(
            date=timer['timer'].output_date,
            h=timer['timer'].output_hour,
            m=timer['timer'].output_min,
            s=timer['timer'].output_sec,
            desc=description,
        )

        with open('timelog.txt', 'a') as timelog:
            timelog.write(time)

        self.system_update(
            '{desc} time logged.'.format(desc=timer['desc'].get()))

    def save_report(self, timer):
        self.system_update(
            'Saving {desc} report...'.format(desc=timer['desc'].get()))
        todo_header = '---=== TODO ===---\r\n\r\n'
        done_header = '---=== DONE ===---\r\n\r\n'
        notes_header = '---=== NOTES ===---\r\n\r\n'

        todo_body = timer['todo'].get('1.0', END)
        done_body = timer['done'].get('1.0', END)
        notes_body = timer['notes'].get('1.0', END)

        output_text = '{todo_h}{todo}\r\n\r\n{done_h}{done}\r\n\r\n{notes_h}{notes}'.format(
            todo_h=todo_header,
            todo=todo_body,
            done_h=done_header,
            done=done_body,
            notes_h=notes_header,
            notes=notes_body,
        )

        filename = timer['filename'].get()

        with open('reports/' + filename + '.txt', 'w') as report:
            report.write(output_text)

        self.system_update(
            '{desc} report saved.'.format(desc=timer['desc'].get()))

    def load_report(self, timer):
        self.system_update(
            'Loading {file}'.format(file=timer['filename'].get()))

        filename = timer['filename'].get()

        with open(filename + '.txt', 'r') as report:
            input_text = report.read()

            input_text = input_text.split('---=== DONE ===---')
            todo_text = input_text[0]
            input_text = input_text[1].split('---=== NOTES ===---')
            done_text = input_text[0]
            notes_text = input_text[1]

            todo_text = todo_text.replace('---=== TODO ===---',
                                          '').replace('\r\n', '')
            done_text = done_text.replace('\r\n', '')
            notes_text = notes_text.replace('\r\n', '')

            timer['todo'].delete('1.0', END)
            timer['todo'].insert(END, todo_text)
            timer['done'].delete('1.0', END)
            timer['done'].insert(END, done_text)
            timer['notes'].delete('1.0', END)
            timer['notes'].insert(END, notes_text)

        self.system_update(
            '{file} loaded.'.format(file=timer['filename'].get()))

    def tick(self):
        for work_timer in self.timer_dict:
            self.timer_dict[work_timer]['timer'].tick(
                self.timer_dict[work_timer])
        self.systemframe.after(1000, self.tick)

    def update_tab(self, event, tab_id, entry_widget):
        updated_title = entry_widget.get()
        self.timer_notebook.tab(tab_id, text=updated_title)

    def system_update(self, sys_text):
        self.system_output.config(text=sys_text)
예제 #12
0
class OpeningPage():
    """@summary: Widget servant à lancer la simulation après
                 avoir renseigné les persos
        """
    def __init__(self, fenetre):
        self.notebk = Notebook(fenetre)
        self.fenetre = fenetre
        self.persoViews = []
        self.caracsNotebk = []
        self.framesPersos = []

    def formSubmission(self, _):
        """@summary: Lance la simulation de combat avec les persos du notebook
        """
        persos = []
        for persoVw in self.persoViews:
            persoVw.inputsToPerso()
            persos.append(persoVw.perso)
            writeSaveFile("save.json", persos)
        launchSimu(self.persoViews)

    def addEmptyPage(self, _):
        """@summary: Ajoute un onglet avec un stub perso dans le notebook0
        """
        self.addPage(readSaveFile("./persos/empty.json"))

    def deleteActiveNotePage(self):
        """@summary: Supprime l'onglet actif et les valeurs de personnages
                     associés.
        """
        nomPanneau = self.notebk.tab(self.notebk.select())["text"]
        indPanneau = int(nomPanneau.split(" ")[1])
        self.notebk.forget(self.notebk.select())
        del self.persoViews[indPanneau-1]

    def addPageSorts(self, persoVw, sortsSuppl=[], sortsDebtCombatSuppl=[]):
        tab_names = [persoVw.caracsNotebk.tab(i, option="text") for i in persoVw.caracsNotebk.tabs()]
        if "Sorts" in tab_names:
            persoVw.caracsNotebk.forget(tab_names.index("Sorts"))
        classe = persoVw.perso["Perso"]["Classe"]
        lvl = persoVw.perso["Perso"]["Level"]
        frameSorts = LabelFrame(persoVw.framePerso, text="Sorts")
        sorts, sortsDebtCombat = Personnages.Personnage.chargerSorts(classe, lvl, {}, True)
        sorts += sortsSuppl
        sortsDebtCombat += sortsDebtCombatSuppl
        for extSort in [x for x in persoVw.perso["Sorts"] if "::" in x]:
            classe, nom_sort = extSort.split("::")
            sortsSuppl, sortsDebtCombatSuppl = Personnages.Personnage.chargerSorts(classe, lvl, {nom_sort:1}, False, 1)
            for sortSuppl in sortsSuppl:
                sortSuppl.nom = classe+"::"+nom_sort
            for sortDebtCombatSuppl in sortsDebtCombatSuppl:
                sortDebtCombatSuppl.nom = classe+"::"+nom_sort
            sorts += sortsSuppl
            sortsDebtCombat += sortsDebtCombatSuppl
        self.variantesFrame = ScrolledWindow(frameSorts, width=400, height=400)
        persoVw.sortsLignes = 0
        persoVw.images = []
        if "Sorts" not in persoVw.inputs:
            persoVw.inputs["Sorts"] = dict()
        addedSpells = {}
        for sort in sorts+sortsDebtCombat:
            if not sort.lancableParJoueur:
                continue
            isVariante = sort.nom_variante != "" and sort.nom_variante in addedSpells
            root_pic1 = Image.open(sort.image)                       # Open the image like this first
            persoVw.images.append(ImageTk.PhotoImage(root_pic1))
            if not isVariante:
                persoVw.sortsLignes += 1
            ind = persoVw.sortsLignes
            imgLbl = Label(self.variantesFrame.scrollwindow, image=persoVw.images[-1], anchor="nw")
            imgLbl.grid(row=ind, column=2 if isVariante else 0, sticky="e")
            varSort = IntVar()
            varSort.set(persoVw.perso["Sorts"].get(sort.nom, 0))
            persoVw.inputs["Sorts"][sort.nom] = varSort
            cbSort = Checkbutton(self.variantesFrame.scrollwindow, text=sort.nom, variable=varSort, onvalue=1, offvalue=0, anchor="w")
            cbSort.grid(row=ind, column=3 if isVariante else 1, sticky="w")
            addedSpells[sort.nom] = ind
        
        addSortButton = Button(frameSorts, text="Ajout Sort/Item", command=self.ajoutSort)
        addSortButton.grid()
        persoVw.caracsNotebk.add(frameSorts, text="Sorts")

    def ajoutSort(self):
        nomPanneau = self.notebk.tab(self.notebk.select())["text"]
        indPanneau = int(nomPanneau.split(" ")[1])
        persoVw = self.persoViews[indPanneau-1]
        dialog = ChildDialogChooseSpell(self.fenetre, persoVw)
        self.fenetre.wait_window(dialog.app)
        filename, sort_name = tuple(dialog.rvalue.split("::"))
        perso = persoVw.perso
        classename = os.path.splitext(filename)[0]
        sorts, sortsDebtCombat = Personnages.Personnage.chargerSorts(classename, int(perso["Perso"]["Level"]), {sort_name:1}, False, 0)
        current = persoVw.caracsNotebk.index("current")
        for sort in sorts:
            sort.nom = filename+"::"+sort_name
        for sort in sortsDebtCombat:
            sort.nom = filename+"::"+sort_name
        self.addPageSorts(persoVw, sorts, sortsDebtCombat)
        persoVw.caracsNotebk.select(current)

    def onClassChange(self, event):
        nomPanneau = self.notebk.tab(self.notebk.select())["text"]
        indPanneau = int(nomPanneau.split(" ")[1])
        persoVw = self.persoViews[indPanneau-1]
        self.addPageSorts(persoVw)
        

    def addPage(self, values):
        """@summary: Ajoute un onglet avec les valeurs de personnages données.
        """
        self.persoViews.append(PersoView(values))
        persoVw = self.persoViews[-1]
        self.framesPersos.append(Frame(self.notebk))
        framePerso = self.framesPersos[-1]
        persoVw.framePerso = framePerso
        self.caracsNotebk.append(Notebook(framePerso))
        caracNotebk = self.caracsNotebk[-1]
        caracNotebk.pack()
        persoVw.caracsNotebk = caracNotebk
        for inputsCategory, inputValues in persoVw.perso.items():
            frameCaracs = LabelFrame(framePerso, text=inputsCategory)
            if persoVw.inputs.get(inputsCategory, None) is None:
                persoVw.inputs[inputsCategory] = dict()
            j = 0
            if inputsCategory == "Sorts":
                self.addPageSorts(persoVw)
                continue
            for inputName, inputValue in inputValues.items():
                if inputName == "Classe":
                    classesDisponibles = \
                        Combobox(frameCaracs,
                                 textvariable=StringVar(),
                                 values=["Cra", "Xelor", "Iop", "Sacrieur",
                                         "Sram", "Poutch", "Eniripsa", "Pandawa"],
                                 state='readonly')
                    classesDisponibles.bind('<<ComboboxSelected>>', self.onClassChange)
                    persoVw.inputs[inputsCategory][inputName] = classesDisponibles
                    persoVw.inputs[inputsCategory][inputName].set(inputValue)

                else:
                    persoVw.inputs[inputsCategory][inputName] = \
                        Entry(frameCaracs, textvariable=StringVar(), width=10)
                    persoVw.inputs[inputsCategory][inputName].insert(END, inputValue)
                lblCarac = Label(frameCaracs,
                                 text=inputName+":")
                lblCarac.grid(row=j, column=0)
                persoVw.inputs[inputsCategory][inputName].grid(row=j, column=1)
                j += 1
            caracNotebk.add(frameCaracs, text=inputsCategory)
        # Pack de la fenêtre, détermine la taille de la fenêtre selon la taille des composants.
        #framePerso.pack(fill="both", expand="yes")
        self.notebk.add(framePerso, text="Perso "+str(len(self.persoViews)))
        saveBtn = Button(framePerso, text='Sauvegarder ce perso', command=persoVw.save)
        loadBtn = Button(framePerso, text='Charger un perso', command=persoVw.load)
        deleteThisBtn = Button(framePerso, text="Supprimer ce perso",
                               command=self.deleteActiveNotePage)
        # Mise du bouton sur la droite de la fenetre
        saveBtn.pack(side="left")
        # Mise du bouton sur la droite de la fenetre
        loadBtn.pack(side="left")
        deleteThisBtn.pack(side="left")

    def main(self):
        """@summary: Lance la création des personnages pour ensuite lancer la simulation
        """
        # Créer la fenêtre Tkinter
        values = readSaveFile("save.json")
        self.notebk.pack()

        for inputPerso in values:
            self.addPage(inputPerso)

        self.notebk.enable_traversal()
        # Ajout du bouton pour lancer la simulation
        submit = Button(self.fenetre, text='Lancer la simulation')
        # Permet au gestionnaire d'événement d'ajouter des paramètres
        # Gestionnaire d'événement pour le clic du bouton
        submit.bind("<Button-1>", self.formSubmission)
        # Mise du bouton sur la droite de la fenetre
        submit.pack(side="right")
        addPersoBtn = Button(self.fenetre, text='Ajouter un perso')
        addPersoBtn.bind("<Button-1>", self.addEmptyPage)
        addPersoBtn.pack(side="right")
예제 #13
0
class App(Tk):

    def __init__(self, args):
        Tk.__init__(self)
        self.height = '720'
        self.width = '1280'
        self.Editors = []
        self.Filenames = {}
        self.lexer_selector = self.createLexers()
        self.Lexers = dict()
        self._icon = Image("photo", file='img/notebook/icon.png')

        self.code_font = Font(family="Latin Modern Mono", size=15)
        self.title_font = Font(family="Ubuntu Mono", size=15)
        self.underline_font = Font(underline=True)

        self.MainWindow = Frame(self, background='#282c34')
        self.notebook = Notebook(self)
        self.configureUI()
        self.args = args

        self.awk_img = PhotoImage(file='img/fext/awk.png')
        self.bash_img = PhotoImage(file='img/fext/bash.png')
        self.c_img = PhotoImage(file='img/fext/c.png')
        self.cs_img = PhotoImage(file='img/fext/c#.png')
        self.cmake_img = PhotoImage(file='img/fext/cmake.png')
        self.coffee_img = PhotoImage(file='img/fext/coffee.png')
        self.cpp_img = PhotoImage(file='img/fext/cpp.png')
        self.css_img = PhotoImage(file='img/fext/css.png')
        self.delphi_img = PhotoImage(file='img/fext/delphi.png')
        self.eiffel_img = PhotoImage(file='img/fext/eiffel.png')
        self.erlang_img = PhotoImage(file='img/fext/erlang.png')
        self.fs_img = PhotoImage(file='img/fext/f#.png')
        self.fortran_img = PhotoImage(file='img/fext/fortran.png')
        self.go_img = PhotoImage(file='img/fext/golang.png')
        self.haskell_img = PhotoImage(file='img/fext/haskell.png')
        self.html_img = PhotoImage(file='img/fext/html.png')
        self.java_img = PhotoImage(file='img/fext/java.png')
        self.js_img = PhotoImage(file='img/fext/js.png')
        self.json_img = PhotoImage(file='img/fext/json.png')
        self.kotlin_img = PhotoImage(file='img/fext/kotlin.png')
        self.lisp_img = PhotoImage(file='img/fext/lisp.png')
        self.makefile_img = PhotoImage(file='img/fext/makefile.png')
        self.matlab_img = PhotoImage(file='img/fext/matlab.png')
        self.mysql_img = PhotoImage(file='img/fext/mysql.png')
        self.perl_img = PhotoImage(file='img/fext/perl.png')
        self.php_img = PhotoImage(file='img/fext/php.png')
        self.prolog_img = PhotoImage(file='img/fext/prolog.png')
        self.python_img = PhotoImage(file='img/fext/python.png')
        self.ruby_img = PhotoImage(file='img/fext/ruby.png')
        self.sass_img = PhotoImage(file='img/fext/sass.png')
        self.scala_img = PhotoImage(file='img/fext/scala.png')
        self.swift_img = PhotoImage(file='img/fext/swift.png')
        self.tcl_img = PhotoImage(file='img/fext/tcl.png')
        self.ts_img = PhotoImage(file='img/fext/ts.png')
        self.txt_img = PhotoImage(file='img/fext/txt.png')
        self.verilog_img = PhotoImage(file='img/fext/verilog.png')
        self.vhdl_img = PhotoImage(file='img/fext/vhdl.png')
        self.xml_img = PhotoImage(file='img/fext/xml.png')
        self.yaml_img = PhotoImage(file='img/fext/yaml.png')

        for file_name in self.args:
            self.openFileByName(file_name)

        self.mainloop()

    def configureUI(self):

        self.configureWindow()
        self.configureMenu()
        self.configureNotebook()
        self.contextualMenu()
        self.bindWindowEvents()
        self.configureStatusBar()

    def configureWindow(self):

        self.geometry(self.width+'x'+self.height+'+0+0')
        self.title("Quode-IDE")
        self.wm_iconphoto(False, self._icon)
        self.MainWindow.pack()

    def configureMenu(self):

        self.menu_bar = Menu(self, background='#21252b', foreground='#ffffff')
        self.file_menu = Menu(self.menu_bar, tearoff=0)
        self.file_menu.add_command(label='New Tab',
                                font=self.title_font,
                                command=self.createNewEditor,
                                activebackground='#123456',
                                activeforeground='#ffffff',
                                accelerator='Ctrl + N')
        self.file_menu.add_command(label="Open",
                                font=self.title_font,
                                command=self.openFile,
                                activebackground='#123456',
                                activeforeground='#ffffff',
                                accelerator='Ctrl + O')
        self.file_menu.add_command(label="Save",
                                font=self.title_font,
                                command=self.saveFile,
                                activebackground='#123456',
                                activeforeground='#ffffff',
                                accelerator='Ctrl + S')
        self.file_menu.add_command(label='Remove Tab',
                                font=self.title_font,
                                command=self.removeCurrentEditor,
                                activebackground='#123456',
                                activeforeground='#ffffff',
                                accelerator='Ctrl + R')
        self.file_menu.add_separator()
        self.file_menu.add_command(label="Exit",
                                font=self.title_font,
                                command=self.askQuit,
                                activebackground='#123456',
                                activeforeground='#ffffff',
                                accelerator='Ctrl + Q')
        self.menu_bar.add_cascade(label="File",
                                font=self.title_font,
                                activebackground='#123456',
                                activeforeground='#ffffff',
                                menu=self.file_menu)

        self.edit_menu = Menu(self.menu_bar,
                                tearoff=0,
                                activebackground='#123456')
        self.edit_menu.add_command(label="Cut",
                                font=self.title_font,
                                command=self.cutSelection,
                                activebackground='#123456',
                                activeforeground='#ffffff',
                                accelerator="Ctrl + X")
        self.edit_menu.add_command(label="Copy",
                                font=self.title_font,
                                command=self.copySelection,
                                activebackground='#123456',
                                activeforeground='#ffffff',
                                accelerator="Ctrl + C")
        self.edit_menu.add_command(label="Paste",
                                font=self.title_font,
                                command=self.pasteSelection,
                                activebackground='#123456',
                                activeforeground='#ffffff',
                                accelerator="Ctrl + V")
        self.edit_menu.add_command(label="Replace (All)",
                                font=self.title_font,
                                activebackground='#123456',
                                activeforeground='#ffffff',
                                command=self.replaceAllWindow)
        self.menu_bar.add_cascade(label="Edit",
                                font=self.title_font,
                                activebackground='#123456',
                                activeforeground='#ffffff',
                                menu=self.edit_menu)

        self.view_menu = Menu(self.menu_bar, tearoff=0)
        self.view_menu.add_command(label="Increase Font Size",
                                font=self.title_font,
                                command=self.increaseFontSize,
                                activebackground='#123456',
                                activeforeground='#ffffff',
                                accelerator="Ctrl + +/=")
        self.view_menu.add_command(label="Decrease Font Size",
                                font=self.title_font,
                                command=self.decreaseFontSize,
                                activebackground='#123456',
                                activeforeground='#ffffff',
                                accelerator="Ctrl + -/_")
        self.view_menu.add_command(label="Find",
                                font=self.title_font,
                                command=self.searchWindow,
                                activebackground='#123456',
                                activeforeground='#ffffff',
                                accelerator="Ctrl + f")
        self.view_menu.add_command(label="File tree",
                                font=self.title_font,
                                command=self.showFileTree,
                                activebackground='#123456',
                                activeforeground='#ffffff',
                                accelerator="Ctrl + t")
        self.menu_bar.add_cascade(label="View",
                                font=self.title_font,
                                activebackground='#123456',
                                activeforeground='#ffffff',
                                menu=self.view_menu)

        self.run_menu = Menu(self.menu_bar, tearoff=0)
        self.run_menu.add_command(label='Run',
                                activebackground='#123456',
                                activeforeground='#ffffff',
                                command=self.runCurrentEditor,
                                font=self.title_font)
        self.menu_bar.add_cascade(label='Run',
                                activebackground='#123456',
                                activeforeground='#ffffff',
                                font=self.title_font,
                                menu=self.run_menu)

        self.help_menu = Menu(self.menu_bar, tearoff=0)
        self.help_menu.add_command(label="About",
                                activebackground='#123456',
                                activeforeground='#ffffff',
                                font=self.title_font,
                                command=self.printAbout)
        self.menu_bar.add_cascade(label="Help",
                                font=self.title_font,
                                activebackground='#123456',
                                activeforeground='#ffffff',
                                menu=self.help_menu)
        self.config(menu=self.menu_bar)

    def configureNotebook(self):

        self.notebook.place_configure(relx=0, rely=0, relheight=0.97, relwidth=1)
        self.notebook.enable_traversal()

    def configureStatusBar(self):

        self.status_bar_label = Label(self)
        self.status_bar_label.place_configure(relx=0,
                                            rely=0.97,
                                            relheight=0.03,
                                            relwidth=1)
        self.status_bar_label.config(text=self.getStatusText())


    def langImg(self, ext):

        img = None
        if (ext == '.c'): img = self.c_img
        elif(ext == '.h'): img = self.c_img
        elif(ext == '.cpp'): img = self.cpp_img
        elif(ext == '.hpp'): img = self.cpp_img
        elif(ext == '.css'): img = self.css_img
        elif(ext == '.sass'): img = self.sass_img
        elif(ext == '.yaml'): img = self.yaml_img
        elif(ext == '.yml'): img = self.yaml_img
        elif(ext == '.json'): img = self.json_img
        elif(ext == '.cs'): img = self.cs_img
        elif(ext == '.fs'): img = self.fs_img
        elif(ext == '.e'): img = self.eiffel_img
        elif(ext == '.erl'): img = self.erlang_img
        elif(ext == '.hrl'): img = self.erlang_img
        elif(ext == '.es'): img = self.erlang_img
        elif(ext == '.f03'): img = self.fortran_img
        elif(ext == '.f90'): img = self.fortran_img
        elif(ext == '.F03'): img = self.fortran_img
        elif(ext == '.F90'): img = self.fortran_img
        elif(ext == '.go'): img = self.go_img
        elif(ext == '.hs'): img = self.haskell_img
        elif(ext == '.v'): img = self.verilog_img
        elif(ext == '.vhdl'): img = self.vhdl_img
        elif(ext == '.vhd'): img = self.vhdl_img
        elif(ext == '.html'): img = self.html_img
        elif(ext == '.htm'): img = self.html_img
        elif(ext == '.xhtml'): img = self.html_img
        elif(ext == '.xml'): img = self.xml_img
        elif(ext == '.js'): img = self.js_img
        elif(ext == '.tex'): img = self.ts_img
        elif(ext == '.coffee'): img = self.coffee_img
        elif(ext == '.java'): img = self.java_img
        elif(ext == '.scala'): img = self.scala_img
        elif(ext == '.kt'): img = self.kotlin_img
        elif(ext == '.ktm'): img = self.kotlin_img
        elif(ext == '.kts'): img = self.kotlin_img
        elif(ext == '.lisp'): img = self.lisp_img
        elif(ext == 'make'): img = self.makefile_img
        elif(ext == 'Make'): img = self.makefile_img
        elif(ext == 'cmake'): img = self.cmake_img
        elif(ext == 'CMake'): img = self.cmake_img
        elif(ext == '.m'): img = self.matlab_img
        elif(ext == '.mat'): img = self.matlab_img
        elif(ext == '.dpr'): img = self.delphi_img
        elif(ext == '.perl'): img = self.perl_img
        elif(ext == '.php'): img = self.php_img
        elif(ext == '.pr'): img = self.prolog_img
        elif(ext == '.py'): img = self.python_img
        elif(ext == '.rb'): img = self.ruby_img
        elif(ext == '.sh'): img = self.bash_img
        elif(ext == '.sql'): img = self.mysql_img
        elif(ext == '.mysql'): img = self.mysql_img
        elif(ext == '.tcl'): img = self.tcl_img
        elif(ext == '.awk'): img = self.awk_img
        else: img = self.txt_img

        return img

    def _get_current_editor(self):
        try:
            index = self.notebook.index('current')
            curr_editor = self.Editors[index]

            return curr_editor

        except _tkinter.TclError:
            messagebox.showerror('Error', 'No Editors Opened!!')
            return None

    def createNewEditor(self):

        new_tab_name = askstring('New Tab', 'Enter name of new tab')
        if new_tab_name:
            f_name, ext = os.path.splitext(new_tab_name)
            scrolled_text = ScrolledText(font=self.code_font,
                                        undo=True, tabs=('2c'),
                                        background='#282c34',
                                        insertbackground='#ffffff',
                                        foreground='#abb2a4')

            self.Editors.append(scrolled_text)
            self.Filenames[scrolled_text] = None
            try :
                lexer = self.lexer_selector[ext]
            except KeyError:
                lexer = None
            self.Lexers[scrolled_text] = lexer
            self.notebook.add(scrolled_text,
                            image=self.langImg(ext),
                            text=os.path.split(new_tab_name)[1],
                            compound='left')
            self.notebook.select(scrolled_text)
            self.createTags()
            self.recolorize(None)
            self.setStatusText(self.getStatusText())

            self.miscBindings(scrolled_text)
            scrolled_text.focus_set()
            scrolled_text.edit_reset()

    def openFile(self):

        opened_file_name = fd.askopenfilename(initialdir=".",
                                              title="Select file",
                                              filetypes=(('all files', '*.*'),))
        if not isinstance(opened_file_name, tuple):
            ext = os.path.splitext(opened_file_name)[1]
            scrolled_text = ScrolledText(font=self.code_font,
                                        undo=True, tabs=('2c'),
                                        background='#282c34',
                                        insertbackground='#ffffff',
                                        foreground='#abb2a4')
            self.Editors.append(scrolled_text)
            self.Filenames[scrolled_text] = opened_file_name
            self.notebook.add(scrolled_text,
                                image=self.langImg(ext),
                                text=os.path.split(opened_file_name)[1],
                                compound='left')
            with open(opened_file_name) as f:
                file_text = f.read()
                f.close()
                scrolled_text.insert('end', file_text)

            self.notebook.select(scrolled_text)
            try :
                lexer = self.lexer_selector[ext]
            except KeyError:
                lexer = None
            self.Lexers[scrolled_text] = lexer
            self.createTags()
            self.recolorize(None)
            scrolled_text.focus_set()
            scrolled_text.edit_reset()
            self.miscBindings(scrolled_text)
            self.setStatusText(self.getStatusText())

    def openFileByName(self, path):

        opened_file_name = path
        if opened_file_name[0] != '/':
            opened_file_name  = os.path.dirname(os.path.abspath(__file__)) + '/' + path
        if not os.path.isdir(opened_file_name):
            ext = os.path.splitext(opened_file_name)[1]
            scrolled_text = ScrolledText(font=self.code_font,
                                        undo=True, tabs=('1.28c'),
                                        background='#282c34',
                                        insertbackground='#ffffff',
                                        foreground='#abb2a4')
            self.Editors.append(scrolled_text)
            self.Filenames[scrolled_text] = opened_file_name
            print(opened_file_name)
            self.notebook.add(scrolled_text,
                                image=self.langImg(ext),
                                text=os.path.split(opened_file_name)[1],
                                compound='left')
            with open(opened_file_name) as f:
                file_text = f.read()
                f.close()
                scrolled_text.insert('end', file_text)

            self.notebook.select(scrolled_text)
            try:
                lexer = self.lexer_selector[ext]
            except KeyError:
                lexer = None
            self.Lexers[scrolled_text] = lexer
            self.createTags()
            self.recolorize(None)
            scrolled_text.focus_set()
            scrolled_text.edit_reset()
            self.miscBindings(scrolled_text)
            self.setStatusText(self.getStatusText())

    def saveFile(self):
        try:
            editor_index = self.notebook.index('current')
            curr_editor = self.Editors[editor_index]
            curr_text = curr_editor.get("1.0", "end")
            if self.Filenames[curr_editor] is not None:
                with open(self.Filenames[curr_editor], 'r+') as f:
                    f.write(curr_text)
                    messagebox.showinfo('Save', 'File Saved!!!')
                    curr_editor.edit_reset()

            else:
                new_file_path = fd.asksaveasfilename(initialdir='.',
                                                filetypes=[("All files", "*")])
                if not isinstance(new_file_path, tuple):

                    self.Filenames[curr_editor] = new_file_path
                    new_file = open(new_file_path, 'w+')
                    new_file.close()

                    new_file = open(new_file_path, 'r+')
                    new_file.write(curr_text)
                    messagebox.showinfo('Save', 'File Saved!!!')
                    self.Filenames[curr_editor] = new_file_path
                    curr_editor.edit_reset()

        except _tkinter.TclError:
            messagebox.showerror("Save File", "No file to save")

    def removeCurrentEditor(self):

        try:
            curr_editor = self._get_current_editor()
            if messagebox.askyesno('Remove Current Tab',
                                'Are you sure you want to remove this Editor?',
                                icon='warning'):
                index = self.notebook.select('current')
                self.notebook.forget(index)
                self.Editors.remove(curr_editor)
                self.Filenames.pop(curr_editor, None)
                self.Lexers.pop(curr_editor, None)

        except _tkinter.TclError:
            messagebox.showerror('Remove Tab', 'Oops!! No tabs to remove!!')


    def askQuit(self):

        if messagebox.askyesno('Remove Current Tab',
                            'Do you really wanna Exit?',
                            icon='warning'):
            self.destroy()

    def bindWindowEvents(self):

        self.bind('<Control-n>', func=lambda e:self.createNewEditor())
        self.bind('<Control-o>', func=lambda e:self.openFile())
        self.bind('<Control-s>', func=lambda e:self.saveFile())
        self.bind('<Control-r>', func=lambda e:self.removeCurrentEditor())
        self.bind('<Control-q>', func=lambda e:self.askQuit())
        self.bind('<Control-x>', func=lambda e:self.cutSelection())
        self.bind('<Control-c>', func=lambda e:self.copySelection())
        self.bind('<Control-v>', func=lambda e:self.pasteSelection())
        self.bind('<Control-a>', func=lambda e:self.selectAll())
        self.bind('<Control-f>', func=lambda e:self.searchWindow())
        self.bind('<Control-z>', func=lambda e:self.undoChange())
        self.bind('<Control-y>', func=lambda e:self.redoChange())
        self.bind('<Control-t>', func=lambda e:self.showFileTree())

        self.bind('<Control-N>', func=lambda e:self.createNewEditor())
        self.bind('<Control-O>', func=lambda e:self.openFile())
        self.bind('<Control-S>', func=lambda e:self.saveFile())
        self.bind('<Control-R>', func=lambda e:self.removeCurrentEditor())
        self.bind('<Control-Q>', func=lambda e:self.askQuit())
        self.bind('<Control-X>', func=lambda e:self.cutSelection())
        self.bind('<Control-C>', func=lambda e:self.copySelection())
        self.bind('<Control-V>', func=lambda e:self.pasteSelection())
        self.bind('<Control-A>', func=lambda e:self.selectAll())
        self.bind('<Control-F>', func=lambda e:self.searchWindow())
        self.bind('<Control-Z>', func=lambda e:self.undoChange())
        self.bind('<Control-Y>', func=lambda e:self.redoChange())
        self.bind('<Control-T>', func=lambda e:self.showFileTree())

        self.bind('<Control-plus>', func=lambda e:self.increaseFontSize())
        self.bind('<Control-minus>', func=lambda e:self.decreaseFontSize())
        self.bind('<Control-KP_Add>', func=lambda e:self.increaseFontSize())
        self.bind('<Control-KP_Subtract>', func=lambda e:self.decreaseFontSize())

        self.bind("<Key>", func=lambda e:self.anyKeyBindings(e))
        # self.bind("<Key>", func=lambda e:self.setStatusText(self.getStatusText()))

        self.bind('<Button>', func=lambda e: self.anyButtonBindings(e))
        self.bind('<Button-3>',
                func=lambda e: self.contextual_menu.post(e.x_root, e.y_root))

    def anyKeyBindings(self, event):

        self.recolorize(None)
        self.setStatusText(self.getStatusText())

    def anyButtonBindings(self, event):

        self.contextual_menu.unpost()
        self.setStatusText(self.getStatusText())

    def cutSelection(self):

        curr_editor = self._get_current_editor()
        curr_editor.event_generate('<<Cut>>')

    def copySelection(self):

        curr_editor = self._get_current_editor()
        curr_editor.event_generate('<<Copy>>')

    def pasteSelection(self):

        curr_editor = self._get_current_editor()
        curr_editor.event_generate('<<Paste>>')

    def contextualMenu(self):

        self.contextual_menu = Menu(self, tearoff=False)

        self.contextual_menu.add_command(label='New Editor',
                                        command=self.createNewEditor)
        self.contextual_menu.add_command(label='Open File',
                                        command=self.openFile)
        self.contextual_menu.add_command(label='Save Editor',
                                        command=self.saveFile)
        self.contextual_menu.add_separator()
        self.contextual_menu.add_command(label='Remove Editor',
                                        command=self.removeCurrentEditor)
        self.contextual_menu.add_command(label='Change title',
                                        command=self.changeEditorTitle)

    def unpostContextMenu(self):

        self.contextual_menu.unpost()

    def changeEditorTitle(self):

        curr_editor = self._get_current_editor()
        new_title = askstring('New Editor', "Enter new title")
        new_ext = os.path.splitext(new_title)[1]
        self.notebook.tab(curr_editor,
                        text=new_title,
                        image=self.langImg(new_ext))
        try :
            new_lexer = self.lexer_selector[new_ext]
        except KeyError:
            new_lexer = None
        self.Lexers[curr_editor] = new_lexer
        self.recolorize(None)

    def increaseFontSize(self):

        curr_editor = self._get_current_editor() # FIXME
        curr_font = Font(curr_editor, curr_editor.cget("font"))
        curr_size = curr_font.cget('size')
        new_size = curr_size+1
        curr_font.configure(size=new_size)
        new_font = curr_font
        curr_editor.configure(font=new_font)

        # print(Font(curr_editor, curr_editor.cget("font")).cget("size"))

    def decreaseFontSize(self):

        curr_editor = self._get_current_editor() # FIXME
        curr_font = Font(curr_editor, curr_editor.cget("font"))
        curr_size = curr_font.cget('size')
        if curr_size > 1:
            new_size = curr_size-1
            curr_font.configure(size=new_size)

    def undoChange(self):
        try:

            curr_editor = self._get_current_editor()
            curr_editor.edit_undo()
            self.createTags()
            self.recolorize(None)
        except _tkinter.TclError:
            pass

    def redoChange(self):
        try:
            curr_editor = self._get_current_editor()
            curr_editor.edit_redo()
        except _tkinter.TclError:
            pass

    def selectAll(self):
        curr_editor = self._get_current_editor()
        curr_editor.tag_add('sel', '1.0', 'end')
        return "break"

    def searchWindow(self):

        self.search_window = SearchWindow(self, 0)

    def removeAllTags(self):

        curr_editor = self._get_current_editor()
        for tag in curr_editor.tag_names():
            curr_editor.tag_delete(tag)

    def replaceAllWindow(self):

        self.replace_window = ReplaceTextWindow(self)

    def replaceAll(self, a, b):

        curr_editor = self._get_current_editor()
        start = "1.0"
        text = curr_editor.get(start, "end")
        if curr_editor:
            pos = curr_editor.search(a, start, stopindex="end")

            while pos:
                length = len(text)
                row, col = pos.split('.')
                end = int(col) + length
                end = row + '.' + str(end)
                curr_editor.tag_add('found', pos, end)
                start = end
                pos = curr_editor.search(a, start, stopindex="end")
            replaced = 0
            if a:
                coordinates = []
                index_list = list(curr_editor.tag_ranges("found"))
                index_list.reverse()
                while index_list:
                    coordinates.append([index_list.pop(), index_list.pop()])
                for start, end in coordinates:
                    curr_editor.delete(start, end)
                    curr_editor.insert(start, b)
                    replaced += 1
                curr_editor.tag_delete("found")
                return replaced

    def createTags(self):
        curr_editor = self._get_current_editor()
        bold_font = Font(curr_editor, curr_editor.cget("font"))
        bold_font.configure(weight='bold')

        italic_font = Font(curr_editor, curr_editor.cget("font"))
        italic_font.configure(slant='italic')

        bold_italic_font = Font(curr_editor, curr_editor.cget("font"))
        bold_italic_font.configure(weight='bold', slant='italic')

        style = get_style_by_name('default')
        for ttype, ndef in style:
            tag_font = None
            if ndef['bold'] and ndef['italic']:
                tag_font = bold_italic_font
            elif ndef['bold']:
                tag_font = bold_font
            elif ndef['italic']:
                tag_font = italic_font

            if ndef['color']:
                foreground = "#%s" % ndef['color']
            else:
                foreground = None

            curr_editor.tag_configure(str(ttype),
                                    foreground=foreground,
                                    font=tag_font)

    def recolorize(self, event):

        if len(self.Editors) != 0:
            curr_editor = self._get_current_editor()
            code = curr_editor.get("1.0", "end-1c")
            lexer = self.Lexers[curr_editor]
            if lexer is not None:
                tokensource = lexer.get_tokens(text=code)
                start_line = 1
                start_index = 0
                end_line = 1
                end_index = 0
                for ttype, value in tokensource:
                    if "\n" in value:
                        end_line += value.count("\n")
                        end_index = len(value.rsplit("\n", 1)[1])
                    else:
                        end_index += len(value)

                    if value not in (" ", "\n"):
                        index1 = "%s.%s" % (start_line, start_index)
                        index2 = "%s.%s" % (end_line, end_index)

                        for tagname in curr_editor.tag_names(index1):
                            curr_editor.tag_remove(tagname, index1, index2)

                        curr_editor.tag_add(str(ttype), index1, index2)

                    start_line = end_line
                    start_index = end_index

            # self.underlineComplement()

    def createLexers(self):

        lex = {}
        lex['.c'] = CFamilyLexer()
        lex['.h'] = CFamilyLexer()
        lex['.cpp'] = CppLexer()
        lex['.hpp'] = CppLexer()
        lex['.css'] = CssLexer()
        lex['.sass'] = SassLexer()
        lex['.yaml'] = YamlLexer()
        lex['.yml'] = YamlLexer()
        lex['.json'] = JsonLexer()
        lex['.cs'] = CSharpLexer()
        lex['.fs'] = FSharpLexer()
        lex['.e'] = EiffelLexer()
        lex['.erl'] = ErlangLexer()
        lex['.hrl'] = ErlangLexer()
        lex['.es'] = ErlangLexer()
        lex['.f03'] = FortranLexer()
        lex['.f90'] = FortranLexer()
        lex['.F03'] = FortranLexer()
        lex['.F90'] = FortranLexer()
        lex['.go'] = GoLexer()
        lex['.hs'] = HaskellLexer()
        lex['.v'] = VerilogLexer()
        lex['.vhdl'] = VhdlLexer()
        lex['.vhd'] = VhdlLexer()
        lex['.html'] = HtmlLexer()
        lex['.htm'] = HtmlLexer()
        lex['.xhtml'] = HtmlLexer()
        lex['.xml'] = XmlLexer()
        lex['.js'] = JavascriptLexer()
        lex['.tex'] = TypeScriptLexer()
        lex['.coffee'] = CoffeeScriptLexer()
        lex['.java'] = JavaLexer()
        lex['.scala'] = ScalaLexer()
        lex['.kt'] = KotlinLexer()
        lex['.ktm'] = KotlinLexer()
        lex['.kts'] = KotlinLexer()
        lex['.lisp'] = CommonLispLexer()
        lex['make'] = MakefileLexer()
        lex['Make'] = MakefileLexer()
        lex['CMake'] = CMakeLexer()
        lex['cmake'] = CMakeLexer()
        lex['.m'] = MatlabLexer()
        lex['.mat'] = MatlabLexer()
        lex['.dpr'] = DelphiLexer()
        lex['.perl'] = PerlLexer()
        lex['.php'] = PhpLexer()
        lex['.pr'] = PrologLexer()
        lex['.py'] = Python3Lexer()
        lex['.rb'] = RubyLexer()
        lex['.sh'] = BashLexer()
        lex['.sql'] = MySqlLexer()
        lex['.mysql'] = MySqlLexer()
        lex['.tcl'] = TclLexer()
        lex['.awk'] = AwkLexer()

        return lex

    def getStatusText(self):

        if len(self.Editors):
            curr_editor = self._get_current_editor()
            cursor_position = curr_editor.index('insert')
            if cursor_position is not None:
                row, col = cursor_position.split('.')
                return "Row: %s Col: %s"%(row, col)
            else:
                return "Quode-IDE"
        else:
            return "Quode-IDE"

    def setStatusText(self, text):

        if len(self.Editors):
            self.status_bar_label.config(text=text)
        else:
            self.status_bar_label.config(text="Quode-IDE")

    def miscBindings(self, scrolled_text):

        scrolled_text.bind('<Control-z>', func=self.undoChange)
        scrolled_text.bind('<Control-y>', func=self.redoChange)
        scrolled_text.bind('<KeyRelease-quoteright>',
                           func=lambda e: self.completeQuoteright(scrolled_text))
        scrolled_text.bind('<KeyRelease-quotedbl>',
                           func=lambda e: self.completeQuotedbl(scrolled_text))
        scrolled_text.bind('<KeyRelease-parenleft>',
                           func=lambda e: self.completeParen(scrolled_text))
        scrolled_text.bind('<KeyRelease-bracketleft>',
                           func=lambda e: self.completeBracket(scrolled_text))
        scrolled_text.bind('<KeyRelease-braceleft>',
                           func=lambda e: self.completeBrace(scrolled_text))
        scrolled_text.bind('<KeyRelease-less>',
                           func=lambda e: self.completeAngles(scrolled_text))
        scrolled_text.bind('<KeyRelease-Return>',
                           func=lambda e: self.returnNewLine(scrolled_text))

        scrolled_text.bind('<parenright>',
                           func=lambda e: self.skipRParen(scrolled_text))
        scrolled_text.bind('<bracketright>',
                           func=lambda e: self.skipRBracket(scrolled_text))
        scrolled_text.bind('<braceright>',
                           func=lambda e: self.skipRBrace(scrolled_text))
        scrolled_text.bind('<greater>',
                           func=lambda e: self.skipRAngle(scrolled_text))
        scrolled_text.bind('<BackSpace>',
                           func=lambda e: self.erasePair(scrolled_text))

    def completeParen(self, scrolled_text):
        scrolled_text.mark_gravity('insert', 'left')
        scrolled_text.insert('insert', ')')
        scrolled_text.mark_gravity('insert', 'right')
        self.recolorize(None)

    def completeBracket(self, scrolled_text):

        scrolled_text.mark_gravity('insert', 'left')
        scrolled_text.insert('insert', ']')
        scrolled_text.mark_gravity('insert', 'right')
        self.recolorize(None)

    def completeBrace(self, scrolled_text):

        scrolled_text.mark_gravity('insert', 'left')
        scrolled_text.insert('insert', '}')
        scrolled_text.mark_gravity('insert', 'right')
        self.recolorize(None)

    def completeQuoteright(self, scrolled_text):

        scrolled_text.mark_gravity('insert', 'left')
        scrolled_text.insert('insert', '\'')
        scrolled_text.mark_gravity('insert', 'right')
        self.recolorize(None)

    def completeQuotedbl(self, scrolled_text):

        scrolled_text.mark_gravity('insert', 'left')
        scrolled_text.insert('insert', '"')
        scrolled_text.mark_gravity('insert', 'right')
        self.recolorize(None)

    def completeAngles(self, scrolled_text):

        scrolled_text.mark_gravity('insert', 'left')
        scrolled_text.insert('insert', '>')
        scrolled_text.mark_gravity('insert', 'right')
        self.recolorize(None)

    def returnNewLine(self, scrolled_text):

        curr_editor = self._get_current_editor()
        cursor_position = curr_editor.index('insert')

        row_index = int(cursor_position.split('.')[0])
        prev_row_index = str(row_index - 1) + '.0'
        prev_line = curr_editor.get(prev_row_index, prev_row_index + ' lineend')
        this_line = curr_editor.get(cursor_position + ' linestart', cursor_position + ' lineend')
        if(len(prev_line) > 1):
            left_char = prev_line[-1]

            new_line = ''.join(self.notAlphaLine(prev_line))

            if len(this_line) > 0:
                right_char = this_line[0]
                if self._are_braces_paired(left_char, right_char):
                    curr_editor.insert('insert', new_line + '\t')
                    curr_editor.mark_gravity('insert', 'left')
                    curr_editor.insert('insert', '\n\t')
                    curr_editor.mark_gravity('insert', 'right')
            else:
                curr_editor.insert('insert', new_line)
        elif(len(prev_line) == 1):
            if(len(this_line) == 0):
                if (prev_line == '\t'):
                    curr_editor.insert('insert', '\t')
            if(len(this_line) > 0):
                left_char = prev_line[0]
                right_char = this_line[0]
                if self._are_braces_paired(left_char, right_char):
                    curr_editor.insert('insert', '\t')
                    curr_editor.mark_gravity('insert', 'left')
                    curr_editor.insert('insert', '\n')
                    curr_editor.mark_gravity('insert', 'right')

    def _are_braces_paired(self, lchar, rchar):

        if(lchar == '(' and rchar == ')'):
            return True
        if(lchar == '[' and rchar == ']'):
            return True
        if(lchar == '{' and rchar == '}'):
            return True
        return False

    def notAlphaLine(self, line):

        new_line = []
        line = ''.join(line)
        for char in line:
            if (char == ' ' or char == '\t'):
                new_line.append(char)
            else:
                return new_line
        return new_line

    def skipRParen(self, scrolled_text):
        try:
            cursor_position = scrolled_text.index('insert')
            row, col = map(int, cursor_position.split('.'))
            next_position = str(row) + '.' + str(col+1)
            if scrolled_text.get(cursor_position, next_position) == ')':
                scrolled_text.delete(cursor_position, next_position)
        except:
            pass

    def skipRBracket(self, scrolled_text):
        try:
            cursor_position = scrolled_text.index('insert')
            row, col = map(int, cursor_position.split('.'))
            next_position = str(row) + '.' + str(col+1)
            if scrolled_text.get(cursor_position, next_position) == ']':
                scrolled_text.delete(cursor_position, next_position)
        except:
            pass

    def skipRBrace(self, scrolled_text):
        try:
            cursor_position = scrolled_text.index('insert')
            row, col = map(int, cursor_position.split('.'))
            next_position = str(row) + '.' + str(col+1)
            if scrolled_text.get(cursor_position, next_position) == '}':
                scrolled_text.delete(cursor_position, next_position)
        except:
            pass

    def skipRAngle(self, scrolled_text):
        try:
            cursor_position = scrolled_text.index('insert')
            row, col = map(int, cursor_position.split('.'))
            next_position = str(row) + '.' + str(col+1)
            if scrolled_text.get(cursor_position, next_position) == '>':
                scrolled_text.delete(cursor_position, next_position)
        except:
            pass

    def erasePair(self, scrolled_text):

        try:
            cursor_position = scrolled_text.index('insert')
            row, col = map(int, cursor_position.split('.'))
            prev_position = str(row) + '.' + str(col-1)
            next_position = str(row) + '.' + str(col+1)
            curr_char = scrolled_text.get(cursor_position, next_position)
            prev_char = scrolled_text.get(prev_position, cursor_position)
            if curr_char == ')' and prev_char == '(':
                scrolled_text.delete(cursor_position, next_position)
            if curr_char == ']' and prev_char == '[':
                scrolled_text.delete(cursor_position, next_position)
            if curr_char == '}' and prev_char == '{':
                scrolled_text.delete(cursor_position, next_position)
            if curr_char == '>' and prev_char == '<':
                scrolled_text.delete(cursor_position, next_position)
        except:
            pass

    def runCurrentEditor(self):
        if len(self.Editors):
            curr_editor = self._get_current_editor()
            if self.Filenames[curr_editor] is not None:
                os.system('gnome-terminal --working-directory=%s' % os.path.dirname(self.Filenames[curr_editor]))
            else:
                messagebox.showerror(title="Could Not Open Terminal",
                                    message="Please save the File to run it")

    def showFileTree(self):

        if len(self.Editors):
            curr_editor = self._get_current_editor()
            directory = os.path.dirname(self.Filenames[curr_editor])
            FileTree(curr_editor, directory)

    def printAbout(self):

        about = """


   qqqqq                           dd                    ii  ddddddd     eeeeeee
  qqq qqq                          dd                    ii  dd     dd   ee
 qqq   qqq                         dd                    ii  dd      dd  ee
qqq     qqq                        dd                    ii  dd      dd  ee
qqq     qqq uu    uu    oo      ddddd   eeeee            ii  dd      dd  eeeeeee
qqq     qqq uu    uu  oo  oo   dd  dd  ee   ee           ii  dd      dd  ee
qqq     qqq uu    uu oo    oo dd   dd ee     ee  zzzzz   ii  dd      dd  ee
 qqq   qqq  uu    uu oo    oo dd   dd eeeeeeeee          ii  dd      dd  ee
  qqq qqq   uu    uu  oo  oo  dd   dd  ee                ii  dd    dd    ee
   qqqqq      uuuu      oo      ddddd   eeeeee           ii  dddddd      eeeeeee
       qqqqqq


       Quode-IDE(Integrated Development Environment)

       Author : Yash Khasbage


DISCLAIMER:

    Identifiers used in this software are purely fictious and bear no
    resembalance to any person living or dead. Any resembalace is purely
    co-incidental.

    No animals were harmed in coding of this software.

        """
        print(about)
        messagebox.showinfo(title="About", message="Check terminal")

    def _get_int_row_col(self):

        curr_editor = self._get_current_editor()
        return list(map(int, curr_editor.index('insert').split('.')))

    def _get_str_row_col(self):

        curr_editor = self._get_current_editor()
        return curr_editor.index('insert')

    def _str_to_int(self, pos):

        return list(map(int, pos.split('.')))

    def _get_current_char(self):

        row, col = self._get_int_row_col()
        curr_pos = str(row)+'.'+str(col)
        next_pos = str(row)+'.'+str(col+1)
        curr_editor = self._get_current_editor()
        return curr_editor.get(curr_pos, next_pos)

    def _next_position(self, pos):
        row, col = list(map(int, pos.split('.')))
        return '%d.%d'%(row, col+1)

    def underlineComplement(self):

        if len(self.Editors):

            pos = self._get_str_row_col()
            curr_char = self._get_current_char()
            if(curr_char == '('):
                self.underlineRParen(pos)
            elif(curr_char == ')'):
                self.underlineLParen(pos)
            elif(curr_char == '['):
                self.underlineRBracket(pos)
            elif(curr_char == ']'):
                self.underlineLBracket(pos)
            elif(curr_char == '{'):
                self.underlineRBrace(pos)
            elif(curr_char == '}'):
                self.underlineLBrace(pos)
            elif(curr_char == '<'):
                self.underlineRAngle(pos)
            elif(curr_char == '>'):
                self.underlineLAngle(pos)

    def underlineRParen(self, l_pos):
        return
        curr_editor = self._get_current_editor()
        text = curr_editor.get(l_pos, 'end')
        count = 0
        index = 0
        for i in range(len(text)):
            if(text[i] == ')' and count == 0):
                index = i
            elif(text[i] == '('):
                count += 1
            elif(text[i] == ')'):
                count -= 1
        j = 0
        line = self._str_to_int(l_pos)[0]
        line_number = 0
        start = l_pos
        end = '%d.end' % line
        j_prev = 0
        while(index > j):
            j_prev = j
            j += len(curr_editor.get(start, end)) - 1
            line_number += 1
            start = "%d.0" % (line+line_number)
        r_paren_index = '%d.%d' % (line+line_number, index-j_prev)
        print("index", index)
        print("j", j)
        print("linenumber", line_number)
        print("r_paren_index", r_paren_index)
        curr_editor.tag_add('underline',
                            l_pos,
                            self._next_position(l_pos))
        curr_editor.tag_add('underline',
                            r_paren_index,
                            self._next_position(r_paren_index))
        curr_editor.tag_configure('underline', underline=True)


    def underlineLParen(self, r_pos):

        pass

    def underlineRBracket(self, l_pos):

        pass

    def underlineLBracket(self, r_pos):

        pass

    def underlineRbrace(self, l_pos):

        pass

    def underlineLBrace(self, r_pos):

        pass

    def underlineRAngle(self, l_pos):

        pass

    def underlineLAngle(self, r_pos):

        pass
예제 #14
0
class MainApp(Tk):

    def __init__(self):
        Tk.__init__(self)
        self.notebook = Notebook(self)
        self.wm_title("Sensitivity Analysis Tool")
        self.notebook.grid()
        self.construct_home_tab()
        
        self.simulations = []
        self.current_simulation = None
        self.current_tab = None
        self.abort = Value('b', False)
        self.abort_univar_overall = Value('b', False)
        self.simulation_vars = {}
        self.attributes("-topmost", True)
        self.tot_sim_num = 0
        self.sims_completed = Value('i',0)
        self.start_time = None
        self.univar_plot_counter = 1
        self.finished_figures = []
        self.univar_row_num=0
        self.last_results_plotted = None
        self.last_update = None


    def construct_home_tab(self):
        self.home_tab = Frame(self.notebook)
        self.notebook.add(self.home_tab, text = 'Home')
        Button(self.home_tab, 
        text='Upload Excel Data',
        command=self.open_excel_file).grid(row=0,column=1, sticky = E, pady = 5,padx = 5)
        self.input_csv_entry = Entry(self.home_tab)
        self.input_csv_entry.grid(row=0, column=2)
        
        Button(self.home_tab, 
              text="Upload Aspen Model",
              command=self.open_aspen_file).grid(row=1, column = 1,sticky = E,
              pady = 5,padx = 5)
        self.aspen_file_entry = Entry(self.home_tab)
        self.aspen_file_entry.grid(row=1, column=2,pady = 5,padx = 5)
        
        Button(self.home_tab, 
              text="Upload Excel Model",
              command=self.open_solver_file).grid(row=2,column = 1,sticky = E,
              pady = 5,padx = 5)
        self.excel_solver_entry = Entry(self.home_tab)
        self.excel_solver_entry.grid(row=2, column=2,pady = 5,padx = 5)
        
        Button(self.home_tab, 
              text="Load Data",
              command=self.make_new_tab).grid(row=5,column = 3,sticky = E,
              pady = 5,padx = 5)
        
        self.analysis_type = StringVar(self.home_tab)
        self.analysis_type.set("Choose Analysis Type")
        
        OptionMenu(self.home_tab, self.analysis_type,"Single Point Analysis","Univariate Sensitivity", 
                "Multivariate Sensitivity").grid(row = 5,sticky = E,column = 2,padx =5, pady = 5)
        
        Label(self.home_tab, text='CPU Core Count :').grid(row=3, column=1, sticky=E)
        self.num_processes_entry = Entry(self.home_tab)
        self.num_processes_entry.grid(row=3, column=2, pady=5, padx=5)

    def make_new_tab(self):
        if self.current_tab:
            self.notebook.forget(self.current_tab)
            self.current_tab = None
        if self.analysis_type.get() == 'Choose Analysis Type':
            print("ERROR: Select an Analysis Type")
        elif self.analysis_type.get() == 'Univariate Sensitivity':
            self.current_tab = Frame(self.notebook)
            self.notebook.add(self.current_tab,text = "Univariate Analysis")
            ##############Tab 2 LABELS##################
            
            Label(self.current_tab, 
                  text="Save As :").grid(row=4, column= 1, sticky = E,pady = 5,padx = 5)
            self.save_as_entry= Entry(self.current_tab)
            self.save_as_entry.grid(row=4, column=2,pady = 5,padx = 5)
            
            Label(self.current_tab,text = ".csv").grid(row = 4, column = 3, sticky = W)
            
            Label(self.current_tab, text ='').grid(row= 13, column =1)
            Button(self.current_tab,
                   text='Run Univariate Sensitivity Analysis',
                   command=self.initialize_univar_analysis).grid(row=14,
                   column=3, columnspan=2,
                   pady=4)
            Button(self.current_tab,
                   text='Display Variable Distributions',
                   command=self.plot_init_dist).grid(row=14,
                   column=1, columnspan=2, sticky = W,
                   pady=4)
            Button(self.current_tab,
                   text='Fill  # Trials',
                   command=self.fill_num_trials).grid(row=7, columnspan = 2, sticky =E,
                   column=1,
                   pady=4)
            self.fill_num_sims = Entry(self.current_tab)
            self.fill_num_sims.grid(row=7,column = 3,sticky =W, pady =2, padx = 2)
            self.fill_num_sims.config(width = 10)
            
            self.options_box = Labelframe(self.current_tab, text='Run Options:')
            self.options_box.grid(row = 15,column = 3, pady = 10,padx = 10)
    
            Button(self.options_box, text = "Next Variable", command=self.abort_sim).grid(
                    row=6,columnspan = 1, column = 2, sticky=W)
            
            Button(self.options_box, text = "Abort", command=self.abort_univar_overall_fun).grid(
                    row= 6,columnspan = 1, column = 3, sticky=W)
        elif  self.analysis_type.get() == 'Single Point Analysis':
            self.current_tab = Frame(self.notebook)
            self.notebook.add(self.current_tab, text = 'Single Point')
             
            Label(self.current_tab, 
                  text="Save As :").grid(row=0, column= 0, sticky = E,pady = 5,padx = 5)
            self.save_as_entry = Entry(self.current_tab)
            self.save_as_entry.grid(row=0, column=1,pady = 5,padx = 5)
            
            Button(self.current_tab, text='Calculate MFSP',
            command=self.initialize_single_point).grid(row=7,
            column=1, columnspan=2, pady=4)
            
        elif  self.analysis_type.get() == 'Multivariate Sensitivity':
            self.current_tab = Frame(self.notebook)
            self.notebook.add(self.current_tab,text = "Multivariate Analysis")
    
            Label(self.current_tab, 
                  text="Number of Simulations :").grid(row=3, column= 1, sticky = E,pady = 5,padx = 5)
            self.num_sim_entry = Entry(self.current_tab)
            self.num_sim_entry.grid(row=3, column=2,pady = 5,padx = 5)
            
            Label(self.current_tab, 
                  text="Save As :").grid(row=4, column= 1, sticky = E,pady = 5,padx = 5)
            self.save_as_entry = Entry(self.current_tab)
            self.save_as_entry.grid(row=4, column=2,pady = 5,padx = 5)
            
            Label(self.current_tab,text = ".csv").grid(row = 4, column = 3, sticky = W)
                   
            Button(self.current_tab,
                   text='Run Multivariate Analysis',
                   command=self.initialize_multivar_analysis).grid(row=6,
                   column=3, columnspan=2, sticky=W, pady=4)
            Button(self.current_tab,
                   text='Display Variable Distributions',
                   command=self.plot_init_dist).grid(row=6,
                   column=1, columnspan=2, sticky=W, pady=4)
            
        self.load_variables_into_GUI()
        self.notebook.select(self.current_tab)
        
    def load_variables_into_GUI(self):
        sens_vars = str(self.input_csv_entry.get())
        single_pt_vars = []
        univariate_vars = []
        multivariate_vars = []
        type_of_analysis = self.analysis_type.get()
        with open(sens_vars) as f:
            reader = DictReader(f)# Skip the header row
            for row in reader:
                if row['Toggle'].lower().strip() == 'true':          
                    if type_of_analysis =='Single Point Analysis':
                        single_pt_vars.append((row["Variable Name"], float(row["Range of Values"].split(',')[0].strip())))
                    elif type_of_analysis == 'Multivariate Analysis':
                        multivariate_vars.append(row["Variable Name"])
                    else:
                        univariate_vars.append((
                                row["Variable Name"], row["Format of Range"].strip().lower(
                                        ), row['Range of Values'].split(',')))
                        
        #now populate the gui with the appropriate tab and variables stored above
        if type_of_analysis == 'Single Point Analysis':
            self.current_tab.config(width = '5c', height = '5c')
            self.sp_value_entries = {}
            
            # Create a frame for the canvas with non-zero row&column weights
            frame_canvas = Frame(self.current_tab)
            frame_canvas.grid(row=2, column=1, pady=(5, 0))
            frame_canvas.grid_rowconfigure(0, weight=1)
            frame_canvas.grid_columnconfigure(0, weight=1)
            frame_canvas.config(height = '5c')
            
            # Add a canvas in the canvas frame
            canvas = Canvas(frame_canvas)
            canvas.grid(row=0, column=0, sticky="news")
            canvas.config(height = '5c')
            # Link a scrollbar to the canvas
            vsb = Scrollbar(frame_canvas, orient="vertical", command=canvas.yview)
            vsb.grid(row=0, column=1,sticky = 'ns')
            canvas.configure(yscrollcommand=vsb.set)
            
            # Create a frame to contain the variables
            frame_vars = Frame(canvas)
            canvas.create_window((0, 0), window=frame_vars, anchor='nw')
            frame_vars.config(height = '5c')
            
            self.sp_row_num = 0
            for name,value in single_pt_vars:
                self.sp_row_num += 1
                key = str(self.sp_row_num)
                Label(frame_vars, 
                text= name).grid(row=self.sp_row_num, column= 1, sticky = E,pady = 5,padx = 5)
                key=Entry(frame_vars)
                key.grid(row=self.sp_row_num, column=2,pady = 5,padx = 5)
                key.delete(first=0,last=END)
                key.insert(0,str(value))
                self.sp_value_entries[name]= key
                
            # Determine the size of the Canvas
            frame_vars.update_idletasks()
            frame_canvas.config(width='5c', height='10c')
            # Set the canvas scrolling region
            canvas.config(scrollregion=canvas.bbox("all"))
    
        if type_of_analysis == 'Univariate Sensitivity':
            self.univar_ntrials_entries = {}
            Label(self.current_tab, 
                text= 'Variable Name').grid(row=8, column= 1,pady = 5,padx = 5, sticky= E)
            Label(self.current_tab, 
                text= 'Sampling Type').grid(row=8, column= 2,pady = 5,padx = 5, sticky=E)
            Label(self.current_tab, 
                text= '# of Trials').grid(row=8, column= 3,pady = 5,padx = 5)
            # Create a frame for the canvas with non-zero row&column weights
            frame_canvas1 = Frame(self.current_tab)
            frame_canvas1.grid(row=9, column=1, columnspan =3, pady=(5, 0))
            frame_canvas1.grid_rowconfigure(0, weight=1)
            frame_canvas1.grid_columnconfigure(0, weight=1)
            frame_canvas1.config(height = '3c')
            
            # Add a canvas in the canvas frame
            canvas1 = Canvas(frame_canvas1)
            canvas1.grid(row=0, column=0, sticky="news")
            canvas1.config(height = '3c')
            
            # Link a scrollbar to the canvas
            vsb = Scrollbar(frame_canvas1, orient="vertical", command=canvas1.yview)
            vsb.grid(row=0, column=1,sticky = 'ns')
            canvas1.configure(yscrollcommand=vsb.set)
            
            # Create a frame to contain the variables
            frame_vars1 = Frame(canvas1)
            frame_vars1.config(height = '3c')
            canvas1.create_window((0, 0), window=frame_vars1, anchor='nw')
            for name, format_of_data, vals in univariate_vars:
                Label(frame_vars1, 
                text= name).grid(row=self.univar_row_num, column= 1,pady = 5,padx = 5)
                Label(frame_vars1, 
                text= format_of_data).grid(row=self.univar_row_num, column= 2,pady = 5,padx = 5)
                
                if not(format_of_data == 'linspace' or format_of_data == 'list'):
                    key2=Entry(frame_vars1)
                    key2.grid(row=self.univar_row_num, column=3,pady = 5,padx = 5)
                    #key2.insert(0,univariate_sims)
                    self.univar_ntrials_entries[name]= key2
                else:
                    if format_of_data == 'linspace':
                        
                        Label(frame_vars1,text= str(vals[2])).grid(row=self.univar_row_num, column= 3,pady = 5,padx = 5)
                    else:
                        Label(frame_vars1,text= str(len(vals))).grid(row=self.univar_row_num, column= 3,pady = 5,padx = 5)
                self.univar_row_num += 1
                
            # Update vars frames idle tasks to let tkinter calculate variable sizes
            frame_vars1.update_idletasks()
            # Determine the size of the Canvas
            
            frame_canvas1.config(width='5c', height='5c')
            
            # Set the canvas scrolling region
            canvas1.config(scrollregion=canvas1.bbox("all"))
            
    def get_distributions(self):
        if self.analysis_type.get() == 'Univariate Sensitivity':
            if self.univar_ntrials_entries:
                max_num_sim = 0
                for slot in self.univar_ntrials_entries.values():
                    try:
                        cur_num_sim = int(slot.get())
                    except:
                        cur_num_sim = 1
                    max_num_sim = max(max_num_sim, cur_num_sim)
            else:
                max_num_sim = 1
            self.simulation_vars, self.simulation_dist = self.construct_distributions(ntrials=max_num_sim)
            for (aspen_variable, aspen_call, fortran_index), dist in self.simulation_vars.items():
                if aspen_variable in self.univar_ntrials_entries:
                    try:
                        num_trials_per_var = int(self.univar_ntrials_entries[aspen_variable].get())
                    except:
                        num_trials_per_var = 1
                    self.simulation_vars[(aspen_variable, aspen_call, fortran_index)] = dist[:num_trials_per_var]
                    self.simulation_dist[aspen_variable] = dist[:num_trials_per_var]                
        else:
            try: 
                ntrials = int(self.num_sim_entry.get())
            except:
                ntrials=1
            self.simulation_vars, self.simulation_dist = self.construct_distributions(ntrials=ntrials) 
            
            
    def construct_distributions(self, ntrials=1):
        '''
        Given the excel input from the user in the GUI, produce a list_of_variables
        the user wants to change as well as their distributions that should be 
        randomly sampled from. 
        '''
        
        gui_excel_input = str(self.input_csv_entry.get())
        with open(gui_excel_input) as f:
            reader = DictReader(f)# Skip the header row
            simulation_vars = {}
            simulation_dist = {}
            for row in reader:
                if row['Toggle'].lower().strip() == 'true':
                    dist_type = row['Format of Range'].lower()
                    aspen_variable = row['Variable Name']
                    aspen_call = row['Variable Aspen Call']
                    bounds = row['Bounds'].split(',')
                    lb = float(bounds[0].strip())
                    ub = float(bounds[1].strip())
                    if 'normal' in dist_type or 'gaussian' in dist_type:
                        dist_variables = row['Range of Values'].split(',')
                        distribution = self.sample_gauss(float(dist_variables[0].strip()),
                                  float(dist_variables[1].strip()), lb, ub, ntrials)
                    if 'linspace' in dist_type:
                        linspace_vars = row['Range of Values'].split(',')
                        distribution = linspace(float(linspace_vars[0].strip()), 
                                                   float(linspace_vars[1].strip()),
                                                   float(linspace_vars[2].strip()))
                    if 'poisson' in dist_type:
                        lambda_p = float(row['Range of Values'].strip())
                        distribution = self.sample_poisson(lambda_p, lb, ub, ntrials)
                    if 'pareto' in dist_type:
                        pareto_vals = row['Range of Values'].split(',')
                        shape = float(pareto_vals[0].strip())
                        scale = float(pareto_vals[1].strip())
                        distribution = self.sample_pareto(shape, scale, lb, ub, ntrials)
                    if 'list' in dist_type:
                        lst = row['Range of Values'].split(',')
                        distribution = []
                        for l in lst:
                            distribution.append(float(l.strip()))                
                    if 'uniform' in dist_type:
                        lb_ub = row['Range of Values'].split(',')
                        lb_uniform, ub_uniform = float(lb_ub[0].strip()), float(lb_ub[1].strip())
                        distribution = self.sample_uniform(lb_uniform, ub_uniform, lb, ub, ntrials)
                    simulation_dist[aspen_variable] = distribution[:]
                    fortran_index = (0,0)
                    if row['Fortran Call'].strip() != "":
                        fortran_call = row['Fortran Call']
                        value_to_change = row['Fortran Value to Change'].strip()
                        len_val = len(value_to_change)
                        for i in range(len(fortran_call)):
                            if fortran_call[i:i+len_val] == value_to_change:
                                fortran_index = (i, i+len_val) #NOT INCLUSIVE
                        for i, v in enumerate(distribution):
                            distribution[i] = self.make_fortran(fortran_call, fortran_index, v)
                    simulation_vars[(aspen_variable, aspen_call, fortran_index)] = distribution
        return simulation_vars, simulation_dist
    
    def sample_gauss(self,mean, std, lb, ub, ntrials):
        d = []
        for i in range(ntrials):
            rand_sample = random.normal(mean,std)
            while(rand_sample < lb or rand_sample > ub):
                rand_sample = random.normal(mean,std)
            d.append(rand_sample)
        return d
    
    def sample_uniform(self,lb_uniform, ub_uniform, lb, ub, ntrials):
        d = []
        for i in range(ntrials):
            rand_sample = random.uniform(lb_uniform, ub_uniform)
            while(rand_sample < lb or rand_sample > ub):
                rand_sample = random.uniform(lb_uniform, ub_uniform)
            d.append(rand_sample)
        return d
    
    
    def sample_poisson(self,lambda_p, lb, ub, ntrials):
        d = []
        for i in range(ntrials):
            rand_sample = random.poisson(10000*lambda_p)/10000
            while(rand_sample < lb or rand_sample > ub):
                rand_sample = random.poisson(10000*lambda_p)/10000
            d.append(rand_sample)
        return d
    
    def sample_pareto(self, shape, scale, lb, ub, ntrials):
        d = []
        for i in range(ntrials):
            rand_sample = (random.pareto(shape) + 1) * scale
            while(rand_sample < lb or rand_sample > ub):
                rand_sample = (random.pareto(shape) + 1) * scale
            d.append(rand_sample)
        return d
    
    def make_fortran(self, fortran_call, fortran_index, val):
        return fortran_call[:fortran_index[0]] + str(val) + fortran_call[fortran_index[1]:]
    
    def disp_sp_mfsp(self):
        try:
            if self.current_simulation.results:
                mfsp = self.current_simulation.results[0].at[0, 'MFSP']
                if mfsp:
                    Label(self.current_tab, text= 'MFSP = ${:.2f}'.format(mfsp)).grid(
                        row=self.sp_row_num+1, column = 1)
                else:
                    Label(self.current_tab, text= 'Aspen Failed to Converge').grid(
                        row=self.sp_row_num+1, column = 1)
            else:
                self.after(5000, self.disp_sp_mfsp)
        except:
            self.after(5000, self.disp_sp_mfsp)
    
    def single_point_analysis(self):
        self.store_user_inputs()
        self.get_distributions()
        # update simulation variable values based on user input in GUI
        for (aspen_variable, aspen_call, fortran_index), values in self.simulation_vars.items():
            self.simulation_vars[(aspen_variable, aspen_call, fortran_index)] = [float(
                    self.sp_value_entries[aspen_variable].get())]
        self.create_simulation_object(self.simulation_vars, self.vars_to_change, self.output_file, self.num_trial)
        self.run_simulations()
        
    
    def run_multivar_sens(self):
        Button(self.current_tab, text = "Abort", command=self.abort_sim).grid(
                    row=7,columnspan = 1, column = 3, sticky=W)
        self.store_user_inputs()
        if len(self.simulation_vars) == 0:
            self.get_distributions()
        self.create_simulation_object(self.simulation_vars, self.vars_to_change, self.output_file, self.num_trial)
        self.run_simulations()
        
        
    def run_univ_sens(self):
        self.store_user_inputs()
        if len(self.simulation_vars) == 0:
            self.get_distributions()
        for (aspen_variable, aspen_call, fortran_index), values in self.simulation_vars.items():
            self.create_simulation_object({(aspen_variable, aspen_call, 
                                            fortran_index): values}, [aspen_variable], 
    self.output_file+'_'+aspen_variable, len(values))
        self.run_simulations()
    
    
    def store_user_inputs(self):
        self.aspen_file = str(self.aspen_file_entry.get())
        try:
            self.num_processes = int(self.num_processes_entry.get())
        except:
            self.num_processes = 1
        self.excel_solver_file= str(self.excel_solver_entry.get())
        try:
            self.num_trial = int(self.num_sim_entry.get())
        except: 
            self.num_trial = 1
        self.output_file = str(self.save_as_entry.get())
        self.input_csv = str(self.input_csv_entry.get())
        
        self.vars_to_change = []
        with open(self.input_csv) as f:
            reader = DictReader(f)# Skip the header row
            for row in reader:
                if row['Toggle'].lower().strip() == 'true':
                    self.vars_to_change.append(row["Variable Name"])
        
        
    def run_simulations(self):
        self.start_time = time()
        
        for sim in self.simulations: 
            self.current_simulation = sim
            self.current_simulation.init_sims()
            if self.abort_univar_overall.value:
                self.abort.value = True
            self.univar_plot_counter += 1
    
    def parse_output_vars(self):
        excels_to_ignore = {}
        for p in process_iter():
            if 'excel' in p.name().lower():
                excels_to_ignore[p.pid] = 1
        excel, book = open_excelCOMS(self.excel_solver_file)
        self.output_vars = []
        row_counter = 3
        while True:
            var_name = book.Sheets('Output').Evaluate("B" + str(row_counter)).Value
            if var_name:
                units = book.Sheets('Output').Evaluate("D" + str(row_counter)).Value
                column_name = var_name + ' (' + units + ')' if units else var_name
                self.output_vars.append(column_name)
            else:
                break
            row_counter += 1
        self.output_value_cells = "C3:C" + str(row_counter - 1)
        self.output_vars += ['Aspen Errors']
        for p in process_iter():
            if 'excel' in p.name().lower() and p.pid not in excels_to_ignore:
                p.terminate()
            
        
    def create_simulation_object(self, simulation_vars, vars_to_change, output_file, num_trial):
        self.parse_output_vars()
        self.output_columns = vars_to_change + self.output_vars
        
        new_sim = Simulation(self.sims_completed, num_trial, simulation_vars, output_file, path.dirname(str(self.input_csv_entry.get())),
                             self.aspen_file, self.excel_solver_file, self.abort, vars_to_change, self.output_value_cells,
                             self.output_columns, save_freq=5, num_processes=self.num_processes)
        self.simulations.append(new_sim)
        self.tot_sim_num += num_trial
        
        
    def initialize_single_point(self):
        self.worker_thread = Thread(
                target=lambda: self.single_point_analysis())
        self.worker_thread.start()
        self.after(5000, self.disp_sp_mfsp)
        
    def initialize_univar_analysis(self):
        self.worker_thread = Thread(
            target=lambda: self.run_univ_sens())
        self.worker_thread.start()
        self.status_label = None
        self.time_rem_label = None
        self.after(5000, self.univar_gui_update)

    
    def initialize_multivar_analysis(self):
        self.worker_thread = Thread(
            target=lambda: self.run_multivar_sens())
        self.worker_thread.start()
        self.status_label = None
        self.time_rem_label = None
        self.multivar_gui_update()
        
        
    def disp_status_update(self):
        if self.current_simulation and not self.abort.value:
            if len(self.current_simulation.results) == self.current_simulation.tot_sim:
                tmp = Label(self.current_tab, text= 'Status: Simulation Complete                   ')
            else:
                tmp = Label(self.current_tab, text= 'Status: Simulation Running | {} Results Collected'.format(
                        len(self.current_simulation.results)))
            if self.univar_row_num != 0:
                row = 15
            else:
                row = 8
            tmp.grid(row=row, column = 1, sticky=W, columnspan=2)
            if self.status_label:
                self.status_label.destroy()
            self.status_label = tmp
        
        
    def disp_time_remaining(self):
        if self.start_time and self.sims_completed.value != self.last_update:
            self.last_update = self.sims_completed.value
            elapsed_time = time() - self.start_time
            if self.sims_completed.value > 0:
                remaining_time = ((elapsed_time / self.sims_completed.value) * (self.tot_sim_num - self.sims_completed.value))//60
                hours, minutes = divmod(remaining_time, 60)
                tmp = Label(self.current_tab, text='Time Remaining: {} Hours, {} Minutes    '.format(int(hours), int(minutes)))
            else:
                tmp = Label(self.current_tab, text='Time Remaining: N/A')
            if self.univar_row_num != 0:
                row = 16
            else:
                row = 9
            tmp.grid(row=row, column=1, columnspan=2,sticky=W)
            if self.time_rem_label:
                self.time_rem_label.destroy()
            self.time_rem_label = tmp
            
            
    def plot_on_GUI(self):
        
        if not self.current_simulation:
            return
        if len(self.current_simulation.results) == self.last_results_plotted:
            return
        self.last_results_plotted = len(self.current_simulation.results)
        
        if self.current_simulation.results:
            results = concat(self.current_simulation.results).sort_index()
            results = results[[d is not None for d in results['MFSP']]] # filter to make sure you aren't plotting None results
        else:
            results = DataFrame(columns=self.output_columns)

        fig_list =[]
        num_bins = 15
        mfsp_fig = Figure(figsize = (3,3), facecolor=[240/255,240/255,237/255], tight_layout=True)
        b = mfsp_fig.add_subplot(111)
        b.hist(results['MFSP'], num_bins, facecolor='blue', edgecolor='black', alpha=1.0)
        b.set_title('MFSP')
        fig_list.append(mfsp_fig)
        
        for var, values in self.simulation_dist.items():
            fig = Figure(figsize = (3,3), facecolor=[240/255,240/255,237/255], tight_layout=True)
            a = fig.add_subplot(111)
            _, bins, _ = a.hist(self.simulation_dist[var], num_bins, facecolor='white', edgecolor='black',alpha=1.0)
            a.hist(results[var], bins=bins, facecolor='blue',edgecolor='black', alpha=1.0)
            a.set_title(var)
            fig_list.append(fig)
        
        if self.univar_row_num != 0:
            row_num = 17
        else:
            row_num = 10
        
        frame_canvas = Frame(self.current_tab)
        frame_canvas.grid(row=row_num, column=1, columnspan = 3,pady=(5, 0))
        frame_canvas.grid_rowconfigure(0, weight=1)
        frame_canvas.grid_columnconfigure(0, weight=1)
        frame_canvas.config(height = '10c', width='16c')
        
        main_canvas = Canvas(frame_canvas)
        main_canvas.grid(row=0, column=0, sticky="news")
        main_canvas.config(height = '10c', width='16c')
        
        vsb = Scrollbar(frame_canvas, orient="vertical", command=main_canvas.yview)
        vsb.grid(row=0, column=1,sticky = 'ns')
        main_canvas.configure(yscrollcommand=vsb.set)
        
        figure_frame = Frame(main_canvas)
        main_canvas.create_window((0, 0), window=figure_frame, anchor='nw')
        figure_frame.config(height = '10c', width='16c')
    
        row_num = 0
        column = False
        for figs in fig_list:
            figure_canvas = FigureCanvasTkAgg(figs, master=figure_frame)
            if column:
                col = 4
            else:
                col = 1
            #figure_canvas.draw()
            figure_canvas.get_tk_widget().grid(
                    row=row_num, column=col,columnspan=2, rowspan = 5, pady = 5,padx = 8, sticky=E)
            #figure_canvas._tkcanvas.grid(row=row_num, column = 0,columnspan = 10, rowspan = 10, sticky= W+E+N+S, pady = 5,padx = 5)
            if column:
                row_num += 5
            column = not column
        

        figure_frame.update_idletasks()
        frame_canvas.config(width='16c', height='10c')
        
        # Set the canvas scrolling region
        main_canvas.config(scrollregion=figure_frame.bbox("all"))
                
            
    def plot_univ_on_GUI(self):
        
        if not self.current_simulation:
            return
        if len(self.current_simulation.results) == self.last_results_plotted:
            return
        self.last_results_plotted = len(self.current_simulation.results)
        
        current_var = self.current_simulation.vars_to_change[0]
        if self.current_simulation.results:
            results = concat(self.current_simulation.results).sort_index()
            results = results[[d is not None for d in results['MFSP']]] # filter to make sure you aren't plotting None results
        else:
            results = DataFrame(columns=self.output_columns)

        fig_list =[]
        var_fig = Figure(figsize = (3,3), facecolor=[240/255,240/255,237/255], tight_layout=True)
        a = var_fig.add_subplot(111)
        num_bins = 15
        _, bins, _ = a.hist(self.simulation_dist[current_var], num_bins, facecolor='white',edgecolor='black', alpha=1.0)
        a.hist(results[current_var], bins=bins, facecolor='blue',edgecolor='black', alpha=1.0)
        a.set_title(current_var)
        fig_list.append(var_fig)
        
        mfsp_fig = Figure(figsize = (3,3), facecolor=[240/255,240/255,237/255], tight_layout=True)
        b = mfsp_fig.add_subplot(111)
        b.hist(results['MFSP'], num_bins, facecolor='blue', edgecolor='black', alpha=1.0)
        b.set_title('MFSP - ' + current_var)
        fig_list.append(mfsp_fig)
        
        figs_to_plot = self.finished_figures[:] + fig_list
        if len(self.current_simulation.results) == self.current_simulation.tot_sim:
            self.finished_figures += fig_list
        
        if self.univar_row_num != 0:
            row_num = 17
        else:
            row_num = 10
        
        frame_canvas = Frame(self.current_tab)
        frame_canvas.grid(row=row_num, column=1, columnspan = 3,pady=(5, 0))
        frame_canvas.grid_rowconfigure(0, weight=1)
        frame_canvas.grid_columnconfigure(0, weight=1)
        frame_canvas.config(height = '10c', width='16c')
        
        main_canvas = Canvas(frame_canvas)
        main_canvas.grid(row=0, column=0, sticky="news")
        main_canvas.config(height = '10c', width='16c')
        
        vsb = Scrollbar(frame_canvas, orient="vertical", command=main_canvas.yview)
        vsb.grid(row=0, column=1,sticky = 'ns')
        main_canvas.configure(yscrollcommand=vsb.set)
        
        figure_frame = Frame(main_canvas)
        main_canvas.create_window((0, 0), window=figure_frame, anchor='nw')
        figure_frame.config(height = '10c', width='16c')
    
        row_num = 0
        column = False
        for figs in figs_to_plot:
            figure_canvas = FigureCanvasTkAgg(figs, master=figure_frame)
            if column:
                col = 4
            else:
                col = 1
            #figure_canvas.draw()
            figure_canvas.get_tk_widget().grid(
                    row=row_num, column=col,columnspan=2, rowspan = 5, pady = 5,padx = 8, sticky=E)
            #figure_canvas._tkcanvas.grid(row=row_num, column = 0,columnspan = 10, rowspan = 10, sticky= W+E+N+S, pady = 5,padx = 5)
            if column:
                row_num += 5
            column = not column
        

        figure_frame.update_idletasks()
        frame_canvas.config(width='16c', height='10c')
        
        # Set the canvas scrolling region
        main_canvas.config(scrollregion=figure_frame.bbox("all"))
        
            
    def plot_init_dist(self):
        '''
        This function will plot the distribution of variable calls prior to running
        the simulation. This will enable users to see whether the distributions are as they expected.
        
        '''
        
        self.get_distributions()        
        fig_list =[]
        for var, values in self.simulation_dist.items():
            fig = Figure(figsize = (3,3), facecolor=[240/255,240/255,237/255], tight_layout=True)
            a = fig.add_subplot(111)
            num_bins = 15
            a.hist(values, num_bins, facecolor='blue', edgecolor='black', alpha=1.0)
            a.set_title(var)
            fig_list.append(fig)
            
        if self.univar_row_num != 0:
            row_num = 17
        else:
            row_num = 10
        frame_canvas = Frame(self.current_tab)
        frame_canvas.grid(row=row_num, column=1, columnspan = 3,pady=(5, 0))
        frame_canvas.grid_rowconfigure(0, weight=1)
        frame_canvas.grid_columnconfigure(0, weight=1)
        frame_canvas.config(height = '10c', width='16c')
        
        main_canvas = Canvas(frame_canvas)
        main_canvas.grid(row=0, column=0, sticky="news")
        main_canvas.config(height = '10c', width='16c')
        
        vsb = Scrollbar(frame_canvas, orient="vertical", command=main_canvas.yview)
        vsb.grid(row=0, column=2,sticky = 'ns')
        main_canvas.configure(yscrollcommand=vsb.set)
        
        figure_frame = Frame(main_canvas)
        main_canvas.create_window((0, 0), window=figure_frame, anchor='nw')
        figure_frame.config(height = '10c', width='16c')
    
        row_num = 0
        column = False
        for figs in fig_list:
            figure_canvas = FigureCanvasTkAgg(figs, master=figure_frame)
            if column:
                col = 4
            else:
                col = 1
            figure_canvas.get_tk_widget().grid(
                    row=row_num, column=col,columnspan=2, rowspan = 5, pady = 5,padx = 8, sticky=E)

            if column:
                row_num += 5
            column = not column

        figure_frame.update_idletasks()
        frame_canvas.config(width='16c', height='10c')
        main_canvas.config(scrollregion=figure_frame.bbox("all"))
        
    def univar_gui_update(self):
        self.disp_status_update()
        self.disp_time_remaining()
        self.plot_univ_on_GUI()
        ####################### ADD AUTO UPDATE GRAPHS #############
        self.after(10000, self.univar_gui_update)
        
        
    def multivar_gui_update(self):
        self.disp_status_update()
        self.disp_time_remaining()
        self.plot_on_GUI()
        ####################### ADD AUTO UPDATE GRAPHS #############
        self.after(10000, self.multivar_gui_update)
        
    
    def fill_num_trials(self):
        ntrials = self.fill_num_sims.get()
        for name, slot in self.univar_ntrials_entries.items():
            slot.delete(0, END)
            slot.insert(0, ntrials)
        

    def open_excel_file(self):
        filename = askopenfilename(title = "Select file", filetypes = (("csv files","*.csv"),("all files","*.*")))
        self.input_csv_entry.delete(0, END)
        self.input_csv_entry.insert(0, filename)
        
        
    def open_aspen_file(self):
        filename = askopenfilename(title = "Select file", filetypes = (("Aspen Models",["*.bkp", "*.apw"]),("all files","*.*")))
        self.aspen_file_entry.delete(0, END)
        self.aspen_file_entry.insert(0, filename)
    
    
    def open_solver_file(self):
        filename = askopenfilename(title = "Select file", filetypes = (("Excel Files","*.xlsm"),("all files","*.*")))
        self.excel_solver_entry.delete(0, END)
        self.excel_solver_entry.insert(0, filename)
        
        
    def abort_sim(self):
        self.abort.value = True
        self.cleanup_thread = Thread(target=self.cleanup_processes_and_COMS)
        self.cleanup_thread.start()
        
    def abort_univar_overall_fun(self):
        self.abort_univar_overall.value = True
        self.abort_sim()
        
    def cleanup_processes_and_COMS(self):
        try:
            self.current_simulation.close_all_COMS()
            self.current_simulation.terminate_processes()
            save_data(self.current_simulation.output_file, self.current_simulation.results, self.current_simulation.directory)
        except:
            self.after(1000, self.cleanup_processes_and_COMS)