Esempio n. 1
0
    def __init__(self):
        self.app = Tk()
        self.app.maxsize(900, 700)
        self.app.minsize(900, 700)
        self.app.title('Passport Seva')
        font11 = "-family Calibri -size 15 -weight bold -slant roman "  \
                "-underline 0 -overstrike 0"
        self.v = StringVar()

        Label(self.app,
              text="Appointment Availability",
              font="Calibri 26",
              fg="blue").place(x=20, y=10)
        Label(self.app, text="Passport Office", font="Arial 18").place(x=20,
                                                                       y=100)
        city = [
            'Amritsar', 'Bhopal', 'Chandigarh', 'Chennai', 'Delhi', 'Goa',
            'Hyderabad', 'Jaipur', 'Jammu', 'Kolkata', 'Lucknow', 'Mumbai',
            'Ranchi', 'Shimla', 'Trivandrum', 'Visakhapatnam'
        ]
        TCombobox1 = Combobox(self.app,
                              values=city,
                              takefocus="",
                              textvariable=self.v,
                              font=font11)
        TCombobox1.configure(state="readonly")
        TCombobox1.place(x=200, y=100, relheight=0.051, relwidth=0.280)
        TCombobox1.bind("<<ComboboxSelected>>", self.fetch)
        self.app.mainloop()
Esempio n. 2
0
class FilterSelectionFrame(LabelFrame):
    def __init__(self, parent, get_all, get_selection, set_selection):
        log.debug(f"creating {type(self).__name__}...")
        super().__init__(parent, text="  Filters  ")

        self.parent = parent
        self.get_all = get_all
        self.get_selection = get_selection
        self.set_selection = set_selection

        Label(self, text="Country: ").grid(row=0, column=0, padx=PAD_X, pady=PAD_Y, sticky=EW)

        self.cb_country = Combobox(self, state="readonly", values=("All",), width=30)
        self.cb_country.bind("<<ComboboxSelected>>", self.apply_country_filter)
        self.cb_country.grid(row=0, column=1, padx=PAD_X, pady=PAD_Y, sticky=EW)
        self.cb_country.current(0)

        Label(self, text="Tournament: ").grid(row=0, column=2, padx=PAD_X, pady=PAD_Y, sticky=EW)

        self.cb_tournament = Combobox(self, state="readonly", values=("All",), width=50)
        self.cb_tournament.bind("<<ComboboxSelected>>", self.apply_tournament_filter)
        self.cb_tournament.current(0)
        self.cb_tournament.grid(row=0, column=3, padx=PAD_X, pady=PAD_Y, sticky=EW)

        Button(self, text="Reset", command=self.reset_filters).grid(row=0, column=4)

    def set_countries(self, countries):
        values = (ALL,)
        if countries:
            values += tuple(countries)

        self.cb_country.configure(values=values)

    def set_tournaments(self, tournaments):
        values = (ALL,)
        if tournaments:
            values += tuple(tournaments)

        self.cb_tournament.configure(values=values)

    def apply_country_filter(self, _):
        country = self.cb_country.get()
        selection = self.get_all() if country == ALL else self.get_selection().with_country(country)
        self.set_selection(selection)

    def apply_tournament_filter(self, _):
        tournament = self.cb_tournament.get()
        selection = self.get_all() if tournament == ALL else self.get_selection().with_tournament(tournament)
        self.set_selection(selection)

    def reset_filters(self):
        self.set_selection(self.get_all())
        self.cb_country.current(0)
        self.cb_tournament.current(0)
Esempio n. 3
0
class SerialPort(Frame):
    def __init__(self, parent, controller):
        Frame.__init__(self, parent, bg='white')

        Config.Readconfig()

        baudrateindex = self.find_index(Config.localserialconfig['baudrate'], Config.cbaudrates)
        if baudrateindex < 0: baudrateindex = 0

        comportindex = self.find_index(Config.localserialconfig['comport'], get_serial_ports())
        if comportindex < 0: comportindex = 0

        self.tc_baudrate = StringVar()
        self.tc_baudrate = Combobox(self, textvariable=self.tc_baudrate)
        self.tc_baudrate['values'] = Config.cbaudrates
        self.tc_baudrate.current(baudrateindex)
        self.tc_baudrate.bind('<<ComboboxSelected>>', self.set_baudrate)
        self.tc_baudrate.configure(takefocus="")
        self.tc_baudrate.grid(row=1, column=0)

        self.tc_comports = StringVar()
        self.tc_comport = Combobox(self, textvariable=self.tc_comports)
        self.tc_comport['values'] = get_serial_ports()
        self.tc_comport.current(comportindex)
        self.tc_comport.bind('<<ComboboxSelected>>', self.set_comport)
        self.tc_comport.configure(takefocus="")
        self.tc_comport.grid(row=2, column=0)

        self.save = Button(self, text="save", command=Config.Close)
        self.save.grid(row=3, column=0)

        # print('baudrate: ', self.tc_baudrate['values'])
        # print('ports: ', get_serial_ports())

    def set_baudrate(self, event):
        Config.localserialconfig["baudrate"] = self.tc_baudrate.get()
        # print('Set baudrate ', config.localserialconfig["baudrate"])
        # print(config.localserialconfig)

    def set_comport(self, event):
        Config.localserialconfig["comport"] = self.tc_comports.get()
        # print('Set comport', config.localserialconfig["comport"])
        # print(config.localserialconfig)

    def find_index(self, value, qlist):
        try:
            idx = qlist.index(value)
        except ValueError:
            idx = -1
        # print('find_index: ', idx, ' Value: ', value, ' list: ', qlist)
        return idx
Esempio n. 4
0
    def import_iron_condor(self):
        self.imp_wd: Tk = Tk()
        self.imp_wd.title('Paper trading')
        window_width: int = self.imp_wd.winfo_reqwidth()
        window_height: int = self.imp_wd.winfo_reqheight()
        position_right: int = int(self.imp_wd.winfo_screenwidth() / 2 - window_width / 2)
        position_down: int = int(self.imp_wd.winfo_screenheight() / 2 - window_height / 2)
        self.imp_wd.geometry("600x300+300+200")
        
        bot_frame: Frame = Frame(self.imp_wd,width=800, height=300)
        bot_frame.pack(anchor='nw', fill='both',expand=True, side=TOP)
        bot_frame.pack_propagate(0)
        
        json_data = self.nse_adapter.get_oc_data()
        match_date = self.date_combo_box_stock.get()
        strike_prices: List[float] = [data['strikePrice'] for data in json_data['records']['data'] \
                                   if (str(data['expiryDate']).lower() == str(match_date).lower())]
        

        self.imp_cbox: List[Combobox]    = []
        self.imp_tbox: List[tk.Text]    = []
        imp_vars: List[StringVar] = []
        imp_lbls: List[Label]     = []
        imp_lbls_txt: List[Label] = ['buy PUT','sell PUT','sell CALL','buy CALL']
        imp_lbls_color: List[Label] = ['green','red','red','green']
            
        row_idx = 0

        for i in enumerate(imp_lbls_txt):
            str_var = StringVar()
            str_var.set(' ')
            lbl: Label = Label(bot_frame,text=i[1],justify=LEFT,font=("TkDefaultFont", 10,"bold"),fg=imp_lbls_color[i[0]],width=20)
            lbl.grid(row=i[0],column=0,sticky=N+S+W)
            cb = Combobox(bot_frame,width=10,textvariable=str_var) 
            cb.grid(row=i[0],column=1,sticky=N+S+W)
            cb.configure(state='readonly')
            cb['values'] = strike_prices
            self.imp_cbox.append(cb)
            txt = tk.Text(bot_frame,width=10,bg='yellow',height=2)
            txt.grid(row=i[0],column=2,sticky=N+S+W)
            self.imp_tbox.append(txt)
            row_idx = i[0]+1
        
        ok_button: Button = tk.Button(bot_frame,text='OK!',command=self.export_iron_condor,width=20,bg='green',fg='white',font=("TkDefaultFont", 10, "bold"))
        ok_button.grid(row=row_idx,column=4,sticky=N+S+W)
        
        load_button: Button = tk.Button(bot_frame,text='Load',command=self.open_file,width=20,bg='green',fg='white',font=("TkDefaultFont", 10, "bold"))
        load_button.grid(row=row_idx+1,column=4,sticky=N+S+W)
Esempio n. 5
0
class AConsumo:
    def __init__(self, master):
        self.master = master
        master.title("Adicionar Consumo")
        master.geometry("600x700")
        master.configure(background='green')

        #-----------------------------ITEMS----------------------------
        Items = []
        connection = psycopg2.connect(user="******",
                                      password="******",
                                      host="127.0.0.1",
                                      port="5432",
                                      database="RandR")
        curs = connection.cursor()

        curs.execute("Select * from listar_itens_comida")
        ra = curs.fetchall()
        i = 0
        for item in ra:
            Items.append(item[0])

            i + 1
        curs.close()
        connection.close()
        #------------------------------------------------------------------

        #-----------------------------Restaurante--------------------------
        TRr = []
        connection = psycopg2.connect(user="******",
                                      password="******",
                                      host="127.0.0.1",
                                      port="5432",
                                      database="RandR")
        curs = connection.cursor()

        curs.execute("SELECT * FROM  public.listar_restaurantes")
        ra = curs.fetchall()
        i = 0
        for item in ra:
            TRr.append(item[0])

            i + 1
        curs.close()
        connection.close()
        #-----------------------------------------------------------------

        #-----------------------------Clientes----------------------------
        Clientess = []
        connection = psycopg2.connect(user="******",
                                      password="******",
                                      host="127.0.0.1",
                                      port="5432",
                                      database="RandR")
        curs = connection.cursor()

        curs.execute("SELECT * FROM  public.listar_restaurantes")
        ra = curs.fetchall()
        i = 0
        for item in ra:
            Clientess.append(item[0])

            i + 1
        curs.close()
        connection.close()
        #------------------------------------------------------------------

        #-----------------------------Clientes-----------------------------
        Clientess = []
        connection = psycopg2.connect(user="******",
                                      password="******",
                                      host="127.0.0.1",
                                      port="5432",
                                      database="RandR")
        curs = connection.cursor()

        curs.execute("SELECT nif FROM public.listar_clientes;")
        ra = curs.fetchall()
        i = 0
        for item in ra:
            Clientess.append(item[0])

            i + 1
        curs.close()
        connection.close()
        #------------------------------------------------------------------

        self.labelR = Label(master, text="Restaurante", height=1, width=600)
        self.labelR.pack()
        self.labelR.configure(background='green')

        self.comboRest = Combobox(master, values=TRr, width=600)
        self.comboRest.pack()
        self.comboRest.bind('<<ComboboxSelected>>', self.comboRest.get())

        self.labelR = Label(master, text="Funcionario : ", height=1, width=600)
        self.labelR.pack()
        self.labelR.configure(background='green')

        self.comboDS = Combobox(master, width=600)
        self.comboDS.pack()
        self.comboDS.bind('<<ComboboxSelected>>', self.comboDS.get())

        self.labelR = Label(master, text="Cliente :", height=1, width=600)
        self.labelR.pack()
        self.labelR.configure(background='green')

        self.comboA = Combobox(master, values=Clientess, width=600)
        self.comboA.pack()
        self.comboA.bind('<<ComboboxSelected>>', self.comboA.get())

        self.labelR = Label(master, text="", height=2, width=600)
        self.labelR.pack()
        self.labelR.configure(background='green')

        self.btnlogin = Button(master,
                               text="Refresh local de consumo e empregado ",
                               command=lambda: self.refresh(),
                               height=1,
                               width=100)
        self.btnlogin.pack()

        self.labeli = Label(master, text="Local consumo:", height=2, width=600)
        self.labeli.pack()
        self.labeli.configure(background='green')

        self.Lconsumo = Combobox(master, width=600)
        self.Lconsumo.pack()
        self.Lconsumo.bind('<<ComboboxSelected>>', self.Lconsumo.get())

        self.labeli = Label(master, text="Items:", height=2, width=600)
        self.labeli.pack()
        self.labeli.configure(background='green')

        self.Items = Combobox(master, values=Items, width=600)
        self.Items.pack()
        self.Items.bind('<<ComboboxSelected>>', self.comboA.get())

        self.btnlogin = Button(master,
                               text="Adicionar Ementa",
                               command=lambda: self.Inserts(),
                               height=1,
                               width=100)
        self.btnlogin.pack()
        self.btnlogin = Button(master,
                               text="Voltar",
                               command=lambda: self.new_window4(),
                               height=1,
                               width=100)
        self.btnlogin.pack()

    def refresh(self):
        connection = psycopg2.connect(user="******",
                                      password="******",
                                      host="127.0.0.1",
                                      port="5432",
                                      database="RandR")
        curs = connection.cursor()
        a = []
        b = []

        curs.execute("SELECT public.listar_l_consumo('" + str(self.IdRest()) +
                     "')")
        resta = curs.fetchall()
        i = 0
        for item in resta:
            a.append(item[0])

            i + 1
        curs.execute("SELECT public.mostrar_funcionarios_restaurante('" +
                     str(self.IdRest()) + "')")
        resta = curs.fetchall()
        i = 0
        for item in resta:
            b.append(item[0])

            i + 1
        curs.close()
        connection.close()

        self.Lconsumo.configure(value=a)
        self.comboDS.configure(value=b)

    def new_window4(self):
        self.master.destroy()
        self.master = tk.Tk()
        self.app = Index_Ger_V.IndexGer(self.master)
        self.master.mainloop()

    def IdRest(self):
        connection = psycopg2.connect(user="******",
                                      password="******",
                                      host="127.0.0.1",
                                      port="5432",
                                      database="RandR")
        curs = connection.cursor()

        curs.execute("SELECT public.saber_id_restaurante('" +
                     self.comboRest.get() + "')")
        resta = curs.fetchall()
        val = 0
        i = 0
        for item in resta:
            val = item[0]
            i + 1
        curs.close()
        connection.close()
        return val

    def idItens(self):
        connection = psycopg2.connect(user="******",
                                      password="******",
                                      host="127.0.0.1",
                                      port="5432",
                                      database="RandR")
        curs = connection.cursor()

        curs.execute("SELECT saber_id_item_nome('" + self.Items.get() + "')")
        resta = curs.fetchall()
        val = 0
        i = 0
        for item in resta:
            val = item[0]
            i + 1
        curs.close()
        connection.close()
        return val

    def idCliente(self):
        connection = psycopg2.connect(user="******",
                                      password="******",
                                      host="127.0.0.1",
                                      port="5432",
                                      database="RandR")
        curs = connection.cursor()

        curs.execute("SELECT public.saber_id_cliente('" + self.comboA.get() +
                     "')")
        resta = curs.fetchall()
        val = 0
        i = 0
        for item in resta:
            val = item[0]
            i + 1
        curs.close()
        connection.close()
        return val

    def idFuncionario(self):
        connection = psycopg2.connect(user="******",
                                      password="******",
                                      host="127.0.0.1",
                                      port="5432",
                                      database="RandR")
        curs = connection.cursor()

        curs.execute("SELECT public.saber_id_funcuinario('" +
                     self.comboDS.get() + "')")
        resta = curs.fetchall()
        val = 0
        i = 0
        for item in resta:
            val = item[0]
            i + 1
        curs.close()
        connection.close()
        return val

    def idConsumo(self):
        connection = psycopg2.connect(user="******",
                                      password="******",
                                      host="127.0.0.1",
                                      port="5432",
                                      database="RandR")
        curs = connection.cursor()

        curs.execute("SELECT max FROM public.saber_id_consumo;")
        resta = curs.fetchall()
        val = 0
        i = 0
        for item in resta:
            val = item[0]
            i + 1
        curs.close()
        connection.close()
        return val

    def idLocalConsumo(self):
        connection = psycopg2.connect(user="******",
                                      password="******",
                                      host="127.0.0.1",
                                      port="5432",
                                      database="RandR")
        curs = connection.cursor()

        curs.execute("SELECT public.saber_id_l_consumo('" +
                     self.Lconsumo.get() + "'," + str(self.IdRest()) + ")")
        resta = curs.fetchall()
        val = 0
        i = 0
        for item in resta:
            val = item[0]
            i + 1
        curs.close()
        connection.close()
        return val

    def Inserts(self):
        connection = psycopg2.connect(user="******",
                                      password="******",
                                      host="127.0.0.1",
                                      port="5432",
                                      database="RandR")
        curs = connection.cursor()

        curs.execute("CALL public.insertconsumo(" +
                     str(self.idLocalConsumo()) + "," +
                     str(self.idFuncionario()) + "," + str(self.idCliente()) +
                     ")")

        connection.commit()
        curs.close()
        connection.close()

        connection = psycopg2.connect(user="******",
                                      password="******",
                                      host="127.0.0.1",
                                      port="5432",
                                      database="RandR")
        curs = connection.cursor()

        curs.execute("CALL public.insertconsumo_itens(" +
                     str(self.idConsumo()) + "," + str(self.idItens()) + ")")

        connection.commit()
        curs.close()
        connection.close()
class _full_combo:
    def __init__(self, master):
    
        grid_frame = Frame( master )
        self.grid_frame = grid_frame
        grid_frame.pack(expand=1, fill=BOTH)
        self.master = master
        
        self.x, self.y, self.w, self.h = 10, 10, 519, 326

        self.master.title("full_combo")

        self.RadioGroup_1_StringVar = StringVar()

        self.make_Button_1( self.grid_frame )          #      Button:  at Main(1,1)
        self.make_Notebook_1( self.grid_frame )        #    Notebook:  at Main(1,2)
        self.make_Tab_1( self.Notebook_1 )             #         Tab: Small : at Notebook_1(1,1)
        self.make_Tab_2( self.Notebook_1 )             #         Tab: Medium : at Notebook_1(1,2)
        self.make_Tab_3( self.Notebook_1 )             #         Tab: Large : at Notebook_1(1,3)
        self.make_Canvas_1( self.Tab_1 )               #      Canvas:  at Tab_1(1,3)
        self.make_Frame_1( self.Tab_1 )                #       Frame:  at Tab_1(1,2)
        self.make_Checkbutton_2( self.Frame_1 )        # Checkbutton:  at Frame_1(1,1)
        self.make_Combobox_2( self.Frame_1 )           #    Combobox: Mine Yours Ours : at Frame_1(2,1)
        self.make_Entry_2( self.Frame_1 )              #       Entry:  at Frame_1(3,1)
        self.make_LabelFrame_1( self.Tab_2 )           #  LabelFrame: Left : at Tab_2(1,1)
        self.make_LabelFrame_2( self.Tab_2 )           #  LabelFrame: Right : at Tab_2(1,2)
        self.make_Listbox_1( self.LabelFrame_1 )       #     Listbox:  at LabelFrame_1(1,1)
        self.make_Message_1( self.LabelFrame_1 )       #     Message:  at LabelFrame_1(2,1)
        self.make_Menubutton_1( self.LabelFrame_2 )    #  Menubutton:  at LabelFrame_2(1,1)
        self.make_Notebook_2( self.LabelFrame_2 )      #    Notebook:  at LabelFrame_2(2,1)
        self.make_Tab_4( self.Notebook_2 )             #         Tab:  at Notebook_2(1,1)
        self.make_Tab_5( self.Notebook_2 )             #         Tab:  at Notebook_2(1,2)
        self.make_RadioGroup_1( self.Tab_4 )           #  RadioGroup:  at Tab_4(1,1)
        self.make_Radiobutton_1( self.RadioGroup_1 )   # Radiobutton: 1 : at RadioGroup_1(2,1)
        self.make_Radiobutton_2( self.RadioGroup_1 )   # Radiobutton: 2 : at RadioGroup_1(3,1)
        self.make_Radiobutton_3( self.RadioGroup_1 )   # Radiobutton: 3 : at RadioGroup_1(4,1)
        self.make_Radiobutton_4( self.RadioGroup_1 )   # Radiobutton: 4 : at RadioGroup_1(5,1)
        self.make_Scale_1( self.Tab_5 )                #       Scale: 2.5 to 7.5 : at Tab_5(2,1)
        self.make_Spinbox_1( self.Tab_5 )              #     Spinbox: 1 to 10 : at Tab_5(3,1)
        self.make_Button_2( self.Tab_3 )               #      Button:  at Tab_3(3,1)
        self.make_Text_1( self.Tab_3 )                 #        Text:  at Tab_3(2,1)
        self.make_Treeview_1( self.Tab_3 )             #    Treeview:  at Tab_3(2,2)

        self.grid_frame.rowconfigure(1, weight=1)
        self.Tab_1.rowconfigure(1, weight=1)
        self.Tab_2.rowconfigure(1, weight=1)
        self.LabelFrame_1.columnconfigure(1, weight=1)
        self.grid_frame.columnconfigure(2, weight=1)
        self.Tab_2.columnconfigure(2, weight=1)
        self.Tab_1.columnconfigure(3, weight=1)
        self.Tab_2.columnconfigure(1, weight=1)

        self.RadioGroup_1_StringVar.set("1")
        self.RadioGroup_1_StringVar_traceName = self.RadioGroup_1_StringVar.trace_variable("w", self.RadioGroup_1_StringVar_Callback)
        # >>>>>>insert any user code below this comment for section "top_of_init"


    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Button_1"
    def make_Button_1(self, frame):
        """      Button:  at Main(1,1)"""
        self.Button_1 = Button( frame , text="Button_1", width="15", anchor="e")
        self.Button_1.grid(row=1, column=1, sticky="s")

        # >>>>>>insert any user code below this comment for section "make_Button_1"

        self.Button_1.bind("<ButtonRelease-1>", self.Button_1_Click)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Notebook_1"
    def make_Notebook_1(self, frame):
        """    Notebook:  at Main(1,2)"""
        self.Notebook_1 = Notebook ( frame , width="400", height="300")
        self.Notebook_1.grid(row=1, column=2, sticky="nsew")

        # >>>>>>insert any user code below this comment for section "make_Notebook_1"


    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Tab_1"
    def make_Tab_1(self, frame):
        """         Tab: Small : at Notebook_1(1,1)"""
        self.Tab_1 = Frame( frame )
        self.Notebook_1.add( self.Tab_1, text="Small" )
        # >>>>>>insert any user code below this comment for section "make_Tab_1"


    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Tab_2"
    def make_Tab_2(self, frame):
        """         Tab: Medium : at Notebook_1(1,2)"""
        self.Tab_2 = Frame( frame )
        self.Notebook_1.add( self.Tab_2, text="Medium" )
        # >>>>>>insert any user code below this comment for section "make_Tab_2"


    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Tab_3"
    def make_Tab_3(self, frame):
        """         Tab: Large : at Notebook_1(1,3)"""
        self.Tab_3 = Frame( frame )
        self.Notebook_1.add( self.Tab_3, text="Large" )
        # >>>>>>insert any user code below this comment for section "make_Tab_3"


    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Canvas_1"
    def make_Canvas_1(self, frame):
        """      Canvas:  at Tab_1(1,3)"""
        self.Canvas_1 = Canvas( frame , height="50", width="60")
        self.Canvas_1.grid(row=1, column=3, sticky="nsew")

        # >>>>>>insert any user code below this comment for section "make_Canvas_1"

        self.Canvas_1.config(bg='#ffffcc')
        self.Canvas_1.bind("<ButtonRelease-1>", self.Canvas_1_Click)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Frame_1"
    def make_Frame_1(self, frame):
        """       Frame:  at Tab_1(1,2)"""
        self.Frame_1 = Frame( frame , width="60", height="50")
        self.Frame_1.grid(row=1, column=2, sticky="n")

        # >>>>>>insert any user code below this comment for section "make_Frame_1"


    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Checkbutton_2"
    def make_Checkbutton_2(self, frame):
        """ Checkbutton:  at Frame_1(1,1)"""
        self.Checkbutton_2 = Checkbutton( frame , text="Checkbutton_2", width="15", anchor="e")
        self.Checkbutton_2.grid(row=1, column=1)
        self.Checkbutton_2_StringVar = StringVar()

        # >>>>>>insert any user code below this comment for section "make_Checkbutton_2"

        self.Checkbutton_2.configure(variable=self.Checkbutton_2_StringVar, onvalue="yes", offvalue="no")
        self.Checkbutton_2_StringVar.set("no")
        self.Checkbutton_2_StringVar_traceName = self.Checkbutton_2_StringVar.trace_variable("w", self.Checkbutton_2_StringVar_Callback)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Combobox_2"
    def make_Combobox_2(self, frame):
        """    Combobox: Mine Yours Ours : at Frame_1(2,1)"""
        self.Combobox_2 = Combobox( frame , text="Combobox_2", values="Mine Yours Ours")
        self.Combobox_2.grid(row=2, column=1)
        self.Combobox_2_StringVar = StringVar()

        # >>>>>>insert any user code below this comment for section "make_Combobox_2"

        self.Combobox_2.configure(textvariable=self.Combobox_2_StringVar)
        self.Combobox_2_StringVar.set( "Mine" )
        self.Combobox_2_StringVar_traceName = self.Combobox_2_StringVar.trace_variable("w", self.Combobox_2_StringVar_Callback)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Entry_2"
    def make_Entry_2(self, frame):
        """       Entry:  at Frame_1(3,1)"""
        self.Entry_2 = Entry( frame , width="15")
        self.Entry_2.grid(row=3, column=1)
        self.Entry_2_StringVar = StringVar()

        # >>>>>>insert any user code below this comment for section "make_Entry_2"

        self.Entry_2.configure(textvariable=self.Entry_2_StringVar)
        self.Entry_2_StringVar_traceName = self.Entry_2_StringVar.trace_variable("w", self.Entry_2_StringVar_Callback)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_LabelFrame_1"
    def make_LabelFrame_1(self, frame):
        """  LabelFrame: Left : at Tab_2(1,1)"""
        self.LabelFrame_1 = LabelFrame( frame , text="Left", width="60", height="50")
        self.LabelFrame_1.grid(row=1, column=1, sticky="nsew")

        # >>>>>>insert any user code below this comment for section "make_LabelFrame_1"


    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_LabelFrame_2"
    def make_LabelFrame_2(self, frame):
        """  LabelFrame: Right : at Tab_2(1,2)"""
        self.LabelFrame_2 = LabelFrame( frame , text="Right", width="60", height="50")
        self.LabelFrame_2.grid(row=1, column=2, sticky="nsew")

        # >>>>>>insert any user code below this comment for section "make_LabelFrame_2"


    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Listbox_1"
    def make_Listbox_1(self, frame):
        """     Listbox:  at LabelFrame_1(1,1)"""
        self.Listbox_1 = Listbox( frame , height="12", width="30")
        self.Listbox_1.grid(row=1, column=1)

        # >>>>>>insert any user code below this comment for section "make_Listbox_1"


        # Edit the Listbox Entries
        self.Listbox_1.insert(END, "apples")
        self.Listbox_1.insert(END, "oranges")
        self.Listbox_1.insert(END, "grapes")

        self.Listbox_1.bind("<ButtonRelease-1>", self.Listbox_1_Click)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Message_1"
    def make_Message_1(self, frame):
        """     Message:  at LabelFrame_1(2,1)"""
        self.Message_1 = Message( frame , text="Message_1", width="55", anchor="e")
        self.Message_1.grid(row=2, column=1, sticky="ew")

        # >>>>>>insert any user code below this comment for section "make_Message_1"


    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Menubutton_1"
    def make_Menubutton_1(self, frame):
        """  Menubutton:  at LabelFrame_2(1,1)"""
        self.Menubutton_1 = Menubutton( frame , text="Menubutton_1", width="15", anchor="e")
        self.Menubutton_1.grid(row=1, column=1)
        self.Menubutton_1_StringVar = StringVar()

        # >>>>>>insert any user code below this comment for section "make_Menubutton_1"

        self.Menubutton_1.configure(textvariable=self.Menubutton_1_StringVar, text="Select")
        self.Menubutton_1_StringVar.set("Select")
        self.Menubutton_1_StringVar_traceName = self.Menubutton_1_StringVar.trace_variable("w", self.Menubutton_1_StringVar_Callback)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Notebook_2"
    def make_Notebook_2(self, frame):
        """    Notebook:  at LabelFrame_2(2,1)"""
        self.Notebook_2 = Notebook ( frame , width="400", height="300")
        self.Notebook_2.grid(row=2, column=1)

        # >>>>>>insert any user code below this comment for section "make_Notebook_2"


    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Tab_4"
    def make_Tab_4(self, frame):
        """         Tab:  at Notebook_2(1,1)"""
        self.Tab_4 = Frame( frame )
        self.Notebook_2.add( self.Tab_4, text="Tab_4" )
        # >>>>>>insert any user code below this comment for section "make_Tab_4"


    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Tab_5"
    def make_Tab_5(self, frame):
        """         Tab:  at Notebook_2(1,2)"""
        self.Tab_5 = Frame( frame )
        self.Notebook_2.add( self.Tab_5, text="Tab_5" )
        # >>>>>>insert any user code below this comment for section "make_Tab_5"


    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_RadioGroup_1"
    def make_RadioGroup_1(self, frame):
        """  RadioGroup:  at Tab_4(1,1)"""
        self.RadioGroup_1 = LabelFrame( frame , width="60", height="50")
        self.RadioGroup_1.grid(row=1, column=1)

        # >>>>>>insert any user code below this comment for section "make_RadioGroup_1"


    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Radiobutton_1"
    def make_Radiobutton_1(self, frame):
        """ Radiobutton: 1 : at RadioGroup_1(2,1)"""
        self.Radiobutton_1 = Radiobutton( frame , text="Radiobutton_1", value="1", width="15", anchor="e")
        self.Radiobutton_1.grid(row=2, column=1)

        # >>>>>>insert any user code below this comment for section "make_Radiobutton_1"

        self.Radiobutton_1.configure(variable=self.RadioGroup_1_StringVar)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Radiobutton_2"
    def make_Radiobutton_2(self, frame):
        """ Radiobutton: 2 : at RadioGroup_1(3,1)"""
        self.Radiobutton_2 = Radiobutton( frame , text="Radiobutton_2", value="2", width="15")
        self.Radiobutton_2.grid(row=3, column=1)

        # >>>>>>insert any user code below this comment for section "make_Radiobutton_2"

        self.Radiobutton_2.configure(variable=self.RadioGroup_1_StringVar)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Radiobutton_3"
    def make_Radiobutton_3(self, frame):
        """ Radiobutton: 3 : at RadioGroup_1(4,1)"""
        self.Radiobutton_3 = Radiobutton( frame , text="Radiobutton_3", value="3", width="15")
        self.Radiobutton_3.grid(row=4, column=1)

        # >>>>>>insert any user code below this comment for section "make_Radiobutton_3"

        self.Radiobutton_3.configure(variable=self.RadioGroup_1_StringVar)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Radiobutton_4"
    def make_Radiobutton_4(self, frame):
        """ Radiobutton: 4 : at RadioGroup_1(5,1)"""
        self.Radiobutton_4 = Radiobutton( frame , text="Radiobutton_4", value="4", width="15")
        self.Radiobutton_4.grid(row=5, column=1)

        # >>>>>>insert any user code below this comment for section "make_Radiobutton_4"

        self.Radiobutton_4.configure(variable=self.RadioGroup_1_StringVar)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Scale_1"
    def make_Scale_1(self, frame):
        """       Scale: 2.5 to 7.5 : at Tab_5(2,1)"""
        self.Scale_1 = Scale( frame , digits="3", tickinterval="1", to="7.5", from_="2.5", resolution=".5")
        self.Scale_1.grid(row=2, column=1)
        self.Scale_1_StringVar = StringVar()

        # >>>>>>insert any user code below this comment for section "make_Scale_1"

        self.Scale_1.configure(variable=self.Scale_1_StringVar)
        self.Scale_1_StringVar_traceName = self.Scale_1_StringVar.trace_variable("w", self.Scale_1_StringVar_Callback)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Spinbox_1"
    def make_Spinbox_1(self, frame):
        """     Spinbox: 1 to 10 : at Tab_5(3,1)"""
        self.Spinbox_1 = Spinbox( frame , to="10", text="Spinbox_1", width="15", from_="1")
        self.Spinbox_1.grid(row=3, column=1)
        self.Spinbox_1_StringVar = StringVar()

        # >>>>>>insert any user code below this comment for section "make_Spinbox_1"

        self.Spinbox_1.configure(textvariable=self.Spinbox_1_StringVar, to="10", from_="1")
        self.Spinbox_1_StringVar.set("1")
        self.Spinbox_1_StringVar_traceName = self.Spinbox_1_StringVar.trace_variable("w", self.Spinbox_1_StringVar_Callback)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Button_2"
    def make_Button_2(self, frame):
        """      Button:  at Tab_3(3,1)"""
        self.Button_2 = Button( frame , text="Button_2", width="15")
        self.Button_2.grid(row=3, column=1)

        # >>>>>>insert any user code below this comment for section "make_Button_2"

        self.Button_2.bind("<ButtonRelease-1>", self.Button_2_Click)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Text_1"
    def make_Text_1(self, frame):
        """        Text:  at Tab_3(2,1)"""

        lbframe = Frame( frame )
        self.Text_1_frame = lbframe
        vbar=Scrollbar(lbframe, orient=VERTICAL)
        self.Text_1 = Text(lbframe, width="40", height="12", yscrollcommand=vbar.set)
        vbar.config(command=self.Text_1.yview)
        
        vbar.grid(row=0, column=1, sticky='ns')        
        self.Text_1.grid(row=0, column=0)

        self.Text_1_frame.grid(row=2, column=1)

        # >>>>>>insert any user code below this comment for section "make_Text_1"


    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Treeview_1"
    def make_Treeview_1(self, frame):
        """    Treeview:  at Tab_3(2,2)"""
        self.Treeview_1 = Treeview( frame )
        self.Treeview_1.grid(row=2, column=2)

        # >>>>>>insert any user code below this comment for section "make_Treeview_1"


        self.Treeview_1.insert('', 'end', 'widgets', text='Widget Tour')
        # Same thing, but inserted as first child:
        self.Treeview_1.insert('', 0, 'gallery', text='Treeview_1')
        # Inserted underneath an existing node:
        self.Treeview_1.insert('widgets', 'end', text='Button')
        self.Treeview_1.insert('widgets', 'end', text='Canvas')
        self.Treeview_1.insert('widgets', 'end', text='Checkbutton')
        self.Treeview_1.insert('widgets', 'end', text='Combobox')
        self.Treeview_1.insert('widgets', 'end', text='Entry')
        self.Treeview_1.insert('widgets', 'end', text='Frame')
        self.Treeview_1.insert('widgets', 'end', text='Label')
        self.Treeview_1.insert('widgets', 'end', text='LabelFrame')
        self.Treeview_1.insert('widgets', 'end', text='Listbox')
        self.Treeview_1.insert('widgets', 'end', text='Menubutton')
        self.Treeview_1.insert('widgets', 'end', text='Message')
        self.Treeview_1.insert('widgets', 'end', text='Notebook')
        self.Treeview_1.insert('widgets', 'end', text='OptionMenu')
        self.Treeview_1.insert('widgets', 'end', text='Progressbar')
        self.Treeview_1.insert('widgets', 'end', text='RadioGroup')
        self.Treeview_1.insert('widgets', 'end', text='Radiobutton')
        self.Treeview_1.insert('widgets', 'end', text='Scale')
        self.Treeview_1.insert('widgets', 'end', text='Separator')
        self.Treeview_1.insert('widgets', 'end', text='Spinbox')
        self.Treeview_1.insert('widgets', 'end', text='Tab')
        self.Treeview_1.insert('widgets', 'end', text='Text')
        self.Treeview_1.insert('widgets', 'end', text='Treeview')

        # Treeview chooses the id:
        id = self.Treeview_1.insert('', 'end', text='Tutorial')
        self.Treeview_1.insert(id, 'end', text='Tree')

        self.Treeview_1.bind("<ButtonRelease-1>", self.Treeview_1_Click)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Button_1_Click"
    def Button_1_Click(self, event): #bind method for component ID=Button_1
        """      Button:  at Main(1,1)"""
        pass
        # >>>>>>insert any user code below this comment for section "Button_1_Click"
        # replace, delete, or comment-out the following
        print( "executed method Button_1_Click" )

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Canvas_1_Click"
    def Canvas_1_Click(self, event): #bind method for component ID=Canvas_1
        """      Canvas:  at Tab_1(1,3)"""
        pass
        # >>>>>>insert any user code below this comment for section "Canvas_1_Click"
        # replace, delete, or comment-out the following
        print( "executed method Canvas_1_Click" )

        print( "clicked in canvas at x,y =",event.x,event.y )
        w = int(self.Canvas_1.cget("width"))
        h = int(self.Canvas_1.cget("height"))
        self.Canvas_1.create_rectangle((2, 2, w+1, h+1), outline="blue")
        self.Canvas_1.create_line(0, 0, w+2, h+2, fill="red")
        x = int(event.x)
        y = int(event.y)
        print( "event x,y=",x,y )
        self.Canvas_1.create_text(x,y, text="NE", fill="green", anchor=NE)
        self.Canvas_1.create_text(x,y, text="SW", fill="magenta", anchor=SW)
    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Listbox_1_Click"
    def Listbox_1_Click(self, event): #bind method for component ID=Listbox_1
        """     Listbox:  at LabelFrame_1(1,1)"""
        pass
        # >>>>>>insert any user code below this comment for section "Listbox_1_Click"
        # replace, delete, or comment-out the following
        print( "executed method Listbox_1_Click" )

        print( "current selection(s) =",self.Listbox_1.curselection() )
        labelL = []
        for i in self.Listbox_1.curselection():
            labelL.append( self.Listbox_1.get(i))
        print( "current label(s) =",labelL )
        # use self.Listbox_1.insert(0, "item zero")
        #     self.Listbox_1.insert(index, "item i")
        #            OR
        #     self.Listbox_1.insert(END, "item end")
        #   to insert items into the list box
    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Button_2_Click"
    def Button_2_Click(self, event): #bind method for component ID=Button_2
        """      Button:  at Tab_3(3,1)"""
        pass
        # >>>>>>insert any user code below this comment for section "Button_2_Click"
        # replace, delete, or comment-out the following
        print( "executed method Button_2_Click" )

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Treeview_1_Click"
    def Treeview_1_Click(self, event): #bind method for component ID=Treeview_1
        """    Treeview:  at Tab_3(2,2)"""
        pass
        # >>>>>>insert any user code below this comment for section "Treeview_1_Click"
        # replace, delete, or comment-out the following
        print( "executed method Treeview_1_Click" )

        curItem = self.Treeview_1.focus()
        print( "current Treeview item(s) =",self.Treeview_1.item( curItem ) )
    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Checkbutton_2_StringVar_traceName"
    def Checkbutton_2_StringVar_Callback(self, varName, index, mode):
        """ Checkbutton:  at Frame_1(1,1)"""
        pass

        # >>>>>>insert any user code below this comment for section "Checkbutton_2_StringVar_traceName"
        # replace, delete, or comment-out the following
        print( "Checkbutton_2_StringVar_Callback varName, index, mode",varName, index, mode )
        print( "    new StringVar value =",self.Checkbutton_2_StringVar.get() )



    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Combobox_2_StringVar_traceName"
    def Combobox_2_StringVar_Callback(self, varName, index, mode):
        """    Combobox: Mine Yours Ours : at Frame_1(2,1)"""
        pass

        # >>>>>>insert any user code below this comment for section "Combobox_2_StringVar_traceName"
        # replace, delete, or comment-out the following
        print( "Combobox_2_StringVar_Callback varName, index, mode",varName, index, mode )
        print( "    new StringVar value =",self.Combobox_2_StringVar.get() )



    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Entry_2_StringVar_traceName"
    def Entry_2_StringVar_Callback(self, varName, index, mode):
        """       Entry:  at Frame_1(3,1)"""
        pass

        # >>>>>>insert any user code below this comment for section "Entry_2_StringVar_traceName"
        # replace, delete, or comment-out the following
        print( "Entry_2_StringVar_Callback varName, index, mode",varName, index, mode )
        print( "    new StringVar value =",self.Entry_2_StringVar.get() )



    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Menubutton_1_StringVar_traceName"
    def Menubutton_1_StringVar_Callback(self, varName, index, mode):
        """  Menubutton:  at LabelFrame_2(1,1)"""
        pass

        # >>>>>>insert any user code below this comment for section "Menubutton_1_StringVar_traceName"
        # replace, delete, or comment-out the following
        print( "Menubutton_1_StringVar_Callback varName, index, mode",varName, index, mode )
        print( "    new StringVar value =",self.Menubutton_1_StringVar.get() )



    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Scale_1_StringVar_traceName"
    def Scale_1_StringVar_Callback(self, varName, index, mode):
        """       Scale: 2.5 to 7.5 : at Tab_5(2,1)"""
        pass

        # >>>>>>insert any user code below this comment for section "Scale_1_StringVar_traceName"
        # replace, delete, or comment-out the following
        print( "Scale_1_StringVar_Callback varName, index, mode",varName, index, mode )
        print( "    new StringVar value =",self.Scale_1_StringVar.get() )



    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Spinbox_1_StringVar_traceName"
    def Spinbox_1_StringVar_Callback(self, varName, index, mode):
        """     Spinbox: 1 to 10 : at Tab_5(3,1)"""
        pass

        # >>>>>>insert any user code below this comment for section "Spinbox_1_StringVar_traceName"
        # replace, delete, or comment-out the following
        print( "Spinbox_1_StringVar_Callback varName, index, mode",varName, index, mode )
        print( "    new StringVar value =",self.Spinbox_1_StringVar.get() )



    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "RadioGroup_1_StringVar_traceName"
    def RadioGroup_1_StringVar_Callback(self, varName, index, mode):
        """  RadioGroup:  at Tab_4(1,1)"""
        pass

        # >>>>>>insert any user code below this comment for section "RadioGroup_1_StringVar_traceName"
        # replace, delete, or comment-out the following
        print( "RadioGroup_1_StringVar_Callback varName, index, mode",varName, index, mode )
        print( "    new StringVar value =",self.RadioGroup_1_StringVar.get() )
Esempio n. 7
0
class SearchFrame:
    def __init__(self, parent):
        self.parent = parent
        self.topFrame = Frame(self.parent.windowFrame, relief=GROOVE, highlightbackground="grey", highlightcolor="grey", highlightthickness=1)
        self.middleFrame = Frame(self.parent.windowFrame, relief=GROOVE, highlightbackground="grey", highlightcolor="grey", highlightthickness=1)
        self.bottomFrame = Frame(self.parent.windowFrame, relief=GROOVE, highlightbackground="grey", highlightcolor="grey", highlightthickness=1)
        self.bottomestFrame = Frame(self.parent.windowFrame)

        self.site = StringVar()
        self.currentTeam = StringVar()

        self.filterFrame = Frame(self.topFrame)
        self.appliedFilterFrame = Frame(self.topFrame)
        self.appliedFilterButtonFrame = Frame(self.topFrame)
        self.selectedStreamsFrame = Frame(self.middleFrame)
        self.streamButtonFrame = Frame(self.middleFrame)
        self.urlFrame = Frame(self.bottomFrame)
        self.streamStartButtonFrame = Frame(self.bottomestFrame)

        self.comboboxTeam = None
        self.buttonTeam = None
        self.comboboxTag = None
        self.buttonTag = None
        self.appliedFiltersListbox = None
        self.buttonRemove = None
        self.buttonReset = None
        self.selectedStreamsListbox = None
        self.buttonClearAllStreams = None
        self.buttonRemoveSelectedStreams = None
        self.siteDropdown = None
        self.buttonOk = None

        self.gridFrames()

        self.populateFilterFrame()
        self.populateAppliedFilterFrame()
        self.populateButtonFrame()
        self.populateSelectedStreamsFrame()
        self.populateStreamButtonFrame()
        self.populateUrlFrame()
        self.populateStreamStartButtonFrame()

    def gridFrames(self):
        self.filterFrame.grid(row=0, sticky=NSEW)
        self.appliedFilterFrame.grid(row=1, sticky=NSEW)
        self.appliedFilterButtonFrame.grid(row=2, sticky=NSEW)
        self.selectedStreamsFrame.grid(row=0, sticky=NSEW)
        self.streamButtonFrame.grid(row=1, sticky=NSEW)
        self.urlFrame.grid(row=0, sticky=NSEW)
        self.streamStartButtonFrame.grid(row=0, sticky=NSEW)

    def populateFilterFrame(self):
        labelFilters = Label(self.filterFrame, text=LabelConstants.FILTERS)
        labelFilters.grid(row=0, column=0, sticky=W, columnspan=2, padx=4, pady=4)

        labelTeam = Label(self.filterFrame, text=LabelConstants.SEARCH_TEAMS)
        labelTeam.grid(row=1, column=0, sticky=W, columnspan=2, padx=4, pady=4)
        self.comboboxTeam = Combobox(self.filterFrame, textvariable=self.currentTeam, values=list(self.parent.teams.keys()), state="readonly", width=32)
        self.comboboxTeam.current(0)
        self.comboboxTeam.grid(row=2, column=0, columnspan=2, padx=4, pady=4)

    def populateAppliedFilterFrame(self):
        labelAppliedFilters = Label(self.appliedFilterFrame, text=LabelConstants.SEARCH_TAG)
        labelAppliedFilters.grid(row=0, column=0, sticky=W, columnspan=2, padx=4, pady=4)
        scrollbarAppliedFilters = Scrollbar(self.appliedFilterFrame)
        scrollbarAppliedFilters.grid(row=1, column=1, sticky="NWS")
        self.appliedFiltersListbox = Listbox(self.appliedFilterFrame, selectmode=MULTIPLE, yscrollcommand=scrollbarAppliedFilters.set, activestyle=NONE, width=33)
        scrollbarAppliedFilters.config(command=self.appliedFiltersListbox.yview)
        self.populateTwitchTagsListbox()
        self.appliedFiltersListbox.grid(row=1, column=0, sticky=NSEW, padx=(4, 0))
        self.appliedFiltersListbox.configure(exportselection=False)

    def populateTwitchTagsListbox(self):
        self.appliedFiltersListbox.delete(0, END)
        activeTags = [tag for tag in self.parent.tags if tag.isActive]
        for tag in list(map(lambda x: x.localizationNames['en-us'], activeTags)):
            self.appliedFiltersListbox.insert(END, tag)

    def populateButtonFrame(self):
        self.buttonRemove = Button(self.appliedFilterButtonFrame, text=LabelConstants.RESET, width=10, command=lambda: self.clearAllTags())
        self.buttonRemove.grid(row=0, column=0, sticky=NSEW, padx=4, pady=4)
        self.buttonReset = Button(self.appliedFilterButtonFrame, text=LabelConstants.REFRESH_STREAMS, width=16, command=lambda: self.parent.scrollableFrame.refresh())
        self.buttonReset.grid(row=0, column=1, sticky=NSEW, padx=4, pady=4)

    def populateSelectedStreamsFrame(self):
        labelSelectedStreamsFrame = Label(self.selectedStreamsFrame, text=LabelConstants.SELECTED_STREAMS)
        labelSelectedStreamsFrame.grid(row=0, column=0, sticky=W, columnspan=2, padx=4, pady=4)
        scrollbarSelectedStreams = Scrollbar(self.selectedStreamsFrame)
        scrollbarSelectedStreams.grid(row=1, column=1, sticky="NWS")
        self.selectedStreamsListbox = Listbox(self.selectedStreamsFrame, selectmode=MULTIPLE, yscrollcommand=scrollbarSelectedStreams.set, activestyle=NONE, width=33)
        scrollbarSelectedStreams.config(command=self.selectedStreamsListbox.yview)
        self.selectedStreamsListbox.grid(row=1, column=0, sticky=NSEW, padx=(4, 0))
        self.selectedStreamsListbox.configure(exportselection=False)

    def populateStreamButtonFrame(self):
        self.buttonClearAllStreams = Button(self.streamButtonFrame, text=LabelConstants.RESET, width=10, command=lambda: self.resetStreams())
        self.buttonClearAllStreams.grid(row=0, column=0, sticky=NSEW, padx=4, pady=4)
        self.buttonRemoveSelectedStreams = Button(self.streamButtonFrame, text=LabelConstants.REMOVE, width=16, command=lambda: self.removeStreams())
        self.buttonRemoveSelectedStreams.grid(row=0, column=1, sticky=NSEW, padx=4, pady=4)

    def populateUrlFrame(self):
        labelSiteDropdown = Label(self.urlFrame, text=LabelConstants.STREAM_DROPDOWN)
        labelSiteDropdown.grid(row=0, column=0, sticky=W, padx=4, pady=4)
        self.siteDropdown = Combobox(self.urlFrame, textvariable=self.site, state="readonly", values=list(URLConstants.ORDERED_STREAMING_SITES.keys()), width=32)
        self.siteDropdown.bind("<<ComboboxSelected>>", self.updateURLSetting)
        self.siteDropdown.grid(row=1, column=0, sticky=NSEW, padx=4, pady=4)

    def populateStreamStartButtonFrame(self):
        self.buttonOk = Button(self.streamStartButtonFrame, text=LabelConstants.OPEN_STREAMS, width=32, height=2, command=lambda: self.openURL())
        self.buttonOk.grid(row=0, column=0, sticky="new", pady=(0,4))

    def clearAllTags(self):
        self.appliedFiltersListbox.selection_clear(0, END)

    def resetStreams(self):
        self.selectedStreamsListbox.delete(0, END)
        self.parent.scrollableFrame.updateStreamFrameBorders([])

    def removeStreams(self):
        for idx in reversed(self.selectedStreamsListbox.curselection()):
            self.selectedStreamsListbox.delete(idx)
        self.parent.scrollableFrame.updateStreamFrameBorders(self.selectedStreamsListbox.get(0, END))

    def updateURLSetting(self, event=None):
        self.parent.settings[LabelConstants.SETTINGS_JSON][MiscConstants.KEY_OPEN_STREAMS_ON] = self.siteDropdown.get()
        writeSettings(self.parent.settings)

    def openURL(self):
        finalURL = URLConstants.ORDERED_STREAMING_SITES.get(self.siteDropdown.get())
        isRareDrop = finalURL == URLConstants.RAREDROP
        watchingSingleStreamOnTwitch = False
        if len(self.selectedStreamsListbox.get(0, END)) == 1 and finalURL != URLConstants.TWITCH and messagebox.askyesno(LabelConstants.TWITCH, MessageConstants.WATCH_ON_TWITCH):
            finalURL = URLConstants.TWITCH
            watchingSingleStreamOnTwitch = True
        if not watchingSingleStreamOnTwitch and not self.siteDropdown.get():
            messagebox.showerror(LabelConstants.ERROR, MessageConstants.NO_SITE_SELECTED)
        elif len(self.selectedStreamsListbox.get(0, END)) > 0:
            if finalURL == URLConstants.TWITCH:
                for stream in self.selectedStreamsListbox.get(0, END):
                    webbrowser.open(finalURL + stream, new=2)
            else:
                for stream in self.selectedStreamsListbox.get(0, END):
                    if isRareDrop:
                        finalURL += "t" + stream + "/"
                    else:
                        finalURL += stream + "/"
                webbrowser.open(finalURL, new=2)
        else:
            messagebox.showerror(LabelConstants.ERROR, MessageConstants.NO_STREAMS_SELECTED)

    def updateComboboxTeam(self):
        self.comboboxTeam.configure(values=list(self.parent.teams.keys()))
        self.comboboxTeam.current(0)

    def getAllSelectedTags(self) -> List[Tag]:
        tagDict = dict(zip([t.localizationNames["en-us"] for t in self.parent.tags], [tag for tag in self.parent.tags]))
        selectedTags = []
        for idx in self.appliedFiltersListbox.curselection():
            selectedTags.append(tagDict[self.appliedFiltersListbox.get(idx)])
        return selectedTags
class NewNoteFrame(Frame):
    """"Window that provides UI(input fields and buttons) necessary for creating new note
    Derives from class Frame"""

    # class variables
    ipadx_val = 1
    ipady_val = 10
    label_font = '"Century Gothic" 10 bold'
    lbl_ctgr_text = 'Category:'
    lbl_dscr_text = 'Description:'
    lbl_date_text = 'Date:'
    lbl_prrt_text = 'Priority:'
    data_font = '"Segoe Print" 11'
    btn_width = 6
    btn_conf_text = 'Confirm'
    btn_cancel_text = 'Cancel'
    btn_font = 'Arial 9'
    btn_padx = 25
    btn_pady = 35

    def __init__(self, master):
        """ctor"""
        super().__init__(master)
        self.pack(fill=BOTH, expand=True)

        # setting default priority to Normal, corresponding background color is lightyellow
        bgcolor = prrt2color_dict[
            priority_names_lst[1]]  # 'Normal':'lightyellow'
        self.create_widgets(master, bgcolor)

    def create_widgets(self, master, bg_color):
        """This method defines UI of the New Note window"""
        self.frm_main_newnote = Frame(self, bg=bg_color)
        self.frm_main_newnote.pack(fill=BOTH)

        self.lbl_category = Label(self.frm_main_newnote,
                                  bg=bg_color,
                                  font=__class__.label_font,
                                  text=__class__.lbl_ctgr_text)
        self.lbl_category.grid(row=0,
                               column=0,
                               sticky=W,
                               ipadx=__class__.ipadx_val,
                               ipady=__class__.ipady_val)

        self.cmbx_category = Combobox(self.frm_main_newnote,
                                      width=12,
                                      font=__class__.data_font)  # ttk.Combobox
        self.cmbx_category.configure(
            values=category_names_lst
        )  # the values are: Personal, College, Work, Home
        self.cmbx_category.current(0)  # i.e. default value is 'Personal'
        self.cmbx_category.grid(row=0,
                                column=1,
                                columnspan=2,
                                sticky=W,
                                ipadx=__class__.ipadx_val)

        self.lbl_description = Label(self.frm_main_newnote,
                                     bg=bg_color,
                                     font=__class__.label_font,
                                     text=__class__.lbl_dscr_text)
        self.lbl_description.grid(row=2,
                                  column=0,
                                  sticky=W,
                                  ipadx=__class__.ipadx_val,
                                  ipady=__class__.ipady_val)

        self.entry_description = Entry(self.frm_main_newnote,
                                       width=14,
                                       font=__class__.data_font)
        self.entry_description.grid(row=2,
                                    column=1,
                                    columnspan=2,
                                    sticky=W,
                                    ipadx=__class__.ipadx_val)

        self.lbl_date = Label(self.frm_main_newnote,
                              bg=bg_color,
                              font=__class__.label_font,
                              text=__class__.lbl_date_text)
        self.lbl_date.grid(row=4,
                           column=0,
                           sticky=W,
                           ipadx=__class__.ipadx_val,
                           ipady=__class__.ipady_val)

        self.entry_date = Entry(self.frm_main_newnote,
                                width=14,
                                font=__class__.data_font)
        self.entry_date.grid(row=4,
                             column=1,
                             columnspan=2,
                             sticky=W,
                             ipadx=__class__.ipadx_val)

        self.lbl_priority = Label(self.frm_main_newnote,
                                  bg=bg_color,
                                  font=__class__.label_font,
                                  text=__class__.lbl_prrt_text)
        self.lbl_priority.grid(row=6,
                               column=0,
                               sticky=W,
                               ipadx=__class__.ipadx_val,
                               ipady=__class__.ipady_val)

        self.cmbx_priority = Combobox(self.frm_main_newnote,
                                      width=12,
                                      font=__class__.data_font)  # ttk.Combobox
        self.cmbx_priority.configure(
            values=priority_names_lst)  # the values are: High, Normal, Low
        self.cmbx_priority.current(1)  # i.e. default value is 'Normal'
        self.cmbx_priority.bind("<<ComboboxSelected>>",
                                self.action_priority2bgcolor)
        self.cmbx_priority.grid(row=6,
                                column=1,
                                columnspan=2,
                                sticky=W,
                                ipadx=__class__.ipadx_val)

        btn_confirm = Button(
            self.frm_main_newnote,
            font=__class__.btn_font,
            width=__class__.btn_width,
            text=__class__.btn_conf_text,
            command=master.destroy)  # master is NewNote dialog
        btn_confirm.bind('<Button-1>', self.action_add_note)
        btn_confirm.grid(row=8,
                         column=1,
                         sticky=E,
                         padx=__class__.btn_padx,
                         pady=__class__.btn_pady)

        self.btn_cancel = Button(
            self.frm_main_newnote,
            font=__class__.btn_font,
            width=__class__.btn_width,
            text=__class__.btn_cancel_text,
            command=master.destroy
        )  # master = dlgNewNote  #self.frm_buttons_view
        self.btn_cancel.grid(row=8,
                             column=2,
                             sticky=W,
                             pady=__class__.btn_pady)

    def action_add_note(self, event):
        """This method registers new note;
        activated by click on button Confirm"""
        # reading note details from UI
        category_str = self.cmbx_category.get().strip()
        descr_str = self.entry_description.get().strip()
        date_str = self.entry_date.get().strip()
        priority_str = self.cmbx_priority.get().strip()

        new_note_obj = NotePureData(
            category_str, descr_str, date_str,
            priority_str)  # object of class NotePureData
        notes_dict[
            new_note_obj.
            id] = new_note_obj  # adding new note object to the notes dictionary
        aux_filter_notes(category_filter_ctrlvar.get(),
                         descr_filter_ctrlvar.get())

        display_notes()
        db_insert_note(new_note_obj)  # adding new note to the database

    def action_priority2bgcolor(self, event):
        """This method defines background color of the frame according to currently selected priority;
        activated by selection of a value from the Priority combo-box"""
        priority = self.cmbx_priority.get()

        # setting value of the background color according to the current task priority
        bgcolor = prrt2color_dict[
            priority]  # {'Low':'lightgreen', 'Normal':'lightyellow', 'High':'lightpink'}

        # setting background color of the NewNote frame and of the relevant widgets
        self.frm_main_newnote.configure(bg=bgcolor)
        widgets_lst = [
            w for w in self.frm_main_newnote.winfo_children()
            if isinstance(w, Label)
        ]
        for w in widgets_lst:
            w.configure(bg=bgcolor)
Esempio n. 9
0
class _propellants(_Dialog):
    def body(self, master):
        dialogframe = Frame(master, width=350, height=135)
        self.dialogframe = dialogframe
        dialogframe.pack()

        self.make_Combobox_1(
            self.dialogframe)  #    Combobox: Oxidizer : at Main(3,1)
        self.make_Combobox_2(
            self.dialogframe)  #    Combobox: Fuel : at Main(3,2)
        self.make_Label_1(
            self.dialogframe)  #       Label: Oxidizer : at Main(2,1)
        self.make_Label_2(self.dialogframe)  #       Label: Fuel : at Main(2,2)
        self.make_Label_3(
            self.dialogframe
        )  #       Label: Select Oxidizer and Fuel : at Main(1,1)
        self.make_Label_4(self.dialogframe)  #       Label:  at Main(0,1)
        self.make_Label_5(self.dialogframe)  #       Label:  at Main(2,0)
        self.make_Label_6(self.dialogframe)  #       Label:  at Main(2,3)

        # >>>>>>insert any user code below this comment for section "top_of_init"

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Combobox_1"
    def make_Combobox_1(self, frame):
        """    Combobox: Oxidizer : at Main(3,1)"""
        self.Combobox_1 = Combobox(frame,
                                   values="Mine Yours Ours",
                                   text="Oxidizer")
        self.Combobox_1.grid(row=3, column=1)
        self.Combobox_1_StringVar = StringVar()

        # >>>>>>insert any user code below this comment for section "make_Combobox_1"

        self.Combobox_1.configure(values=' '.join(oxidizerL))

        self.Combobox_1.configure(textvariable=self.Combobox_1_StringVar)
        self.Combobox_1_StringVar.set(self.dialogOptions['oxName'])
        self.Combobox_1_StringVar_traceName = self.Combobox_1_StringVar.trace_variable(
            "w", self.Combobox_1_StringVar_Callback)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Combobox_2"
    def make_Combobox_2(self, frame):
        """    Combobox: Fuel : at Main(3,2)"""
        self.Combobox_2 = Combobox(frame,
                                   values="Mine Yours Ours",
                                   text="Fuel")
        self.Combobox_2.grid(row=3, column=2)
        self.Combobox_2_StringVar = StringVar()

        # >>>>>>insert any user code below this comment for section "make_Combobox_2"
        self.Combobox_2.configure(values=' '.join(fuelL))

        self.Combobox_2.configure(textvariable=self.Combobox_2_StringVar)
        self.Combobox_2_StringVar.set(self.dialogOptions['fuelName'])
        self.Combobox_2_StringVar_traceName = self.Combobox_2_StringVar.trace_variable(
            "w", self.Combobox_2_StringVar_Callback)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_1"
    def make_Label_1(self, frame):
        """       Label: Oxidizer : at Main(2,1)"""
        self.Label_1 = Label(frame, text="Oxidizer", width="15")
        self.Label_1.grid(row=2, column=1)

        # >>>>>>insert any user code below this comment for section "make_Label_1"

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_2"
    def make_Label_2(self, frame):
        """       Label: Fuel : at Main(2,2)"""
        self.Label_2 = Label(frame, text="Fuel", width="15")
        self.Label_2.grid(row=2, column=2)

        # >>>>>>insert any user code below this comment for section "make_Label_2"

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_3"
    def make_Label_3(self, frame):
        """       Label: Select Oxidizer and Fuel : at Main(1,1)"""
        self.Label_3 = Label(frame,
                             text="Select Oxidizer and Fuel",
                             width="30")
        self.Label_3.grid(row=1, column=1, columnspan="2")

        # >>>>>>insert any user code below this comment for section "make_Label_3"

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_4"
    def make_Label_4(self, frame):
        """       Label:  at Main(0,1)"""
        self.Label_4 = Label(frame, text="", width="15", height="2")
        self.Label_4.grid(row=0, column=1)

        # >>>>>>insert any user code below this comment for section "make_Label_4"

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_5"
    def make_Label_5(self, frame):
        """       Label:  at Main(2,0)"""
        self.Label_5 = Label(frame, text="", width="8")
        self.Label_5.grid(row=2, column=0)

        # >>>>>>insert any user code below this comment for section "make_Label_5"

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_6"
    def make_Label_6(self, frame):
        """       Label:  at Main(2,3)"""
        self.Label_6 = Label(frame, text="", width="8")
        self.Label_6.grid(row=2, column=3)

        # >>>>>>insert any user code below this comment for section "make_Label_6"

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Combobox_1_StringVar_traceName"
    def Combobox_1_StringVar_Callback(self, varName, index, mode):
        """    Combobox: Oxidizer : at Main(3,1)"""
        pass

        # >>>>>>insert any user code below this comment for section "Combobox_1_StringVar_traceName"
        # replace, delete, or comment-out the following
        print("Combobox_1_StringVar_Callback varName, index, mode", varName,
              index, mode)
        print("    new StringVar value =", self.Combobox_1_StringVar.get())

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Combobox_2_StringVar_traceName"
    def Combobox_2_StringVar_Callback(self, varName, index, mode):
        """    Combobox: Fuel : at Main(3,2)"""
        pass

        # >>>>>>insert any user code below this comment for section "Combobox_2_StringVar_traceName"
        # replace, delete, or comment-out the following
        print("Combobox_2_StringVar_Callback varName, index, mode", varName,
              index, mode)
        print("    new StringVar value =", self.Combobox_2_StringVar.get())

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "dialog_validate"
    def validate(self):
        self.result = {}  # return a dictionary of results

        #self.result["Combobox_1"] = self.Combobox_1_StringVar.get()
        #self.result["Combobox_2"] = self.Combobox_2_StringVar.get()

        # >>>>>>insert any user code below this comment for section "dialog_validate"
        # set values in "self.result" dictionary for return
        # for example...
        # self.result["age"] = self.Entry_2_StringVar.get()
        self.result["oxName"] = self.Combobox_1_StringVar.get()
        self.result["fuelName"] = self.Combobox_2_StringVar.get()
        """
    # for testing, reinstate this code below
        dialog = _propellants(self.master, "Propellants Dialog", 
                 dialogOptions={'oxName':'LOX', 'fuelName':'MMH'})

        """

        #self.result["test"] = "test message"
        return 1


# TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "end"

    def apply(self):
        pass
Esempio n. 10
0
class CombatManager(Tk):
    def __init__(self):
        Tk.__init__(self)
        self.title("Combat Manager")

        # allows row 0 (=frame, textframe) to expand vertically
        self.rowconfigure(0, weight=1)
        # allows column 5 (=buttonframe) to expand horizontally
        self.columnconfigure(5, weight=1)

        self.entities = []
        self.queue = EntityQueue()
        self.started = False
        self.textcommandhistory = []
        self.commandhistory = CommandHistory()
        self.names = dict()
        self.damage = 1
        # Menu
        self.menubar = Menu(self)
        # File Menu
        self.filemenu = Menu(self.menubar, tearoff=0)
        self.filemenu.add_command(label="Load Entity",
                                  command=self.loadEntityCallback)
        self.filemenu.add_command(label="Load Players",
                                  command=self.loadPlayersCallback)
        self.filemenu.add_separator()
        self.filemenu.add_command(label="Save Fight",
                                  command=self.saveFightCallback,
                                  state="disable")
        self.filemenu.add_command(label="Load Fight",
                                  command=self.loadFightCallback)
        self.filemenu.add_separator()
        self.filemenu.add_command(label="Settings",
                                  command=self.settingsCallback)
        self.filemenu.add_separator()
        self.filemenu.add_command(label="Exit", command=self.exitCallback)

        #Tools Menu
        self.toolsmenu = Menu(self.menubar, tearoff=0)
        self.toolsmenu.add_command(label="Die Roll",
                                   command=self.dierollCallback)
        self.toolsmenu.add_command(label="Group Damage",
                                   command=self.groupdamageCallback,
                                   state="disable")

        self.menubar.add_cascade(label="Menu", menu=self.filemenu)
        self.menubar.add_cascade(label="Tools", menu=self.toolsmenu)
        self.config(menu=self.menubar)

        #VerticalScrolledFrame containing EntityFrames
        self.frame = VerticalScrolledFrame(self, borderwidth=2, relief=RIDGE)
        self.frame.grid(row=0, column=0, columnspan=4, sticky=NSEW)

        # start, add, clear and load buttons
        self.startButton = Button(self,
                                  text="Start",
                                  command=self.startCallback)
        # self.startButton.grid(row=1,column=0,sticky=EW,padx=5,pady=5)
        self.startButton.grid(row=1,
                              column=0,
                              rowspan=2,
                              sticky=NSEW,
                              padx=5,
                              pady=5)

        self.loadButton = Button(self,
                                 text="Load Entity",
                                 command=self.loadEntityCallback)
        # self.loadButton.grid(row=1,column=1,sticky=EW,padx=5,pady=5)
        self.loadButton.grid(row=1,
                             column=1,
                             rowspan=2,
                             sticky=NSEW,
                             padx=5,
                             pady=5)

        self.clearButton = Button(self,
                                  text="Clear",
                                  command=self.clearCallback)
        # self.clearButton.grid(row=1,column=2,sticky=EW,padx=5,pady=5)
        self.clearButton.grid(row=1,
                              column=2,
                              rowspan=2,
                              sticky=NSEW,
                              padx=5,
                              pady=5)

        self.addButton = Button(self, text="+", command=self.addCallback)
        # self.addButton.grid(row=1,column=3,sticky=E,padx=5,pady=5)
        self.addButton.grid(row=1,
                            column=3,
                            rowspan=2,
                            sticky=NSEW,
                            padx=5,
                            pady=5)

        #EntityQueueuFrame containing the EntityQueue
        self.eqf = EntityQueueFrame(self, self)
        self.eqf.grid(row=0, column=4, columnspan=2, sticky=NSEW)

        #Damage entry, half damage tickbox, in seperate frame
        self.damageFrame = Frame(self)
        self.damageFrame.grid(row=1, column=4, padx=5, pady=5, rowspan=2)
        self.damageFrame['bd'] = 1
        self.damageFrame['relief'] = 'ridge'
        Label(self.damageFrame, text="Damage:").grid(row=0,
                                                     column=0,
                                                     sticky=W,
                                                     padx=5,
                                                     pady=5)
        self.damageVar = IntVar()
        self.damageVar.set(1)
        self.damageVar.trace('w', self.damageCallback)
        self.damageEntry = Entry(self.damageFrame,
                                 width=2,
                                 textvariable=self.damageVar,
                                 state='disabled')
        self.damageEntry.bind('<ButtonRelease-1>', self.damageEntryCallback)
        self.damageEntry.grid(row=0, column=1, sticky=W, padx=5, pady=5)
        Label(self.damageFrame, text="Half Damage:").grid(row=1,
                                                          column=0,
                                                          sticky=W,
                                                          padx=5,
                                                          pady=5)
        self.halfdamage = BooleanVar()
        self.halfdamage.set(False)
        self.halfdamage.trace('w', self.damageCallback)
        self.halfdamageCheckbutton = Checkbutton(self.damageFrame,
                                                 variable=self.halfdamage,
                                                 state='disabled')
        self.halfdamageCheckbutton.grid(row=1,
                                        column=1,
                                        sticky=W,
                                        padx=5,
                                        pady=5)

        # command line, run ,undo, redo and next buttons in seperate frame
        self.buttonFrame = Frame(self)
        self.buttonFrame.grid(row=1,
                              column=5,
                              padx=5,
                              pady=5,
                              rowspan=2,
                              sticky=EW)
        for i in range(5):
            self.buttonFrame.columnconfigure(i, weight=1)

        self.nextButton = Button(self.buttonFrame,
                                 text="Next",
                                 command=self.nextCallback,
                                 state='disabled')
        self.nextButton.grid(row=0,
                             column=0,
                             columnspan=5,
                             sticky=EW,
                             padx=5,
                             pady=5)

        self.commandstring = StringVar()
        Label(self.buttonFrame, text="Command:").grid(row=1,
                                                      column=0,
                                                      sticky=E,
                                                      padx=5,
                                                      pady=5)
        self.commandEntry = Combobox(self.buttonFrame,
                                     textvariable=self.commandstring,
                                     state='disabled',
                                     postcommand=self.updateHistory)
        self.commandEntry.bind('<Return>', self.runCallback)
        self.commandEntry.bind('<KP_Enter>', self.runCallback)
        self.commandEntry.grid(row=1, column=1, sticky=EW, padx=5, pady=5)
        self.runButton = Button(self.buttonFrame,
                                text="Run",
                                command=self.runCallback,
                                state='disabled')
        self.runButton.grid(row=1, column=2, sticky=EW, padx=5, pady=5)
        self.undoButton = Button(self.buttonFrame,
                                 text="Undo",
                                 command=self.undoCallback,
                                 state='disabled')
        self.undoButton.grid(row=1, column=3, sticky=EW, padx=5, pady=5)
        self.redoButton = Button(self.buttonFrame,
                                 text="Redo",
                                 command=self.redoCallback,
                                 state='disabled')
        self.redoButton.grid(row=1, column=4, sticky=EW, padx=5, pady=5)

        # General Key Bindings
        self.bind('<Control-q>', self.exitCallback)
        self.bind('<Control-z>', self.undoCallback)
        self.bind('<Control-Z>', self.redoCallback)
        self.bind('<Control-n>', self.nextCallback)
        self.bind('<Control-o>', self.loadFightCallback)
        self.bind('<Control-s>', self.saveFightCallback)
        self.bind('<Control-c>', self.focusCallback)

        # Load Settings
        self.loadSettings()

    def configureCanvas(self, event):
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))

    def updatename(self, name):
        for e in self.queue:
            if e.name == name:
                e.name = name + ' 1'

    def loadSettings(self):
        if os.path.exists('settings.json'):
            try:
                f = open('settings.json', 'r')
                self.settings = json.load(f)
                f.close()
            except OSError:
                messagebox.showerror('Load Settings',
                                     'Could not load settings')
            except (KeyError, TypeError):
                messagebox.showerror('Load Settings',
                                     'Settings file not in correct format')
        else:
            self.initializeSettings()

    def initializeSettings(self):
        currentdir = os.getcwd()
        self.settings = dict()
        self.settings['fightdir'] = currentdir
        self.settings['entitydir'] = currentdir
        self.settings['playerfiles'] = []
        try:
            f = open('settings.json', 'w')
            json.dump(self.settings, f)
            f.close()
        except OSError:
            messagebox.showerror("Save Settings", "Could not save settings")

    def updateHistory(self):
        # use splicing to reverse list
        self.commandEntry.configure(values=[''] +
                                    self.textcommandhistory[::-1])

    def addCallback(self):
        e = EntryFrame(self.frame.interior, self)
        e.pack(padx=5, pady=5)
        index = len(self.entities)
        self.entities.append(e)
        e.setIndex(index)
        return e

    def updateIndices(self):
        for i in range(len(self.entities)):
            self.entities[i].setIndex(i)

    # enables certain widgets on start
    def enableWidgetsOnStart(self):
        self.damageEntry['state'] = 'normal'
        self.halfdamageCheckbutton['state'] = 'normal'
        self.commandEntry['state'] = 'normal'
        self.runButton['state'] = 'normal'
        # self.undoButton['state']='normal'
        # self.redoButton['state']='normal'
        self.nextButton['state'] = 'normal'
        for ef in self.entities:
            if not ef.player.get():
                ef.addToCombatButton['state'] = 'normal'
                # ef.autoroll.set(False)
        self.filemenu.entryconfig("Save Fight", state='normal')
        self.toolsmenu.entryconfig("Group Damage", state='normal')

    # disables certain widgets on stop
    def disableWidgetsOnStop(self):
        self.damageEntry['state'] = 'disabled'
        self.halfdamageCheckbutton['state'] = 'disabled'
        self.commandEntry['state'] = 'disabled'
        self.runButton['state'] = 'disabled'
        self.undoButton['state'] = 'disabled'
        self.redoButton['state'] = 'disabled'
        self.nextButton['state'] = 'disabled'
        for ef in self.entities:
            if not ef.player.get():
                ef.addToCombatButton['state'] = 'disabled'
                # ef.autoroll.set(True)
        self.filemenu.entryconfig("Save Fight", state='disable')
        self.toolsmenu.entryconfig("Group Damage", state='disable')

    #external callbacks (=called from object other than combatmanager)
    def addToCombat(self, e):
        if e.hasError():
            messagebox.showwarning("Add Entity",
                                   "One or more entries contain errors.")
            return
        rd = RollDialog(self, [e], self.names)
        if rd.rolls == None:
            return
        else:
            i = 0
            entities = []
            for j in range(e.amount.get()):
                entities.append(
                    Entity(rd.names[i], e.bonus.get(),
                           dice.getHealth(e.health.get()), rd.rolls[i],
                           e.ac.get(), e.player.get()))
                i += 1

            command = AddCommand(self.queue, entities)
            self.executeCommand(command)

    def startCallback(self):
        error = False
        if len(self.entities) == 0:
            return
        # two passes: one to check if any errors popped up, if not: one to actually make entities and append
        # entities
        for e in self.entities:
            if e.hasError():
                error = True
        if error:
            messagebox.showwarning("Start",
                                   "One or more entries contain errors.")
        else:

            if self.started:
                if messagebox.askyesno(
                        "Start",
                        "Are you sure you  want to restart combat? Progress will be lost."
                ):
                    self.queue.clear()
                    self.names.clear()
                else:
                    return
            # second pass
            rd = RollDialog(self, self.entities, self.names)
            # print(self.names)
            if rd.rolls == None:
                self.names.clear()
                return
            else:
                i = 0
                for e in self.entities:
                    for j in range(e.amount.get()):
                        self.queue.append(
                            Entity(rd.names[i], e.bonus.get(),
                                   dice.getHealth(e.health.get()), rd.rolls[i],
                                   e.ac.get(), e.player.get()))
                        i += 1

                #self.queue.sort()
                self.refreshDisplay()

                self.enableWidgetsOnStart()
                self.started = True

    def damageEntryCallback(self, event=None):
        self.halfdamage.set(False)
        self.damageEntry.selection_range(0, END)
        return 'break'

    def damageCallback(self, *args):
        try:
            if self.halfdamage.get():
                self.damage = int(self.damageVar.get() / 2)
            else:
                self.damage = self.damageVar.get()
            self.refreshDisplay()
        except:
            pass

    def nextCallback(self, event=None):
        if self.started:
            command = NextCommand(self.queue)
            command.execute()
            self.commandhistory.append(command)
            self.checkCommandHistory()
            self.refreshDisplay()

    def runCallback(self, event=None):
        commandstring = self.commandstring.get()
        commandstring = commandstring.split()
        command = None
        if len(commandstring) == 0:
            pass
        # usage: next
        # make the next active entity in the queue, the acting entity
        elif (commandstring[0] == commands[0]
              or commandstring[0] == shortcuts[0]) and len(commandstring) == 1:
            command = NextCommand(self.queue)
        # usage: heal n hp
        # heals entity with index n hp points
        elif (commandstring[0] == commands[1]
              or commandstring[0] == shortcuts[1]) and len(commandstring) == 3:
            try:
                command = HealCommand(self.queue,
                                      int(commandstring[1]) - 1,
                                      int(commandstring[2]))
            except ValueError:
                messagebox.showwarning("Run", 'Not a valid number.')
        # usage: damage n hp
        # damages entity with index n hp points
        elif (commandstring[0] == commands[2]
              or commandstring[0] == shortcuts[2]) and len(commandstring) == 3:
            try:
                command = DamageCommand(self.queue,
                                        int(commandstring[1]) - 1,
                                        int(commandstring[2]))
            except ValueError:
                messagebox.showwarning("Run", 'Not a valid number.')
        # usage: remove n
        # remove entity with number n from queue
        elif (commandstring[0] == commands[3]
              or commandstring[0] == shortcuts[3]) and len(commandstring) == 2:
            try:
                command = RemoveCommand(self.queue, int(commandstring[1]) - 1)
            except ValueError:
                messagebox.showwarning("Run", 'Not a valid number.')
        # usage: restore n
        # revive a previously removed entity from the queue
        elif (commandstring[0] == commands[4]
              or commandstring[0] == shortcuts[4]) and len(commandstring) == 2:
            try:
                command = RestoreCommand(self.queue, int(commandstring[1]) - 1)
            except ValueError:
                messagebox.showwarning("Run", 'Not a valid number.')
        # usage: delay n up/down
        # delay entity with number n up or down
        elif (commandstring[0] == commands[5]
              or commandstring[0] == shortcuts[5]) and len(commandstring) == 3:
            try:
                if commandstring[2] == 'down':
                    down = True
                elif commandstring[2] == 'up':
                    down = False
                else:
                    messagebox.showwarning("Run", "Use Up/Down")
                    return
                command = DelayCommand(self.queue,
                                       int(commandstring[1]) - 1, down)
            except ValueError:
                messagebox.showwarning("Run", 'Not a valid number.')
        # help
        elif (commandstring[0] == commands[6]
              or commandstring[0] == shortcuts[6]) and len(commandstring) == 1:
            s = helpdict['help'] + '\nCommands:\n'
            for i in commands:
                s += i + '\n'
            messagebox.showinfo("Help", s)
            return
        elif (commandstring[0] == commands[6]
              or commandstring[0] == shortcuts[6]) and len(commandstring) == 2:
            try:
                messagebox.showinfo("Help", helpdict[commandstring[1]])
            except KeyError:
                s = 'Not a command\nCommands:\n'
                for i in commands:
                    s += i + '\n'
                messagebox.showinfo("Help", s)
        # stop
        elif (commandstring[0] == commands[7]
              or commandstring[0] == shortcuts[7]) and len(commandstring) == 1:
            self.exitCallback()
        else:
            messagebox.showwarning(
                "Run",
                'Unknown Command or Wrong Syntax. Use help command for, you know, help.'
            )

        # execute command
        if command is not None:
            try:
                self.executeCommand(command)
                self.textcommandhistory.append(self.commandstring.get())
                self.commandstring.set('')
            except IndexError:
                messagebox.showwarning("Run", "Index Out of Range.")

            # check if there are any enemies left
            if self.queue.activeEnemies() == 0 and self.started:
                messagebox.showinfo("Run", 'All enemies defeated.')

    def undoCallback(self, event=None):
        if self.started:
            self.commandhistory.undo()
            self.checkCommandHistory()
            self.refreshDisplay()

    def redoCallback(self, event=None):
        if self.started:
            self.commandhistory.redo()
            self.checkCommandHistory()
            self.refreshDisplay()

    def checkCommandHistory(self):
        # disable undo if at begin of commandhistory
        if self.commandhistory.atBegin():
            self.undoButton['state'] = 'disabled'
        else:
            self.undoButton['state'] = 'normal'
        # disable redo if at end of commandhistory
        if self.commandhistory.atEnd():
            self.redoButton['state'] = 'disabled'
        else:
            self.redoButton['state'] = 'normal'

    # refresh display of entityqueue
    def refreshDisplay(self):
        self.eqf.refresh()

    # clear display of entityqueue
    def clearDisplay(self):
        self.eqf.clear()

    def clearCallback(self):
        self.queue.clear()
        self.commandhistory.clear()
        self.names.clear()
        self.clearDisplay()
        for e in self.entities:
            e.destroy()
        self.entities = []
        self.started = False
        self.disableWidgetsOnStop()

    def executeCommand(self, command):
        command.execute()
        self.refreshDisplay()
        self.commandhistory.append(command)
        self.checkCommandHistory()

    # Menu Callbacks

    def loadEntityCallback(self):
        filenames = filedialog.askopenfilenames(
            initialdir=self.settings['entitydir'])
        for filename in filenames:
            try:
                f = open(filename, 'r')
                d = json.load(f)
                f.close()
                e = self.addCallback()
                e.fillIn(d)
            except OSError:
                messagebox.showerror('Load Entity',
                                     'Could not open file ' + filename)
                e.destroyCallback()
            except (KeyError, TypeError):
                messagebox.showerror(
                    'Load Entity',
                    'File ' + filename + ' not in correct format')
                e.destroyCallback()

    def saveEntityCallback(self, e):
        if e.name.get() == "":
            messagebox.showwarning("Save", "No name given.")
            return
        try:
            filename = os.path.join(self.settings['entitydir'],
                                    e.name.get() + ".json")
            f = open(filename, 'w')
            d = e.toJson()
            d['amount'] = 1
            json.dump(d, f)
            f.close()
            messagebox.showinfo("Save", "Entity saved as " + filename)
        except OSError:
            messagebox.showerror("Save", "Could not save file")

    def loadPlayersCallback(self):
        for p in self.settings['playerfiles']:
            try:
                f = open(p, 'r')
                d = json.load(f)
                f.close()
                e = self.addCallback()
                e.fillIn(d)
            except OSError:
                messagebox.showerror('Load Player', 'Could not open file ' + p)
            except (KeyError, TypeError):
                messagebox.showerror('Load Player',
                                     'File ' + p + ' not in correct format')

    def saveFightCallback(self, event=None):
        if self.started:
            filename = filedialog.asksaveasfilename(
                initialdir=self.settings['fightdir'], defaultextension=".json")
            if filename:
                try:
                    d = dict()
                    d["position"] = self.queue.position
                    d["round"] = self.queue.round
                    # iterate over entities in EntityQueue and save their dictionary representation to a list
                    entitiesList = []
                    for e in self.queue.queue:
                        entitiesList.append(e.__dict__)
                    d["queue"] = entitiesList
                    # iterate over EntityFrames and save their dictionary representation to a list
                    entityFramesList = []
                    for ef in self.entities:
                        entityFramesList.append(ef.toJson())
                    d["frames"] = entityFramesList
                    d["names"] = self.names
                    f = open(filename, 'w')
                    json.dump(d, f)
                    f.close()
                    messagebox.showinfo("Save Fight",
                                        "Fight saved as " + filename)
                except OSError:
                    messagebox.showerror("Save Fight", "Could not save file")

    def loadFightCallback(self, event=None):
        if self.started:
            if not messagebox.askyesno(
                    "Start",
                    "Are you sure you  want to restart combat? Progress will be lost."
            ):
                return
        filename = filedialog.askopenfilename(
            initialdir=self.settings['fightdir'])
        if filename:
            try:
                f = open(filename, 'r')
                d = json.load(f)
                f.close()
                self.queue.clear()
                self.queue.position = d["position"]
                self.queue.round = d["round"]
                for e in d["queue"]:
                    self.queue.append(Entity.fromDict(e))
                #self.queue.sort()
                self.refreshDisplay()
                for ef in d["frames"]:
                    e = self.addCallback()
                    e.fillIn(ef)
                self.names = d["names"]
                self.started = True
                self.enableWidgetsOnStart()
            except OSError:
                messagebox.showerror('Load Fight',
                                     'Could not open file ' + filename)
            except (KeyError, TypeError):
                messagebox.showerror(
                    'Load Fight',
                    'File ' + filename + ' not in correct format')

    def settingsCallback(self):
        sd = SettingsDialog(self, self.settings)
        print(sd.settings)
        if sd.settings is not None:
            self.settings = sd.settings
            try:
                f = open('settings.json', 'w')
                json.dump(self.settings, f)
                f.close()
            except OSError:
                messagebox.showerror("Save Settings",
                                     "Could not save settings")

    def dierollCallback(self):
        dr = DiceDialog(self)

    def groupdamageCallback(self):
        gdd = GroupDamageDialog(self, self.queue)

    def focusCallback(self, event=None):
        self.commandEntry.focus()

    def exitCallback(self, event=None):
        if messagebox.askyesno("Exit", "Are you sure you want to exit?"):
            self.destroy()
Esempio n. 11
0
class CsvFrame:
    """ Display csv data in a tkinter TreeView """

    def __init__(self, parent, manager):
        """ CsvFrame constructor """
        top = self.top = tkinter.Toplevel(parent)
        self.__parent = parent
        self.__manager = manager

        top_frame = tkinter.Frame(top, borderwidth=2, relief=tkinter.GROOVE)
        top_frame.pack(side=tkinter.TOP, fill=tkinter.X, padx=5, pady=5)

        label_data = Label(top_frame, text="Data: ")
        label_data.grid(row=1, column=1, padx=5, pady=5)
        data_select_combo3 = tkinter.StringVar()
        self.combo_data = Combobox(top_frame, textvariable=data_select_combo3, values=manager.get_field_names(),
                                   state='readonly',
                                   postcommand=lambda: self.combo_data.configure(values=manager.get_field_names()))
        self.combo_data.grid(row=1, column=2, padx=5, pady=5)

        edit_button = Button(top_frame, text="Edit header", command=self.edit_header, width=20)
        edit_button.grid(row=1, column=3, columnspan=1, rowspan=1, padx=5, pady=5)

        # TODO change values for combobox
        transform_select_combo4 = tkinter.StringVar()
        self.combo_transform = Combobox(top_frame, textvariable=transform_select_combo4, values=["rad_to_deg",
                                                                                                       "deg_to_rad"],
                                        state='readonly')
        self.combo_transform.grid(row=1, column=4, padx=5, pady=5)

        transform_button = Button(top_frame, text="Transform data", command=self.transform_data, width=20)
        transform_button.grid(row=1, column=5, columnspan=1, rowspan=1, padx=5, pady=5)

        table_frame = Frame(top)
        table_frame.pack(side=tkinter.BOTTOM, expand=True, fill=tkinter.BOTH)

        scrollbar_x = Scrollbar(table_frame, orient=tkinter.HORIZONTAL)
        scrollbar_y = Scrollbar(table_frame, orient=tkinter.VERTICAL)

        self.tree = Treeview(table_frame, columns=manager.get_field_names(), show="headings", selectmode="extended",
                             yscrollcommand=scrollbar_y.set, xscrollcommand=scrollbar_x.set)

        scrollbar_y.config(command=self.tree.yview)
        scrollbar_y.pack(side=tkinter.RIGHT, fill=tkinter.Y)
        scrollbar_x.config(command=self.tree.xview)
        scrollbar_x.pack(side=tkinter.BOTTOM, fill=tkinter.X)

        self.fill_data()

        self.tree.pack(expand=True, fill=tkinter.BOTH)
        self.top.protocol("WM_DELETE_WINDOW", self.quit)

    def edit_header(self):
        """ Edit the header a data column """
        if self.combo_data.get() != "":
            answer = simpledialog.askstring("Input", "What is the new header?", parent=self.top)
            if answer is not None:
                self.__manager.edit_header(answer, self.combo_data.get())
                self.fill_data()
                self.combo_data.set('')
            else:
                logger.log(logging.INFO, "[CsvFrame] No new header entered")
        else:
            logger.log(logging.ERROR, "[CsvFrame] No data field selected")

    def clear_data(self):
        """ Clear data in Treeview """
        logger.log(logging.INFO, "[CsvFrame] Clear data in TreeView")
        for i in self.tree.get_children():
            self.tree.delete(i)

    def fill_data(self):
        """ Fill data in Treeview """
        logger.log(logging.INFO, "[CsvFrame] Fill data in TreeView")

        self.clear_data()
        self.tree.config(columns=self.__manager.get_field_names())

        for field_name in self.__manager.get_field_names():
            self.tree.heading(field_name, text=field_name, anchor=tkinter.W)
            self.tree.column(field_name, stretch=tkinter.YES)

        for entry in self.__manager.get_data_tuple():
            self.tree.insert("", 'end', values=entry)

    def transform_data(self):
        """ Transform data and add in Treeview """
        # TODO to be completed
        data_field_name = self.combo_data.get()
        if data_field_name != "":
            if self.combo_transform.get() != "":
                data = self.__manager.get_data_from_field_name(data_field_name)
                transformed_data = transform_data(self.combo_transform.get(), self.combo_data.get(), data)
                if transformed_data[0] != "":
                    self.__manager.add_data(transformed_data[0], transformed_data[1], transformed_data[2])
                    self.fill_data()
                else:
                    logger.log(logging.ERROR, "[CsvFrame] Data has not been transformed")
            else:
                logger.log(logging.ERROR, "[CsvFrame] No transform operation selected")
        else:
            logger.log(logging.ERROR, "[CsvFrame] No data field selected")

    def quit(self):
        """ Destroy the frame """
        self.__parent.reset_csvframe()
        self.top.destroy()
### On ajoute le bouton et la variable contenant notre liste de villes à global, pour pouvoir les modifier de partout
global BDepart, villeDepartList
###On crée notre variable vierge
villeDepartList = ()

###On crée notre Combobox
###On lui associe une fonction lorsqu'on la sélectionne
###On configure sa taille et son état
BDepart = Combobox(sub1,
                   textvariable=villeDepart,
                   values=villeDepartList,
                   state='readonly')
BDepart.bind("<<ComboboxSelected>>", Depart)
BDepart.pack(fill=X, padx=2, pady=2)
BDepart.configure(state=DISABLED)

###On crée un espace entre les deux Combobox
Label(sub1, text='\n\n\n\n').pack(padx=2, pady=2)

###Même chose que pour la ville de départ, mais cette fois ci pour l'arrivée
Label(sub1, text='''Ville d'arrivée : \n''').pack(fill=X, padx=2, pady=2)

global villeArrivee
villeArrivee = StringVar()
villeArrivee.set('''Ville d'arrivée ''')

global BArrivee
global villeArriveeList
villeArriveeList = ()
BArrivee = Combobox(sub1,
Esempio n. 13
0
class RAnalysisFrame(tkinter.Tk):
    """ Main GUI window: Display menu and PlotFrame """
    def __init__(self, parent):
        """ MainFrame constructor """
        tkinter.Tk.__init__(self, parent)
        self.__parent = parent

        self.geometry("+50+50")

        self.__logger_frame = None

        self.__plot_frame_combo = None
        self.__variable1_combo = None
        self.__variable2_combo = None

        self.__plot_frame_select_combo = tkinter.StringVar()
        self.__plot_frame = {}
        self.__plot_frame_list = ["all"]
        self.__counter = 0

        self.__data_manager = DataManager()

        self.__csv_frame = None

        self.initialize()

    def initialize(self):
        """ Initialize all the tkinter objects of the frame """
        self.title('RGINE Data Analysis')

        # frame
        top_frame = tkinter.Frame(self)
        top_frame.pack(side=tkinter.TOP, fill=tkinter.X)

        data_frame = tkinter.Frame(top_frame)
        data_frame.pack(side=tkinter.TOP, fill=tkinter.X)

        data_frame_csv = tkinter.Frame(data_frame,
                                       borderwidth=2,
                                       relief=tkinter.GROOVE)
        data_frame_csv.pack(side=tkinter.LEFT, fill=tkinter.X, padx=5, pady=5)

        data_frame_data = tkinter.Frame(data_frame,
                                        borderwidth=2,
                                        relief=tkinter.GROOVE)
        data_frame_data.pack(side=tkinter.RIGHT,
                             fill=tkinter.X,
                             padx=5,
                             pady=5)

        plot_frame = tkinter.Frame(top_frame,
                                   borderwidth=2,
                                   relief=tkinter.GROOVE)
        plot_frame.pack(side=tkinter.LEFT, fill=tkinter.X, padx=5, pady=5)

        action_frame = tkinter.Frame(top_frame,
                                     borderwidth=2,
                                     relief=tkinter.GROOVE)
        action_frame.pack(side=tkinter.RIGHT, fill=tkinter.X, padx=5, pady=5)

        # button
        load_button = Button(data_frame_csv,
                             text="Load CSV file",
                             command=self.load_data,
                             width=20)
        load_button.grid(row=1,
                         column=1,
                         columnspan=1,
                         rowspan=1,
                         padx=5,
                         pady=5)
        refresh_file_button = Button(data_frame_csv,
                                     text="Refresh CSV file",
                                     command=self.refresh_file,
                                     width=20)
        refresh_file_button.grid(row=1, column=2, padx=5, pady=5)
        display_button = Button(data_frame_data,
                                text="Display data",
                                command=self.display_data,
                                width=20)
        display_button.grid(row=1, column=3, padx=5, pady=5)
        save_button = Button(data_frame_data,
                             text="Save data",
                             command=self.save_data,
                             width=20)
        save_button.grid(row=1, column=4, padx=5, pady=5)
        clear_button = Button(data_frame_data,
                              text="Clear data",
                              command=self.clear_data,
                              width=20)
        clear_button.grid(row=1, column=5, padx=5, pady=5)

        add_button = Button(action_frame,
                            text="Add plot",
                            command=self.add_plot,
                            width=20)
        add_button.grid(row=1, column=3, rowspan=1, padx=5, pady=5)
        function_button = Button(action_frame,
                                 text="Plot math function",
                                 command=self.add_plot_function,
                                 width=20)
        function_button.grid(row=2,
                             column=3,
                             columnspan=1,
                             rowspan=1,
                             padx=5,
                             pady=5)

        add_plot_button = Button(plot_frame,
                                 text="Add Plot frame",
                                 command=self.add_plot_frame,
                                 width=20)
        add_plot_button.grid(row=1,
                             column=1,
                             columnspan=1,
                             rowspan=1,
                             padx=5,
                             pady=5)
        clear_plot_button = Button(plot_frame,
                                   text="Clear all plots",
                                   command=self.clear_all_plots,
                                   width=20)
        clear_plot_button.grid(row=1,
                               column=2,
                               columnspan=1,
                               rowspan=1,
                               padx=5,
                               pady=5)
        remove_plot_button = Button(plot_frame,
                                    text="Remove all plots",
                                    command=self.remove_all_plots,
                                    width=20)
        remove_plot_button.grid(row=2,
                                column=2,
                                columnspan=1,
                                rowspan=1,
                                padx=5,
                                pady=5)

        # label
        label_x = Label(action_frame, text="Choose X axis data: ", width=20)
        label_x.grid(row=1, column=1, padx=5, pady=5)
        label_y = Label(action_frame, text="Choose Y axis data: ", width=20)
        label_y.grid(row=2, column=1, padx=5, pady=5)

        # combo
        self.__plot_frame_combo = Combobox(
            plot_frame,
            textvariable=self.__plot_frame_select_combo,
            values=self.__plot_frame_list,
            state='readonly',
            postcommand=lambda: self.__plot_frame_combo.configure(
                values=self.__plot_frame_list),
            width=17)
        self.__plot_frame_combo.current(0)
        self.__plot_frame_combo.grid(row=2, column=1, padx=5, pady=5)

        data_select_combo1 = tkinter.StringVar()
        self.__variable1_combo = Combobox(
            action_frame,
            textvariable=data_select_combo1,
            values=self.__data_manager.get_field_names(),
            state='readonly',
            postcommand=lambda: self.__variable1_combo.configure(
                values=self.__data_manager.get_field_names()),
            width=19)
        self.__variable1_combo.grid(row=1, column=2, padx=5, pady=5)

        data_select_combo2 = tkinter.StringVar()
        self.__variable2_combo = Combobox(
            action_frame,
            textvariable=data_select_combo2,
            values=self.__data_manager.get_field_names(),
            state='readonly',
            postcommand=lambda: self.__variable2_combo.configure(
                values=self.__data_manager.get_field_names()),
            width=19)
        self.__variable2_combo.grid(row=2, column=2, padx=5, pady=5)

        # menu
        frame_menu = tkinter.Menu(self)
        help_menu = tkinter.Menu(frame_menu, tearoff=0)
        help_menu.add_command(label="Logger", command=self.open_logger_command)
        help_menu.add_separator()
        help_menu.add_command(label="How to", command=self.how_to_command)
        help_menu.add_command(label="About", command=self.about_command)
        frame_menu.add_cascade(label="Help", menu=help_menu)

        self.config(menu=frame_menu)

    def open_logger_command(self):
        """ Display or hide the LoggerFrame """
        logger.log(logging.INFO, "[MainFrame] Opening Logger frame")
        if self.__logger_frame is not None:
            self.__logger_frame.quit()
        self.__logger_frame = None
        self.__logger_frame = LoggerFrame(self)

    def how_to_command(self):
        """ Displaying some "how to" questions """
        messagebox.showinfo(
            "How to ?", " - Create independent plots frame to analyze data\n"
            " - Load data\n"
            " - Choose x and y axis then add the graph to the list\n"
            " - Select in the list, all the graphs to display")

    def about_command(self):
        """ Displaying RAnalysis informations """
        messagebox.showinfo(
            "About",
            "RAnalaysis v0.1\n\nhttp://gitlab-dtis.onera/s2im/rgine/ranalysis")

    def add_plot_frame(self):
        """ Creating new plot frame """
        plot_frame_id = "Plot frame " + str(self.__counter)
        plot_frame = PlotFrame(self, plot_frame_id)

        self.__plot_frame[plot_frame_id] = plot_frame
        self.__plot_frame_list.append(plot_frame_id)

        self.__counter += 1
        logger.log(logging.INFO,
                   "[MainFrame] Opening Plot frame: " + plot_frame_id)

    def load_data(self):
        """ Load data from a csv file """
        filename = askopenfilename(title="Open data file",
                                   filetypes=[('csv files', '.csv'),
                                              ('out files', '.out'),
                                              ('all files', '.*')])

        if filename is not None and len(filename) > 0:
            input_dialog = InputDialog(self)
            self.wait_window(input_dialog.top)
            logger.log(logging.INFO,
                       "[MainFrame] loading file " + str(filename))

            if self.__data_manager is not None:
                if input_dialog.get_input_options()['clear']:
                    self.clear_data()
            else:
                self.__data_manager = DataManager()

            self.__data_manager.read_csv_file(filename,
                                              input_dialog.get_input_options())
        else:
            logger.log(logging.ERROR, "[MainFrame] No file selected")

    def refresh_file(self):
        """ Refresh data from the same csv file """
        if self.__data_manager.manager_have_data():
            logger.log(logging.INFO, "[MainFrame] Refreshing file")
            self.__data_manager.refresh_data()
            if self.__csv_frame is not None:
                self.__csv_frame.fill_data()
        else:
            logger.log(logging.ERROR, "[MainFrame] No data to refresh")

    def display_data(self):
        """ Display csv data in a CsvFrame """
        if self.__data_manager.manager_have_data():
            logger.log(logging.INFO, "[MainFrame] Displaying data")
            self.__csv_frame = CsvFrame(self, self.__data_manager)
        else:
            logger.log(
                logging.ERROR,
                "[MainFrame] Could not display data, data manager does not have data"
            )

    def clear_data(self):
        """ Clear data """
        if self.__data_manager is not None:
            logger.log(logging.INFO, "[MainFrame] Clearing data")
            self.__data_manager.reset_manager()
        else:
            logger.log(logging.ERROR, "[MainFrame] No data to clear")
        self.__variable1_combo.set('')
        self.__variable2_combo.set('')

    def save_data(self):
        """ Save data in a CSV file """
        file_type = [('csv files', '.csv'), ('out files', '.out'),
                     ('all files', '.*')]
        file = asksaveasfile(filetypes=file_type, defaultextension=file_type)
        if file is None:
            logger.log(logging.ERROR, "[PlotFrame] No save file selected")
        else:
            logger.log(logging.INFO, "[MainFrame] Saving data")
            self.__data_manager.save_csv_file(file.name)

    def reset_csvframe(self):
        """ Reset csv frame """
        self.__csv_frame = None

    def reset_plot_frame(self, plot_frame_id):
        """ Reset plot frame """
        self.__plot_frame_combo.current(0)
        self.__plot_frame_list.remove(plot_frame_id)
        del self.__plot_frame[plot_frame_id]

    def add_plot(self):
        """ Add_button action to add created plot in the list """
        if len(self.__plot_frame) > 0:
            if self.__variable1_combo.get(
            ) != "" and self.__variable2_combo.get() != "":
                if self.__data_manager.manager_have_data():
                    plot = PlotCreator.get_instance().plot_from_fieldnames(
                        self.__data_manager, self.__variable1_combo.get(),
                        [self.__variable2_combo.get()])
                    logger.log(logging.INFO,
                               "[MainFrame] Creating plot " + str(plot[0]))
                    if self.__plot_frame_combo.get() == "all":
                        for item in list(self.__plot_frame.values()):
                            item.add_plot(plot[0])
                    else:
                        self.__plot_frame[
                            self.__plot_frame_combo.get()].add_plot(plot[0])
                else:
                    logger.log(logging.ERROR,
                               "[MainFrame] Data manager does not have data")
            else:
                logger.log(logging.ERROR, "[MainFrame] No variables selected")
        else:
            logger.log(logging.ERROR, "[MainFrame] No Plot frame opened")

    def add_plot_function(self):
        """ Create plot from math functions to validate data """
        if len(self.__plot_frame) > 0:
            function_dialog = FunctionDialog(self)
            self.wait_window(function_dialog.top)
            if function_dialog.get_plot() is not None:
                logger.log(
                    logging.INFO, "[MainFrame] Creating math plot " +
                    str(function_dialog.get_plot()))
                if self.__plot_frame_combo.get() == "all":
                    for item in list(self.__plot_frame.values()):
                        item.add_plot(function_dialog.get_plot())
                else:
                    self.__plot_frame[self.__plot_frame_combo.get()].add_plot(
                        function_dialog.get_plot())
            else:
                logger.log(logging.ERROR, "[MainFrame] No math plot created")
        else:
            logger.log(logging.ERROR, "[MainFrame] No Plot frame opened")

    def clear_all_plots(self):
        """ Clear/reset the plot frame """
        logger.log(logging.INFO, "[MainFrame] Clearing all plots")
        for item in list(self.__plot_frame.values()):
            item.clear_all_plots()

    def remove_all_plots(self):
        """ Remove all the plots from the plot list """
        logger.log(logging.INFO, "[MainFrame] Remove all plots")
        for item in list(self.__plot_frame.values()):
            item.remove_all_plots()
Esempio n. 14
0
class STKKApplication(tk.Frame):

    colorButtons = []              # List of the tkinter Buttons that select colors
    lights_buffer = []             # List of integers containing color values + 1 int header
    header_value = MK1_HEADER_VAL  # Header value for lights buffer
    buffer_scale = 3               # Integer scale value for indexing into the buffer
    color_list = []                # List of tuples containing the currently selected colors
    off_color = (0x00,)            # Tuple for turning off a light
    kb_hid_id = S61_MK1_ID         # Keyboard identifier used when opening HID
    kb_num_keys = 61               # Number of keys on the keyboard
    kb_note_offset = -36           # Offset to convert MIDI note value to buffer index
                                   # Calculated as 60 - number of keys below Middle C
    connected = False              # Boolean to indicate if currently connected
    listen = True                  # Boolean to control threaded listen loop
    kb_device = None               # HID keyboard device handle
    port_name = ""                 # Name of LoopBe1 MIDI loopback port
    thread_handle = None           # Handle for thread
    map_palette_dialog = None      # Handle for Map Palette dialog
    map_palette_index = None       # Handle for index label
    map_palette_color = None       # Handle for color swatch
    map_palette_dict = None        # Dictionary containing mapped palette values


    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        if master != None:
            master.title("Synthesia To Komplete Kontrol")
            master.geometry("640x420")
        self.grid(column=0, row=0)
        self.createWidgets()

    def createWidgets(self):
        """Creates the GUI widgets"""

        # Read user prefs from the .ini file
        uprefs = self.readUserPrefs()

        # Keyboard combobox label
        self.kb_combobox_label = tk.Label(self)
        self.kb_combobox_label["text"] = "Komplete Kontrol model"
        self.kb_combobox_label.grid(column=0, row=0, padx=10, pady=5, columnspan=2, sticky='W')

        # Keyboard listbox
        self.kb_combobox = Combobox(self)
        self.kb_combobox['values'] = [
            "Komplete Kontrol S61 MK2",
            "Komplete Kontrol S88 MK2",
            "Komplete Kontrol S49 MK2",
            "Komplete Kontrol S61 MK1",
            "Komplete Kontrol S88 MK1",
            "Komplete Kontrol S49 MK1",
            "Komplete Kontrol S25 MK1"]
        self.kb_combobox.current(uprefs['selectedkeyboard'])
        self.kb_combobox.grid(column=0, row=1, ipadx=10, padx=10, pady=5, columnspan=2, sticky='W')

        # Color labels & buttons
        self.colors_label = tk.Label(self)
        self.colors_label["text"] = "Key Colors:"
        self.colors_label.grid(column=0, row=2, padx=10, sticky='W')

        self.color0_label = tk.Label(self)
        self.color0_label["text"] = "Default (Unknown hand/finger)"
        self.color0_label.grid(column=1, row=3, padx=5, sticky='W')
        self.color0_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(0), bg=uprefs['defaultcolor'])
        self.color0_button.grid(column=0, row=3, pady=1, sticky='E')
        self.colorButtons.append(self.color0_button)

        self.color1_label = tk.Label(self)
        self.color1_label["text"] = "Left thumb"
        self.color1_label.grid(column=1, row=4, padx=5, sticky='W')
        self.color1_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(1), bg=uprefs['leftthumb'])
        self.color1_button.grid(column=0, row=4, pady=1, sticky='E')
        self.colorButtons.append(self.color1_button)

        self.color2_label = tk.Label(self)
        self.color2_label["text"] = "Left index"
        self.color2_label.grid(column=1, row=5, padx=5, sticky='W')
        self.color2_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(2), bg=uprefs['leftindex'])
        self.color2_button.grid(column=0, row=5, pady=1, sticky='E')
        self.colorButtons.append(self.color2_button)

        self.color3_label = tk.Label(self)
        self.color3_label["text"] = "Left middle"
        self.color3_label.grid(column=1, row=6, padx=5, sticky='W')
        self.color3_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(3), bg=uprefs['leftmiddle'])
        self.color3_button.grid(column=0, row=6, pady=1, sticky='E')
        self.colorButtons.append(self.color3_button)

        self.color4_label = tk.Label(self)
        self.color4_label["text"] = "Left ring"
        self.color4_label.grid(column=1, row=7, padx=5, sticky='W')
        self.color4_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(4), bg=uprefs['leftring'])
        self.color4_button.grid(column=0, row=7, pady=1, sticky='E')
        self.colorButtons.append(self.color4_button)

        self.color5_label = tk.Label(self)
        self.color5_label["text"] = "Left pinky"
        self.color5_label.grid(column=1, row=8, padx=5, sticky='W')
        self.color5_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(5), bg=uprefs['leftpinky'])
        self.color5_button.grid(column=0, row=8, pady=1, sticky='E')
        self.colorButtons.append(self.color5_button)

        self.color6_label = tk.Label(self)
        self.color6_label["text"] = "Right thumb"
        self.color6_label.grid(column=3, row=4, padx=5, sticky='W')
        self.color6_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(6), bg=uprefs['rightthumb'])
        self.color6_button.grid(column=2, row=4, pady=1, sticky='E')
        self.colorButtons.append(self.color6_button)

        self.color7_label = tk.Label(self)
        self.color7_label["text"] = "Right index"
        self.color7_label.grid(column=3, row=5, padx=5, sticky='W')
        self.color7_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(7), bg=uprefs['rightindex'])
        self.color7_button.grid(column=2, row=5, pady=1, sticky='E')
        self.colorButtons.append(self.color7_button)

        self.color8_label = tk.Label(self)
        self.color8_label["text"] = "Right middle"
        self.color8_label.grid(column=3, row=6, padx=5, sticky='W')
        self.color8_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(8), bg=uprefs['rightmiddle'])
        self.color8_button.grid(column=2, row=6, pady=1, sticky='E')
        self.colorButtons.append(self.color8_button)

        self.color9_label = tk.Label(self)
        self.color9_label["text"] = "Right ring"
        self.color9_label.grid(column=3, row=7, padx=5, sticky='W')
        self.color9_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(9), bg=uprefs['rightring'])
        self.color9_button.grid(column=2, row=7, pady=1, sticky='E')
        self.colorButtons.append(self.color9_button)

        self.color10_label = tk.Label(self)
        self.color10_label["text"] = "Right pinky"
        self.color10_label.grid(column=3, row=8, padx=5, sticky='W')
        self.color10_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(10), bg=uprefs['rightpinky'])
        self.color10_button.grid(column=2, row=8, pady=1, sticky='E')
        self.colorButtons.append(self.color10_button)

        self.color11_label = tk.Label(self)
        self.color11_label["text"] = "Left hand (Unknown finger)"
        self.color11_label.grid(column=1, row=9, padx=5, sticky='W')
        self.color11_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(11), bg=uprefs['lefthand'])
        self.color11_button.grid(column=0, row=9, pady=1, sticky='E')
        self.colorButtons.append(self.color11_button)

        self.color12_label = tk.Label(self)
        self.color12_label["text"] = "Right hand (Unknown finger)"
        self.color12_label.grid(column=3, row=9, padx=5, sticky='W')
        self.color12_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(12), bg=uprefs['righthand'])
        self.color12_button.grid(column=2, row=9, pady=1, sticky='E')
        self.colorButtons.append(self.color12_button)

        # Control buttons
        self.connectButton = tk.Button(self, text=" Connect  ", command=self.start, bg='#fefefe')
        self.connectButton.grid(column=0, row=10, pady=10)
        self.disconnectButton = tk.Button(self, text="Disconnect", command=self.stop, bg='#fefefe', state='disabled')
        self.disconnectButton.grid(column=1, row=10, pady=10)
        self.exitButton = tk.Button(self, text="  Exit  ", command=self.quit, bg='#fefefe')
        self.exitButton.grid(column=2, row=10, pady=10)
        self.mapPaletteButton = tk.Button(self, text="Map Palette", state='disabled', command=self.mapPalette, bg='#fefefe')
        self.mapPaletteButton.grid(column=3, row=10, pady=10)

    def colorButtonClick(self, button_num):
        """Color button click handler, opens color picker to set
           button's color"""
        start_color = self.colorButtons[button_num].cget('bg')
        result = askcolor(start_color)
        if result[1]:
            self.colorButtons[button_num].configure(bg=result[1])

    def enableGUIControls(self, enable = True):
        """Enable or disable GUI elements while connected"""
        for button in self.colorButtons:
            if enable:
                button.configure(state = 'normal')
            else:
                button.configure(state = 'disabled')
        if enable:
            self.kb_combobox.configure(state='normal')
        else:
            self.kb_combobox.configure(state='disabled')

    def start(self):
        """Connect button click handler"""
        if not self.connected:
            self.setAttributes()
            self.connected = self.connectToKeyboard()
            if self.connected:
                if self.findMIDIPort():
                    self.enableGUIControls(False)
                    self.disconnectButton.configure(state='normal')
                    self.mapPaletteButton.configure(state='normal')
                    self.listen = True
                    self.lightsOut()
                    self.thread_handle = threading.Thread(target=self.lightKeyboardThread, args=())
                    self.thread_handle.daemon = True
                    self.thread_handle.start()
                else:
                    self.kb_device.close()
                    self.connected = False


    def stop(self):
        """Disconnect button click handler"""
        self.listen = False
        self.connected = False # Disconnect from keyboard is handled in thread
        self.thread_handle.join()
        self.thread_handle = None
        self.enableGUIControls()
        self.mapPaletteButton.configure(state='disabled')
        self.disconnectButton.configure(state='disabled')


    def quit(self):
        """Exit button click handler"""
        self.listen = False
        self.writeUserPrefs()
        if self.thread_handle:
            self.thread_handle.join()
        if self.map_palette_dialog:
            self.map_palette_dialog.destroy()
        root.destroy()

    def setAttributes(self):
        """Sets the object's attributes based on KK model"""

        # Get the index of the currently selected keyboard
        selected = self.kb_combobox.current()

        # Setup variables according to keyboard model
        if selected == 0:  # Komplete Kontrol S61 MK2
            self.kb_num_keys = 61
            self.kb_note_offset = -36
            self.kb_hid_id = S61_MK2_ID
            self.header_value = MK2_HEADER_VAL
            self.buffer_scale = 1
            self.off_color = (0x00,)
            self.color_list = self.ButtonsToPaletteColorList()
        elif selected == 1:  # Komplete Kontrol S88 MK2
            self.kb_num_keys = 88
            self.kb_note_offset = -21
            self.kb_hid_id = S88_MK2_ID
            self.header_value = MK2_HEADER_VAL
            self.buffer_scale = 1
            self.off_color = (0x00,)
            self.color_list = self.ButtonsToPaletteColorList()
        elif selected == 2:  # Komplete Kontrol S49 MK2
            self.kb_num_keys = 49
            self.kb_note_offset = -36
            self.kb_hid_id = S49_MK2_ID
            self.header_value = MK2_HEADER_VAL
            self.buffer_scale = 1
            self.off_color = (0x00,)
            self.color_list = self.ButtonsToPaletteColorList()
        elif selected == 3:  # Komplete Kontrol S61 MK1
            self.kb_num_keys = 61
            self.kb_note_offset = -36
            self.kb_hid_id = S61_MK1_ID
            self.header_value = MK1_HEADER_VAL
            self.buffer_scale = 3
            self.off_color = (0x00,0x00,0x00)
            self.color_list = self.ButtonsToRGBColorList()
        elif selected == 4:  # Komplete Kontrol S88 MK1
            self.kb_num_keys = 88
            self.kb_note_offset = -21
            self.kb_hid_id = S88_MK1_ID
            self.header_value = MK1_HEADER_VAL
            self.buffer_scale = 3
            self.off_color = (0x00,0x00,0x00)
            self.color_list = self.ButtonsToRGBColorList()
        elif selected == 5:  # Komplete Kontrol S49 MK1
            self.kb_num_keys = 49
            self.kb_note_offset = -36
            self.kb_hid_id = S49_MK1_ID
            self.header_value = MK1_HEADER_VAL
            self.buffer_scale = 3
            self.off_color = (0x00,0x00,0x00)
            self.color_list = self.ButtonsToRGBColorList()
        elif selected == 6:  # Komplete Kontrol S25 MK1
            self.kb_num_keys = 25
            self.kb_note_offset = -48
            self.kb_hid_id = S25_MK1_ID
            self.header_value = MK1_HEADER_VAL
            self.buffer_scale = 3
            self.off_color = (0x00,0x00,0x00)
            self.color_list = self.ButtonsToRGBColorList()
        else:
            return False

        # Create the buffer for the color values
        self.lights_buffer = [0x00] * (self.kb_num_keys * self.buffer_scale + 1)
        self.lights_buffer[0] = self.header_value

        return True

    def connectToKeyboard(self):
        """Attempts to connect to keyboard as HID"""
        self.kb_device=hid.device()
        try:
            self.kb_device.open(NI_HID_ID, self.kb_hid_id)
        except Exception as e:
            showerror("Could not connect to KK", 'Connection error: ' + str(e))
            return False

        # Set the keyboard to receive Light Guide data
        self.kb_device.write([LIGHT_GUIDE_CMD])
        return True

    def findMIDIPort(self):
        """Looks for the LoopBe1 MIDI port"""
        ports = mido.get_input_names()
        for port in ports:
            if "LoopBe" in port:
                self.port_name = port
        if self.port_name == "":
            showerror("MIDI Port Error",
                "Please install LoopBe1 from http://www.nerds.de/en/download.html.")
            return False
        return True

    def lightsOut(self):
        """Turn off all lights"""
        for i in range(1, len(self.lights_buffer)):
            self.lights_buffer[i] = 0x00
        self.kb_device.write(self.lights_buffer)
    
    def MIDIMsgToLightGuide(self, note, status, channel, velocity):
        """Use MIDI messages to update KK's Light Guide"""

        # Turn off light
        if status == 'note_off':
            self.writeColorToBuffer(self.off_color, note + self.kb_note_offset)

        # Turn on light
        elif status == 'note_on' and channel >= 0 and channel < len(self.color_list): 
            self.writeColorToBuffer(self.color_list[channel], note + self.kb_note_offset)

        # Write the buffer to the keyboard device
        self.kb_device.write(self.lights_buffer)

    def writeColorToBuffer(self, color, index):
        """Writes a color to the lights buffer -
           color should be a tuple -
           index should be an int between 0 and (number of keys - 1), inclusive"""
        
        # Calculate the index for the lights buffer
        index = 1 + (index  * self.buffer_scale)

        # Check the index is within range of the buffer
        if index < 1 or index > (len(self.lights_buffer) - self.buffer_scale):
            return  

        # Write the color value to the lights buffer
        for color_val in color:
            self.lights_buffer[index] = color_val
            index += 1

    def krSweep(self, loopcount):
        """Performs a red light sweep across Light Guide"""
        speed = 0.01

        if self.buffer_scale == 3:
            color1 = (0x7F, 0x00, 0x00)
            color2 = (0x3F, 0x00, 0x00)
            color3 = (0x0F, 0x00, 0x00)
        else:
            color1 = (0x07,)
            color2 = (0x05,)
            color3 = (0x04,)

        while loopcount > 0:
            # Forward
            for x in range(0, self.kb_num_keys):
                for i in range(1, len(self.lights_buffer)):
                    self.lights_buffer[i] = 0x00
                self.writeColorToBuffer(color1, x)
                if x + 1 < self.kb_num_keys:
                    self.writeColorToBuffer(color2, x + 1)
                if x + 2 < self.kb_num_keys:
                    self.writeColorToBuffer(color3, x + 2)
                if x - 1 >= 0:
                    self.writeColorToBuffer(color2, x - 1)
                if x - 2 >= 0:
                    self.writeColorToBuffer(color3, x - 2)
                self.kb_device.write(self.lights_buffer)
                time.sleep(speed)
            # Backward
            for x in range(self.kb_num_keys - 1, -1, -1):
                for i in range(1, len(self.lights_buffer)):
                    self.lights_buffer[i] = 0x00
                self.writeColorToBuffer(color1, x)
                if x + 1 < self.kb_num_keys:
                    self.writeColorToBuffer(color2, x + 1)
                if x + 2 < self.kb_num_keys:
                    self.writeColorToBuffer(color3, x + 2)
                if x - 1 >= 0:
                    self.writeColorToBuffer(color2, x - 1)
                if x - 2 >= 0:
                    self.writeColorToBuffer(color3, x - 2)
                self.kb_device.write(self.lights_buffer)
                time.sleep(speed)
            loopcount -= 1
        self.lightsOut()
        
    def lightKeyboardThread(self):
        """Threaded method to update KK Light Guide"""
        self.krSweep(2)
        midiPort = mido.open_input(self.port_name)
        while self.listen:
            for message in midiPort.iter_pending():
                if message.type in ('note_on', 'note_off'):
                    self.MIDIMsgToLightGuide(message.note, message.type, message.channel, message.velocity)
        self.lightsOut()
        self.kb_device.close()
        midiPort.close()

    def readUserPrefs(self):
        """Reads user preferences from STKKConfig.ini"""
        prefs = {}

        prefs_file = cfg.ConfigParser()
        files = prefs_file.read('STKKConfig.ini')
        if len(files) == 1 and 'UserPrefs' in prefs_file:
            up = prefs_file['UserPrefs']
            prefs['selectedkeyboard'] = up.getint('selectedkeyboard', fallback=3)
            prefs['defaultcolor'] = up.get('defaultcolor', fallback='#ff0000')
            prefs['leftthumb'] = up.get('leftthumb', fallback='#00ff00')
            prefs['leftindex'] = up.get('leftindex', fallback='#00ff00')
            prefs['leftmiddle'] = up.get('leftmiddle', fallback='#00ff00')
            prefs['leftring'] = up.get('leftring', fallback='#00ff00')
            prefs['leftpinky'] = up.get('leftpinky', fallback='#00ff00')
            prefs['lefthand'] = up.get('lefthand', fallback='#00ff00')
            prefs['rightthumb'] = up.get('rightthumb', fallback='#0000ff')
            prefs['rightindex'] = up.get('rightindex', fallback='#0000ff')
            prefs['rightmiddle'] = up.get('rightmiddle', fallback='#0000ff')
            prefs['rightring'] = up.get('rightring', fallback='#0000ff')
            prefs['rightpinky'] = up.get('rightpinky', fallback='#0000ff')
            prefs['righthand'] = up.get('righthand', fallback='#0000ff')
        else:
            # STKKConfig.ini not found, set defaults
            prefs['selectedkeyboard'] = 3
            prefs['defaultcolor'] = '#ff0000'
            prefs['leftthumb'] = '#00ffff'
            prefs['leftindex'] = '#0099ff'
            prefs['leftmiddle'] = '#0000ff'
            prefs['leftring'] = '#6600ff'
            prefs['leftpinky'] = '#ff00ff'
            prefs['lefthand'] = '#0000ff'
            prefs['rightthumb'] = '#ff8000'
            prefs['rightindex'] = '#ffd900'
            prefs['rightmiddle'] = '#b3ff00'
            prefs['rightring'] = '#00ff00'
            prefs['rightpinky'] = '#00ffbf'
            prefs['righthand'] = '#00ff00'

        return prefs

    def writeUserPrefs(self):
        """Writes user preferences to STKKConfig.ini"""
        config = cfg.ConfigParser()
        config['UserPrefs'] = {}
        up = config['UserPrefs']
        up['selectedkeyboard'] = str(self.kb_combobox.current())
        up['defaultcolor'] = self.colorButtons[0].cget('bg')
        up['leftthumb'] = self.colorButtons[1].cget('bg')
        up['leftindex'] = self.colorButtons[2].cget('bg')
        up['leftmiddle'] = self.colorButtons[3].cget('bg')
        up['leftring'] = self.colorButtons[4].cget('bg')
        up['leftpinky'] = self.colorButtons[5].cget('bg')
        up['lefthand'] = self.colorButtons[11].cget('bg')
        up['rightthumb'] = self.colorButtons[6].cget('bg')
        up['rightindex'] = self.colorButtons[7].cget('bg')
        up['rightmiddle'] = self.colorButtons[8].cget('bg')
        up['rightring'] = self.colorButtons[9].cget('bg')
        up['rightpinky'] = self.colorButtons[10].cget('bg')
        up['righthand'] = self.colorButtons[12].cget('bg')
        with open('STKKConfig.ini', 'w') as configfile:
            config.write(configfile)

    def ButtonsToRGBColorList(self):
        """Takes the attribute list of color Buttons and returns a list of 
            7-bit RGB tuples containing their background colors"""
        colors = []
        for button in self.colorButtons:
            if isinstance(button, tk.Button):
                colors.append(RGBStringToTuple(button.cget('bg')))
        return colors

    def ButtonsToPaletteColorList(self):
        """Takes the attribute list of color Buttons and returns a list of 
        one element tuples containing their background colors
        mapped to palette indices"""
        colors = []
        # Load the palette map from the .ini file
        prefs_file = cfg.ConfigParser()
        files = prefs_file.read('PaletteMap.ini')

        # If the .ini contains the palette map, map
        # button background colors to palette
        if len(files) == 1 and 'PaletteMap' in prefs_file:
            palette_map = prefs_file['PaletteMap']
            for button in self.colorButtons:
                if isinstance(button, tk.Button):
                    colors.append(mapRGBStringToPalette(button.cget('bg'), palette_map))
        else:
            # Palette map not loaded, map to arbitrary colors
            colors.append((0x07,))
            colors.append((0x2D,))
            colors.append((0x2F,))
            colors.append((0x2F,))
            colors.append((0x2F,))
            colors.append((0x2F,))
            colors.append((0x1F,))
            colors.append((0x1B,))
            colors.append((0x1B,))
            colors.append((0x1B,))
            colors.append((0x1B,))
            colors.append((0x2F,))
            colors.append((0x1B,))
        return colors

    ###
    # Map Palette methods
    ###
    def mapPalette(self):
        """Map Palette button click handler"""

        # If the keyboard is not connected, show an error
        if not self.connected:
            showerror(title='Not Connected',
                message='Connect to keyboard before mapping palette')
            return

        # If the buffer scale is 3, assume this is a MK1 keyboard
        # and show an error
        if self.buffer_scale == 3:
            showerror(title="Unmappable",
                message="MK1 keyboards do not need to be mapped")
            return

        # Disable buttons
        self.enableGUIControls(False)
        self.disconnectButton.configure(state='disabled')
        self.mapPaletteButton.configure(state='disabled')

        # If the palette dialog doesn't exist, create it
        if not self.map_palette_dialog:
            # Create window
            self.map_palette_dialog = tk.Toplevel(self)
            self.map_palette_dialog.title('Map MK2 Palette')
            # Create labels
            valueLabel = tk.Label(self.map_palette_dialog)
            valueLabel["text"] = "Index:"
            valueLabel.grid(column=0, row=0, padx=5, pady=10, sticky='E')
            colorLabel = tk.Label(self.map_palette_dialog)
            colorLabel["text"] = "Color:"
            colorLabel.grid(column=2, row=0, padx=5, pady=10, sticky='W')
            #Create index and color displays
            self.map_palette_index = tk.Label(self.map_palette_dialog)
            self.map_palette_index["text"] = "0x01"
            self.map_palette_index.grid(column=1, row=0, sticky='W')
            self.map_palette_color = tk.Button(self.map_palette_dialog, width=8, state='disabled', bg='#000000')
            self.map_palette_color.grid(column=3, row=0, padx=2, sticky='W')
            # Create buttons
            previousButton = tk.Button(self.map_palette_dialog, text="< Prev", command=self.mapPalettePrev, bg='#fefefe')
            previousButton.grid(column=0, row=2, sticky='E')
            nextButton = tk.Button(self.map_palette_dialog, text="Next >", command=self.mapPaletteNext, bg='#fefefe')
            nextButton.grid(column=1, row=2, sticky='W')
            setButton = tk.Button(self.map_palette_dialog, text="Set Color", command=self.mapPaletteSetColor, bg='#fefefe')
            setButton.grid(column=3, row=2, sticky='W')
            saveButton = tk.Button(self.map_palette_dialog, text=" Save ", command=self.mapPaletteSave, bg='#fefefe')
            saveButton.grid(column=0, row=3, padx=10, pady=10, sticky='W')
            cancelButton = tk.Button(self.map_palette_dialog, text="Cancel", command=self.mapPaletteCancel, bg='#fefefe')
            cancelButton.grid(column=1, row=3, padx=10, sticky='W')
            # Capture the Close Window event and
            # map it to the Cancel button handler
            self.map_palette_dialog.protocol("WM_DELETE_WINDOW", self.mapPaletteCancel)
        elif self.map_palette_dialog.state() == 'iconic':
            # Else show the window
            self.map_palette_dialog.deiconify()
        
        # If there is no palette map dictionary
        if not self.map_palette_dict:
            # Try to load the palette map from the .ini file
            prefs_file = cfg.ConfigParser()
            files = prefs_file.read('PaletteMap.ini')
            # If the .ini contains the palette map, set the dictionary
            if len(files) == 1 and 'PaletteMap' in prefs_file:
                self.map_palette_dict = prefs_file['PaletteMap']
            else:
                # Else create a new dictionary
                self.map_palette_dict = {}
        # Display the current palette map color in the dialog
        self.showCurrentMapColor()

    def showCurrentMapColor(self):
        """Displays the color of the current index in the map palette dialog"""
        # Get the current palette index from the dialog
        currentIndex = self.map_palette_index.cget('text')
        currentColor = '#000000'
        # Read the currently mapped color if the palette map dictionary exists
        if self.map_palette_dict:
            if currentIndex in self.map_palette_dict:
                currentColor = self.map_palette_dict[currentIndex]
        # Display the color in the dialog
        self.map_palette_color.configure(bg=currentColor)
        # Display the palette index on the keyboard
        self.displayPaletteIndex(currentIndex)

    def displayPaletteIndex(self, index):
        """Displays the palette index on the keyboard"""
        # Make sure the keyboard is connected
        if not self.connected:
            return
        # If the passed index is not an int, convert it
        if not isinstance(index, int):
            index = int(index, 16)
        # Create the tuple
        indexTuple = (index,)
        # Display the palette index in the first 12 keys
        for i in range(0, 12):
            self.writeColorToBuffer(indexTuple, i)
        self.kb_device.write(self.lights_buffer)

    def mapPalettePrev(self):
        """Map Palette dialog Prev button handler"""
        # Read the current index from the dialog
        currentIndex = self.map_palette_index.cget('text')
        # Convert the index to an int
        currentIndex = int(currentIndex, 16)
        # If the index is > 1
        if currentIndex > 1:
            # Decrement the index
            currentIndex -= 1
            # Update the dialog and keyboard
            currentIndex = '0x' + ("%02x" % (currentIndex,))
            self.map_palette_index.configure(text=currentIndex)
            self.showCurrentMapColor()

    def mapPaletteNext(self):
        """Map Palette dialog Next button handler"""
        # Read the current index from the dialog
        currentIndex = self.map_palette_index.cget('text')
        # Convert the index to an int
        currentIndex = int(currentIndex, 16)
        # If the index is < 255
        if currentIndex < 255:
            # Increment the index
            currentIndex += 1
            # Update the dialog and keyboard
            currentIndex = '0x' + ("%02x" % (currentIndex,))
            self.map_palette_index.configure(text=currentIndex)
            self.showCurrentMapColor()

    def mapPaletteSetColor(self):
        """Map Palette dialog Set Color button handler"""
        # Get the current color from the dialog
        currentColor = self.map_palette_color.cget('bg')
        # Show the color picker
        result = askcolor(currentColor, parent=self.map_palette_dialog)
        # If a color was selected
        if result[1]:
            # Update the dialog with the new color
            self.map_palette_color.configure(bg=result[1])
            # Get the current index from the dialog
            currentIndex = self.map_palette_index.cget('text')
            # Store in the palette map dictionary
            self.map_palette_dict[currentIndex] = result[1]

    def mapPaletteSave(self):
        """Map Palette dialog Save button handler"""
        # Create a ConfigParser
        config = cfg.ConfigParser()
        # Set the palette map dictionary
        config['PaletteMap'] = self.map_palette_dict
        # Write the palette map to the config file
        with open('PaletteMap.ini', 'w') as configfile:
            config.write(configfile)
        # Turn off keyboard lights
        self.lightsOut()
        # Enable buttons
        self.enableGUIControls()
        self.disconnectButton.configure(state='normal')
        self.mapPaletteButton.configure(state='normal')
        # Destroy the Map Palette dialog
        self.map_palette_dialog.destroy()
        self.map_palette_dialog = None

    def mapPaletteCancel(self):
        """Map Palette dialog Cancel button handler"""
        # Turn off keyboard lights
        self.lightsOut()
        # Enable buttons
        self.enableGUIControls()
        self.disconnectButton.configure(state='normal')
        self.mapPaletteButton.configure(state='normal')
        # Destroy the Map Palette dialog
        self.map_palette_dialog.destroy()
        self.map_palette_dialog = None
Esempio n. 15
0
class paper_trade:
    def __init__(self, window:Tk)->None:
        self.imp_strikes: List[float] = []
        self.imp_my_buy_price: List[float] = []
        self.nse_adapter = OC_DATA()
        self.stop = False
        self.my_atm: float = 0.0
        self.interval = 10.
        self.first_run = True
        self.buy_pe_limit: List[float] = []
        self.sell_pe_limit: List[float] = []
        self.sell_ce_limit: List[float] = []
        self.buy_ce_limit: List[float] = []
        self.market_price: List[float] = []
        self.vix_percentage = 2
        self.my_buy_price = []
        self.strategies: List[String] = ['IRON CONDOR']
        self.sh_cols: List[List[String]] = [['Instrument','Qty','My_price','LTP','P&L']]
        self.indices: List[str] = ['NIFTY','BANKNIFTY','RELIANCE','ASHOKLEY','TATAMOTORS','SBIN']
        self.indices_lot: dict[str,str]={'NIFTY':'75','BANKNIFTY':'25','RELIANCE':'505','ASHOKLEY':'9000','TATAMOTORS':'5700', \
                                         'SBIN':'3000'}
        self.symb_lot_dict: dict[str,List[str]] = {}
        self.symb_lot_dict['SYMBOLS'] = ['NIFTY','BANKNIFTY','RELIANCE']
        self.symb_lot_dict['LOT_SIZE'] = ['75','25']
        self.setup_main_window(window)
    
    def setup_main_window(self,window)->None:
        self.sh_window: Tk = window
        self.sh_window.title('Paper trading')
        window_width: int = self.sh_window.winfo_reqwidth()
        window_height: int = self.sh_window.winfo_reqheight()
        position_right: int = int(self.sh_window.winfo_screenwidth() / 2 - window_width / 2)
        position_down: int = int(self.sh_window.winfo_screenheight() / 2 - window_height / 2)
        self.sh_window.geometry("1000x800+300+100")
        self.sh_window.grid_rowconfigure(0, weight=0)
        self.sh_window.grid_columnconfigure(0, weight=1)
        rh = self.sh_window.winfo_height()
        rw = self.sh_window.winfo_width()
        #self.sh_window.configure(width=1200,height=800)
        #self.sh_window.grid_propagate(0)
        
        pdx = 5
        pdy = 5
        row_idx = 0
        top_frame: Frame = Frame(self.sh_window,width=rw,height=.1*rh)
        #top_frame.pack(anchor='nw',fill='both', expand=True, side=TOP)
        top_frame.grid(row=0,column=0,sticky='nsew')
        #top_frame.grid_rowconfigure(0, weight=0)
        #top_frame.grid_columnconfigure(0, weight=0)
        #top_frame.grid_propagate(1)
        #top_frame.configure(height=500)
        
        var_stock: StringVar = StringVar()
        var_stock.set(" ")
        lbl_stock: Label = Label(top_frame,text='Symbol',justify=LEFT,font=("TkDefaultFont", 10,"bold"),width=10)
        #lbl_stock.pack(anchor=N, expand=False, side=LEFT)
        lbl_stock.grid(row=0,column=0,sticky='nw',padx=pdx,pady=pdy)
        self.combo_box_stock = Combobox(top_frame,width=10,textvariable=var_stock) 
        #self.combo_box_stock.pack(anchor=N, expand=False, side=LEFT)
        self.combo_box_stock.grid(row=0,column=1,sticky='nw',padx=pdx,pady=pdy)
        self.combo_box_stock.configure(state='readonly')
        self.combo_box_stock['values'] = self.indices
        self.combo_box_stock.bind('<<ComboboxSelected>>', self.set_expiry_date)

        date_var_stock: StringVar = StringVar()
        date_var_stock.set(" ")
        lbl_exp_date_stock: Label = Label(top_frame,text='Expiry',justify=LEFT,font=("TkDefaultFont", 10,"bold"),width=10)
        #lbl_exp_date_stock.pack(anchor=N, expand=False, side=LEFT)
        lbl_exp_date_stock.grid(row=1,column=0,sticky=N+S+W,padx=pdx,pady=pdy)
        self.date_combo_box_stock = Combobox(top_frame,width=10,textvariable=date_var_stock) 
        #self.date_combo_box_stock.pack(anchor=N, expand=False, side=LEFT)
        self.date_combo_box_stock.grid(row=1,column=1,sticky=N+S+W,padx=pdx,pady=pdy)
        self.date_combo_box_stock.configure(state='readonly')
        self.date_combo_box_stock.bind('<<ComboboxSelected>>', self.set_expiry_date)
        #
        var_lot_size: StringVar = StringVar()
        var_lot_size.set(" ")
        lbl_lot_size: Label = Label(top_frame,text='Qty',justify=LEFT,font=("TkDefaultFont", 10, "bold"))
        #lbl_lot_size.pack(anchor=N, expand=False, side=LEFT)
        lbl_lot_size.grid(row=0,column=2,sticky=N+S+W,padx=pdx,pady=pdy)
        self.qty_combo_box = Combobox(top_frame,width=10,textvariable=var_lot_size) 
        #self.qty_combo_box.pack(anchor=N, expand=False, side=LEFT)
        self.qty_combo_box.configure(state='readonly')
        self.qty_combo_box.grid(row=0,column=3,sticky=N+S+W,padx=pdx,pady=pdy)
        
        var_vix: StringVar = StringVar()
        var_vix.set(" ")
        lbl_vix: Label = Label(top_frame,text='VIX',justify=LEFT,font=("TkDefaultFont", 10, "bold"))
        #lbl_vix.pack(anchor=N, expand=False, side=LEFT)
        lbl_vix.grid(row=1,column=2,sticky=N+S+W,padx=pdx,pady=pdy)
        self.vix_combo_box = Combobox(top_frame,width=10,textvariable=var_vix) 
        #self.vix_combo_box.pack(anchor=N, expand=False, side=LEFT)
        self.vix_combo_box.grid(row=1,column=3,sticky=N+S+W,padx=pdx,pady=pdy)
        self.vix_combo_box.configure(state='readonly')
        self.vix_combo_box['values'] = list(map(lambda x: x/10.0, range(5, 100, 5)))
        self.vix_combo_box.bind('<<ComboboxSelected>>', self.set_VIX)
        

        self.start_button: Button = tk.Button(top_frame,text='Trade',command=self.main_recursive,width=10,bg='green',fg='white',font=("TkDefaultFont", 10, "bold"))
        #self.start_button.pack(anchor=N, expand=False, side=LEFT)
        self.start_button.grid(row=0,column=4,sticky=N+S+W)#,padx=pdx,pady=pdy)
        self.start_button.configure(state='disabled')
        
        self.import_button: Button = tk.Button(top_frame,text='Manual',command=self.import_iron_condor,width=10,bg='red',fg='white',font=("TkDefaultFont", 10, "bold"))
        #self.import_button.pack(anchor=N, expand=False, side=LEFT)
        self.import_button.grid(row=0,column=5,sticky=N+S+W)#,padx=pdx,pady=pdy)
        self.import_button.configure(state='disabled')
        
        self.load_button: Button = tk.Button(top_frame,text='Load trade',command=self.load_file,width=10,bg='yellow',fg='black',font=("TkDefaultFont", 10, "bold"))
        self.load_button.grid(row=1,column=4,sticky=N+S+W+E)
        self.load_button.configure(state='normal')
        
        self.lbl_nse_con_time: Label = Label(top_frame,text=' ',justify=LEFT,font=("TkDefaultFont", 10, "bold"))
        #self.lbl_nse_con_time.pack(anchor=N, expand=False, side=LEFT)
        self.lbl_nse_con_time.grid(row=0,column=6,sticky=N+S+W+E)
        
        bot_frame: Frame = Frame(self.sh_window,width=1200,height=.3*rh)
        #bot_frame.pack(anchor='nw', fill='both',expand=True, side=TOP)
        bot_frame.grid(row=1,column=0,sticky='nsew')
        #bot_frame.grid_rowconfigure(0, weight=1)
        #bot_frame.grid_columnconfigure(0, weight=1)
        #bot_frame.grid_propagate(0)
        
        self.plot_frame: Frame = Frame(self.sh_window,width=1200, height=.6*rh)
        #self.plot_frame.pack(anchor='nw', fill='both',expand=True, side=TOP)
        self.plot_frame.grid(row=2,column=0,sticky="nsew")
        #self.plot_frame.grid_rowconfigure(0, weight=1)
        #self.plot_frame.grid_columnconfigure(0, weight=1)
        #self.plot_frame.grid_propagate(0)
        
        fig = Figure(figsize = (2, 2), dpi = 200) 
        self.plot1 = fig.add_subplot(111)
        self.plot1.tick_params(axis='both', which='minor', labelsize=8)

        self.canvas = FigureCanvasTkAgg(fig,master = self.plot_frame)
        self.canvas.get_tk_widget().pack(anchor=N,fill='both',expand=True) 
        
        self.NB: Notebook = Notebook(bot_frame)
        self.NB.pack(anchor=N,fill="both", expand=True)
        self.NBF: List[Frame] = []
        self.NBS: List[tksheet.Sheet] = []
        self.NB_DF: List[pd.Dataframe] = []
        
        for strat in enumerate(self.strategies):
            self.NBF.append(Frame(self.NB))
            self.NB.add(self.NBF[-1],text=strat[1])
            sh = tksheet.Sheet(self.NBF[-1], column_width=100, align="center",
                                                  headers = self.sh_cols[strat[0]],
                                                  header_font=("TkDefaultFont", 10, "bold"),
                                                  empty_horizontal=0, empty_vertical=20, header_height=35)
            sh.enable_bindings(
            ("toggle_select", "drag_select", "column_select", "row_select", "column_width_resize",
             "arrowkeys", "right_click_popup_menu", "rc_select", "copy", "select_all"))
            sh.pack(anchor=W,fill="both", expand=True)
            #sh.change_theme("dark")
            self.NBS.append(sh)
    
    def export_iron_condor(self):
        self.imp_strikes.clear()
        self.imp_my_buy_price.clear()
        for i in enumerate(self.imp_cbox):
            if(i[1].get()==""):
                break
            self.imp_strikes.append(float(i[1].get()))
            self.imp_my_buy_price.append(float(self.imp_tbox[i[0]].get('1.0',END)))
        df_export: pd.DataFrame = pd.DataFrame()
        df_export['Strikes'] = self.imp_strikes
        df_export['Buy_price'] = self.imp_my_buy_price
        save_name = self.combo_box_stock.get()+'-'+self.date_combo_box_stock.get()+'-'+datetime.now().strftime("%H:%M:%S")
        df_export.to_csv(save_name+'.csv')
        
        self.imp_wd.destroy() 
        self.import_button.configure(state='disabled')
    
    def save_current_data(self):
        save_name = self.combo_box_stock.get()+'_'+self.date_combo_box_stock.get()+'_'+date.today().strftime("%b-%d-%Y")+'.csv'
        if(not path.exists(save_name)):
            df_export: pd.DataFrame = pd.DataFrame()
            df_export['Strikes'] = self.df['Instrument']
            df_export['Buy_price'] = self.df['My_price']
            df_export['Qty'] = [(self.df['Qty'].tolist())[0]]*5
            df_export.to_csv(save_name)

    def load_file(self): 
        file = askopenfile(mode ='r', filetypes =[('CSV files', '*.csv')]) 
        self.df_loaded: pd.DataFrame = pd.read_csv(file.name)
        self.imp_strikes = self.df_loaded['Strikes'].tolist()
        self.imp_my_buy_price = self.df_loaded['Buy_price'].tolist()
        qty = (self.df_loaded['Qty'].tolist())[0]
        name_split = (os.path.basename(file.name)).split('_')
        print(name_split)
        self.combo_box_stock.set(name_split[0])
        self.date_combo_box_stock.set(name_split[1])
        self.qty_combo_box.set(qty)
        self.nse_adapter.set_stock(self.combo_box_stock.get())
        self.main_recursive()
    
    def open_file(self): 
        file = askopenfile(mode ='r', filetypes =[('CSV files', '*.csv')]) 
        #if file is not None: 
        #    content = file.read() 
        #    print(content) 
        self.df_loaded: pd.DataFrame = pd.read_csv(file.name)
        self.imp_strikes = self.df_loaded['Strikes'].tolist()
        self.imp_my_buy_price = self.df_loaded['Buy_price'].tolist()
        self.imp_wd.destroy() 
        self.import_button.configure(state='disabled')
    
    def import_iron_condor(self):
        self.imp_wd: Tk = Tk()
        self.imp_wd.title('Paper trading')
        window_width: int = self.imp_wd.winfo_reqwidth()
        window_height: int = self.imp_wd.winfo_reqheight()
        position_right: int = int(self.imp_wd.winfo_screenwidth() / 2 - window_width / 2)
        position_down: int = int(self.imp_wd.winfo_screenheight() / 2 - window_height / 2)
        self.imp_wd.geometry("600x300+300+200")
        
        bot_frame: Frame = Frame(self.imp_wd,width=800, height=300)
        bot_frame.pack(anchor='nw', fill='both',expand=True, side=TOP)
        bot_frame.pack_propagate(0)
        
        json_data = self.nse_adapter.get_oc_data()
        match_date = self.date_combo_box_stock.get()
        strike_prices: List[float] = [data['strikePrice'] for data in json_data['records']['data'] \
                                   if (str(data['expiryDate']).lower() == str(match_date).lower())]
        

        self.imp_cbox: List[Combobox]    = []
        self.imp_tbox: List[tk.Text]    = []
        imp_vars: List[StringVar] = []
        imp_lbls: List[Label]     = []
        imp_lbls_txt: List[Label] = ['buy PUT','sell PUT','sell CALL','buy CALL']
        imp_lbls_color: List[Label] = ['green','red','red','green']
            
        row_idx = 0

        for i in enumerate(imp_lbls_txt):
            str_var = StringVar()
            str_var.set(' ')
            lbl: Label = Label(bot_frame,text=i[1],justify=LEFT,font=("TkDefaultFont", 10,"bold"),fg=imp_lbls_color[i[0]],width=20)
            lbl.grid(row=i[0],column=0,sticky=N+S+W)
            cb = Combobox(bot_frame,width=10,textvariable=str_var) 
            cb.grid(row=i[0],column=1,sticky=N+S+W)
            cb.configure(state='readonly')
            cb['values'] = strike_prices
            self.imp_cbox.append(cb)
            txt = tk.Text(bot_frame,width=10,bg='yellow',height=2)
            txt.grid(row=i[0],column=2,sticky=N+S+W)
            self.imp_tbox.append(txt)
            row_idx = i[0]+1
        
        ok_button: Button = tk.Button(bot_frame,text='OK!',command=self.export_iron_condor,width=20,bg='green',fg='white',font=("TkDefaultFont", 10, "bold"))
        ok_button.grid(row=row_idx,column=4,sticky=N+S+W)
        
        load_button: Button = tk.Button(bot_frame,text='Load',command=self.open_file,width=20,bg='green',fg='white',font=("TkDefaultFont", 10, "bold"))
        load_button.grid(row=row_idx+1,column=4,sticky=N+S+W)

        
    def set_VIX(self,event):
        self.vix_percentage = float(self.vix_combo_box.get())
    def set_expiry_date(self,event):
        self.nse_adapter.set_stock(self.combo_box_stock.get())
        self.nse_adapter.get_expiry_dates()
        self.date_combo_box_stock['values'] = tuple(self.nse_adapter.expiry_dates)
        self.date_combo_box_stock.set(self.nse_adapter.expiry_dates[0])
        qtys = [x*int(self.indices_lot[self.combo_box_stock.get()]) for x in range(1,11)]
        self.qty_combo_box['values'] = qtys
        self.qty_combo_box.set(qtys[0])
        self.start_button.configure(state='normal')
        self.import_button.configure(state='normal')
    
    def main_recursive(self)->None:
        if(self.first_run):
            self.start_button.configure(state='disabled')
            self.combo_box_stock.configure(state='disabled')
            self.date_combo_box_stock.configure(state='disabled')
            self.qty_combo_box.configure(state='disabled')
            self.refresh_data()
            self.first_run = False
        self.curr_time = time.time()
        time_passed = int(self.curr_time-self.prev_time)
        if(time_passed>=self.interval):
            self.refresh_data()
        else:
            self.sh_window.after((10 * 1000),self.main_recursive)
            return
        if(not self.stop):
            self.sh_window.after((10 * 1000),self.main_recursive)
            return

    def refresh_data(self):
        for strat in enumerate(self.strategies):
            curr_sh = self.NBS[strat[0]]
            if(strat[1]=='IRON CONDOR'):
                df = self.df_iron_condor()
                for col in enumerate(df.columns):
                    curr_sh.set_column_data(col[0],values=df[col[1]])
                for i in range(curr_sh.get_total_rows()):
                    if(float(curr_sh.get_cell_data(i,len(df.columns)-1))<=0.0):
                        curr_sh.highlight_cells(row=i, column=len(df.columns)-1, bg='white',fg='red')
                    if(float(curr_sh.get_cell_data(i,len(df.columns)-1))>0.0):
                        curr_sh.highlight_cells(row=i, column=len(df.columns)-1, bg='green',fg='white')
        self.prev_time = time.time()
        curr_sh.refresh()

    
    def df_iron_condor(self):
        df: pd.DataFrame = pd.DataFrame()
        df_graph: pd.DataFrame = pd.DataFrame()
        
        buy_pe_pl: List[float] = []
        sell_pe_pl: List[float] = []
        sell_ce_pl: List[float] = []
        buy_ce_pl: List[float] = []
        
        start = time.time()
        json_data = self.nse_adapter.get_oc_data()
        end = time.time();
        strr = "NSE response time (sec) : " + str(round(end-start,2)) + " ( " + str(self.nse_adapter.con_trial) + " hits)"
        self.lbl_nse_con_time.config(text=strr)
        match_date = self.date_combo_box_stock.get()
        print(match_date)
        strike_prices: List[float] = [data['strikePrice'] for data in json_data['records']['data'] \
                                   if (str(data['expiryDate']).lower() == str(match_date).lower())]
        ce_values: List[dict] = [data['CE'] for data in json_data['records']['data'] \
                    if "CE" in data and (str(data['expiryDate'].lower()) == str(match_date.lower()))]
        pe_values: List[dict] = [data['PE'] for data in json_data['records']['data'] \
                    if "PE" in data and (str(data['expiryDate'].lower()) == str(match_date.lower()))]
         
        ce_data: pd.DataFrame = pd.DataFrame(ce_values)
        pe_data: pd.DataFrame = pd.DataFrame(pe_values)
       
        #print(list(ce_data.columns))
        
        pe_otm_data: pd.DataFrame = pd.DataFrame()
        ce_otm_data: pd.DataFrame = pd.DataFrame()

        df_call_buy: pd.DataFrame = pd.DataFrame() 

        strike_diff: List[float] = []
        
        
        curr_price = ce_data['underlyingValue'][0]
        self.sh_window.title('Paper trading-->'+self.combo_box_stock.get()+' ('+str(curr_price)+' ) last updated @--'+datetime.now().strftime("%H:%M:%S"))
        if(self.first_run):
            diff = [abs(x-curr_price) for x in strike_prices]
            min_pos = diff.index(min(diff))
            self.my_atm = strike_prices[min_pos]
            
        strike_diff = list(map(lambda x:x-self.my_atm,strike_prices))
        
        iron_condor_strikes: List[float] = []
        if(len(self.imp_strikes)==0):
            search_strike = (1-(self.vix_percentage/100.))*self.my_atm
            diff = [abs(x-search_strike) for x in strike_prices]
            min_pos = diff.index(min(diff))
            sell_pe_idx = min_pos

            buy_pe_idx = sell_pe_idx-1
            iron_condor_strikes.append(buy_pe_idx)#buy_pe_strike
            iron_condor_strikes.append(sell_pe_idx)#sell_pe_strike
         
            pe_otm_data = pe_data.iloc[iron_condor_strikes] 
            
            iron_condor_strikes.clear()
            search_strike = (1+(self.vix_percentage/100.))*self.my_atm
            diff = [abs(x-search_strike) for x in strike_prices]
            min_pos = diff.index(min(diff))
            sell_ce_idx = min_pos
            iron_condor_strikes.append(min_pos)#sell_ce_strike
            
            buy_ce_idx = sell_ce_idx + 1
            iron_condor_strikes.append(buy_ce_idx)#buy_ce_strike
            
            ce_otm_data = ce_data.iloc[iron_condor_strikes]
        else:
            iron_condor_strikes.append(strike_prices.index(self.imp_strikes[0]))
            iron_condor_strikes.append(strike_prices.index(self.imp_strikes[1]))
            pe_otm_data = pe_data.iloc[iron_condor_strikes] 
            buy_pe_idx = iron_condor_strikes[0]
            sell_pe_idx = iron_condor_strikes[1]
            
            iron_condor_strikes.clear()
            iron_condor_strikes.append(strike_prices.index(self.imp_strikes[2]))
            iron_condor_strikes.append(strike_prices.index(self.imp_strikes[3]))
            ce_otm_data = ce_data.iloc[iron_condor_strikes]
            
            sell_ce_idx = iron_condor_strikes[0]
            buy_ce_idx = iron_condor_strikes[1]
            
            self.my_buy_price = self.imp_my_buy_price
            

        
        pd_concat = pd.concat([pe_otm_data,ce_otm_data],axis=0)
        sell_buy_signs = [1.,-1.,-1.,1.]
        lot_list = [float(self.qty_combo_box.get())]*4
        qty_list = list(map(mul,lot_list,sell_buy_signs))
        ltp_list = list(map(float,pd_concat['lastPrice'].tolist()))
        if(self.first_run and len(self.imp_strikes)==0):
            self.my_buy_price = pd_concat['lastPrice'].tolist()
        
        net_points: List[float] = list(map(mul,sell_buy_signs,self.my_buy_price))
        net_points = list(map(lambda x: x*-1,net_points))
        tt = list(map(sub,ltp_list,self.my_buy_price))
        df['Instrument'] = pd_concat['strikePrice'].tolist() 
        df['Qty'] = qty_list
        df['My_price'] = list(map(float,self.my_buy_price))
        df['LTP'] = ltp_list
        df['P&L'] = list(map(mul,tt,qty_list))
        df['P&L'] =  df['P&L'].round(3)
        total_row = {'Instrument':' ','Qty':' ','My_price':str(round(sum(net_points),2)),'LTP':'Total ','P&L':df['P&L'].sum()}
        df = df.append(total_row,ignore_index=True)
        
        for i in range(len(strike_prices)):
            if(i>=buy_pe_idx):
                val = -self.my_buy_price[0]
            else:
                val = abs(strike_prices[i]-strike_prices[buy_pe_idx])-self.my_buy_price[0]
            buy_pe_pl.append(val)
            
            if(i>=sell_pe_idx):
                val = self.my_buy_price[1]
            else:
                val = self.my_buy_price[1]-abs(strike_prices[i]-strike_prices[sell_pe_idx])
            sell_pe_pl.append(val)
            
            if(i<=sell_ce_idx):
                val = self.my_buy_price[2]
            else:
                val = self.my_buy_price[2]-abs(strike_prices[i]-strike_prices[sell_ce_idx])
            sell_ce_pl.append(val)
            
            if(i<=buy_ce_idx):
                val = -self.my_buy_price[3]
            else:
                val = abs(strike_prices[i]-strike_prices[buy_ce_idx])-self.my_buy_price[3]
            buy_ce_pl.append(val)
        
        self.buy_pe_limit.append((pd_concat['strikePrice'].tolist())[0])
        self.sell_pe_limit.append((pd_concat['strikePrice'].tolist())[1])
        self.sell_ce_limit.append((pd_concat['strikePrice'].tolist())[2])
        self.buy_ce_limit.append((pd_concat['strikePrice'].tolist())[3])
        self.market_price.append(curr_price)
        
        ttl1 = list(map(add,buy_pe_pl,sell_pe_pl)) 
        ttl2 = list(map(add,buy_ce_pl,sell_ce_pl)) 
        ttl3 = list(map(add,ttl1,ttl2)) 
        ttl3 = list(map(lambda x:x*float(self.qty_combo_box.get()),ttl3))
        df_graph['sell_call'] = ttl3

        #plt.clf()
        #plt.plot(strike_prices,ttl3,'-b')
        #plt.axvline(x=(pd_concat['strikePrice'].tolist())[0],linestyle='--',color='g')
        #plt.axvline(x=(pd_concat['strikePrice'].tolist())[1],linestyle='--',color='r')
        #plt.axvline(x=(pd_concat['strikePrice'].tolist())[2],linestyle='--',color='r')
        #plt.axvline(x=(pd_concat['strikePrice'].tolist())[3],linestyle='--',color='g')
        #plt.plot(curr_price,df['P&L'].iloc[0:-1].sum(),'D')
        #plt.text(1.05*min(strike_prices),.9*max(ttl3),'max_profit = '+str(round(max(ttl3),2)),color='green',fontsize='10')
        #plt.text(1.05*min(strike_prices),.3*max(ttl3),'max_loss = '+str(round(min(ttl3),2)),color='red',fontsize='10')
        #clr = 'red'
        #if(df['P&L'].iloc[0:-1].sum()>0):
        #    clr = 'green'
        #plt.text(1.01*curr_price,1.01*df['P&L'].iloc[0:-1].sum(),str(df['P&L'].iloc[0:-1].sum()),color=clr,fontsize='8')
        #plt.pause(.0001)
        #plt.show(block = False)
        #plt.title('Paper trading-->'+self.combo_box_stock.get()+' ('+str(curr_price)+' ) last updated @--'+datetime.now().strftime("%H:%M:%S"))
        self.strike_prices = strike_prices
        self.pd_concat = pd_concat
        self.curr_price = curr_price
        self.ttl3 = ttl3
        self.df = df
        self.draw_plot()
        self.save_current_data()
        return df
        
    def draw_plot(self):
        self.plot1.clear()
        self.plot1.plot(self.strike_prices,self.ttl3,'-b',lw=.8)
        self.plot1.axvline(x=(self.pd_concat['strikePrice'].tolist())[0],linestyle='--',color='g',lw=.8)
        self.plot1.axvline(x=(self.pd_concat['strikePrice'].tolist())[1],linestyle='--',color='r',lw=.8)
        self.plot1.axvline(x=(self.pd_concat['strikePrice'].tolist())[2],linestyle='--',color='r',lw=.8)
        self.plot1.axvline(x=(self.pd_concat['strikePrice'].tolist())[3],linestyle='--',color='g',lw=.8)
        self.plot1.plot(self.curr_price,self.df['P&L'].iloc[0:-1].sum(),'D',markersize=2)
        self.plot1.text(1.01*min(self.strike_prices),.5*max(self.ttl3),'max_profit ='+str(round(max(self.ttl3),2)),color='green',fontsize='6')
        self.plot1.text(1.1*min(self.strike_prices),.5*max(self.ttl3),'max_loss = '+str(round(min(self.ttl3),2)),color='red',fontsize='6')
        clr = 'red'
        if(self.df['P&L'].iloc[0:-1].sum()>0):
            clr = 'green'
        self.plot1.text(1.01*self.curr_price,1.01*self.df['P&L'].iloc[0:-1].sum(),str(self.df['P&L'].iloc[0:-1].sum()),color=clr,fontsize='4')
        self.canvas.draw()
Esempio n. 16
0
class Config(Toplevel):
    def __init__(self, master):
        Toplevel.__init__(self, master)
        self.title(_("Preferences"))
        self.grab_set()
        self.resizable(False, False)
        self.protocol("WM_DELETE_WINDOW", self.quit)
        self.changes = {}, {}

        # --- style
        style = Style(self)
        style.theme_use("clam")
        style.configure("TScale", sliderlength=20)
        style.map("TCombobox",
                  fieldbackground=[('readonly', 'white')],
                  selectbackground=[('readonly', 'white')],
                  selectforeground=[('readonly', 'black')])
        style.configure("prev.TLabel", background="white")
        style.map("prev.TLabel", background=[("active", "white")])
        color = CONFIG.get("Categories",
                           CONFIG.get("General", "default_category"))
        style.configure("titlebar.TFrame", background=color)
        style.configure("titlebar.TLabel", background=color)
        style.configure("text.TFrame", background="white")

        # --- body
        self.notebook = Notebook(self)
        okcancel_frame = Frame(self)
        okcancel_frame.columnconfigure(0, weight=1)
        okcancel_frame.columnconfigure(1, weight=1)
        self.notebook.pack(expand=True, fill="both")
        okcancel_frame.pack(fill="x", expand=True)

        # --- * General settings
        general_settings = Frame(self.notebook)
        general_settings.columnconfigure(0, weight=1)
        self.notebook.add(general_settings,
                          text=_("General"),
                          sticky="ewsn",
                          padding=4)

        # --- *-- language
        lang = {"fr": "Français", "en": "English"}
        self.lang = StringVar(self, lang[CONFIG.get("General", "language")])
        lang_frame = Frame(general_settings)
        Label(lang_frame, text=_("Language")).grid(row=0,
                                                   sticky="w",
                                                   padx=4,
                                                   pady=4)
        menu_lang = Menu(lang_frame, tearoff=False)
        Menubutton(lang_frame, menu=menu_lang, width=9,
                   textvariable=self.lang).grid(row=0,
                                                column=1,
                                                padx=8,
                                                pady=4)
        menu_lang.add_radiobutton(label="English",
                                  value="English",
                                  variable=self.lang,
                                  command=self.translate)
        menu_lang.add_radiobutton(label="Français",
                                  value="Français",
                                  variable=self.lang,
                                  command=self.translate)
        # --- *-- opacity
        self.opacity_scale = Scale(general_settings,
                                   orient="horizontal",
                                   length=200,
                                   from_=0,
                                   to=100,
                                   value=CONFIG.get("General", "opacity"),
                                   command=self.display_label)
        self.opacity_label = Label(
            general_settings,
            text="{val}%".format(val=self.opacity_scale.get()))
        # --- *-- position
        frame_position = Frame(general_settings)
        self.position = StringVar(self, CONFIG.get("General", "position"))
        Label(frame_position,
              text=_("Default position of the notes")).grid(row=0,
                                                            columnspan=3,
                                                            sticky="w",
                                                            padx=4,
                                                            pady=4)
        Radiobutton(frame_position,
                    text=_("Always above"),
                    value="above",
                    variable=self.position).grid(row=1, column=0)
        Radiobutton(frame_position,
                    text=_("Always below"),
                    value="below",
                    variable=self.position).grid(row=1, column=1)
        Radiobutton(frame_position,
                    text=_("Normal"),
                    value="normal",
                    variable=self.position).grid(row=1, column=2)
        # --- *-- titlebar
        self.titlebar_disposition = StringVar(
            self, CONFIG.get("General", "buttons_position"))
        font_title = "%s %s" % (CONFIG.get("Font", "title_family").replace(
            " ", "\ "), CONFIG.get("Font", "title_size"))
        style = CONFIG.get("Font", "title_style").split(",")
        if style:
            font_title += " "
            font_title += " ".join(style)

        frame_titlebar = Frame(general_settings)
        frame_titlebar.columnconfigure(1, weight=1)
        frame_titlebar.columnconfigure(3, weight=1)
        Label(frame_titlebar,
              text=_("Title bar disposition")).grid(row=0,
                                                    columnspan=4,
                                                    sticky="w",
                                                    padx=4,
                                                    pady=4)
        Radiobutton(frame_titlebar,
                    value="right",
                    variable=self.titlebar_disposition).grid(row=1, column=0)
        right = Frame(frame_titlebar, style="titlebar.TFrame")
        right.grid(row=1, column=1, sticky="ew")

        def select_right(event):
            self.titlebar_disposition.set("right")

        Label(right,
              text=_("Title"),
              style="titlebar.TLabel",
              anchor="center",
              font=font_title).pack(side="left", fill="x", expand=True)
        Label(right, image="img_close",
              style="titlebar.TLabel").pack(side="right")
        Label(right, image="img_roll",
              style="titlebar.TLabel").pack(side="right")
        for ch in right.children.values():
            ch.bind("<Button-1>", select_right)
        Radiobutton(frame_titlebar,
                    value="left",
                    variable=self.titlebar_disposition).grid(row=1, column=2)
        left = Frame(frame_titlebar, style="titlebar.TFrame")
        left.grid(row=1, column=3, sticky="ew")

        def select_left(event):
            self.titlebar_disposition.set("left")

        Label(left, image="img_close",
              style="titlebar.TLabel").pack(side="left")
        Label(left, image="img_roll",
              style="titlebar.TLabel").pack(side="left")
        Label(left,
              text=_("Title"),
              style="titlebar.TLabel",
              anchor="center",
              font=font_title).pack(side="right", fill="x", expand=True)
        for ch in left.children.values():
            ch.bind("<Button-1>", select_left)
        # --- *-- placement
        lang_frame.grid(sticky="w")
        Separator(general_settings, orient="horizontal").grid(sticky="ew",
                                                              pady=10)
        Label(general_settings, text=_("Opacity")).grid(sticky="w",
                                                        padx=4,
                                                        pady=4)
        self.opacity_scale.grid(padx=4, pady=(4, 10))
        self.opacity_label.place(in_=self.opacity_scale,
                                 relx=1,
                                 rely=0.5,
                                 anchor="w",
                                 bordermode="outside")
        Separator(general_settings, orient="horizontal").grid(sticky="ew",
                                                              pady=10)
        frame_position.grid(sticky="ew")
        Separator(general_settings, orient="horizontal").grid(sticky="ew",
                                                              pady=10)
        frame_titlebar.grid(sticky="ew", pady=4)
        if LATEX:
            Separator(general_settings, orient="horizontal").grid(sticky="ew",
                                                                  pady=10)
            Button(general_settings,
                   text=_('Delete unused LaTex data'),
                   command=self.cleanup).grid(padx=4, pady=4, sticky='w')

        # --- * Font settings
        font_settings = Frame(self.notebook)
        font_settings.columnconfigure(0, weight=1)
        self.notebook.add(font_settings,
                          text=_("Font"),
                          sticky="ewsn",
                          padding=4)

        # --- *-- title
        fonttitle_frame = Frame(font_settings)

        title_size = CONFIG.get("Font", "title_size")
        title_family = CONFIG.get("Font", "title_family")

        self.sampletitle = Label(fonttitle_frame,
                                 text=_("Sample text"),
                                 anchor="center",
                                 style="prev.TLabel",
                                 relief="groove")

        self.sampletitle.grid(row=2,
                              columnspan=2,
                              padx=4,
                              pady=6,
                              ipadx=4,
                              ipady=4,
                              sticky="eswn")
        self.fonts = list(set(font.families()))
        self.fonts.append("TkDefaultFont")
        self.fonts.sort()
        w = max([len(f) for f in self.fonts])
        self.sizes = [
            "%i" % i for i in (list(range(6, 17)) + list(range(18, 32, 2)))
        ]

        self.fonttitle_family = Combobox(fonttitle_frame,
                                         values=self.fonts,
                                         width=(w * 2) // 3,
                                         exportselection=False,
                                         validate="key")
        self._validate_title_size = self.register(
            lambda *args: self.validate_font_size(self.fonttitle_size, *args))
        self._validate_title_family = self.register(
            lambda *args: self.validate_font_family(self.fonttitle_family, *
                                                    args))
        self.fonttitle_family.configure(
            validatecommand=(self._validate_title_family, "%d", "%S", "%i",
                             "%s", "%V"))
        self.fonttitle_family.current(self.fonts.index(title_family))
        self.fonttitle_family.grid(row=0, column=0, padx=4, pady=4)
        self.fonttitle_size = Combobox(
            fonttitle_frame,
            values=self.sizes,
            width=5,
            exportselection=False,
            validate="key",
            validatecommand=(self._validate_title_size, "%d", "%P", "%V"))
        self.fonttitle_size.current(self.sizes.index(title_size))
        self.fonttitle_size.grid(row=0, column=1, padx=4, pady=4)

        frame_title_style = Frame(fonttitle_frame)
        frame_title_style.grid(row=1, columnspan=2, padx=4, pady=6)
        self.is_bold = Checkbutton(frame_title_style,
                                   text=_("Bold"),
                                   command=self.update_preview_title)
        self.is_italic = Checkbutton(frame_title_style,
                                     text=_("Italic"),
                                     command=self.update_preview_title)
        self.is_underlined = Checkbutton(frame_title_style,
                                         text=_("Underline"),
                                         command=self.update_preview_title)
        style = CONFIG.get("Font", "title_style")
        if "bold" in style:
            self.is_bold.state(("selected", ))
        if "italic" in style:
            self.is_italic.state(("selected", ))
        if "underline" in style:
            self.is_underlined.state(("selected", ))
        self.is_bold.pack(side="left")
        self.is_italic.pack(side="left")
        self.is_underlined.pack(side="left")

        self.update_preview_title()
        # --- *-- text
        size = CONFIG.get("Font", "text_size")
        family = CONFIG.get("Font", "text_family")

        font_frame = Frame(font_settings)
        self.sample = Label(font_frame,
                            text=_("Sample text"),
                            anchor="center",
                            style="prev.TLabel",
                            relief="groove")
        self.sample.grid(row=1,
                         columnspan=2,
                         padx=4,
                         pady=6,
                         ipadx=4,
                         ipady=4,
                         sticky="eswn")

        self.font_family = Combobox(font_frame,
                                    values=self.fonts,
                                    width=(w * 2) // 3,
                                    exportselection=False,
                                    validate="key")
        self._validate_family = self.register(
            lambda *args: self.validate_font_family(self.font_family, *args))
        self._validate_size = self.register(
            lambda *args: self.validate_font_size(self.font_size, *args))
        self.font_family.configure(validatecommand=(self._validate_family,
                                                    "%d", "%S", "%i", "%s",
                                                    "%V"))
        self.font_family.current(self.fonts.index(family))
        self.font_family.grid(row=0, column=0, padx=4, pady=4)
        self.font_size = Combobox(font_frame,
                                  values=self.sizes,
                                  width=5,
                                  exportselection=False,
                                  validate="key",
                                  validatecommand=(self._validate_size, "%d",
                                                   "%P", "%V"))
        self.font_size.current(self.sizes.index(size))
        self.font_size.grid(row=0, column=1, padx=4, pady=4)

        self.update_preview()

        # --- *-- placement
        Label(font_settings, text=_("Title")).grid(row=0,
                                                   padx=4,
                                                   pady=4,
                                                   sticky="w")
        fonttitle_frame.grid(row=1)
        Separator(font_settings, orient="horizontal").grid(row=2,
                                                           sticky="ew",
                                                           pady=10)
        Label(font_settings, text=_("Text")).grid(row=3,
                                                  padx=4,
                                                  pady=4,
                                                  sticky="w")
        font_frame.grid(row=4)

        # --- * Categories
        self.category_settings = CategoryManager(self.notebook, master)
        self.notebook.add(self.category_settings,
                          text=_("Categories"),
                          sticky="ewsn",
                          padding=4)
        # --- * Symbols
        symbols_settings = Frame(self.notebook)
        self.notebook.add(symbols_settings,
                          text=_("Symbols"),
                          sticky="ewsn",
                          padding=4)
        txt_frame = Frame(symbols_settings,
                          relief="sunken",
                          borderwidth=1,
                          style="text.TFrame")
        self.symbols = Text(txt_frame,
                            width=1,
                            height=1,
                            highlightthickness=0,
                            spacing2=5,
                            spacing1=5,
                            relief="flat",
                            padx=4,
                            pady=4,
                            font="%s %s" % (family.replace(" ", "\ "), size))
        self.symbols.insert("1.0", CONFIG.get("General", "symbols"))
        Label(symbols_settings, text=_("Available symbols")).pack(padx=4,
                                                                  pady=4)
        txt_frame.pack(fill="both", expand=True, padx=4, pady=4)
        self.symbols.pack(fill="both", expand=True)
        Button(symbols_settings, text=_('Reset'),
               command=self.reset_symbols).pack(padx=4, pady=4)

        # --- Ok/Cancel buttons
        Button(okcancel_frame, text="Ok", command=self.ok).grid(row=1,
                                                                column=0,
                                                                padx=4,
                                                                pady=10,
                                                                sticky="e")
        Button(okcancel_frame, text=_("Cancel"),
               command=self.destroy).grid(row=1,
                                          column=1,
                                          padx=4,
                                          pady=10,
                                          sticky="w")
        # --- bindings
        self.font_family.bind('<<ComboboxSelected>>', self.update_preview)
        self.font_family.bind('<Return>', self.update_preview)
        self.font_size.bind('<<ComboboxSelected>>',
                            self.update_preview,
                            add=True)
        self.font_size.bind('<Return>', self.update_preview, add=True)
        self.fonttitle_family.bind('<<ComboboxSelected>>',
                                   self.update_preview_title)
        self.fonttitle_size.bind('<<ComboboxSelected>>',
                                 self.update_preview_title,
                                 add=True)
        self.fonttitle_family.bind('<Return>', self.update_preview_title)
        self.fonttitle_size.bind('<Return>',
                                 self.update_preview_title,
                                 add=True)

    def reset_symbols(self):
        self.symbols.delete('1.0', 'end')
        self.symbols.insert('1.0', SYMBOLS)

    def cleanup(self):
        ''' Remove unused latex images '''
        self.master.cleanup()

    def validate_font_size(self, combo, d, ch, V):
        ''' Validation of the size entry content '''
        if d == '1':
            l = [i for i in self.sizes if i[:len(ch)] == ch]
            if l:
                i = self.sizes.index(l[0])
                combo.current(i)
                index = combo.index("insert")
                combo.selection_range(index + 1, "end")
                combo.icursor(index + 1)
            return ch.isdigit()
        else:
            return True

    def validate_font_family(self, combo, action, modif, pos, prev_txt, V):
        """ completion of the text in the path entry with existing
            folder/file names """
        try:
            sel = combo.selection_get()
            txt = prev_txt.replace(sel, '')
        except TclError:
            txt = prev_txt
        if action == "0":
            txt = txt[:int(pos)] + txt[int(pos) + 1:]
            return True
        else:
            txt = txt[:int(pos)] + modif + txt[int(pos):]
            l = [i for i in self.fonts if i[:len(txt)] == txt]
            if l:
                i = self.fonts.index(l[0])
                combo.current(i)
                index = combo.index("insert")
                combo.delete(0, "end")
                combo.insert(0, l[0].replace("\ ", " "))
                combo.selection_range(index + 1, "end")
                combo.icursor(index + 1)
                return True
            else:
                return False

    def ok(self):
        family = self.font_family.get()
        if family not in self.fonts:
            l = [i for i in self.fonts if i[:len(family)] == family]
            if l:
                family = l[0]
            else:
                family = 'TkDefaultFont'
        size = self.font_size.get()
        familytitle = self.fonttitle_family.get()
        if familytitle not in self.fonts:
            l = [i for i in self.fonts if i[:len(familytitle)] == familytitle]
            if l:
                familytitle = l[0]
            else:
                familytitle = 'TkDefaultFont'
        sizetitle = self.fonttitle_size.get()
        opacity = "%i" % float(self.opacity_scale.get())
        language = self.lang.get().lower()[:2]
        style = ""
        if self.is_bold.instate(("selected", )):
            style += "bold,"
        if self.is_italic.instate(("selected", )):
            style += "italic,"
        if self.is_underlined.instate(("selected", )):
            style += "underline,"
        if style:
            style = style[:-1]

        symbols = [
            l.strip() for l in self.symbols.get("1.0", "end").splitlines()
        ]

        CONFIG.set("General", "default_category",
                   self.category_settings.default_category.get().lower())
        CONFIG.set("General", "language", language)
        CONFIG.set("General", "opacity", opacity)
        CONFIG.set("General", "position", self.position.get())
        CONFIG.set("General", "buttons_position",
                   self.titlebar_disposition.get())
        CONFIG.set("General", "symbols", "".join(symbols))
        CONFIG.set("Font", "text_size", size)
        CONFIG.set("Font", "text_family", family)
        CONFIG.set("Font", "title_family", familytitle)
        CONFIG.set("Font", "title_size", sizetitle)
        CONFIG.set("Font", "title_style", style)

        col_changes = {}
        name_changes = {}
        for cat in self.category_settings.categories:
            new_name = self.category_settings.get_name(cat)
            if cat in CONFIG.options("Categories"):
                old_color = CONFIG.get("Categories", cat)
                new_color = COLORS[self.category_settings.get_color(cat)]
                if new_name != cat:
                    name_changes[cat] = new_name
                    CONFIG.remove_option("Categories", cat)
                    CONFIG.set("Categories", new_name, new_color)
                if old_color != new_color:
                    col_changes[new_name] = (old_color, new_color)
                    CONFIG.set("Categories", new_name, new_color)

            else:
                CONFIG.set("Categories", new_name,
                           COLORS[self.category_settings.get_color(cat)])
        save_config()
        self.changes = col_changes, name_changes
        self.destroy()

    def get_changes(self):
        return self.changes

    def translate(self):
        showinfo(
            "Information",
            _("The language setting will take effect after restarting the application"
              ),
            parent=self)

    def update_preview(self, event=None):
        family = self.font_family.get()
        size = self.font_size.get()
        self.sample.configure(font="%s %s" % (family.replace(" ", "\ "), size))

    def update_preview_title(self, event=None):
        family = self.fonttitle_family.get()
        size = self.fonttitle_size.get()
        config = "%s %s" % (family.replace(" ", "\ "), size)
        if self.is_bold.instate(("selected", )):
            config += " bold"
        if self.is_italic.instate(("selected", )):
            config += " italic"
        if self.is_underlined.instate(("selected", )):
            config += " underline"
        self.sampletitle.configure(font=config)

    def display_label(self, value):
        self.opacity_label.configure(text=" {val} %".format(
            val=int(float(value))))

    def quit(self):
        self.destroy()
class EnergyMonitor():
    def __init__(self, parent):
        self.parent = parent

        self.data_container = OrderedDict()
        self.monthly_data = OrderedDict()
        self.loaded_ids = []
        self.loaded_fuels = []

        self.welcome_label = tk.Label(self.parent,
                                      text='Welcome to the Energy Monitor!',
                                      font=('Calibri', 32))
        self.welcome_label.configure(background='#c6e2ff')
        self.welcome_label.pack()

        self.message_label = tk.Label(
            self.parent,
            text=
            'Please use the dialog below to load a CSV file, which will be displayed '
            + 'in the box below.',
            font=('Calibri', 14),
            wraplength=540)
        self.message_label.configure(background='#c6e2ff')
        self.message_label.pack(pady=20)

        # self.btn_file = Button(parent, text="Load file", command=load_file)
        self.btn_file = tk.Button(self.parent,
                                  text="Load file",
                                  command=self.load_file)
        self.btn_file.pack(pady=20)

        self.scrolled_text = tk.scrolledtext.ScrolledText(self.parent,
                                                          width=40,
                                                          height=10)
        self.scrolled_text.pack()

        self.house_combo = Combobox(self.parent)
        self.house_combo.pack_forget()

        self.fuel_label = tk.Label(self.parent, text="", font=('Calibri', 11))
        self.fuel_label.pack_forget()

        self.btn_graph_annual = tk.Button(
            self.parent,
            text='Annual Usage',
            command=functools.partial(self.generate_annual_graph_singlehouse,
                                      self.house_combo.get()))
        self.btn_graph_annual.pack_forget()

        self.btn_graph_monthly = tk.Button(
            self.parent,
            text='Monthly Usage',
            command=functools.partial(self.generate_monthly_graph_singlehouse,
                                      self.house_combo.get()))
        self.btn_graph_monthly.pack_forget()

        self.btn_graph_multiple_monthly = tk.Button(
            self.parent,
            text='All Houses Monthly Usage',
            command=functools.partial(self.generate_graph_monthly_multiple,
                                      self.house_combo.get()))
        self.btn_graph_multiple_monthly.pack_forget()

        self.selected_radio = tk.IntVar()
        self.radio_gas = tk.Radiobutton(self.parent,
                                        text="Gas",
                                        value=FuelType.gas.value,
                                        variable=self.selected_radio)
        self.radio_electric = tk.Radiobutton(self.parent,
                                             text="Electricity",
                                             value=FuelType.electricity.value,
                                             variable=self.selected_radio)
        self.radio_gas.pack_forget()
        self.radio_electric.pack_forget()

    def load_file(self, file=None):

        if file is None:
            file = filedialog.askopenfilename(
                initialdir=path.dirname(__file__))
        elif not path.isfile(file):
            raise ValueError("This file does not exist or is not readable.")

        print(file)

        re_single_house = re.compile('^(.*?)_both_daily$')
        re_multiple_houses = re.compile('^(gas|electricity)_daily$')

        filename = basename(file).split('.')[0]
        single_match = re_single_house.search(filename)
        multiple_match = re_multiple_houses.search(filename)

        if single_match is not None:
            self.process_single_file(file, single_match.group(1))
        elif multiple_match is not None:
            fuel_type = FuelType[multiple_match.group(1)]
            self.process_multiple_file(file, fuel_type)
        else:
            raise ValueError(
                "File format is not correct, must be one of '{fuel-type}_daily.csv"
                + " or '{house-id}_both_daily.csv is invalid")

        self.house_combo.configure(values=self.loaded_ids)
        self.house_combo.current(0)
        self.house_combo.pack(pady=5)

        self.fuel_label.configure(
            text="Available fuel types: " +
            ','.join(list(map(lambda f: str(f.name), self.loaded_fuels))))
        self.fuel_label.pack(pady=20)

        self.btn_graph_annual.pack(pady=5)
        self.btn_graph_monthly.pack()

        if len(self.loaded_ids) > 1:

            self.btn_graph_multiple_monthly.pack()
            if FuelType.gas in self.loaded_fuels:
                self.radio_gas.pack()
            if FuelType.electricity in self.loaded_fuels:
                self.radio_electric.pack()

    def process_single_file(self, file, house_id):
        print(
            "This file is a single house with both fuel types. The house id is '%s'."
            % house_id)
        print("Deleting old data")
        self.data_container.clear()
        self.loaded_ids.clear()
        self.loaded_fuels.clear()

        with open(file, 'r') as file_contents:
            reader = csv.reader(file_contents)
            header = next(reader, None)

            if header[1].lower() != 'electricity' or header[2].lower(
            ) != 'gas':
                raise ValueError(
                    'File is not in correct format. First column must be electricity, second must be gas.'
                )

            for row in reader:
                print(row)
                this_date = datetime.datetime.strptime(row[0], '%Y%m%d').date()

                self.data_container[this_date] = {
                    house_id: {
                        FuelType.electricity: float(row[1]),
                        FuelType.gas: float(row[2])
                    }
                }

            # Since we have only loaded one file, set the id directly
            self.loaded_ids.append(house_id)
            self.loaded_fuels.extend([FuelType.electricity, FuelType.gas])

    def process_multiple_file(self, file, fuel_type):
        print("This file is a multiple house file with %s data." % fuel_type)

        with open(file, 'r') as file_contents:
            reader = csv.reader(file_contents)
            header = next(reader, None)
            # Add the loaded ids to the list
            self.loaded_ids = header[1:len(header)]

            if fuel_type not in self.loaded_fuels:
                self.loaded_fuels.append(fuel_type)

            if header[0].lower() != 'date':
                raise ValueError(
                    'The header line must begin with a date column, then a column for each property'
                )

            for row in reader:
                this_date = datetime.datetime.strptime(row[0], '%Y%m%d').date()

                if this_date not in self.data_container:
                    self.data_container[this_date] = {}

                # Validate number of rows with data in is correct with the header
                if len(row) != len(header):
                    raise ValueError(
                        'The number of elements in this row is not correct.')

                for index in range(1, len(row)):

                    this_house_id = header[index]
                    if this_house_id not in self.data_container[this_date]:
                        self.data_container[this_date][this_house_id] = {}

                    self.data_container[this_date][this_house_id][
                        fuel_type] = row[index]

    def generate_monthly_data(self):
        print('Generating monthly data')

        this_monthly_data = OrderedDict()

        for date in self.data_container:
            this_date = datetime.date(date.year, date.month, 1)

            if this_date not in this_monthly_data:
                this_monthly_data[this_date] = {}

            for house in self.data_container[this_date].keys():

                if house not in this_monthly_data[this_date]:
                    this_monthly_data[this_date][house] = {
                        FuelType.gas: 0.0,
                        FuelType.electricity: 0.0
                    }

                if FuelType.gas in self.data_container[date][house]:
                    this_monthly_data[this_date][house][FuelType.gas] += float(
                        self.data_container[date][house][FuelType.gas])

                if FuelType.electricity in self.data_container[date][house]:
                    this_monthly_data[this_date][house][
                        FuelType.electricity] += float(
                            self.data_container[date][house][
                                FuelType.electricity])

        return this_monthly_data

    def generate_metrics(self):
        print("Metrics")

    #     When the combobox changes we should fill the scroll bar with metrics for that house

    def generate_monthly_graph_singlehouse(self, house_id=None):

        if house_id is None:
            raise ValueError("No house ID passed in, cannot generate graph.")
        elif house_id == '':
            house_id = self.house_combo.get()

        print("Generating monthly data for house with id %s" % house_id)
        self.monthly_data = self.generate_monthly_data()

        date_range = list(self.monthly_data.keys())
        (gas_values, electricity_values) = ([], [])

        for date in date_range:

            if FuelType.gas not in self.monthly_data[date][house_id] \
                    or FuelType.electricity not in self.monthly_data[date][house_id]:

                raise KeyError(
                    "Both fuel values must be present to display this graph correctly."
                )

            gas_values.append(self.monthly_data[date][house_id][FuelType.gas])
            electricity_values.append(
                self.monthly_data[date][house_id][FuelType.electricity])

        gas_trace = go.Scatter(x=date_range, y=gas_values, name='Gas')

        electricity_trace = go.Scatter(x=date_range,
                                       y=electricity_values,
                                       name='Electricity',
                                       yaxis='y2')

        layout = go.Layout(title='Monthly Both Fuels',
                           yaxis=dict(title='Gas Usage (kWh)'),
                           yaxis2=dict(
                               title='Electricity Usage (kWh)',
                               titlefont=dict(color='rgb(148, 103, 189)'),
                               tickfont=dict(color='rgb(148, 103, 189)'),
                               overlaying='y',
                               side='right'))
        fig = go.Figure(data=[gas_trace, electricity_trace], layout=layout)
        plotly.offline.plot(fig, auto_open=True)

    def generate_graph(self):
        print("Stub method for generating graphs")

    # Use this one in the submitted code, keep the agnosting one separate
    def generate_annual_graph_singlehouse(self, house_id=None):

        if house_id is None:
            raise ValueError("No house ID passed in, cannot generate graph.")
        elif house_id == '':
            house_id = self.house_combo.get()

        date_range = list(self.data_container.keys())
        (gas_values, electricity_values) = ([], [])

        for date in date_range:

            if FuelType.gas not in self.data_container[date][house_id] \
                    or FuelType.electricity not in self.data_container[date][house_id]:

                raise KeyError(
                    "Both fuel values must be present to display this graph correctly."
                )

            gas_values.append(
                self.data_container[date][house_id][FuelType.gas])
            electricity_values.append(
                self.data_container[date][house_id][FuelType.electricity])

        gas_trace = go.Scatter(x=date_range, y=gas_values, name='gas trace')

        electricity_trace = go.Scatter(x=date_range,
                                       y=electricity_values,
                                       name='electricity trace',
                                       yaxis='y2')
        graph_data = [gas_trace, electricity_trace]

        layout = go.Layout(title='Single House Both Fuels',
                           yaxis=dict(title='Usage (kWh)'),
                           yaxis2=dict(
                               title='yaxis2 title',
                               titlefont=dict(color='rgb(148, 103, 189)'),
                               tickfont=dict(color='rgb(148, 103, 189)'),
                               overlaying='y',
                               side='right'))

        fig = go.Figure(data=graph_data, layout=layout)
        plotly.offline.plot(fig, auto_open=True)

    def generate_graph_singlehouse(self, data, house_id=None):

        if house_id is None:
            raise ValueError("No house ID passed in, cannot generate graph.")
        elif house_id == '':
            house_id = self.house_combo.get()

        date_range = list(data.keys())
        (gas_values, electricity_values) = ([], [])

        for date in date_range:

            if FuelType.gas not in data[date][house_id] \
                    or FuelType.electricity not in data[date][house_id]:

                raise KeyError(
                    "Both fuel values must be present to display this graph correctly."
                )

            gas_values.append(data[date][house_id][FuelType.gas])
            electricity_values.append(
                data[date][house_id][FuelType.electricity])

        gas_trace = go.Scatter(x=date_range, y=gas_values, name='gas trace')

        electricity_trace = go.Scatter(x=date_range,
                                       y=electricity_values,
                                       name='electricity trace',
                                       yaxis='y2')
        graph_data = [gas_trace, electricity_trace]

        layout = go.Layout(title='Single House Both Fuels',
                           yaxis=dict(title='Usage (kWh)'),
                           yaxis2=dict(
                               title='yaxis2 title',
                               titlefont=dict(color='rgb(148, 103, 189)'),
                               tickfont=dict(color='rgb(148, 103, 189)'),
                               overlaying='y',
                               side='right'))

        fig = go.Figure(data=graph_data, layout=layout)
        plotly.offline.plot(fig, auto_open=True)

    def generate_graph_monthly_multiple(self, fuel_type=None):

        if fuel_type is None or fuel_type == '':
            fuel_type = FuelType(self.selected_radio.get())

        self.monthly_data = self.generate_monthly_data()

        if fuel_type is None:
            # TODO fetch the value somehow
            fuel_type = FuelType.gas

        date_range = list(self.monthly_data.keys())
        usages = OrderedDict()
        data = []

        for date in date_range:
            for house in list(self.monthly_data[date].keys()):
                if house not in usages:
                    usages[house] = []

                usages[house].append(self.monthly_data[date][house][fuel_type])

        for house in list(usages.keys()):
            data.append(go.Bar(x=date_range, y=usages[house], name=house))

        layout = go.Layout(barmode='group')

        fig = go.Figure(data=data, layout=layout)
        plotly.offline.plot(fig, auto_open=True)
Esempio n. 18
0
class Ui(object):
    def __init__(self, switcher: Switcher):
        self._switcher = switcher
        self._tk_root = Tk()
        self._tk_root.title(TITLE)
        self._tk_root.columnconfigure(1, weight=1)
        self._tk_root.rowconfigure(2, weight=1)
        self._tk_root.geometry('560x120')
        self._tk_root.protocol('WM_DELETE_WINDOW', self._on_destroy)

        # UI elements
        # |---------|-----------------|
        # | Name:   | dropdown        |
        # | Set DLL | dll path text   |
        # | Apply   | Create shortcut |

        self._text_dll_name = Label(self._tk_root, text='Name:', anchor=W)
        self._text_dll_name.grid(row=0, column=0, padx=8, sticky=W)

        self._combobox = Combobox(self._tk_root,
                                  values=tuple(self._switcher.dll_names),
                                  validate='key',
                                  validatecommand=(self._tk_root.register(
                                      self._dll_name_typed), '%P'))
        self._combobox.grid(row=0, column=1, padx=8, pady=8, sticky=W)
        self._combobox.bind('<<ComboboxSelected>>',
                            lambda _: self._dll_name_selected())
        if self._switcher.dll_names:
            self._combobox.current(0)

        self._button_set_dll = Button(self._tk_root,
                                      text='Set DLL',
                                      command=self._set_dll)
        self._button_set_dll.grid(row=1, column=0, padx=8, sticky=W)

        self._text_dll_path = Label(self._tk_root, anchor=W)
        self._text_dll_path.grid(row=1,
                                 column=1,
                                 columnspan=2,
                                 padx=8,
                                 sticky=W)

        self._button_apply = Button(self._tk_root,
                                    text='Apply',
                                    command=self._apply)
        self._button_apply.grid(row=2,
                                column=0,
                                columnspan=2,
                                padx=8,
                                pady=8,
                                sticky=W + S)

        self._button_create_shortcut = Button(self._tk_root,
                                              text='Create shortcut',
                                              command=self._create_shortcut)
        self._button_create_shortcut.grid(row=2,
                                          column=1,
                                          padx=8,
                                          pady=8,
                                          sticky=W + S)

        self._validate_ori_root()
        self._dll_name_selected()

    def _validate_ori_root(self):
        if self._switcher.assembly_csharp:
            return

        messagebox.showinfo(message='Please locate your Ori DE directory',
                            parent=self._tk_root,
                            title=TITLE)
        while True:
            ori_root = filedialog.askdirectory(
                parent=self._tk_root,
                title='Select the Ori DE directory',
                mustexist=True)
            if not ori_root:
                messagebox.showerror(message='Ori DE directory not found',
                                     parent=self._tk_root,
                                     title=TITLE)
                sys.exit(1)

            ori_root = os.path.abspath(ori_root)
            if self._switcher.get_assemblycsharp_path(ori_root):
                break

            messagebox.showerror(
                message=
                'Invalid Ori DE directory. Should be the directory that contains oriDE.exe',
                parent=self._tk_root,
                title=TITLE)

        self._switcher.ori_root = ori_root

    # new dll path was set
    def _update_dll_path(self, dll_path):
        self._text_dll_path.configure(text=dll_path or '')
        self._button_apply.configure(state=NORMAL if dll_path else DISABLED)
        self._button_create_shortcut.configure(
            state=NORMAL if dll_path else DISABLED)

    # dll name changed
    def _update_dll_name(self, dll_name):
        self._button_set_dll.configure(state=NORMAL if dll_name else DISABLED)
        dll_path = self._switcher.get_dll_path(dll_name)
        self._update_dll_path(dll_path)

    # user chose a name from the list
    def _dll_name_selected(self):
        self._update_dll_name(self._combobox.get())

    # user is typing a name (combobox validatecommand callback)
    def _dll_name_typed(self, text):
        self._update_dll_name(text)
        return True

    # user clicked on button_set_dll
    def _set_dll(self):
        dll_name = self._combobox.get()
        dll_path = filedialog.askopenfilename(
            filetypes=[('DLL', '*.dll')],
            initialdir=self._switcher.ori_root,
            parent=self._tk_root,
            title=f'Choose your "{dll_name}" DLL file')
        if not dll_path:
            return
        dll_path = os.path.abspath(dll_path)
        if dll_path == self._switcher.assembly_csharp:
            messagebox.showerror(
                message=
                "You cannot choose the game's original DLL path.\nIf this is your mod DLL, please rename it or copy it elsewhere.",
                title=TITLE)
            return

        self._switcher.set_dll_path(dll_name, dll_path)
        self._update_dll_path(dll_path)
        self._combobox.configure(values=tuple(self._switcher.dll_names))

    # user clicked on button_apply
    def _apply(self):
        try:
            dll_name = self._combobox.get()
            self._switcher.switch(dll_name)
            messagebox.showinfo(message=f'Switched to {dll_name} DLL',
                                parent=self._tk_root,
                                title=TITLE)
            self._on_destroy()
        except SwitcherException as e:
            # Should never happen
            messagebox.showerror(message=e, title=TITLE)

    # user clicked on button_create_shortcut
    def _create_shortcut(self):
        dll_name = self._combobox.get()
        shortcut_name = f'SwitchTo{dll_name.capitalize()}.lnk'
        win_cmd_path = r'C:\Windows\System32\cmd.exe'
        program_dir, program_filename = os.path.split(
            os.path.abspath(sys.argv[0]))

        if program_filename.endswith('.py'):
            program_filename = 'py ' + program_filename
        elif not program_filename.endswith('.exe'):
            messagebox.showerror(message='Cannot create shortcut',
                                 parent=self._tk_root,
                                 title=TITLE)
            return
        args = f'/c {program_filename} {dll_name}'

        shortcut_dir = filedialog.askdirectory(parent=self._tk_root,
                                               title='Choose location',
                                               mustexist=True)
        if not shortcut_dir:
            return
        shortcut_dir = os.path.abspath(shortcut_dir)

        shortcut = Dispatch('WScript.Shell').CreateShortCut(
            os.path.join(shortcut_dir, shortcut_name))
        shortcut.Targetpath = win_cmd_path
        shortcut.Arguments = args
        shortcut.WorkingDirectory = program_dir
        shortcut.save()
        messagebox.showinfo(message=f'Shortcut {shortcut_name[:-4]} created',
                            parent=self._tk_root,
                            title=TITLE)

    def _on_destroy(self):
        self._switcher.save_data_json()
        self._tk_root.destroy()

    def mainloop(self):
        self._tk_root.mainloop()
Esempio n. 19
0
class WidgetTable(Frame):
    """
    A frame which contains rows which can be populate with multiple
    widgets in each column.
    We can have a button to remove rows, and a few different ways to add new
    rows.

    Parameters
    ----------
    headings : list(str)
        A list of strings for the headings.
        If the value is specified as `None` then no header row will be drawn.
    pattern : list(instance of Variable)
        A list of Variables to be associated with the widget.
        These variables need to be the appropriate type for the
        entry_type associated with the data, as well as the data passed in
        (if the table is to be initially or automatically populated).
        The Variable information can be passed in as a dicitonary to allow
        very specific modification of how the data works.
        The dictionary has the following keys:
        - var: An instantiated Variable object
        - text: A string (used as the text on buttons, or default text
            for an entry/label)
        - configs: A dictionary of the configuration to be applied to the
            widget.
        - func: The function used as a callback for buttons, checkbuttons
            etc.
        - func_has_row_ctx: (bool) whether or not the function specified by
            func is given the current line as an argument.
    widgets_pattern : list of Widget instances
        A list of Widgets that will be drawn in each
        column.
        These widgets *must* be un-instantiated to allow cloning when
        creating new rows.
    add_options : list, optional
        A fixed length list of options that can be added.
        If None then the rows can just be added arbitrarily using button.
    data_array : list, optional
        A list of the intial data to populate the table with.
        This can either be raw data or an array of the variables
    adder_script : function, optional
        A function that will be called when the Add button is
        pressed or a value is picked from the add_options option box.
        If this function returns an values they are assumed to be the
        values to be passed into the newly created widgets if possible.
        To remove the functionality to add new rows set this to
        tkinter.DISABLED.
    remove_script : function, optional
        A callback for when a row is deleted.
        This function can be used to block deletion. This is acheived by having
        this function return anything. If nothing is returned then the deletion
        occurs as expected.
        To remove the functionality to remove rows set this to
        tkinter.DISABLED.
    sort_column : int, optional
        The column number that the data will automatically be sorted by.
    max_rows : int, optional
        The maximum number of rows to display before forcing the
        ScrollableFrame to have a scroller.
    style : dict, optional
        A dictionary containing a number of style parameters.
        Possible parameters are:
        nodivders : bool
            Whether or not to draw the dividers.

    """
    def __init__(self,
                 master,
                 headings=[],
                 pattern=[],
                 widgets_pattern=[],
                 add_options=None,
                 data_array=[],
                 adder_script=None,
                 remove_script=None,
                 sort_column=None,
                 max_rows=None,
                 style=dict(),
                 *args,
                 **kwargs):
        self.master = master

        # s = Style(self.master)
        # s.configure('proper.TEntry', background='green')

        super(WidgetTable, self).__init__(self.master, *args, **kwargs)

        self.rows = []
        self.headings = headings
        self.pattern = pattern
        self.widgets_pattern = widgets_pattern
        self.num_columns = len(self.widgets_pattern)
        self.add_options = add_options
        self.adder_script = adder_script
        self.remove_script = remove_script
        self.sort_column = sort_column
        self.max_rows = max_rows
        self.style = style

        self.entry_config = {
            'readonlybackground': OSCONST.TEXT_RONLY_BG,
            'highlightbackground': OSCONST.CANVAS_BG
        }

        # the index we need to redraw the rows after
        self.first_redraw_row = 0

        self.row_offset = 0
        self.separator_offset = 0

        self.widgets = []
        self.add_button = None
        self._create_widgets()

        self.separators = []
        if not self.style.get('nodividers', False):
            for _ in range(self.num_columns - 1):
                sep = Separator(self.sf.frame, orient='vertical')
                self.separators.append(sep)

        self.delete_icon = Image.open(OSCONST.ICON_REMOVE)
        self.delete_icon = self.delete_icon.resize((20, 20), Image.LANCZOS)
        self.delete_icon = ImageTk.PhotoImage(self.delete_icon)

        # storage variables
        if data_array != []:
            # ensure a 2D array
            if not isinstance(data_array[0], list):
                data_array = [data_array]
            self.data = []
            self.set(data_array)
        else:
            # empty table
            self.data = []
            self._draw_separators()

        self.bind(OSCONST.ADDROW, self._add_row_from_key)

        self.sf.configure_view(needs_update=True)

#region public methods

    def add_row_data(self, idx, data=None):
        """
        Add the provided row data at the required index

        Paramaters
        ----------
        idx : int
            Index the data is the be added at.
        data : list
            This is a list of either the values the variables will take or the
            data itself.
            Any entry can be None which indicates the default un-initiated data
            should be used.

        """
        # TODO: fix the optimisation so that this is not 0 any more...
        self.first_redraw_row = 0  # len(self.data) - 1
        self._assign_row_data(idx, data)

    def add_row_widgets(self, count=1):
        """ Add one or more sets of row widgets to the end of the table
        The widgets are added from the WidgetTable's widget_pattern property.

        Parameters
        ----------
        count : int
            The number of rows of widgets to add.
            Defaults to 1

        """
        # remove the add button if it exists
        if count != 0:
            if self.add_button is not None:
                self.add_button.grid_forget()

            initial_rows = len(self.widgets)

        for r in range(count):
            row_widgets = []

            rows = self.sf.frame.grid_size()[1]
            # draw each of the new widgets in the last row
            for i, w in enumerate(self.widgets_pattern):
                w_actual = w(self.sf.frame)
                w_actual.bind(OSCONST.ADDROW, self._add_row_from_key)
                w_actual.grid(row=rows,
                              column=2 * i,
                              sticky='nsew',
                              padx=2,
                              pady=2)
                row_widgets.append(w_actual)

            # add the delete button at the end of the row
            if self.remove_script != DISABLED:
                curr_row = initial_rows + r
                delete_button = tkButton(
                    self.sf.frame,
                    command=lambda x=curr_row: self.delete_rows_and_update(x),
                    relief='flat',
                    borderwidth=0,
                    highlightthickness=0,
                    takefocus=0)
                delete_button.config(image=self.delete_icon)
                delete_button.grid(row=rows, column=2 * self.num_columns - 1)
                row_widgets.append(delete_button)
            self.widgets.append(row_widgets)

            # set the focus on the first of the widgets in the bottom row
            # TODO: this will probably need a bit more complexity added to it??
            self.widgets[-1][0].focus_set()

        if count != 0:
            # finally, fix up separators and add button if needed
            self._draw_separators()
            if self.add_button is not None:
                self.add_button.grid(row=rows + 1,
                                     column=2 * self.num_columns - 1)

    def add_rows(self, data=None, count=1, from_start=False):
        """
        Add a new row to the end of the current data and redraw all the
        current data from the new data onward.
        We can add multiple rows at a time to save drawing, undrawing then
        drawing the add button again and again.

        Parameters
        data : list | None
            Data to be automatically added to the new row(s)
        count : int
            Number of new rows to add.
            Defaults to 1.
        from_start : bool
            Whether to assign row data from the start of not.
            This should always be False unless count == 0.
        """
        refresh = False

        # if from_start == True then the data will be placed from row 0
        curr_rows = (1 - from_start) * len(self.data)
        # if there is no size difference we simply want to refresh the data
        if count == 0:
            refresh = True
            count = len(data)
        if data is not None and data != []:
            data = self.ensure_2D_array(data)
            for i in range(count):
                self.add_row_data(curr_rows + i, data[i])
        else:
            for i in range(count):
                self.add_row_data(curr_rows + i)

        if not refresh:
            self.add_row_widgets(count)

        # now sort the data if needed.
        # we only want to sort if data is provided, otherwise we can have weird
        # effects like the new data being inserted at the start.
        if data is not None:
            self.sort_data()

        self._correct_idx_refs()

        # apply the data appropriately
        self._apply_data()

    def add_row_from_button(self):
        """ Add a row from the 'Add Row' button """
        # before anything happens call the adder script if there is one to
        # determine whether there is any data that can populate the new row.
        if self.adder_script is not None:
            try:
                ret = self.adder_script()
                if ret is None:
                    self.add_rows()
                else:
                    self.add_rows(ret)
            except TypeError:
                # in this case the wrong number of arguments have been passed
                # (potentially. Print a message and pass)
                print(("The adder function used wasn't called because "
                       "it had the wrong number of arguments"))
            except ValueError:
                # In this case the function may have broken.
                # This indicates we do not want to add the row
                pass
        else:
            self.add_rows()

        self._resize_to_max(resize_canvas='xy', move_to_bottom=True)

    def add_row_from_selection(self, event):
        """ Add a new row from the list of possible rows to add """
        # this only needs to be different to implement the functionality to
        # allow the entry in the list to be removed if it needs to be
        # unless we leave that functionality up to the user...
        if self.adder_script is not None:
            ret = self.adder_script()
            if ret is None:
                self.add_rows()
            else:
                self.add_rows(ret)
        self._resize_to_max(resize_canvas='x')

    def delete_row(self, idx, ignore_script=False):
        """ Remove the row widgets and data

        Parameters
        ----------
        idx : int
            Row index to delete.
        ignore_script : bool
            Whether or not to ignore the call to the removal script.
            Defaults to False (runs removal script by default if there is one)

        """
        remove_rtn = None
        if self.remove_script is not None and not ignore_script:
            remove_rtn = self.remove_script(idx)
        if remove_rtn is None:
            for w in self.widgets[-1]:
                w.grid_forget()
            del self.widgets[-1]
            del self.data[idx]

    def delete_rows_and_update(self, idx, count=1, ignore_script=False):
        """ Remove one or more row widgets and update the table

        Parameters
        ----------
        idx : int
            Row index to delete.
        count : int
            Number of rows to delete. Defaults to 1.
        ignore_script : bool
            Whether or not to ignore the call to the removal script.
            Defaults to False (runs removal script by default if there is one).

        """
        # remove up to the maximum number of rows
        for _ in range(min(len(self.widgets), count)):
            self.delete_row(idx, ignore_script)
        if self.remove_script != DISABLED:
            # remap the delete command for the buttons
            for i in range(len(self.widgets)):
                del_btn = self.widgets[i][-1]
                del_btn.config(
                    command=lambda x=i: self.delete_rows_and_update(x))
        # now, reapply all the variables
        self.first_redraw_row = 0
        self._correct_idx_refs()
        self._apply_data()
        self._resize_to_max(resize_canvas='xy')

    def get(self, values=True):
        """
        Return a 2D array of all the data contained.

        Parameters
        ----------
        values : bool
            If values == True, the value of the Variables will be
        returned. If False the Variables themselves will be returned
        """
        out_data = []
        for row in self.data:
            row_data = []
            if values:
                for var in row:
                    if not isinstance(var, dict):
                        row_data.append(var.get())
                    else:
                        if 'var' in var:
                            row_data.append(var['var'].get())
                        elif 'text' in var:
                            row_data.append(var['text'])
            else:
                # simply return the actual row data
                row_data.append(row)
            out_data.append(row_data)
        return out_data

    def set(self, data=[]):
        """
        Force the table to be updated with new data
        """
        diff = len(data) - len(self.data)
        if diff < 0:
            # assign the row data
            for i in range(len(data)):
                self.add_row_data(i, data[i])
            # remove all unneccesary rows
            self.delete_rows_and_update(-1, abs(diff), ignore_script=True)
        elif diff > 0:
            # assign the data up to the number of existing widgets
            for i in range(len(data) - diff):
                self.add_row_data(i, data[i])
            self.add_rows(data[-diff:], diff)
        elif diff == 0:
            self.add_rows(data, diff, from_start=True)

        self._resize_to_max()

    def set_row(self, idx, data):
        """
        Set the data for a specific row

        Parameters
        ----------
        idx : int
            Index of the row the data will be set in.
        data : list
            Row data to be assigned. This should be a list of raw values, not
            a list of instances of Variables.
        """
        for i, val in enumerate(data):
            if val is not None:
                self.data[idx][i].set(val)

    def sort_data(self):
        """ If a sort column is specified on intialisation of the WidgetTable
        then sort by this column."""
        if isinstance(self.sort_column, int):
            if self.sort_column < self.num_columns:
                self.data.sort(key=lambda x: x[self.sort_column].get())

#region private methods

    def _add_row_from_key(self, *args):
        """ Add a new row when the new row keyboard shortcut is pressed

        This will only be possible when we don't have a fixed list of
        possibilites to add.

        """
        if not isinstance(self.add_options, list):
            self.add_row_from_button()

    def _apply_data(self):
        """
        Apply all the data in self.data to the widget array.
        The widgets are traversed column by column so that we can create an
        apply function specifically for that widget type.
        """
        # do columns then rows to save having to check data types repeatedly
        for column in range(self.num_columns):
            # first, create a lambda which can be re-used for each row
            w = self.widgets_pattern[column]
            try:
                if callable(w):
                    # in this case the widget is actually one wrapped in a
                    # lambda statement.
                    # extract it by checking the type
                    w = type(w(self))
                if issubclass(w, Label):
                    if isinstance(self.pattern[column], dict):
                        # apply any provided configs:
                        if self.pattern[column].get('var') is not None:
                            apply = lambda wgt, var: wgt.configure(
                                textvariable=var['var'],
                                **var.get('configs', dict()))  # noqa: E731
                        elif self.pattern[column].get('text') is not None:
                            apply = lambda wgt, var: wgt.configure(
                                text=var['text'], **var.get('configs', dict()
                                                            ))  # noqa: E731
                    else:
                        apply = lambda wgt, var: wgt.configure(  # noqa: E731
                            textvariable=var)
                elif issubclass(w, tkEntry):
                    # combobox is a subclass of the ttk.Entry object
                    if issubclass(w, Combobox):
                        # we will be assuming that the underlying data type is
                        # an OptionsVar to provide simplest functionality
                        if isinstance(self.pattern[column], dict):

                            def apply(wgt, var):
                                configs = var.get('configs', dict())
                                var = var['var']
                                wgt.configure(values=var.options, **configs)
                                wgt.set(var.get())
                                # set the selection binding
                                select_value = lambda e, w=wgt: var.set(
                                    wgt.get())  # noqa: E731
                                wgt.bind("<<ComboboxSelected>>", select_value)
                        else:

                            def apply(wgt, var):
                                wgt.configure(values=var.options)
                                wgt.set(var.get())
                                # set the selection binding
                                select_value = lambda e, w=wgt: var.set(
                                    wgt.get())  # noqa: E731
                                wgt.bind("<<ComboboxSelected>>", select_value)
                    elif issubclass(w, Entry):
                        if isinstance(self.pattern[column], dict):
                            # apply any provided configs:
                            apply = lambda wgt, var: wgt.configure(
                                textvariable=var['var'],
                                **var.get('configs', dict()))  # noqa: E731
                        else:
                            apply = lambda wgt, var: wgt.configure(
                                textvariable=var)  # noqa: E731
                    else:
                        if isinstance(self.pattern[column], dict):
                            # apply any provided configs:
                            apply = lambda wgt, var: wgt.configure(
                                textvariable=var['var'],
                                **self.entry_config,
                                **var.get('configs', dict()))  # noqa: E731
                        else:
                            apply = lambda wgt, var: wgt.configure(
                                textvariable=var, **self.entry_config
                            )  # noqa: E731
                elif issubclass(w, Checkbutton):
                    # check underlying data type to provide correct function
                    if isinstance(self.pattern[column], dict):
                        apply = lambda wgt, var: wgt.configure(  # noqa: E731
                            variable=var['var'],
                            command=var.get('func', None),
                            **var.get('configs', dict()))
                    else:
                        apply = lambda wgt, var: wgt.configure(
                            variable=var)  # noqa: E731,E501
                elif issubclass(w, Button):
                    apply = lambda wgt, var: wgt.configure(
                        text=var['text'],  # noqa: E731,E501
                        command=var['func'])
                else:
                    raise TypeError
            except TypeError:
                print('unsupported Widget Type??')
                print(w, w.__name__)
                raise
            # now, on each row apply the data
            for row in range(self.first_redraw_row, len(self.widgets)):
                apply(self.widgets[row][column], self.data[row][column])

    def _assign_row_data(self, idx, data=None):
        """
        Assign the data provided to the WidgetTable's data array's Variables.

        Parameters
        ----------
        idx : int
            Index to place the new data in the data array
        data : list | None
            Data to assign. This data is processed to ensure that it is in the
            right format for being assigned to the underlying Variables.
            This can consist of either the raw values for each widget, an
            instance of a Variable, or a dictionary with parameters as
            described by the docstring of the widget table.
            (see help(WidgetTable) for more info)
        """
        row_vars = []
        # iterate over the columns
        for i in range(len(self.pattern)):
            if data is not None:
                val = data[i]
            else:
                val = None
            if val is not None:
                if isinstance(self.pattern[i], dict):
                    # create a copy of the pattern for the current column data
                    new_dict = copy_dict(self.pattern[i])
                    # then populate the new dict with any provided data
                    if isinstance(val, Variable):
                        # in this case we are just receiving the Variable
                        # and don't want to modify the rest of the dictionary
                        if hasattr(val, 'copy'):
                            new_dict['var'] = val.copy()
                        else:
                            new_dict['var'] = val
                        p = self.pattern[i]
                        if p.get('func_has_row_ctx', False):
                            f = copy(p['func'])
                            new_dict['func'] = lambda x=idx: f(x)
                    else:
                        # otherwise we have been passed a (at least partial)
                        # dictionary of data
                        if 'var' in val:
                            var = val['var']
                            if isinstance(var, Variable):
                                if hasattr(var, 'copy'):
                                    new_dict['var'] = var.copy()
                                else:
                                    new_dict['var'] = var
                            else:
                                new_dict['var'].set(var)
                        if 'text' in val:
                            new_dict['text'] = val['text']
                        if 'func' in val:
                            if val.get('func_has_row_ctx', False):
                                # if the function requires knowledge of the row
                                # it is then we give it to it.
                                new_dict['func'] = lambda x=idx: val['func'](x)
                            else:
                                new_dict['func'] = val['func']
                        if 'configs' in val:
                            new_dict['configs'] = val['configs']
                    var = new_dict
                else:
                    if isinstance(val, Variable):
                        if hasattr(val, 'copy'):
                            var = val.copy()
                        else:
                            var = val
                    else:
                        var = self.pattern[i]()
                        var.set(val)
            else:
                if not isinstance(self.pattern[i], dict):
                    try:
                        issubclass(self.pattern[i], Variable)
                        var = self.pattern[i]()
                    except TypeError:
                        if hasattr(self.pattern[i], 'copy'):
                            var = self.pattern[i].copy()
                        else:
                            var = self.pattern[i]
                else:
                    # we still need to check if the function requires row
                    # context
                    var = dict()
                    for key in self.pattern[i].keys():
                        if key != 'func':
                            if key == 'var':
                                if hasattr(self.pattern[i][key], 'copy'):
                                    var[key] = self.pattern[i][key].copy()
                                else:
                                    var[key] = self.pattern[i][key]
                            else:
                                var[key] = self.pattern[i][key]
                    if var.get('func_has_row_ctx', False):
                        var['func'] = lambda x=idx: self.pattern[i]['func'](x)
            row_vars.append(var)
        if idx < len(self.data):
            self.data[idx] = row_vars
        else:
            self.data.append(row_vars)

    def _assign_data(self, data):
        """
        This is used to assign raw data to the underlying variables
        """
        # clear self.data
        self.data = []
        for i, row in enumerate(data):
            self._assign_row_data(i, row)

    def _correct_idx_refs(self):
        """ Correct any reference to index in any function in the data array"""
        for i, row in enumerate(self.data):
            for val in row:
                if isinstance(val, dict):
                    if val.get('func_has_row_ctx', False):
                        f = copy(val['func'])
                        del val['func']
                        val['func'] = lambda x=i: f(x)

    def _create_widgets(self):
        """ Create all the base widgets required """
        if isinstance(self.add_options, list):
            add_option_frame = Frame(self)
            Label(add_option_frame, text="Add an option: ").grid(column=0,
                                                                 row=0,
                                                                 sticky='w')
            self.nameselection = Combobox(add_option_frame,
                                          values=self.add_options,
                                          state='readonly',
                                          exportselection=0)
            self.nameselection.grid(column=2, row=0, sticky='w')
            self.nameselection.bind("<<ComboboxSelected>>",
                                    self.add_row_from_selection)
            self.separator_offset = 1
            add_option_frame.grid(column=0, row=0, sticky='w', padx=2, pady=2)
            self.sf = ScrollableFrame(self)
            self.sf.grid(column=0, row=1, sticky='nsew')

            self.grid_rowconfigure(0, weight=0)
            self.grid_rowconfigure(1, weight=1)
            self.grid_columnconfigure(0, weight=1)
        else:
            self.sf = ScrollableFrame(self)
            self.sf.grid(column=0, row=0, sticky='nsew')
            if self.adder_script != DISABLED:
                self.add_button = Button(self.sf.frame,
                                         text="Add Row",
                                         command=self.add_row_from_button)
                self.add_button.grid(row=2, column=2 * self.num_columns - 1)
                self.add_button.bind(OSCONST.ADDROW, self._add_row_from_key)

            self.grid_rowconfigure(0, weight=1)
            self.grid_columnconfigure(0, weight=1)
        if self.headings is not None:
            for i, heading in enumerate(self.headings):
                Label(self.sf.frame,
                      text=heading).grid(column=2 * i,
                                         row=self.separator_offset,
                                         sticky='nsew',
                                         padx=2,
                                         pady=2)
            Separator(self.sf.frame, orient='horizontal').grid(
                column=0,
                row=self.separator_offset + 1,
                columnspan=2 * self.num_columns - 1,
                sticky='ew')

        self.row_offset = self.sf.frame.grid_size()[1]

    def _draw_separators(self):
        """ Redraw all the separators when the table is being redrawn """
        if self.style.get('nodividers', False):
            return
        rows = self.sf.frame.grid_size()[1]
        for i, sep in enumerate(self.separators):
            sep.grid_forget()
            sep.grid(column=2 * i + 1,
                     row=self.separator_offset,
                     rowspan=rows - self.separator_offset,
                     sticky='ns')

    def _resize_to_max(self, **config):
        """ Resize the ScrollCanvas up to the maximum allowed size if a max
        number of rows is specified.
        """
        max_x, max_y = (None, None)
        self.sf.update_idletasks()

        if self.max_rows is not None:
            if len(self.data) > self.max_rows:
                max_x, max_y = self.sf.frame.grid_bbox(
                    column=0,
                    row=self.sf.frame.grid_size()[1] - 2 - self.max_rows,
                    col2=self.sf.frame.grid_size()[0] - 1,
                    row2=self.sf.frame.grid_size()[1] - 1)[2:]

        self.sf.block_resize = False
        self.sf.configure_view(max_size=(max_x, max_y),
                               needs_update=True,
                               **config)

#region properties

    @property
    def options(self):
        return self.add_options

    @options.setter
    def options(self, value):
        if len(value) > 0:
            self.nameselection.configure(values=value)
            self.nameselection.set(value[0])

#region class methods

#TODO: move to utils?

    @staticmethod
    def ensure_2D_array(arr):
        """ If the provided array is not 2D convert it to one """
        if isinstance(arr, list):
            if not isinstance(arr[0], list):
                return [arr]
            else:
                return arr
        else:
            raise ValueError("Provided data is not an array")
Esempio n. 20
0
class TeamWindow:
    def __init__(self, parent, teams):
        self.window = Toplevel(parent.window)
        self.window.withdraw()
        self.parent = parent
        self.teams = deepcopy(teams)
        self.teamFrame = Frame(self.window)
        self.streamFrame = Frame(self.window)
        self.buttonFrame = Frame(self.window)

        self.isRename = False
        self.tempName = None
        self.currentTeam = None
        self.teamsExist = False
        self.pageLoaded = False

        self.comboboxTeam = None
        self.freeAgentListbox = None
        self.teamMemberListbox = None

        self.selectedFreeAgents = None
        self.selectedTeamMembers = None

        self.buttonLeftArrow = None
        self.buttonUpArrow = None
        self.buttonDownArrow = None
        self.buttonRightArrow = None
        self.buttonRename = None

        WindowHelper.initializeWindow(self.window, self.parent, 380, 282, 30, 50, LabelConstants.TEAM_WINDOW)
        self.gridFrames()
        self.addDropdown()
        self.addFreeAgentListbox()
        self.addListboxButtons()
        self.addTeamMemberListbox()
        self.addButtons()
        if self.teamsExist:
            self.switchActiveTeam()
        self.pageLoaded = True
        WindowHelper.finalizeWindow(self.window, self.parent)

    def gridFrames(self):
        self.buttonFrame.grid_columnconfigure(0, weight=1)
        self.buttonFrame.grid_columnconfigure(1, weight=1)
        self.buttonFrame.grid_columnconfigure(2, weight=1)
        self.buttonFrame.grid_columnconfigure(3, weight=1)
        self.teamFrame.grid(row=0, sticky=NSEW, padx=4, pady=4)
        self.streamFrame.grid(row=1, sticky=NSEW, padx=4, pady=4)
        self.buttonFrame.grid(row=2, sticky=NSEW, padx=4, pady=4)

    def addDropdown(self):
        teams = self.getListOfTeams()
        labelTeam = Label(self.teamFrame, text=LabelConstants.TEAMS_DROPDOWN)
        labelTeam.grid(row=0, column=0, sticky=NSEW, padx=4, pady=4)
        self.comboboxTeam = Combobox(self.teamFrame, values=teams, state="readonly")
        self.comboboxTeam.bind("<<ComboboxSelected>>", self.switchActiveTeam)
        if teams:
            self.teamsExist = True
            self.comboboxTeam.current(0)
            self.currentTeam = self.comboboxTeam.get()
        self.comboboxTeam.grid(row=0, column=1, padx=4, pady=4)
        buttonNewTeam = Button(self.teamFrame, text=LabelConstants.CREATE_NEW_TEAM, width=16, command=self.createNewTeam)
        buttonNewTeam.grid(row=0, column=2, sticky=NSEW, padx=(40, 4), pady=4)

    def addFreeAgentListbox(self):
        frameFreeAgentListBox = Frame(self.streamFrame)
        frameFreeAgentListBox.grid(row=0, column=0, sticky=NSEW, padx=4, pady=(0, 4))
        labelFreeAgentListBox = Label(frameFreeAgentListBox, text=LabelConstants.FREE_AGENTS)
        labelFreeAgentListBox.grid(row=0, column=0, padx=4, sticky=W)
        scrollbar = Scrollbar(frameFreeAgentListBox)
        scrollbar.grid(row=1, column=1, sticky="NWS")
        self.freeAgentListbox = Listbox(frameFreeAgentListBox, selectmode=MULTIPLE, yscrollcommand=scrollbar.set, activestyle=NONE)
        scrollbar.config(command=self.freeAgentListbox.yview)
        self.freeAgentListbox.bind('<<ListboxSelect>>', self.onSelectFreeAgentListbox)
        self.freeAgentListbox.grid(row=1, column=0, sticky=NSEW, padx=(4, 0))

    def addListboxButtons(self):
        frameListBoxButtons = Frame(self.streamFrame)
        frameListBoxButtons.grid(row=0, column=1, sticky=NSEW, pady=(0, 4))
        self.buttonLeftArrow = Button(frameListBoxButtons, text=LabelConstants.LEFT, width=7, command=lambda: self.moveLeft(), state=DISABLED)
        self.buttonLeftArrow.grid(row=0, sticky=NSEW, padx=4, pady=(38, 4))
        self.buttonUpArrow = Button(frameListBoxButtons, text=LabelConstants.UP, width=7, command=lambda: self.moveUp(), state=DISABLED)
        self.buttonUpArrow.grid(row=1, sticky=NSEW, padx=4, pady=4)
        self.buttonDownArrow = Button(frameListBoxButtons, text=LabelConstants.DOWN, width=7, command=lambda: self.moveDown(), state=DISABLED)
        self.buttonDownArrow.grid(row=2, sticky=NSEW, padx=4, pady=4)
        self.buttonRightArrow = Button(frameListBoxButtons, text=LabelConstants.RIGHT, width=7, command=lambda: self.moveRight(), state=DISABLED)
        self.buttonRightArrow.grid(row=3, sticky=NSEW, padx=4, pady=4)

    def addTeamMemberListbox(self):
        frameTeamMemberListbox = Frame(self.streamFrame)
        frameTeamMemberListbox.grid(row=0, column=2, sticky=NSEW, pady=(0, 4))
        labelLiveListBox = Label(frameTeamMemberListbox, text=LabelConstants.TEAM_MEMBERS)
        labelLiveListBox.grid(row=0, column=0, padx=4, sticky=W)
        scrollbar = Scrollbar(frameTeamMemberListbox)
        scrollbar.grid(row=1, column=1, sticky="NWS")
        self.teamMemberListbox = Listbox(frameTeamMemberListbox, selectmode=SINGLE, yscrollcommand=scrollbar.set, activestyle=NONE)
        scrollbar.config(command=self.teamMemberListbox.yview)
        self.teamMemberListbox.bind('<<ListboxSelect>>', self.onSelectTeamMemberListbox)
        self.teamMemberListbox.grid(row=1, column=0, sticky=NSEW, padx=(4, 0))

    def addButtons(self):
        # TODO: These don't need to be defined as self.
        self.buttonRename = Button(self.buttonFrame, text=LabelConstants.RENAME, width=8, command=lambda: self.rename())
        self.buttonRename.grid(row=0, column=0, sticky=NSEW, padx=(8, 4), pady=4)
        buttonDelete = Button(self.buttonFrame, text=LabelConstants.DELETE, width=8, command=lambda: self.delete())
        buttonDelete.grid(row=0, column=1, sticky=NSEW, padx=4, pady=4)
        buttonSave = Button(self.buttonFrame, text=LabelConstants.OK, width=8, command=lambda: self.ok())
        buttonSave.grid(row=0, column=2, sticky=NSEW, padx=4, pady=4)
        buttonCancel = Button(self.buttonFrame, text=LabelConstants.CANCEL, width=8, command=lambda: self.window.destroy())
        buttonCancel.grid(row=0, column=3, sticky=NSEW, padx=4, pady=4)

    def moveLeft(self):
        if self.selectedTeamMembers:
            for stream in self.selectedTeamMembers:
                self.freeAgentListbox.insert(END, self.teamMemberListbox.get(stream))
            for stream in reversed(self.selectedTeamMembers):
                self.teamMemberListbox.delete(stream)
            self.teamMemberListbox.selection_clear(0, END)
            self.selectedTeamMembers = None
            self.buttonLeftArrow.configure(state=DISABLED)

    def moveUp(self):
        index = self.teamMemberListbox.curselection()
        if self.selectedTeamMembers and len(self.selectedTeamMembers) == 1 and index is not None and index[0] != 0:
            stream = self.teamMemberListbox.get(index[0])
            self.teamMemberListbox.delete(index[0])
            self.teamMemberListbox.insert(index[0] - 1, stream)
            self.teamMemberListbox.selection_set(index[0] - 1)

    def moveDown(self):
        index = self.teamMemberListbox.curselection()
        if self.selectedTeamMembers and len(self.selectedTeamMembers) == 1 and index is not None and index[0] != self.teamMemberListbox.size() - 1:
            stream = self.teamMemberListbox.get(index[0])
            self.teamMemberListbox.delete(index[0])
            self.teamMemberListbox.insert(index[0] + 1, stream)
            self.teamMemberListbox.selection_set(index[0] + 1)

    def moveRight(self):
        if self.selectedFreeAgents:
            for stream in self.selectedFreeAgents:
                self.teamMemberListbox.insert(END, self.freeAgentListbox.get(stream))
            for stream in reversed(self.selectedFreeAgents):
                self.freeAgentListbox.delete(stream)
            self.freeAgentListbox.selection_clear(0, END)
            self.selectedFreeAgents = None
            self.buttonRightArrow.configure(state=DISABLED)

    def switchActiveTeam(self, event=None):
        if self.pageLoaded and self.currentTeam is not None and len(self.currentTeam) > 0:
            self.storeCurrentTeamChanges(self.currentTeam)
        teamMembers = self.teams[self.comboboxTeam.get()]
        freeAgents = sorted([x for x in self.teams[LabelConstants.ALL_TEAM] if x not in teamMembers], key=str.casefold)
        self.clearListboxes()
        for streamer in freeAgents:
            self.freeAgentListbox.insert(END, streamer)
        for streamer in teamMembers:
            self.teamMemberListbox.insert(END, streamer)
        self.currentTeam = self.comboboxTeam.get()

    def clearListboxes(self):
        self.freeAgentListbox.selection_clear(0, END)
        self.teamMemberListbox.selection_clear(0, END)
        self.freeAgentListbox.delete(0, END)
        self.teamMemberListbox.delete(0, END)

    def onSelectFreeAgentListbox(self, event):
        w = event.widget
        self.selectedFreeAgents = w.curselection()
        self.buttonRightArrow.configure(state=NORMAL)
        self.buttonLeftArrow.configure(state=DISABLED)
        self.buttonUpArrow.configure(state=DISABLED)
        self.buttonDownArrow.configure(state=DISABLED)

    def onSelectTeamMemberListbox(self, event):
        w = event.widget
        self.selectedTeamMembers = w.curselection()
        self.buttonRightArrow.configure(state=DISABLED)
        self.buttonLeftArrow.configure(state=NORMAL)
        if len(self.selectedTeamMembers) > 1:
            self.buttonUpArrow.configure(state=DISABLED)
            self.buttonDownArrow.configure(state=DISABLED)
        else:
            self.buttonUpArrow.configure(state=NORMAL)
            self.buttonDownArrow.configure(state=NORMAL)

    def getListOfTeams(self) -> List[str]:
        return list(key for key in self.teams.keys() if key != LabelConstants.ALL_TEAM and key != LabelConstants.TOP_TWITCH_TEAM)

    def rename(self):
        if self.comboboxTeam.current() >= 0:
            self.isRename = True
            TeamNameWindow(self)

    def storeCurrentTeamChanges(self, key):
        self.teams[key] = list(self.teamMemberListbox.get(0, END))

    def ok(self):
        if self.comboboxTeam.get() != "":
            self.storeCurrentTeamChanges(self.comboboxTeam.get())
        self.parent.setTeams(self.teams)
        self.window.destroy()

    def delete(self):
        self.teams.pop(self.comboboxTeam.get())
        self.comboboxTeam.set("")
        self.comboboxTeam.selection_clear()
        self.clearListboxes()
        self.comboboxTeam.configure(values=self.getListOfTeams())
        self.currentTeam = None

    def createNewTeam(self):
        self.isRename = False
        TeamNameWindow(self)
class _get_value_w_units(_Dialog):
    def body(self, master):
        dialogframe = Frame(master, width=466, height=221)
        self.dialogframe = dialogframe
        dialogframe.pack()

        self.make_Button_1(
            self.dialogframe
        )  #      Button: Set XXX to None (not used) : at Main(3,1)
        self.make_Combobox_1(
            self.dialogframe)  #    Combobox: Mine Yours Ours : at Main(5,3)
        self.make_Entry_1(self.dialogframe)  #       Entry:  at Main(5,2)
        self.make_Label_1(
            self.dialogframe)  #       Label: Input XXX Value : at Main(1,1)
        self.make_Label_2(
            self.dialogframe)  #       Label: definition : at Main(2,1)
        self.make_Label_3(
            self.dialogframe)  #       Label: Value : at Main(4,2)
        self.make_Label_4(
            self.dialogframe)  #       Label: Units : at Main(4,3)
        self.make_Label_5(self.dialogframe)  #       Label: XXX= : at Main(5,1)
        self.make_Label_6(self.dialogframe)  #       Label:  at Main(5,0)
        self.make_Label_7(self.dialogframe)  #       Label:  at Main(5,4)

        self.dialogframe.columnconfigure(4, weight=1)
        self.dialogframe.columnconfigure(0, weight=1)

        # >>>>>>insert any user code below this comment for section "top_of_init"

        self.set_value_to_none = False
        if not self.dialogOptions.get('show_none_btn', False):
            self.Button_1.grid_remove()

        self.Entry_1.focus_set()
        self.Entry_1.select_range(0, END)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Button_1"
    def make_Button_1(self, frame):
        """      Button: Set XXX to None (not used) : at Main(3,1)"""
        self.Button_1 = Button(frame,
                               text="Set XXX to None (i.e. not used)",
                               width="45")
        self.Button_1.grid(row=3, column=1, columnspan="3")

        # >>>>>>insert any user code below this comment for section "make_Button_1"

        self.Button_1.bind("<ButtonRelease-1>", self.Button_1_Click)
        name = self.dialogOptions.get('label', '')
        if not name:
            name = self.dialogOptions.get('name', '')
        self.Button_1.configure(text='Set %s to None (i.e. not used)' % name)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Combobox_1"
    def make_Combobox_1(self, frame):
        """    Combobox: Mine Yours Ours : at Main(5,3)"""
        self.Combobox_1 = Combobox(frame,
                                   values="Mine Yours Ours",
                                   text="Combobox_1")
        self.Combobox_1.grid(row=5, column=3, sticky="w")
        self.Combobox_1_StringVar = StringVar()

        # >>>>>>insert any user code below this comment for section "make_Combobox_1"
        units = self.dialogOptions.get('units', '')
        category = get_category(units)
        catL = categoryD.get(category, [units])
        self.Combobox_1.configure(values=' '.join(catL))

        self.Combobox_1.configure(textvariable=self.Combobox_1_StringVar)
        self.Combobox_1_StringVar.set(units)
        self.Combobox_1_StringVar_traceName = self.Combobox_1_StringVar.trace_variable(
            "w", self.Combobox_1_StringVar_Callback)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Entry_1"
    def make_Entry_1(self, frame):
        """       Entry:  at Main(5,2)"""
        self.Entry_1 = Entry(frame, width="15")
        self.Entry_1.grid(row=5, column=2, sticky="ew", columnspan="1")
        self.Entry_1_StringVar = StringVar()

        # >>>>>>insert any user code below this comment for section "make_Entry_1"
        value = self.dialogOptions.get('value', '')
        self.Entry_1_StringVar.set(value)

        self.Entry_1.configure(textvariable=self.Entry_1_StringVar)
        self.Entry_1_StringVar_traceName = self.Entry_1_StringVar.trace_variable(
            "w", self.Entry_1_StringVar_Callback)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_1"
    def make_Label_1(self, frame):
        """       Label: Input XXX Value : at Main(1,1)"""
        self.Label_1 = Label(frame, text="Input XXX Value", width="60")
        self.Label_1.grid(row=1, column=1, columnspan="3")

        # >>>>>>insert any user code below this comment for section "make_Label_1"
        name = self.dialogOptions.get('label', '')
        if not name:
            name = self.dialogOptions.get('name', '')
        self.Label_1.configure(text='Input: ' + name)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_2"
    def make_Label_2(self, frame):
        """       Label: definition : at Main(2,1)"""
        self.Label_2 = Label(frame, text="definition", width="60", height="6")
        self.Label_2.grid(row=2, column=1, columnspan="3")

        # >>>>>>insert any user code below this comment for section "make_Label_2"
        desc = self.dialogOptions.get('desc', '')
        self.Label_2.configure(text=desc, wraplength=400)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_3"
    def make_Label_3(self, frame):
        """       Label: Value : at Main(4,2)"""
        self.Label_3 = Label(frame, text="Value", width="15")
        self.Label_3.grid(row=4, column=2)

        # >>>>>>insert any user code below this comment for section "make_Label_3"

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_4"
    def make_Label_4(self, frame):
        """       Label: Units : at Main(4,3)"""
        self.Label_4 = Label(frame, text="Units", width="15", anchor="w")
        self.Label_4.grid(row=4, column=3)

        # >>>>>>insert any user code below this comment for section "make_Label_4"

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_5"
    def make_Label_5(self, frame):
        """       Label: XXX= : at Main(5,1)"""
        self.Label_5 = Label(frame, text="XXX=", width="15", anchor="e")
        self.Label_5.grid(row=5, column=1, sticky="e")

        # >>>>>>insert any user code below this comment for section "make_Label_5"
        name = self.dialogOptions.get('name', '')
        self.Label_5.configure(text=name + '=')

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_6"
    def make_Label_6(self, frame):
        """       Label:  at Main(5,0)"""
        self.Label_6 = Label(frame, text="", width="2")
        self.Label_6.grid(row=5, column=0)

        # >>>>>>insert any user code below this comment for section "make_Label_6"

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_7"
    def make_Label_7(self, frame):
        """       Label:  at Main(5,4)"""
        self.Label_7 = Label(frame, text="", width="2")
        self.Label_7.grid(row=5, column=4)

        # >>>>>>insert any user code below this comment for section "make_Label_7"

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Button_1_Click"
    def Button_1_Click(self, event):  #bind method for component ID=Button_1
        """      Button: Set XXX to None (not used) : at Main(3,1)"""
        pass
        # >>>>>>insert any user code below this comment for section "Button_1_Click"
        # replace, delete, or comment-out the following
        #print( "executed method Button_1_Click" )

        self.set_value_to_none = True
        self.ok()

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Combobox_1_StringVar_traceName"
    def Combobox_1_StringVar_Callback(self, varName, index, mode):
        """    Combobox: Mine Yours Ours : at Main(5,3)"""
        pass

        # >>>>>>insert any user code below this comment for section "Combobox_1_StringVar_traceName"
        # replace, delete, or comment-out the following
        #print( "Combobox_1_StringVar_Callback varName, index, mode",varName, index, mode )
        #print( "    new StringVar value =",self.Combobox_1_StringVar.get() )

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Entry_1_StringVar_traceName"
    def Entry_1_StringVar_Callback(self, varName, index, mode):
        """       Entry:  at Main(5,2)"""
        pass

        # >>>>>>insert any user code below this comment for section "Entry_1_StringVar_traceName"
        # replace, delete, or comment-out the following
        #print( "Entry_1_StringVar_Callback varName, index, mode",varName, index, mode )
        #print( "    new StringVar value =",self.Entry_1_StringVar.get() )

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "standard_message_dialogs"

    # standard message dialogs... showinfo, showwarning, showerror
    def ShowInfo(self, title='Title', message='your message here.'):
        tkinter.messagebox.showinfo(title, message)
        return

    def ShowWarning(self, title='Title', message='your message here.'):
        tkinter.messagebox.showwarning(title, message)
        return

    def ShowError(self, title='Title', message='your message here.'):
        tkinter.messagebox.showerror(title, message)
        return

    # standard question dialogs... askquestion, askokcancel, askyesno, or askretrycancel
    # return True for OK, Yes, Retry, False for Cancel or No
    def AskYesNo(self, title='Title', message='your question here.'):
        return tkinter.messagebox.askyesno(title, message)

    def AskOK_Cancel(self, title='Title', message='your question here.'):
        return tkinter.messagebox.askokcancel(title, message)

    def AskRetryCancel(self, title='Title', message='your question here.'):
        return tkinter.messagebox.askretrycancel(title, message)

    # return "yes" for Yes, "no" for No
    def AskQuestion(self, title='Title', message='your question here.'):
        return tkinter.messagebox.askquestion(title, message)

    # END of standard message dialogs

    # >>>>>>insert any user code below this comment for section "standard_message_dialogs"

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "dialog_validate"
    def validate(self):
        self.result = {}  # return a dictionary of results

        #self.result["Combobox_1"] = self.Combobox_1_StringVar.get()
        #self.result["Entry_1"] = self.Entry_1_StringVar.get()

        # >>>>>>insert any user code below this comment for section "dialog_validate"
        # set values in "self.result" dictionary for return
        # for example...
        # self.result["age"] = self.Entry_2_StringVar.get()

        self.result["return_units"] = self.Combobox_1_StringVar.get()
        s = self.Entry_1_StringVar.get().strip()

        if self.set_value_to_none or s.lower() == 'none':
            self.result["return_value"] = None
        else:
            try:
                s = eval(s)
            except:
                self.ShowError(
                    title='Invalid Number',
                    message='"%s" NOT recognized as number\nPlease Try Again.'
                    % s)
                return 0

            try:
                value = float(s)
            except:
                self.ShowError(
                    title='Invalid Number',
                    message='"%s" is NOT a number\nPlease Try Again.' % s)
                return 0
            self.result["return_value"] = s

        #print('Value w Units Dialog result =', self.result)

        #self.result["test"] = "test message"
        return 1

    """
    replace test code
        desc = 'radius of curvature just downstream of throat (Rdownstream / Rthrt) this could be a very long description and we would just need to wrap it.'
        dialog = _get_value_w_units(self.master, "Test Dialog", 
                 dialogOptions={'name':'Rthrt', 'units':'in', 'value':'22', 'desc':desc, 'show_none_btn':True})    
    """

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "end"

    def apply(self):
        pass
Esempio n. 22
0
Checkbutton3.configure(text='''Header photo''')
Checkbutton3.configure(variable=check2)

Label1 = Label(Frame1)
Label1.place(relx=0.04, rely=-0.04)
Label1.configure(text='''Upload''')

Button1 = Button(Frame1)
Button1.place(relx=0.74, rely=0.7, height=25, width=60)
Button1.configure(padding=(2, 0, 0, 0))
Button1.configure(text='''Upload''')
Button1.configure(command=up)

TCombobox1 = Combobox(Frame1)
TCombobox1.place(relx=0.09, rely=0.22, relheight=0.18, relwidth=0.61)
TCombobox1.configure(textvariable=combobox1)
TCombobox1.configure(width=173)
TCombobox1.configure(takefocus="")
TCombobox1.configure(state="readonly")
TCombobox1['values'] = photos

Frame3 = Frame(root)
Frame3.place(relx=0.02, rely=0.33, relheight=0.63, relwidth=0.46)
Frame3.configure(relief=GROOVE)
Frame3.configure(borderwidth="2")
Frame3.configure(relief=GROOVE)
Frame3.configure(width=285)

Label4 = Label(Frame3)
Label4.place(relx=0.04, rely=-0.04, height=21, width=44)
Label4.configure(text='''Follow''')
Esempio n. 23
0
    def OnDoubleClick(self, event):
        """ редактирование элемента по двойному клику """
        common_width = 17
        add_width = 3
        add_item_window = Toplevel()
        add_item_window.minsize(width=250, height=340)
        item = self.selection()[0]
        set_to_edit = self.item(item, "values")
        labels = [item for item in self.data]
        lbl = []
        values = {}
        for i in range(0, len(labels)):
            values[labels[i]] = StringVar()
            lbl.append(Label(add_item_window, text=labels[i]))
            lbl[i].grid(column=0, row=i, padx=10, pady=10, sticky='w')

            if labels[i] == 'Кинотеатр':
                v = Combobox(
                    add_item_window,
                    values=[row[0] for index, row in self.cinemas.iterrows()],
                    textvariable=values[labels[i]],
                    width=common_width)
            elif labels[i] == 'Время':
                v = Entry(add_item_window, textvariable=values[labels[i]])
                values[labels[i]].trace(
                    'w',
                    lambda name, index, mode, sv=values[labels[
                        i]], item=v: entryUpdateEndHour(sv, item))
                values[labels[i]].set(set_to_edit[i])
            elif labels[i] == 'Фильм':
                """ живое подтверждение того, что DataFrame для строк идея плохая """
                lst = list(self.films['Фильм'])
                lst = [item.replace('[', '') for item in lst]
                lst = [item.strip("'") for item in lst]
                v = Combobox(add_item_window,
                             values=lst,
                             textvariable=values[labels[i]],
                             width=common_width)

            # это можно переписать с помощью lambda в одну строку
            elif labels[i] == 'Класс':
                v = Combobox(add_item_window,
                             values=self.dictionaries['class'],
                             textvariable=values[labels[i]],
                             width=common_width)
            elif labels[i] == '3D':
                v = Combobox(add_item_window,
                             values=self.dictionaries['3D'],
                             textvariable=values[labels[i]],
                             width=common_width)
            elif labels[i] == 'Статус':
                v = Combobox(add_item_window,
                             values=self.dictionaries['status'],
                             textvariable=values[labels[i]],
                             width=common_width)
            else:
                v = Entry(add_item_window,
                          textvariable=values[labels[i]],
                          width=common_width + add_width)
                if labels[i] == 'Билет':
                    v.configure(state=DISABLED)
            values[labels[i]].trace('w',
                                    lambda name, index, mode, sv=values[labels[
                                        i]], item=v: updateBoxes(sv, item))
            values[labels[i]].set(set_to_edit[i])

            v.grid(column=1, row=i, padx=10, pady=10, sticky='w')

        ok_button = Button(add_item_window,
                           text='Изменить',
                           width=12,
                           command=lambda data=values, frame=add_item_window:
                           self.save_item(data, frame))
        ok_button.grid(column=0, row=i + 1, pady=10, padx=10)

        cancel_button = Button(add_item_window,
                               text='Отменить',
                               command=add_item_window.destroy,
                               width=12)
        cancel_button.grid(column=1, row=i + 1, pady=10, padx=15)
Esempio n. 24
0
class _tk_rocket_units:
    def __init__(self, master):

        grid_frame = Frame(master)
        self.grid_frame = grid_frame
        grid_frame.pack(expand=1, fill=BOTH)
        self.master = master

        self.x, self.y, self.w, self.h = 10, 10, 403, 513

        self.master.title("tk_rocket_units")

        self.make_Frame_1(self.grid_frame)  #       Frame:  at Main(1,1)
        self.make_Label_10(self.grid_frame)  #       Label:  at Main(0,0)
        self.make_Label_11(self.grid_frame)  #       Label:  at Main(4,1)
        self.make_Label_7(self.grid_frame)  #       Label:  at Main(2,1)
        self.make_Label_8(self.grid_frame)  #       Label:  at Main(1,0)
        self.make_Label_9(self.grid_frame)  #       Label:  at Main(1,2)
        self.make_Text_1(self.grid_frame)  #        Text:  at Main(3,1)
        self.make_Combobox_1(
            self.Frame_1)  #    Combobox: Mine Yours Ours : at Frame_1(1,1)
        self.make_Combobox_2(
            self.Frame_1)  #    Combobox: Mine Yours Ours : at Frame_1(3,1)
        self.make_Combobox_3(
            self.Frame_1)  #    Combobox: Mine Yours Ours : at Frame_1(6,3)
        self.make_Entry_1(self.Frame_1)  #       Entry:  at Frame_1(5,1)
        self.make_Label_1(
            self.Frame_1)  #       Label: Category : at Frame_1(1,2)
        self.make_Label_2(self.Frame_1)  #       Label: Units : at Frame_1(3,2)
        self.make_Label_3(self.Frame_1)  #       Label: Value : at Frame_1(5,2)
        self.make_Label_4(
            self.Frame_1)  #       Label: Number Format : at Frame_1(5,3)
        self.make_Label_5(self.Frame_1)  #       Label:  at Frame_1(2,1)
        self.make_Label_6(self.Frame_1)  #       Label:  at Frame_1(4,1)

        self.grid_frame.rowconfigure(3, weight=1)
        self.grid_frame.columnconfigure(1, weight=1)

        # >>>>>>insert any user code below this comment for section "top_of_init"

        self.master.title("RocketUnits v%s" % get_version())

        self.show_all_units()

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Frame_1"
    def make_Frame_1(self, frame):
        """       Frame:  at Main(1,1)"""
        self.Frame_1 = Frame(frame,
                             width="60",
                             height="50",
                             borderwidth="0",
                             relief="flat")
        self.Frame_1.grid(row=1, column=1, sticky="w")

        # >>>>>>insert any user code below this comment for section "make_Frame_1"

    def show_all_units(self):
        self.Text_1.delete(1.0, END)

        cat = self.Combobox_1_StringVar.get()
        inp_units = self.Combobox_2_StringVar.get()
        fmt = float_formatD[self.Combobox_3_StringVar.get()]

        try:
            inp_val = float(self.Entry_1_StringVar.get())
        except:
            inp_val = 0.0

        def_unit_val = (inp_val - offsetD[inp_units]) / conv_factD[inp_units]

        for units in display_unitsD[cat]:
            val = def_unit_val * conv_factD[units] + offsetD[units]

            if fmt == 'd':
                dval = eng_context.create_decimal_from_float(val)
                sOut = dval.to_eng_string()
            elif fmt == 's':
                dval = sci_context.create_decimal_from_float(val)
                sOut = str(dval.normalize())
            else:
                sOut = fmt % val
            self.Text_1.insert(END, UNIT_FMT_STR % units + " = " + sOut + '\n')

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_10"
    def make_Label_10(self, frame):
        """       Label:  at Main(0,0)"""
        self.Label_10 = Label(frame, text="", width="4")
        self.Label_10.grid(row=0, column=0)

        # >>>>>>insert any user code below this comment for section "make_Label_10"

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_11"
    def make_Label_11(self, frame):
        """       Label:  at Main(4,1)"""
        self.Label_11 = Label(frame, text="", width="4")
        self.Label_11.grid(row=4, column=1)

        # >>>>>>insert any user code below this comment for section "make_Label_11"

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_7"
    def make_Label_7(self, frame):
        """       Label:  at Main(2,1)"""
        self.Label_7 = Label(frame, text="", width="15")
        self.Label_7.grid(row=2, column=1)

        # >>>>>>insert any user code below this comment for section "make_Label_7"

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_8"
    def make_Label_8(self, frame):
        """       Label:  at Main(1,0)"""
        self.Label_8 = Label(frame, text="", width="4")
        self.Label_8.grid(row=1, column=0)

        # >>>>>>insert any user code below this comment for section "make_Label_8"

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_9"
    def make_Label_9(self, frame):
        """       Label:  at Main(1,2)"""
        self.Label_9 = Label(frame, text="", width="4")
        self.Label_9.grid(row=1, column=2)

        # >>>>>>insert any user code below this comment for section "make_Label_9"

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Text_1"
    def make_Text_1(self, frame):
        """        Text:  at Main(3,1)"""
        self.Text_1 = Text(frame, width="40", height="20")
        self.Text_1.grid(row=3, column=1, sticky="nsew")

        # >>>>>>insert any user code below this comment for section "make_Text_1"

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Combobox_1"
    def make_Combobox_1(self, frame):
        """    Combobox: Mine Yours Ours : at Frame_1(1,1)"""
        self.Combobox_1 = Combobox(frame,
                                   values="Mine Yours Ours",
                                   text="Combobox_1")
        self.Combobox_1.grid(row=1, column=1, sticky="e")
        self.Combobox_1_StringVar = StringVar()

        # >>>>>>insert any user code below this comment for section "make_Combobox_1"

        self.Combobox_1.configure(textvariable=self.Combobox_1_StringVar)
        self.Combobox_1_StringVar.set("Length")
        self.Combobox_1['height'] = len(categoryL)
        self.Combobox_1['values'] = categoryL

        self.Combobox_1_StringVar_traceName = self.Combobox_1_StringVar.trace_variable(
            "w", self.Combobox_1_StringVar_Callback)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Combobox_2"
    def make_Combobox_2(self, frame):
        """    Combobox: Mine Yours Ours : at Frame_1(3,1)"""
        self.Combobox_2 = Combobox(frame,
                                   values="Mine Yours Ours",
                                   text="Combobox_2")
        self.Combobox_2.grid(row=3, column=1, sticky="e")
        self.Combobox_2_StringVar = StringVar()

        # >>>>>>insert any user code below this comment for section "make_Combobox_2"

        self.Combobox_2.configure(textvariable=self.Combobox_2_StringVar)
        self.Combobox_2_StringVar.set("ft")
        self.Combobox_2['height'] = 20
        self.Combobox_2['values'] = display_unitsD[
            self.Combobox_1_StringVar.get()]

        self.Combobox_2_StringVar_traceName = self.Combobox_2_StringVar.trace_variable(
            "w", self.Combobox_2_StringVar_Callback)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Combobox_3"
    def make_Combobox_3(self, frame):
        """    Combobox: Mine Yours Ours : at Frame_1(6,3)"""
        self.Combobox_3 = Combobox(frame,
                                   values="Mine Yours Ours",
                                   text="Combobox_3")
        self.Combobox_3.grid(row=6, column=3, sticky="e")
        self.Combobox_3_StringVar = StringVar()

        # >>>>>>insert any user code below this comment for section "make_Combobox_3"

        self.Combobox_3.configure(textvariable=self.Combobox_3_StringVar)
        self.Combobox_3_StringVar.set("general")
        self.Combobox_3['height'] = len(float_formatD)
        self.Combobox_3['values'] = list(float_formatL)
        self.Combobox_3_StringVar_traceName = self.Combobox_3_StringVar.trace_variable(
            "w", self.Combobox_3_StringVar_Callback)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Entry_1"
    def make_Entry_1(self, frame):
        """       Entry:  at Frame_1(5,1)"""
        self.Entry_1 = Entry(frame, width="13")
        self.Entry_1.grid(row=5, column=1, sticky="e")
        self.Entry_1_StringVar = StringVar()

        # >>>>>>insert any user code below this comment for section "make_Entry_1"
        self.Entry_1_StringVar.set("1.0")

        self.Entry_1.configure(textvariable=self.Entry_1_StringVar)
        self.Entry_1_StringVar_traceName = self.Entry_1_StringVar.trace_variable(
            "w", self.Entry_1_StringVar_Callback)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_1"
    def make_Label_1(self, frame):
        """       Label: Category : at Frame_1(1,2)"""
        self.Label_1 = Label(frame, text="Category", width="15", anchor="w")
        self.Label_1.grid(row=1, column=2, sticky="w")

        # >>>>>>insert any user code below this comment for section "make_Label_1"

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_2"
    def make_Label_2(self, frame):
        """       Label: Units : at Frame_1(3,2)"""
        self.Label_2 = Label(frame, text="Units", width="15", anchor="w")
        self.Label_2.grid(row=3, column=2, sticky="w")

        # >>>>>>insert any user code below this comment for section "make_Label_2"

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_3"
    def make_Label_3(self, frame):
        """       Label: Value : at Frame_1(5,2)"""
        self.Label_3 = Label(frame, text="Value", width="15", anchor="w")
        self.Label_3.grid(row=5, column=2, sticky="w")

        # >>>>>>insert any user code below this comment for section "make_Label_3"

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_4"
    def make_Label_4(self, frame):
        """       Label: Number Format : at Frame_1(5,3)"""
        self.Label_4 = Label(frame, text="Number Format", width="15")
        self.Label_4.grid(row=5, column=3)

        # >>>>>>insert any user code below this comment for section "make_Label_4"

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_5"
    def make_Label_5(self, frame):
        """       Label:  at Frame_1(2,1)"""
        self.Label_5 = Label(frame, text="", width="15")
        self.Label_5.grid(row=2, column=1)

        # >>>>>>insert any user code below this comment for section "make_Label_5"

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_6"
    def make_Label_6(self, frame):
        """       Label:  at Frame_1(4,1)"""
        self.Label_6 = Label(frame, text="", width="15")
        self.Label_6.grid(row=4, column=1)

        # >>>>>>insert any user code below this comment for section "make_Label_6"

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Combobox_1_StringVar_traceName"
    def Combobox_1_StringVar_Callback(self, varName, index, mode):
        """    Combobox: Mine Yours Ours : at Frame_1(1,1)"""
        pass

        # >>>>>>insert any user code below this comment for section "Combobox_1_StringVar_traceName"
        # replace, delete, or comment-out the following
        self.Combobox_2['values'] = display_unitsD[
            self.Combobox_1_StringVar.get()]
        self.Combobox_2_StringVar.set(
            display_def_unitsD[self.Combobox_1_StringVar.get()])
        #self.Combobox_2.current(0)

        self.show_all_units()

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Combobox_2_StringVar_traceName"
    def Combobox_2_StringVar_Callback(self, varName, index, mode):
        """    Combobox: Mine Yours Ours : at Frame_1(3,1)"""
        pass

        # >>>>>>insert any user code below this comment for section "Combobox_2_StringVar_traceName"
        # replace, delete, or comment-out the following
        self.show_all_units()

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Combobox_3_StringVar_traceName"
    def Combobox_3_StringVar_Callback(self, varName, index, mode):
        """    Combobox: Mine Yours Ours : at Frame_1(6,3)"""
        pass

        # >>>>>>insert any user code below this comment for section "Combobox_3_StringVar_traceName"
        # replace, delete, or comment-out the following
        self.show_all_units()

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Entry_1_StringVar_traceName"
    def Entry_1_StringVar_Callback(self, varName, index, mode):
        """       Entry:  at Frame_1(5,1)"""
        pass

        # >>>>>>insert any user code below this comment for section "Entry_1_StringVar_traceName"
        # replace, delete, or comment-out the following
        self.Combobox_2['values'] = display_unitsD[
            self.Combobox_1_StringVar.get()]
        #self.Combobox_2.current(0)
        self.show_all_units()
Esempio n. 25
0
class MainWindow(mp.Process):
    """Defines the main control window and all its control logic.

    As Tkinter only allows to create root windwo (Tk()) in the main process, this is implemented as its own
    subprocess that will open the window with a call to self.run()

    Args:
        connector_dict: Dictionary create by calling multiprocessing.Manger().dict()
        message_q: Queue that will be polled every few seconds. Elements in queue will be plotted to the internal
            text field.
        start_analysis_e: Event signaling if analysis can be started
        connected_e: Event signaling that LSL streams are connected
        ready_for_connection_e: Event signaling that LSL streams have been selected in GUI
        save_e: Event signaling that data should be saved.

    """
    def __init__(self, connector_dict: Dict, message_q: mp.Queue,
                 start_recording_e: mp.Event, start_analysis_e: mp.Event,
                 connected_e: mp.Event, ready_for_connection_e: mp.Event,
                 save_e: mp.Event):
        super().__init__()
        self.connector_dict = connector_dict
        self.message_q = message_q
        self.start_recording_e = start_recording_e
        self.start_analysis_e = start_analysis_e
        self.ready_for_connection_e = ready_for_connection_e
        self.connected_e = connected_e
        self.save_e = save_e

        self.master = None

        # Parameters
        self.eeg_stream = None
        self.eeg_streams_dict = None
        self.marker_stream = None
        self.marker_streams_dict = None
        self.channel_select = None
        self.update_interval = None
        self.record_time = None
        self.y_min = None
        self.y_max = None
        self.save_filename = None
        self.filter_check = None
        self.squared_check = None
        self.connected = None

        # Widgets
        self.eeg_stream_label = None
        self.eeg_stream_combobox = None
        self.eeg_stream_button = None
        self.marker_stream_label = None
        self.marker_stream_combobox = None
        self.marker_stream_button = None
        self.filter_checkbutton_label = None
        self.filter_checkbutton = None
        self.connect_button = None
        self.seperator = None
        self.start_recording_btn = None
        self.record_time_label = None
        self.Separator_2 = None
        self.update_interval_label = None
        self.update_interval_combobox = None
        self.start_analysis_btn = None
        self.channel_select_label = None
        self.channel_select_combobox = None
        self.squared_label = None
        self.squared_checkbtn = None
        self.update_ylim_btn = None
        self.y_min_label = None
        self.y_min_entry = None
        self.y_max_label = None
        self.y_max_entry = None
        self.seperator = None
        self.save_label = None
        self.save_entry = None
        self.save_btn = None
        self.text_console = None

    def build_main_window(self):
        # Hack to make tkinter work in other process than main
        from tkinter import Tk, StringVar, Text, HORIZONTAL, EW, IntVar
        from tkinter.ttk import Separator, Combobox, Button, Label, Entry, Checkbutton

        self.master = Tk()

        # Parameters
        self.eeg_stream = StringVar()
        self.eeg_streams_dict = {}
        self.marker_stream = StringVar()
        self.marker_streams_dict = {}
        self.channel_select = IntVar()
        self.channel_select.set(0)
        self.update_interval = IntVar()
        self.update_interval.set(0)
        self.record_time = StringVar()
        self.record_time.set("00:00 minutes recorded")
        self.y_min = IntVar()
        self.y_min.set(-10)
        self.y_max = IntVar()
        self.y_max.set(10)
        self.save_filename = StringVar()
        self.save_filename.set("1")
        self.filter_check = IntVar()
        self.filter_check.set(1)
        self.squared_check = IntVar()
        self.squared_check.set(0)

        self.connected = False

        self.print_from_queue()

        # Widgets
        self.eeg_stream_label = Label(self.master, text='EEG LSL-stream:')
        self.eeg_stream_label.grid(row=0, column=0)

        self.eeg_stream_combobox = Combobox(self.master,
                                            textvariable=self.eeg_stream)
        self.eeg_stream_combobox.configure(state='disabled')
        self.eeg_stream_combobox.grid(row=0, column=1)

        self.eeg_stream_button = Button(
            self.master,
            text='Refresh',
            command=lambda: self.find_streams('EEG', self.eeg_stream_combobox,
                                              self.eeg_streams_dict, self.
                                              eeg_stream))
        self.eeg_stream_button.grid(row=0, column=2)

        self.marker_stream_label = Label(self.master,
                                         text='Marker LSL-stream:')
        self.marker_stream_label.grid(row=1, column=0)

        self.marker_stream_combobox = Combobox(self.master,
                                               textvariable=self.marker_stream)
        self.marker_stream_combobox.configure(state='disabled')
        self.marker_stream_combobox.grid(row=1, column=1)

        self.marker_stream_button = Button(
            self.master,
            text='Refresh',
            command=lambda: self.find_streams(
                'P300_Marker', self.marker_stream_combobox, self.
                marker_streams_dict, self.marker_stream))
        self.marker_stream_button.grid(row=1, column=2)

        self.filter_checkbutton_label = Label(
            self.master, text='Filter (Butter, Order 4, Cutoff: 1, 30):')
        self.filter_checkbutton_label.grid(row=2, column=0)

        self.filter_checkbutton = Checkbutton(self.master,
                                              variable=self.filter_check,
                                              text='')
        self.filter_checkbutton.grid(row=2, column=1)

        self.connect_button = Button(self.master,
                                     text='Connect',
                                     command=self.connect_streams)
        self.connect_button.grid(row=2, column=2)
        self.connect_button.configure(state='disabled')

        self.seperator = Separator(self.master, orient=HORIZONTAL)
        self.seperator.grid(row=3, column=0, columnspan=3, sticky=EW)

        self.start_recording_btn = Button(self.master,
                                          text='Start recoding',
                                          command=self.start_recording)
        self.start_recording_btn.grid(row=4, column=2)
        self.start_recording_btn.configure(state='disabled')

        self.record_time_label = Label(self.master,
                                       textvariable=self.record_time)
        self.record_time_label.grid(row=4, column=1)

        self.Separator_2 = Separator(self.master)
        self.Separator_2.grid(row=5, column=0, columnspan=3, sticky=EW)

        self.update_interval_label = Label(self.master,
                                           text='Update interval (seconds):')
        self.update_interval_label.grid(row=6, column=0)

        self.update_interval_combobox = Combobox(
            self.master, textvariable=self.update_interval)
        self.update_interval_combobox.bind('<<ComboboxSelected>>',
                                           self.update_connector_dict)
        self.update_interval_combobox.grid(row=6, column=1)
        self.update_interval_combobox['values'] = list(range(10))
        self.update_interval_combobox.configure(state='disabled')

        self.start_analysis_btn = Button(self.master,
                                         text='Start analysis',
                                         command=self.start_analysis)
        self.start_analysis_btn.grid(row=6, column=2)
        self.start_analysis_btn.configure(state='disabled')

        self.channel_select_label = Label(self.master,
                                          text='Channel to display:')
        self.channel_select_label.grid(row=7, column=0)

        self.channel_select_combobox = Combobox(
            self.master, textvariable=self.channel_select)
        self.channel_select_combobox.bind('<<ComboboxSelected>>',
                                          self.update_connector_dict)
        self.channel_select_combobox.grid(row=7, column=1)
        self.channel_select_combobox.configure(state='disabled')

        self.squared_label = Label(self.master, text='squared')
        self.squared_label.grid(row=8, column=0)

        self.squared_checkbtn = Checkbutton(self.master,
                                            variable=self.squared_check)
        self.squared_checkbtn.grid(row=8, column=1)
        self.squared_checkbtn.configure(state='disabled')

        self.update_ylim_btn = Button(self.master,
                                      text='Update',
                                      command=self.update_connector_dict)
        self.update_ylim_btn.grid(row=8, column=2)
        self.update_ylim_btn.configure(state='disabled')

        self.y_min_label = Label(self.master, text='Y min:')
        self.y_min_label.grid(row=9, column=0)

        self.y_min_entry = Entry(self.master, textvariable=self.y_min)
        self.y_min_entry.grid(row=9, column=1)
        self.y_min_entry.configure(state='disabled')

        self.y_max_label = Label(self.master, text='Y max:')
        self.y_max_label.grid(row=10, column=0)

        self.y_max_entry = Entry(self.master, textvariable=self.y_max)
        self.y_max_entry.grid(row=10, column=1)
        self.y_max_entry.configure(state='disabled')

        self.seperator = Separator(self.master, orient=HORIZONTAL)
        self.seperator.grid(row=11, column=0, columnspan=3, sticky=EW)

        self.save_label = Label(self.master, text='Filename:')
        self.save_label.grid(row=12, column=0)

        self.save_entry = Entry(self.master, textvariable=self.save_filename)
        self.save_entry.grid(row=12, column=1)
        self.save_entry.configure(state='disabled')

        self.save_btn = Button(self.master, text='Save', command=self.save)
        self.save_btn.grid(row=12, column=2)
        self.save_btn.configure(state='disabled')

        self.text_console = Text(self.master)
        self.text_console.grid(row=15, column=0, rowspan=3, columnspan=3)
        self.text_console.configure(state='disabled')

    def save(self):
        self.update_connector_dict()
        self.save_e.set()

    def update_channel_select(self):
        num_channels = self.connector_dict['number of channels']
        self.channel_select_combobox['values'] = list(range(num_channels))

    def start_recording(self):
        self.connect_button.configure(state='disabled')
        self.start_recording_btn.configure(state='disabled')
        self.channel_select_combobox.configure(state='normal')
        self.update_interval_combobox.configure(state='normal')
        self.y_min_entry.configure(state='normal')
        self.y_max_entry.configure(state='normal')
        self.update_ylim_btn.configure(state='normal')
        self.squared_checkbtn.configure(state='normal')

        self.update_channel_select()
        self.update_recording_time()

        self.start_recording_e.set()

        self.start_analysis_btn.configure(state='normal')

    def update_recording_time(self):
        num_samples = self.connector_dict['sample count']
        samplerate = self.connector_dict['samplerate']
        number_of_seconds = int(num_samples / samplerate)

        minutes = number_of_seconds // 60
        remaining_seconds = number_of_seconds % 60

        result_string = '{:02}:{:02} minutes recorded'.format(
            minutes, remaining_seconds)

        self.record_time.set(result_string)
        self.master.after(1000, self.update_recording_time)

    def start_analysis(self):
        self.start_analysis_btn.configure(state='disabled')
        self.save_btn.configure(state='normal')
        self.save_entry.configure(state='normal')

        self.update_connector_dict()
        self.start_analysis_e.set()

    def find_streams(self, stream_type, widget, stream_dict, var):
        stream_dict.clear()
        timeout = 3
        self.print_to_console('Searching for ' + stream_type +
                              ' streams... (timeout = ' + str(timeout) +
                              ' seconds)')

        streams = resolve_byprop('type', stream_type, timeout=timeout)
        if not streams:
            self.print_to_console('No stream found.')
            return

        widget.configure(state='normal')

        stream_list = []
        for stream in streams:
            stream_dict[stream.name()] = stream
            stream_list.append(stream.name())

        widget['values'] = stream_list

        if len(streams) >= 1:
            var.set(streams[0].name())

        self.print_to_console(str(len(streams)) + ' Stream(s) found!')
        self.test_if_two_streams()

    def test_if_two_streams(self):
        if self.eeg_stream.get() is not '' and self.marker_stream.get(
        ) is not '':
            self.connect_button.configure(state='normal')
        else:
            self.connect_button.configure(state='disabled')

    def print_to_console(self, text_to_print):
        text_to_print = str(text_to_print)

        self.text_console.configure(state='normal')
        self.text_console.insert('end', text_to_print + '\n')
        self.text_console.configure(state='disabled')

    def print_from_queue(self):
        if not self.message_q.empty():
            self.print_to_console(self.message_q.get())
        self.master.after(500, self.print_from_queue)

    # noinspection PyUnusedLocal
    def update_connector_dict(self, event=None):
        self.connector_dict['update interval'] = self.update_interval.get()
        self.connector_dict['channel select'] = self.channel_select.get()
        self.connector_dict['eeg streamname'] = self.eeg_stream.get()
        self.connector_dict['marker streamname'] = self.marker_stream.get()
        self.connector_dict['y lim'] = [self.y_min.get(), self.y_max.get()]
        self.connector_dict['savefile'] = self.save_filename.get()
        self.connector_dict['filter'] = self.filter_check.get()
        self.connector_dict['squared'] = self.squared_check.get()

    def connect_streams(self):
        self.eeg_stream_combobox.configure(state='disabled')
        self.eeg_stream_button.configure(state='disabled')
        self.marker_stream_combobox.configure(state='disabled')
        self.marker_stream_button.configure(state='disabled')
        self.filter_checkbutton.configure(state='disabled')
        self.connect_button.configure(state='disabled')

        self.update_connector_dict()
        self.ready_for_connection_e.set()

        self.connected_e.wait()

        self.start_recording_btn.configure(state='normal')

    def run(self):
        self.build_main_window()
        self.master.mainloop()
class ChooseSeats:
    """ChooseSeats class: ChooseSeats window.
         - Choose how many tickets you want
         - Choose which seats you want
         - See how much it cost for tickets

    old_window: reference to the tk() object (Login window)
    username: User's username -_-
    location: Location where the employee works. Use to get the database of that location
    scheduleId: Use to access and modify seating and update database
     """
    def __init__(self, username, scheduleID, old_window, location):
        global cinemaDB_path
        cinemaDB_path = os.path.abspath(
            os.path.join(os.path.dirname(__file__), "..", f"{location}.db"))

        self.old_window = old_window

        self.username = username
        self.scheduleID = scheduleID
        self.location = location
        self.cinema_info = get_cinema_info(scheduleID=scheduleID)
        self.movie_name = self.cinema_info["movie_name"]
        self.movie_time = self.cinema_info["movie_time"]
        self.movie_date = self.cinema_info["movie_date"]
        self.cinema_hall = self.cinema_info["cinema_hall"]
        self._seat_layout = seating_layout_list(
            self.cinema_info["cinema_layout"])
        self.available_seats = self.cinema_info["available_seats"]
        self.num_seats_chosen = 0
        self._btn_list = []
        self._temp_choice = []

        # Ticket Price
        self.adult_price = Decimal(9.20)
        self.child_price = Decimal(7.80)

        self.window = Toplevel()
        self.window.title("Choose your seats.")
        self.window.geometry("900x600+300+10")
        self.window.resizable(False, False)
        self.window.protocol(
            "WM_DELETE_WINDOW",
            self.go_back)  # Closing the window is same as signing out

        # Background
        Label(self.window).grid(row=0, column=0,
                                padx=(60, 0))  # Just for aligning the GUI
        self.window.bg = PhotoImage(file="image/Seating.gif")
        self.background = Label(self.window,
                                image=self.window.bg,
                                width=900,
                                height=600)
        self.background.place(x=0, y=0)
        self.heading = Label(self.window,
                             text="Choose your seats",
                             font=("Arial", 30),
                             bg="#D7BDE2")
        self.heading.grid(row=0,
                          column=0,
                          columnspan=1200,
                          padx=(80, 0),
                          pady=(10, 0))
        self.go_back_btn = Button(self.window,
                                  text="Go Back",
                                  command=self.go_back,
                                  font=15,
                                  bd=1,
                                  bg="#D0D3D4")
        self.go_back_btn.place(x=30, y=15)

        # Cinema Screen
        self.screen = Label(self.window,
                            text="Screen",
                            width=50,
                            height=2,
                            bg="#EBC9C2",
                            font=20)
        self.screen.grid(row=3,
                         column=0,
                         columnspan=1200,
                         pady=15,
                         padx=(80, 0))

        # If there are available seats, enable them to book seats.
        if self.available_seats != 0:

            # Choose the number of tickets
            self.num_tickets_display = Label(
                self.window,
                text="How many movie tickets do you want:",
                bg="#D7BDE2",
                font=("Arial", 15))
            self.num_tickets_display.grid(row=1,
                                          column=0,
                                          pady=(20, 4),
                                          columnspan=50,
                                          padx=(70, 0))
            self.ticket_frame = LabelFrame(
                self.window,
                text=
                "    Type\t       Price\t       Quantity       Sub Total         Total",
                fg="white",
                bg="#414141",
                font=("Arial", 12))
            self.ticket_frame.grid(row=2,
                                   column=0,
                                   columnspan=50,
                                   padx=(60, 0))
            # Adult tickets
            self.adult_ticket_lbl = Label(self.ticket_frame,
                                          text="Adult",
                                          font=("Arial", 10),
                                          fg="white",
                                          bg="#A6A6A6",
                                          width=9)
            self.adult_ticket_lbl.grid(row=0, column=0)
            self.adult_price_lbl = Label(
                self.ticket_frame,
                text=f"£{self.adult_price.quantize(Decimal('0.00'))}",
                fg="#EEEEEE",
                bg="#A6A6A6",
                font=("Arial", 10),
                width=10)
            self.adult_price_lbl.grid(row=0, column=1)
            self.adult_option = Combobox(self.ticket_frame,
                                         state="readonly",
                                         width=10)
            self.adult_option.grid(row=0, column=2)
            self.adult_option["values"] = list(
                range(0, self.available_seats + 1))
            self.adult_option.current(0)
            self.adult_total = Label(self.ticket_frame,
                                     text="£0.00",
                                     fg="#EEEEEE",
                                     bg="#A6A6A6",
                                     font=("Arial", 10),
                                     width=10)
            self.adult_total.grid(row=0, column=3)
            self.adult_option.bind("<<ComboboxSelected>>",
                                   lambda e: self.adult_ticket_update())
            # Children tickets
            self.child_ticket_lbl = Label(self.ticket_frame,
                                          text="Child",
                                          fg="white",
                                          bg="#A6A6A6",
                                          font=("Arial", 10),
                                          width=9)
            self.child_ticket_lbl.grid(row=1, column=0)
            self.child_price_lbl = Label(
                self.ticket_frame,
                text=f"£{self.child_price.quantize(Decimal('0.00'))}",
                fg="#EEEEEE",
                bg="#A6A6A6",
                font=("Arial", 10),
                width=10)
            self.child_price_lbl.grid(row=1, column=1)
            self.child_option = Combobox(self.ticket_frame,
                                         state="readonly",
                                         width=10)
            self.child_option.grid(row=1, column=2)
            self.child_option["values"] = list(
                range(0, self.available_seats + 1))
            self.child_option.current(0)
            self.child_total = Label(self.ticket_frame,
                                     text="£0.00",
                                     fg="#EEEEEE",
                                     bg="#A6A6A6",
                                     font=("Arial", 10),
                                     width=10)
            self.child_total.grid(row=1, column=3)
            self.child_option.bind("<<ComboboxSelected>>",
                                   lambda e: self.child_ticket_update())
            # Total Cost
            self.total_cost = Label(self.ticket_frame,
                                    text="£0.00",
                                    fg="#EEEEEE",
                                    bg="#A6A6A6",
                                    font=("Arial", 13),
                                    width=9,
                                    height=2)
            self.total_cost.grid(row=0, rowspan=2, column=4)

            self.enter_btn = Button(self.window,
                                    text="Enter",
                                    command=self.enter,
                                    bd=2,
                                    bg="#FAE5D3",
                                    font=("Arial", 10))
            self.enter_btn.grid(row=2, column=16)
            self.change_btn = Button(self.window,
                                     text="Change",
                                     command=self.choose_again,
                                     bd=1,
                                     bg="#FAE5D3")

            self.pay_btn = Button(self.window,
                                  text="Pay",
                                  font=15,
                                  bg="#D6EAF8",
                                  command=self.pay_function,
                                  bd=1)
            self.pay_btn.grid(row=20, column=10, pady=10, columnspan=2)
        else:
            self.no_booking = Label(self.window,
                                    text="There are no seats available.",
                                    font=("Arial", 20),
                                    bg="#F54949")
            self.no_booking.grid(row=1,
                                 column=0,
                                 pady=(20, 4),
                                 columnspan=50,
                                 padx=(70, 0))

        x, y = 1, 1
        for i in self._seat_layout:
            level = []
            for j in i:
                if j == 0:
                    btn = Button(self.window,
                                 width=5,
                                 height=2,
                                 bd=1,
                                 bg="white",
                                 command=partial(self.press_seat,
                                                 (x - 1, y - 1)))
                    if x == 1:
                        btn.grid(column=x + 1, row=y + 3)
                    else:
                        btn.grid(column=x + 1, row=y + 3)
                    level.append(btn)
                elif j == 1:
                    btn = Button(self.window,
                                 width=5,
                                 height=2,
                                 bd=1,
                                 bg="grey",
                                 state="disabled",
                                 command=partial(self.press_seat,
                                                 (x - 1, y - 1)))
                    btn.grid(column=x + 1, row=y + 3)
                    level.append(btn)
                else:
                    level.append(NONE)
                x += 1
            self._btn_list.append(level)

            x = 1
            y += 1

    def go_back(self):
        self.window.destroy()
        self.old_window.deiconify()

    def enter(self):
        if self.child_option.get() != "0" and self.adult_option.get() == "0":
            messagebox.showinfo("Invalid", "There must be at least one adult.")
        elif self.adult_option.get() != "0" or self.child_option.get() != "0":
            self.num_seats_chosen = int(self.adult_option.get()) + int(
                self.child_option.get())
            self.adult_option.configure(state="disabled")
            self.child_option.configure(state="disabled")
            self.enter_btn.configure(state="disabled")
            self.change_btn.grid(row=2, column=17, columnspan=2)
        else:
            messagebox.showinfo(
                "Invalid",
                "Choose how many tickets you want, then you can choose your seats."
            )

    def adult_ticket_update(self):
        sub_total = Decimal(self.adult_price *
                            int(self.adult_option.get())).quantize(
                                Decimal('0.00'))
        self.adult_total.configure(text=f"£{sub_total}")
        self.child_option["values"] = list(
            range(0,
                  (self.available_seats + 1) - int(self.adult_option.get())))
        total = Decimal(sub_total) + Decimal(
            self.child_price * int(self.child_option.get())).quantize(
                Decimal('0.00'))
        self.total_cost.configure(text=total.quantize(Decimal('0.00')))

    def child_ticket_update(self):
        sub_total = Decimal(self.child_price *
                            int(self.child_option.get())).quantize(
                                Decimal('0.00'))
        self.child_total.configure(text=f"£{sub_total}")
        self.adult_option["values"] = list(
            range(0,
                  (self.available_seats + 1) - int(self.child_option.get())))
        total = Decimal(sub_total) + Decimal(
            self.adult_price * int(self.adult_option.get())).quantize(
                Decimal('0.00'))
        self.total_cost.configure(text=total.quantize(Decimal('0.00')))

    def pay_function(self):
        if len(
                self._temp_choice
        ) == self.num_seats_chosen and self.enter_btn["state"] == "disabled":
            num_to_alph = {
                0: "A",
                1: "B",
                2: "C",
                3: "D",
                4: "E",
                5: "F",
                6: "G",
                7: "H"
            }
            seat = ",".join([
                str(i[0] + 1) + str(num_to_alph[i[1]])
                for i in self._temp_choice
            ])
            message = f"""
Movie: {self.movie_name}
Location: {self.location}
Date: {self.movie_date}
Time: {self.movie_time}
Cinema Hall: {self.cinema_hall}
Number Of Seats: {len(self._temp_choice)}
Adult Ticket{"s" if int(self.adult_option.get()) > 1 else ""}: {self.adult_option.get()}
Child Ticket{"s" if int(self.child_option.get()) > 1 else ""}: {self.child_option.get()}
Seat Location{"s" if len(self._temp_choice) > 1 else ""}: {seat}
Total Cost: £{self.total_cost.cget("text")}

Are you ready to pay?"""
            if messagebox.askyesno("Confirm", message):
                global userDB_path
                db = sqlite3.connect(userDB_path)
                cursor = db.cursor()
                cursor.execute(
                    f"""SELECT userID FROM people WHERE username = ?""",
                    (self.username, ))
                userID = cursor.fetchone()[0]
                db.close()
                new_available_seats = self.available_seats - len(
                    self._temp_choice)
                updated_layout = seating_layout_string(self._seat_layout)

                global cinemaDB_path
                db = sqlite3.connect(cinemaDB_path)
                cursor = db.cursor()

                cursor.execute(
                    """INSERT INTO customer_tickets(userID, scheduleID, user_tickets, num_tickets, adult_tickets, child_tickets, cost)
                       VALUES(?,?,?,?,?,?,?)""",
                    (userID, self.scheduleID, seat, len(
                        self._temp_choice), self.adult_option.get(),
                     self.child_option.get(), self.total_cost.cget("text")))
                cursor.execute(
                    """UPDATE seating_plan SET available_seats=?, cinema_layout=? WHERE scheduleID=?""",
                    (new_available_seats, updated_layout, self.scheduleID))

                db.commit()
                db.close()
                self.go_back()
                messagebox.showinfo("Enjoy", "Enjoy Your movie.")
        else:
            messagebox.showinfo("Invalid", "Please choose your seat first.")

    def choose_again(self):
        self.adult_option.configure(state="readonly")
        self.child_option.configure(state="readonly")
        self.enter_btn.configure(state="normal")
        self.change_btn.grid_forget()
        for pos in self._temp_choice:
            self._seat_layout[pos[1]][pos[0]] = 0
            self._btn_list[pos[1]][pos[0]].configure(bg="white")
        self._temp_choice = []
        self.num_seats_chosen = 0

    def press_seat(self, pos):
        if self._seat_layout[pos[1]][pos[0]] != 3:
            if self.num_seats_chosen != 0:
                if len(self._temp_choice) < self.num_seats_chosen:
                    self._btn_list[pos[1]][pos[0]].configure(bg="green")
                    self._seat_layout[pos[1]][pos[0]] = 3
                    self._temp_choice.append((pos[0], pos[1]))
                else:
                    messagebox.showwarning(
                        "Invalid", "You have already chosen your seats."
                        "\nIf you want to change it, you can do it by tapping the green square."
                    )
            else:
                messagebox.showinfo(
                    "Invalid",
                    "Choose how many tickets you want, then you can choose your seats."
                )
        else:
            self._btn_list[pos[1]][pos[0]].configure(bg="white")
            self._seat_layout[pos[1]][pos[0]] = 0
            self._temp_choice.remove((pos[0], pos[1]))
class MainWindow(Frame):
    """This class defines UI and functionality of the application main window
    Derives from class Frame"""

    # class variables
    left_panel_width = 300
    left_upper_height = 270  # width required to display the calendar (date picker)
    notes_ctrl_height = 50
    base_color = 'bisque'
    cover_color = 'indianred'
    lbl_font = '"Century Gothic" 16'
    lbl_fontcolor = 'floralwhite'
    input_font = '"Segoe UI" 16'
    input_fontcolor = 'brown'
    btn_font = '"Century Gothic" 12 bold'
    btn_fontcolor = 'brown'
    str_by_category = 'filter by category:'
    str_by_text = 'filter by text:'
    str_newnote = 'newnote'
    noteview_side = 250
    note_padding = 5

    def __init__(self, container):
        """ctor"""
        super().__init__(container)
        container.update_idletasks()
        self.total_height = container.winfo_height()
        self.total_width = container.winfo_width()
        self.left_middle_height = self.left_lower_height = (
            self.total_height - __class__.left_upper_height) // 2
        self.right_area_width = self.total_width - __class__.left_panel_width
        self.notes_display_height = self.total_height - self.__class__.notes_ctrl_height

        self.msgboard_img = PhotoImage(
            file=msgboard_img_path
        )  # object that represents the background as cork-board texture
        self.justdoit_img = PhotoImage(
            file=justdoit_img_path)  # placeholder #1
        self.colornotes_img = PhotoImage(
            file=colornotes_img_path)  # placeholder #2

        self.create_widgets(container)

        # initial calculation of the grid dimensions according to the available space and the note frame size
        self.cnvs_notes_display.gridcols_cnt = self.right_area_width // (
            __class__.noteview_side + __class__.note_padding)
        self.cnvs_notes_display.gridrows_cnt = self.notes_display_height // (
            __class__.noteview_side + __class__.note_padding)
        self.cnvs_notes_display.grid_propagate(False)

    def create_widgets(self, container):
        """This method defines UI of the main window"""
        self.frm_main = Frame(container)
        self.frm_main.pack(fill=BOTH, expand=True)

        self.frm_left_main = Frame(self.frm_main,
                                   width=__class__.left_panel_width,
                                   height=self.total_height,
                                   bg=__class__.base_color)
        self.frm_left_main.pack(side=LEFT)

        self.frm_left_top = Frame(self.frm_left_main,
                                  width=__class__.left_panel_width,
                                  height=__class__.left_upper_height,
                                  bg=__class__.cover_color)
        self.frm_left_top.grid(row=0)
        self.frm_left_top.grid_propagate(False)
        self.calendar = Calendar(self.frm_left_top,
                                 padx_param=__class__.left_panel_width / 5,
                                 pady_param=__class__.left_upper_height / 8)

        self.frm_left_middle = Frame(self.frm_left_main,
                                     width=__class__.left_panel_width,
                                     height=self.left_middle_height,
                                     bg=__class__.base_color)
        self.frm_left_middle.grid(row=1)
        self.cnvs_left_middle = Canvas(
            self.frm_left_middle,
            width=self.left_panel_width,
            height=self.left_middle_height)  #, bg='white'
        self.cnvs_left_middle.grid(row=0, column=0)
        self.cnvs_left_middle.create_image(self.left_panel_width // 2,
                                           self.left_middle_height // 2,
                                           image=self.justdoit_img)

        self.frm_left_btm = Frame(self.frm_left_main,
                                  width=__class__.left_panel_width,
                                  height=self.left_lower_height,
                                  bg=__class__.base_color)
        self.frm_left_btm.grid(row=2)
        self.cnvs_left_bottom = Canvas(
            self.frm_left_btm,
            width=self.left_panel_width,
            height=self.left_lower_height)  #, bg='white'
        self.cnvs_left_bottom.grid(row=0, column=0)
        self.cnvs_left_bottom.create_image(self.left_panel_width // 2,
                                           self.left_lower_height // 2,
                                           image=self.colornotes_img)

        self.frm_right_main = Frame(self.frm_main,
                                    width=self.right_area_width,
                                    height=self.total_height,
                                    bg=__class__.base_color)
        self.frm_right_main.pack()

        self.frm_notes_control = Frame(self.frm_right_main,
                                       width=self.right_area_width,
                                       height=__class__.notes_ctrl_height,
                                       bg=__class__.cover_color)
        self.frm_notes_control.pack(fill=X)
        self.frm_notes_control.pack_propagate(False)

        self.lbl_filter_by_category = Label(self.frm_notes_control,
                                            font=__class__.lbl_font,
                                            fg=__class__.lbl_fontcolor,
                                            bg=__class__.cover_color,
                                            text=__class__.str_by_category)
        self.lbl_filter_by_category.pack(side=LEFT)

        self.cmbx_filter_by_category = Combobox(
            self.frm_notes_control,
            font=__class__.input_font,
            foreground=__class__.input_fontcolor,
            textvariable=category_filter_ctrlvar)  # ttk.Combobox
        self.cmbx_filter_by_category.configure(values=['All'] +
                                               category_names_lst)
        self.cmbx_filter_by_category.current(0)  # i.e. default value is 'All'
        self.cmbx_filter_by_category.bind("<<ComboboxSelected>>",
                                          self.action_filter_notes)
        self.cmbx_filter_by_category.pack(side=LEFT)

        self.lbl_filter_by_text = Label(self.frm_notes_control,
                                        font=__class__.lbl_font,
                                        fg=__class__.lbl_fontcolor,
                                        bg=__class__.cover_color,
                                        text=__class__.str_by_text)
        self.lbl_filter_by_text.pack(side=LEFT)

        self.entry_filter_by_text = Entry(self.frm_notes_control,
                                          font=__class__.input_font,
                                          fg=__class__.input_fontcolor,
                                          textvariable=descr_filter_ctrlvar)
        self.entry_filter_by_text.bind('<KeyRelease>',
                                       self.action_filter_notes)
        self.entry_filter_by_text.pack(side=LEFT)

        self.btn_new_note = Button(self.frm_notes_control,
                                   font=__class__.btn_font,
                                   fg=__class__.btn_fontcolor,
                                   text=__class__.str_newnote)
        self.btn_new_note.bind("<Button-1>", action_new_note_dialog)
        self.btn_new_note.pack(side=RIGHT, padx=5)

        self.frm_notes_display = Frame(self.frm_right_main,
                                       width=self.right_area_width,
                                       height=self.notes_display_height,
                                       bg='bisque')
        self.frm_notes_display.pack()

        self.cnvs_notes_display = Canvas(self.frm_notes_display,
                                         width=self.right_area_width,
                                         height=self.notes_display_height)
        self.cnvs_notes_display.bind('<Configure>', self.action_config_display)
        self.cnvs_notes_display.pack(fill=BOTH)
        self.cnvs_notes_display.create_image(self.right_area_width // 2,
                                             self.notes_display_height // 2,
                                             image=self.msgboard_img)

        self.sizegrip = Sizegrip(self)  #ttk.Sizegrip
        self.sizegrip.pack(side=RIGHT)

    def action_config_display(self, event):
        """This method deploys according to the new screen dimensions"""
        #self.after(250, clean_display())

        root.update_idletasks()
        self.total_height = root.winfo_height()
        self.total_width = root.winfo_width()
        self.left_middle_height = self.left_lower_height = (
            self.total_height - __class__.left_upper_height) // 2
        self.right_area_width = self.total_width - __class__.left_panel_width
        self.notes_display_height = self.total_height - self.__class__.notes_ctrl_height

        # recalculation of the grid dimensions according to available space and note frame size
        self.cnvs_notes_display.gridcols_cnt = self.right_area_width // (
            __class__.noteview_side + __class__.note_padding)
        self.cnvs_notes_display.gridrows_cnt = self.notes_display_height // (
            __class__.noteview_side + __class__.note_padding)

        self.action_filter_notes(event)

    def action_filter_notes(self, event=None):
        """This method displays notes that meet currentl filtering criteria"""

        aux_filter_notes(category_filter_ctrlvar.get(),
                         descr_filter_ctrlvar.get())
        display_notes(event)
class NSE:
    def stop_all(self) -> None:
        self.stop = True

    def main_recursive(self) -> None:
        if (self.first_run):
            #print("FIRST time")
            self.refresh_data()
            self.first_run = False
        self.curr_time = time.time()
        time_passed = int(self.curr_time - self.prev_time)
        if (time_passed > self.interval):
            self.refresh_data()
        else:
            self.sh_window.after((10 * 1000), self.main_recursive)
            return
        if (not self.stop):
            self.sh_window.after((10 * 1000), self.main_recursive)
            return

    def __init__(self, window: Tk) -> None:
        self.first_run_live_price: List[float] = []
        self.plot_only: bool = True
        self.graph_index, = plt.plot([], [], 'o-', label='BANKNIFTY')
        self.first_run: bool = True
        self.dict_dfs_INDEX: dict[pd.DataFrame] = {}
        self.dict_dfs_STOCK: dict[pd.DataFrame] = {}
        self.nb_names: List[String] = [
            'PCR OTM', 'DIFF OTM', 'PCR FAR OTM', 'CE-OTM', 'PE-OTM',
            'CE-FAR_OTM', 'PE-FAR_OTM', 'LTP', 'PCR'
        ]
        for i in self.nb_names:
            self.dict_dfs_INDEX[i] = pd.DataFrame()
            self.dict_dfs_STOCK[i] = pd.DataFrame()
        self.stop: bool = False
        self.curr_time = ""
        self.interval = 5  #seconds
        self.red: str = "#e53935"
        self.green: str = "#00e676"
        self.df_INDEX: pd.DataFrame = pd.DataFrame()
        self.df_STOCK: pd.DataFrame = pd.DataFrame()
        self.popular_stocks: List[str] = ['AUROPHARMA','TATASTEEL','ASHOKLEY','AXISBANK', 'BAJAJ-AUTO', 'BAJAJFINSV',\
                                          'BRITANNIA','DRREDDY','GLENMARK','HDFC', 'HDFCBANK',\
                                          'ICICIBANK','INDUSINDBK','INFY','MANAPPURAM','MARUTI',\
                                          'MUTHOOTFIN','RELIANCE','SBILIFE', 'SBIN','TATAMOTORS',\
                                          'TCS','WIPRO','ZEEL']
        self.hdr: Dict[str, str] = {
            'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 \
                                (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36',
            'accept-language': 'en-US,en;q=0.9'
        }
        self.stock_symbs: List[str] = [
            'AARTIIND', 'ACC', 'ADANIENT', 'ADANIPORTS', 'AMARAJABAT',
            'AMBUJACEM', 'APOLLOHOSP', 'APOLLOTYRE', 'ASHOKLEY', 'ASIANPAINT',
            'AUROPHARMA', 'AXISBANK', 'BAJAJ-AUTO', 'BAJAJFINSV', 'BAJFINANCE',
            'BALKRISIND', 'BANDHANBNK', 'BANKBARODA', 'BATAINDIA', 'BEL',
            'BERGEPAINT', 'BHARATFORG', 'BHARTIARTL', 'BHEL', 'BIOCON',
            'BOSCHLTD', 'BPCL', 'BRITANNIA', 'CADILAHC', 'CANBK', 'CHOLAFIN',
            'CIPLA', 'COALINDIA', 'COFORGE', 'COLPAL', 'CONCOR', 'CUMMINSIND',
            'DABUR', 'DIVISLAB', 'DLF', 'DRREDDY', 'EICHERMOT', 'ESCORTS',
            'EXIDEIND', 'FEDERALBNK', 'GAIL', 'GLENMARK', 'GMRINFRA',
            'GODREJCP', 'GODREJPROP', 'GRASIM', 'HAVELLS', 'HCLTECH', 'HDFC',
            'HDFCAMC', 'HDFCBANK', 'HDFCLIFE', 'HEROMOTOCO', 'HINDALCO',
            'HINDPETRO', 'HINDUNILVR', 'IBULHSGFIN', 'ICICIBANK', 'ICICIGI',
            'ICICIPRULI', 'IDEA', 'IDFCFIRSTB', 'IGL', 'INDIGO', 'INDUSINDBK',
            'INDUSTOWER', 'INFY', 'IOC', 'ITC', 'JINDALSTEL', 'JSWSTEEL',
            'JUBLFOOD', 'KOTAKBANK', 'LALPATHLAB', 'LICHSGFIN', 'LT', 'LUPIN',
            'MANAPPURAM', 'MARICO', 'MARUTI', 'MCDOWELL-N', 'MFSL', 'MGL',
            'MINDTREE', 'MOTHERSUMI', 'MRF', 'MUTHOOTFIN', 'NATIONALUM',
            'NAUKRI', 'NESTLEIND', 'NMDC', 'NTPC', 'ONGC', 'PAGEIND', 'PEL',
            'PETRONET', 'PFC', 'PIDILITIND', 'PNB', 'POWERGRID', 'PVR',
            'RAMCOCEM', 'RBLBANK', 'RECLTD', 'RELIANCE', 'SAIL', 'SBILIFE',
            'SBIN', 'SHREECEM', 'SIEMENS', 'SRF', 'SRTRANSFIN', 'SUNPHARMA',
            'SUNTV', 'TATACHEM', 'TATACONSUM', 'TATAMOTORS', 'TATAPOWER',
            'TATASTEEL', 'TCS', 'TECHM', 'TITAN', 'TORNTPHARM', 'TORNTPOWER',
            'TVSMOTOR', 'UBL', 'ULTRACEMCO', 'UPL', 'VEDL', 'VOLTAS', 'WIPRO'
        ]
        #self.stock_symbs: List[str] = ['INFY','UPL', 'VEDL', 'VOLTAS', 'WIPRO', 'ZEEL']
        #self.stock_symbs: List[str] = ['INFY','UPL']
        self.stock_symbs = self.popular_stocks
        self.indices: List[str] = ['NIFTY', 'BANKNIFTY']
        #self.indices: List[str] = ['BANKNIFTY']
        self.SYMBS: List[String] = self.indices
        self.stock_symb: String = ""
        self.session: requests.Session = requests.Session()
        self.make_intial_nse_connection()
        self.expiry_date: String = ""
        self.setup_main_window(window)
        self.resposne: requests.Response = requests.Response()

    def make_intial_nse_connection(self) -> None:
        self.session.close()
        self.session = requests.Session()
        url_oc = 'https://www.nseindia.com/option-chain'
        try:
            self.response = self.session.get(url_oc,
                                             headers=self.hdr,
                                             timeout=5)
        except:
            self.sh_window.after((10 * 1000), self.make_intial_nse_connection)
            return
        self.cookies = self.response.cookies
        if (self.stock_symb != ""):
            try:
                self.response = self.session.get(url,
                                                 headers=self.hdr,
                                                 timeout=5,
                                                 cookies=self.cookies)
            except:
                #self.make_intial_nse_connection()
                self.sh_window.after((10 * 1000),
                                     self.make_intial_nse_connection)
                return

    def refresh_data(self) -> None:
        self.col_time = datetime.now().strftime("%H:%M:%S")
        self.prev_time = time.time()

        if (self.sh_frame):
            self.sh_frame.destroy()
        self.sh_frame: Frame = Frame(self.sh_window, height=2)
        self.sh_frame.rowconfigure(0, weight=1)
        self.sh_frame.columnconfigure(0, weight=1)
        self.sh_frame.pack(anchor=N, fill="x", expand=False)

        if (self.stock_frame):
            self.stock_frame.destroy()
        self.stock_frame: Frame = Frame(self.sh_window)
        self.stock_frame.rowconfigure(3, weight=1)
        self.stock_frame.columnconfigure(0, weight=1)
        self.stock_frame.pack(anchor=N, fill="both", expand=True)

        if (self.check_index_var.get()):
            self.SYMBS = self.indices
            self.index_call = True

            if (self.plot_only):
                self.get_data_plot_only()
            else:
                self.set_sheet(self.sh_frame)
                self.sheet_formatting()
            self.draw_plots()

        if (self.check_stocks_var.get()):
            self.SYMBS = self.stock_symbs
            #selected_symbs = []
            #for i in range(len(self.stock_check_var)):
            #    if(self.stock_check_var[i].get()):
            #        selected_symbs.append(self.stock_check[i].text)
            ##self.SYMBS.extend(selected_symbs)
            self.index_call = False
            self.set_sheet(self.stock_frame)
            self.sheet_formatting()

    def get_data_plot_only(self):
        self.NB_DF: List[pd.Dataframe] = []
        df, dict_dfs = self.append_df_with_OC()
        for key in dict_dfs.keys():
            self.NB_DF.append(pd.concat([df, dict_dfs[key]], axis=1))

    def set_sheet(self, my_frame: Frame) -> None:
        self.NB: Notebook = Notebook(my_frame)
        self.NB.pack(anchor=N, fill="both", expand=True)
        self.NBF: List[Frame] = []
        self.NBS: List[tksheet.Sheet] = []
        self.NB_DF: List[pd.Dataframe] = []

        df, dict_dfs = self.append_df_with_OC()
        for key in dict_dfs.keys():
            self.NBF.append(Frame(self.NB))
            self.NB_DF.append(pd.concat([df, dict_dfs[key]], axis=1))
            self.NB.add(self.NBF[-1], text=key)
            sh = tksheet.Sheet(self.NBF[-1],
                               column_width=80,
                               align="center",
                               headers=list(self.NB_DF[-1].columns),
                               header_font=("TkDefaultFont", 10, "bold"),
                               empty_horizontal=0,
                               empty_vertical=20,
                               header_height=35)
            sh.enable_bindings(
                ("toggle_select", "drag_select", "column_select", "row_select",
                 "column_width_resize", "arrowkeys", "right_click_popup_menu",
                 "rc_select", "copy", "select_all"))
            sh.pack(anchor=W, fill="both", expand=True)
            self.NBS.append(sh)

    def set_expiry_date(self, event) -> None:
        self.expiry_date = self.date_combo_box.get()

    def set_ref_intvl(self, event) -> None:
        self.interval = float(self.ref_intvl_cbox.get())

    def sheet_formatting(self) -> None:
        num_std_cols = 3  #Symb & ATM
        for i in range(len(self.NBS)):
            curr_sh = self.NBS[i]
            num_cols = len(self.NB_DF[i].columns)
            for col in enumerate(self.NB_DF[i].columns):
                curr_sh.set_column_data(col[0], values=self.NB_DF[i][col[1]])
            if (not self.first_run):
                for i in range(curr_sh.get_total_rows()):
                    for j in range(num_std_cols, num_cols - 2, 1):
                        diff = float(curr_sh.get_cell_data(i, j)) - float(
                            curr_sh.get_cell_data(i, j + 1))
                        perc_change = 1.
                        if (float(curr_sh.get_cell_data(i, j - 1)) > 0.0):
                            perc_change = diff * 100 / float(
                                curr_sh.get_cell_data(i, j - 1))
                        if (diff < 0.):
                            curr_sh.highlight_cells(row=i,
                                                    column=j,
                                                    bg=self.red,
                                                    fg='white')
                        elif diff == 0.0:
                            curr_sh.highlight_cells(row=i,
                                                    column=j,
                                                    bg='white',
                                                    fg='black')
                        else:
                            curr_sh.highlight_cells(row=i,
                                                    column=j,
                                                    bg='blue',
                                                    fg='white')
                        if perc_change > 40.:
                            curr_sh.highlight_cells(row=i,
                                                    column=j,
                                                    bg='green',
                                                    fg='white')
            curr_sh.set_currently_selected(0, num_cols - 1)
            curr_sh.refresh()

    def setup_main_window(self, window) -> None:
        self.sh_window: Tk = window
        self.sh_window.title('Option chain analyzer')
        window_width: int = self.sh_window.winfo_reqwidth()
        window_height: int = self.sh_window.winfo_reqheight()
        position_right: int = int(self.sh_window.winfo_screenwidth() / 2 -
                                  window_width / 2)
        position_down: int = int(self.sh_window.winfo_screenheight() / 2 -
                                 window_height / 2)
        #self.sh_window.geometry("1200x600+{}+{}".format(position_right, position_down))
        self.sh_window.geometry("1200x600+300+200")
        #self.sh_window.geometry("+{}+{}".format(position_right, position_down))

        self.sh_frame: Frame = Frame(self.sh_window)
        self.stock_frame: Frame = Frame(self.sh_window)

        top_frame: Frame = Frame(self.sh_window)
        top_frame.rowconfigure(0, weight=1)
        top_frame.columnconfigure(0, weight=1)
        top_frame.pack(anchor=S, expand=False, side=TOP)

        row_idx: int = 0

        self.index_call = True
        self.get_expiry_dates()
        date_var: StringVar = StringVar()
        date_var.set(" ")
        lbl_exp_date: Label = Label(top_frame,
                                    text='Index Expiry',
                                    justify=LEFT,
                                    font=("TkDefaultFont", 10, "bold"))
        #lbl_exp_date.grid(row=row_idx,column=0,sticky=N+S+W)
        lbl_exp_date.pack(anchor=N, expand=False, side=LEFT)
        self.date_combo_box = Combobox(top_frame,
                                       width=10,
                                       textvariable=date_var)
        self.date_combo_box.pack(anchor=N, expand=False, side=LEFT)
        #self.date_combo_box.grid(row=row_idx, column=1, sticky=N + S + E + W)
        self.date_combo_box.bind('<<ComboboxSelected>>', self.set_expiry_date)
        self.date_combo_box['values'] = tuple(self.expiry_dates)
        self.date_combo_box.set(self.expiry_dates[0])
        self.date_combo_box.configure(state='readonly')
        row_idx += 1

        self.index_call = False
        self.get_expiry_dates()
        date_var_stock: StringVar = StringVar()
        date_var_stock.set(" ")
        lbl_exp_date_stock: Label = Label(top_frame,
                                          text='Stock Expiry',
                                          justify=LEFT,
                                          font=("TkDefaultFont", 10, "bold"))
        #lbl_exp_date_stock.grid(row=row_idx,column=0,sticky=N+S+W)
        lbl_exp_date_stock.pack(anchor=N, expand=False, side=LEFT)
        self.date_combo_box_stock = Combobox(top_frame,
                                             width=10,
                                             textvariable=date_var_stock)
        self.date_combo_box_stock.pack(anchor=N, expand=False, side=LEFT)
        #self.date_combo_box_stock.grid(row=row_idx, column=1, sticky=N + S + E + W)
        self.date_combo_box_stock.bind('<<ComboboxSelected>>',
                                       self.set_expiry_date)
        self.date_combo_box_stock['values'] = tuple(self.expiry_dates)
        self.date_combo_box_stock.set(self.expiry_dates[0])
        self.date_combo_box_stock.configure(state='readonly')
        row_idx += 1

        self.check_stocks_var = IntVar()
        self.check_stocks = Checkbutton(top_frame, text = "Stocks", variable = self.check_stocks_var, \
                                    onvalue = 1, offvalue = 0, width = 10)
        #self.check_stocks.grid(row=row_idx, column=1, sticky=N + S + E + W)
        self.check_stocks.pack(anchor=N, expand=False, side=LEFT)
        self.check_stocks_var.set(0)
        row_idx += 1

        self.check_index_var = IntVar()
        self.check_index = Checkbutton(top_frame, text = "Index", variable = self.check_index_var, \
                                    onvalue = 1, offvalue = 0, width = 10)
        #self.check_index.grid(row=row_idx, column=1, sticky=N + S + E + W)
        self.check_index.pack(anchor=N, expand=False, side=LEFT)
        self.check_index_var.set(1)
        row_idx += 1

        ref_intvl: Stringvar = StringVar()
        ref_intvl.set(" ")
        lbl_refresh_interval: Label = Label(top_frame,
                                            text='Interval (min)',
                                            justify=LEFT,
                                            font=("TkDefaultFont", 10, "bold"))
        #lbl_refresh_interval.grid(row=row_idx,column=0,sticky=N+S+W)
        lbl_refresh_interval.pack(anchor=N, expand=False, side=LEFT)
        self.ref_intvl_cbox: Combobox = Combobox(top_frame,
                                                 width=10,
                                                 textvariable=ref_intvl)
        #self.ref_intvl_cbox.grid(row=row_idx, column=1, sticky=N + S + E + W)
        self.ref_intvl_cbox.pack(anchor=N, expand=False, side=LEFT)
        self.ref_intvl_cbox.bind('<<ComboboxSelected>>', self.set_ref_intvl)
        self.ref_intvl_cbox['values'] = tuple(range(10, 600, 20))
        self.ref_intvl_cbox.configure(state='readonly')
        row_idx += 1

        self.start_button: Button = Button(top_frame,
                                           text='START',
                                           command=self.main_recursive,
                                           width=10)
        #self.start_button.grid(row=row_idx, column=1, sticky=N + S + E + W)
        self.start_button.pack(anchor=N, expand=True, side=TOP)
        row_idx += 1

        canvas = tk.Canvas(self.sh_window)
        scroll_y = tk.Scrollbar(self.sh_window,
                                orient="vertical",
                                command=canvas.yview)

        bot_frame: Frame = Frame(canvas)
        #bot_frame = ScrollFrame(bot_frame)
        #bot_frame.rowconfigure(0, weight=1)
        #bot_frame.columnconfigure(0, weight=1)
        #bot_frame.grid(row=row_idx,column=0,sticky=N+S+W)
        #bot_frame = ScrollableFrame(self.sh_window)
        #bot_frame = ScrollFrame(self.sh_window)
        #bot_frame.rowconfigure(1, weight=1)
        #bot_frame.columnconfigure(0, weight=1)
        #bot_frame.pack(anchor=N, expand=False, side=LEFT)

        #bot_frame: Listbox = Listbox(self.sh_window)
        #bot_frame.pack(side=LEFT,fill='both')
        #vscrollbar = Scrollbar(self.sh_window)
        #vscrollbar.pack(side = LEFT, fill = 'both')
        #for i in range(10000):
        #    bot_frame.insert(END,i)

        self.stock_check_var: List[IntVar] = []
        self.stock_check: List[Checkbutton] = []
        int_col = 0
        tmp_row_idx = row_idx
        for stk in enumerate(self.stock_symbs):
            #if(int(stk[0])>30 and int_col==0):
            #    int_col = 1
            #    row_idx = tmp_row_idx
            self.stock_check_var.append(IntVar())
            cb = Checkbutton(bot_frame, text = stk[1], variable = self.stock_check_var[-1], \
                                    onvalue = 1, offvalue = 0, width =12)
            cb.pack()
            if (stk[1] in self.popular_stocks):
                self.stock_check_var[-1].set(1)
            else:
                self.stock_check_var[-1].set(0)
            self.stock_check.append(cb)
            row_idx += 1
        canvas.create_window(0, 0, anchor='nw', window=bot_frame)
        canvas.update_idletasks()
        canvas.configure(scrollregion=canvas.bbox('all'),
                         yscrollcommand=scroll_y.set)

        canvas.pack(fill='y', expand=False, side=LEFT)
        scroll_y.pack(fill='y', side=LEFT, expand=False)

        self.sh_window.mainloop()

    def get_stock_symbols(self) -> None:
        url = 'https://www.nseindia.com/api/master-quote'
        url_oc = 'https://www.nseindia.com/'
        response = self.session.get(url_oc, headers=self.hdr, timeout=5)
        ck = response.cookies
        response = self.session.get(url,
                                    headers=self.hdr,
                                    timeout=5,
                                    cookies=ck)
        json_data = response.json()
        self.stock_symbs = list(json_data)

    def get_option_chain_data(self) -> None:
        if self.index_call:
            self.url = 'https://www.nseindia.com/api/option-chain-indices?symbol=' + self.stock_symb
        else:
            self.url = 'https://www.nseindia.com/api/option-chain-equities?symbol=' + self.stock_symb
        try:
            self.response = self.session.get(self.url,
                                             headers=self.hdr,
                                             timeout=5,
                                             cookies=self.cookies)
            if self.response.status_code == 401:
                self.session.close()
                self.session = requests.Session()
                request = self.session.get(self.url_oc,
                                           headers=self.hdr,
                                           timeout=5)
                self.cookies = dict(request.cookies)
                self.response = self.session.get(self.url,
                                                 headers=self.hdr,
                                                 timeout=5,
                                                 cookies=self.cookies)
                print("reset cookies")
        except Exception as err:
            print(self.response)
            print(err, "5")
            #self.make_intial_nse_connection()
            self.sh_window.after((10 * 1000), self.main_recursive)
            return
            #try:
            #    self.session.close()
            #    self.session = requests.Session()
            #    request = self.session.get(self.url_oc, headers=self.hdr, timeout=5)
            #    self.cookies = dict(request.cookies)
            #    self.response = self.session.get(self.url,headers=self.hdr,timeout=5,cookies=self.cookies)
            #    print("reset cookies")
            #except Exception as err:
            #    print(request)
            #    print(response)
            #    print(err, "5")
            #    return

    def get_expiry_dates(self) -> Tuple:
        if self.index_call:
            self.stock_symb = 'NIFTY'
        else:
            self.stock_symb = 'INFY'
        self.get_option_chain_data()
        json_data = self.response.json()
        self.expiry_dates: List = []
        self.expiry_dates = json_data['records']['expiryDates']

    def draw_plots(self):
        symbb = "BANKNIFTY"
        self.plot_keys = ['PCR OTM', 'LTP']
        mrk_type = ['-ro', '--gs']
        #self.plot_keys = ['PCR OTM']
        idx: Int = -1
        plt.clf()
        maxx = 0.0
        minn = 10000.0
        for key in enumerate(self.plot_keys):
            idx = -1
            try:
                idx = self.nb_names.index(key[1])
            except:
                pass
            if (idx != -1):
                xx = self.NB_DF[idx].loc[self.NB_DF[idx]['SYMB'] == symbb]
                y_data = (xx[xx.columns[3:]].values)
                y_dat = (y_data[0].tolist())
                y_dat.reverse()
                x_data = range(len(y_dat))
                if (minn > min(y_dat)):
                    minn = min(y_dat)
                if (maxx < max(y_dat)):
                    maxx = max(y_dat)
                if self.index_call:
                    #self.graph_index.set_ydata(y_dat)
                    #self.graph_index.set_xdata(x_data)
                    plt.plot(x_data,
                             y_dat,
                             mrk_type[key[0]],
                             label=key[1],
                             markersize=1)
                    plt.legend()
                    plt.xlim([0, 1.1 * len(y_dat)])
        plt.ylim([.9 * minn, 1.1 * maxx])
        plt.pause(.0001)
        plt.show(block=False)
        strr = datetime.today().strftime('%Y-%m-%d')
        plt.title(symbb + "--->" + strr)
        plt.savefig(strr + '.pdf', dpi=300)

    def append_df_with_OC(self):
        self.diff_otm: List = []
        self.atms: List = []
        self.pcr: List = []
        self.pcr_otm: List = []
        self.pcr_far_otm: List = []
        self.live_prices: List[float] = []
        self.DIFF_otm: List[float] = []
        self.call_sum_otm: List[float] = []
        self.put_sum_otm: List[float] = []
        self.call_sum_far_otm: List[float] = []
        self.put_sum_far_otm: List[float] = []
        for stk in enumerate(self.SYMBS):
            self.stock_symb = stk[1]
            self.get_option_chain_data()
            if self.response is not None:
                try:
                    json_data = self.response.json()
                except:
                    json_data = {}
                    return
            #print(stk)
            #quote = nse.get_quote(stk)
            #print(quote['data'][0]['lastPrice'])
            #print(json_data['records']['data'])
            #try:
            #    self.live_prices.append(float(quote['data'][0]['lastPrice'].replace(',','')))
            #except:
            #    self.live_prices.append('null')
            if self.index_call:
                match_date = self.date_combo_box.get()
            else:
                match_date = self.date_combo_box_stock.get()
            my_atm: float = 0.0
            strike_prices: List[float] = [data['strikePrice'] for data in json_data['records']['data'] \
                                       if (str(data['expiryDate']).lower() == str(match_date).lower())]
            ce_values: List[dict] = [data['CE'] for data in json_data['records']['data'] \
                        if "CE" in data and (str(data['expiryDate'].lower()) == str(match_date.lower()))]
            pe_values: List[dict] = [data['PE'] for data in json_data['records']['data'] \
                        if "PE" in data and (str(data['expiryDate'].lower()) == str(match_date.lower()))]

            ce_data: pd.DataFrame = pd.DataFrame(ce_values)
            pe_data: pd.DataFrame = pd.DataFrame(pe_values)

            #print(list(ce_data.columns))
            curr_price = ce_data['underlyingValue'][0]
            if (self.first_run):
                self.first_run_live_price.append(curr_price)
            try:
                diff = [abs(x - curr_price) for x in strike_prices]
                min_pos = diff.index(min(diff))
                my_atm = strike_prices[min_pos]
                self.atms.append(my_atm)
            except:
                self.atms.append('null')

            self.live_prices.append(curr_price /
                                    self.first_run_live_price[stk[0]])
            ce_data_otm: pd.DataFrame = ce_data[min_pos:min_pos + 4]
            pe_data_otm: pd.DataFrame = pe_data[min_pos - 2:min_pos + 2]

            ce_data_far_otm: pd.DataFrame = ce_data[min_pos + 4:min_pos + 8]
            pe_data_far_otm: pd.DataFrame = pe_data[min_pos - 7:min_pos - 3]

            call_sum_otm = ce_data_otm['openInterest'].sum()
            put_sum_otm = pe_data_otm['openInterest'].sum()
            diff_otm = (ce_data_otm['changeinOpenInterest'].sum() -
                        pe_data_otm['changeinOpenInterest'].sum()
                        ) / ce_data_otm['changeinOpenInterest'].sum()

            if (call_sum_otm == 0.):
                call_sum_otm = 0.001
            if (put_sum_otm == 0.):
                put_sum_otm = 0.001

            call_sum_far_otm = ce_data_far_otm['openInterest'].sum()
            put_sum_far_otm = pe_data_far_otm['openInterest'].sum()

            if (call_sum_far_otm == 0.):
                call_sum_far_otm = 0.001
            if (put_sum_far_otm == 0.):
                put_sum_far_otm = 0.001

            diff_far_otm = call_sum_far_otm - put_sum_far_otm

            if (ce_data['openInterest'].sum() != 0):
                pcr_ratio = float(pe_data['openInterest'].sum()) / float(
                    ce_data['openInterest'].sum())
            else:
                pcr_ratio = float(pe_data['openInterest'].sum()) / .001
            self.pcr.append(pcr_ratio)
            self.call_sum_otm.append(call_sum_otm)
            self.put_sum_otm.append(put_sum_otm)
            self.call_sum_far_otm.append(call_sum_far_otm)
            self.put_sum_far_otm.append(put_sum_far_otm)
            self.pcr_otm.append(put_sum_otm / call_sum_otm)
            self.pcr_far_otm.append(put_sum_far_otm / call_sum_far_otm)
            self.diff_otm.append(diff_otm)

        self.live_price_normalized = list(
            map(mul, self.pcr_otm, self.live_prices))
        #self.live_price_normalized = self.live_prices
        if (self.index_call):
            self.df_INDEX['SYMB'] = self.SYMBS
            self.df_INDEX['ATM'] = self.atms
            self.df_INDEX['CONST PRICE'] = self.first_run_live_price
            self.dict_dfs_INDEX['PCR'].insert(0, self.col_time, self.pcr)
            self.dict_dfs_INDEX['PCR'][self.col_time] = self.dict_dfs_INDEX[
                'PCR'][self.col_time].round(3)
            self.dict_dfs_INDEX['CE-OTM'].insert(0, self.col_time,
                                                 self.call_sum_otm)
            self.dict_dfs_INDEX['PE-OTM'].insert(0, self.col_time,
                                                 self.put_sum_otm)
            self.dict_dfs_INDEX['CE-FAR_OTM'].insert(0, self.col_time,
                                                     self.call_sum_far_otm)
            self.dict_dfs_INDEX['PE-FAR_OTM'].insert(0, self.col_time,
                                                     self.put_sum_far_otm)
            self.dict_dfs_INDEX['LTP'].insert(0, self.col_time,
                                              self.live_price_normalized)
            self.dict_dfs_INDEX['LTP'][self.col_time] = self.dict_dfs_INDEX[
                'LTP'][self.col_time].round(3)
            self.dict_dfs_INDEX['PCR OTM'].insert(0, self.col_time,
                                                  self.pcr_otm)
            self.dict_dfs_INDEX['PCR OTM'][
                self.col_time] = self.dict_dfs_INDEX['PCR OTM'][
                    self.col_time].round(3)
            self.dict_dfs_INDEX['PCR FAR OTM'].insert(0, self.col_time,
                                                      self.pcr_far_otm)
            self.dict_dfs_INDEX['PCR FAR OTM'][
                self.col_time] = self.dict_dfs_INDEX['PCR FAR OTM'][
                    self.col_time].round(3)
            self.dict_dfs_INDEX['DIFF OTM'].insert(0, self.col_time,
                                                   self.diff_otm)
            self.dict_dfs_INDEX['DIFF OTM'][
                self.col_time] = self.dict_dfs_INDEX['DIFF OTM'][
                    self.col_time].round(3)
            self.dict_dfs_INDEX['DIFF OTM'][
                self.col_time] = self.dict_dfs_INDEX['DIFF OTM'][
                    self.col_time].round(3)

            return self.df_INDEX, self.dict_dfs_INDEX
        else:
            self.df_STOCK['SYMB'] = self.SYMBS
            self.df_STOCK['ATM'] = self.atms
            self.df_STOCK['CONST PRICE'] = self.first_run_live_price
            self.dict_dfs_STOCK['PCR'].insert(0, self.col_time, self.pcr)
            self.dict_dfs_STOCK['PCR'][self.col_time] = self.dict_dfs_STOCK[
                'PCR'][self.col_time].round(3)
            self.dict_dfs_STOCK['CE-OTM'].insert(0, self.col_time,
                                                 self.call_sum_otm)
            self.dict_dfs_STOCK['PE-OTM'].insert(0, self.col_time,
                                                 self.put_sum_otm)
            self.dict_dfs_STOCK['CE-FAR_OTM'].insert(0, self.col_time,
                                                     self.call_sum_far_otm)
            self.dict_dfs_STOCK['PE-FAR_OTM'].insert(0, self.col_time,
                                                     self.put_sum_far_otm)
            self.dict_dfs_STOCK['LTP'].insert(0, self.col_time,
                                              self.live_price_normalized)
            self.dict_dfs_STOCK['LTP'][self.col_time] = self.dict_dfs_INDEX[
                'LTP'][self.col_time].round(3)
            self.dict_dfs_STOCK['PCR OTM'].insert(0, self.col_time,
                                                  self.pcr_otm)
            self.dict_dfs_STOCK['PCR OTM'][
                self.col_time] = self.dict_dfs_STOCK['PCR OTM'][
                    self.col_time].round(3)
            self.dict_dfs_STOCK['PCR FAR OTM'].insert(0, self.col_time,
                                                      self.pcr_far_otm)
            self.dict_dfs_STOCK['PCR FAR OTM'][
                self.col_time] = self.dict_dfs_STOCK['PCR FAR OTM'][
                    self.col_time].round(3)
            self.dict_dfs_STOCK['DIFF OTM'].insert(0, self.col_time,
                                                   self.diff_otm)
            self.dict_dfs_STOCK['DIFF OTM'][
                self.col_time] = self.dict_dfs_STOCK['DIFF OTM'][
                    self.col_time].round(3)
            return self.df_STOCK, self.dict_dfs_STOCK
Esempio n. 29
0
class Login:

    def __init__(self, master):
        self.master = master
        master.title("Login")
        master.geometry("600x240")
        master.configure(background='green')
        

        #
        v = []
      
       
        connection = psycopg2.connect(user="******",password="******", host="127.0.0.1", port="5432",database="RandR")
        curs = connection.cursor()

        curs.execute("select * from Listar_Restaurantes")
        resta = curs.fetchall()  
        i=0
        for item in resta :
         v.append(item[0])
        
         i+1
        curs.close()
        connection.close()

        #
        self.labelR = Label(master, text="Restaurante" , height = 2, width = 600)
        self.labelR.pack()
        self.labelR.configure(  background='green')

        
        self.combo = Combobox(master,values=v ,  width = 600)
        self.combo.pack()
        self.combo.bind('<<ComboboxSelected>>', self.combo.get())

        self.other_button = Button(master, text="refresh funcionarios", command=lambda: self.refresh(self.combo.get()), height = 1, width = 100)
        self.other_button.pack()


        self.comboid = Combobox(master,  width = 600)
        self.comboid.pack()
        self.comboid.bind('<<ComboboxSelected>>', self.combo.get())

        
        self.labelR = Label(master, text="Password" , height = 2, width = 600)
        self.labelR.pack()
        self.labelR.configure(  background='green')
        
        
        self.passw = Entry(master,  show='*' ,  width = 600)
        self.passw.pack()

        self.btnlogin = Button(master, text="Login", command=lambda: self.Login(self.comboid.get(),self.passw.get()), height = 1, width = 100)
        self.btnlogin.pack()

        

    def refresh(self ,k):
        connection = psycopg2.connect(user="******",password="******", host="127.0.0.1", port="5432",database="RandR")   
        curs = connection.cursor()
        a = []
        curs.execute("select * from MostrarFuncionarios('"+k+"')")
        resta = curs.fetchall()  
        i=0
        for item in resta :
         a.append(item[0])
        
         i+1
        curs.close()
        connection.close()
        self.comboid.configure(value=a)

    def Login(self ,k, passs):
        connection = psycopg2.connect(user="******",password="******", host="127.0.0.1", port="5432",database="RandR")   
        curs = connection.cursor()
        resta = 0
        curs.execute("select  testa_login ('"+k+"', '"+str(passs)+"')")
        resta = curs.fetchone()  
        print(str(resta))
        if str(resta) == "(1,)" : 
            self.master.destroy() 
            self.master = tk.Tk() 
            self.app = Index_Ger_V.IndexGer(self.master) 
            self.master.mainloop()
        else :
         self.labels = Label( text= "Erro no login" , height = 2, width = 600)
         self.labels.pack()
         self.labels.configure(  background='green')
            
        
        curs.close()
        connection.close()
class Booking:
    """Booking class: Booking window.
        - Choose where you want to watch the movie ["London", "Canary Wharf", "The O2 Arena", "Waterloo"]
        - You choose which movie to watch
        - Book seats
        - See the image of the movie
        - See movie info
    "window": it is a Tk() object (tkinter object) that is passed around so we do not need to create it every single
    time
    old_window: reference to the tk() object (Login window)
    username: User's username -_-
    """
    def __init__(self, window, old_window, username):
        self.username = username
        self.old_window = old_window

        self.window = window
        self.window.title("Booking")
        self.window.theatre = PhotoImage(file="image/theatre.gif")

        # Customers Options
        self.home = Button(self.window,
                           text="Home",
                           font=("Arial", 30),
                           bd=0,
                           bg="#CBFBB5",
                           command=self.goto_home)
        self.home.grid(row=0, column=0, padx=(15, 10))
        self.booking = Button(self.window,
                              text=" Booking ",
                              font=("Arial", 30),
                              bd=0,
                              bg="#CA65F5")
        self.booking.grid(row=0, column=1, padx=(0, 10))
        self.booked = Button(self.window,
                             text=" Booked ",
                             font=("Arial", 30),
                             bd=0,
                             bg="#1F8BF3",
                             command=self.goto_booked)
        self.booked.grid(row=0, column=2, padx=(0, 10))
        self.user = Button(self.window,
                           text=" User ",
                           font=("Comic Sans", 30),
                           bd=0,
                           bg="#BDC3C7",
                           command=self.goto_user)
        self.user.grid(row=0, column=3, padx=(0, 10))
        self.sign_out = Button(self.window,
                               text=" Sign Out ",
                               font=("Comic Sans", 30),
                               bd=0,
                               bg="#FF916E",
                               command=self.goto_sign_out)
        self.sign_out.grid(row=0, column=4, padx=(0, 10))

        # Choose the location
        global cinema_location

        self.choose_location_display = LabelFrame(
            self.window,
            text="Where will you watch it?",
            bg="#414141",
            fg="white",
            width=100)
        self.choose_location_display.grid(row=1, column=0, pady=(20, 4))
        self.location_option = Combobox(self.choose_location_display,
                                        state="readonly")
        self.location_option["values"] = cinema_location
        self.location_option.current(0)
        self.location_option.grid()
        self.enter_location_btn = Button(self.window,
                                         text="Enter Location",
                                         command=self.enter_location,
                                         bd=2,
                                         bg="#CAE4F8")
        self.enter_location_btn.grid(row=3, column=0, pady=7)

        # Choose Movie
        self.choose_movie_display = LabelFrame(self.window,
                                               text="Choose movie:",
                                               bg="#414141",
                                               fg="white",
                                               width=100)
        self.movie_option = Combobox(self.choose_movie_display,
                                     state="readonly")
        self.enter_movie_btn = Button(self.window,
                                      text="Enter Movie",
                                      command=self.enter_name,
                                      bd=2,
                                      bg="#CAE4F8")

        # Choose Date
        self.choose_date_display = LabelFrame(self.window,
                                              text="Choose date:",
                                              bg="#414141",
                                              fg="white")
        self.date_option = Combobox(self.choose_date_display, state="readonly")
        self.enter_date_btn = Button(self.window,
                                     text="Enter Date",
                                     command=self.enter_date,
                                     bg="#CAE4F8")
        # Choose Time
        self.choose_time_display = LabelFrame(self.window,
                                              text="Choose time:",
                                              bg="#414141",
                                              fg="white")
        self.time_option = Combobox(self.choose_time_display, state="readonly")
        self.enter_time_btn = Button(self.window,
                                     text="Enter Time",
                                     command=self.enter_time,
                                     bg="#CAE4F8")
        # Book Seats
        self.book_seats_btn = Button(self.window,
                                     text="Book Seats",
                                     font=("Arial", 15),
                                     command=self.book_seats,
                                     width=10,
                                     height=3,
                                     bg="#C9A594",
                                     fg="#3F3F3F")
        # No Movie available display
        self.no_movie = Label(
            self.window,
            text="Sorry, there are no movies playing.\nPlease come back later.",
            font=("Arial", 30))

        self.movie_pic = Label(self.window,
                               bg="silver",
                               bd=10,
                               image=self.window.theatre)
        self.movie_pic.place(x=105, y=220)

        self.movie_info_btn = Button(self.window,
                                     text="Movie Info",
                                     font=("Arial", 15),
                                     command=self.movie_info)

        # All the widget I created, I store it here. So i can easily destroy them later.
        self.widgets = [
            self.home, self.booked, self.booking, self.user, self.sign_out,
            self.choose_movie_display, self.movie_option, self.enter_movie_btn,
            self.movie_pic, self.choose_date_display, self.date_option,
            self.enter_date_btn, self.choose_time_display, self.time_option,
            self.enter_time_btn, self.book_seats_btn, self.movie_info_btn,
            self.no_movie, self.location_option, self.choose_location_display,
            self.enter_location_btn
        ]

    def movie_info(self):
        self.window.withdraw()
        MovieInfo(movie_name=self.movie_option.get(),
                  old_window=self.window,
                  location=self.location_option.get())

    def destroy_all(self):
        """ destroy_all() Destroys all the widget (Clears the window, so I can use the same window for adding new
         widgets) """
        [widget.destroy() for widget in self.widgets]

    def goto_home(self):
        """Takes you to the Home window"""
        self.destroy_all()
        self.window.Home(window=self.window,
                         old_window=self.old_window,
                         username=self.username)

    def goto_booked(self):
        """Takes you to the Booked window"""
        self.destroy_all()
        self.window.Booked(window=self.window,
                           old_window=self.old_window,
                           username=self.username)

    def goto_user(self):
        """Takes you to the user window"""
        self.destroy_all()
        self.window.User(window=self.window,
                         old_window=self.old_window,
                         username=self.username,
                         customer=True)

    def goto_sign_out(self):
        """Signs out the user and takes the user back to the Login menu. It also logs the date and the time when the
        user signs out"""

        logging.basicConfig(level=logging.INFO, filename="logging.log")
        logging.info(
            f"Username: {self.username} Sign-out {datetime.datetime.now()}")
        self.window.destroy()
        self.old_window.deiconify()

    def enter_location(self):
        """enter_location() obtains the location where the user want to watch the movie at.
        Get the path to the database for the cinema branch.
        Then gives the user the list of movie available in that cinema at that location
        Change the enter location button to change location
        Disable the location option"""

        self.location_option.configure(state="disabled")
        self.enter_location_btn.configure(text="Change Location",
                                          command=self.change_location)
        global cinemaDB_path
        location = self.location_option.get()
        cinemaDB_path = os.path.abspath(
            os.path.join(os.path.dirname(__file__), "..", f"{location}.db"))

        self.movie_name_dict = get_movie_names()  # Obtain the movie name

        # If no names
        if len(self.movie_name_dict) == 0:
            messagebox.showwarning(
                "Sorry",
                "Sorry, there are not any movie playing in this cinema hall.")

        # Checks if there is any movie playing
        if self.movie_name_dict:
            self.choose_movie_display.grid(row=1, column=1, pady=(20, 4))
            self.movie_option["values"] = [
                name for name in self.movie_name_dict.keys()
            ]
            self.movie_option.current(0)
            self.movie_option.grid()
            self.movie_option.bind(
                "<<ComboboxSelected>>", lambda e: self.movie_pic.configure(
                    image=self.window.booking_img[self.movie_option.get()]))
            self.enter_movie_btn.grid(row=3, column=1, pady=7)

            # Getting the images of the movie
            self.window.booking_img = {}
            for name in self.movie_name_dict.keys():
                if os.path.exists(f"./image/Booking/{name}.gif"):
                    img = PhotoImage(file=f"./image/Booking/{name}.gif")
                else:
                    img = PhotoImage(file="./image/Error_Booking.gif")
                self.window.booking_img[name] = img

            self.movie_pic.configure(
                image=self.window.booking_img[self.movie_option.get()])
            self.movie_info_btn.place(x=713, y=230)

        else:
            # If there is no movie in the database
            self.no_movie.place(x=200, y=250)

    def enter_name(self):
        """enter_name() select the movie and give a list of available time.
        Change the enter movie button to change movie
        Disable the movie option list
        """

        self.movie_option.configure(state="disabled")
        self.enter_movie_btn.configure(text="Change Movie",
                                       command=self.change_movie)

        date = get_dates(
            movie_id=self.movie_name_dict[self.movie_option.get()])
        if date:
            date.sort()
            self.choose_date_display.grid(row=1, column=2, pady=(20, 4))
            self.date_option["values"] = date
            self.date_option.current(0)
            self.date_option.grid()
            self.enter_date_btn.grid(row=3, column=2, pady=7)

    def enter_date(self):
        """enter_data() select the date and give a list of available time.
        Change the enter date button to change date
        Disable the date option list"""

        self.date_option.configure(state="disabled")
        self.enter_date_btn.configure(text="Change Date",
                                      command=self.change_date)
        self.choose_time_display.grid(row=1,
                                      column=2,
                                      pady=(20, 4),
                                      columnspan=3)
        time = get_times(
            movie_id=self.movie_name_dict[self.movie_option.get()],
            date=self.date_option.get())
        time.sort()
        self.time_option["values"] = time
        self.time_option.current(0)
        self.time_option.grid()
        self.enter_time_btn.grid(row=3, column=3, pady=7)

    def enter_time(self):
        """enter_date() selects the time, then book seats button appear
        Change the enter time to change time
        Disable the time option list"""

        self.time_option.configure(state="disable")
        self.enter_time_btn.configure(text="Change Time",
                                      command=self.change_time)
        self.book_seats_btn.grid(row=1, column=4, rowspan=3)

    def change_location(self):
        """change_location() will enable the the location option
        Change the change location to enter location
        Hide the choose movie, date and time option and book seats button"""

        self.location_option.configure(state="readonly")
        self.enter_location_btn.configure(text="Enter Location",
                                          command=self.enter_location)
        self.choose_movie_display.grid_remove()
        self.movie_option.grid_remove()
        self.enter_movie_btn.grid_remove()
        self.movie_info_btn.place_forget()
        self.movie_pic.configure(image=self.window.theatre)

        self.change_movie()

    def change_movie(self):
        """change_movie() will enable the the movie option
          Change the change movie to enter movie
          Hide the choose date and time option and book seats button"""

        self.movie_option.configure(state="readonly")
        self.enter_movie_btn.configure(text="Enter Movie",
                                       command=self.enter_name)
        self.choose_date_display.grid_remove()
        self.date_option.grid_remove()
        self.enter_date_btn.grid_remove()
        self.change_date()

    def change_date(self):
        """change_date() will enable the the date option
          Change the change date to enter date
          Hide the choose time option and book seats button"""

        self.enter_date_btn.configure(text="Enter Date",
                                      command=self.enter_date)
        self.choose_time_display.grid_remove()
        self.time_option.grid_remove()
        self.enter_time_btn.grid_remove()
        self.date_option.configure(state="readonly")
        self.enter_date_btn.configure(state="normal")
        self.change_time()

    def change_time(self):
        """change_time() will enable the the time option
          Change the change time to enter time
          Hide the seats button"""

        self.enter_time_btn.configure(text="Enter Time",
                                      command=self.enter_time)
        self.time_option.configure(state="readonly")
        self.book_seats_btn.grid_remove()

    def book_seats(self):
        """Takes the user to booking seats window"""
        global cinemaDB_path
        db = sqlite3.connect(cinemaDB_path)
        cursor = db.cursor()

        cursor.execute(
            f"""SELECT s.scheduleID FROM seating_plan sp, schedule s
            WHERE s.scheduleID = sp.scheduleID AND date= ? AND time= ?""",
            (self.date_option.get(), self.time_option.get()))
        scheduleID = cursor.fetchone()[0]
        db.close()

        self.window.withdraw()
        location = self.location_option.get()
        ChooseSeats(old_window=self.window,
                    username=self.username,
                    scheduleID=scheduleID,
                    location=location)