Exemple #1
2
class per():
    def __init__(self,data,y,v='план'):
        
        w=Toplevel()
        w.wm_title('Доп')
        w.columnconfigure(0,weight=1)
        w.rowconfigure(0,weight=1)
        
        years=sorted(data.keys())
        cols=data['2013']['degurs']  # ЗАГЛУШКА : список дежурных

        self.t=Treeview(w,columns=cols)
        for c in cols:
            self.t.heading(c,text=c)
            self.t.column(c,width=65,anchor='center')
        self.t.tag_configure('табель',background='green')
        self.t.tag_configure('ош',background='red')
        #self.t.tag_configure('табель',background='green')
        self.scrX=Scrollbar(w,orient='horizontal',command=self.t.xview)
        self.scrY=Scrollbar(w,orient='vertical',command=self.t.yview)
        self.t['xscrollcommand']=self.scrX.set
        self.t['yscrollcommand']=self.scrY.set
        self.t.grid(row=0,column=0,sticky=N+S+E+W)
        self.scrX.grid(row=1,column=0,sticky=E+W)
        self.scrY.grid(row=0,column=1,sticky=N+S)

        for y in years:
            x=self.t.insert('','end',text=y)
            eeY=[]
            for m in ['01','02','03','04','05','06','07','08','09','10','11','12']:
                d0=data[y]
                if m not in d0: continue
                d=d0[m]
                rez=dict()
                tag=''
                if v=='авто':
                    if 'табель' in d['degur']:
                        vv='табель'
                        tag=vv
                    else:
                        vv='план'
                elif v=='табель':
                    if 'табель' not in d['degur']:
                        vv='план'
                        tag='ош'
                    else:
                        vv=v
                        tag=vv
                else:
                    vv=v
                for j,s in d['degur'][vv].items():
                    rez[j]=analyse2(s,d)
                NUL=(0,0,0,0,0,0,0)
                ee=[rez.get(j,NUL)[0]-rez.get(j,NUL)[3]+rez.get(j,NUL)[4] for j in cols]
                eeY.append(ee)
                self.t.insert(x,'end',text=m,values=[x or '-' for x in ee],tag=tag)
            eeY=[sum(x) for x in zip(*eeY)]
            self.t.insert(x,'end',text='итого',values=eeY,tag='Y')
Exemple #2
0
class DataTree(Frame):
    def __init__(self, master):
        Frame.__init__(self, master, bg="black")
        scroll = Scrollbar(self)

        self.tree = Treeview(self, yscrollcommand=scroll.set)
        scroll.config(command=self.tree.yview)

        self.items = []

        self.tree.pack(side=LEFT, fill=BOTH, expand=1)
        scroll.pack(side=LEFT, fill=Y)

    def update(self, files):
        self.files = files

        # reversing, since removing a node with children removes the children as
        # well. there might be a cleaner way to do this by clearing each of the
        # file nodes, but that might add more burden to the garbage collector
        # down the line.
        for item in reversed(self.items):
            self.tree.delete(item)

        self.items = []

        for (i, datafile) in enumerate(self.files):
            self.add_file(datafile, i)

    def add_file(self, f, f_id):
        file_id = self.tree.insert("", "end", text=f.name)
        self.items.append(file_id)

        self.add_node(file_id, f.data, f_id)

    def add_node(self, p, node, f_id):
        if node.name != '':
            node_id = self.tree.insert(p, "end", text=node.name,
                                       values=(f_id, node.path))
            self.items.append(node_id)
        else:
            node_id = p

        if node.is_grp:
            for child in node.children:
                self.add_node(node_id, child, f_id)
def _maketree(parent_tree, wallpapers, conf):
    tree = Treeview(parent_tree)
    i = 0
    if conf['type'] == 'workspace':
        for workspace, wallpaper_files in wallpapers.items():
            i += 1
            index = str(i)
            tree.insert('', 'end', index, text=workspace)
            for j, wallpaper_file in enumerate(wallpaper_files):
                inner_index = index + '_' + str(j)
                tree.insert(index, 'end', inner_index, text=wallpaper_file)
    elif conf['type'] == 'desktop':
        for wallpaper_file in wallpapers:
            i += 1
            index = str(i)
            tree.insert('', 'end', index, text=wallpaper_file)
    tree.pack()
Exemple #4
0
class statistic_q():
    def __init__(self,data,y,v='план'):
        
        w=Toplevel()
        w.wm_title('Поквартальная статистика за {0} год ({1})'.format(y,v))
        w.columnconfigure(0,weight=1)
        w.rowconfigure(0,weight=1)
        
        cols=data[y]['degurs']  # ЗАГЛУШКА : список дежурных
        
        self.t=Treeview(w,columns=cols)
        self.t.column('#0',width=120)
        for c in cols:
            self.t.heading(c,text=c)
            self.t.column(c,width=65,anchor='center')
        self.t.tag_configure('табель',background='green')
        self.t.tag_configure('ош',background='red')
        self.scrX=Scrollbar(w,orient='horizontal',command=self.t.xview)
        self.scrY=Scrollbar(w,orient='vertical',command=self.t.yview)
        self.t['xscrollcommand']=self.scrX.set
        self.t['yscrollcommand']=self.scrY.set
        self.t.grid(row=0,column=0,sticky=N+S+E+W)
        self.scrX.grid(row=1,column=0,sticky=E+W)
        self.scrY.grid(row=0,column=1,sticky=N+S)
        r=self.t.insert('','end',text='рабочих')
        w=self.t.insert('','end',text='отработано')
        e=self.t.insert('','end',text='дополнительные')
        n=self.t.insert('','end',text='ночные')
        h=self.t.insert('','end',text='праздничные')
        x=self.t.insert('','end',text='xxx')
        rz_root=self.t.insert('','end',text='резерв')
        
        rez=dict()
        wwY=[]
        rrY=[]
        eeY=[]
        xxY=[]
        nnY=[]
        hhY=[]
        rzY=[]
        for mm in [1,2,3,4]:
            mmm=[str((mm-1)*3+x).zfill(2) for x in [1,2,3]]
            mmm=[x for x in mmm if x in data[y]]
            tag=''
            
            k=['табель' in data[y][m]['degur'] for m in mmm]
            #print(k)
            if v=='авто':
                if k==[True, True, True]:
                    vv='табель'
                    tag=vv
                else:
                    vv='план'
            elif v=='табель':
                if k!=[True, True, True]:
                    vv='план'
                    tag='ош'
                else:
                    vv=v
                    tag=vv
            else:
                vv=v
            
            ww=[]
            rr=[]
            ee=[]
            xx=[]
            nn=[]
            hh=[]
            rz=[]
            for m in mmm:
                d=data[y][m]
                for j in cols:
                    s=d['degur'][vv].get(j,'*ООООООООООООООООООООООООООООООО*')
                    rez[j]=analyse2(s,d)
                NUL=(0,0,0,0,0,0,0)
                ww.append([rez.get(j,NUL)[0] for j in cols])
                ee.append([rez.get(j,NUL)[0]-rez.get(j,NUL)[3] + \
                        rez.get(j,NUL)[4] for j in cols])
                xx.append([rez.get(j,NUL)[0]-rez.get(j,NUL)[3] for j in cols])
                rr.append([rez.get(j,NUL)[3]-rez.get(j,NUL)[4] for j in cols])
                nn.append([rez.get(j,NUL)[1] for j in cols])
                hh.append([rez.get(j,NUL)[2] for j in cols])
                rz.append([rez.get(j,NUL)[5] for j in cols])
            ww=[sum(x) for x in zip(*ww)]
            rr=[sum(x) for x in zip(*rr)]
            ee=[sum(x) for x in zip(*ee)]
            xx=[sum(x) for x in zip(*xx)]
            nn=[sum(x) for x in zip(*nn)]
            hh=[sum(x) for x in zip(*hh)]
            rz=[sum(x) for x in zip(*rz)]
            wwY.append(ww)
            rrY.append(rr)
            eeY.append(ee)
            xxY.append(xx)
            nnY.append(nn)
            hhY.append(hh)
            rzY.append(rz)
            self.t.insert(w,'end',text=mm,values=ww,tag=tag)
            self.t.insert(r,'end',text=mm,values=rr,tag=tag)
            self.t.insert(n,'end',text=mm,values=nn,tag=tag)
            self.t.insert(h,'end',text=mm,values=hh,tag=tag)
            self.t.insert(e,'end',text=mm,values=ee,tag=tag)
            self.t.insert(x,'end',text=mm,values=xx,tag=tag)
            self.t.insert(rz_root,'end',text=mm,values=rz,tag=tag)
        wwY=[sum(x) for x in zip(*wwY)]
        rrY=[sum(x) for x in zip(*rrY)]
        eeY=[sum(x) for x in zip(*eeY)]
        xxY=[sum(x) for x in zip(*xxY)]
        nnY=[sum(x) for x in zip(*nnY)]
        hhY=[sum(x) for x in zip(*hhY)]
        rzY=[sum(x) for x in zip(*rzY)]
        self.t.insert(w,'end',text='итого',values=wwY,tag='Y')
        self.t.insert(r,'end',text='итого',values=rrY,tag='Y')
        self.t.insert(n,'end',text='итого',values=nnY,tag='Y')
        self.t.insert(h,'end',text='итого',values=hhY,tag='Y')
        self.t.insert(e,'end',text='итого',values=eeY,tag='Y')
        self.t.insert(x,'end',text='итого',values=xxY,tag='Y')
        self.t.insert(rz_root,'end',text='итого',values=rzY,tag='Y')
Exemple #5
0
class Example(Frame):
    contadorQuerysTabs = 1
    def __init__(self):

        super().__init__()
        #self contador numero tab querys

        serverimage = tk.PhotoImage(file="images/server.png")


        #Creacion de ventana
        self.master.title("TytusDB")
        self.pack(fill=BOTH, expand=True)
        
        self.columnconfigure(1, weight=1)
        self.columnconfigure(3, pad=7)
        self.rowconfigure(3, weight=1)
        self.rowconfigure(5, pad=7)

        self.lbl = Label(self, text="TytusDB")
        self.lbl.grid(sticky=W, pady=4, padx=5)


        self.nb = CustomNotebook(self)
        self.fm = Frame(self.nb)
        self.fm.pack(fill=BOTH, expand=True)        
        self.fm.columnconfigure(1, weight=1)
        self.fm.columnconfigure(3, pad=7)
        self.fm.rowconfigure(3, weight=1)
        self.fm.rowconfigure(5, pad=7)
        self.nb.add(self.fm, text='Query '+str(self.contadorQuerysTabs))
        self.nb.grid(row=1, column=1, columnspan=2, rowspan=4,
                       padx=5, sticky=E + W + S + N)
        self.area = Text(self.fm)
        self.area.grid(row=1, column=1, columnspan=2, rowspan=4,
                       padx=5, sticky=E + W + S + N)

        # *************************** BARRA DE MENÚ ***************************
        menubar = Menu(self.master)
        self.master.filemenu = Menu(menubar, tearoff=0)
        self.master.filemenu.add_command(label="Nuevo")
        self.master.filemenu.add_command(label="Abrir",command=self.openFile)
        self.master.filemenu.add_command(label="Guardar", command=self.saveFile)
        self.master.filemenu.add_command(label="Salir", command=self.master.quit)
        self.master.helpmenu = Menu(menubar, tearoff=0)
        self.master.helpmenu.add_command(label="Documentación")
        self.master.helpmenu.add_command(label="Acerca de...")
        self.master.servermenu = Menu(menubar, tearoff=0)
        self.master.servermenu.add_command(label="Nueva conexión")
        self.master.servermenu.add_command(label="Quitar conexión")
        self.master.herramientasMenu = Menu(menubar, tearoff=0)
        self.master.herramientasMenu.add_command(label="Query Tool", command=self.addQueryTool)
        self.master.herramientasMenu.add_command(label="run", command=self.run)
        menubar.add_cascade(label="Archivo", menu=self.master.filemenu)
        menubar.add_cascade(label="Servidor", menu=self.master.servermenu)
        menubar.add_cascade(label="Herramientas", menu=self.master.herramientasMenu)
        menubar.add_cascade(label="Ayuda", menu=self.master.helpmenu)
        self.master.config(menu=menubar);
        # *********************************************************************
        
        # ******************************* ÁRBOL *******************************
        self.treeview = Treeview(self)    
        self.treeview.grid(row=1, column=0, columnspan=1, rowspan=4, padx=5, sticky=E + W + S + N);                       
        self.serverimage = tk.PhotoImage(file="images/server.png")
        self.databaseimage = tk.PhotoImage(file="images/database.png")
        self.tableimage = tk.PhotoImage(file="images/table.png")
        self.functionimage = tk.PhotoImage(file="images/function.png")
        self.usersimage = tk.PhotoImage(file="images/users.png")
        self.singleuserimage = tk.PhotoImage(file="images/single_user.png")
        self.viewimage = tk.PhotoImage(file="images/view.png")
        self.triggerimage = tk.PhotoImage(file="images/trigger.png")
        servers = self.treeview.insert("", tk.END, text=" Servidores", image=self.serverimage)
        srvr1 = self.treeview.insert(servers, tk.END, text=" server_vd2020", image=self.serverimage)
        dbs = self.treeview.insert(srvr1, tk.END, text=" Databases", image=self.databaseimage)
        dvdrental = self.treeview.insert(dbs, tk.END, text=" dvdrental", image=self.databaseimage)
        funcdvdrental = self.treeview.insert(dvdrental, tk.END, text=" Functions", image=self.functionimage)
        tabldvdrental = self.treeview.insert(dvdrental, tk.END, text=" Tables", image=self.tableimage)
        triggersdvdrental = self.treeview.insert(dvdrental, tk.END, text="Trigger Functions", image=self.triggerimage)
        viewsdvdrental = self.treeview.insert(dvdrental, tk.END, text=" Views", image=self.viewimage)
        sports = self.treeview.insert(dbs, tk.END, text=" sports", image=self.databaseimage)
        funcsports = self.treeview.insert(sports, tk.END, text=" Functions", image=self.functionimage)
        tablsport = self.treeview.insert(sports, tk.END, text="Tables", image=self.tableimage)
        triggersport = self.treeview.insert(sports, tk.END, text=" Trigger Functions", image=self.triggerimage)
        viewsport = self.treeview.insert(sports, tk.END, text=" Views", image=self.viewimage)
        logingrp = self.treeview.insert(srvr1, tk.END, text=" Login/Group Roles", image=self.usersimage)
        usr1 = self.treeview.insert(logingrp, tk.END, text=" user1", image=self.singleuserimage)
        usr2 = self.treeview.insert(logingrp, tk.END, text=" user2", image=self.singleuserimage)
        usr3 = self.treeview.insert(logingrp, tk.END, text=" user3", image=self.singleuserimage)
        usr4 = self.treeview.insert(logingrp, tk.END, text=" user4", image=self.singleuserimage)        
        # *********************************************************************
        

    #Metodo agregar QueryTool
    def addQueryTool( self ):
        self.contadorQuerysTabs = self.contadorQuerysTabs+1
        self.nb.fm = Frame(self.nb)
        self.nb.fm.pack(fill=BOTH, expand=True)
        self.nb.fm.columnconfigure(1, weight=1)
        self.nb.fm.columnconfigure(3, pad=7)
        self.nb.fm.rowconfigure(3, weight=1)
        self.nb.fm.rowconfigure(5, pad=7)
        self.nb.add(self.nb.fm, text='Query '+str(self.contadorQuerysTabs))
        self.nb.grid(row=1, column=0, columnspan=2, rowspan=4,
                     padx=5, sticky=E + W + S + N)
        self.nb.fm.area = Text(self.nb.fm)
        self.nb.fm.area.grid(row=1, column=0, columnspan=2, rowspan=4,
                       padx=5, sticky=E + W + S + N)
        #self.lbl.configure(text="Cambia")

    def run(self):
        active_object = self.nb.nametowidget(self.nb.select())
        messagebox.showinfo("Info",active_object.area.get("1.0",'end-1c'))
        #print(self.nb.index(self.nb.select()))
        #print(self.nb.tab(self.nb.select(), "text"))

    def saveFile( self ):

        f = filedialog.asksaveasfile(initialdir="/", title="Select file",
                                     mode='w', defaultextension=".sql")
        if f is None:  # asksaveasfile return `None` if dialog closed with "cancel".
            return
        active_object = self.nb.nametowidget(self.nb.select())
        text2save = str(active_object.area.get("1.0", 'end-1c'))  # starts from `1.0`, not `0.0`
        self.nb.tab(self.nb.select(), text=os.path.basename(f.name))
        f.write(text2save)
        f.close()

    def openFile( self ):
        filename = filedialog.askopenfilename(initialdir="/", title="Select a File")
        with open(filename, "r") as f:
            self.contadorQuerysTabs = self.contadorQuerysTabs + 1
            self.nb.fm = Frame(self.nb)
            self.nb.fm.pack(fill=BOTH, expand=True)
            self.nb.fm.columnconfigure(1, weight=1)
            self.nb.fm.columnconfigure(3, pad=7)
            self.nb.fm.rowconfigure(3, weight=1)
            self.nb.fm.rowconfigure(5, pad=7)
            self.nb.add(self.nb.fm, text=os.path.basename(filename))
            self.nb.grid(row=1, column=0, columnspan=2, rowspan=4,
                         padx=5, sticky=E + W + S + N)
            self.nb.fm.area = Text(self.nb.fm)
            self.nb.fm.area.insert(1.0, f.read())
            self.nb.fm.area.grid(row=1, column=0, columnspan=2, rowspan=4,
                                 padx=5, sticky=E + W + S + N)
class DialogPluginManager(Toplevel):
    def __init__(self, mainWin, modulesWithNewerFileDates):
        super(DialogPluginManager, self).__init__(mainWin.parent)
        
        self.ENABLE = _("Enable")
        self.DISABLE = _("Disable")
        self.parent = mainWin.parent
        self.cntlr = mainWin
        
        # copy plugins for temporary display
        self.pluginConfig = PluginManager.pluginConfig
        self.pluginConfigChanged = False
        self.uiClassMethodsChanged = False
        self.modelClassesChanged = False
        self.disclosureSystemTypesChanged = False
        self.hostSystemFeaturesChanged = False
        self.modulesWithNewerFileDates = modulesWithNewerFileDates
        
        parentGeometry = re.match("(\d+)x(\d+)[+]?([-]?\d+)[+]?([-]?\d+)", self.parent.geometry())
        dialogX = int(parentGeometry.group(3))
        dialogY = int(parentGeometry.group(4))

        self.title(_("Plug-in Manager"))
        frame = Frame(self)
        
        # left button frame
        buttonFrame = Frame(frame, width=40)
        buttonFrame.columnconfigure(0, weight=1)
        addLabel = Label(buttonFrame, text=_("Find plug-in modules:"), wraplength=60, justify="center")
        addSelectLocalButton = Button(buttonFrame, text=_("Select"), command=self.selectLocally)
        ToolTip(addSelectLocalButton, text=_("Select python module files from the local plugin directory."), wraplength=240)
        addBrowseLocalButton = Button(buttonFrame, text=_("Browse"), command=self.browseLocally)
        ToolTip(addBrowseLocalButton, text=_("File chooser allows browsing and selecting python module files to add (or reload) plug-ins, from the local file system."), wraplength=240)
        addWebButton = Button(buttonFrame, text=_("On Web"), command=self.findOnWeb)
        ToolTip(addWebButton, text=_("Dialog to enter URL full path to load (or reload) plug-ins, from the web or local file system."), wraplength=240)
        addLabel.grid(row=0, column=0, pady=4)
        addSelectLocalButton.grid(row=1, column=0, pady=4)
        addBrowseLocalButton.grid(row=2, column=0, pady=4)
        addWebButton.grid(row=3, column=0, pady=4)
        buttonFrame.grid(row=0, column=0, rowspan=3, sticky=(N, S, W), padx=3, pady=3)
        
        # right tree frame (plugins already known to arelle)
        modulesFrame = Frame(frame, width=720)
        vScrollbar = Scrollbar(modulesFrame, orient=VERTICAL)
        hScrollbar = Scrollbar(modulesFrame, orient=HORIZONTAL)
        self.modulesView = Treeview(modulesFrame, xscrollcommand=hScrollbar.set, yscrollcommand=vScrollbar.set, height=7)
        self.modulesView.grid(row=0, column=0, sticky=(N, S, E, W))
        self.modulesView.bind('<<TreeviewSelect>>', self.moduleSelect)
        hScrollbar["command"] = self.modulesView.xview
        hScrollbar.grid(row=1, column=0, sticky=(E,W))
        vScrollbar["command"] = self.modulesView.yview
        vScrollbar.grid(row=0, column=1, sticky=(N,S))
        modulesFrame.columnconfigure(0, weight=1)
        modulesFrame.rowconfigure(0, weight=1)
        modulesFrame.grid(row=0, column=1, columnspan=4, sticky=(N, S, E, W), padx=3, pady=3)
        self.modulesView.focus_set()

        self.modulesView.column("#0", width=120, anchor="w")
        self.modulesView.heading("#0", text=_("Name"))
        self.modulesView["columns"] = ("author", "ver", "status", "date", "update", "descr", "license")
        self.modulesView.column("author", width=100, anchor="w", stretch=False)
        self.modulesView.heading("author", text=_("Author"))
        self.modulesView.column("ver", width=60, anchor="w", stretch=False)
        self.modulesView.heading("ver", text=_("Version"))
        self.modulesView.column("status", width=50, anchor="w", stretch=False)
        self.modulesView.heading("status", text=_("Status"))
        self.modulesView.column("date", width=70, anchor="w", stretch=False)
        self.modulesView.heading("date", text=_("File Date"))
        self.modulesView.column("update", width=50, anchor="w", stretch=False)
        self.modulesView.heading("update", text=_("Update"))
        self.modulesView.column("descr", width=200, anchor="w", stretch=False)
        self.modulesView.heading("descr", text=_("Description"))
        self.modulesView.column("license", width=70, anchor="w", stretch=False)
        self.modulesView.heading("license", text=_("License"))

        classesFrame = Frame(frame)
        vScrollbar = Scrollbar(classesFrame, orient=VERTICAL)
        hScrollbar = Scrollbar(classesFrame, orient=HORIZONTAL)
        self.classesView = Treeview(classesFrame, xscrollcommand=hScrollbar.set, yscrollcommand=vScrollbar.set, height=5)
        self.classesView.grid(row=0, column=0, sticky=(N, S, E, W))
        hScrollbar["command"] = self.classesView.xview
        hScrollbar.grid(row=1, column=0, sticky=(E,W))
        vScrollbar["command"] = self.classesView.yview
        vScrollbar.grid(row=0, column=1, sticky=(N,S))
        classesFrame.columnconfigure(0, weight=1)
        classesFrame.rowconfigure(0, weight=1)
        classesFrame.grid(row=1, column=1, columnspan=4, sticky=(N, S, E, W), padx=3, pady=3)
        self.classesView.focus_set()
        
        self.classesView.column("#0", width=200, anchor="w")
        self.classesView.heading("#0", text=_("Class"))
        self.classesView["columns"] = ("modules",)
        self.classesView.column("modules", width=500, anchor="w", stretch=False)
        self.classesView.heading("modules", text=_("Modules"))
        
        # bottom frame module info details
        moduleInfoFrame = Frame(frame, width=700)
        moduleInfoFrame.columnconfigure(1, weight=1)
        
        self.moduleNameLabel = Label(moduleInfoFrame, wraplength=600, justify="left", 
                                     font=font.Font(family='Helvetica', size=12, weight='bold'))
        self.moduleNameLabel.grid(row=0, column=0, columnspan=4, sticky=W)
        self.moduleAuthorHdr = Label(moduleInfoFrame, text=_("author:"), state=DISABLED)
        self.moduleAuthorHdr.grid(row=1, column=0, sticky=W)
        self.moduleAuthorLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleAuthorLabel.grid(row=1, column=1, columnspan=3, sticky=W)
        self.moduleDescrHdr = Label(moduleInfoFrame, text=_("description:"), state=DISABLED)
        self.moduleDescrHdr.grid(row=2, column=0, sticky=W)
        self.moduleDescrLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleDescrLabel.grid(row=2, column=1, columnspan=3, sticky=W)
        self.moduleClassesHdr = Label(moduleInfoFrame, text=_("classes:"), state=DISABLED)
        self.moduleClassesHdr.grid(row=3, column=0, sticky=W)
        self.moduleClassesLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleClassesLabel.grid(row=3, column=1, columnspan=3, sticky=W)
        ToolTip(self.moduleClassesLabel, text=_("List of classes that this plug-in handles."), wraplength=240)
        self.moduleVersionHdr = Label(moduleInfoFrame, text=_("Version:"), state=DISABLED)
        self.moduleVersionHdr.grid(row=4, column=0, sticky=W)
        self.moduleVersionLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleVersionLabel.grid(row=4, column=1, columnspan=3, sticky=W)
        ToolTip(self.moduleVersionLabel, text=_("Version of plug-in module."), wraplength=240)
        self.moduleUrlHdr = Label(moduleInfoFrame, text=_("URL:"), state=DISABLED)
        self.moduleUrlHdr.grid(row=5, column=0, sticky=W)
        self.moduleUrlLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleUrlLabel.grid(row=5, column=1, columnspan=3, sticky=W)
        ToolTip(self.moduleUrlLabel, text=_("URL of plug-in module (local file path or web loaded file)."), wraplength=240)
        self.moduleDateHdr = Label(moduleInfoFrame, text=_("date:"), state=DISABLED)
        self.moduleDateHdr.grid(row=6, column=0, sticky=W)
        self.moduleDateLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleDateLabel.grid(row=6, column=1, columnspan=3, sticky=W)
        ToolTip(self.moduleDateLabel, text=_("Date of currently loaded module file (with parenthetical node when an update is available)."), wraplength=240)
        self.moduleLicenseHdr = Label(moduleInfoFrame, text=_("license:"), state=DISABLED)
        self.moduleLicenseHdr.grid(row=7, column=0, sticky=W)
        self.moduleLicenseLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleLicenseLabel.grid(row=7, column=1, columnspan=3, sticky=W)
        self.moduleImportsHdr = Label(moduleInfoFrame, text=_("imports:"), state=DISABLED)
        self.moduleImportsHdr.grid(row=8, column=0, sticky=W)
        self.moduleImportsLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleImportsLabel.grid(row=8, column=1, columnspan=3, sticky=W)
        self.moduleEnableButton = Button(moduleInfoFrame, text=self.ENABLE, state=DISABLED, command=self.moduleEnable)
        ToolTip(self.moduleEnableButton, text=_("Enable/disable plug in."), wraplength=240)
        self.moduleEnableButton.grid(row=9, column=1, sticky=E)
        self.moduleReloadButton = Button(moduleInfoFrame, text=_("Reload"), state=DISABLED, command=self.moduleReload)
        ToolTip(self.moduleReloadButton, text=_("Reload/update plug in."), wraplength=240)
        self.moduleReloadButton.grid(row=9, column=2, sticky=E)
        self.moduleRemoveButton = Button(moduleInfoFrame, text=_("Remove"), state=DISABLED, command=self.moduleRemove)
        ToolTip(self.moduleRemoveButton, text=_("Remove plug in from plug in table (does not erase the plug in's file)."), wraplength=240)
        self.moduleRemoveButton.grid(row=9, column=3, sticky=E)
        moduleInfoFrame.grid(row=2, column=0, columnspan=5, sticky=(N, S, E, W), padx=3, pady=3)
        moduleInfoFrame.config(borderwidth=4, relief="groove")
        
        okButton = Button(frame, text=_("Close"), command=self.ok)
        ToolTip(okButton, text=_("Accept and changes (if any) and close dialog."), wraplength=240)
        cancelButton = Button(frame, text=_("Cancel"), command=self.close)
        ToolTip(cancelButton, text=_("Cancel changes (if any) and close dialog."), wraplength=240)
        okButton.grid(row=3, column=3, sticky=(S,E), pady=3)
        cancelButton.grid(row=3, column=4, sticky=(S,E), pady=3, padx=3)
        
        enableDisableFrame = Frame(frame)
        enableDisableFrame.grid(row=3, column=1, sticky=(S,W), pady=3)
        enableAllButton = Button(enableDisableFrame, text=_("Enable All"), command=self.enableAll)
        ToolTip(enableAllButton, text=_("Enable all plug ins."), wraplength=240)
        disableAllButton = Button(enableDisableFrame, text=_("Disable All"), command=self.disableAll)
        ToolTip(disableAllButton, text=_("Disable all plug ins."), wraplength=240)
        enableAllButton.grid(row=1, column=1)
        disableAllButton.grid(row=1, column=2)
        
        self.loadTreeViews()

        self.geometry("+{0}+{1}".format(dialogX+50,dialogY+100))
        frame.grid(row=0, column=0, sticky=(N,S,E,W))
        frame.columnconfigure(0, weight=0)
        frame.columnconfigure(1, weight=1)
        frame.rowconfigure(0, weight=1)
        window = self.winfo_toplevel()
        window.columnconfigure(0, weight=1)
        window.rowconfigure(0, weight=1)
        
        self.bind("<Return>", self.ok)
        self.bind("<Escape>", self.close)
        
        self.protocol("WM_DELETE_WINDOW", self.close)
        self.grab_set()
        self.wait_window(self)
        
    def loadTreeViews(self):
        self.selectedModule = None

        # clear previous treeview entries
        for previousNode in self.modulesView.get_children(""): 
            self.modulesView.delete(previousNode)
            
        def loadSubtree(parentNode, moduleItems):
            for moduleItem in sorted(moduleItems, key=lambda item: item[0]):
                moduleInfo = moduleItem[1]
                if parentNode or not moduleInfo.get("isImported"):
                    nodeName = moduleItem[0]
                    if parentNode:
                        nodeName = parentNode + GROUPSEP + nodeName
                    name = moduleInfo.get("name", nodeName)
                    node = self.modulesView.insert(parentNode, "end", nodeName, text=name)
                    self.modulesView.set(node, "author", moduleInfo.get("author"))
                    self.modulesView.set(node, "ver", moduleInfo.get("version"))
                    self.modulesView.set(node, "status", moduleInfo.get("status"))
                    self.modulesView.set(node, "date", moduleInfo.get("fileDate"))
                    if name in self.modulesWithNewerFileDates:
                        self.modulesView.set(node, "update", _("available"))
                    self.modulesView.set(node, "descr", moduleInfo.get("description"))
                    self.modulesView.set(node, "license", moduleInfo.get("license"))
                    if moduleInfo.get("imports"):
                        loadSubtree(node, [(importModuleInfo["name"],importModuleInfo)
                                           for importModuleInfo in moduleInfo["imports"]])
            
        loadSubtree("", self.pluginConfig.get("modules", {}).items())
        
        # clear previous treeview entries
        for previousNode in self.classesView.get_children(""): 
            self.classesView.delete(previousNode)

        for i, classItem in enumerate(sorted(self.pluginConfig.get("classes", {}).items())):
            className, moduleList = classItem
            node = self.classesView.insert("", "end", className, text=className)
            self.classesView.set(node, "modules", ', '.join(moduleList))
            
        self.moduleSelect()  # clear out prior selection

    def ok(self, event=None):
        # check for orphaned classes (for which there is no longer a corresponding module)
        _moduleNames = self.pluginConfig.get("modules", {}).keys()
        _orphanedClassNames = set()
        for className, moduleList in self.pluginConfig.get("classes", {}).items():
            for _moduleName in moduleList.copy():
                if _moduleName not in _moduleNames: # it's orphaned
                    moduleList.remove(_moduleName)
                    self.pluginConfigChanged = True
            if not moduleList: # now orphaned
                _orphanedClassNames.add(className)
                self.pluginConfigChanged = True
        for _orphanedClassName in _orphanedClassNames:
            del self.pluginConfig["classes"][_orphanedClassName]
        
        if self.pluginConfigChanged:
            PluginManager.pluginConfig = self.pluginConfig
            PluginManager.pluginConfigChanged = True
            PluginManager.reset()  # force reloading of modules
        if self.uiClassMethodsChanged or self.modelClassesChanged or self.disclosureSystemTypesChanged or self.hostSystemFeaturesChanged:  # may require reloading UI
            affectedItems = ""
            if self.uiClassMethodsChanged:
                affectedItems += _("menus of the user interface")
            if self.modelClassesChanged:
                if affectedItems:
                    affectedItems += _(" and ")
                affectedItems += _("model objects of the processor")
            if self.disclosureSystemTypesChanged:
                if affectedItems:
                    affectedItems += _(" and ")
                affectedItems += _("disclosure system types")
            if self.hostSystemFeaturesChanged:
                if affectedItems:
                    affectedItems += _(" and ")
                affectedItems += _("host system features")
            if messagebox.askyesno(_("User interface plug-in change"),
                                   _("A change in plug-in class methods may have affected {0}.  " 
                                     "Please restart Arelle to due to these changes.  \n\n"
                                     "Should Arelle restart itself now "
                                     "(if there are any unsaved changes they would be lost!)?"
                                     ).format(affectedItems),
                                   parent=self):
                self.cntlr.uiThreadQueue.put((self.cntlr.quit, [None, True]))
        self.close()
        
    def close(self, event=None):
        self.parent.focus_set()
        self.destroy()
                
    def moduleSelect(self, *args):
        node = (self.modulesView.selection() or (None,))[0]
        if node:
            node = node.rpartition(GROUPSEP)[2] # drop leading path names for module name
        moduleInfo = self.pluginConfig.get("modules", {}).get(node)
        if moduleInfo:
            self.selectedModule = node
            name = moduleInfo["name"]
            self.moduleNameLabel.config(text=name)
            self.moduleAuthorHdr.config(state=ACTIVE)
            self.moduleAuthorLabel.config(text=moduleInfo.get("author"))
            self.moduleDescrHdr.config(state=ACTIVE)
            self.moduleDescrLabel.config(text=moduleInfo.get("description"))
            self.moduleClassesHdr.config(state=ACTIVE)
            self.moduleClassesLabel.config(text=', '.join(moduleInfo["classMethods"]))
            self.moduleVersionHdr.config(state=ACTIVE)
            self.moduleVersionLabel.config(text=moduleInfo.get("version"))
            self.moduleUrlHdr.config(state=ACTIVE)
            self.moduleUrlLabel.config(text=moduleInfo["moduleURL"])
            self.moduleDateHdr.config(state=ACTIVE)
            self.moduleDateLabel.config(text=moduleInfo["fileDate"] + " " +
                    (_("(an update is available)") if name in self.modulesWithNewerFileDates else ""))
            self.moduleLicenseHdr.config(state=ACTIVE)
            self.moduleLicenseLabel.config(text=moduleInfo["license"])
            if moduleInfo.get("imports"):
                self.moduleImportsHdr.config(state=ACTIVE)
                _text = ", ".join(mi["name"] for mi in moduleInfo["imports"][:3])
                if len(moduleInfo["imports"]) >= 3:
                    _text += ", ..."
                self.moduleImportsLabel.config(text=_text)
            _buttonState = DISABLED if moduleInfo.get("isImported") else ACTIVE
            self.moduleEnableButton.config(state=_buttonState,
                                           text={"enabled":self.DISABLE,
                                                 "disabled":self.ENABLE}[moduleInfo["status"]])
            self.moduleReloadButton.config(state=_buttonState)
            self.moduleRemoveButton.config(state=_buttonState)
        else:
            self.selectedModule = None
            self.moduleNameLabel.config(text="")
            self.moduleAuthorHdr.config(state=DISABLED)
            self.moduleAuthorLabel.config(text="")
            self.moduleDescrHdr.config(state=DISABLED)
            self.moduleDescrLabel.config(text="")
            self.moduleClassesHdr.config(state=DISABLED)
            self.moduleClassesLabel.config(text="")
            self.moduleVersionHdr.config(state=DISABLED)
            self.moduleVersionLabel.config(text="")
            self.moduleUrlHdr.config(state=DISABLED)
            self.moduleUrlLabel.config(text="")
            self.moduleDateHdr.config(state=DISABLED)
            self.moduleDateLabel.config(text="")
            self.moduleLicenseHdr.config(state=DISABLED)
            self.moduleLicenseLabel.config(text="")
            self.moduleImportsHdr.config(state=DISABLED)
            self.moduleImportsLabel.config(text="")
            self.moduleEnableButton.config(state=DISABLED, text=self.ENABLE)
            self.moduleReloadButton.config(state=DISABLED)
            self.moduleRemoveButton.config(state=DISABLED)

    def selectLocally(self):
        choices = [] # list of tuple of (file name, description)
        def sortOrder(key):
            return {"EdgarRenderer": "1",
                    "validate": "2",
                    "xbrlDB": "3"}.get(key, "4") + key.lower()
        def selectChoices(dir, indent=""):
            dirHasEntries = False
            for f in sorted(os.listdir(dir), key=sortOrder):
                if f not in (".", "..", "__pycache__", "__init__.py"):
                    fPath = os.path.join(dir, f)
                    fPkgInit = os.path.join(fPath, "__init__.py")
                    dirInsertPoint = len(choices)
                    moduleInfo = None
                    if ((os.path.isdir(fPath) and os.path.exists(fPkgInit)) or
                        ((os.path.isfile(fPath) and f.endswith(".py")))):
                        moduleInfo = PluginManager.moduleModuleInfo(fPath)
                        if moduleInfo:
                            choices.append((indent + f, 
                                            "name: {}\ndescription: {}\n version {}".format(
                                                        moduleInfo["name"],
                                                        moduleInfo["description"],
                                                        moduleInfo.get("version")), 
                                            fPath, moduleInfo["name"], moduleInfo.get("version"), moduleInfo["description"]))
                            dirHasEntries = True
                    if os.path.isdir(fPath) and f not in ("DQC_US_Rules",):
                        if selectChoices(fPath, indent=indent + "   ") and not moduleInfo:
                            choices.insert(dirInsertPoint, (indent + f,None,None,None,None,None))
            return dirHasEntries
        selectChoices(self.cntlr.pluginDir)
        selectedPath = DialogOpenArchive.selectPlugin(self, choices)
        if selectedPath:
            moduleInfo = PluginManager.moduleModuleInfo(selectedPath)
            self.loadFoundModuleInfo(moduleInfo, selectedPath)
        
    def browseLocally(self):
        initialdir = self.cntlr.pluginDir # default plugin directory
        if not self.cntlr.isMac: # can't navigate within app easily, always start in default directory
            initialdir = self.cntlr.config.setdefault("pluginOpenDir", initialdir)
        filename = self.cntlr.uiFileDialog("open",
                                           parent=self,
                                           title=_("Choose plug-in module file"),
                                           initialdir=initialdir,
                                           filetypes=[(_("Python files"), "*.py")],
                                           defaultextension=".py")
        if filename:
            # check if a package is selected (any file in a directory containing an __init__.py
            #if (os.path.basename(filename) == "__init__.py" and os.path.isdir(os.path.dirname(filename)) and
            #    os.path.isfile(filename)):
            #    filename = os.path.dirname(filename) # refer to the package instead
            self.cntlr.config["pluginOpenDir"] = os.path.dirname(filename)
            moduleInfo = PluginManager.moduleModuleInfo(filename)
            self.loadFoundModuleInfo(moduleInfo, filename)
                

    def findOnWeb(self):
        url = DialogURL.askURL(self)
        if url:  # url is the in-cache or local file
            moduleInfo = PluginManager.moduleModuleInfo(url)
            self.cntlr.showStatus("") # clear web loading status
            self.loadFoundModuleInfo(moduleInfo, url)
                
    def loadFoundModuleInfo(self, moduleInfo, url):
        if moduleInfo and moduleInfo.get("name"):
            self.addPluginConfigModuleInfo(moduleInfo)
            self.loadTreeViews()
        else:
            messagebox.showwarning(_("Module is not itself a plug-in or in a directory with package __init__.py plug-in.  "),
                                   _("File does not itself contain a python program with an appropriate __pluginInfo__ declaration: \n\n{0}")
                                   .format(url),
                                   parent=self)
        
    def checkIfImported(self, moduleInfo):
        if moduleInfo.get("isImported"):
            messagebox.showwarning(_("Plug-in is imported by a parent plug-in.  "),
                                   _("Plug-in has a parent, please request operation on the parent: \n\n{0}")
                                   .format(moduleInfo.get("name")),
                                   parent=self)
            return True
        return False
    
    def checkClassMethodsChanged(self, moduleInfo):
        for classMethod in moduleInfo["classMethods"]:
            if classMethod.startswith("CntlrWinMain.Menu"):
                self.uiClassMethodsChanged = True  # may require reloading UI
            elif classMethod == "ModelObjectFactory.ElementSubstitutionClasses":
                self.modelClassesChanged = True # model object factor classes changed
            elif classMethod == "DisclosureSystem.Types":
                self.disclosureSystemTypesChanged = True # disclosure system types changed
            elif classMethod.startswith("Proxy."):
                self.hostSystemFeaturesChanged = True # system features (e.g., proxy) changed
    
    def removePluginConfigModuleInfo(self, name):
        moduleInfo = self.pluginConfig["modules"].get(name)
        if moduleInfo:
            if self.checkIfImported(moduleInfo):
                return;
            def _removePluginConfigModuleInfo(moduleInfo):
                _name = moduleInfo.get("name")
                if _name:
                    self.checkClassMethodsChanged(moduleInfo)
                    for classMethod in moduleInfo["classMethods"]:
                        classMethods = self.pluginConfig["classes"].get(classMethod)
                        if classMethods and _name in classMethods:
                            classMethods.remove(_name)
                            if not classMethods: # list has become unused
                                del self.pluginConfig["classes"][classMethod] # remove class
                    for importModuleInfo in moduleInfo.get("imports", EMPTYLIST):
                        _removePluginConfigModuleInfo(importModuleInfo)
                    self.pluginConfig["modules"].pop(_name, None)
            _removePluginConfigModuleInfo(moduleInfo)
            if not self.pluginConfig["modules"] and self.pluginConfig["classes"]:
                self.pluginConfig["classes"].clear() # clean orphan classes
            self.pluginConfigChanged = True

    def addPluginConfigModuleInfo(self, moduleInfo):
        if self.checkIfImported(moduleInfo):
            return;
        name = moduleInfo.get("name")
        self.removePluginConfigModuleInfo(name)  # remove any prior entry for this module
        def _addPlugin(moduleInfo):
            _name = moduleInfo.get("name")
            if _name:
                self.modulesWithNewerFileDates.discard(_name) # no longer has an update available
                self.pluginConfig["modules"][_name] = moduleInfo
                # add classes
                for classMethod in moduleInfo["classMethods"]:
                    classMethods = self.pluginConfig["classes"].setdefault(classMethod, [])
                    if name not in classMethods:
                        classMethods.append(_name)
                self.checkClassMethodsChanged(moduleInfo)
            for importModuleInfo in moduleInfo.get("imports", EMPTYLIST):
                _addPlugin(importModuleInfo)
        _addPlugin(moduleInfo)
        self.pluginConfigChanged = True

    def moduleEnable(self):
        if self.selectedModule in self.pluginConfig["modules"]:
            moduleInfo = self.pluginConfig["modules"][self.selectedModule]
            if self.checkIfImported(moduleInfo):
                return;
            def _moduleEnable(moduleInfo):
                if self.moduleEnableButton['text'] == self.ENABLE:
                    moduleInfo["status"] = "enabled"
                elif self.moduleEnableButton['text'] == self.DISABLE:
                    moduleInfo["status"] = "disabled"
                self.checkClassMethodsChanged(moduleInfo)
                for importModuleInfo in moduleInfo.get("imports", EMPTYLIST):
                    _moduleEnable(importModuleInfo) # set status on nested moduleInfo
                    if importModuleInfo['name'] in self.pluginConfig["modules"]: # set status on top level moduleInfo
                        _moduleEnable(self.pluginConfig["modules"][importModuleInfo['name']])
            _moduleEnable(moduleInfo)
            if self.moduleEnableButton['text'] == self.ENABLE:
                self.moduleEnableButton['text'] = self.DISABLE
            elif self.moduleEnableButton['text'] == self.DISABLE:
                self.moduleEnableButton['text'] = self.ENABLE
            self.pluginConfigChanged = True
            self.loadTreeViews()
            
    def moduleReload(self):
        if self.selectedModule in self.pluginConfig["modules"]:
            url = self.pluginConfig["modules"][self.selectedModule].get("moduleURL")
            if url:
                moduleInfo = PluginManager.moduleModuleInfo(url, reload=True)
                if moduleInfo:
                    if self.checkIfImported(moduleInfo):
                        return;
                    self.addPluginConfigModuleInfo(moduleInfo)
                    self.loadTreeViews()
                    self.cntlr.showStatus(_("{0} reloaded").format(moduleInfo["name"]), clearAfter=5000)
                else:
                    messagebox.showwarning(_("Module error"),
                                           _("File or module cannot be reloaded: \n\n{0}")
                                           .format(url),
                                           parent=self)

    def moduleRemove(self):
        if self.selectedModule in self.pluginConfig["modules"]:
            self.removePluginConfigModuleInfo(self.selectedModule)
            self.pluginConfigChanged = True
            self.loadTreeViews()
                    
    def enableAll(self):
        self.enableDisableAll(True)
                    
    def disableAll(self):
        self.enableDisableAll(False)
                    
    def enableDisableAll(self, doEnable):
        for module in self.pluginConfig["modules"]:
            moduleInfo = self.pluginConfig["modules"][module]
            if not moduleInfo.get("isImported"):
                def _enableDisableAll(moduleInfo):
                    if doEnable:
                        moduleInfo["status"] = "enabled"
                    else:
                        moduleInfo["status"] = "disabled"
                    for importModuleInfo in moduleInfo.get("imports", EMPTYLIST):
                        _enableDisableAll(importModuleInfo)
                _enableDisableAll(moduleInfo)
                if doEnable:
                    self.moduleEnableButton['text'] = self.DISABLE
                else:
                    self.moduleEnableButton['text'] = self.ENABLE
        self.pluginConfigChanged = True
        self.loadTreeViews()
            
class App:
    def __init__(self):
        # создание основного окна Tkinter
        self.window = Tk()
        self.window.title("Треугольники")
        self.window.geometry('520x520')
        self.window.minsize(520, 520)
        self.window.maxsize(520, 520)

        self.press_x, self.press_y = 0, 0
        self.release_x, self.release_y = 0, 0

        # флаги нажатия/отжатия кнопки
        self.pressed = False

        # размещение элементов интерфейса

        # основной элемент - Canvas
        self.canvas_x = 470
        self.canvas_y = 270
        self.c = Canvas(self.window,
                        width=self.canvas_x,
                        height=self.canvas_y,
                        bg='black')
        self.c.pack(side=TOP, padx=10, pady=(10, 10))

        # элементы управления: настройки, отображение параметров, очистка/выход
        setup = Frame(self.window, width=470)
        setup_left = Frame(setup, width=270)
        setup_right = Frame(setup, width=200)

        self.setup_notebook = Notebook(setup_left)

        setup1 = Frame(setup_left, width=250, height=140)
        setup2 = Frame(setup_left, width=250, height=140)
        setup3 = Frame(setup_left, width=250, height=140)

        # элементы управления на вкладках
        # вкладка 1
        Label(setup1, text='Длина стороны').pack(side=TOP,
                                                 pady=(10, 0),
                                                 padx=(10, 0),
                                                 anchor=W)
        self.scal_b = Scale(setup1,
                            orient=HORIZONTAL,
                            length=200,
                            from_=0,
                            to=300,
                            tickinterval=100,
                            resolution=10)
        self.scal_b.pack(side=TOP)
        self.scal_b.set(100)
        self.scal_b.bind("<ButtonRelease-1>", self.draw_triangle)
        Label(setup1, text='Угол \u03b1').pack(side=TOP,
                                               pady=(10, 0),
                                               padx=(10, 0),
                                               anchor=W)
        self.scal_alpha = Scale(setup1,
                                orient=HORIZONTAL,
                                length=200,
                                from_=0,
                                to=180,
                                tickinterval=30,
                                resolution=15)
        self.scal_alpha.pack(side=TOP)
        self.scal_alpha.set(30)
        self.scal_alpha.bind("<ButtonRelease-1>", self.draw_triangle)

        # вкладка 2
        Label(setup2, text='Угол \u03b1').pack(side=TOP,
                                               pady=(10, 0),
                                               padx=(10, 0),
                                               anchor=W)
        self.scal_alpha2 = Scale(setup2,
                                 orient=HORIZONTAL,
                                 length=200,
                                 from_=0,
                                 to=90,
                                 tickinterval=15,
                                 resolution=5)
        self.scal_alpha2.pack(side=TOP)
        self.scal_alpha2.set(60)
        self.scal_alpha2.bind("<ButtonRelease-1>", self.draw_triangle)
        Label(setup2, text='Угол \u03b2').pack(side=TOP,
                                               pady=(10, 0),
                                               padx=(10, 0),
                                               anchor=W)
        self.scal_beta = Scale(setup2,
                               orient=HORIZONTAL,
                               length=200,
                               from_=0,
                               to=90,
                               tickinterval=15,
                               resolution=5)
        self.scal_beta.pack(side=TOP)
        self.scal_beta.set(60)
        self.scal_beta.bind("<ButtonRelease-1>", self.draw_triangle)

        # вкладка 3
        Label(setup3, text='Длина стороны 2').pack(side=TOP,
                                                   pady=(10, 0),
                                                   padx=(10, 0),
                                                   anchor=W)
        self.scal_a = Scale(setup3,
                            orient=HORIZONTAL,
                            length=200,
                            from_=0,
                            to=300,
                            tickinterval=100,
                            resolution=10)
        self.scal_a.pack(side=TOP)
        self.scal_a.set(100)
        self.scal_a.bind("<ButtonRelease-1>", self.draw_triangle)
        Label(setup3, text='Длина стороны 3').pack(side=TOP,
                                                   pady=(10, 0),
                                                   padx=(10, 0),
                                                   anchor=W)
        self.scal_b2 = Scale(setup3,
                             orient=HORIZONTAL,
                             length=200,
                             from_=0,
                             to=300,
                             tickinterval=100,
                             resolution=10)
        self.scal_b2.pack(side=TOP)
        self.scal_b2.set(100)
        self.scal_b2.bind("<ButtonRelease-1>", self.draw_triangle)

        setup1.pack()
        setup2.pack()
        setup3.pack()

        self.setup_notebook.add(setup1, text='Задача 1')
        self.setup_notebook.add(setup2, text='Задача 2')
        self.setup_notebook.add(setup3, text='Задача 3')
        self.setup_notebook.bind('<<NotebookTabChanged>>', self.draw_triangle)

        self.setup_notebook.pack(side=LEFT)

        columns = ('#1', '#2')
        self.params = Treeview(setup_right,
                               show='headings',
                               columns=columns,
                               height=5)
        self.params.heading('#1', text='Параметр')
        self.params.heading('#2', text='Значение')
        self.params.column('#1', width=110, minwidth=50, stretch=NO, anchor=N)
        self.params.column('#2', width=110, minwidth=50, stretch=NO, anchor=N)
        self.params.pack(side=TOP, padx=(15, 0), pady=(15, 5))

        butframe = Frame(setup_right)
        Button(butframe, text='Очистить', width=10,
               command=self.draw_base()).pack(side=LEFT, padx=(25, 5))
        Button(butframe,
               text='Выход',
               width=10,
               command=lambda x=0: sys.exit(x)).pack(side=LEFT, padx=(0, 10))
        butframe.pack(side=TOP, pady=(17, 5))

        setup_left.pack(side=LEFT, padx=(0, 20))
        setup_right.pack(side=LEFT)
        setup.pack(side=TOP, pady=(5, 10), padx=(5, 5))

        self.window.bind('<Button-1>', self.press)
        self.window.bind('<ButtonRelease-1>', self.release)
        self.window.bind('<Motion>', self.motion)

        self.draw_base()
        self.window.mainloop()

    def motion(self, event):
        if self.pressed:
            if event.widget.master is not None:
                if event.widget.widgetName == 'canvas':
                    self.draw_base()
                    self.c.create_line(
                        [self.press_x, self.press_y, event.x, event.y],
                        dash=True,
                        fill='yellow')

    def draw_base(self):
        self.c.delete("all")
        # базовые оси
        self.c.create_line([10, 250, 460, 250], arrow=LAST, fill='white')
        self.c.create_line([20, 260, 20, 10], arrow=LAST, fill='white')

        # метки
        for i in range(1, 5):
            self.c.create_line([100 * i + 20, 247, 100 * i + 20, 253],
                               fill='white')
        for i in range(1, 3):
            self.c.create_line([17, 250 - 100 * i, 23, 250 - 100 * i],
                               fill='white')

        # надписи
        # наименование осей
        self.c.create_text(457, 258, text='x', fill='white')
        self.c.create_text(30, 15, text='y', fill='white')
        # наименование меток
        for i in range(0, 5):
            self.c.create_text(100 * i + 25,
                               260,
                               text=str(100 * i),
                               fill='white')
        for i in range(1, 3):
            self.c.create_text(34,
                               250 - 100 * i,
                               text=str(100 * i),
                               fill='white')

    def press(self, event):
        """
        Обработчик события "нажатие кнопки мыши"
        :param event:
        :return:
        """
        if event.widget.master is not None:
            if event.widget.widgetName == 'canvas':
                self.draw_base()
                self.press_x, self.press_y = event.x, event.y
                self.pressed = True

    def release(self, event):
        if event.widget.master is not None:
            if event.widget.widgetName == 'canvas':
                self.release_x, self.release_y = event.x, event.y
                if (self.release_x in range(450)) & (self.release_y
                                                     in range(250)):
                    self.draw_triangle(None)
        self.pressed = False

    def check_coordinates(self, C):
        if (C[0] < 0) | (C[1] < 0):
            return False
        if (C[0] > self.canvas_x) | (C[1] > self.canvas_y):
            return False
        return True

    def draw_triangle(self, event):
        if (self.press_x > 0) & (self.press_y > 0) & (self.release_x > 0) & (
                self.release_y > 0):
            self.draw_base()
            triangle = Math((self.press_x, self.press_y),
                            (self.release_x, self.release_y), (20, 250))
            task = self.setup_notebook.index(self.setup_notebook.select()) + 1
            if task == 1:
                data_dict = {
                    'b': self.scal_b.get(),
                    'alpha': self.scal_alpha.get()
                }
            elif task == 2:
                data_dict = {
                    'alpha': self.scal_alpha2.get(),
                    'beta': self.scal_beta.get()
                }
            elif task == 3:
                data_dict = {'a': self.scal_a.get(), 'b': self.scal_b2.get()}
            else:
                return
            C1, C2, data_dict = triangle.get_c(task, data_dict)
            if self.check_coordinates(C1) & self.check_coordinates(C2):
                self.c.create_polygon([
                    self.press_x, self.press_y, self.release_x, self.release_y,
                    C1[0], C1[1]
                ],
                                      fill='red')
                self.c.create_polygon([
                    self.press_x, self.press_y, self.release_x, self.release_y,
                    C2[0], C2[1]
                ],
                                      fill='blue')
                self.update_treeview(data_dict)
            else:
                self.c.create_text(300,
                                   100,
                                   text='Одна из точек вне области построения',
                                   fill='white')

    def update_treeview(self, data):
        """
        запись параметров в элемент Treeview
        :return: None
        """
        for x in self.params.get_children():
            self.params.delete(x)
        for key in data.keys():
            self.params.insert("", END, values=[key, data[key]])
class Window:
    def fillTree(self,path, parent, list):
        for file in os.listdir(path):
            abspath = os.path.join(path,file)
            color = ""
            treelist = None
            for mini in list:
                if abspath in mini:
                    color = 'red'
                    treelist = mini
                else:
                    for lk in mini:
                        if abspath in lk:
                            color = 'purple'
            child = None
            if color == 'red':
                child = self.tree.insert(parent,'end',text=file,open=False,tags=(abspath,'red',str(treelist)),)
            elif color == 'purple':
                child = self.tree.insert(parent,'end',text=file,open=False,tags=(abspath,'purple'))
            else:
                child = self.tree.insert(parent,'end',text=file,open=False,tags=(abspath,'white'))
            if(os.path.isdir(abspath)):
                self.tree.insert(child,'end',text='',open=False)
    def __init__(self,list,dirlist):
        self.root = Tk()
        self.root.wm_title("Duplicate_Files")
        self.min = None
        self.list = list
        self.root.geometry('600x600+0+0')
        self.tree = Treeview(self.root ,height=15)
        self.tree.pack(expand='yes',fill='both')
        self.tree.heading('#0',text="files")
        self.tree.tag_configure('red',foreground='red')
        self.tree.tag_configure('purple',foreground='#cc00ff')
        self.tree.bind("<Double-1>",self.onDoubleClick)
        self.tree.bind("<<TreeviewOpen>>",self.onOpen)
        self.tree.bind("<<TreeviewClose>>",self.onClose)
        for path in dirlist:
            branch = self.tree.insert('','end',text=path,open=True,tags=(path,'white'))
            self.fillTree(path,branch,list)
        self.root.mainloop()


    def onDoubleClick(self,event):
        item = self.tree.selection()[0]
        print ("clicked" + str(self.tree.item(item,'tags')[0]))
        if str(self.tree.item(item,'tags')[1]) == "red":
            list_of_files = ast.literal_eval(str(self.tree.item(item,'tags')[2]))
            if self.min != None:
                if self.min.mini.winfo_exists():
                    self.min.mini.destroy()
            self.min = MiniWindow(self.root,list_of_files)

    def onOpen(self,event):
        item = self.tree.selection()[0]
        if self.tree.parent(item) != '':
            if len(self.tree.get_children(item))>0:
                self.tree.delete(self.tree.get_children(item))
            abspath = str(self.tree.item(item,'tags')[0])
            if(os.path.isdir(abspath)):
                self.fillTree(abspath, item,self.list)
    def onClose(self,event):
        item = self.tree.selection()[0]
        if self.tree.parent(item) != '':
            if len(self.tree.get_children(item))>0:
                self.tree.delete(self.tree.get_children(item))
class ComponentsDumpWindow(Toplevel):
	def __init__(self, application, barNumber = None, **kwargs):
		Toplevel.__init__(self)
		
		self.application = application
		self.barNumber = barNumber
		
		
		self.fromLabel = Label(self)
		self.fromLabel.grid(column = 0, row = 0)
		
		self.fromVar = StringVar()
		self.fromEntry = Entry(self, textvariable = self.fromVar, justify = RIGHT)
		self.fromEntry.grid(column = 1, row = 0, sticky = W + E)
		self.columnconfigure(1, weight = 1)
		
		
		self.toLabel = Label(self)
		self.toLabel.grid(column = 2, row = 0)
		
		self.toVar = StringVar()
		self.toEntry = Entry(self, textvariable = self.toVar, justify = RIGHT)
		self.toEntry.grid(column = 3, row = 0, sticky = W + E)
		self.columnconfigure(3, weight = 1)
		
		
		self.stepLabel = Label(self, text = "dx:")
		self.stepLabel.grid(column = 4, row = 0)
		
		self.stepVar = StringVar()
		self.stepEntry = Entry(self, textvariable = self.stepVar, justify = RIGHT)
		self.stepEntry.grid(column = 5, row = 0, sticky = W + E)
		self.columnconfigure(5, weight = 1)
		
		
		self.calculateButton = Button(self, text = "Рассчитать",
									  command = self.onCalculateButtonClicked)
		self.calculateButton.grid(column = 6, row = 0, columnspan = 2)
		
		
		# Таблица рассчитанных значений
		columns = ("№ стержня", "x", "Nx", "U", "σ")
		
		self.tree = Treeview(self, columns = columns, displaycolumns = columns)
		self.tree.grid(column = 0, row = 1, columnspan = 7, sticky = W + N + E + S)
		self.tree.column("#0", width = 0, stretch = 0)
		
		# Настройки отображения таблицы
		self.tree.column(columns[0], anchor = CENTER)
		self.tree.heading(columns[0], text = columns[0], anchor = CENTER)
		
		for x in columns[1:]:
			self.tree.column(x, anchor = E)
			self.tree.heading(x, text = x, anchor = E)
		
		self.rowconfigure(1, weight = 1)
		
		
		self.bind("<Destroy>", self.onWindowDestroy)
		
		
		self.updateTitles()
		self.onConstructionChanged(False)
	
	
	def updateTitles(self):
		if self.barNumber is None:
			titleDescStr = ""
			xDescStr     = "global"
		else:
			titleDescStr = "%sСтержень (%d)" % (self.application.nameDelim, self.barNumber)
			xDescStr     = "local"
		
		self.title("%s%sКомпоненты%s" \
				   % (self.application.name, self.application.nameDelim, titleDescStr))
		
		self.fromLabel["text"] = "От x(" + xDescStr + "):"
		self.toLabel["text"] = "До x(" + xDescStr + "):"
	
	
	def onWindowDestroy(self, event):
		self.application.onWindowDestroy(self)
	
	
	def onCalculateButtonClicked(self):
		try:
			self.calculate()
		except Exception as e:
			self.showError(e)
	
	
	def onConstructionChanged(self, constructed = True):
		if not constructed:
			for var in self.fromVar, self.toVar, self.stepVar:
				var.set("0")
			return
		
		try:
			self.calculate()
		except Exception:
			self.clear()
	
	
	def onPointCalculated(self, barNumber, x, N, U, Sigma):
		if self.barNumber is not None and barNumber != self.barNumber:
			return
		
		self.tree.insert(parent = "", index = "end",
						 values = ("—" if barNumber is None else str(barNumber),
								   "%.14f" % x, "%.14f" % N,
								   "%.14f" % U, "%.14f" % Sigma))
	
	
	def clear(self):
		self.tree.delete(*self.tree.get_children())
	
	
	def calculate(self):
		self.clear()
		
		if self.barNumber not in range(0, self.application.logic.barsCount()):
			self.barNumber = None
			self.updateTitles()
		
		for var in self.fromVar, self.toVar, self.stepVar:
			try:
				float(var.get())
			except ValueError:
				var.set("0")
		
		xFrom = float(self.fromVar.get())
		xTo = float(self.toVar.get())
		xStep = float(self.stepVar.get())
		
		self.application.logic.calculateComponents(xFrom, xTo, xStep, barNumber = self.barNumber,
												   onPointCalculated = self.onPointCalculated)
	
	
	def showError(self, message):
		tkinter.messagebox.showerror("Ошибка", message)
Exemple #10
0
class Gui(Interface):
    """The GUI interface uses the tkinter module to generate
    a window using tk
    """

    TREE_COLUMNS = ("Number of probes : {nProbes}", "Probe address", "Status")
    RESULT_DIPLAY_HEIGHT = 10

    def __init__(self, ip):
        Interface.__init__(self, ip)
        self.commandHistory = []
        self.mainWin = Tk()
        self.command = StringVar(self.mainWin)
        self.status = StringVar(self.mainWin, value="Waiting for command ...")
        self.text = StringVar(self.mainWin, value="Enter a command :")
        self.result = None
        self.probesDisplay = None
        self.mainWin.title("Commander for probe with ip : " + ip)
        self.isRunning = True
        self.mainWin.protocol("WM_DELETE_WINDOW", self.quit)

        # define the threads
        self.thProbe = Thread(target=self.updateProbes, name="Probe updater", daemon=True)
        self.thResults = Thread(target=self.updateResults, name="Results Updater", daemon=True)

    def start(self):
        """Starts (opens) the commander window"""
        self.mainWin.geometry("800x600")
        txtText = Label(self.mainWin, textvariable=self.text)
        txtText.grid(row=0, column=0, sticky=W)

        txtInput = Entry(self.mainWin, textvariable=self.command, width=30)
        txtInput.grid(row=0, column=1, sticky=E + W)
        txtInput.bind("<Return>", self.doCommand)
        txtInput.bind("<Up>", self.recallCommand)

        button = Button(self.mainWin, text="Refresh", fg="blue", command=self.triggerFetchProbes)
        button.grid(row=1, column=0, sticky=N + S + E + W)

        txtStatus = Label(self.mainWin, textvariable=self.status, wraplength=600, justify=CENTER)
        txtStatus.grid(row=1, column=1, sticky=N + S + E + W)

        self.probesDisplay = Treeview(self.mainWin, columns=self.TREE_COLUMNS, show="headings")
        self.probesDisplay.grid(row=2, columnspan=2, sticky=N + S + E + W)
        for i in range(0, len(self.TREE_COLUMNS)):
            self.updateHeading(i, nProbes=0)

        self.result = Text(self.mainWin, textvariable=self.result, height=self.RESULT_DIPLAY_HEIGHT, wrap=WORD)
        self.result.configure(state=DISABLED)
        self.result.grid(row=3, columnspan=2, sticky=N + S + E + W)
        self.addResult("Awaiting results .... ")

        self.mainWin.grid_rowconfigure(2, weight=1)
        self.mainWin.grid_columnconfigure(1, weight=1)

        self.probeFetcherScheduler()
        self.thProbe.start()

        self.resultFetcherScheduler()
        self.thResults.start()

        self.logger.info("Commander : Starting main window")

        self.mainWin.mainloop()

        self.logger.debug("Commander : mainloop over")

    def recallCommand(self, event):
        """Function to rewrite previous command in box"""
        if len(self.commandHistory) != 0:
            self.command.set(self.commandHistory[-1])
        return "break"

    def doCommand(self, event):
        """Executes user command"""
        self.commandHistory.append(self.command.get())
        self.logger.info("Commander : executing command")
        cmd = super().doCommand(self.command.get())
        # cmd.join()
        self.command.set("")

    def updateStatus(self, status):
        """Update status of the probe in status label
        :param status: new status"""
        self.status.set(status)
        self.mainWin.update_idletasks()

    def addResult(self, result):
        """Add (prepend) a result in the result test area
        :param result: the result to add
        """
        self.result.configure(state=NORMAL)
        self.result.insert("1.0", result + "\n")
        self.result.configure(state=DISABLED)

    def setResult(self, result):
        """Put this result in the result area
        :param result: result to put
        """
        self.result.configure(state=NORMAL)
        self.result.set(result)
        self.result.configure(state=DISABLED)

    def updateProbes(self):
        """Update the list of probes in the Treeview"""
        while self.isRunning:
            try:
                probes = self.probesToItems(self.fetchProbes())
                self.probesDisplay.set_children("")
                self.updateHeading(0, nProbes=len(probes))
                for item in probes:
                    self.probesDisplay.insert("", "end", values=item)
                #             self.probesDisplay.set_children('', probes)
            except ProbeConnectionFailed:
                self.updateStatus("Cannot get list of probes")
                self.logger.error("Error while getting list of probes : connection failed", exc_info=1)
            finally:
                self.doFetchProbes.wait()

    def updateHeading(self, index, **kw):
        self.probesDisplay.heading(index, anchor=W, text=self.TREE_COLUMNS[index].format(**kw))

    @staticmethod
    def probesToItems(probes):
        """Transform probe object into lists for display
        :param probes: list of probes to transform
        """
        return [(str(probe.getId()), probe.getIp(), probe.getStatus()) for probe in probes]

    def updateResults(self):
        """Update the results is the box"""
        while self.isRunning:
            try:
                result = self.fetchResults()
                self.addResult(result)
            except ProbeConnectionFailed:
                self.updateStatus("Cannot fetch results")
                self.logger.error("Cannot fetch results : connection to probe failed", exc_info=1)
            finally:
                self.doFetchResults.wait()

    def quit(self):
        """Exit and close the commander window"""
        self.logger.info("Commander : exiting commander")
        self.isRunning = False
        self.triggerFetchProbes()
        self.thProbe.join()
        super().quit()
        # no join because answer is blocking...
        #         self.thResults.join()
        self.mainWin.quit()
Exemple #11
0
class DialogOpenArchive(Toplevel):
    def __init__(self,
                 parent,
                 openType,
                 filesource,
                 filenames,
                 title,
                 colHeader,
                 showAltViewButton=False):
        if isinstance(parent, Cntlr):
            cntlr = parent
            parent = parent.parent  # parent is cntlrWinMain
        else:  # parent is a Toplevel dialog
            cntlr = parent.cntlr
        super(DialogOpenArchive, self).__init__(parent)
        self.parent = parent
        self.showAltViewButton = showAltViewButton
        parentGeometry = re.match("(\d+)x(\d+)[+]?([-]?\d+)[+]?([-]?\d+)",
                                  parent.geometry())
        dialogX = int(parentGeometry.group(3))
        dialogY = int(parentGeometry.group(4))
        self.accepted = False

        self.transient(self.parent)

        frame = Frame(self)

        treeFrame = Frame(frame, width=500)
        vScrollbar = Scrollbar(treeFrame, orient=VERTICAL)
        hScrollbar = Scrollbar(treeFrame, orient=HORIZONTAL)
        self.treeView = Treeview(treeFrame,
                                 xscrollcommand=hScrollbar.set,
                                 yscrollcommand=vScrollbar.set)
        self.treeView.grid(row=0, column=0, sticky=(N, S, E, W))
        hScrollbar["command"] = self.treeView.xview
        hScrollbar.grid(row=1, column=0, sticky=(E, W))
        vScrollbar["command"] = self.treeView.yview
        vScrollbar.grid(row=0, column=1, sticky=(N, S))
        treeFrame.columnconfigure(0, weight=1)
        treeFrame.rowconfigure(0, weight=1)
        treeFrame.grid(row=0,
                       column=0,
                       columnspan=4,
                       sticky=(N, S, E, W),
                       padx=3,
                       pady=3)
        self.treeView.focus_set()

        if openType not in (PLUGIN, PACKAGE):
            cntlr.showStatus(_("loading archive {0}").format(filesource.url))
        self.filesource = filesource
        self.filenames = filenames
        self.selection = filesource.selection
        self.hasToolTip = False
        selectedNode = None

        if openType == ENTRY_POINTS:
            try:
                metadataFiles = filesource.taxonomyPackageMetadataFiles
                ''' take first for now
                if len(metadataFiles) != 1:
                    raise IOError(_("Taxonomy package contained more than one metadata file: {0}.")
                                  .format(', '.join(metadataFiles)))
                '''
                metadataFile = metadataFiles[0]
                metadata = filesource.url + os.sep + metadataFile
                self.metadataFilePrefix = os.sep.join(
                    os.path.split(metadataFile)[:-1])
                if self.metadataFilePrefix:
                    self.metadataFilePrefix += "/"  # zip contents have /, never \ file seps
                self.taxonomyPkgMetaInf = '{}/META-INF/'.format(
                    os.path.splitext(os.path.basename(filesource.url))[0])

                self.taxonomyPackage = parsePackage(
                    cntlr, filesource, metadata,
                    os.sep.join(os.path.split(metadata)[:-1]) + os.sep)

                # may be a catalog file with no entry oint names
                if not self.taxonomyPackage["entryPoints"]:
                    openType = ARCHIVE  # no entry points to show, just archive
                    self.showAltViewButton = False
            except Exception as e:
                self.close()
                err = _(
                    "Failed to parse metadata; the underlying error was: {0}"
                ).format(e)
                messagebox.showerror(_("Malformed taxonomy package"), err)
                cntlr.addToLog(err)
                return

        if openType not in (PLUGIN, PACKAGE):
            cntlr.showStatus(None)

        if openType in (DISCLOSURE_SYSTEM, PLUGIN, PACKAGE):
            y = 3
        else:
            y = 1

        okButton = Button(frame, text=_("OK"), command=self.ok)
        cancelButton = Button(frame, text=_("Cancel"), command=self.close)
        okButton.grid(row=y, column=2, sticky=(S, E, W), pady=3)
        cancelButton.grid(row=y, column=3, sticky=(S, E, W), pady=3, padx=3)

        if self.showAltViewButton:
            self.altViewButton = Button(frame, command=self.showAltView)
            self.altViewButton.grid(row=y,
                                    column=0,
                                    sticky=(S, W),
                                    pady=3,
                                    padx=3)

        self.loadTreeView(openType, colHeader, title)

        self.geometry("+{0}+{1}".format(dialogX + 50, dialogY + 100))
        frame.grid(row=0, column=0, sticky=(N, S, E, W))
        frame.columnconfigure(0, weight=1)
        frame.rowconfigure(0, weight=1)
        window = self.winfo_toplevel()
        window.columnconfigure(0, weight=1)
        window.rowconfigure(0, weight=1)

        self.bind("<Return>", self.ok)
        self.bind("<Escape>", self.close)

        self.toolTipText = StringVar()
        if self.hasToolTip:
            self.treeView.bind("<Motion>", self.motion, '+')
            self.treeView.bind("<Leave>", self.leave, '+')
            self.toolTipText = StringVar()
            self.toolTip = ToolTip(self.treeView,
                                   textvariable=self.toolTipText,
                                   wraplength=640,
                                   follow_mouse=True,
                                   state="disabled")
            self.toolTipRowId = None

        self.protocol("WM_DELETE_WINDOW", self.close)
        self.grab_set()

        self.wait_window(self)

    def loadTreeView(self, openType, title, colHeader):
        self.title(title)
        self.openType = openType
        selectedNode = None

        # clear previous treeview entries
        for previousNode in self.treeView.get_children(""):
            self.treeView.delete(previousNode)

        # set up treeView widget and tabbed pane
        if openType in (ARCHIVE, DISCLOSURE_SYSTEM, PLUGIN, PACKAGE):
            if openType in (PLUGIN, PACKAGE): width = 770
            else: width = 500
            self.treeView.column("#0", width=width, anchor="w")
            self.treeView.heading("#0", text=colHeader)
            self.isRss = getattr(self.filesource, "isRss", False)
            if self.isRss:
                self.treeView.column("#0", width=350, anchor="w")
                self.treeView["columns"] = ("descr", "date", "instDoc")
                self.treeView.column("descr",
                                     width=50,
                                     anchor="center",
                                     stretch=False)
                self.treeView.heading("descr", text="Form")
                self.treeView.column("date",
                                     width=170,
                                     anchor="w",
                                     stretch=False)
                self.treeView.heading("date", text="Pub Date")
                self.treeView.column("instDoc",
                                     width=200,
                                     anchor="w",
                                     stretch=False)
                self.treeView.heading("instDoc", text="Instance Document")
            elif openType == PLUGIN:
                self.treeView.column("#0", width=150, anchor="w")
                self.treeView["columns"] = ("name", "vers", "descr", "license")
                self.treeView.column("name",
                                     width=150,
                                     anchor="w",
                                     stretch=False)
                self.treeView.heading("name", text="Name")
                self.treeView.column("vers",
                                     width=60,
                                     anchor="w",
                                     stretch=False)
                self.treeView.heading("vers", text="Version")
                self.treeView.column("descr",
                                     width=300,
                                     anchor="w",
                                     stretch=False)
                self.treeView.heading("descr", text="Description")
                self.treeView.column("license",
                                     width=60,
                                     anchor="w",
                                     stretch=False)
                self.treeView.heading("license", text="License")
            elif openType == PACKAGE:
                self.treeView.column("#0", width=200, anchor="w")
                self.treeView["columns"] = ("vers", "descr", "license")
                self.treeView.column("vers",
                                     width=100,
                                     anchor="w",
                                     stretch=False)
                self.treeView.heading("vers", text="Version")
                self.treeView.column("descr",
                                     width=400,
                                     anchor="w",
                                     stretch=False)
                self.treeView.heading("descr", text="Description")
                self.treeView.column("license",
                                     width=70,
                                     anchor="w",
                                     stretch=False)
                self.treeView.heading("license", text="License")
            else:
                self.treeView["columns"] = tuple()

            loadedPaths = []
            for i, filename in enumerate(self.filenames):
                if isinstance(filename, tuple):
                    if self.isRss:
                        form, date, instDoc = filename[2:5]
                    elif openType == PLUGIN:
                        name, vers, descr, license = filename[3:7]
                    elif openType == PACKAGE:
                        vers, descr, license = filename[3:6]
                    filename = filename[0]  # ignore tooltip
                    self.hasToolTip = True
                if filename.endswith("/"):
                    filename = filename[:-1]
                path = filename.split("/")
                if not self.isRss and len(
                        path) > 1 and path[:-1] in loadedPaths:
                    parent = "file{0}".format(loadedPaths.index(path[:-1]))
                else:
                    parent = ""
                node = self.treeView.insert(parent,
                                            "end",
                                            "file{0}".format(i),
                                            text=path[-1])
                if self.isRss:
                    self.treeView.set(node, "descr", form)
                    self.treeView.set(node, "date", date)
                    self.treeView.set(node, "instDoc",
                                      os.path.basename(instDoc))
                elif openType == PLUGIN:
                    self.treeView.set(node, "name", name)
                    self.treeView.set(node, "vers", vers)
                    self.treeView.set(node, "descr", descr)
                    self.treeView.set(node, "license", license)
                elif openType == PACKAGE:
                    self.treeView.set(node, "vers", vers)
                    self.treeView.set(node, "descr", descr)
                    self.treeView.set(node, "license", license)
                if self.selection == filename:
                    selectedNode = node
                loadedPaths.append(path)

        elif openType == ENTRY_POINTS:
            self.treeView.column("#0", width=200, anchor="w")
            self.treeView.heading("#0", text="Name")

            self.treeView["columns"] = ("url", )
            self.treeView.column("url", width=300, anchor="w")
            self.treeView.heading("url", text="URL")

            for name, urls in sorted(
                    self.taxonomyPackage["entryPoints"].items(),
                    key=lambda i: i[0][2]):
                self.treeView.insert("",
                                     "end",
                                     name,
                                     values="\n".join(url[1] for url in urls),
                                     text=name or urls[0][2])

            self.hasToolTip = True
        else:  # unknown openType
            return None
        if selectedNode:
            self.treeView.see(selectedNode)
            self.treeView.selection_set(selectedNode)

        if self.showAltViewButton:
            self.altViewButton.config(text=_("Show Files") if openType ==
                                      ENTRY_POINTS else _("Show Entries"))

    def ok(self, event=None):
        selection = self.treeView.selection()
        if len(selection) > 0:
            if hasattr(self, "taxonomyPackage"):
                # load file source remappings
                self.filesource.mappedPaths = self.taxonomyPackage[
                    "remappings"]
            filename = None
            if self.openType in (ARCHIVE, DISCLOSURE_SYSTEM):
                filename = self.filenames[int(selection[0][4:])]
                if isinstance(filename, tuple):
                    if self.isRss:
                        filename = filename[4]
                    else:
                        filename = filename[0]
            elif self.openType == ENTRY_POINTS:
                epName = selection[0]
                #index 0 is the remapped Url, as opposed to the canonical one used for display
                # Greg Acsone reports [0] does not work for Corep 1.6 pkgs, need [1], old style packages
                filenames = []
                for url in self.taxonomyPackage["entryPoints"][epName]:
                    filename = url[0]
                    if not filename.endswith("/"):
                        # check if it's an absolute URL rather than a path into the archive
                        if not isHttpUrl(
                                filename
                        ) and self.metadataFilePrefix != self.taxonomyPkgMetaInf:
                            # assume it's a path inside the archive:
                            filename = self.metadataFilePrefix + filename
                    filenames.append(filename)
                if filenames:
                    self.filesource.select(filenames)
                    self.accepted = True
                    self.close()
                return
            elif self.openType in (PLUGIN, PACKAGE):
                filename = self.filenames[int(selection[0][4:])][2]
            if filename is not None and not filename.endswith("/"):
                if hasattr(self, "taxonomyPackage"):
                    # attempt to unmap the filename to original file
                    # will be mapped again in loading, but this allows schemaLocation to be unmapped
                    for prefix, remapping in self.taxonomyPackage[
                            "remappings"].items():
                        if isHttpUrl(remapping):
                            remapStart = remapping
                        else:
                            remapStart = self.metadataFilePrefix + remapping
                        if filename.startswith(remapStart):
                            # set unmmapped file
                            filename = prefix + filename[len(remapStart):]
                            break
                if self.openType in (PLUGIN, PACKAGE):
                    self.filesource.selection = filename
                else:
                    self.filesource.select(filename)
                self.accepted = True
                self.close()

    def close(self, event=None):
        self.parent.focus_set()
        self.destroy()

    def showAltView(self, event=None):
        if self.openType == ENTRY_POINTS:
            self.loadTreeView(ARCHIVE, _("Select Entry Point"), _("File"))
        else:
            self.loadTreeView(ENTRY_POINTS, _("Select Archive File"),
                              _("File"))

    def leave(self, *args):
        self.toolTipRowId = None

    def motion(self, *args):
        tvRowId = self.treeView.identify_row(args[0].y)
        if tvRowId != self.toolTipRowId:
            text = None
            if self.openType in (ARCHIVE, DISCLOSURE_SYSTEM, PLUGIN, PACKAGE):
                self.toolTipRowId = tvRowId
                if tvRowId and len(tvRowId) > 4:
                    try:
                        text = self.filenames[int(tvRowId[4:])]
                        if isinstance(text, tuple):
                            text = (text[1] or "").replace("\\n", "\n")
                    except (KeyError, ValueError):
                        pass
            elif self.openType == ENTRY_POINTS:
                try:
                    text = "{0}\n{1}".format(
                        tvRowId, "\n".join(
                            url[1] for url in
                            self.taxonomyPackage["entryPoints"][tvRowId]))
                except KeyError:
                    pass
            self.setToolTip(text)

    def setToolTip(self, text):
        self.toolTip._hide()
        if text:
            self.toolTipText.set(text)
            self.toolTip.configure(state="normal")
            self.toolTip._schedule()
        else:
            self.toolTipText.set("")
            self.toolTip.configure(state="disabled")
Exemple #12
0
class ContactsListView(Frame):
    """View displaying a list of all contacts."""
    def __init__(self, master, **kwargs):
        """
        Creates list view layout and controls.

        :param master: application root window
        """
        super().__init__(master, **kwargs)

        self.search_text = StringVar()
        self.console_text = StringVar()

        # Treeview setup
        col_ids = ("first_name", "surname", "phone", "email", "last_edited")
        self.contacts_list = Treeview(self, columns=col_ids, show='headings')
        for col_id, text in zip(
                col_ids,
            ["First name", "Surname", "Phone", "Email", "Last edited"]):
            self.contacts_list.column(col_id, stretch=True, width=160)
            self.contacts_list.heading(col_id, text=text)

        # Search panel
        search_panel = Frame(self)
        search_entry = Entry(search_panel, textvariable=self.search_text)
        self.search_btn = Button(search_panel, text="Search")
        search_entry.pack(side=LEFT)
        self.search_btn.pack(side=LEFT)

        # Controls
        self.add_btn = Button(self, text="Add")
        self.edit_btn = Button(self, text="Edit")
        self.delete_btn = Button(self, text="Delete")
        self.console = Label(self, textvariable=self.console_text)

        # Layout
        search_panel.pack()
        self.contacts_list.pack(fill=BOTH, expand=True)
        self.console.pack()
        self.delete_btn.pack(side=RIGHT)
        self.edit_btn.pack(side=RIGHT)
        self.add_btn.pack(side=RIGHT)

    def set(self, contacts):
        """
        Sets contacts to be displayed, clears console.

        :param contacts: collection of contacts fields as tuples
                         with contacts ids
        """
        self.contacts_list.delete(*self.contacts_list.get_children())
        for contact_fields in contacts:
            rowid, values = str(contact_fields[0]), contact_fields[1:]
            self.contacts_list.insert('', 'end', text=rowid, values=values)
        self.log()

    def get_selected_contacts_ids(self):
        """Returns collection of ids."""
        focused_rows = self.contacts_list.selection()
        return map(lambda focus: self.contacts_list.item(focus)['text'],
                   focused_rows)

    def log(self, message=''):
        """Writes message on the console."""
        self.console_text.set(message)
Exemple #13
0
class statistic_xx():
    def __init__(self,data,y,v='план'):
        
        w=Toplevel()
        w.wm_title('Итоги по месяцам за {0} год ({1}) '.format(y,v))
        w.columnconfigure(0,weight=1)
        w.rowconfigure(0,weight=1)
        
        cols=data[y]['degurs']  # ЗАГЛУШКА : список дежурных
        
        self.t=Treeview(w,columns=cols)
        self.t.column('#0',width=120)
        for c in cols:
            self.t.heading(c,text=c)
            self.t.column(c,width=65,anchor='center')
        self.t.tag_configure('табель',background='green')
        self.t.tag_configure('ош',background='red')
        self.scrX=Scrollbar(w,orient='horizontal',command=self.t.xview)
        self.scrY=Scrollbar(w,orient='vertical',command=self.t.yview)
        self.t['xscrollcommand']=self.scrX.set
        self.t['yscrollcommand']=self.scrY.set
        self.t.grid(row=0,column=0,sticky=N+S+E+W)
        self.scrX.grid(row=1,column=0,sticky=E+W)
        self.scrY.grid(row=0,column=1,sticky=N+S)
        roots=dict()
        for m in ['01','02','03','04','05','06','07','08','09','10','11','12']:
            d0=data[y]
            if m not in d0: continue
            roots[m]=self.t.insert('','end',text=m+' ('+data[y][m]['month']+')')
        #r=self.t.insert('','end',text='рабочих')
        #x=self.t.insert('','end',text='xxx')
        #w=self.t.insert('','end',text='отработано')
        #e=self.t.insert('','end',text='дополнительные')
        #n=self.t.insert('','end',text='ночные')
        #h=self.t.insert('','end',text='праздничные')
        #rz_root=self.t.insert('','end',text='резерв')
        
        for m in ['01','02','03','04','05','06','07','08','09','10','11','12']:
            d0=data[y]
            if m not in d0: continue
            d=d0[m]

            rez=dict()
            tag=''
            if v=='авто':
                if 'табель' in d['degur']:
                    vv='табель'
                    tag=vv
                else:
                    vv='план'
            elif v=='табель':
                if 'табель' not in d['degur']:
                    vv='план'
                    tag='ош'
                else:
                    vv=v
                    tag=vv
            else:
                vv=v

            for j,s in d['degur'][vv].items():
                rez[j]=analyse2(s,d)
            NUL=(0,0,0,0,0,0,0)
            ww=[rez.get(j,NUL)[0] for j in cols]
            ee=[rez.get(j,NUL)[0]-rez.get(j,NUL)[3]+rez.get(j,NUL)[4] for j in cols]
            xx=[rez.get(j,NUL)[0]-rez.get(j,NUL)[3] for j in cols]
            nn=[rez.get(j,NUL)[1] for j in cols]
            hh=[rez.get(j,NUL)[2] for j in cols]
            rr=[rez.get(j,NUL)[3]-rez.get(j,NUL)[4] for j in cols]
            rz=[rez.get(j,NUL)[5] for j in cols]
            self.t.insert(roots[m],'end',text='отработано',values=ww,tag=tag)
            self.t.insert(roots[m],'end',text='рабочие',values=rr,tag=tag)
            self.t.insert(roots[m],'end',text='дополнительные',values=ee,tag=tag)
            self.t.insert(roots[m],'end',text='ночные',values=nn,tag=tag)
            self.t.insert(roots[m],'end',text='праздничные',values=hh,tag=tag)
Exemple #14
0
class Gr():
    def __init__(self,root,data,SCRY=None):
        self.data=data
        self.columns=[x for x in range(1,8)]+['day']
        root.rowconfigure(1,weight=1)
        root.columnconfigure(0,weight=1)
        root.columnconfigure(1,weight=1)
        root.columnconfigure(2,weight=1)
        f=Frame(root)
        f.columnconfigure(0,weight=1)
        f.rowconfigure(1,weight=1)
        self.v=Combobox(root)
        self.v.grid(row=0,column=0)
        self.v.bind('<<ComboboxSelected>>',self.select_ver)
        f.grid(row=1,column=0,columnspan=3,sticky=N+S)
        self.tree=Treeview(f,
                columns=self.columns,
                displaycolumns=['day']+self.columns[:-1],
                show='headings')
        #self.tree.tag_configure('odd',background='white')
        #self.tree.tag_configure('even',background='gray')
        self.tree.tag_configure('dif',foreground='brown')
        self.tree.tag_configure('work',background='white')
        self.tree.tag_configure('short',background='#F5EFE0')
        self.tree.tag_configure('rest',background='#E0B0B0')
        self.tree.tag_configure('holyday',background='#E7B7A4')
        for c in self.columns:
            self.tree.heading(c,text=c)
            self.tree.column(c,width=65,anchor='center')
        self.tree.column('day',width=30)
        scrX=Scrollbar(f,orient='horizontal',command=self.tree.xview)
        self.tree['xscrollcommand']=scrX.set
        if not SCRY:
            self.scrY=Scrollbar(f,orient='vertical',command=self.yview)
            self.tree['yscrollcommand']=self.scrY.set
        else:
            self.tree['yscrollcommand']=SCRY.set
        self.tree.grid(row=1,column=0,sticky=N+S)
        if not SCRY:
            self.scrY.grid(row=1,column=1,sticky=N+S)
        scrX.grid(row=2,column=0,sticky=E+W)
    def set(self,y,m):
        self.y=y
        self.m=m
        self.show()
    def yview(self,*args):
        self.tree.yview(*args)
        self.yview2(*args)
    def yview2(self,*args):
        pass
    def show(self):
        d=self.data[self.y][self.m]
        V=list(d['degur'].keys())
        self.v['values']=V
        self.v.set(V[0])
        self.select_ver()
    def select_ver(self,*e):
        self.tree.delete(*self.tree.get_children())
        d=self.data[self.y][self.m]
        offset=d['offset']
        v=self.v.get()
        col=[]
        for i,deg in enumerate(d['degurs']):
            self.tree.heading(i+1,text=deg)
            col.append(i+1)
        self.tree.configure(displaycolumns=['day']+col)
        items=dict()

        if 'табель' in d['degur']:
            a=[''.join(x) for x in zip(*[[x for x in d['degur']['план'][j]] \
                    for j in d['degurs']])]
            b=[''.join(x) for x in zip(*[[x for x in d['degur']['табель'][j]] \
                    for j in d['degurs']])]
            c=[x!=y for x,y  in zip(a,b)]
        else:
            c=[False]*32

        for i in range(1,d['days']+1):
            tag = (i+offset) % 7 in [0,6] and 'rest' or 'work'
            if i in d['holydays'] : tag='holyday'
            elif i in d['restdays'] : tag='rest'
            elif i in d['shortdays'] : tag='short'
            elif i in d['workdays'] : tag='work'
            if c[i]: tag=[tag,'dif']
            ii=self.tree.insert('','end',values=['-','-','-','-','-'],tag=tag)
            self.tree.set(ii,column='day',value=i)
            items[i]=ii

        
        for j,s in d['degur'][v].items(): # j-degur
            if not s: continue
            for i,val in enumerate(s[1:-1]):
                if val=='J':
                    val='до'
                elif val=='j':
                    val='од'
                elif val=='a':
                    val='10'
                self.tree.set(items[i+1],column=d['degurs'].index(j)+1,value=val)
            if s[0]=='Н':
                if s[1]=='-':
                    self.tree.set(items[1],column=d['degurs'].index(j)+1,value='Н(8)')
                else:
                    self.tree.set(items[1],column=d['degurs'].index(j)+1,value='!')
            if s[-2]=='Н':
                if s[-1]=='-':
                    self.tree.set(items[len(s)-2],column=d['degurs'].index(j)+1,value='Н(4)')
                else:
                    self.tree.set(items[len(s)-2],column=d['degurs'].index(j)+1,value='!')
        self.calc(self.y,self.m)
    def calc(self,y,m):
        d=self.data[y][m]
        offset=d['offset']
        WH=0
        for i in range(1,d['days']+1):
            if i in d['holydays']: wh=0
            elif i in d['restdays'] : wh=0
            elif i in d['shortdays'] : wh=7
            elif i in d['workdays'] : wh=8
            elif (i+offset) % 7 in [0,6]: wh=0
            else: wh=8
            WH+=wh
class ElementListWidget(Frame):
	def __init__(self, parent, label, columns, showError):
		Frame.__init__(self, parent)
		
		self.showError = showError
		
		self.columnconfigure(0, weight = 1)
		self.rowconfigure(1, weight = 1)
		
		
		# Название таблицы
		self.titleLabel = Label(self, text = label)
		self.titleLabel.grid(column = 0, row = 0, sticky = W + E)
		
		
		# Таблица значений
		columns = ("Метка", "№") + columns
		self.tree = Treeview(self, columns = columns, displaycolumns = columns,
							 selectmode = "browse")
		self.tree.grid(column = 0, row = 1, sticky = W + N + E + S)
		
		# Настраиваем внешний вид таблицы (первые колонки)
		self.tree.column("#0", width = 0, stretch = 0)	# Прячем колонку с иконкой
		
		self.tree.column( columns[0], anchor = W, width = 150)
		self.tree.heading(columns[0], anchor = W, text = columns[0])
		
		self.tree.column( columns[1], anchor = E, width = 80)
		self.tree.heading(columns[1], anchor = E, text = columns[1])
		
		self.tree.bind("<<TreeviewSelect>>", self.onSelectionChanged)
		
		
		# Панель с кнопками
		self.buttonPanel = Frame(self)
		self.buttonPanel.grid(column = 0, row = 2, sticky = W + E)
		
		self.buttonPanel.columnconfigure(0, weight = 1)
		self.buttonPanel.columnconfigure(3, minsize = emptySpaceSize, weight = 0)
		self.buttonPanel.columnconfigure(6, minsize = emptySpaceSize, weight = 0)
		self.buttonPanel.columnconfigure(9, weight = 1)
		
		# Кнопки добавления/удаления элемента
		self.buttonAdd = Button(self.buttonPanel, text = "+", width = 3,
								command = self.onButtonAddClicked)
		self.buttonAdd.grid(column = 1, row = 0)
		
		self.buttonRemove = Button(self.buttonPanel, text = "-", width = 3, state = DISABLED,
								   command = self.onButtonRemoveClicked)
		self.buttonRemove.grid(column = 2, row = 0)
		
		# Кнопки перемещения элемента
		self.buttonUp = Button(self.buttonPanel, text = "↑", width = 3, state = DISABLED,
							   command = self.onButtonUpClicked)
		self.buttonUp.grid(column = 4, row = 0)
		
		self.buttonDown = Button(self.buttonPanel, text = "↓", width = 3, state = DISABLED,
								 command = self.onButtonDownClicked)
		self.buttonDown.grid(column = 5, row = 0)
		
		# Кнопки применить/отменить (для выбранного элемента)
		self.buttonCancel = Button(self.buttonPanel, text = "✗", width = 3,
								   command = self.updateSelectedFrame)
		self.buttonCancel.grid(column = 7, row = 0)
		
		self.buttonApply = Button(self.buttonPanel, text = "✓", width = 3,
								  command = self.onButtonApplyClicked)
		self.buttonApply.grid(column = 8, row = 0)
		
		
		# Редактирование выделенного элемента
		self.i     = StringVar()
		self.label = (StringVar(), StringVar())
		
		self.selectedFrame = Frame(self)
		self.selectedFrame.grid(column = 0, row = 3, sticky = W + E)
		
		# Номер
		Label(self.selectedFrame, text = "№:") \
			.grid(column = 0, row = 0)
		Label(self.selectedFrame, textvariable = self.i, width = 3, justify = RIGHT) \
			.grid(column = 1, row = 0)
		
		# Пустое пространство
		self.selectedFrame.columnconfigure(2, minsize = emptySpaceSize, weight = 0)
		
		# Метка
		Entry(self.selectedFrame, textvariable = self.label[0]) \
			.grid(column = 3, row = 0, sticky = W + E)
		
		Entry(self.selectedFrame, textvariable = self.label[1], bg = defaultValueBG) \
			.grid(column = 4, row = 0, sticky = W + E)
		
		# Виджет для элементов классов-потомков
		self.detailFrame = Frame(self.selectedFrame)
		self.detailFrame.grid(column = 3, row = 1, columnspan = 2, sticky = W + N + E + S)
		
		self.selectedFrame.columnconfigure(3, weight = 1)
		self.selectedFrame.columnconfigure(4, weight = 1)
		self.selectedFrame.rowconfigure(1, weight = 1)
	
	
	def onButtonUpClicked(self):
		item = self.selectedItem()
		if item is None: return
		
		prev = self.tree.prev(item)
		if prev != "":
			parent, index = self.tree.parent(item), self.tree.index(item)
			self.tree.move(item, parent, index - 1)
			
			# Корректируем номера элементов
			self.tree.set(item, "№", index - 1)
			self.tree.set(prev, "№", index)
			
			self.updateSelectedFrame(item)
	
	
	def onButtonDownClicked(self):
		item = self.selectedItem()
		if item is None: return
		
		next = self.tree.next(item)
		if next != "":
			parent, index = self.tree.parent(item), self.tree.index(item)
			self.tree.move(item, parent, index + 1)
			
			# Корректируем номера элементов
			self.tree.set(item, "№", index + 1)
			self.tree.set(next, "№", index)
			
			self.updateSelectedFrame(item)
	
	
	def onButtonAddClicked(self):
		pass
	
	
	def onButtonRemoveClicked(self):
		item = self.selectedItem()
		if item is None: return
		
		next = self.tree.next(item)
		self.tree.delete(item)
		
		while next != "":
			i = int(self.tree.set(next, "№"))
			self.tree.set(next, "№", i - 1)
			next = self.tree.next(next)
		
		self.onSelectionChanged()
	
	
	def onButtonApplyClicked(self, item = None):
		if item is None: item = self.selectedItem()
		if item is None: return None
		
		label = self.label[0].get()
		self.tree.set(item, "Метка", label)
		
		return item
	
	
	def onSelectionChanged(self, event = None):
		item = self.selectedItem()
		
		# Обновляем состояние кнопок
		state = DISABLED if item is None else NORMAL
		for x in (self.buttonRemove, self.buttonUp, self.buttonDown):
			x["state"] = state
		
		self.updateSelectedFrame(item)
	
	
	def selectedItem(self):
		selection = self.tree.selection()
		return None if type(selection) == type("") else selection[0]
	
	
	def clear(self):
		for item in self.tree.get_children():
			self.tree.delete(item)
	
	
	def updateSelectedFrame(self, item = None, values = None):
		if item is None: item = self.selectedItem()
		values = None
		
		if item is None:
			i     = ""
			label = ""
		else:
			if values is None: values = self.tree.set(item)
			
			i     = values["№"]
			label = values["Метка"]
		
		self.i.set(i)
		self.label[0].set(label)
		
		return (item, values)
	
	
	def addElement(self, values):
		self.tree.insert(parent = "", index = END, values = values)
	
	
	def setDefaultElement(self, label):
		self.label[1].set(label)
	
	
	def elementsCount(self):
		return len(self.tree.get_children())
	
	
	def elements(self, transform):
		return [ transform(item) for item in self.tree.get_children() ]
Exemple #16
0
class DialogOpenArchive(Toplevel):
    def __init__(self, parent, openType, filesource, filenames, title, colHeader, showAltViewButton=False):
        if isinstance(parent, Cntlr):
            cntlr = parent
            parent = parent.parent # parent is cntlrWinMain
        else: # parent is a Toplevel dialog
            cntlr = parent.cntlr
        super(DialogOpenArchive, self).__init__(parent)
        self.parent = parent
        self.showAltViewButton = showAltViewButton
        parentGeometry = re.match("(\d+)x(\d+)[+]?([-]?\d+)[+]?([-]?\d+)", parent.geometry())
        dialogX = int(parentGeometry.group(3))
        dialogY = int(parentGeometry.group(4))
        self.accepted = False

        self.transient(self.parent)
        
        frame = Frame(self)

        treeFrame = Frame(frame, width=500)
        vScrollbar = Scrollbar(treeFrame, orient=VERTICAL)
        hScrollbar = Scrollbar(treeFrame, orient=HORIZONTAL)
        self.treeView = Treeview(treeFrame, xscrollcommand=hScrollbar.set, yscrollcommand=vScrollbar.set)
        self.treeView.grid(row=0, column=0, sticky=(N, S, E, W))
        hScrollbar["command"] = self.treeView.xview
        hScrollbar.grid(row=1, column=0, sticky=(E,W))
        vScrollbar["command"] = self.treeView.yview
        vScrollbar.grid(row=0, column=1, sticky=(N,S))
        treeFrame.columnconfigure(0, weight=1)
        treeFrame.rowconfigure(0, weight=1)
        treeFrame.grid(row=0, column=0, columnspan=4, sticky=(N, S, E, W), padx=3, pady=3)
        self.treeView.focus_set()
        
        if openType not in (PLUGIN, PACKAGE):
            cntlr.showStatus(_("loading archive {0}").format(filesource.url))
        self.filesource = filesource
        self.filenames = filenames
        self.selection = filesource.selection
        self.hasToolTip = False
        selectedNode = None

        if openType == ENTRY_POINTS:
            try:
                metadataFiles = filesource.taxonomyPackageMetadataFiles
                ''' take first for now
                if len(metadataFiles) != 1:
                    raise IOError(_("Taxonomy package contained more than one metadata file: {0}.")
                                  .format(', '.join(metadataFiles)))
                '''
                metadataFile = metadataFiles[0]
                metadata = filesource.url + os.sep + metadataFile
                self.metadataFilePrefix = os.sep.join(os.path.split(metadataFile)[:-1])
                if self.metadataFilePrefix:
                    self.metadataFilePrefix += "/"  # zip contents have /, never \ file seps
                self.taxonomyPkgMetaInf = '{}/META-INF/'.format(
                            os.path.splitext(os.path.basename(filesource.url))[0])

        
                self.taxonomyPackage = parsePackage(cntlr, filesource, metadata,
                                                    os.sep.join(os.path.split(metadata)[:-1]) + os.sep)
                
                
                if self.taxonomyPackage["entryPoints"]:
                    # may have instance documents too
                    self.packageContainedInstances = []
                    packageContentTypeCounts = {}
                    for suffix in (".xhtml", ".htm", ".html"):
                        for potentialInstance in filesource.dir:
                            if potentialInstance.endswith(".xhtml"):
                                _type = "Inline Instance"
                                self.packageContainedInstances.append([potentialInstance, _type])
                                packageContentTypeCounts[potentialInstance] = packageContentTypeCounts.get(potentialInstance, 0) + 1
                        if self.packageContainedInstances:
                            break 
                    if self.packageContainedInstances: # add sequences to any duplicated entry types
                        for _type, count in packageContentTypeCounts.items():
                            if count > 1:
                                _dupNo = 0
                                for i in range(len(self.packageContainedInstances)):
                                    if self.packageContainedInstances[i][0] == _type:
                                        _dupNo += 1
                                        self.packageContainedInstances[i][0] = "{} {}".format(_type, _dupNo)
                                    
                else:
                    # may be a catalog file with no entry oint names
                    openType = ARCHIVE  # no entry points to show, just archive
                    self.showAltViewButton = False
            except Exception as e:
                self.close()
                err = _("Failed to parse metadata; the underlying error was: {0}").format(e)
                messagebox.showerror(_("Malformed taxonomy package"), err)
                cntlr.addToLog(err)
                return
    
        if openType not in (PLUGIN, PACKAGE):
            cntlr.showStatus(None)
        
        if openType in (DISCLOSURE_SYSTEM, PLUGIN, PACKAGE):
            y = 3
        else:
            y = 1

        okButton = Button(frame, text=_("OK"), command=self.ok)
        cancelButton = Button(frame, text=_("Cancel"), command=self.close)
        okButton.grid(row=y, column=2, sticky=(S,E,W), pady=3)
        cancelButton.grid(row=y, column=3, sticky=(S,E,W), pady=3, padx=3)
        
        if self.showAltViewButton:
            self.altViewButton = Button(frame, command=self.showAltView)
            self.altViewButton.grid(row=y, column=0, sticky=(S,W), pady=3, padx=3)
        
        self.loadTreeView(openType, colHeader, title)

        self.geometry("+{0}+{1}".format(dialogX+50,dialogY+100))
        frame.grid(row=0, column=0, sticky=(N,S,E,W))
        frame.columnconfigure(0, weight=1)
        frame.rowconfigure(0, weight=1)
        window = self.winfo_toplevel()
        window.columnconfigure(0, weight=1)
        window.rowconfigure(0, weight=1)
        
        self.bind("<Return>", self.ok)
        self.bind("<Escape>", self.close)
        
        self.toolTipText = StringVar()
        if self.hasToolTip:
            self.treeView.bind("<Motion>", self.motion, '+')
            self.treeView.bind("<Leave>", self.leave, '+')
            self.toolTipText = StringVar()
            self.toolTip = ToolTip(self.treeView, 
                                   textvariable=self.toolTipText, 
                                   wraplength=640, 
                                   follow_mouse=True,
                                   state="disabled")
            self.toolTipRowId = None

        self.protocol("WM_DELETE_WINDOW", self.close)
        self.grab_set()
        
        self.wait_window(self)

    
        
        
    def loadTreeView(self, openType, title, colHeader):
        self.title(title)
        self.openType = openType
        selectedNode = None

        # clear previous treeview entries
        for previousNode in self.treeView.get_children(""): 
            self.treeView.delete(previousNode)

        # set up treeView widget and tabbed pane
        if openType in (ARCHIVE, DISCLOSURE_SYSTEM, PLUGIN, PACKAGE):
            if openType in (PLUGIN, PACKAGE): width = 770
            else: width = 500
            self.treeView.column("#0", width=width, anchor="w")
            self.treeView.heading("#0", text=colHeader)
            self.isRss = getattr(self.filesource, "isRss", False)
            if self.isRss:
                self.treeView.column("#0", width=350, anchor="w")
                self.treeView["columns"] = ("descr", "date", "instDoc")
                self.treeView.column("descr", width=50, anchor="center", stretch=False)
                self.treeView.heading("descr", text="Form")
                self.treeView.column("date", width=170, anchor="w", stretch=False)
                self.treeView.heading("date", text="Pub Date")
                self.treeView.column("instDoc", width=200, anchor="w", stretch=False)
                self.treeView.heading("instDoc", text="Instance Document")
            elif openType == PLUGIN:
                self.treeView.column("#0", width=150, anchor="w")
                self.treeView["columns"] = ("name", "vers", "descr", "license")
                self.treeView.column("name", width=150, anchor="w", stretch=False)
                self.treeView.heading("name", text="Name")
                self.treeView.column("vers", width=60, anchor="w", stretch=False)
                self.treeView.heading("vers", text="Version")
                self.treeView.column("descr", width=300, anchor="w", stretch=False)
                self.treeView.heading("descr", text="Description")
                self.treeView.column("license", width=60, anchor="w", stretch=False)
                self.treeView.heading("license", text="License")
            elif openType == PACKAGE:
                self.treeView.column("#0", width=200, anchor="w")
                self.treeView["columns"] = ("vers", "descr", "license")
                self.treeView.column("vers", width=100, anchor="w", stretch=False)
                self.treeView.heading("vers", text="Version")
                self.treeView.column("descr", width=400, anchor="w", stretch=False)
                self.treeView.heading("descr", text="Description")
                self.treeView.column("license", width=70, anchor="w", stretch=False)
                self.treeView.heading("license", text="License")
            else:
                self.treeView["columns"] = tuple()
        
            loadedPaths = []
            for i, filename in enumerate(self.filenames):
                if isinstance(filename,tuple):
                    if self.isRss:
                        form, date, instDoc = filename[2:5]
                    elif openType == PLUGIN:
                        name, vers, descr, license = filename[3:7]
                    elif openType == PACKAGE:
                        vers, descr, license = filename[3:6]
                    filename = filename[0] # ignore tooltip
                    self.hasToolTip = True
                if filename.endswith("/"):
                    filename = filename[:-1]
                path = filename.split("/")
                if not self.isRss and len(path) > 1 and path[:-1] in loadedPaths:
                    parent = "file{0}".format(loadedPaths.index(path[:-1]))
                else:
                    parent = "" 
                node = self.treeView.insert(parent, "end", "file{0}".format(i), text=path[-1])
                if self.isRss:
                    self.treeView.set(node, "descr", form)
                    self.treeView.set(node, "date", date)
                    self.treeView.set(node, "instDoc", os.path.basename(instDoc))
                elif openType == PLUGIN:
                    self.treeView.set(node, "name", name)
                    self.treeView.set(node, "vers", vers)
                    self.treeView.set(node, "descr", descr)
                    self.treeView.set(node, "license", license)
                elif openType == PACKAGE:
                    self.treeView.set(node, "vers", vers)
                    self.treeView.set(node, "descr", descr)
                    self.treeView.set(node, "license", license)
                if self.selection == filename:
                    selectedNode = node
                loadedPaths.append(path)

        elif openType == ENTRY_POINTS:
            self.treeView.column("#0", width=200, anchor="w")
            self.treeView.heading("#0", text="Name")
    
            self.treeView["columns"] = ("url",)
            self.treeView.column("url", width=300, anchor="w")
            self.treeView.heading("url", text="URL")
            
            for fileType, fileUrl in getattr(self, "packageContainedInstances", ()):
                self.treeView.insert("", "end", fileUrl, 
                                     values=fileType, 
                                     text=fileUrl or urls[0][2])
            for name, urls in sorted(self.taxonomyPackage["entryPoints"].items(), key=lambda i:i[0][2]):
                self.treeView.insert("", "end", name, 
                                     values="\n".join(url[1] for url in urls), 
                                     text=name or urls[0][2])
                
            self.hasToolTip = True
        else: # unknown openType
            return None
        if selectedNode:
            self.treeView.see(selectedNode)
            self.treeView.selection_set(selectedNode)

        if self.showAltViewButton:
            self.altViewButton.config(text=_("Show Files") if openType == ENTRY_POINTS else _("Show Entries"))

        
    def ok(self, event=None):
        selection = self.treeView.selection()
        if len(selection) > 0:
            if hasattr(self, "taxonomyPackage"):
                # load file source remappings
                self.filesource.mappedPaths = self.taxonomyPackage["remappings"]
            filename = None
            if self.openType in (ARCHIVE, DISCLOSURE_SYSTEM):
                filename = self.filenames[int(selection[0][4:])]
                if isinstance(filename,tuple):
                    if self.isRss:
                        filename = filename[4]
                    else:
                        filename = filename[0]
            elif self.openType == ENTRY_POINTS:
                epName = selection[0]
                #index 0 is the remapped Url, as opposed to the canonical one used for display
                # Greg Acsone reports [0] does not work for Corep 1.6 pkgs, need [1], old style packages
                filenames = []
                for _url, _type in self.packageContainedInstances: # check if selection was an inline instance
                    if _type == epName:
                        filenames.append(_url)
                if not filenames: # else if it's a named taxonomy entry point
                    for url in self.taxonomyPackage["entryPoints"][epName]:
                        filename = url[0]
                        if not filename.endswith("/"):
                            # check if it's an absolute URL rather than a path into the archive
                            if not isHttpUrl(filename) and self.metadataFilePrefix != self.taxonomyPkgMetaInf:
                                # assume it's a path inside the archive:
                                filename = self.metadataFilePrefix + filename
                        filenames.append(filename)
                if filenames:
                    self.filesource.select(filenames)
                    self.accepted = True
                    self.close()
                return
            elif self.openType in (PLUGIN, PACKAGE):
                filename = self.filenames[int(selection[0][4:])][2]
            if filename is not None and not filename.endswith("/"):
                if hasattr(self, "taxonomyPackage"):
                    # attempt to unmap the filename to original file
                    # will be mapped again in loading, but this allows schemaLocation to be unmapped
                    for prefix, remapping in self.taxonomyPackage["remappings"].items():
                        if isHttpUrl(remapping):
                            remapStart = remapping
                        else:
                            remapStart = self.metadataFilePrefix + remapping
                        if filename.startswith(remapStart):
                            # set unmmapped file
                            filename = prefix + filename[len(remapStart):]
                            break
                if self.openType in (PLUGIN, PACKAGE):
                    self.filesource.selection = filename
                else:
                    self.filesource.select(filename)
                self.accepted = True
                self.close()
                        
        
    def close(self, event=None):
        self.parent.focus_set()
        self.destroy()
        
    def showAltView(self, event=None):
        if self.openType == ENTRY_POINTS:
            self.loadTreeView(ARCHIVE, _("Select Entry Point"), _("File"))
        else:
            self.loadTreeView(ENTRY_POINTS, _("Select Archive File"), _("File"))
        
    def leave(self, *args):
        self.toolTipRowId = None

    def motion(self, *args):
        tvRowId = self.treeView.identify_row(args[0].y)
        if tvRowId != self.toolTipRowId:
            text = None
            if self.openType in (ARCHIVE, DISCLOSURE_SYSTEM, PLUGIN, PACKAGE):
                self.toolTipRowId = tvRowId
                if tvRowId and len(tvRowId) > 4:
                    try:
                        text = self.filenames[ int(tvRowId[4:]) ]
                        if isinstance(text, tuple):
                            text = (text[1] or "").replace("\\n","\n")
                    except (KeyError, ValueError):
                        pass
            elif self.openType == ENTRY_POINTS:
                try:
                    text = "{0}\n{1}".format(tvRowId, 
                             "\n".join(url[1] for url in self.taxonomyPackage["entryPoints"][tvRowId]))
                except KeyError:
                    pass
            self.setToolTip(text)
                
    def setToolTip(self, text):
        self.toolTip._hide()
        if text:
            self.toolTipText.set(text)
            self.toolTip.configure(state="normal")
            self.toolTip._schedule()
        else:
            self.toolTipText.set("")
            self.toolTip.configure(state="disabled")
Exemple #17
0
class Tree(LibraryListener):
    def __init__(self, config, master):
        self.views = config['views']
        self.library = None
        self.__make_widgets(master)

    def __make_widgets(self, root):
        self.tree = Treeview(root)

    def on_library_change(self, library):
        self.library = library
        self.__make_root_nodes()

    def __make_root_nodes(self):
        for i in self.tree.get_children():
            self.tree.delete(i)
        root_nodes = self.query_library({}, self.views[0])
        for node in root_nodes:
            child = self.tree.insert("", "end", self.__make_node_id(None, self.views[0], node), text=node,
                                     tags=self.views[0])
            self.fetch_children(child)

    @staticmethod
    def __make_node_id(parent_node, node_type, node_value):
        node_id = {}
        if parent_node:
            node_id = copy(parent_node)
        node_id[node_type] = node_value
        return node_id

    def can_be_expanded(self, node_type):
        return node_type != self.views[len(self.views) - 1]

    def get_child_node_type(self, node_type):
        return self.views[self.views.index(node_type) + 1]

    def query_library(self, node_id, view):
        return self.library.aggregate(node_id, view)

    def __has_children(self, node):
        return len(self.children(node)) > 0

    def fetch_children(self, node):
        if not self.__has_children(node):
            node_type = self.tree.item(node, "tags")[0]
            if self.can_be_expanded(node_type):
                children_node_type = self.get_child_node_type(node_type)
                node_id = literal_eval(node)
                nodes = self.query_library(node_id, children_node_type)
                for child_node in nodes:
                    self.tree.insert(node, "end", self.__make_node_id(node_id, children_node_type, child_node),
                                     text=child_node, tags=children_node_type)

    def delete_children(self, parent_node):
        children = self.children(parent_node)
        for node in children:
            self.tree.delete(node)

    @property
    def selected_node(self):
        if len(self.tree.selection()):
            return self.tree.selection()[0]

    def children(self, node):
        return self.tree.get_children(node)
Exemple #18
0
class NameView(object):
    """Shows a treeview of unique names."""

    def __init__(self, master, names):
        self.widget = Frame(master)
        self._tree = Treeview(self.widget, columns='name')
        self._tree.grid(row=0,column=0, sticky=(N,S,W,E))
        self._tree.view = self
        self.widget.columnconfigure(0, weight=1)
        self.widget.rowconfigure(0,weight=1)
        self._tree.column('name', width=50)
        self._tree['show'] = 'tree'
        actions = {'edit': lambda e: self.edit(),
                'search': lambda e: self.search(),
                'focus_next': lambda e: self.focus_next(),
                'focus_prev': lambda e: self.focus_prev(),
                'select': lambda e: self._tree.selection_toggle(self._tree.focus()),
                'clear_selection': lambda e: self._tree.selection_set([])
                }
        kb.make_bindings(kb.tagview, actions, self._tree.bind)
        self._iids = dict()
        self._names = dict()
        logger.debug('Names: %s', names)
        self.widget.focus_set = self._tree.focus_set
        for name in sorted(names):
            iid = self._tree.insert('', 'end', text=name)
            self._names[iid] = name
            self._iids[name] = iid
        self._scroll = Scrollbar(self.widget, command=self._tree.yview)
        self._tree['yscrollcommand'] = self._scroll.set
        self._scroll.grid(row=0, column=1, sticky=(N, S))
        self.widget.columnconfigure(1, weight=0)


    def selection(self):
        logger.debug('Selection: %s', self._tree.selection())
        return [self._names[iid] for iid in self._tree.selection()]

    def edit(self):
        self._tree.event_generate('<<NameViewEdit>>')

    def search(self):
        if len(self._tree.selection()) == 0:
            self._tree.selection_add(self._tree.focus())
        self._tree.event_generate('<<NameViewSearch>>')

    def append(self, names):
        logger.debug('Append names: %s', names)
        for name in names:
            if name not in self._names.values():
                iid = self._tree.insert('', 'end', text=name)
                self._names[iid] = name
                self._iids[name] = iid

    def delete(self, name):
        self._tree.delete(self._iids[name])
        del self._names[self._iids[name]]
        del self._iids[name]

    def _focus(self, iid):
        self._tree.focus(iid)
        self._tree.see(iid)

    def focus_next(self):
        cur_iid = self._tree.focus()
        next_iid = self._tree.next(cur_iid)
        if next_iid == '':
            iids = self._tree.get_children()
            next_iid = iids[0]
        self._focus(next_iid)

    def focus_prev(self):
        cur_iid = self._tree.focus()
        prev_iid = self._tree.prev(cur_iid)
        if prev_iid == '':
            iids = self._tree.get_children()
            prev_iid = iids[-1]
        self._focus(prev_iid)

    def jump_to(self, name):
        try:
            iid = self._iids[name]
            self._focus(iid)
        except KeyError:
            pass

    def get_names(self):
        return tuple(self._names.values())

    def set(self, names):
        self._tree.delete(*self._iids.values())
        self._iids.clear()
        self._names.clear()
        for name in sorted(names):
            iid = self._tree.insert('', 'end', text=name)
            self._names[iid] = name
            self._iids[name] = iid
Exemple #19
0
class show:
    def __init__(self):
        self.window=Tk()
        self.window.title("Show | Products Quantity")
        self.window.iconbitmap('shop.ico')
        self.window.geometry("1365x700+0+0")
        self.window.maxsize(1365,700)
        self.window.minsize(1365,700)
        # self.window.resizable(width=False,height=False)
    def add_background(self):
        self.image = Image.open("images/back.jpg")
        self.image = self.image.resize((1365, 700), Image.ANTIALIAS)
        self.img = ImageTk.PhotoImage(self.image)
        self.li = Label(image = self.img, text="TALHA")
        self.li.image = self.img
        self.li.pack()
        self.Menubar()

    def Menubar(self):
        self.menubar = Menu()
        self.menuitems_add = Menu(self.menubar, tearoff=0,bg="blue",fg="white")
        self.menuitems_add.add_command(label="Add Products", command=self.add_products)
        # self.menuitems.add_separator()

        self.menuitems_sales = Menu(self.menubar, tearoff=0,bg="blue",fg="white")
        self.menuitems_sales.add_command(label="Sale Products", command=self.sales_products)

        self.menuitems_customer = Menu(self.menubar, tearoff=0, bg="blue", fg="white")
        self.menuitems_customer.add_command(label="Add Customer", command=self.add_customer)
        self.menuitems_customer.add_command(label="Show Customer Records", command=self.customer_record)

        self.menuitems_reports = Menu(self.menubar, tearoff=0, bg="blue", fg="white")
        self.menuitems_reports.add_command(label="Check Products Quantity", command=self.check_products_quantity)
        self.menuitems_reports.add_command(label="Check Profit/Loss", command=self.check_profit_loss)
        self.menuitems_reports.add_command(label="Check Sales Products", command=self.check_products_sales)
        self.menuitems_reports.add_command(label="Check Sent Amount Details", command=self.check_amount)

        self.menubar.add_cascade(label="Add Products", menu=self.menuitems_add)
        self.menubar.add_cascade(label="Sales Products", menu=self.menuitems_sales)
        self.menubar.add_cascade(label="Customer", menu=self.menuitems_customer)
        self.menubar.add_cascade(label="Reports", menu=self.menuitems_reports)
        self.menubar.add_cascade(label="Exit", command=quit)
        self.window.config(menu=self.menubar)

    def add_table(self):
        self.l1=Label(self.window,text="**Products Quantity**",font="Courier 25 bold",bg="black",fg="white",width=61)
        self.l1.place(x=82,y=20)

        self.l1 = Label(self.window, text="Developed by : Muhammad Talha | NTU", font="Courier 10 bold")
        self.l1.place(x=280, y=610)

        self.l1 = Label(self.window, text="Enter Product Name:", font="courier 16 bold",bg="blue",fg="white")
        self.l1.place(x=280, y=90)

        self.Entry_reg = Entry(self.window, font="courior 14 bold")
        self.Entry_reg.place(x=550, y=90, height=30)

        self.b1 = Button(self.window, text="Search", font="Times 13 bold",fg="white",bg="blue",width=10)
        self.b1.place(x=790, y=90)
        self.b1.bind('<Button-1>', self.search_product)


        # for Style Table
        style = Style()
        style.configure("mystyle.Treeview", highlightthickness=0, bd=0,
                        font=('courier 12 bold'),rowheight=43)  # Modify the font of the body
        style.configure("mystyle.Treeview.Heading", font=('Times 15 bold'),foreground="black")  # Modify the font of the headings
        # style.layout("mystyle.Treeview", [('mystyle.Treeview.treearea', {'sticky': 'nswe'})])  # Remove the borders
        # import TreeViewe
        self.tr=Treeview(self.window,columns=('A','B','C'),selectmode="extended",style='mystyle.Treeview')
        # heading key+text
        self.tr.heading("#0", text="Sr.No")
        self.tr.column("#0", minwidth=0, width=85, stretch=NO)

        self.tr.heading("#1",text="Product Name")
        self.tr.column("#1",minwidth=0,width=160,stretch=NO)

        self.tr.heading("#2", text="Product Catagory")
        self.tr.column("#2", minwidth=0, width=200, stretch=NO)

        self.tr.heading("#3", text="Total Quantity")
        self.tr.column("#3", minwidth=0, width=175, stretch=NO)


        j=1
        for i in Database.show_product_details():
            self.tr.insert('',index=j,text=j,values=(i[1],i[2],i[3]))
            j+=1

        self.Entry_reg.bind('<KeyRelease>', self.remove)


        self.sb = Scrollbar(self.tr)
        self.sb.place(x=600,y=2,height=452,width=22,bordermode=OUTSIDE)
        self.sb.config(command=self.tr.yview)
        self.tr.config(yscrollcommand=self.sb.set)
        self.tr.place(x=280,y=150)

        # to excel file
        self.b1 = Button(self.window, text="Save to Excel", font="Times 12 bold",bg="blue",fg="white",width=20,
        )
        self.b1.place(x=713, y=610)
        self.b1.bind('<Button-1>', self.excel)


        self.window.mainloop()

    def remove(self,event):
        for row in self.tr.get_children():
            self.tr.delete(row)
        j = 1
        for i in Database.show_product_details():
            self.tr.insert('', index=j, text=j, values=(i[1], i[2], i[3]))
            j += 1

    def search_product(self,event):
        try:
            data = (self.Entry_reg.get(),)
            if self.Entry_reg.get() == "":
                msg.showwarning("Message ! ", "please insert product name !")
            else:
                j = 1
                D = Database.search_details(data)
                if D:
                    for row in self.tr.get_children():
                        self.tr.delete(row)
                    self.Entry_reg.delete(0, END)
                    for i in D:
                        self.tr.insert('', index=j, text=j, values=(i[1],i[2],i[3]))
                        j += 1
                else:
                    msg.showwarning("Message!", "No result Found!")

        except:
            msg.showwarning("Error!", "Something went wrong! please contact with developer !!!")
    def excel(self,event):
        try:
            x=Database.show_product_details()
            p_name=[]
            p_catagory=[]
            p_quantity=[]
            for i in range(len(x)):
                z=x.__getitem__(i)
                p_name.append(z[1])
                p_catagory.append(z[2])
                p_quantity.append(z[3])

            products = pd.DataFrame({
                "Product Name": p_name,
                "Product Catagory":p_catagory,
                "Total Quantity":p_quantity,
            })

            with pd.ExcelWriter("Excel Files/Products_Quantity.xlsx") as writer:
                products.to_excel(writer, sheet_name="Products_Quantity", index=False)
            msg.showinfo("Message ! ", "Your data has been inserted Susccessfully !")
        except:
            msg.showwarning("Message!","Something Went Wrong!please contact with developer!!!")

    def add_products(self):
        self.window.destroy()
        home = Home.data()
        home.add_background()
        home.add_frame()

    def sales_products(self):
        self.window.destroy()
        showP = Showing_Records.show()
        showP.add_background()
        showP.add_table()
    def check_products_quantity(self):
        pass
    def check_products_sales(self):
        self.window.destroy()
        showP = Check_Sales_Products.show()
        showP.add_background()
        showP.add_table()
    def check_profit_loss(self):
        self.window.destroy()
        showP = Check_Profit_Loss_GUI.show()
        showP.add_background()
        showP.add_table()
    def check_amount(self):
        self.window.destroy()
        showP = Check_Amount_Details.show()
        showP.add_background()
        showP.add_table()

    def add_customer(self):
        self.window.destroy()
        home = Add_Customer.data()
        home.add_background()
        home.add_frame()
    def customer_record(self):
        self.window.destroy()
        showP = Customer_Records.show()
        showP.add_background()
        showP.add_table()
Exemple #20
0
class tabel():
    def __init__(self,data,y,m):
        w=Toplevel()
        w.geometry('{0}x{1}+0+0'.format(120+25*21,w.winfo_screenheight()-80))
        
        w.columnconfigure(0,weight=1)
        w.rowconfigure(0,weight=1)
        
        d=data[y][m]
        v='план'
        if 'табель' in d['degur']:
            v='табель'
        w.wm_title('{0} {1} {2}'.format(v,y,m))
        #deg=data['2013']['11']['degurs']  # ЗАГЛУШКА : список дежурных
        deg=d['degurs']  # ЗАГЛУШКА : список дежурных
        cc=list(range(1,17))
        cols=[str(c) for c in cc]+['s','сум','ноч','пра','доп']
        
        self.t=Treeview(w,columns=cols)
        self.t.column('#0',width=100)
        for c in cols:
            self.t.heading(c,text=c)
            self.t.column(c,width=25,anchor='center')
        self.t.tag_configure('title',background='gray')
        self.scrX=Scrollbar(w,orient='horizontal',command=self.t.xview)
        self.scrY=Scrollbar(w,orient='vertical',command=self.t.yview)
        self.t['xscrollcommand']=self.scrX.set
        self.t['yscrollcommand']=self.scrY.set
        self.t.grid(row=0,column=0,sticky=N+S+E+W)
        self.scrX.grid(row=1,column=0,sticky=E+W)
        self.scrY.grid(row=0,column=1,sticky=N+S)

        rez=dict()
        for j,s in d['degur'][v].items():
                rez[j]=analyse2(s,d)
        for j in deg:
            ww1=[]
            ww2=[]
            a=0
            nn1=[]
            for x in d['degur'][v].get(j,''):
                if a:
                    if x=='Д':
                        ww1.append('!!')
                        nn1+=[0,0]
                        y=a+12
                        a=0
                    elif x in [str(xx) for xx in range(1,10)]:
                        ww1.append('Я')
                        nn1+=[0,0]
                        y=a+int(x)
                        a=0
                    elif x=='Н':
                        ww1.append('!')
                        nn1+=[2,6]
                        y=a+4
                        a=8
                    elif x=='-':
                        ww1.append('Н')
                        nn1+=[0,0]
                        y=a+0
                        a=0
                    else:
                        ww1.append('!')
                        nn1+=[0,0]
                        y=a+0
                        a=0
                else:
                    if x=='Д':
                        ww1.append('Я')
                        nn1+=[0,0]
                        y=12
                        a=0
                    elif x in [str(xx) for xx in range(1,10)]:
                        ww1.append('Я')
                        nn1+=[0,0]
                        y=int(x)
                        a=0
                    elif x=='Н':
                        ww1.append(x)
                        nn1+=[2,6]
                        y=4
                        a=8
                    elif x=='-':
                        ww1.append('В')
                        nn1+=[0,0]
                        y=0
                        a=0
                    else:
                        ww1.append(x)
                        nn1+=[0,0]
                        y=0
                        a=0
                ww2.append(y)
            ww=rez.get(j,(0,0,0,0))[0]
            ee=rez.get(j,(0,0,0,0))[0] -rez.get(j,(0,0,0,0))[3]
            #ee=rez.get(j,(0,0,0,0))[3]
            nn=rez.get(j,(0,0,0,0))[1]
            hh=rez.get(j,(0,0,0,0))[2]
            s1=sum([x and 1 for x in ww2[1:16]])
            s2=sum([x and 1 for x in ww2[16:-1]])
            n0=sum([x=='Н' and 1 or 0 for x in ww1[1:-1]])

            z=self.t.insert('','end',text=j)
            self.t.insert(z,'end',text='',values=list(range(1,16)),tag='title')
            self.t.insert(z,'end',text='',values=ww1[1:16]+['',s1])
            self.t.insert(z,'end',text='',values=[x or '-' for x in ww2[1:16]]+ \
                    ['']+[sum(ww2[1:16])])
            self.t.insert(z,'end',text='',values=list(range(16,32)),tag='title')
            self.t.insert(z,'end',text='',values=ww1[16:-1]+['']*(33-len(ww1))+ \
                    [s2,s1+s2,n0])
            self.t.insert(z,'end',text='',values=[x or '-' for x in ww2[16:-1]]+ \
                    ['']*(16-len(ww2[16:-1]))+[sum(ww2[16:-1]),sum(ww2[1:-1]),sum(nn1[1:-3]),hh,ee])
Exemple #21
0
class ShowWindow:
    def __init__(self):
        self.win = Toplevel()
        canvas = Canvas(self.win, width=800, height=400, bg='white')
        canvas.pack(expand=YES, fill=BOTH)

        # show window in center of screen
        width = self.win.winfo_screenwidth()
        height = self.win.winfo_screenheight()
        x = int(width / 2 - 800 / 2)
        y = int(height / 2 - 400 / 2)
        str1 = "800x400+" + str(x) + "+" + str(y)
        self.win.geometry(str1)

        # Disable resize of the window
        self.win.resizable(width=False, height=False)
        self.win.title("truTrackerEXP | SHOW INCOME SOURCES")

    def add_frame(self):

        self.frame = Frame(self.win, width=600, height=350)
        self.frame.place(x=80, y=20)

        x, y = 70, 20

        # Use treeview to show the data in forms of table
        # Mention number of columns
        self.tr = Treeview(self.frame,
                           columns=('A', 'B', 'C', 'D'),
                           selectmode="extended")

        #  Heading key + text
        self.tr.heading('#0', text='Sr No')
        self.tr.column('#0', minwidth=0, width=40, stretch=NO)
        self.tr.heading('#1', text='Source')
        self.tr.column('#1', minwidth=0, width=100, stretch=NO)
        self.tr.heading('#2', text='Description')
        self.tr.column('#2', minwidth=0, width=200, stretch=NO)
        self.tr.heading('#3', text='Update')
        self.tr.column('#3', minwidth=0, width=60, stretch=NO)
        self.tr.heading('#4', text='Delete')
        self.tr.column('#4', minwidth=0, width=60, stretch=NO)

        j = 0
        for i in db.db.show_income():
            self.tr.insert('',
                           index=j,
                           text=i[2],
                           values=(i[0], i[1], 'Update', 'Delete'))
            j += 1

        # Create action on selected row
        self.tr.bind('<Double-Button-1>', self.actions)

        # Position the table on the frame
        self.tr.place(x=50, y=y + 50)

        self.win.mainloop()

    def actions(self, e):
        # Get the value of the selected row
        tt = self.tr.focus()

        # Get the column id
        col = self.tr.identify_column(e.x)
        print(compile)
        print(self.tr.item(tt))

        tup = (self.tr.item(tt).get('text'), )

        if col == '#4':
            res = messagebox.askyesno("Message",
                                      "Are you sure you want to delete?")
            if res:
                rs = db.db.delete_income(tup)
                if rs:
                    messagebox.showinfo("Message", "Data has been deleted.")
                    self.win.destroy()
                    z = ShowWindow()
                    z.add_frame()
            else:
                self.win.destroy()
                z = ShowWindow()
                z.add_frame()

        if col == '#3':
            res = income.add_income.IncomeWindow(self.tr.item(tt))
            self.win.destroy()
            res.add_frame()
fr0.grid_rowconfigure(0, weight=1)

# insert header, data and tag configuration
for ix,col in enumerate(tree_columns):
    tree.heading(col, text=col.title(),
       command=lambda c=col: sort_by(tree, c, 0))
    #tree.column(col,stretch=True)
    #tree.column(col,width=font.nametofont('TkHeadingFont').measure(col.title()),
                #stretch=False)
    tree.column(col,width=font.Font(family=font_family,size=font_size,weight='bold').measure(col.title()) + 10,
                stretch=False)
    #print(tree.column(col))

# insert data row by row, then measure each items' width
for ix, item in enumerate(tree_data):
    item_ID = tree.insert('', 'end', values=item)
    tree.item(item_ID, tags=item_ID)
    tree.tag_configure(item_ID, background=backg[ix%2])

    for indx, val in enumerate(item):
        #ilen = font.Font(family="Segoe UI", size=10, weight="normal").measure(val)
        ilen = font.nametofont('TkDefaultFont').measure(val)
        if tree.column(tree_columns[indx], width=None) < ilen +10:
            tree.column(tree_columns[indx], width=ilen + 10)
        # you should see the widths adjust
        #print('col',tree.column(tree_columns[indx]),ilen)

# display selection
lvar = StringVar()
lbl = Label(fr0, textvariable=lvar, text="Ready")
lbl.grid(column=0, row=2, sticky='nsew')
Exemple #23
0
class BioInfo(Tk):
    def __init__(self):
        Tk.__init__(self)
        self.wm_title("BioInfo : comparaison des listes")
        self.resizable(width=FALSE, height=FALSE)
        self.SortDir = False

        # Lists Types
        self.typeList1 = None
        self.typeList2 = None

        # Frame content
        self.frameContent = Frame(self)
        self.frameContent.pack(side=TOP, fill=X)

        # ScrollBar
        scrollbar = Scrollbar(self.frameContent, orient=VERTICAL)
        scrollbar.pack(side=RIGHT, fill=Y)

        # Result Content
        self.dataCols = ('microArn_A', 'microArn_B', 'FoldC', 'p-Value', 'Note')
        self.tree = Treeview(self.frameContent, columns=self.dataCols, show = 'headings', yscrollcommand=scrollbar.set)

        # configure column headings
        for c in self.dataCols:
            self.tree.heading(c, text=c, command=lambda c=c: self.columnSort(c, self.SortDir))
            self.tree.column(c, width=10)

        self.tree.pack(side=LEFT, fill=X, expand="yes")

        scrollbar.config(command=self.tree.yview)

        # Frame Lists
        self.frameLists = Frame(self)
        self.frameLists.pack(side=LEFT)

        # Frame Forms
        self.frameForms = Frame(self)
        self.frameForms.pack(side=LEFT, padx=20)

        #Liste n°1 selection
        self.frameList1 = Frame(self.frameLists)
        self.frameList1.pack()

        self.typeListStr1 = StringVar(self.frameList1)
        self.typeListStr1.set(str(ListBioType.TypeA))

        self.buttonTypeList1 = OptionMenu(self.frameList1, self.typeListStr1, str(ListBioType.TypeA), str(ListBioType.TypeB)).pack(side=LEFT)

        self.entrylist1 = Entry(self.frameList1, width=30)
        self.entrylist1.pack(side=LEFT)

        self.buttonBrowseList1 = Button(self.frameList1, text="Parcourir", command=self.load_fileList1, width=10)
        self.buttonBrowseList1.pack(side=LEFT, padx=5)

        # List n°2 selection
        self.frameList2 = Frame(self.frameLists)
        self.frameList2.pack(side=BOTTOM)

        self.typeListStr2 = StringVar(self.frameList2)
        self.typeListStr2.set(str(ListBioType.TypeB))

        self.buttonTypeList2 = OptionMenu(self.frameList2, self.typeListStr2, str(ListBioType.TypeA), str(ListBioType.TypeB)).pack(side=LEFT)

        self.entrylist2 = Entry(self.frameList2, width=30)
        self.entrylist2.pack(side=LEFT)

        self.buttonBrowseList2 = Button(self.frameList2, text="Parcourir", command=self.load_fileList2, width=10)
        self.buttonBrowseList2.pack(side=LEFT, padx=5)

        # Form pValue
        self.framePVal = Frame(self.frameForms)
        self.framePVal.pack()

        Label(self.framePVal, text="pValue").pack(side=LEFT)
        self.entryPVal = Entry(self.framePVal, width=6)
        self.entryPVal.pack(side=LEFT)

        # Form foldC
        self.frameFoldC = Frame(self.frameForms)
        self.frameFoldC.pack()

        Label(self.frameFoldC, text="foldCh").pack(side=LEFT)
        self.entryFoldC = Entry(self.frameFoldC, width=6)
        self.entryFoldC.pack(side=LEFT)

        # Form note
        self.frameNote = Frame(self.frameForms)
        self.frameNote.pack()

        Label(self.frameNote, text="note    ").pack(side=LEFT)
        self.entryNote = Entry(self.frameNote, width=6)
        self.entryNote.pack(side=LEFT)

        # Bouton comparer
        self.buttonComparer = Button(self, text="Comparer", command=self.compare, width=10, state=DISABLED)
        self.buttonComparer.pack(fill= X, expand="yes", padx=20, pady=(10,0))

        #Bouton exporter
        self.buttonExport = Button(self, text="Exporter", command=self.export, width=10, state=DISABLED)
        self.buttonExport.pack(fill= X, expand="yes", padx=20)

        # Réinitialiser
        self.buttonReset = Button(self, text="Réinitialiser", command=self.reset, width=10)
        self.buttonReset.pack(fill= X, expand="yes", padx=20, pady=(0,10))

        # file members
        self.list1 = None
        self.list2 = None

    def load_fileList1(self):
        fname = askopenfilename(filetypes=(("CSV files", "*.csv"),
                                           ("All files", "*.*") ))
        if fname:
            self.entrylist1.delete(0, END)
            self.list1 = fname
            self.entrylist1.insert(0,fname)

            self.buttonComparer.config(state=NORMAL)


    def load_fileList2(self):
        fname = askopenfilename(filetypes=(("CSV files", "*.csv"),
                                           ("All files", "*.*") ))
        if fname:
            self.entrylist2.delete(0, END)
            self.list2 = fname
            self.entrylist2.insert(0,fname)

            self.buttonComparer.config(state=NORMAL)

        else:
            showerror("Erreur : fichier B", "La liste B est introuvable")


    def resetTree (self):
        for i in self.tree.get_children():
            self.tree.delete(i)

    def reset(self):
        self.list1 = None
        self.entrylist1.delete(0, END)

        self.list2 = None
        self.entrylist2.delete(0, END)

        self.entryPVal.delete(0,END)
        self.entryFoldC.delete(0, END)
        self.entryNote.delete(0, END)

        self.typeList1 = None
        self.typeList2 = None

        self.buttonExport.config(state=DISABLED)
        self.buttonComparer.config(state=DISABLED)

        self.resetTree()

    def isValidfoldC(self, s):
        try:
            float(s)
            return True
        except ValueError:
            return False

    def isValidPValue(self, s):
        try:
            f = float(s)
            if f >= 0 and f <= 1:
                return True
            else:
                return False
        except:
            return False

    def isValidNote (self, s):
        try:
            f = int(s)
            return True
        except:
            return False

    def compare(self):
        self.buttonExport.config(state=NORMAL)

        # Détermination type Listes

        # List 1

        if self.typeListStr1.get() == str(ListBioType.TypeA):
            self.typeList1 = ListBioType.TypeA
        elif self.typeListStr1.get() == str(ListBioType.TypeB):
            self.typeList1 = ListBioType.TypeB
        else:
            self.typeList1 = None

        # List 2
        if self.typeListStr2.get() == str(ListBioType.TypeA):
            self.typeList2 = ListBioType.TypeA
        elif self.typeListStr2.get() == str(ListBioType.TypeB):
            self.typeList2 = ListBioType.TypeB
        else:
            self.typeList2 = None


        if not self.isValidfoldC(self.entryFoldC.get()) and not self.entryFoldC.get() == "":
            showerror("Erreur : foldC","La valeur fold Change n'est pas un nombre")

        elif not self.isValidPValue(self.entryPVal.get()) and not self.entryPVal.get() == "":
            showerror("Erreur : pValue","La valeur pValue n'est pas un nombre compris entre 0 et 1")

        elif not self.isValidNote(self.entryNote.get()) and not self.entryNote.get() == "":
            showerror("Erreur : note", "La valeur note n'est pas un nombre entier")

        # (List A and No List) or (No List and List A)
        elif ((self.list1 is not None and self.typeList1 == ListBioType.TypeA) and (self.list2 is None)) or\
             ((self.list2 is not None and self.typeList2 == ListBioType.TypeA) and (self.list1 is None)):

            self.resetTree()

            try:
                listComp = ListComparator(self.list1, self.list2, self.entryPVal.get(), self.entryFoldC.get(), self.entryNote.get())
                for e in listComp.getFilterListA():
                    self.tree.insert('', 'end', values=e)

            except IndexError:
                showerror("Erreur : liste A invalide", "Le fichier liste A n'est pas un fichier valide")


        # (List B and No List) or (No List and List B)
        elif ((self.list1 is not None and self.typeList1 == ListBioType.TypeB) and (self.list2 is None)) or\
             ((self.list2 is not None and self.typeList2 == ListBioType.TypeB) and (self.list1 is None)):

            self.resetTree()

            try:
                listComp = ListComparator(self.list1, self.list2, self.entryPVal.get(), self.entryFoldC.get())
                for e in listComp.getFilterListB():
                    self.tree.insert('', 'end', values=e)
            
            except IndexError:
                showerror("Erreur : liste A invalide", "Le fichier liste A n'est pas un fichier valide")

        # (List A and List B) or (List B and List A)
        elif ((self.list1 is not None and self.typeList1 == ListBioType.TypeA) and \
             (self.list2 is not None and self.typeList2 == ListBioType.TypeB)) or \
             ((self.list1 is not None and self.typeList1 == ListBioType.TypeB) and \
             (self.list2 is not None and self.typeList2 == ListBioType.TypeA)):

            self.resetTree()

            listA = ""
            listB = ""
            if self.typeList1 == ListBioType.TypeA:
                listA = self.list1
            else:
                listA = self.list2

            if self.typeList1 == ListBioType.TypeB:
                listB = self.list1
            else:
                listB = self.list2
            try:
                listComp = ListComparator(listA, listB, self.entryPVal.get(), self.entryFoldC.get(), self.entryNote.get())
                for e in listComp.getDiffAandB():
                    self.tree.insert('', 'end', values=e)

            except IndexError:
                showerror("Erreur : liste A ou B invalide", "Le fichier liste A ou B n'est pas un fichier valide")

        # (List A and List A)
        elif ((self.list1 is not None and self.typeList1 == ListBioType.TypeA) and \
             (self.list2 is not None and self.typeList2 == ListBioType.TypeA)):

            self.resetTree()

            try:
                listComp = ListComparator(self.list1, self.list2, self.entryPVal.get(), self.entryFoldC.get(), self.entryNote.get())
                for e in listComp.getDiffAandA():
                    self.tree.insert('', 'end', values=e)

            except IndexError:
                showerror("Erreur : liste A ou B invalide", "Le fichier liste A ou B n'est pas un fichier valide")

        # (List B and List B)
        elif ((self.list1 is not None and self.typeList1 == ListBioType.TypeB) and \
             (self.list2 is not None and self.typeList2 == ListBioType.TypeB)):

            self.resetTree()

            try:
                listComp = ListComparator(self.list1, self.list2, self.entryPVal.get(), self.entryFoldC.get())
                for e in listComp.getDiffBandB():
                    self.tree.insert('', 'end', values=e)

            except IndexError:
                showerror("Erreur : liste A ou B invalide", "Le fichier liste A ou B n'est pas un fichier valide")
        else:
            showerror("Erreur : Combinaisons de listes invalides", "Votre choix de types de listes ne correspond à aucune combinaison possible, contacter le developpeur")


    def export(self):
        if len(self.tree.get_children()) == 0:
            showinfo("Export", "Il n'y a rien à exporter")
            return

        fname = asksaveasfilename(filetypes=(("CSV files", "*.csv"),
                                             ("All files", "*.*") ))

        if fname:
            resExp = []
            for it in self.tree.get_children():
                resExp.append(self.tree.item(it)["values"])

            expTabToCSV = TreeExportator(resExp, fname)
            expTabToCSV.export()

            showinfo("Export", "Exportation au format CSV réussi")

    def columnSort (self, col, descending=False):
        data = [(self.tree.set(child, col), child) for child in self.tree.get_children('')]

        data.sort(reverse=descending)
        for indx, item in enumerate(data):
            self.tree.move(item[1], '', indx)

        # reverse sort direction for next sort operation
        self.SortDir = not descending
class IncomeGUI(Frame):   
    inDB = incomeDB()

    def createIncome(self):
        addIncome = Button(self, text="Add income", command=lambda: self.sequence(self.addMonth))
        addIncome.pack(fill=X, padx=10, pady=20)

        incomeButton = Button(self, text="View income", command =lambda: self.sequence(self.viewIncome))
        incomeButton.pack(fill=X, padx=10, pady=5)

        backButton = Button(self, text="Back")
        backButton.pack(side=BOTTOM)

    def addMonth(self):
        monthlabel = Label(self, text = "Select Month: ")
        monthlabel.pack()
        self.monthChoice = IntVar(self)
        months = self.numberings(1, 12)
        self.monthChoice.set(1) 
        self.monthInput = OptionMenu(self, self.monthChoice, *months)
        self.monthInput.pack()
        yearlabel = Label(self, text = "Select Year: ")
        yearlabel.pack()
        self.yearChoice = IntVar(self)
        years = self.numberings(2000, 2020)
        self.yearChoice.set(2000) 
        self.yearInput = OptionMenu(self, self.yearChoice, *years)
        self.yearInput.pack()
        

        nextButton = Button(self, text="Next", command=lambda: self.sequence(self.addIncome))
        nextButton.pack()
        backButton = Button(self, text="Back", command=lambda: self.sequence(
            self.createIncome))
        backButton.pack()

    def addIncome(self):
        month = self.monthChoice.get()
        self.income = income(month)
        self.income.year = self.yearChoice.get()

        amountlabel = Label(self, text="Amount of items sold this month: ")
        amountlabel.pack()
        self.amountinput = Entry(self)
        self.amountinput.pack()

        incomelabel = Label(self, text="Income earned: ")
        incomelabel.pack()
        self.incomeinput = Entry(self)
        self.incomeinput.pack()

        nextButton = Button(self, text="Next",
                            command= self.saveDetails)
        nextButton.pack()
        backButton = Button(self, text="Back", command=lambda: self.sequence(
            self.createIncome))
        backButton.pack()

    def saveDetails(self):
        self.income.amount = self.amountinput.get()
        self.income.income = self.incomeinput.get()
        self.sequence(self.confirmation)

    def confirmation(self):

        year = Label(self, text="Year: ")
        year.pack()
        yearin = Label(self, text=self.income.year)
        yearin.pack()

        month = Label(self, text="Month: ")
        month.pack()
        monthin = Label(self, text=self.income.month)
        monthin.pack()

        quantity = Label(self, text="Amount of items sold this month: ")
        quantity.pack()
        itemQuantity = Label(self, text=self.income.amount)
        itemQuantity.pack()

        price = Label(self, text="Income earned: ")
        price.pack()
        itemPrice = Label(self, text=self.income.income)
        itemPrice.pack()        

        nextButton = Button(self, text="Next",
                            command=lambda: self.sequence(self.addToIncomeDatabase))
        nextButton.pack()
        backButton = Button(self, text="Back", command=lambda: self.sequence(
            self.createIncome))
        backButton.pack()

    def addToIncomeDatabase(self):
        self.incomeDB.insertIntoDB(self.income)

        addedMessage = Message(self, text = "Added to database!")
        addedMessage.pack()

        endSessionButton = Button(self, text = "End Session", command=lambda: self.sequence(self.createIncome))
        endSessionButton.pack()

    def viewIncome(self):
        self.tree = Treeview(height="20", columns=("Year", "Month", "Income"))
        self.tree.pack()
        self.tree.heading('#1', text = "Year", anchor = CENTER)
        self.tree.heading('#2', text = "Month", anchor = CENTER)
        self.tree.heading('#3', text = "Income", anchor = CENTER)
        self.tree.column('#1', minwidth=0, width = 100)
        self.tree.column('#2', minwidth=0, width = 100)
        self.tree.column('#3', minwidth=0, width = 100)
        self.tree.column('#0', minwidth=0, width = 0)

        for row in (self.incomeDB.getInfo()):
            year = row[1]
            month = row[0]
            income = row[3]

            self.tree.insert("", "end", values = (year,month,income))

        backButton = Button(self, text="Back", command=lambda: self.sequence(
            self.createIncome))
        backButton.pack()
        

    def sequence(self, funct):
        for child in self.winfo_children():
            child.destroy()
        funct()

    def numberings(self, first, last):
        num = range(first, last + 1)
        return num

    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        self.createIncome()
        self.incomeDB = incomeDB()
        #self.incomeDB.createDB()
        self.master.title("Income")
class DialogPackageManager(Toplevel):
    def __init__(self, mainWin, packageNamesWithNewerFileDates):
        super(DialogPackageManager, self).__init__(mainWin.parent)
        
        self.ENABLE = _("Enable")
        self.DISABLE = _("Disable")
        self.parent = mainWin.parent
        self.cntlr = mainWin
        
        # copy plugins for temporary display
        self.packagesConfig = PackageManager.packagesConfig
        self.packagesConfigChanged = False
        self.packageNamesWithNewerFileDates = packageNamesWithNewerFileDates
        
        parentGeometry = re.match("(\d+)x(\d+)[+]?([-]?\d+)[+]?([-]?\d+)", self.parent.geometry())
        dialogX = int(parentGeometry.group(3))
        dialogY = int(parentGeometry.group(4))

        self.title(_("Taxonomy Packages Manager"))
        frame = Frame(self)
        
        # left button frame
        buttonFrame = Frame(frame, width=40)
        buttonFrame.columnconfigure(0, weight=1)
        addLabel = Label(buttonFrame, text=_("Find taxonomy packages:"), wraplength=64, justify="center")
        addLocalButton = Button(buttonFrame, text=_("Locally"), command=self.findLocally)
        ToolTip(addLocalButton, text=_("File chooser allows selecting taxonomy packages to add (or reload), from the local file system.  "
                                       "Select either a taxonomy package zip file, or a taxonomy manifest (.taxonomyPackage.xml) within an unzipped taxonomy package.  "), wraplength=240)
        addWebButton = Button(buttonFrame, text=_("On Web"), command=self.findOnWeb)
        ToolTip(addWebButton, text=_("Dialog to enter URL full path to load (or reload) package, from the web or local file system.  "
                                     "URL may be either a taxonomy package zip file, or a taxonomy manifest (.taxonomyPackage.xml) within an unzipped taxonomy package.  "), wraplength=240)
        manifestNameButton = Button(buttonFrame, text=_("Manifest"), command=self.manifestName)
        ToolTip(manifestNameButton, text=_("Provide non-standard archive manifest file name pattern (e.g., *taxonomyPackage.xml).  "
                                           "Uses unix file name pattern matching.  "
                                           "Multiple manifest files are supported in archive (such as oasis catalogs).  "
                                           "(Replaces search for either .taxonomyPackage.xml or catalog.xml).  "), wraplength=240)
        self.manifestNamePattern = ""
        addLabel.grid(row=0, column=0, pady=4)
        addLocalButton.grid(row=1, column=0, pady=4)
        addWebButton.grid(row=2, column=0, pady=4)
        manifestNameButton.grid(row=3, column=0, pady=4)
        buttonFrame.grid(row=0, column=0, rowspan=3, sticky=(N, S, W), padx=3, pady=3)
        
        # right tree frame (packages already known to arelle)
        packagesFrame = Frame(frame, width=700)
        vScrollbar = Scrollbar(packagesFrame, orient=VERTICAL)
        hScrollbar = Scrollbar(packagesFrame, orient=HORIZONTAL)
        self.packagesView = Treeview(packagesFrame, xscrollcommand=hScrollbar.set, yscrollcommand=vScrollbar.set, height=7)
        self.packagesView.grid(row=0, column=0, sticky=(N, S, E, W))
        self.packagesView.bind('<<TreeviewSelect>>', self.packageSelect)
        hScrollbar["command"] = self.packagesView.xview
        hScrollbar.grid(row=1, column=0, sticky=(E,W))
        vScrollbar["command"] = self.packagesView.yview
        vScrollbar.grid(row=0, column=1, sticky=(N,S))
        packagesFrame.columnconfigure(0, weight=1)
        packagesFrame.rowconfigure(0, weight=1)
        packagesFrame.grid(row=0, column=1, columnspan=4, sticky=(N, S, E, W), padx=3, pady=3)
        self.packagesView.focus_set()

        self.packagesView.column("#0", width=120, anchor="w")
        self.packagesView.heading("#0", text=_("Name"))
        self.packagesView["columns"] = ("ver", "status", "date", "update", "descr")
        self.packagesView.column("ver", width=150, anchor="w", stretch=False)
        self.packagesView.heading("ver", text=_("Version"))
        self.packagesView.column("status", width=50, anchor="w", stretch=False)
        self.packagesView.heading("status", text=_("Status"))
        self.packagesView.column("date", width=170, anchor="w", stretch=False)
        self.packagesView.heading("date", text=_("File Date"))
        self.packagesView.column("update", width=50, anchor="w", stretch=False)
        self.packagesView.heading("update", text=_("Update"))
        self.packagesView.column("descr", width=200, anchor="w", stretch=False)
        self.packagesView.heading("descr", text=_("Description"))

        remappingsFrame = Frame(frame)
        vScrollbar = Scrollbar(remappingsFrame, orient=VERTICAL)
        hScrollbar = Scrollbar(remappingsFrame, orient=HORIZONTAL)
        self.remappingsView = Treeview(remappingsFrame, xscrollcommand=hScrollbar.set, yscrollcommand=vScrollbar.set, height=5)
        self.remappingsView.grid(row=0, column=0, sticky=(N, S, E, W))
        hScrollbar["command"] = self.remappingsView.xview
        hScrollbar.grid(row=1, column=0, sticky=(E,W))
        vScrollbar["command"] = self.remappingsView.yview
        vScrollbar.grid(row=0, column=1, sticky=(N,S))
        remappingsFrame.columnconfigure(0, weight=1)
        remappingsFrame.rowconfigure(0, weight=1)
        remappingsFrame.grid(row=1, column=1, columnspan=4, sticky=(N, S, E, W), padx=3, pady=3)
        self.remappingsView.focus_set()
        
        self.remappingsView.column("#0", width=200, anchor="w")
        self.remappingsView.heading("#0", text=_("Prefix"))
        self.remappingsView["columns"] = ("remapping")
        self.remappingsView.column("remapping", width=500, anchor="w", stretch=False)
        self.remappingsView.heading("remapping", text=_("Remapping"))
        
        # bottom frame package info details
        packageInfoFrame = Frame(frame, width=700)
        packageInfoFrame.columnconfigure(1, weight=1)
        
        self.packageNameLabel = Label(packageInfoFrame, wraplength=600, justify="left", 
                                      font=font.Font(family='Helvetica', size=12, weight='bold'))
        self.packageNameLabel.grid(row=0, column=0, columnspan=6, sticky=W)
        self.packageVersionHdr = Label(packageInfoFrame, text=_("version:"), state=DISABLED)
        self.packageVersionHdr.grid(row=1, column=0, sticky=W)
        self.packageVersionLabel = Label(packageInfoFrame, wraplength=600, justify="left")
        self.packageVersionLabel.grid(row=1, column=1, columnspan=5, sticky=W)
        self.packageDescrHdr = Label(packageInfoFrame, text=_("description:"), state=DISABLED)
        self.packageDescrHdr.grid(row=2, column=0, sticky=W)
        self.packageDescrLabel = Label(packageInfoFrame, wraplength=600, justify="left")
        self.packageDescrLabel.grid(row=2, column=1, columnspan=5, sticky=W)
        self.packagePrefixesHdr = Label(packageInfoFrame, text=_("prefixes:"), state=DISABLED)
        self.packagePrefixesHdr.grid(row=3, column=0, sticky=W)
        self.packagePrefixesLabel = Label(packageInfoFrame, wraplength=600, justify="left")
        self.packagePrefixesLabel.grid(row=3, column=1, columnspan=5, sticky=W)
        ToolTip(self.packagePrefixesLabel, text=_("List of prefixes that this package remaps."), wraplength=240)
        self.packageUrlHdr = Label(packageInfoFrame, text=_("URL:"), state=DISABLED)
        self.packageUrlHdr.grid(row=4, column=0, sticky=W)
        self.packageUrlLabel = Label(packageInfoFrame, wraplength=600, justify="left")
        self.packageUrlLabel.grid(row=4, column=1, columnspan=5, sticky=W)
        ToolTip(self.packageUrlLabel, text=_("URL of taxonomy package (local file path or web loaded file)."), wraplength=240)
        self.packageDateHdr = Label(packageInfoFrame, text=_("date:"), state=DISABLED)
        self.packageDateHdr.grid(row=5, column=0, sticky=W)
        self.packageDateLabel = Label(packageInfoFrame, wraplength=600, justify="left")
        self.packageDateLabel.grid(row=5, column=1, columnspan=5, sticky=W)
        ToolTip(self.packageDateLabel, text=_("Date of currently loaded package file (with parenthetical node when an update is available)."), wraplength=240)
        self.packageEnableButton = Button(packageInfoFrame, text=self.ENABLE, state=DISABLED, command=self.packageEnable)
        ToolTip(self.packageEnableButton, text=_("Enable/disable package."), wraplength=240)
        self.packageEnableButton.grid(row=6, column=1, sticky=E)
        self.packageMoveUpButton = Button(packageInfoFrame, text=_("Move Up"), state=DISABLED, command=self.packageMoveUp)
        ToolTip(self.packageMoveUpButton, text=_("Move package up (above other remappings)."), wraplength=240)
        self.packageMoveUpButton.grid(row=6, column=2, sticky=E)
        self.packageMoveDownButton = Button(packageInfoFrame, text=_("Move Down"), state=DISABLED, command=self.packageMoveDown)
        ToolTip(self.packageMoveDownButton, text=_("Move package down (below other remappings)."), wraplength=240)
        self.packageMoveDownButton.grid(row=6, column=3, sticky=E)
        self.packageReloadButton = Button(packageInfoFrame, text=_("Reload"), state=DISABLED, command=self.packageReload)
        ToolTip(self.packageReloadButton, text=_("Reload/update package."), wraplength=240)
        self.packageReloadButton.grid(row=6, column=4, sticky=E)
        self.packageRemoveButton = Button(packageInfoFrame, text=_("Remove"), state=DISABLED, command=self.packageRemove)
        ToolTip(self.packageRemoveButton, text=_("Remove package from packages table (does not erase the package file)."), wraplength=240)
        self.packageRemoveButton.grid(row=6, column=5, sticky=E)
        packageInfoFrame.grid(row=2, column=0, columnspan=5, sticky=(N, S, E, W), padx=3, pady=3)
        packageInfoFrame.config(borderwidth=4, relief="groove")
        
        okButton = Button(frame, text=_("Close"), command=self.ok)
        ToolTip(okButton, text=_("Accept and changes (if any) and close dialog."), wraplength=240)
        cancelButton = Button(frame, text=_("Cancel"), command=self.close)
        ToolTip(cancelButton, text=_("Cancel changes (if any) and close dialog."), wraplength=240)
        okButton.grid(row=3, column=3, sticky=(S,E), pady=3)
        cancelButton.grid(row=3, column=4, sticky=(S,E), pady=3, padx=3)
        
        self.loadTreeViews()

        self.geometry("+{0}+{1}".format(dialogX+50,dialogY+100))
        frame.grid(row=0, column=0, sticky=(N,S,E,W))
        frame.columnconfigure(0, weight=0)
        frame.columnconfigure(1, weight=1)
        frame.rowconfigure(0, weight=1)
        window = self.winfo_toplevel()
        window.columnconfigure(0, weight=1)
        window.rowconfigure(0, weight=1)
        
        self.bind("<Return>", self.ok)
        self.bind("<Escape>", self.close)
        
        self.protocol("WM_DELETE_WINDOW", self.close)
        self.grab_set()
        self.wait_window(self)
        
    def loadTreeViews(self):
        self.selectedModule = None

        # clear previous treeview entries
        for previousNode in self.packagesView.get_children(""): 
            self.packagesView.delete(previousNode)

        for i, packageInfo in enumerate(self.packagesConfig.get("packages", [])):
            name = packageInfo.get("name", "package{}".format(i))
            node = self.packagesView.insert("", "end", "_{}".format(i), text=name)
            self.packagesView.set(node, "ver", packageInfo.get("version"))
            self.packagesView.set(node, "status", packageInfo.get("status"))
            self.packagesView.set(node, "date", packageInfo.get("fileDate"))
            if name in self.packageNamesWithNewerFileDates:
                self.packagesView.set(node, "update", _("available"))
            self.packagesView.set(node, "descr", packageInfo.get("description"))
        
        # clear previous treeview entries
        for previousNode in self.remappingsView.get_children(""): 
            self.remappingsView.delete(previousNode)

        for i, remappingItem in enumerate(sorted(self.packagesConfig.get("remappings", {}).items())):
            prefix, remapping = remappingItem
            node = self.remappingsView.insert("", "end", prefix, text=prefix)
            self.remappingsView.set(node, "remapping", remapping)
            
        self.packageSelect()  # clear out prior selection

    def ok(self, event=None):
        if self.packagesConfigChanged:
            PackageManager.packagesConfig = self.packagesConfig
            PackageManager.packagesConfigChanged = True
            self.cntlr.onPackageEnablementChanged()
        self.close()
        
    def close(self, event=None):
        self.parent.focus_set()
        self.destroy()
                
    def packageSelect(self, *args):
        node = (self.packagesView.selection() or (None,))[0]
        try:
            nodeIndex = int(node[1:])
        except (ValueError, TypeError):
            nodeIndex = -1
        if 0 <= nodeIndex < len(self.packagesConfig["packages"]):
            packageInfo = self.packagesConfig["packages"][nodeIndex]
            self.selectedPackageIndex = nodeIndex
            name = packageInfo["name"]
            self.packageNameLabel.config(text=name)
            self.packageVersionHdr.config(state=ACTIVE)
            self.packageVersionLabel.config(text=packageInfo["version"])
            self.packageDescrHdr.config(state=ACTIVE)
            self.packageDescrLabel.config(text=packageInfo["description"])
            self.packagePrefixesHdr.config(state=ACTIVE)
            self.packagePrefixesLabel.config(text=', '.join(packageInfo["remappings"].keys()))
            self.packageUrlHdr.config(state=ACTIVE)
            self.packageUrlLabel.config(text=packageInfo["URL"])
            self.packageDateHdr.config(state=ACTIVE)
            self.packageDateLabel.config(text=packageInfo["fileDate"] + " " +
                    (_("(an update is available)") if name in self.packageNamesWithNewerFileDates else ""))
            self.packageEnableButton.config(state=ACTIVE,
                                           text={"enabled":self.DISABLE,
                                                 "disabled":self.ENABLE}[packageInfo["status"]])
            self.packageMoveUpButton.config(state=ACTIVE if 0 < nodeIndex else DISABLED)
            self.packageMoveDownButton.config(state=ACTIVE if nodeIndex < (len(self.packagesConfig["packages"]) - 1) else DISABLED)
            self.packageReloadButton.config(state=ACTIVE)
            self.packageRemoveButton.config(state=ACTIVE)
        else:
            self.selectedPackageIndex = -1
            self.packageNameLabel.config(text="")
            self.packageVersionHdr.config(state=DISABLED)
            self.packageVersionLabel.config(text="")
            self.packageDescrHdr.config(state=DISABLED)
            self.packageDescrLabel.config(text="")
            self.packagePrefixesHdr.config(state=DISABLED)
            self.packagePrefixesLabel.config(text="")
            self.packageUrlHdr.config(state=DISABLED)
            self.packageUrlLabel.config(text="")
            self.packageDateHdr.config(state=DISABLED)
            self.packageDateLabel.config(text="")

            self.packageEnableButton.config(state=DISABLED, text=self.ENABLE)
            self.packageMoveUpButton.config(state=DISABLED)
            self.packageMoveDownButton.config(state=DISABLED)
            self.packageReloadButton.config(state=DISABLED)
            self.packageRemoveButton.config(state=DISABLED)
        
    def findLocally(self):
        initialdir = self.cntlr.pluginDir # default plugin directory
        if not self.cntlr.isMac: # can't navigate within app easily, always start in default directory
            initialdir = self.cntlr.config.setdefault("packageOpenDir", initialdir)
        filename = self.cntlr.uiFileDialog("open",
                                           parent=self,
                                           title=_("Choose taxonomy package file"),
                                           initialdir=initialdir,
                                           filetypes=[(_("Taxonomy package files (*.zip)"), "*.zip"),
                                                      (_("Manifest (*.taxonomyPackage.xml)"), "*.taxonomyPackage.xml"),
                                                      (_("Oasis Catalog (*catalog.xml)"), "*catalog.xml")],
                                           defaultextension=".zip")
        if filename:
            # check if a package is selected (any file in a directory containing an __init__.py
            self.cntlr.config["packageOpenDir"] = os.path.dirname(filename)
            packageInfo = PackageManager.packageInfo(filename, packageManifestName=self.manifestNamePattern)
            self.loadFoundPackageInfo(packageInfo, filename)
                

    def findOnWeb(self):
        url = DialogURL.askURL(self)
        if url:  # url is the in-cache or local file
            packageInfo = PackageManager.packageInfo(url, packageManifestName=self.manifestNamePattern)
            self.cntlr.showStatus("") # clear web loading status
            self.loadFoundPackageInfo(packageInfo, url)
                
    def manifestName(self):
        self.manifestNamePattern = simpledialog.askstring(_("Archive manifest file name pattern"),
                                                          _("Provide non-standard archive manifest file name pattern (e.g., *taxonomyPackage.xml).  \n"
                                                            "Uses unix file name pattern matching.  \n"
                                                            "Multiple manifest files are supported in archive (such as oasis catalogs).  \n"
                                                            "(If blank, search for either .taxonomyPackage.xml or catalog.xml).  "),
                                                          initialvalue=self.manifestNamePattern,
                                                          parent=self)
                
    def loadFoundPackageInfo(self, packageInfo, url):
        if packageInfo and packageInfo.get("name"):
            self.addPackageInfo(packageInfo)
            self.loadTreeViews()
        else:
            messagebox.showwarning(_("Package is not itself a taxonomy package.  "),
                                   _("File does not itself contain a manifest file: \n\n{0}\n\n  "
                                     "If opening an archive file, the manifest file search pattern currently is \"\", please press \"Manifest\" to change manifest file name pattern, e.g.,, \"*.taxonomyPackage.xml\", if needed.  ")
                                   .format(url),
                                   parent=self)
            
    def removePackageInfo(self, name, version):
        # find package entry
        packagesList = self.packagesConfig["packages"]
        j = -1
        for i, packageInfo in enumerate(packagesList):
            if packageInfo['name'] == name and packageInfo['version'] == version:
                j = i
                break
        if 0 <= j < len(packagesList):
            del self.packagesConfig["packages"][i]
            self.packagesConfigChanged = True

    def addPackageInfo(self, packageInfo):
        name = packageInfo["name"]
        version = packageInfo["version"]
        self.removePackageInfo(name, version)  # remove any prior entry for this package
        self.packageNamesWithNewerFileDates.discard(name) # no longer has an update available
        self.packagesConfig["packages"].append(packageInfo)
        PackageManager.rebuildRemappings()
        self.packagesConfigChanged = True

    def packageEnable(self):
        if 0 <= self.selectedPackageIndex < len(self.packagesConfig["packages"]):
            packageInfo = self.packagesConfig["packages"][self.selectedPackageIndex]
            if self.packageEnableButton['text'] == self.ENABLE:
                packageInfo["status"] = "enabled"
                self.packageEnableButton['text'] = self.DISABLE
            elif self.packageEnableButton['text'] == self.DISABLE:
                packageInfo["status"] = "disabled"
                self.packageEnableButton['text'] = self.ENABLE
            self.packagesConfigChanged = True
            PackageManager.rebuildRemappings()
            self.loadTreeViews()
            
    def packageMoveUp(self):
        if 1 <= self.selectedPackageIndex < len(self.packagesConfig["packages"]):
            packages = self.packagesConfig["packages"]
            packageInfo = packages[self.selectedPackageIndex]
            del packages[self.selectedPackageIndex]
            packages.insert(self.selectedPackageIndex -1, packageInfo)
            self.packagesConfigChanged = True
            PackageManager.rebuildRemappings()
            self.loadTreeViews()
            
    def packageMoveDown(self):
        if 0 <= self.selectedPackageIndex < len(self.packagesConfig["packages"]) - 1:
            packages = self.packagesConfig["packages"]
            packageInfo = packages[self.selectedPackageIndex]
            del packages[self.selectedPackageIndex]
            packages.insert(self.selectedPackageIndex + 1, packageInfo)
            self.packagesConfigChanged = True
            PackageManager.rebuildRemappings()
            self.loadTreeViews()
            
    def packageReload(self):
        if 0 <= self.selectedPackageIndex < len(self.packagesConfig["packages"]):
            packageInfo = self.packagesConfig["packages"][self.selectedPackageIndex]
            url = packageInfo.get("URL")
            if url:
                packageInfo = PackageManager.packageInfo(url, reload=True, packageManifestName=packageInfo.get("manifestName"))
                if packageInfo:
                    self.addPackageInfo(packageInfo)
                    PackageManager.rebuildRemappings()
                    self.loadTreeViews()
                    self.cntlr.showStatus(_("{0} reloaded").format(packageInfo.get("name")), clearAfter=5000)
                else:
                    messagebox.showwarning(_("Package error"),
                                           _("File or package cannot be reloaded: \n\n{0}")
                                           .format(url),
                                           parent=self)

    def packageRemove(self):
        if 0 <= self.selectedPackageIndex < len(self.packagesConfig["packages"]):
            packageInfo = self.packagesConfig["packages"][self.selectedPackageIndex]
            self.removePackageInfo(packageInfo["name"], packageInfo["version"])
            self.packagesConfigChanged = True
            PackageManager.rebuildRemappings()
            self.loadTreeViews()
class ReturnWindow:
    def __init__(self):
        self.win = Tk()
        self.canvas = Canvas(self.win, width=800, height=420, bg='white')
        self.canvas.pack(expand=YES, fill=BOTH)

        # show window in center of the screen
        width = self.win.winfo_screenwidth()
        height = self.win.winfo_screenheight()
        x = int(width / 2 - 800 / 2)
        y = int(height / 2 - 420 / 2)
        str1 = "800x420+" + str(x) + "+" + str(y)
        self.win.geometry(str1)

        # disable resize window
        self.win.resizable(False, False)

        # changing title of the window
        self.win.title(
            "| BOOK RETURNING DETAILS | LIBRARY MANAGEMENT SYSTEM |")

    def add_frame(self):

        self.frame = Frame(self.win, height=420, width=800)
        self.frame.place(x=0, y=0)

        x, y = 0, 0

        self.label = Label(self.frame, text="RETURNING BOOKS", fg='black')
        self.label.config(font=("Poppins", 20, 'underline bold'))
        self.label.place(x=250, y=30)

        # use tree view to show details from the table
        self.tr = Treeview(self.frame,
                           columns=('BOOK_ID', 'STUDENT_ID', 'ISSUE_DATE',
                                    'RETURN_DATE'),
                           selectmode="extended")

        self.tr.heading('#0', text='BOOK_ID')
        self.tr.column('#0', minwidth=0, width=100, stretch=NO)
        self.tr.heading('#1', text='STUDENT_ID')
        self.tr.column('#1', minwidth=0, width=100, stretch=NO)
        self.tr.heading('#2', text='ISSUE_DATE')
        self.tr.column('#2', minwidth=0, width=100, stretch=NO)
        self.tr.heading('#3', text='RETURN_DATE')
        self.tr.column('#3', minwidth=0, width=100, stretch=NO)
        self.tr.heading('#4', text='RETURN')
        self.tr.column('#4', minwidth=0, width=100, stretch=NO)
        # self.tr.heading('#5', text='RETURN')
        # self.tr.column('#5', minwidth=0, width=100, stretch=NO)

        j = 0
        for i in Database.database.BookLend():
            self.tr.insert('',
                           index=j,
                           text=i[0],
                           values=(i[1], i[2], i[3], 'RETURN'))
            j += 1

        # create action on deletion
        self.tr.bind('<Double-Button-1>', self.bounce)
        self.tr.place(x=140, y=y + 100)

        self.win.mainloop()

    def bounce(self, e):
        # get the value of deleted row
        tt = self.tr.focus()
        # get the column id
        col = self.tr.identify_column(e.x)
        # print(col)
        # print(self.tr.item(tt))
        # print(self.tr.item(tt)['text'])
        # print(self.tr.item(tt)['values'][0])
        data = (
            str(self.tr.item(tt)['text']),
            str(self.tr.item(tt)['values'][0]),
        )

        if col == '#4':
            res = messagebox.askyesno("Message", "Do you want  to Return..!")
            if res:
                d, fine_days = Database.database.Return(data)
                if d:
                    message = ("Book Returned successfully..! \n Fine = ",
                               fine_days)
                    messagebox.showinfo("Message", message)
                    self.win.destroy()
                    x = Thirdpage
                    # x.add_frame()
            else:
                self.win.destroy()
                x = Student.Return.ReturnWindow()
                x.add_frame()
def mains(username):
    root = Tk()
    bg_color = "powder blue"
    root.title("Buy Products")
    root.geometry('1525x800+0+0')
    root.configure(bg=bg_color)
    root.resizable(False, False)
    print(username)
    billingFrame = Frame(root, bd=15, relief=GROOVE)
    billingFrame.place(x=0, y=170, width=399, height=380)

    bill_title = Label(billingFrame,
                       text='Bill Area',
                       font=('times', 15, 'italic'),
                       bd=10,
                       relief=GROOVE)
    bill_title.pack(fill=X)

    def savebill():
        bill_data = billarea.get('1.0', END)
        f1 = open(
            "C:\\Users\\DELL\\Desktop\\Billing_recipts\\" +
            str(bill_no.get()) + ".txt", "w")
        f1.write(bill_data)
        f1.close()
        messagebox.showinfo('Notification',
                            f'Bill No:{bill_no.get()} saved successfully',
                            parent=root)

    def on_entersearchbtn(e):
        searchbtn.configure(bg='red')

    def on_leavesearchbtn(e):
        searchbtn.configure(bg='blue')

    def on_enterplaceorderbtn(e):
        placeorderbtn.configure(bg='red')

    def on_leaveplaceorderbtn(e):
        placeorderbtn.configure(bg='blue')

    def placeorderfunc():
        def on_entersubmitplaceorderbtn(e):
            submitplaceorderbtn.configure(bg='red')

        def on_leavesubmitplaceorderbtn(e):
            submitplaceorderbtn.configure(bg='blue')

        custname = custnameval.get()
        custphone = custphoneval.get()
        if (custname.strip() == ""):
            messagebox.showinfo("Info",
                                "Please fill your name...!!!",
                                parent=root)
        elif (custphone == ""):
            messagebox.showinfo("Info",
                                "Please fill your phone number...!!!",
                                parent=root)
        elif (len(custphone) != 10):
            messagebox.showinfo("Info",
                                "Not a valid phone number...!!!",
                                parent=root)
        else:
            global bill_no
            bill_no = StringVar()
            x = random.randint(1000, 9999)
            bill_no.set(str(x))

            billarea.delete('1.0', END)
            billarea.insert(END, "\tWelcome Dear Customer\n")
            billarea.insert(END, f"\n\nBill Number    : {bill_no.get()}")
            billarea.insert(END, f"\nCustomer Name  : {custnameval.get()}")
            billarea.insert(END, f"\nCustomer Phone : {custphoneval.get()}")
            billarea.insert(END,
                            f"\n===========================================")
            billarea.insert(END, f"\nProducts\t\tSize\t\tPrice\n")
            billarea.insert(END,
                            f"===========================================\n")
            total = 0
            list = []
            f1 = open(f"temp_bills{custphoneval.get()}.txt", "r")
            line = f1.readlines()
            for l in line:
                s = l.split('\t\t')
                list.append(s[-1])
            print(list)
            res = [int(sub.split('\n')[0]) for sub in list]
            for ele in range(0, len(res)):
                total = total + res[ele]
            print(total)
            file = open(f"temp_bills{custphoneval.get()}.txt", "a")
            file.write(f"\n===========================================")
            file.write(f"\nTotal Bill\t\t\t{total}\n")
            file.close()
            file = open(f"temp_bills{custphoneval.get()}.txt", "r")
            line = file.read()
            billarea.insert(END, f"{line}")

            placeorderWin = Toplevel()
            placeorderWin.geometry('550x230+500+250')
            placeorderWin.grab_set(
            )  ######Untill this window is closed nothing will work
            placeorderWin.resizable(False, False)
            placeorderWin.title("Product Details")
            placeorderWin.configure(bg='powder blue')

            def submitplaceorderfunc():
                askorderid = bill_no.get()
                askname = custnameval.get()
                askphone = custphoneval.get()
                askemail = askemailval.get()
                askaddress = askaddressval.get()
                askorderdate = datetime.today().strftime('%Y-%m-%d')
                askdeliverstatus = "Pending"
                if (askemail.strip() == "" or askaddress.strip() == ""):
                    messagebox.showinfo("Info",
                                        "Please fill all details...!!!",
                                        parent=placeorderWin)
                else:
                    try:
                        query = 'insert into customerinfo values(%s,%s,%s,%s,%s,%s,%s);'
                        mycursor.execute(
                            query,
                            (askorderid, askname, askphone, askemail,
                             askaddress, askorderdate, askdeliverstatus))
                        con.commit()
                        messagebox.showinfo(
                            'Notification',
                            'Your Order Placed Successfully...',
                            parent=placeorderWin)
                        savebill()

                    except:
                        pass

            #################################################Labels
            askemailLabel = Label(placeorderWin,
                                  text="Enter Email : ",
                                  bg='powder blue',
                                  font=('times', 20, 'bold italic'),
                                  anchor='w')
            askemailLabel.place(x=10, y=20)

            askaddressLabel = Label(placeorderWin,
                                    text="Enter Address : ",
                                    bg='powder blue',
                                    font=('times', 20, 'bold italic'),
                                    anchor='w')
            askaddressLabel.place(x=10, y=80)

            #################################################Entry Boxes
            askemailval = StringVar()
            askaddressval = StringVar()

            askemailEntry = Entry(placeorderWin,
                                  textvariable=askemailval,
                                  width=32,
                                  font=('arial', 12, 'italic'),
                                  bd=5,
                                  bg='light pink')
            askemailEntry.place(x=240, y=20)

            askaddressEntry = Entry(placeorderWin,
                                    textvariable=askaddressval,
                                    width=32,
                                    font=('arial', 12, 'italic'),
                                    bd=5,
                                    bg='light pink')
            askaddressEntry.place(x=240, y=80)

            ########################################################Buttons
            submitplaceorderbtn = Button(placeorderWin,
                                         text='Submit',
                                         font=('Arial', 13, 'bold'),
                                         width=7,
                                         bg='blue',
                                         activebackground='red',
                                         activeforeground='white',
                                         relief=GROOVE,
                                         bd=9,
                                         command=submitplaceorderfunc)
            submitplaceorderbtn.place(x=200, y=160)
            submitplaceorderbtn.bind('<Enter>', on_entersubmitplaceorderbtn)
            submitplaceorderbtn.bind('<Leave>', on_leavesubmitplaceorderbtn)

    placeorderbtn = Button(root,
                           text='Place Order',
                           font=('Arial', 15, 'bold'),
                           width=10,
                           bg='blue',
                           foreground="white",
                           activebackground='red',
                           activeforeground='white',
                           relief=GROOVE,
                           bd=9,
                           command=placeorderfunc)
    placeorderbtn.place(x=130, y=600)
    placeorderbtn.bind('<Enter>', on_enterplaceorderbtn)
    placeorderbtn.bind('<Leave>', on_leaveplaceorderbtn)

    scroll_y = Scrollbar(billingFrame, orient=VERTICAL)
    billarea = Text(billingFrame, yscrollcommand=scroll_y.set)
    scroll_y.pack(side=RIGHT, fill=Y)
    scroll_y.configure(command=billarea.yview)
    billarea.pack(fill=BOTH, expand=1)

    # billarea.configure(state='disabled')

    def searchfunc():
        searchproduct = searchproductnameval.get()
        if (searchproduct != ''):
            query = 'select * from productinfo where name=%s and status=%s;'
            mycursor.execute(query, (searchproduct, "Available"))
            data = mycursor.fetchall()
            productsTable.delete(*productsTable.get_children())
            for i in data:
                vv = [i[0], i[1], i[5], i[3]]
                productsTable.insert('', END, values=vv)
        else:
            query = 'select * from productinfo where status=%s;'
            mycursor.execute(query, ("Available"))
            data = mycursor.fetchall()
            productsTable.delete(*productsTable.get_children())
            for i in data:
                vv = [i[0], i[1], i[5], i[3]]
                productsTable.insert('', END, values=vv)

    searchproductnameval = StringVar()
    custnameval = StringVar()
    custphoneval = StringVar()

    searchproductEntry = Entry(root,
                               textvariable=searchproductnameval,
                               width=38,
                               font=('arial', 12, 'italic'),
                               bd=5,
                               bg='light pink')
    searchproductEntry.place(x=20, y=50)

    searchbtn = Button(root,
                       text='Search Product',
                       font=('Arial', 15, 'bold'),
                       width=14,
                       bg='blue',
                       foreground="white",
                       activebackground='red',
                       activeforeground='white',
                       relief=GROOVE,
                       bd=9,
                       command=searchfunc)
    searchbtn.place(x=100, y=100)
    searchbtn.bind('<Enter>', on_entersearchbtn)
    searchbtn.bind('<Leave>', on_leavesearchbtn)

    ####################################################################Customer Entry Details
    custnameLabel = Label(root,
                          text="Your Name : ",
                          bg='powder blue',
                          font=('times', 20, 'bold italic'),
                          anchor='w')
    custnameLabel.place(x=400, y=10)

    custphoneLabel = Label(root,
                           text="Your Phone No.: ",
                           bg='powder blue',
                           font=('times', 20, 'bold italic'),
                           anchor='w')
    custphoneLabel.place(x=950, y=10)

    custnameEntry = Entry(root,
                          textvariable=custnameval,
                          width=32,
                          font=('arial', 12, 'italic'),
                          bd=5,
                          bg='light pink')
    custnameEntry.place(x=580, y=10)

    con = pymysql.connect(host='localhost', user='******', password='')
    mycursor = con.cursor()
    query = 'use inventoryDB;'
    mycursor.execute(query)

    query = "select * from login_info where username=%s;"
    mycursor.execute(query, (username))
    name = mycursor.fetchall()
    for i in name:
        custnameEntry.insert(0, i[4])
        custnameval.set(i[4])
        print(i[4])

    custphoneEntry = Entry(root,
                           textvariable=custphoneval,
                           width=32,
                           font=('arial', 12, 'italic'),
                           bd=5,
                           bg='light pink')
    custphoneEntry.place(x=1180, y=10)

    for i in name:
        custphoneEntry.insert(0, i[5])
        custphoneval.set(i[5])
        print(i[5])

    #####################################################################ProductsInfo Table
    productstableFrame = Frame(root, bg='gold2', relief=GROOVE, borderwidth=5)
    productstableFrame.place(x=400, y=50, width=1120, height=730)

    style = ttk.Style()
    style.configure('Treeview.Heading',
                    font=('times', 15, 'italic'),
                    foreground='green')
    style.configure('Treeview',
                    font=('times', 12, 'italic'),
                    foreground='black',
                    background='powder blue')

    scroll_x = Scrollbar(productstableFrame, orient=HORIZONTAL)
    scroll_y = Scrollbar(productstableFrame, orient=VERTICAL)

    productsTable = Treeview(productstableFrame,
                             columns=('Product ID', 'Name', 'Price', 'Size'),
                             yscrollcommand=scroll_y.set,
                             xscrollcommand=scroll_x.set)

    def select_item(a):
        popupWin = Toplevel()
        popupWin.geometry('550x570+500+150')
        popupWin.grab_set(
        )  ######Untill this window is closed nothing will work
        popupWin.resizable(False, False)
        popupWin.title("Product Details")
        popupWin.configure(bg='powder blue')

        def on_enteraddtocartbtn(e):
            addtocartbtn.configure(bg='red')

        def on_leaveaddtocartbtn(e):
            addtocartbtn.configure(bg='blue')

        def addtocartbtnfunc():
            custname = custnameval.get()
            custphone = custphoneval.get()
            if (custname.strip() == ""):
                messagebox.showinfo("Info",
                                    "Please fill your name...!!!",
                                    parent=popupWin)
            elif (custphone == ""):
                messagebox.showinfo("Info",
                                    "Please fill your phone number...!!!",
                                    parent=popupWin)
            elif (len(custphone) != 10):
                messagebox.showinfo("Info",
                                    "Not a valid phone number...!!!",
                                    parent=popupWin)
            else:
                items = ""
                billarea.delete('1.0', END)
                billarea.insert(END, "\tWelcome Dear Customer\n")
                billarea.insert(END, f"\nCustomer Name  : {custnameval.get()}")
                billarea.insert(END,
                                f"\nCustomer Phone : {custphoneval.get()}")
                billarea.insert(
                    END, f"\n===========================================")
                billarea.insert(END, f"\nProducts\t\tSize\t\tPrice\n")
                billarea.insert(
                    END, f"===========================================\n")
                items = items + f"{a_nameEntry['text']}\t\t{a_sizeEntry['text']}\t\t{a_priceEntry['text']}"
                file = open(f"temp_bills{custphoneval.get()}.txt", "a")
                file.write(
                    f"{a_nameEntry['text']}\t\t{a_sizeEntry['text']}\t\t{a_priceEntry['text']}\n"
                )
                file.close()
                file = open(f"temp_bills{custphoneval.get()}.txt", "r")
                line = file.read()
                billarea.insert(END, f"{line}")
                query = "update productinfo set qty=%s where productid=%s"
                mycursor.execute(
                    query,
                    (str(int(a_qtyEntry['text']) - 1), a_idEntry['text']))
                data = mycursor.fetchall()
                for i in data:
                    a_idEntry.configure(text=i[0])

        #################################################Labels
        s_idLabel = Label(popupWin,
                          text="Product ID : ",
                          bg='powder blue',
                          font=('times', 20, 'bold italic'),
                          anchor='w')
        s_idLabel.place(x=10, y=10)

        s_nameLabel = Label(popupWin,
                            text="Name : ",
                            bg='powder blue',
                            font=('times', 20, 'bold italic'),
                            anchor='w')
        s_nameLabel.place(x=10, y=70)

        s_qtyLabel = Label(popupWin,
                           text="Qty Aval. : ",
                           bg='powder blue',
                           font=('times', 20, 'bold italic'),
                           anchor='w')
        s_qtyLabel.place(x=10, y=130)

        s_sizeLabel = Label(popupWin,
                            text="Size : ",
                            bg='powder blue',
                            font=('times', 20, 'bold italic'),
                            anchor='w')
        s_sizeLabel.place(x=10, y=190)

        s_weightLabel = Label(popupWin,
                              text="Weight(kg) : ",
                              bg='powder blue',
                              font=('times', 20, 'bold italic'),
                              anchor='w')
        s_weightLabel.place(x=10, y=250)

        s_priceLabel = Label(popupWin,
                             text="Price(Rs.) : ",
                             bg='powder blue',
                             font=('times', 20, 'bold italic'),
                             anchor='w')
        s_priceLabel.place(x=10, y=310)

        s_colorLabel = Label(popupWin,
                             text="Color : ",
                             bg='powder blue',
                             font=('times', 20, 'bold italic'),
                             anchor='w')
        s_colorLabel.place(x=10, y=370)

        s_statusLabel = Label(popupWin,
                              text="Status : ",
                              bg='powder blue',
                              font=('times', 20, 'bold italic'),
                              anchor='w')
        s_statusLabel.place(x=10, y=430)

        #################################################Labels as Entry Boxes
        a_idEntry = Label(popupWin,
                          width=32,
                          font=('arial', 12, 'italic'),
                          bd=5,
                          bg='light pink')
        a_idEntry.place(x=240, y=10)

        a_nameEntry = Label(popupWin,
                            width=32,
                            font=('arial', 12, 'italic'),
                            bd=5,
                            bg='light pink')
        a_nameEntry.place(x=240, y=70)

        a_qtyEntry = Label(popupWin,
                           width=32,
                           font=('arial', 12, 'italic'),
                           bd=5,
                           bg='light pink')
        a_qtyEntry.place(x=240, y=130)

        a_sizeEntry = Label(popupWin,
                            width=32,
                            font=('arial', 12, 'italic'),
                            bd=5,
                            bg='light pink')
        a_sizeEntry.place(x=240, y=190)

        a_weightEntry = Label(popupWin,
                              width=32,
                              font=('arial', 12, 'italic'),
                              bd=5,
                              bg='light pink')
        a_weightEntry.place(x=240, y=250)

        a_priceEntry = Label(popupWin,
                             width=32,
                             font=('arial', 12, 'italic'),
                             bd=5,
                             bg='light pink')
        a_priceEntry.place(x=240, y=310)

        a_colorEntry = Label(popupWin,
                             width=32,
                             font=('arial', 12, 'italic'),
                             bd=5,
                             bg='light pink')
        a_colorEntry.place(x=240, y=370)

        s_statusEntry = Label(popupWin,
                              width=32,
                              font=('arial', 12, 'italic'),
                              bd=5,
                              bg='light pink')
        s_statusEntry.place(x=240, y=430)

        ########################################################Buttons
        addtocartbtn = Button(popupWin,
                              text='Add To Cart',
                              font=('Arial', 15, 'bold'),
                              width=10,
                              bg='blue',
                              foreground="white",
                              activebackground='red',
                              activeforeground='white',
                              relief=GROOVE,
                              bd=9,
                              command=addtocartbtnfunc)
        addtocartbtn.place(x=190, y=490)
        addtocartbtn.bind('<Enter>', on_enteraddtocartbtn)
        addtocartbtn.bind('<Leave>', on_leaveaddtocartbtn)

        test_str_library = productsTable.item(productsTable.selection(
        ))  # gets all the values of the selected row
        print('The test_str = ', type(test_str_library), test_str_library,
              '\n')  # prints a dictionay of the selected row
        item = productsTable.selection()[0]  # which row did you click on
        print('item clicked ',
              item)  # variable that represents the row you clicked on
        # print (productsTable.item(item)['values'][0]) # prints the first value of the values (the id value)

        selectedItemId = test_str_library['values'][0]
        query = "select * from productinfo where productid=%s"
        mycursor.execute(query, (selectedItemId))
        data = mycursor.fetchall()
        for i in data:
            a_idEntry.configure(text=i[0])
            a_nameEntry.configure(text=i[1])
            a_qtyEntry.configure(text=i[2])
            a_sizeEntry.configure(text=i[3])
            a_weightEntry.configure(text=i[4])
            a_priceEntry.configure(text=i[5])
            a_colorEntry.configure(text=i[6])
            s_statusEntry.configure(text=i[7])

    productsTable.bind('<ButtonRelease-1>', select_item)

    scroll_x.pack(side=BOTTOM, fill=X)
    scroll_y.pack(side=RIGHT, fill=Y)
    scroll_x.configure(command=productsTable.xview)
    scroll_y.configure(command=productsTable.yview)

    productsTable.heading('Product ID', text='Product ID')
    productsTable.heading('Name', text='Name')
    productsTable.heading('Price', text='Price')
    productsTable.heading('Size', text='Size')

    productsTable.configure(show='headings')

    productsTable.column('Product ID', width=100, anchor="center")
    productsTable.column('Name', width=200, anchor="center")
    productsTable.column('Price', width=200, anchor="center")
    productsTable.column('Size', width=300, anchor="center")

    productsTable.pack(fill=BOTH, expand=1)

    con = pymysql.connect(host='localhost', user='******', password='')
    mycursor = con.cursor()
    query = 'use inventoryDB;'
    mycursor.execute(query)
    query = 'select * from productinfo where status=%s;'
    mycursor.execute(query, ("Available"))
    data = mycursor.fetchall()
    productsTable.delete(*productsTable.get_children())

    for i in data:
        vv = [i[0], i[1], i[5], i[3]]
        productsTable.insert('', END, values=vv)

    root.mainloop()
Exemple #28
0
class Gui(Frame):
    __slots__ = ('selectedbox','desiredbox','logger','clidisp','ls','tgtbox',\
                 'thread','dir','running','startb','cliententry','commandlist','clientnum',
                 'scale'\
                     )

    def __init__(self, master):
        Frame.__init__(self, master)
        xpos = 0.05
        self.running = 0  #not listening

        self.debug = BooleanVar()
        self.debug.set(False)

        self.frame = Frame(colormap='new')
        self.frame.place(relx=xpos, rely=0.67)
        self.startb = Button(self.frame, text = "Start Server", command = self.startc,height=2, width=20,\
                             bg='#90ee90')
        self.startb.pack(side=LEFT, anchor=S)

        self.connectionl = Label(self.frame,
                                 text="OFF.",
                                 height=2,
                                 bg='#ff5f5f')

        self.connectionl.pack(side=LEFT, anchor=E, expand=YES)
        self.expertmode = BooleanVar()
        self.expertmode.set(False)
        self.showexpert = Checkbutton(text='Expert Mode',
                                      variable=self.expertmode,
                                      command=self.placeframe)
        self.showexpert.place(relx=xpos, rely=0.74)

        self.framecommand = Frame()

        self.commandlabel = Label(self.framecommand,
                                  text='Command to Client: ')
        self.commandtext = Entry(self.framecommand, width=15)
        self.cliententry = Entry(self.framecommand, width=10)
        self.addrlabel = Label(self.framecommand, text='Client Box ID: ')
        self.sendbutton=Button(self.framecommand,text='Send Command\nto Client', width=12,height=4\
                               ,command=self.send_command)

        self.tgtbox = None

        self.logoframe = Frame()
        self.logoframe.place(relx=xpos, rely=0.04)
        self.logo = PhotoImage(file=os.path.join('images', 'logo2.png'))
        self.logolabel = Label(self.logoframe, image=self.logo)
        self.logolabel.pack()

        self.cliframe = Frame(colormap='new')
        self.cliframe.place(relx=0.4, rely=0.1)

        #        self.condisp=Listbox (self.cliframe,width=80,height=12)
        self.scrollbartop = Scrollbar(self.cliframe)
        self.clidisp = Treeview(self.cliframe, height=12)
        self.clidisp['show'] = 'headings'
        self.clidisp['columns'] = ('boxid', 'ip')
        self.clidisp.heading('ip', text='IP')
        self.clidisp.heading('boxid', text='Box ID')
        self.clidisp.column('boxid', width=152)
        self.clidisp.column('ip', width=490)
        self.clidisp.pack(side=LEFT, fill=Y)

        #        self.condisp.pack(side=LEFT,fill=Y)
        self.scrollbartop.pack(side=RIGHT, fill=Y)
        self.scrollbartop.config(command=self.clidisp.yview)
        self.clidisp.config(yscrollcommand=self.scrollbartop.set)

        self.conntitle = Label(text='Connected Clients↓ ')
        self.conntitle.place(relx=0.4, rely=0.05)
        self.cdframe = Frame(colormap='new')
        self.cdframe.place(relx=0.7, rely=0.05)
        self.numtitle=Label(self.cdframe,text='Total Connected Clients: ',\
                            bg='#ff5f5f')


        self.clientnum=Label(self.cdframe,text=str(len(self.clidisp.get_children())),\
                             bg='#ff5f5f',font=("", 16))

        self.numtitle.pack(side=LEFT)
        self.clientnum.pack(side=LEFT)

        self.checkdebug = Checkbutton(text='Debug Mode', variable=self.debug)
        self.checkdebug.place(relx=0.6, rely=0.5)
        self.logtitile = Label(text='Logs↓ ')
        self.logtitile.place(relx=0.4, rely=0.5)
        self.scrolltext = Frame(colormap='new')
        self.scrolltext.place(relx=0.4, rely=0.55)

        if sys.platform.startswith('win'):
            self.logger = Text(self.scrolltext,
                               state=DISABLED,
                               height=16,
                               width=71)
        else:
            self.logger = Text(self.scrolltext,
                               state=DISABLED,
                               height=15,
                               width=64)

        self.scrollbar = Scrollbar(self.scrolltext)
        self.logger.pack(side=LEFT, fill=Y)
        self.scrollbar.pack(fill=BOTH, expand=True)
        self.scrollbar.config(command=self.logger.yview)
        self.logger.config(yscrollcommand=self.scrollbar.set)

        self.logger.tag_configure(0,
                                  background="#27d827",
                                  foreground='#d82780')
        self.logger.tag_configure(1, background="#58a758")
        self.logger.tag_configure(2, background="#4bb543")
        self.logger.tag_configure(3,
                                  background="#000000",
                                  foreground='#00aecd')
        self.logger.tag_configure(4, background="#ffd8ff")
        self.logger.tag_configure(5, background="#ffc4ff")
        self.logger.tag_configure(6, background="#ff89ff")
        self.logger.tag_configure(7, background="#ff9d9d")
        self.logger.tag_configure(8, background="#ff6262")
        self.logger.tag_configure(9,
                                  background="#d80000",
                                  foreground='#00d8d8')

        self.framehp = Frame()

        self.framehp.place(relx=xpos, rely=0.17)
        self.framehost = Frame(self.framehp)
        self.frameport = Frame(self.framehp)
        self.invalidtext = Label(self.framehost,
                                 text=' ✘ Please Enter a number \nfrom 0-254',
                                 foreground='#c40000')
        self.invalidtextport = Label(
            self.frameport,
            text=' ✘ Please Enter a number \nfrom 1-65535',
            foreground='#c40000')
        self.framehost.pack(side=TOP, anchor=W)
        self.frameport.pack(side=TOP, anchor=W)

        self.hostnum1 = intEnt(self.framehost, width=3, label=self.invalidtext)
        self.hostnum1.insert(INSERT, '0')
        self.hostnum2 = intEnt(self.framehost, width=3, label=self.invalidtext)
        self.hostnum2.insert(INSERT, '0')
        self.hostnum3 = intEnt(self.framehost, width=3, label=self.invalidtext)
        self.hostnum3.insert(INSERT, '0')
        self.hostnum4 = intEnt(self.framehost, width=3, label=self.invalidtext)
        self.hostnum4.insert(INSERT, '0')
        self.dot1 = Label(self.framehost, text='.')
        self.dot2 = Label(self.framehost, text='.')
        self.dot3 = Label(self.framehost, text='.')

        self.hostlabel = Label(self.framehost, text='Host  :')

        self.portnum=intEnt(self.frameport,width=6,\
                            maxlen=5,minval=0,maxval=65536,label=self.invalidtextport)

        self.portlabel = Label(self.frameport, text='Port  :')

        self.portnum.insert(INSERT, '10086')
        self.hostlabel.pack(side=LEFT, pady=3)
        self.hostnum1.pack(side=LEFT, pady=3)
        self.dot1.pack(side=LEFT, pady=3)
        self.hostnum2.pack(side=LEFT, pady=3)
        self.dot2.pack(side=LEFT, pady=3)
        self.hostnum3.pack(side=LEFT, pady=3)
        self.dot3.pack(side=LEFT, pady=3)
        self.hostnum4.pack(side=LEFT, pady=3)
        self.portlabel.pack(side=LEFT, pady=3)
        self.portnum.pack(side=LEFT, pady=3)

        self.errhost = Label(text='Number must between 0 and 255')
        self.errport = Label(text='Number must between 1 and 65535')

        self.framets = Frame(colormap='new')
        self.framets.place(relx=xpos, rely=0.27)
        self.timespan = IntVar()
        self.scale=Scale(self.framets,variable=self.timespan, orient=HORIZONTAL, \
                         from_=10, to=60,bg='#dcdcdc', length=230)
        self.scale.set(60)
        self.tslabel = Label(self.framets, text='Time per File (seconds):')
        self.tslabel.pack(side=TOP, anchor=W)
        self.scale.pack(side=LEFT)

        self.frame2 = Frame(colormap='new')
        self.frame2.place(relx=xpos, rely=0.5)
        self.outbtn = Button(text='Select Directory',
                             command=self.Folder,
                             bg='#cfcfcf',
                             width=20)
        self.dir = os.path.join('data', '')
        self.outbtn.place(relx=xpos, rely=0.4)
        self.dirlabel = Label(self.frame2, text='↓ Curret Directory ')
        self.dirtext = Label(self.frame2,
                             text=self.dir,
                             wraplength=400,
                             justify=LEFT)
        self.dirlabel.pack(side=TOP, anchor=W, pady=5)
        self.dirtext.pack(side=LEFT)

        self.radioframe = Frame(colormap='new')
        self.v = BooleanVar()
        explain = Label(self.radioframe, text='Save File As: ').pack(side=LEFT,
                                                                     anchor=W)
        self.rb1 = Radiobutton(self.radioframe,
                               text=".mseed",
                               variable=self.v,
                               value=False)
        self.rb1.pack(side=LEFT, anchor=W)
        self.rb2 = Radiobutton(self.radioframe,
                               text=".dat",
                               variable=self.v,
                               value=True)
        self.rb2.pack(side=LEFT, anchor=W)

        self.radioframe.place(relx=xpos, rely=0.45)
        self.sendbutton.pack(side=RIGHT,
                             anchor=SE,
                             padx=20,
                             pady=10,
                             expand=YES)
        self.addrlabel.pack(side=TOP, anchor=NW)
        self.cliententry.pack(side=TOP, anchor=NW)
        self.commandlabel.pack(side=TOP, anchor=NW)
        self.commandtext.pack(side=TOP, anchor=NW)
        self.bytestosend = bytearray(b'')

        self.selectedbox = None
        self.desiredbox = None
        self.headlen = 24
        self.commandlist = {
            'command1': b'\x55\xaa\x55',
            'command2': b'\xaa\x55\xaa'
        }
        return

    def send_command(self):

        box = self.cliententry.get()
        self.tgtbox = box
        self.showtext(
            '{} Command send to Box# {}'.format(self.commandtext.get(), box),
            2)
        return

    def check_entval(self):

        self.hostcheck=all((self.hostnum1.check(),self.hostnum2.check(),\
                            self.hostnum3.check(),self.hostnum4.check()))
        self.portcheck = self.portnum.check()

        if self.hostcheck:
            self.errhost.place(relx=0.4, rely=0.4)
        else:
            self.errhost.place_forget()
        if self.portcheck:
            self.errport.place(relx=0.4, rely=0.4)
        else:
            self.errport.place_forget()
        return

    def socket_thread(self):

        host = self.check_ip()
        port = self.check_port()
        if (host and port):

            self.showtext("thread started.. ", 0)
            self.ls = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.ls.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            try:
                self.ls.bind((host, port))

            except OSError as err:
                self.enableedit()
                self.showtext("OS error: {0} ".format(err), 9)
                self.showtext(
                    'Please Close Application using Port: %s ' % port, 9)
                self.showtext('Server Stopped ', 7)
                self.connectionl.configure(text="OFF.", bg='#ff5f5f')
                raise OSError('Port Being Used')
                return

            self.running = 1
            sleep(0.2)

            try:
                self.showtext("Server listening on port %s " % port, 1)
                while self.running != 0:
                    self.ls.listen(5)
                    self.ls.setblocking(1)
                    self.connectionl.configure(text="RUNNING!", bg='#4bb543')
                    (conn, addr) = self.ls.accept()
                    self.showtext("client is at "+ str(addr[0])+ \
                                       " on port "+str(addr[1]),2)
                    newthread = Thread(target=self.run_server,
                                       args=(conn, addr))
                    newthread.start()
                    newthread.join(1)

            except (Exception) as e:
                self.enableedit()
                self.showtext("Connect exception: " + str(e) + '', 9)
                self.connectionl.configure(text="OFF.", bg='#ff5f5f')
                self.forcestop()
                return

        return

    def run_server(self, conn, addr):
        head = b'\x34\x37\x36\x35'
        NotInserted = True
        i = 0
        counter = 0
        data_saved = bytearray(b'')
        seed_data = []

        recv_data = bytearray(b'')
        data_recv = bytearray(b'')
        timeNotpresent = True
        SendClientInfo = False
        st = Stream([])

        self.showtext("connected to {}, {}".format(conn, addr), 3)
        self.showtext('Data From: {}'.format(addr), 3)

        try:

            while self.running != 0:

                recv_data = bytearray(conn.recv(524288))
                Permission = False
                data_recv += recv_data

                if len(data_recv) >= 15000:

                    start = data_recv.find(b'\x32\x34\x56\x67')
                    end = data_recv.rfind(b'\x32\x34\x56\x67')
                    check = (len(data_recv[start:end]) - self.headlen) % 4

                    if start == end:

                        data_recv = data_recv[start:]

                    elif end > start and (check) % 4 == 0:

                        data_buffer = data_recv[start:end]
                        data_recv = data_recv[end:]
                        Permission = True

                    elif end > start:

                        data_buffer = data_recv[start:end - check]
                        data_recv = data_recv[end:]
                        Permission = True

                if (Permission and len(data_buffer) > 12):

                    connect_start = time()  # reset timeout time

                    if i == 0:
                        i += 1
                        data_buffer.clear()
                        Permission = False
                        continue

                    ID = str(data_buffer[4:7].decode())

                    if (ID == 'SEL'):

                        children = self.clidisp.get_children()
                        # self.values=b'\xff\xfe\xfd\xfc\xfb'
                        self.values = bytearray(b'')

                        for child in children:
                            a = list(self.clidisp.item(child).values())
                            a = a[2][0]
                            if isinstance(a, int):
                                thing = struct.pack('>H', a)
                                self.values += thing

                        conn.sendall(self.bytestosend + head + self.values)
                        # self.bytestosend.clear()
                        self.bytestosend = bytearray(b'')

                        if NotInserted:
                            address = ('{}:{}'.format(addr[0], addr[1]))
                            self.clidisp.insert('',
                                                'end',
                                                'box' + ID,
                                                values=(ID, address))
                            #                        self.clientnum.config(text=str(len(self.clidisp.get_children())))
                            NotInserted = False

                        if (data_buffer[7:9] != b'\x99\x99'):
                            self.desiredbox = struct.unpack(
                                '>H', data_buffer[7:9])[0]

                    else:
                        # conn.settimeout(120)
                        conn.sendall(data_buffer[0:7])

                        #                       print(data_buffer[0:7])

                        if int(ID) == self.desiredbox:
                            self.bytestosend.clear()
                            self.bytestosend += data_buffer

                        if (self.tgtbox == ID):

                            command = self.commandtext.get()
                            commandtosend = self.commandlist[command]
                            conn.sendall(commandtosend)
                            counter += 1

                            if counter >= 5:
                                self.tgtbox = None
                                continue
                            if counter > 10:
                                self.tgtbox = None
                                break

                        if NotInserted:
                            address = ('{}:{}'.format(addr[0], addr[1]))
                            try:
                                self.clidisp.insert('',
                                                    'end',
                                                    'box{}'.format(ID),
                                                    values=(ID, address))
                            except:
                                pass

    #                        self.clientnum.config(text=str(len(self.clidisp.get_children())))
                            NotInserted = False
                            self.showtext('Hello, I am Box# {}'.format(ID), 2)
                        self.checkcolor()
                        if timeNotpresent:
                            try:
                                year = struct.unpack('>1H', data_buffer[7:9])
                                year = int(year[0])
                                month = int(
                                    struct.unpack('>1B', data_buffer[9:10])[0])
                                day = int(
                                    struct.unpack('>1B',
                                                  data_buffer[10:11])[0])
                                hour = int(
                                    struct.unpack('>1B',
                                                  data_buffer[11:12])[0])
                                minute = int(
                                    struct.unpack('>1B',
                                                  data_buffer[12:13])[0])
                                second = int(
                                    struct.unpack('>1B',
                                                  data_buffer[13:14])[0])
                                starttime = datetime(year, month, day, hour,
                                                     minute, second)

                            except:
                                self.showtext(
                                    'Invalid Time in box# {}.. Using Computer UTC\
                                                time instead'.format(ID), 7)
                                starttime = datetime.utcnow()
                                timeNotpresent = False

                        data_buffer = bytearray(data_buffer[self.headlen:])

                        if self.v.get():
                            if timeNotpresent:
                                fn = starttime.strftime("%Y%m%d%H%M%Ss")
                                timeNotpresent = False

                            data_saved += data_buffer

                            if len(data_saved) >= 12000 * self.timespan.get():
                                #                            self.showtext('Time Check--> '+str(starttime),2,self.debug.get())
                                self.showtext(
                                    '{} Writing Original Files'.format(addr),
                                    2, self.debug.get())
                                with open(
                                        os.path.join(self.dir, str(ID),
                                                     fn + '.dat'), 'wb') as f:
                                    f.write(data_saved)
                                data_saved.clear()
                                timeNotpresent = True

                        else:

                            unpacked_display_data = np.array(
                                unpack(data_buffer))
                            if max(unpacked_display_data) > 10e10:
                                data_buffer.clear()
                                Permission = False
                                self.showtext(
                                    'Box {} Have corrupted Data'.format(ID), 7)
                                seed_data.extend(
                                    np.zeros(len(unpacked_display_data)))
                                continue

                            # seed_data.extend(unpacked_display_data)

                            # if len(seed_data) >=3000*self.timespan.get():
                            #     self.showtext('{} Writing miniseed Files'.format(addr),2,self.debug.get())
                            #     writeseed(np.array(seed_data[:3000*self.timespan.get()]),\
                            #               starttime,ID,self.dir)
                            #     seed_data=seed_data[3000*self.timespan.get():]
                            #     timeNotpresent=True

                            tempst=trace_gen(unpacked_display_data,\
                                              starttime,ID)

                            st += tempst

                            if (len(st) >= int(3 * self.timespan.get())):

                                self.showtext(
                                    '{} Writing mini-seed Files'.format(addr),
                                    2, self.debug.get())
                                st.merge(method=1, fill_value='interpolate')
                                # st.merge(method=-1)
                                writestream(st, ID, self.dir)
                                st = Stream([])

                    data_buffer.clear()
                    Permission = False

                    if (self.running == 0) or (time() - connect_start > 60):
                        self.showtext("No Data! Closing Connections!", 9)
                        # self.clidisp.delete('box'+str(ID))
                        break

        except (Exception) as e:
            # we can wait on the line if desired
            self.showtext("socket error: " + repr(e), 9)

        finally:

            self.showtext("Client at {} disconnected...".format(addr), 3)
            SendClientInfo = False
            try:
                self.clidisp.delete('box{}'.format(ID))
                conn.shutdown(socket.SHUT_RDWR)
            except:
                pass
            self.showtext("closing connection on Box# {}".format(ID), 5)
            conn.close()
            self.showtext("connection closed on Box# {}".format(ID), 4)
            self.tgtbox = None
            counter = 0
            self.checkcolor()
            return

    def close_sequence(self, conn, addr, ID=None):

        try:
            self.clidisp.delete('box{}'.format(ID))
            self.forcestop()
        except:
            pass

        self.checkcolor()
        return

    def startc(self):

        if self.running == 0:

            self.disableedit()
            self.connectionl.configure(text="INITIALIZING!", bg='#ffffaa')
            self.size = 1000 * 3 * int(self.timespan.get())
            self.scale.config(state='disabled', bg='#3f3f3f', fg='#fafafa')
            self.showtext("Starting Server ", 0)
            self.thread = Thread(target=self.socket_thread)
            self.thread.start()

            self.startb.configure(bg='#ff276f',
                                  text="Stop Server",
                                  command=self.stopc)

        else:
            self.showtext("Server already started. ", 8)
            return
        return

    def stopc(self):

        self.enableedit()
        self.scale.config(state='active', bg='#dcdcdc', fg='#000000')

        if self.running:
            self.forcestop(Close=True)
            self.showtext("stopping thread... ", 7)
            sleep(1)
            self.clidisp.delete(*self.clidisp.get_children())
            self.checkcolor()
            self.connectionl.configure(text="OFF.", bg='#ff5f5f')
            self.running = 0
            self.thread.join(1)

        try:
            raise KeyboardInterrupt('Server Terminated Due to user Action')
        except KeyboardInterrupt:
            self.showtext('Server Terminated Due to user Action', 7)
            return
        else:
            self.showtext("Server not running", 7)
        return

    def check_ip(self):

        try:
            if int(self.hostnum1.get()) > 255:
                showerror(
                    "Error",
                    "First number in your Host Section is greather than 255 ")
                self.showtext('Server Stopped ', 7)
                return 0
            elif int(self.hostnum2.get()) > 255:
                showerror(
                    "Error",
                    "Second number in your Host Section is greather than 255 ")
                self.showtext('Server Stopped ', 7)
                return 0

            elif int(self.hostnum3.get()) > 255:
                showerror(
                    "Error",
                    "Third number in your Host Section is greather than 255 ")
                self.showtext('Server Stopped ', 7)
                return 0

            elif int(self.hostnum4.get()) > 255:

                showerror(
                    "Error",
                    "Forth number in your Host Section is greather than 255 ")
                self.showtext('Server Stopped ', 7)
                return 0

            else:
                return '{}.{}.{}.{}'.format (self.hostnum1.get(),self.hostnum2.get(),\
                  self.hostnum3.get(),self.hostnum4.get())
        except:
            showerror(
                "Error",
                "Please make sure whole numbers are entered in host section")
            self.showtext('Server Stopped ', 7)
            return 0

    def check_port(self):

        try:

            if 65536 < int(self.portnum.get()):

                showerror(
                    "Error",
                    "Please enter a whole number between 1 and 65535 in Port section"
                )
                self.showtext('Server Stopped ', 7)
            else:
                return int(self.portnum.get())

        except:

            showerror(
                "Error",
                "Please make sure whole numbers are entered in port section")
            self.showtext('Server Stopped ', 7)

            return 0

    def Folder(self):

        targetdir = askdirectory()

        if targetdir:
            self.dirtext.config(text=targetdir)
            self.dir = targetdir
        return

    def checkcolor(self):

        if len(self.clidisp.get_children()) > 0:

            self.numtitle.config(text='Total Connected Clients: ',\
                        bg='#afffbf')

            self.clientnum.config(text=str(len(self.clidisp.get_children())),\
                         bg='#afffbf',font=("", 16))
        else:

            self.numtitle.config(text='Total Connected Clients: ',\
                        bg='#ff5f5f')

            self.clientnum.config(text=str(len(self.clidisp.get_children())),\
                         bg='#ff5f5f',font=("", 16))
        return

    def placeframe(self):

        if self.expertmode.get():
            showwarning("Warning","Command in Expert Mode can permnantly " \
                               'shutdown selected device(s)')
            self.framecommand.place(relx=0.05, rely=0.79)

        else:

            self.framecommand.place_forget()

        return

    def showtext(self, text, colorcheck, DEBUG=True):

        with open('logs.txt', 'a+') as f:
            f.write(gettime() + text + '\n')

        if DEBUG:
            self.logger.config(state=NORMAL)
            self.logger.insert(END, gettime() + text + '\n', colorcheck)
            self.logger.see('end')
            self.logger.config(state=DISABLED)
            return
        return

    def forcestop(self, Close=False):
        self.startb.configure(bg='#90ee90',
                              text="Start Server",
                              command=self.startc)
        try:
            self.ls.shutdown(socket.SHUT_RDWR)
        except:
            pass
        if Close:
            try:
                self.ls.close()
            except:
                pass
        return

    def enableedit(self):

        self.portnum.configure(state='normal')
        self.hostnum1.configure(state='normal')
        self.hostnum2.configure(state='normal')
        self.hostnum3.configure(state='normal')
        self.hostnum4.configure(state='normal')
        self.rb1.configure(state='normal')
        self.rb2.configure(state='normal')
        self.outbtn.configure(state='normal')
        return

    def disableedit(self):

        self.portnum.configure(state='disable')
        self.hostnum1.configure(state='disable')
        self.hostnum2.configure(state='disable')
        self.hostnum3.configure(state='disable')
        self.hostnum4.configure(state='disable')
        self.rb1.configure(state='disable')
        self.rb2.configure(state='disable')
        self.outbtn.configure(state='disable')
        return
Exemple #29
0
class App(Frame):
    cnx = ""

    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.variable = ""
        self.searchby = Button()
        self.login(parent)
        self.tree = ""
        self.b_login = Button()
        self.searchbylist = [
            "All", "Date", "Crime Type", "Reporter", "Building Name"
        ]  # Select

    # default value

    def login(self, parent):
        username = Label(parent, text="Username: "******"Password: "******"Invalid",
                                    "Invalid Username or Password. Try Again")
                e_password.delete(0, 'end')
                e_username.delete(0, 'end')

        self.b_login = Button(parent, text="login", command=cconnectwrap)
        self.b_login.pack()

    def searchswitch(self, parent):
        self.searchby = self.variable.get()
        crimetypelist = []  # Select
        cur = App.cnx.cursor()
        cur.execute("SELECT type from crime_type")
        for row in cur.fetchall():
            crimetypelist.append(row)
        variable1 = StringVar(parent)
        variable1.set(crimetypelist[0])  # default value
        cur.close()

    def homescreen(self):
        parent = Tk()
        parent.geometry("600x300")
        title = Label(parent, text="Search By:")
        title.pack()
        self.variable = StringVar(parent)
        self.variable.set(self.searchbylist[0])

        d_searchBy = OptionMenu(parent, self.variable, *self.searchbylist)
        d_searchBy.pack()

        self.e_searchbyx = Entry(parent)
        self.e_searchbyx.pack()

        b_search = Button(parent,
                          text="search",
                          command=(lambda: self.view(parent)))
        b_search.pack()

        b_create = Button(parent,
                          text="Report a New Crime",
                          command=self.create)
        b_create.pack()

    entrydate = ""
    entrytime = ""
    entryreporter = ""
    entrybuildingname = ""
    entrystreet = ""
    entrycity = ""
    entryzipcode = ""
    entrystate = ""
    entrysuspect = ""
    entrycrimetype = ""
    entryresolution = ""
    entrynotes = ""

    def create(self):
        root3 = Tk()

        def createindbwrapper():
            print("empty")
            if len(e_state.get()) == 0 or len(e_street.get()) == 0 or len(
                    e_suspect.get()) == 0 or len(
                    e_time.get()) == 0 or len(e_notes.get()) == 0 \
                    or len(e_resolution.get()) == 0 or len(e_date.get()) == 0 or len(
                e_reporter.get()) == 0 or len(e_crimetype.get()) == 0 \
                    or len(e_buildingname.get()) == 0 or len(e_zipcode.get()) == 0 or len(
                e_city.get()) == 0:
                print("empty")
                MessageBox.showinfo("Invalid", "Must Fill All Fields")
            elif validatedate(e_date.get()):
                MessageBox.showinfo("Invalid", "Must enter a valid date")
            elif validatetime(e_time.get()):
                MessageBox.showinfo("Invalid", "Must enter a valid time")
            elif len(e_zipcode.get()) >= 5:
                MessageBox.showinfo("Invalid", "Must enter a valid zipcode"
                                    )  # TODO:CHECK ZIP AND STATE ABREV
            else:
                createindb()

        def createindb():
            cursor = App.cnx.cursor()
            sql = """INSERT INTO report (location_id, crime_type, reporter_id, date, resolution, 
            notes, time, suspect_id) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)"""

            query = "SELECT getAddressID(%s, %s, %s, %s)"
            cursor.execute(
                query,
                (e_state.get(), e_city.get(), e_street.get(), e_zipcode.get()))
            pk1 = cursor.fetchone()
            pk2 = list(pk1.values())
            address = pk2[0]
            App.cnx.commit()
            print(address)

            query = "SELECT getLocationID(%s, %s)"
            cursor.execute(query, (e_buildingname.get(), address))
            pk1 = cursor.fetchone()
            pk2 = list(pk1.values())
            buildingname = pk2[0]
            App.cnx.commit()

            query = "SELECT getCrimeTypeID(%s)"
            cursor.execute(query, e_crimetype.get())
            pk1 = cursor.fetchone()
            pk2 = list(pk1.values())
            crimetype = pk2[0]
            App.cnx.commit()

            query = "SELECT getReporterID(%s)"
            cursor.execute(query, e_reporter.get())
            pk1 = cursor.fetchone()
            pk2 = list(pk1.values())
            reporter = pk2[0]
            App.cnx.commit()

            date = e_date.get()

            resolution = e_resolution.get()

            notes = e_notes.get()

            time = e_time.get()

            query = "SELECT getSuspectID(%s)"
            cursor.execute(query, e_suspect.get())
            pk1 = cursor.fetchone()
            pk2 = list(pk1.values())
            suspect = pk2[0]
            App.cnx.commit()

            vals = ({buildingname}, {crimetype}, {reporter}, {date},
                    {resolution}, {notes}, {time}, {suspect})

            cursor.execute(sql, vals)
            App.cnx.commit()
            cursor.close()
            root3.destroy()

        l_date = Label(root3, text="Date (YYYY-MM-DD)")
        l_date.pack()
        e_date = Entry(root3)
        e_date.pack()
        e_date.insert(0, self.entrydate)

        l_time = Label(root3, text="Time (HH:MM:SS)")
        l_time.pack()
        e_time = Entry(root3)
        e_time.pack()
        e_time.insert(0, self.entrytime)

        l_reporter = Label(root3, text="Reporter")
        l_reporter.pack()
        e_reporter = Entry(root3)
        e_reporter.pack()
        e_reporter.insert(0, self.entryreporter)

        l_buildingname = Label(root3, text="Building Name")
        l_buildingname.pack()
        e_buildingname = Entry(root3)
        e_buildingname.pack()
        e_buildingname.insert(0, self.entrybuildingname)

        l_street = Label(root3, text="Street")
        l_street.pack()
        e_street = Entry(root3)
        e_street.pack()
        e_street.insert(0, self.entrystreet)

        l_city = Label(root3, text="City")
        l_city.pack()
        e_city = Entry(root3)
        e_city.pack()
        e_city.insert(0, self.entrycity)

        l_zipcode = Label(root3, text="Zipcode")
        l_zipcode.pack()
        e_zipcode = Entry(root3)
        e_zipcode.pack()
        e_zipcode.insert(0, self.entryzipcode)

        l_state = Label(root3, text="State Abbrev.")
        l_state.pack()
        e_state = Entry(root3)
        e_state.pack()
        e_state.insert(0, self.entrystate)

        l_suspect = Label(root3, text="Suspect")
        l_suspect.pack()
        e_suspect = Entry(root3)
        e_suspect.pack()
        e_suspect.insert(0, self.entrysuspect)

        l_crimetype = Label(root3, text="Crime Type")
        l_crimetype.pack()
        e_crimetype = Entry(root3)
        e_crimetype.pack()
        e_crimetype.insert(0, self.entrycrimetype)

        l_resolution = Label(root3, text="Resolution")
        l_resolution.pack()
        e_resolution = Entry(root3)
        e_resolution.pack()
        e_resolution.insert(0, self.entryresolution)

        l_notes = Label(root3, text="Notes")
        l_notes.pack()
        e_notes = Entry(root3)
        e_notes.pack()
        e_notes.insert(0, self.entrynotes)

        b_submit = Button(root3, text="Submit", command=createindbwrapper)
        b_submit.pack()

    def view(self, root5):

        self.searchswitch(root5)

        searchcategory = self.searchby
        searchtext = self.e_searchbyx.get()
        cursor = App.cnx.cursor()
        print(searchcategory)

        if searchcategory == "All":
            query = "SELECT * FROM report"
            cursor.execute(query)
        elif searchtext == "":
            MessageBox.showinfo("Invalid", "Enter a Search")
        elif validatedate(searchtext) and searchcategory == "Date":
            MessageBox.showinfo("Invalid", "Enter a Valid Date")
        elif searchcategory == "Crime Type":
            query = "SELECT getCrimeTypeID(%s)"
            cursor.execute(query, searchtext)
            pk1 = cursor.fetchone()
            pk2 = list(pk1.values())
            pk = pk2[0]
            print(pk)
            query = "SELECT * FROM report WHERE crime_type = %s"
            cursor.execute(query, pk)
        elif searchcategory == "Building Name":
            query = "SELECT location_id FROM location WHERE building_name = %s"
            cursor.execute(query, searchtext)
            pk1 = cursor.fetchone()
            pk2 = list(pk1.values())
            pk = pk2[0]
            query = "SELECT * FROM report WHERE location_id = %s"
            cursor.execute(query, pk)
        elif searchcategory == "Date":
            query = "SELECT * FROM report WHERE date = %s"
            cursor.execute(query, searchtext)
        elif searchcategory == "Reporter":
            query = "SELECT getReporterID(%s)"
            cursor.execute(query, searchtext)
            pk1 = cursor.fetchone()
            pk2 = list(pk1.values())
            pk = pk2[0]
            print(pk)
            query = "SELECT * FROM report WHERE reporter_id = %s"
            cursor.execute(query, pk)

        def create_window(root2):
            def update():

                curItem = self.tree.focus()
                selected_item = self.tree.selection()[0]  ## get selected item
                curAddy = ""
                curAddy2 = ""
                for child in self.tree.get_children(curItem):
                    curAddy = child
                for child in self.tree.get_children(selected_item):
                    curAddy2 = child
                prik = (self.tree.item(curItem).get("values")[0])
                self.entrydate = (self.tree.item(curItem).get("values")[1])
                self.entrytime = (self.tree.item(curItem).get("values")[2])
                self.entryreporter = (self.tree.item(curItem).get("values")[3])
                self.entrybuildingname = (
                    self.tree.item(curItem).get("values")[4])
                self.entrycrimetype = (
                    self.tree.item(curItem).get("values")[5])
                self.entrysuspect = (self.tree.item(curItem).get("values")[6])
                self.entryresolution = (
                    self.tree.item(curItem).get("values")[7])
                self.entrynotes = (self.tree.item(curItem).get("values")[8])
                self.entrystreet = (self.tree.item(child)).get("values")[3]
                self.entrycity = (self.tree.item(child)).get("values")[4]
                self.entrystate = (self.tree.item(child)).get("values")[5]
                self.entryzipcode = (self.tree.item(child)).get("values")[6]

                self.tree.item(selected_item,
                               values=(prik, self.entrydate, self.entrytime,
                                       self.entryreporter,
                                       self.entrybuildingname,
                                       self.entrycrimetype, self.entrysuspect,
                                       self.entryresolution, self.entrynotes))
                self.tree.item(curAddy2,
                               values=(" ", " ", "Address: ", self.entrystreet,
                                       self.entrycity, self.entrystate,
                                       self.entryzipcode))
                self.create()

                self.entrydate = ""
                self.entrytime = ""
                self.entryreporter = ""
                self.entrybuildingname = ""
                self.entrystreet = ""
                self.entrycity = ""
                self.entryzipcode = ""
                self.entrystate = ""
                self.entrysuspect = ""
                self.entrycrimetype = ""
                self.entryresolution = ""
                self.entrynotes = ""

                query = "CALL crime.delete_report(%s);"
                cursor.execute(query, prik)
                self.cnx.commit()

            def delete():
                try:
                    curItem = self.tree.focus()
                    prik = (self.tree.item(curItem).get("values")[0])
                    selected_item = self.tree.selection()[
                        0]  ## get selected item
                    self.tree.delete(selected_item)
                    if prik in lreportid:
                        query4 = "CALL crime.delete_report(%s);"
                        cursor.execute(query4, prik)
                        self.cnx.commit()
                except IndexError:
                    print("uu")

            b_delete = Button(root2, text="Delete", command=delete)
            b_delete.pack()

            b_update = Button(root2, text="Update", command=update)
            b_update.pack()

            bikesstolen = "SELECT MAX(stolen_so_far) FROM bikes_stolen"
            cursor.execute(bikesstolen)
            disp = cursor.fetchone()
            display = str(disp.get("MAX(stolen_so_far)"))
            t = "Bikes Stolen So Far: " + display
            l_bikes = Label(root2, text=t)
            l_bikes.pack()

            self.tree = Treeview(root2)
            style = ttk.Style(root2)
            style.configure('Treeview', rowheight=130)
            self.tree['show'] = 'headings'
            self.tree["columns"] = ("1", "2", "3", "4", "5", "6", "7", "8",
                                    "9")
            self.tree.column("1", width=30)
            self.tree.column("2", width=100)
            self.tree.column("3", width=70)
            self.tree.column("4", width=150)
            self.tree.column("5", width=150)
            self.tree.column("6", width=100)
            self.tree.column("7", width=150)
            self.tree.column("8", width=250)
            self.tree.column("9", width=300)

            self.tree.heading("1", text="Report ID")
            self.tree.heading("2", text="Date")
            self.tree.heading("3", text="Time")
            self.tree.heading("4", text="Reporter")
            self.tree.heading("5", text="Building Name")
            self.tree.heading("6", text="Crime Type")
            self.tree.heading("7", text="Suspect")
            self.tree.heading("8", text="Resolution")
            self.tree.heading("9", text="Notes")

            i = 0
            while i < numrows:
                a = self.tree.insert("",
                                     lreportid[i],
                                     values=(lreportid[i], ldate[i], ltime[i],
                                             lreporter[i], lbuildingname[i],
                                             lcrimetype[i],
                                             lsuspect[i], lresolution[i],
                                             wrap(lnotes[i], 40)))

                valuedat = lstreet[i] + " " + lcity[i] + ", " + lstate[
                    i] + " " + lzipcode[i]
                self.tree.insert(a,
                                 lreportid[i],
                                 values=(" ", " ", "Address: ", lstreet[i],
                                         lcity[i], lstate[i], lzipcode[i]))
                i += 1
            self.tree.pack()

        if (searchtext != "" or searchcategory
                == "All") or (searchcategory == "Date"
                              and validatedate(searchtext)):  # TODO:wlkj
            data = cursor.fetchall()
            numrows = 0
            lreportid = []
            query1 = "SELECT building_name FROM location WHERE location_id = %s"
            lbuildingname = []
            query2 = "SELECT type FROM crime_type WHERE crime_type_id = %s"
            lcrimetype = []
            ldate = []
            ltime = []
            lresolution = []
            lnotes = []
            query3 = "SELECT suspect_desc FROM suspect WHERE suspect_id = %s"
            lsuspect = []
            query4 = "SELECT reporter_description FROM reporter WHERE reporter_id = %s"
            lreporter = []

            query5 = "SELECT state FROM address JOIN location ON location.address = " \
                     "address.address_id WHERE location_id = %s"
            lstate = []

            query6 = "SELECT city FROM address JOIN location ON location.address = " \
                     "address.address_id WHERE location_id = %s"
            lcity = []

            query7 = "SELECT street FROM address JOIN location ON location.address = " \
                     "address.address_id WHERE location_id = %s"
            lstreet = []

            query8 = "SELECT zipcode FROM address JOIN location ON location.address = " \
                     "address.address_id WHERE location_id = %s"
            lzipcode = []

            for row in data:
                print(row)
                lreportid.insert(numrows, row.get('report_id'))

                print(row.get('location_id'))
                cursor.execute(query1, row.get('location_id'))
                buildingname = cursor.fetchone()
                print(buildingname)
                lbuildingname.insert(numrows,
                                     buildingname.get("building_name"))

                cursor.execute(query2, row.get('crime_type'))
                crimetype = cursor.fetchone()

                lcrimetype.insert(numrows, crimetype.get("type"))

                ldate.insert(numrows, row.get('date'))

                ltime.insert(numrows, row.get('time'))

                lresolution.insert(numrows, row.get('resolution'))

                lnotes.insert(numrows, row.get('notes'))

                cursor.execute(query3, row.get('suspect_id'))
                suspect = cursor.fetchone()
                lsuspect.insert(numrows, suspect.get("suspect_desc"))

                cursor.execute(query4, row.get('reporter_id'))
                reporter = cursor.fetchone()
                lreporter.insert(numrows, reporter.get("reporter_description"))

                cursor.execute(query5, row.get('location_id'))
                state = cursor.fetchone()
                lstate.insert(numrows, state.get("state"))

                cursor.execute(query6, row.get('location_id'))
                city = cursor.fetchone()
                lcity.insert(numrows, city.get("city"))

                cursor.execute(query7, row.get('location_id'))
                street = cursor.fetchone()
                lstreet.insert(numrows, street.get("street"))

                cursor.execute(query8, row.get('location_id'))
                zipcode = cursor.fetchone()
                lzipcode.insert(numrows, zipcode.get("zipcode"))
                numrows += 1

            root2 = Tk()
            root2.geometry("1500x1000")

            create_window(root2)
Exemple #30
0
class PyCube:
    
    def __init__(self):
        self.root = Tk()
        self.root.title("PyCube")
        
        self.session = Session()
        
        # init UI
        self.initMenu()
        self.leftframe = Frame(self.root)
        self.leftframe.pack(side=LEFT, fill=BOTH, expand=1)
        
        self.rightframe = Frame(self.root)
        self.rightframe.pack(side=RIGHT, fill=BOTH, expand=1)
        
        self.cubesize = 3
        scrambler.parse(self.cubesize, 30, False, False)
        scrambler.scramble()
        self.scramble = Label(self.leftframe, text=scrambler.scramblestring(0))
        self.scramble.pack()

        self.time_label = Label(self.leftframe, text="0.000")
        self.time_label.pack()
        
        self.plus2_button = Button(self.leftframe, text="+2", command=self.plus2)
        self.plus2_button.pack()
        
        self.dnf_button = Button(self.leftframe, text="DNF", command=self.dnf)
        self.dnf_button.pack()
        
        self.delete_button = Button(self.leftframe, text="Delete", command=self.delete)
        self.delete_button.pack()
        
        self.scramble_img = Label(self.leftframe)
        self.scramble_img.pack()
        self.update_image()
        
        self.grid = Treeview(self.rightframe)
        self.grid["columns"] = ("times", "avg5", "avg12", "mean", "sd")
        self.grid.heading("#0", text='Time', anchor='w')
        self.grid.column("#0", stretch=NO, width=0, anchor="w")
        self.grid.heading("times", text="Times")
        self.grid.column('times', anchor='center', width=70)
        self.grid.heading("avg5", text="Avg. of 5")
        self.grid.column('avg5', anchor='center', width=70)
        self.grid.heading("avg12", text="Avg. of 12")
        self.grid.column('avg12', anchor='center', width=70)
        self.grid.heading("mean", text="Session mean")
        self.grid.column('mean', anchor='center', width=80)
        self.grid.heading("sd", text="SD")
        self.grid.column('sd', anchor='center', width=70)
        
        self.gridscroll = Scrollbar()
        self.gridscroll.configure(command=self.grid.yview)
        
        self.grid.configure(yscrollcommand=self.gridscroll.set)
        self.grid.pack(side=TOP)
        
        self.root.bind("<KeyRelease-space>", self.start_inspection)
        self._job = None
        self.running = False
        
        self.root.mainloop()
        
    def initMenu(self):
        menubar = Menu(self.root)
        self.root.config(menu=menubar)
        
        fileMenu = Menu(menubar)
        fileMenu.add_command(label="New", command=self.session_new)
        fileMenu.add_separator()
        fileMenu.add_command(label="Import", command=self.session_import)
        fileMenu.add_command(label="Export", command=self.session_export)
        menubar.add_cascade(label="File", menu=fileMenu)
        
    def start_timer(self, event=None):
        if not self.running:
            self.root.after_cancel(self._job)
            self._job = None
            self.t0 = float("%.3f" % time.time())
            self.update_timer()
            self.running = True
            self.root.bind("<KeyPress-space>", self.reset_timer)
    
    def reset_timer(self, event=None):
        if self.running:
            self.root.after_cancel(self._job)
            self._job = None
            self.running = False
            self.root.bind("<KeyRelease-space>", self.rebind)
            
            t = self.time_label.cget("text")
            if ":" in str(t):
                mins, secs = t.split(":")
                t = (mins * 60) + secs
            self.session.addtime(t, 0, scrambler.scramblestring(0))
            
            entry = self.session.data[-1][1:]
            self.grid.insert("", "end", values=(entry))
            
            scrambler.parse(self.cubesize, 30, False, False)
            scrambler.scramble()
            scramblestr = scrambler.scramblestring(0)
            self.scramble.configure(text=scramblestr)
            self.update_image()
            
    def rebind(self, event=None):
        self.root.bind("<KeyRelease-space>", self.start_inspection)
        
    def update_timer(self):
        now = float("%.3f" % (time.time() - self.t0))
        if now > 60:
            mins = math.floor(now / 60)
            secs = now - (mins * 60)
            now = f"{mins}:{secs}"
        self.time_label.configure(text=now, fg="black")
        self._job = self.root.after(10, self.update_timer)
    
    def start_inspection(self, event=None):
        self.inspect_time = 16
        self.root.bind("<KeyRelease-space>", self.start_timer)
        self.update_inspection()
    
    def update_inspection(self):
        if self.inspect_time == 0:
            self.time_label.configure(text="DNF", fg="red")
            
            # Really ugly was to add a straight DNF, should fix later
            # NOTE: Known bug when first time is DNF. MUST FIX
            self.session.addtime(0, 2, scrambler.scramblestring(0))
            entry = self.session.data[-1][1:]
            self.grid.insert("", "end", values=(entry))
            self.dnf()
        else:
            self.inspect_time -= 1
            self.time_label.configure(text=self.inspect_time, fg="red")
            self._job = self.root.after(1000, self.update_inspection)
        
    def update_image(self):
        img = ImageTk.PhotoImage(genimage(scrambler.imagestring(0), self.cubesize))
        self.scramble_img.configure(image=img)
        self.scramble_img.image = img
    
    def delete(self, event=None):
        if len(self.session.data) > 0:
            last = self.session.getlastitemid()
            self.grid.delete(last)
            self.session.removetime(last) 
    
    def plus2(self, event=None):
        if len(self.session.data) > 0:
            last = self.session.getlastitemid()
            index = len(self.session.data) - 1
            entry = self.session.data[index]
            
            # Check if time isn't already +2 or DNF9
            if entry[6] != 0:
                return
            
            entry[1] = float("%.3f" % (entry[1] + 2))
            entry[6] = 1
            entry = self.session.calcstats()
            vals = entry[1:] + [scrambler.scramblestring(0)]
            vals[0] = str(vals[0]) + "(+2)"
            self.grid.item(last, values=(vals))
            
    def dnf(self, event=None):
        if len(self.session.data) > 0:
            last = self.session.getlastitemid()
            index = len(self.session.data) - 1
            entry = self.session.data[index]
            
            entry[1] = "DNF"
            entry[6] = 2
            
            entry = self.session.calcstats()
            vals = entry[1:]
            self.grid.item(last, values=(vals))
            
    def session_new(self):
        self.session.clear()
        self.grid.delete(*self.grid.get_children())
    
    def session_import(self):
        f = filedialog.askopenfilename(initialdir="../data/",
                                       title="Import session",
                                       filetypes=(("Text Documents", "*.txt"), ("All Files", "*.*")))
        if f == '':
            return
        with open(f) as file:
            self.session_new()
            self.session = Session(file.read())
            
            for entry in self.session.data:
                self.grid.insert("", "end", values=(entry[1:]))
    
    def session_export(self):
        if not os.path.isdir("../data/"):
            os.makedirs("../data/")
            
        name = str(datetime.now())[:-7].replace('-', '').replace(':', '').replace(' ', '')
        f = filedialog.asksaveasfilename(initialfile=name,
                                         initialdir="../data/",
                                         defaultextension="*.txt",
                                         title="Export session",
                                         filetypes=(("Text Documents","*.txt"), ("All Files","*.*")))
        if f == '':
            return
        with open(f, 'w') as file:
            file.write(str(self.session))
Exemple #31
0
 def fill_table(self, table: ttk.Treeview, data: dict, **kwds) -> None:
     """Fills the table with data."""
     assert len(data) > 0, 'wrong data passes to the table'
     tag = kwds.get('tag', 'default')
     for values in data:
         table.insert('', END, values=(values, ), tags=tag)
class PreviewDataTable:
    """
    PreviewDataTable
    show the user the head of the data that they have imported
    @methods:
    ----------
    update_table: remove column names and rows, get column names from ImportDataManager, append data to each row
    Problem: treeview is resizing to the width of the screen size, when it's told explcitly not to (stretch=False)
    """
    def __init__(self, mainframe):
        self.mainframe = mainframe
        self.treeview = Treeview(mainframe.root)
        self.treeview['columns'] = ("column 1", "column 2", "column 3",
                                    "column 4", "column 5")
        self.treeview['show'] = 'headings'  # removes empty identifier column
        for column in self.treeview['columns']:
            self.treeview.heading(column, text=str(column), anchor="w")
            self.treeview.column(column,
                                 anchor="center",
                                 width=80,
                                 stretch=False)
        for i in range(5):
            self.treeview.insert('', 'end')
            self.treeview.bind('<Button-1>', self.handle_click)

    def update_table(self, dataframe=None):
        if isinstance(dataframe, pd.DataFrame) or isinstance(
                self.mainframe.importExportDataManager.get_data(),
                pd.DataFrame):
            # delete everything from treeview
            for child in self.treeview.get_children():
                self.treeview.delete(child)
            # create columns
            self.treeview[
                'columns'] = self.mainframe.importExportDataManager.get_column_names(
                )
            for column in self.treeview['columns']:
                self.treeview.heading(column,
                                      text=str(column),
                                      anchor="center")
                self.treeview.column(column,
                                     anchor="center",
                                     width=80,
                                     stretch=False)

            # insert data from head of pandas dataframe
            if dataframe is None and self.mainframe.importExportDataManager.get_data(
            ) is not None:
                df = self.mainframe.importExportDataManager.get_data().copy()
            else:
                df = dataframe.copy()
            self.format_data(df)
            for i, j in df.head().iterrows():
                append_data = []
                for k in j:
                    append_data.append(k)
                self.treeview.insert('', 'end', value=append_data)

    def format_data(self, df):
        if isinstance(df, pd.DataFrame):
            for column in df.columns:
                if df[column].dtype == "float64":
                    df[column] = df[column].round(decimals=int(
                        self.mainframe.optionsWindow.settings.get(
                            "decimal places")))

    # makes columns unresizeable
    def handle_click(self, event):
        if self.treeview.identify_region(event.x, event.y) == "separator":
            return "break"
Exemple #33
0
class ViewBookWindow:
    def __init__(self):
        self.win = tk.Tk()
        self.canvas = Canvas(self.win, width=800, height=450, bg='white')
        self.canvas.pack(expand=YES, fill=BOTH)

        # show window in center of the screen
        width = self.win.winfo_screenwidth()
        height = self.win.winfo_screenheight()
        x = int(width / 2 - 800 / 2)
        y = int(height / 2 - 450 / 2)
        str1 = "800x450+" + str(x) + "+" + str(y)
        self.win.geometry(str1)

        # disable resize window
        self.win.resizable(False, False)

        # changing title of the window
        self.win.title("| VIEWING BOOK DETAILS | LIBRARY MANAGEMENT SYSTEM |")

    def add_frame(self):
        self.frame = Frame(self.win, height=450, width=800)
        self.frame.place(x=0, y=0)

        # x, y = 0, 0

        self.label = Label(self.frame, text="VIEW BOOK DETAILS", fg='black')
        self.label.config(font=("Poppins", 20, 'underline bold'))
        self.label.place(x=265, y=30)

        # use tree view to show details from the table
        self.tr = Treeview(self.frame,
                           columns=('A', 'B', 'C', 'D', 'E'),
                           selectmode="extended")

        # heading key + text
        self.tr.heading('#0', text='BOOK_ID')
        self.tr.column('#0', minwidth=0, width=100, stretch=NO)
        self.tr.heading('#1', text='BOOK_TITLE')
        self.tr.column('#1', minwidth=0, width=100, stretch=NO)
        self.tr.heading('#2', text='AUTHOR NAME')
        self.tr.column('#2', minwidth=0, width=100, stretch=NO)
        self.tr.heading('#3', text='PUBLISHED_YEAR')
        self.tr.column('#3', minwidth=0, width=100, stretch=NO)
        self.tr.heading('#4', text='PRICE')
        self.tr.column('#4', minwidth=0, width=100, stretch=NO)
        self.tr.heading('#5', text='BOOK_CATEGORY')
        self.tr.column('#5', minwidth=0, width=115, stretch=NO)

        self.list = [
            'None', 'First Sem', 'Second Sem', 'Third Sem', 'Fourth Sem',
            'Fifth Sem', 'Sixth Sem', 'Seventh Sem', 'Eighth Sem',
            'Management', 'Technology', 'News paper', 'Magazines'
        ]
        self.filter = tk.StringVar(self.frame)
        self.drop = tk.OptionMenu(self.frame, self.filter, *self.list)
        self.drop.config(width=24)
        self.filter.set(self.list[0])
        self.drop.place(x=440, y=94)
        # self.filter = Entry(self.frame, font="Arial 12")
        # self.filter.place(x=440, y=94)
        search_text = self.filter.get()
        self.btn = Button(self.frame,
                          text='SEARCH',
                          width=9,
                          bg='white',
                          fg='black',
                          font=("Poppins", 11, "bold"),
                          command=self.sea)
        self.btn.place(x=630, y=90)
        j = 0

        for i in Database.database.ViewBooks():
            self.tr.insert('',
                           index=j,
                           text=i[0],
                           values=(i[1], i[2], i[3], i[4], i[5]))
            j += 1
        self.tr.place(x=100, y=140)

    def sea(self):
        nk = (self.filter.get(), )
        self.tr = Treeview(self.frame,
                           columns=('A', 'B', 'C', 'D', 'E'),
                           selectmode="extended")
        print(nk)

        # heading key + text
        self.tr.heading('#0', text='BOOK_ID')
        self.tr.column('#0', minwidth=0, width=100, stretch=NO)
        self.tr.heading('#1', text='BOOK_TITLE')
        self.tr.column('#1', minwidth=0, width=100, stretch=NO)
        self.tr.heading('#2', text='AUTHOR NAME')
        self.tr.column('#2', minwidth=0, width=100, stretch=NO)
        self.tr.heading('#3', text='PUBLISHED_YEAR')
        self.tr.column('#3', minwidth=0, width=100, stretch=NO)
        self.tr.heading('#4', text='PRICE')
        self.tr.column('#4', minwidth=0, width=100, stretch=NO)
        self.tr.heading('#5', text='BOOK_CATEGORY')
        self.tr.column('#5', minwidth=0, width=115, stretch=NO)

        j = 0
        if nk[0] == "":
            for i in Database.database.ViewBooks():
                self.tr.insert('',
                               index=j,
                               text=i[0],
                               values=(i[1], i[2], i[3], i[4], i[5]))
                j += 1
        else:
            for i in Database.database.filter(nk):
                self.tr.insert('',
                               index=j,
                               text=i[0],
                               values=(i[1], i[2], i[3], i[4], i[5]))
                j += 1

        self.tr.place(x=100, y=140)
        self.win.mainloop()
Exemple #34
0
class main():
    def __init__(self, tk):

        self.frame_lgn = Frame(lgn_Screen, width=450, height=750)
        self.frame_lgn.pack()

        #Separator
        self.pane_W = LabelFrame(lgn_Screen,
                                 text='Your Credentials',
                                 width=300,
                                 height=200)
        self.pane_W.place(x=1, y=10)

        #Login Entry
        self.usr_label = Label(lgn_Screen, text="Usuário:")
        self.usr_label.place(x=22, y=53)
        self.usr_entry = Entry(lgn_Screen, width=25)
        self.usr_entry.place(x=72, y=50)
        #Passowrd Entry
        self.pw_label = Label(lgn_Screen, text="Senha:")
        self.pw_label.place(x=30, y=103)
        self.pw_entry = Entry(lgn_Screen, show="*", width=25)
        self.pw_entry.place(x=72, y=100)

        def validate():
            usr = str(self.usr_entry.get())
            pw = str(self.pw_entry.get())

            print(usr)
            print(pw)

        #Separator message
        self.pane_W_Text = LabelFrame(lgn_Screen,
                                      text='Your Message:',
                                      width=300,
                                      height=200)
        self.pane_W_Text.place(x=1, y=210)
        #textbox
        self.tb = Text(lgn_Screen, width=35, height=8, borderwidth=0)
        self.tb.place(x=7, y=225)

        #Separator data
        self.pane_groups = LabelFrame(lgn_Screen,
                                      text='Seus Grupos aparecerão aqui:',
                                      width=300,
                                      height=200)
        self.pane_groups.place(x=1, y=410)

        self.tvGroups = Treeview(lgn_Screen)
        self.tvGroups.place(x=7, y=425, width=287, height=130)

        #Aviso de Botão
        fontStyle = tkFont.Font(size=8)
        self.advcLbl = Label(
            lgn_Screen,
            text=
            "* Aviso: o botão para confirmar o grupo será \nliberado em breve!",
            font=fontStyle)
        self.advcLbl.place(x=7, y=610)

        def conf_Message():
            msg = str(self.tb.get('1.0', 'end-1c'))
            print(msg)
            from selenium import webdriver
            from time import sleep
            from selenium.webdriver.common.keys import Keys

            url = "https://facebook.com/"
            d = webdriver.Chrome()
            d.get(url)

            sleep(2)

            target_user = d.find_element_by_xpath('//*[@id="email"]')
            target_pw = d.find_element_by_xpath('//*[@id="pass"]')
            target_user.click()
            sleep(2)
            target_user.send_keys(str(self.usr_entry.get()))
            sleep(2)
            target_pw.send_keys(str(self.pw_entry.get()))
            sleep(6)
            log_in = d.find_element_by_xpath('//*[@id="u_0_b"]')
            sleep(1)
            log_in.click()
            sleep(3)
            webdriver.ActionChains(d).send_keys(Keys.ESCAPE).perform()
            sleep(4)
            explore_Group = d.find_element_by_xpath(
                '//*[@id="navItem_1434659290104689"]/a/div')
            explore_Group.click()
            sleep(3)
            webdriver.ActionChains(d).send_keys(Keys.ESCAPE).perform()
            sleep(1)
            try:
                while True:
                    see_more = d.find_element_by_xpath(
                        "//*[contains(text(), 'Ver mais')]")
                    see_more.click()
                    sleep(2)
            except:
                pass
            sleep(3)
            groups = d.find_elements_by_class_name('_2yaa')
            l_groups = []
            for g_names in groups:
                l_groups.append(str(g_names.text))

            print(l_groups)
            group_index = []
            counter = 0
            for j in l_groups[:-1]:
                if str(j) == 'Descobrir':
                    continue
                print(str(counter) + " - " + str(j))
                counter += 1
                self.tvGroups.insert('', 'end', text=j)

            #selected_Group = ""
            def confirmGroup():
                self.cur = self.tvGroups.focus()
                self.selectedItem = str(self.tvGroups.item(self.cur)['text'])
                print(self.selectedItem)

                openGroup = d.find_element_by_xpath("//*[contains(text(), '" +
                                                    self.selectedItem + "')]")
                openGroup.click()
                sleep(6)
                postit = d.find_element_by_xpath(
                    "//*[@name='xhpc_message_text']")
                postit.send_keys(str(self.tb.get('1.0', 'end-1c')))
                sleep(5)
                publish = d.find_element_by_class_name('_332r')
                publish.click()

            self.selgroup = Button(lgn_Screen,
                                   text="Confirmar",
                                   width=10,
                                   font='Verdana 8',
                                   borderwidth=0,
                                   bg='#FFFFFF',
                                   fg='#363636',
                                   command=confirmGroup)
            self.selgroup.place(x=175, y=570)

        self.cnf_Msg = Button(lgn_Screen,
                              text="Confirmar",
                              width=10,
                              font='Verdana 8',
                              borderwidth=0,
                              bg='#FFFFFF',
                              fg='#363636',
                              command=conf_Message)
        self.cnf_Msg.place(x=175, y=370, height=20)
Exemple #35
0
class CreateGroup:
    def __init__(self):
        self.win = Tk()
        self.win.title("The Hive")
        self.win.geometry('{}x{}'.format(500, 400))
        self.canvas = Canvas(self.win, bg='#454b54')
        self.canvas.pack(expand=TRUE, fill=BOTH)
        self.frame = Frame(self.canvas, bg='#454b54', width=600, height=340)
        self.frame.pack(expand=TRUE)
        self.textBox = Text(self.frame, width=20, height=5)
        self.tree = Treeview(self.frame,
                             columns=1,
                             show="headings",
                             height="7")
        self.name = StringVar()

    def main(self):
        Label(self.frame,
              text="Group Name:",
              bg="#454b54",
              fg="#f7cc35",
              font="Arial 10 bold").grid(row=0, column=0)
        Entry(self.frame, width=20, textvariable=self.name).grid(row=1,
                                                                 column=0,
                                                                 pady=10)

        Label(self.frame,
              text="Description:",
              bg="#454b54",
              fg="#f7cc35",
              font="Arial 10 bold").grid(row=2, column=0)
        self.textBox.grid(row=3, column=0, pady=10)

        self.tree.grid(row=0, column=1, rowspan=5, padx=20)
        self.tree.heading(1, text="Select User")

        Button(self.frame,
               text="Send Invite",
               bg='#2C92D6',
               fg='#C5A32A',
               command=self.invite).grid(row=5, column=1, sticky=N)
        Button(self.frame,
               text="Create Group",
               bg='#2C92D6',
               fg='#C5A32A',
               command=self.create_group).grid(row=4, column=0)

        db.cursor.execute('SELECT username FROM users')
        users = db.cursor.fetchall()
        for row in users:
            self.tree.insert('', END, values=row)

        self.win.mainloop()

    def invite(self):
        try:
            for selected_item in self.tree.selection():
                inviter = db.getName()
                invited = self.tree.item(selected_item, 'values')

            db.cursor.execute("SELECT LAST_INSERT_ID()")
            groupID = db.cursor.fetchone()
            db.cursor.execute("INSERT INTO invitations VALUES(%s, %s, %s)",
                              (inviter, invited[0], groupID[0]))

            for selected_item in self.tree.selection():
                self.tree.delete(selected_item)
        except db.mysql.connector.errors.IntegrityError:
            messagebox.showwarning("Status", "Create Group First!")

    def create_group(self):
        description = self.textBox.get("1.0", "end-1c")
        initialPost = "Hello. Welcome to the group!"

        if self.name.get() == "" or description == "":
            messagebox.showwarning("Create Group Status",
                                   "All fields are required!")
        else:
            db.cursor.execute(
                "INSERT INTO projects(name, description, creator) VALUES(%s, %s, %s)",
                (self.name.get(), description, db.getName()))

            db.cursor.execute("SELECT id FROM projects WHERE name = '%s'" %
                              self.name.get())
            groupID = db.cursor.fetchone()[0]

            #Creator is auto in group
            db.cursor.execute("INSERT INTO group_membership VALUES (%s, %s)",
                              (db.getName(), groupID))
            #Insert intial post to db to display
            db.cursor.execute("INSERT into posts VALUES (%s, %s, %s, %s)",
                              (1, groupID, db.getName(), initialPost))
Exemple #36
0
class MainFrame(Frame):
    """ Główna ramka aplikacji
    """
    def __init__(self, ui: SharedrawUI):
        Frame.__init__(self, ui.root)
        self.parent = ui.root
        self.ui = ui

        self.parent.title(
            "Sharedraw [%s:%s, id: %s]" %
            (self.ui.peer_pool.ip, self.ui.peer_pool.port, own_id))
        self.drawer = Drawer(self.parent, WIDTH, HEIGHT, self.save)
        self.clients_table = Treeview(self.parent, columns=('R', 'G', 'from'))
        self.clients_table.heading('#0', text='Id')
        self.clients_table.heading('R', text='R')
        self.clients_table.heading('G', text='G')
        self.clients_table.heading('from', text='Otrzymano od:')
        self.clients_table.pack()
        self.token_owner_label = MutableLabel(self.parent,
                                              'Posiadacz tokena: %s',
                                              lambda s: s
                                              if s else 'Nikt', None)
        self.token_owner_label.pack()
        self.locked_label = MutableLabel(
            self.parent, 'Tablica %s', lambda b: 'zablokowana'
            if b else 'odblokowana', False)
        self.locked_label.pack()
        # Przycisk czyszczenia
        self.clean_btn = self._create_button(text="Czyść", func=self.clean)
        # Przycisk podłączenia
        self.connect_btn = self._create_button(text="Podłącz",
                                               func=self.connect)
        # Przycisk żądania przejęcia na własność
        self.req_btn = self._create_button(text="Chcę przejąć tablicę",
                                           func=self._make_request)
        # Rezygnacja z posiadania blokady
        self.resign_btn = self._create_button(text='Zrezygnuj z blokady',
                                              func=self._resign)

    def _create_button(self, text: str, func):
        """ Tworzy nowy przycisk w bieżącej ramce
        :param text: tekst przycisku
        :param func: funkcja wywoływana po naciśnięciu
        :return: przycisk
        """
        btn = Button(self.parent, text=text, command=func)
        btn.pack()
        return btn

    def save(self):
        """ Wysyła komunikat o zmianie obrazka do innych klientów
        :return:
        """
        if self.drawer.changed_pxs:
            msg = PaintMessage(self.drawer.changed_pxs, self.drawer.color)
            self.ui.peer_pool.send(msg)
            # Reset listy punktów
            self.drawer.changed_pxs = []

    def clean(self):
        """ Czyści obrazek oraz wysyła komunikat o wyczyszczeniu
        :return:
        """
        self.drawer.clean_img()
        msg = CleanMessage(own_id)
        self.ui.peer_pool.send(msg)

    def _make_request(self):
        """ Żąda przejęcia tablicy na własność
        :return:
        """
        clients_info = self.ui.om.claim_ownership()
        self.update_clients_info(clients_info)

    def _resign(self):
        clients_info = self.ui.om.resign()
        self.update_clients_info(clients_info)

    def connect(self):
        """ Uruchamia okno dialogowe do podłączenia się z innym klientem
        :return:
        """
        d = ConnectDialog(self.ui)
        self.parent.wait_window(d.top)

    def update_clients_info(self, clients: ClientsTable):
        # Aktualizacja listy klientów
        for ch in self.clients_table.get_children():
            self.clients_table.delete(ch)
        for client in clients.clients:
            self.clients_table.insert('',
                                      'end',
                                      text=client.id,
                                      values=(client.requested, client.granted,
                                              client.received_from_id))
        # Aktualizacja info o właścicielu tokena i blokadzie
        self.locked_label.update_text(clients.locked)
        self.token_owner_label.update_text(clients.token_owner)
        # Aktualizacja blokady
        has_token = clients.token_owner == own_id
        self.__set_lock_state(clients.locked, has_token)
        # Aktualizacja przycisków
        # jeśli zablokowaliśmy, to nie możemy tego zrobić drugi raz
        is_locker = (has_token and clients.locked)
        # tak samo jeśli już zażądaliśmy
        has_requested = clients.find_self().has_requested()
        self.__set_button_enabled(self.req_btn,
                                  not (is_locker or has_requested))
        # jeśli nie zablokowaliśmy, to nie możemy rezygnować
        self.__set_button_enabled(self.resign_btn, is_locker)
        # Możemy się podłączyć, tylko, jeśli nie jesteśmy do nikogo podłączeni
        self.__set_button_enabled(self.connect_btn, len(clients.clients) <= 1)
        # Przycisk czyść aktywny jeśli możemy rysować
        self.__set_button_enabled(self.clean_btn, has_token
                                  or not clients.locked)

    @staticmethod
    def __set_button_enabled(btn: Button, enabled: bool):
        btn.configure(state=(NORMAL if enabled else DISABLED))

    def __set_lock_state(self, locked: bool, has_token: bool):
        self.drawer.locked = locked and not has_token
        # Dodatkowo ustawiamy kolor tła, żeby było ładnie widać
        if locked:
            if has_token:
                color = '#66FF66'
            else:
                color = '#FF9999'
        else:
            color = '#FFFFFF'
        self.parent.configure(bg=color)
Exemple #37
0
class CleanDialog(Frame):
    def __init__(self, root, mr: MetaRecord):
        super().__init__(root, padding=10)
        self.pack(side=TOP, anchor=N, fill=BOTH, expand=True)
        self.metarecord = mr

        self.tree = Treeview(self, padding=5, selectmode="browse")
        self.tree.heading("#0", text="Files")
        self.tree.pack(fill=BOTH, expand=True)

        self.frm_btns = Frame(self, padding=5)
        self.frm_btns.pack(side=BOTTOM, anchor=S)

        self.btn_include = Button(self.frm_btns,
                                  text="Perform Clean",
                                  command=self._perform_clean)
        self.btn_include.pack(side=RIGHT, anchor=W)

        self.frm_status = StatusFrame(self)
        self.frm_status.pack(side=TOP, anchor=N, fill=X, expand=True)

        self.cleaner = Cleaner(mr)
        self._setup_tree()

    def _perform_clean(self):
        res = askyesno("Folder Manager - Clean",
                       f"Perform clean on {self.cleaner.file_count()} files?")
        if res:
            queue = self.cleaner.perform_clean()
            self.listen_for_result(queue)
        else:
            showinfo("Folder Manager - Clean", "Aborting cleanup")

    def listen_for_result(self,
                          data_queue: Queue,
                          on_complete: Optional[Callable] = None):
        try:
            while not data_queue.empty():
                res: AsyncUpdate = data_queue.get_nowait()
                if not res.is_minor():
                    self.frm_status.set_major(
                        f"[{res.get_completion()}%] {res.message}")
                    self.frm_status.set_progress(res.get_completion())
                else:
                    self.frm_status.set_minor(f"|> {res.message}")
        except Empty:
            pass
        finally:
            if self.cleaner.thread is not None and (
                    self.cleaner.thread.is_alive() or not data_queue.empty()):
                self.after(
                    100,
                    lambda: self.listen_for_result(data_queue, on_complete))
            elif on_complete is not None:
                on_complete()

    def _setup_tree(self):
        queue = self.cleaner.generate_diffs()

        def update_table():
            for r, files in self.cleaner.to_delete:
                parent = self.tree.insert("", END, text=r.name)
                for f in files:
                    self.tree.insert(parent, END, text=f)

        self.listen_for_result(queue, update_table)

    @staticmethod
    def create_dialog(mr: MetaRecord) -> Toplevel:
        window = Toplevel()
        CleanDialog(window, mr)
        window.title("MetaRecord Rebuilder")
        return window
class RefBook(Frame):

    ########
    # Opens database from provided arguments and creates and populates widgets.
    def __init__(self, master, *args, **kwargs):
        super().__init__(master)

        self._dbm = DatabaseManager(*args, **kwargs)
        self._openItems = {}
        self._openStores = {}
        self._openAttacks = {}
        self._openCreatures = {}
        self._openLocations = {}

        self._create_widgets()
        self._populate_items()
        self._populate_stores()
        self._populate_attacks()
        self._populate_creatures()
        self._populate_locations()

    ########
    # Initializes and places all GUI elements.
    def _create_widgets(self):
        self._nb = Notebook(self)

        # items
        self._itemTab = Frame(self._nb)
        self._itemTree = Treeview(self._itemTab,
                                  columns=["type", "value"],
                                  selectmode="browse",
                                  height=25)
        self._itemTree.heading("#0", text="Item", anchor=N + W)
        self._itemTree.column("#0", width=300, anchor=N + W, stretch=True)
        self._itemTree.heading("type", text="Type", anchor=N + W)
        self._itemTree.column("type", width=100, anchor=N + W)
        self._itemTree.heading("value", text="Value", anchor=N + W)
        self._itemTree.column("value", width=60, anchor=N + W)
        self._itemScroll = Scrollbar(self._itemTab,
                                     command=self._itemTree.yview)
        self._itemTree.config(yscrollcommand=self._itemScroll.set)

        self._itemTree.grid(row=0, column=0, sticky=N + W + S + E)
        self._itemScroll.grid(row=0, column=1, sticky=N + S)
        self._nb.add(self._itemTab, text="Items")

        # stores
        self._storeTab = Frame(self._nb)
        self._storeTree = Treeview(self._storeTab,
                                   columns=["location"],
                                   selectmode="browse",
                                   height=25)
        self._storeTree.heading("#0", text="Store", anchor=N + W)
        self._storeTree.column("#0", width=330, anchor=N + W, stretch=True)
        self._storeTree.heading("location", text="Location", anchor=N + W)
        self._storeTree.column("location", width=130, anchor=N + W)
        self._storeScroll = Scrollbar(self._storeTab,
                                      command=self._storeTree.yview)
        self._storeTree.config(yscrollcommand=self._storeScroll.set)

        self._storeTree.grid(row=0, column=0, sticky=N + W + S + E)
        self._storeScroll.grid(row=0, column=1, sticky=N + S)
        self._nb.add(self._storeTab, text="Stores")

        # attacks
        self._attackTab = Frame(self._nb)
        self._attackTree = Treeview(self._attackTab,
                                    columns=["id", "spell"],
                                    selectmode="browse",
                                    height=25)
        self._attackTree.heading("#0", text="Attacks", anchor=N + W)
        self._attackTree.column("#0", width=370, anchor=N + W, stretch=True)
        self._attackTree.heading("id", text="ID", anchor=N + W)
        self._attackTree.column("id", width=40, anchor=N + E)
        self._attackTree.heading("spell", text="Spell", anchor=N + W)
        self._attackTree.column("spell", width=50, anchor=CENTER)
        self._attackScroll = Scrollbar(self._attackTab,
                                       command=self._attackTree.yview)
        self._attackTree.config(yscrollcommand=self._attackScroll.set)

        self._attackTree.grid(row=0, column=0, sticky=N + W + S + E)
        self._attackScroll.grid(row=0, column=1, sticky=N + S)
        self._nb.add(self._attackTab, text="Attacks")

        # creatures
        self._creatureTab = Frame(self._nb)
        self._creatureTree = Treeview(self._creatureTab,
                                      columns=["hd"],
                                      selectmode="browse",
                                      height=25)
        self._creatureTree.heading("#0", text="Creatures", anchor=N + W)
        self._creatureTree.column("#0", width=420, anchor=N + W, stretch=True)
        self._creatureTree.heading("hd", text="HD", anchor=N + W)
        self._creatureTree.column("hd", width=40, anchor=N + E)
        self._creatureScroll = Scrollbar(self._creatureTab,
                                         command=self._creatureTree.yview)
        self._creatureTree.config(yscrollcommand=self._creatureScroll.set)

        self._creatureTree.grid(row=0, column=0, sticky=N + W + S + E)
        self._creatureScroll.grid(row=0, column=1, sticky=N + S)
        self._nb.add(self._creatureTab, text="Creatures")

        # locations
        self._locationTab = Frame(self._nb)
        self._locationTree = Treeview(self._locationTab,
                                      selectmode="browse",
                                      height=25)
        self._locationTree.heading("#0", text="Locations", anchor=N + W)
        self._locationTree.column("#0", width=460, anchor=N + W, stretch=True)
        self._locationScroll = Scrollbar(self._locationTab,
                                         command=self._locationTree.yview)
        self._locationTree.config(yscrollcommand=self._locationScroll.set)

        self._locationTree.grid(row=0, column=0, sticky=N + W + S + E)
        self._locationScroll.grid(row=0, column=1, sticky=N + S)
        self._nb.add(self._locationTab, text="Locations")

        self._nb.grid(row=0, column=0, sticky=N + W + S + E)

        # bindings
        self._itemTree.bind("<Double-Button-1>", self._item_on_double_click)
        self._storeTree.bind("<Double-Button-1>", self._store_on_double_click)
        self._attackTree.bind("<Double-Button-1>",
                              self._attack_on_double_click)
        self._creatureTree.bind("<Double-Button-1>",
                                self._creature_on_double_click)
        self._locationTree.bind("<Double-Button-1>",
                                self._location_on_double_click)

    ########
    # Populates item list.
    def _populate_items(self):
        self._itemList = self._dbm.get_item_list()

        allItems = self._itemTree.get_children()
        for item in allItems:
            self._itemTree.delete(item)
        self._itemImgs = []
        if self._dbm == None:
            return
        for entry in self._itemList:
            img = entry["img"]
            if img == None:
                img = BaseView.DEFAULT_IMG
            img = utility.get_img(img, maxSize=20)
            name = entry["name"]
            fields = [BaseView.TYPE_MAP[entry["type"]], entry["value"]]
            for i in range(len(fields)):
                if fields[i] == None:
                    fields[i] = BaseView.EMPTY_STR
            self._itemImgs.append(img)
            self._itemTree.insert("", END, image=img, text=name, values=fields)

    ########
    # Populates store list.
    def _populate_stores(self):
        self._storeList = self._dbm.get_store_list()

        allStores = self._storeTree.get_children()
        for store in allStores:
            self._storeTree.delete(store)
        self._storeImgs = []
        if self._dbm == None:
            return
        for entry in self._storeList:
            img = entry["img"]
            if img == None:
                img = BaseView.DEFAULT_IMG
            img = utility.get_img(img, maxSize=20)
            name = entry["name"]
            fields = [entry["location"]]
            for i in range(len(fields)):
                if fields[i] == None:
                    fields[i] = BaseView.EMPTY_STR
            self._storeImgs.append(img)
            self._storeTree.insert("",
                                   END,
                                   image=img,
                                   text=name,
                                   values=fields)

    ########
    # Populates attack list.
    def _populate_attacks(self):
        self._attackList = self._dbm.get_attack_list()

        allAttacks = self._attackTree.get_children()
        for attack in allAttacks:
            self._attackTree.delete(attack)
        self._attackImgs = []
        if self._dbm == None:
            return
        for entry in self._attackList:
            img = entry["img"]
            if img == None:
                img = BaseView.DEFAULT_IMG
            img = utility.get_img(img, maxSize=20)
            name = entry["name"]
            fields = [entry["id"], "✔" if entry["isSpell"] else ""]
            for i in range(len(fields)):
                if fields[i] == None:
                    fields[i] = BaseView.EMPTY_STR
            self._attackImgs.append(img)
            self._attackTree.insert("",
                                    END,
                                    image=img,
                                    text=name,
                                    values=fields)

    ########
    # Populates creature list.
    def _populate_creatures(self):
        self._creatureList = self._dbm.get_creature_list()

        allCreatures = self._creatureTree.get_children()
        for creature in allCreatures:
            self._creatureTree.delete(creature)
        self._creatureImgs = []
        if self._dbm == None:
            return
        for entry in self._creatureList:
            img = entry["img"]
            if img == None:
                img = BaseView.DEFAULT_IMG
            img = utility.get_img(img, maxSize=20)
            name = entry["name"]
            fields = [str(entry["hd"])]
            for i in range(len(fields)):
                if fields[i] == None:
                    fields[i] = BaseView.EMPTY_STR
            self._creatureImgs.append(img)
            self._creatureTree.insert("",
                                      END,
                                      image=img,
                                      text=name,
                                      values=fields)

    ########
    # Populates location list.
    def _populate_locations(self):
        self._locationList = self._dbm.get_location_list()

        allLocations = self._locationTree.get_children()
        for location in allLocations:
            self._locationTree.delete(location)
        self._locationImgs = []
        if self._dbm == None:
            return
        for entry in self._locationList:
            img = entry["img"]
            if img == None:
                img = BaseView.DEFAULT_IMG
            img = utility.get_img(img, maxSize=20)
            name = entry["name"]
            self._locationImgs.append(img)
            self._locationTree.insert("", END, image=img, text=name)

    ########
    # Callback for double clicking in item treeview.
    def _item_on_double_click(self, *args, **kwargs):
        if len(self._itemTree.selection()) == 0:
            return
        self.show_item(self._itemList[self._itemTree.index(
            self._itemTree.selection())]["name"])

    ########
    # Callback for double clicking in store treeview.
    def _store_on_double_click(self, *args, **kwargs):
        if len(self._storeTree.selection()) == 0:
            return
        curr = self._storeList[self._storeTree.index(
            self._storeTree.selection())]
        self.show_store(curr["name"], curr["location"])

    ########
    # Callback for double clicking in attack treeview.
    def _attack_on_double_click(self, *args, **kwargs):
        if len(self._attackTree.selection()) == 0:
            return
        self.show_attack(self._attackList[self._attackTree.index(
            self._attackTree.selection())]["id"])

    ########
    # Callback for double clicking in creature treeview.
    def _creature_on_double_click(self, *args, **kwargs):
        if len(self._creatureTree.selection()) == 0:
            return
        self.show_creature(self._creatureList[self._creatureTree.index(
            self._creatureTree.selection())]["name"])

    ########
    # Callback for double clicking in location treeview.
    def _location_on_double_click(self, *args, **kwargs):
        if len(self._locationTree.selection()) == 0:
            return
        self.show_location(self._locationList[self._locationTree.index(
            self._locationTree.selection())]["name"])

    ########
    # Shows a full item in a new window.
    def show_item(self, name):
        if name in self._openItems.keys():
            # TODO: make this cleaner
            try:
                self._openItems[name].lift()
                self._openItems[name].focus_set()
                return
            except TclError:
                pass  # fallthrough to make new window
        newWindow = Toplevel(self)
        itemView = ItemView(newWindow, self._dbm.get_item(name), refBook=self)
        itemView.grid(row=0, column=0, sticky=N + W + E + S)
        newWindow.title(name)
        newWindow.lift()
        newWindow.focus_set()
        self._openItems[name] = newWindow

    ########
    # Shows a full store in a new window.
    def show_store(self, name, location):
        key = (name, location)
        if key in self._openStores.keys():
            # TODO: make this cleaner
            try:
                self._openStores[key].lift()
                self._openStores[key].focus_set()
                return
            except TclError:
                pass  # fallthrough to make new window
        newWindow = Toplevel(self)
        storeView = StoreView(newWindow,
                              self._dbm.get_store(name, location),
                              refBook=self)
        storeView.grid(row=0, column=0, sticky=N + W + E + S)
        newWindow.title(name)
        newWindow.lift()
        newWindow.focus_set()
        self._openStores[key] = newWindow

    ########
    # Shows a full attack in a new window.
    def show_attack(self, attackId):
        if attackId in self._openAttacks.keys():
            # TODO: make this cleaner
            try:
                self._openAttacks[attackId].lift()
                self._openAttacks[attackId].focus_set()
                return
            except TclError:
                pass  # fallthrough to make new window
        attack = self._dbm.get_attack(attackId)
        newWindow = Toplevel(self)
        attackView = AttackView(newWindow,
                                self._dbm.get_attack(attackId),
                                refBook=self)
        attackView.grid(row=0, column=0, sticky=N + W + E + S)
        newWindow.title("{} ({})".format(attack["name"], attack["id"]))
        newWindow.lift()
        newWindow.focus_set()
        self._openAttacks[attackId] = newWindow

    ########
    # Shows a full creature in a new window.
    def show_creature(self, name):
        if name in self._openCreatures.keys():
            # TODO: make this cleaner
            try:
                self._openCreatures[name].lift()
                self._openCreatures[name].focus_set()
                return
            except TclError:
                pass  # fallthrough to make new window
        newWindow = Toplevel(self)
        creatureView = CreatureView(newWindow,
                                    self._dbm.get_creature(name),
                                    refBook=self)
        creatureView.grid(row=0, column=0, sticky=N + W + E + S)
        newWindow.title(name)
        newWindow.lift()
        newWindow.focus_set()
        self._openCreatures[name] = newWindow

    ########
    # Shows a full location in a new window.
    def show_location(self, name):
        if name in self._openLocations.keys():
            # TODO: make this cleaner
            try:
                self._openLocations[name].lift()
                self._openLocations[name].focus_set()
                return
            except TclError:
                pass  # fallthrough to make new window
        newWindow = Toplevel(self)
        locationView = LocationView(newWindow,
                                    self._dbm.get_location(name),
                                    refBook=self)
        locationView.grid(row=0, column=0, sticky=N + W + E + S)
        newWindow.title(name)
        newWindow.lift()
        newWindow.focus_set()
        self._openLocations[name] = newWindow
Exemple #39
0
    def add_info(self, structure, frame, variantID, price):
        """ Add info of the plotted structure

        Parameters
        ----------
        structure : str
            name of the structure to design
        frame : tk.Frame
            frame to add the info to
        variantID : str
            identifier of the variant of which the info must be displayed
        price : float
            price of the specified variant
        """
        # get the dimensions of the frame
        param_width = 150
        value_width = settings('interactive')['info_width'] - param_width - 10

        # get the font
        font = settings('font')['info']

        # get the concept breakwater and variant
        concept = getattr(self, f'{structure}_new')
        variant = concept.get_variant(variantID)

        # create the treeview
        tree = Treeview(frame)

        # add columns
        tree['columns'] = ('#1')
        tree.column('#0', width=param_width, stretch=tk.NO)
        tree.heading('#0', text='Parameter', anchor=tk.W)
        tree.column('#1', width=value_width, stretch=tk.NO)
        tree.heading('#1', text='Value', anchor=tk.W)

        # check if a price has been specified
        if price is not None:
            # add cost
            tree.insert('', 1, iid=1, text='Cost', values=(np.round(price, 2)))

            # set row
            row = 2

        else:
            # no cost, set row to first one
            row = 1

        # check if RubbleMound structure
        if structure == 'RRM' or structure == 'CRM':
            # parameters to show
            includes = ['computed Dn50', 'class']

            # add Rc
            tree.insert('',
                        row,
                        iid=row,
                        text='Rc',
                        values=(f'{np.round(concept.Rc, 3)}m'))

            # increment row
            row += 1

            # add the info
            for layer, dimensions in variant.items():
                # add to first column
                header = tree.insert('',
                                     row,
                                     iid=row,
                                     text=layer.capitalize(),
                                     values=(''))

                # increment row
                row += 1

                # iterate over the dimensions of the layer
                for parameter, value in dimensions.items():
                    # check if value is an int or float
                    if isinstance(value, int) or isinstance(value, float):
                        if layer == 'armour' and parameter == 'class':
                            if structure == 'CRM':
                                SUB = str.maketrans('3', '³')
                                unit = 'm3'.translate(SUB)
                            else:
                                unit = 'm'
                        else:
                            unit = 'm'
                        # round the dimension to 3 decimals
                        value = f'{np.round(value, 3)}{unit}'

                    if parameter in includes:
                        # parameter and value
                        tree.insert(header,
                                    'end',
                                    iid=row,
                                    text=parameter.capitalize(),
                                    values=(value))

                        # increment the row
                        row += 1

            # pack the tree to the frame
            tree.pack(side=tk.TOP, fill=tk.Y)

        # check if Caisson breakwater
        elif structure == 'RC' or structure == 'CC':
            # parameters to show
            includes = ['computed Dn50', 'class', 'd', 'B', 'h_acc']
            no_capital = ['h_acc', 'd']

            # add Rc
            Rc = variant['caisson']['Rc']
            tree.insert('',
                        row,
                        iid=row,
                        text='Rc',
                        values=(f'{np.round(Rc, 3)}m'))

            # increment row
            row += 1

            # add the info
            for layer, dimensions in variant.items():
                # add to first column
                header = tree.insert('',
                                     row,
                                     iid=row,
                                     text=layer.capitalize(),
                                     values=(''))

                # increment row
                row += 1

                # iterate over the dimensions of the layer
                for parameter, value in dimensions.items():
                    # check if value is an int or float
                    if isinstance(value, int) or isinstance(value, float):
                        if layer == 'armour' and parameter == 'class':
                            if structure == 'CC':
                                SUB = str.maketrans('3', '³')
                                unit = 'm3'.translate(SUB)
                            else:
                                unit = 'm'
                        else:
                            unit = 'm'

                        # round the dimension to 3 decimals
                        value = f'{np.round(value, 3)}{unit}'

                    if parameter in includes:
                        if parameter not in no_capital:
                            parameter = parameter.capitalize()
                        # parameter and value
                        tree.insert(header,
                                    'end',
                                    iid=row,
                                    text=parameter,
                                    values=(value))

                        # increment the row
                        row += 1

            # add geotechnical parameters if computed
            if self.controller.parameters['Soil'] is not None:
                # define the stresses
                stresses = ['p', 'p_cap']

                # add header of the geotechnical parameters
                geo = tree.insert('',
                                  row,
                                  iid=row,
                                  text='Geotechnical',
                                  values=(''))

                # increment row
                row += 1

                # add values
                for parameter, value in concept.geotechnical.items():
                    # check if parameter is a stess
                    if parameter in stresses:
                        # stress, round value and add unit
                        value = f'{np.round(value, 2)}kPa'
                    else:
                        # only round value
                        value = f'{np.round(value, 2)}'

                    # add to the tree and increment row
                    tree.insert(geo,
                                'end',
                                iid=row,
                                text=parameter,
                                values=(value))
                    row += 1

            # pack the tree to the frame
            tree.pack(side=tk.TOP, fill=tk.Y)

        else:
            # other type
            raise NotImplementedError(f'{structure} has not been implemented')
Exemple #40
0
vsb.grid(row=2, column=3)
tree.configure(yscrollcommand=vsb.set)
tree["columns"] = ("one", "two", "three")
tree.column("#0", width=30)
tree.column("one", width=80)
tree.column("two", width=100)
tree.column("three", width=90)
#############################################  update treeview --- serach select baham --- editable treeview
tree.heading("#0", text="ID", anchor=W)
tree.heading("one", text="Name")
tree.heading("two", text="Family")
tree.heading("three", text="Code", anchor=W)
persons = StudentSelect().get()
for person in persons:
    tree.insert("",
                person[0],
                text=person[0],
                values=(person[1], person[2], person[4]))
tree.grid(row=2, column=0, columnspan=3)
tree.bind("<Double-Button-1>", on_double_click)
# #################################################################### #
Label(g_insert, text='Math').grid(row=0, column=0)
math = StringVar()
Entry(g_insert, textvariable=math).grid(row=0, column=1)

Label(g_insert, text='Chemistry').grid(row=1, column=0)
chemistry = StringVar()
Entry(g_insert, textvariable=chemistry).grid(row=1, column=1)

Label(g_insert, text='Physics').grid(row=2, column=0)
physics = StringVar()
Entry(g_insert, textvariable=physics).grid(row=2, column=1)
Exemple #41
0
class NodeTree:
    def __init__(self):
        self._client = KazooClient(hosts='localhost:2181')
        # self._client = KazooClient(hosts='10.128.62.34:2181,10.128.62.34:2182,10.128.62.34:2183')
        self._client.start()
        self._selected_node = None
        self._win = None
        self._root = None
        self._tree_canvas = None
        self._tree_frame_id = None
        self.init_ui()
        self.init_tree()
        self._count = 0
        # self.treeify()

        print(self._count)
        self._win.mainloop()

    def init_ui(self):
        self._win = tk.Tk()
        self._win.title("zk-client")
        self._win.geometry('900x700+500+300')
        self._win.resizable(height=False, width=False)
        tree_wrapper = tk.Frame(self._win, bg='red', width=300)
        tree_wrapper.pack(side=tk.LEFT, fill=tk.Y)

        canvas = self._tree_canvas = tk.Canvas(tree_wrapper,
                                               width=300,
                                               height=700,
                                               scrollregion=(0, 0, 300, 700),
                                               bg='gray')  # 创建canvas
        canvas.place(x=0, y=0)  # 放置canvas的位置

        frame = tk.Frame(canvas)  # 把frame放在canvas里
        # frame.place(width=180, height=600)  # frame的长宽,和canvas差不多的
        vbar = Scrollbar(canvas, orient=tk.VERTICAL)  # 竖直滚动条
        vbar.place(x=281, width=20, height=700)
        vbar.configure(command=canvas.yview)
        hbar = Scrollbar(canvas, orient=tk.HORIZONTAL)  # 水平滚动条
        hbar.place(x=0, y=680, width=280, height=20)
        hbar.configure(command=canvas.xview)
        canvas.config(xscrollcommand=hbar.set, yscrollcommand=vbar.set)  # 设置
        canvas.bind_all(
            "<MouseWheel>", lambda event: canvas.yview_scroll(
                int(-1 * (event.delta / 120)), "units"))

        self._tree_frame_id = canvas.create_window(
            0, 0, window=frame, anchor='nw')  # create_window)

        self._root = Treeview(frame)
        #
        self._root.pack(expand=True, fill=tk.BOTH)
        # self._root.bind("<Button-1>", self.clear_pre_selected)
        # self._root.bind("<< TreeviewClose>>", self.clear_pre_selected)
        self._root.bind("<<TreeviewOpen>>", self.open_node)

    def adjust_size(self):
        self._root.update()
        width = self._root.winfo_width()
        height = self._root.winfo_height()
        print(width, height)
        self._tree_canvas.itemconfigure(self._tree_frame_id,
                                        height=height)  # 设定窗口tv_frame的高度
        self._tree_canvas.config(scrollregion=(0, 0, width, height))
        self._tree_canvas.config(
            scrollregion=self._tree_canvas.bbox("all"))  # 滚动指定的范围
        self._tree_canvas.config(height=height)
        pass

    def init_tree(self):
        tops = self._client.get_children("/")
        for index, top in enumerate(tops):
            self._root.insert('', index, text=top)
            children = self._client.get_children("/" + top + "/")
            if children is not None and len(children) > 0:
                pass

    def clear_pre_selected(self, event):
        focus = self._root.focus()
        if focus == '':
            return
        children = self._root.get_children(focus)
        for child in children:
            self._root.delete(child)

    def open_node(self, event):
        iid = self._root.focus()
        path = self.get_current_path(iid)
        children = self._client.get_children(path)
        for index, p in enumerate(children):
            self._root.insert(iid, index, text=p)
        self.adjust_size()

    def get_current_path(self, item):
        curr_item = self._root.item(item)
        pid = self._root.parent(item)
        if pid == '':
            return '/' + curr_item['text'] + "/"
        else:
            return self.get_current_path(pid) + curr_item['text'] + "/"

    def treeify(self):
        self._client.start()
        self.treeify_recursive("/", parent='', index=0)

    def treeify_recursive(self, path, parent, index):
        self._count += 1
        cd = self._client.get_children(path=path)
        if cd and len(cd) > 0:
            for i, c in enumerate(cd):
                tmp_path = path + c + '/'
                tc = self._client.get_children(tmp_path)
                if tc and len(tc) > 0:
                    insert = self._root.insert(parent, i, text=c)
                    self.treeify_recursive(path=tmp_path,
                                           parent=insert,
                                           index=i)
                else:
                    self._root.insert(parent, i, text=c)
Exemple #42
0
class PopulationGenerator:
    '''
    构造函数
    进行一些初始化
    '''
    def __init__(self):
        self.url = 'https://en.wikipedia.org/wiki/United_States_Census'
        self.stateUrl = 'https://en.wikipedia.org/wiki/%s_United_States_census'
        self.header = {
            'User-Agent':
            'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:85.0) Gecko/20100101 Firefox/85.0'
        }

        self.years = self.getYears()
        self.stateTotalMap = dict()
        self.resultData = None
        self.yearsMapIndex = {'1870': 2}
        self.outfile = open('output.csv', 'w', newline='')
        self.outDate = csv.writer(self.outfile)
        self.outDate.writerow(
            ['input_year', 'input_state', 'output_population_size'])

    '''
    界面编写
    '''

    def ui(self):
        root = Tk()
        # 窗口的标题
        root.title('PopulationGenerator')

        # 创建大小和位置
        width = root.winfo_screenwidth()
        height = root.winfo_screenheight()
        root_height = 400
        root_wight = 1000
        x_width = (width - root_wight) / 2
        x_height = (height - root_height) / 2
        root.geometry('%dx%d+%d+%d' %
                      (root_wight, root_height, x_width, x_height))
        self.host = StringVar()
        self.port = StringVar()

        tab_main = Notebook(root)
        tab_main.place(relx=0.02, rely=0.02, relwidth=0.887, relheight=0.876)
        tab1 = Frame(tab_main)
        tab1.place(x=0, y=30)
        tab_main.add(tab1, text='wiki')  # 将第一页插入分页栏中

        frameTop = Frame(tab1, pady=10)
        frameTop.pack()
        frameCenter = Frame(tab1, pady=10)
        frameCenter.pack()
        frameBottom = Frame(tab1, pady=10)
        frameBottom.pack()

        # 选择年份的
        yearLabel = Label(frameTop, text='year:', font=12, pady=3, padx=5)

        yearLabel.grid(row=0, column=0)

        self.yearBox = Combobox(frameTop)

        self.yearBox['values'] = self.years
        self.yearBox.bind('<<ComboboxSelected>>', self.getState)

        self.yearBox.grid(row=0, column=1)

        # 选择州
        stateLabel = Label(frameTop, text='state:', font=12, pady=3, padx=5)
        stateLabel.grid(row=0, column=2)
        self.stateBox = Combobox(frameTop)
        self.stateBox.grid(row=0, column=3)

        hostLabel = Label(frameTop, text='host:', font=12, pady=3, padx=5)
        hostLabel.grid(row=1, column=0)
        self.hostText = Entry(frameTop, textvariable=self.host)
        self.hostText.grid(row=1, column=1)
        portLabel = Label(frameTop, text='port:', font=12, pady=3, padx=5)
        portLabel.grid(row=1, column=2)
        self.portText = Entry(frameTop, textvariable=self.port)
        self.portText.grid(row=1, column=3)

        # 请求按钮
        button = Button(frameBottom,
                        text='generate',
                        padx=30,
                        pady=10,
                        command=self.get_result)

        button.pack()

        # 显示数据结果
        # self.text = Text(frameBottom, height=4)
        self.resultData = StringVar()
        self.text = Label(frameBottom,
                          textvariable=self.resultData,
                          height=4,
                          bg='green',
                          fg='white',
                          width=50,
                          font=15)
        self.text.pack()

        tab2 = Frame(tab_main)
        tab2.place(x=100, y=30)
        tab_main.add(tab2, text='life_server')
        frameTop2 = Frame(tab2, pady=10)
        frameTop2.pack()
        typeLabel = Label(frameTop2, text='type:', font=12, pady=3, padx=5)
        typeLabel.grid(row=0, column=0)
        self.typeValue = StringVar()
        typeEntry = Entry(frameTop2, textvariable=self.typeValue)
        typeEntry.grid(row=0, column=1)
        categoryLabel = Label(frameTop2,
                              text='category:',
                              font=12,
                              pady=3,
                              padx=5)
        categoryLabel.grid(row=1, column=0)
        self.categoryValue = StringVar()
        categoryEntry = Entry(frameTop2, textvariable=self.categoryValue)
        categoryEntry.grid(row=1, column=1)

        number_to_generateLabel = Label(frameTop2,
                                        text='number_to_generate:',
                                        font=12,
                                        pady=3,
                                        padx=5)
        number_to_generateLabel.grid(row=2, column=0)
        self.number_to_generateValue = StringVar()
        number_to_generateEntry = Entry(
            frameTop2, textvariable=self.number_to_generateValue)
        number_to_generateEntry.grid(row=2, column=1)

        frameBottom2 = Frame(tab2, pady=10)
        frameBottom2.pack()
        # 发送按钮
        button2 = Button(frameBottom2,
                         text='send',
                         padx=30,
                         pady=10,
                         command=self.sendToLifeServer)
        button2.pack()

        self.tableData = Treeview(tab2)
        self.tableData['columns'] = [str(i + 1) for i in range(20)]
        for item in self.tableData['columns']:
            self.tableData.column(item, width=40)
            self.tableData.heading(item, text=item)
        self.tableData.pack()
        scrollbar = Scrollbar(tab2,
                              orient='horizontal',
                              command=self.tableData.xview)
        scrollbar.pack()
        self.tableData.configure(yscrollcommand=scrollbar.set)

        root.mainloop()

    def sendToLifeServer(self):
        # print('sendToLifeServer')

        PORT = 5000
        HOST = 'localhost'

        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            s.connect((HOST, PORT))
            data = [
                self.typeValue.get(),
                self.categoryValue.get(),
                self.number_to_generateValue.get()
            ]
            data = [i for i in data if i != '']
            print(data)
            if len(data) >= 3:
                s.sendall(bytes(','.join(data), encoding="utf8"))
                server_msg = s.recv(4096).decode('utf-8')
                server_msg = eval(server_msg)
                for index, item in enumerate(server_msg):
                    print(item)
                    self.tableData.insert('',
                                          index,
                                          text=str(index),
                                          values=item)
                self.tableData.pack()

            else:
                print('输入信息不完整')

    '''
    '''

    def get_result(self):
        # # print('hello world')
        year = self.yearBox.get()
        state = self.stateBox.get()
        if self.stateTotalMap.__contains__(state):
            # print(year + ':' + state + ':' + self.stateTotalMap[state])
            self.resultData.set(self.stateTotalMap[state])
            self.outDate.writerow([year, state, self.stateTotalMap[state]])

    '''获取年份函数'''

    def getYears(self):
        return self.wikiYears()
        # return [1900, 1910, 1920]

    '''
    根据年份获取州的信息
    '''

    def getState(self, *args):
        self.stateTotalMap = self.wikiState(self.yearBox.get())
        # print(len(self.stateTotalMap), self.stateTotalMap)
        self.stateBox['values'] = [k for k in self.stateTotalMap]

    '''
    获取网页上的年份  > tbody > tr:nth-child(1) > td:nth-child(1) > a
    '''

    def wikiYears(self):
        r = requests.get(self.url, params={}).text
        soup = BeautifulSoup(r, 'html.parser')
        years = soup.select(
            '#mw-content-text > div.mw-parser-output > table.sortable.wikitable >tbody > tr >td:nth-child(1)>a'
        )
        return [item.text for item in years]

    '''
    获取键值对 
        州:人数
    '''

    def wikiState(self, year):
        if year == '1790':
            return self.year1790(year)
        elif year == '1800':
            return self.year1800(year)
        elif year == '1870':
            return self.year1870(year)
        else:
            return self.yearOthers(year)
        return {'a': 333, 'b': 444, 'c': 555}

    def year1790(self, year):
        r = requests.get(self.stateUrl % year).text
        soup = BeautifulSoup(r, 'html.parser')
        stateNamesTemp = soup.select(
            '#mw-content-text > div.mw-parser-output>table.wikitable.sortable>tbody> tr>td:nth-child(1)>a'
        )
        stateNames = [item.text for item in stateNamesTemp]
        stateTotalTemp = soup.select(
            '#mw-content-text > div.mw-parser-output >table.wikitable.sortable>tbody > tr > td:nth-child(8)'
        )
        stateTotal = [getDigital(item.text) for item in stateTotalTemp]
        # print(len(stateNames), stateNames)
        # print(len(stateTotal), stateTotal)
        return {k.strip(): v for k, v in zip(stateNames, stateTotal)}

    '''

    '''

    def year1800(self, year):
        r = requests.get(self.stateUrl % year).text
        soup = BeautifulSoup(r, 'html.parser')
        stateNamesTemp = soup.select(
            '#mw-content-text > div.mw-parser-output>table.wikitable.sortable>tbody> tr>td:nth-child(1)'
        )
        stateNames = [item.text.strip() for item in stateNamesTemp]
        stateTotalTemp = soup.select(
            '#mw-content-text > div.mw-parser-output >table.wikitable.sortable>tbody > tr > td:nth-child(14)'
        )
        stateTotal = [getDigital(item.text) for item in stateTotalTemp]
        # print(len(stateNames), stateNames)
        # print(len(stateTotal), stateTotal)
        return {k.strip(): v for k, v in zip(stateNames, stateTotal)}

    '''
    #mw-content-text > div.mw-parser-output > table:nth-child(15) > tbody > tr:nth-child(1) > td:nth-child(2)
    '''

    def yearOthers(self, year):
        # print(year)
        r = requests.get(self.stateUrl % year).text
        soup = BeautifulSoup(r, 'html.parser')
        soupTemp = soup.select(
            '#mw-content-text > div.mw-parser-output > table.wikitable.sortable'
        )[0]
        stateNamesTemp = soupTemp.select("tbody>tr>td:nth-child(2)")
        stateNames = [item.text for item in stateNamesTemp]
        stateTotalTemp = soupTemp.select('tbody>tr>td:nth-child(3)')
        stateTotal = [getDigital(item.text) for item in stateTotalTemp]
        # print(len(stateNames), stateNames)
        # print(len(stateTotal), stateTotal)
        return {k.strip(): v for k, v in zip(stateNames, stateTotal)}

    '''
   #mw-content-text > div.mw-parser-output > table:nth-child(20) > tbody > tr:nth-child(1) > td:nth-child(2) 
    '''

    def year1870(self, year):
        # print(year)
        r = requests.get(self.stateUrl % year).text
        soup = BeautifulSoup(r, 'html.parser')
        soupTemp = soup.select(
            '#mw-content-text > div.mw-parser-output > table.wikitable.sortable.mw-collapsible'
        )[1]

        stateNamesTemp = soupTemp.select("tbody>tr>td:nth-child(2)")
        stateNames = [item.text for item in stateNamesTemp]
        stateTotalTemp = soupTemp.select('tbody>tr>td:nth-child(3)')
        stateTotal = [getDigital(item.text) for item in stateTotalTemp]
        # print(len(stateNames), stateNames)
        # print(len(stateTotal), stateTotal)
        return {k.strip(): v for k, v in zip(stateNames, stateTotal)}

    '''
    直接处理文件
    '''

    def dealCSV(self, name):
        inDate = csv.reader(open(name, 'r'))

        for row in inDate:
            # print(row)
            if row[0] != 'input_year':
                self.stateTotalMap = self.wikiState(row[0])
                row.append(self.stateTotalMap[row[1]] if self.stateTotalMap.
                           __contains__(row[1]) else '')
                self.outDate.writerow(row)

    def getValue(self, year, state):
        state_to_pop = self.wikiState(year)
        return state_to_pop[state]
        # a_dict = {'Pennsylvania': '1,348,233', 'Virginia': '1,044,054'}
        # return a_dict[state]

    def sender(self, filename, host=None, port=None):
        '''
        发送文件给服务器
        :param filename:
        :param host:
        :param port:
        :return:
        '''
        if host is None:
            host = self.host.get()
        if port is None:
            port = self.port.get()
        if host != '' and port != '' and port.isdigit():
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

            # 连接服务,指定主机和端口
            s.connect((host, int(port)))

            fileLen = os.stat(filename).st_size

            a, b = fileStruck(filename, fileLen)

            s.send(a.to_bytes(4, byteorder='big', signed=False))

            s.send(b)

            has_sent = 0
            # print('发送文件', has_sent, fileLen)
            with open(filename, 'rb') as fb:
                while has_sent != fileLen:
                    data = fb.read(1024)
                    s.sendall(data)
                    has_sent += len(data)
                    # print(has_sent)
            s.close()

    def save(self):
        self.outfile.close()
Exemple #43
0
class DialogPluginManager(Toplevel):
    def __init__(self, mainWin, modulesWithNewerFileDates):
        super(DialogPluginManager, self).__init__(mainWin.parent)
        
        self.ENABLE = _("Enable")
        self.DISABLE = _("Disable")
        self.parent = mainWin.parent
        self.cntlr = mainWin
        
        # copy plugins for temporary display
        self.pluginConfig = PluginManager.pluginConfig
        self.pluginConfigChanged = False
        self.uiClassMethodsChanged = False
        self.modulesWithNewerFileDates = modulesWithNewerFileDates
        
        parentGeometry = re.match("(\d+)x(\d+)[+]?([-]?\d+)[+]?([-]?\d+)", self.parent.geometry())
        dialogX = int(parentGeometry.group(3))
        dialogY = int(parentGeometry.group(4))

        self.title(_("Plug-in Manager"))
        frame = Frame(self)
        
        # left button frame
        buttonFrame = Frame(frame, width=40)
        buttonFrame.columnconfigure(0, weight=1)
        addLabel = Label(buttonFrame, text=_("Find plug-in modules:"), wraplength=60, justify="center")
        addLocalButton = Button(buttonFrame, text=_("Locally"), command=self.findLocally)
        ToolTip(addLocalButton, text=_("File chooser allows selecting python module files to add (or reload) plug-ins, from the local file system."), wraplength=240)
        addWebButton = Button(buttonFrame, text=_("On Web"), command=self.findOnWeb)
        ToolTip(addWebButton, text=_("Dialog to enter URL full path to load (or reload) plug-ins, from the web or local file system."), wraplength=240)
        addLabel.grid(row=0, column=0, pady=4)
        addLocalButton.grid(row=1, column=0, pady=4)
        addWebButton.grid(row=2, column=0, pady=4)
        buttonFrame.grid(row=0, column=0, rowspan=2, sticky=(N, S, W), padx=3, pady=3)
        
        # right tree frame (plugins already known to arelle)
        modulesFrame = Frame(frame, width=700)
        vScrollbar = Scrollbar(modulesFrame, orient=VERTICAL)
        hScrollbar = Scrollbar(modulesFrame, orient=HORIZONTAL)
        self.modulesView = Treeview(modulesFrame, xscrollcommand=hScrollbar.set, yscrollcommand=vScrollbar.set, height=7)
        self.modulesView.grid(row=0, column=0, sticky=(N, S, E, W))
        self.modulesView.bind('<<TreeviewSelect>>', self.moduleSelect)
        hScrollbar["command"] = self.modulesView.xview
        hScrollbar.grid(row=1, column=0, sticky=(E,W))
        vScrollbar["command"] = self.modulesView.yview
        vScrollbar.grid(row=0, column=1, sticky=(N,S))
        modulesFrame.columnconfigure(0, weight=1)
        modulesFrame.rowconfigure(0, weight=1)
        modulesFrame.grid(row=0, column=1, columnspan=4, sticky=(N, S, E, W), padx=3, pady=3)
        self.modulesView.focus_set()

        self.modulesView.column("#0", width=120, anchor="w")
        self.modulesView.heading("#0", text=_("Name"))
        self.modulesView["columns"] = ("author", "ver", "status", "date", "update", "descr", "license")
        self.modulesView.column("author", width=100, anchor="w", stretch=False)
        self.modulesView.heading("author", text=_("Author"))
        self.modulesView.column("ver", width=50, anchor="w", stretch=False)
        self.modulesView.heading("ver", text=_("Version"))
        self.modulesView.column("status", width=50, anchor="w", stretch=False)
        self.modulesView.heading("status", text=_("Status"))
        self.modulesView.column("date", width=70, anchor="w", stretch=False)
        self.modulesView.heading("date", text=_("File Date"))
        self.modulesView.column("update", width=50, anchor="w", stretch=False)
        self.modulesView.heading("update", text=_("Update"))
        self.modulesView.column("descr", width=200, anchor="w", stretch=False)
        self.modulesView.heading("descr", text=_("Description"))
        self.modulesView.column("license", width=70, anchor="w", stretch=False)
        self.modulesView.heading("license", text=_("License"))

        classesFrame = Frame(frame)
        vScrollbar = Scrollbar(classesFrame, orient=VERTICAL)
        hScrollbar = Scrollbar(classesFrame, orient=HORIZONTAL)
        self.classesView = Treeview(classesFrame, xscrollcommand=hScrollbar.set, yscrollcommand=vScrollbar.set, height=5)
        self.classesView.grid(row=0, column=0, sticky=(N, S, E, W))
        hScrollbar["command"] = self.classesView.xview
        hScrollbar.grid(row=1, column=0, sticky=(E,W))
        vScrollbar["command"] = self.classesView.yview
        vScrollbar.grid(row=0, column=1, sticky=(N,S))
        classesFrame.columnconfigure(0, weight=1)
        classesFrame.rowconfigure(0, weight=1)
        classesFrame.grid(row=1, column=1, columnspan=4, sticky=(N, S, E, W), padx=3, pady=3)
        self.classesView.focus_set()
        
        self.classesView.column("#0", width=200, anchor="w")
        self.classesView.heading("#0", text=_("Class"))
        self.classesView["columns"] = ("modules")
        self.classesView.column("modules", width=500, anchor="w", stretch=False)
        self.classesView.heading("modules", text=_("Modules"))
        
        # bottom frame module info details
        moduleInfoFrame = Frame(frame, width=700)
        moduleInfoFrame.columnconfigure(1, weight=1)
        
        self.moduleNameLabel = Label(moduleInfoFrame, wraplength=600, justify="left", 
                                     font=font.Font(family='Helvetica', size=12, weight='bold'))
        self.moduleNameLabel.grid(row=0, column=0, columnspan=4, sticky=W)
        self.moduleAuthorHdr = Label(moduleInfoFrame, text=_("author:"), state=DISABLED)
        self.moduleAuthorHdr.grid(row=1, column=0, sticky=W)
        self.moduleAuthorLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleAuthorLabel.grid(row=1, column=1, columnspan=3, sticky=W)
        self.moduleDescrHdr = Label(moduleInfoFrame, text=_("description:"), state=DISABLED)
        self.moduleDescrHdr.grid(row=2, column=0, sticky=W)
        self.moduleDescrLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleDescrLabel.grid(row=2, column=1, columnspan=3, sticky=W)
        self.moduleClassesHdr = Label(moduleInfoFrame, text=_("classes:"), state=DISABLED)
        self.moduleClassesHdr.grid(row=3, column=0, sticky=W)
        self.moduleClassesLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleClassesLabel.grid(row=3, column=1, columnspan=3, sticky=W)
        ToolTip(self.moduleClassesLabel, text=_("List of classes that this plug-in handles."), wraplength=240)
        self.moduleUrlHdr = Label(moduleInfoFrame, text=_("URL:"), state=DISABLED)
        self.moduleUrlHdr.grid(row=4, column=0, sticky=W)
        self.moduleUrlLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleUrlLabel.grid(row=4, column=1, columnspan=3, sticky=W)
        ToolTip(self.moduleUrlLabel, text=_("URL of plug-in module (local file path or web loaded file)."), wraplength=240)
        self.moduleDateHdr = Label(moduleInfoFrame, text=_("date:"), state=DISABLED)
        self.moduleDateHdr.grid(row=5, column=0, sticky=W)
        self.moduleDateLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleDateLabel.grid(row=5, column=1, columnspan=3, sticky=W)
        ToolTip(self.moduleDateLabel, text=_("Date of currently loaded module file (with parenthetical node when an update is available)."), wraplength=240)
        self.moduleLicenseHdr = Label(moduleInfoFrame, text=_("license:"), state=DISABLED)
        self.moduleLicenseHdr.grid(row=6, column=0, sticky=W)
        self.moduleLicenseLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleLicenseLabel.grid(row=6, column=1, columnspan=3, sticky=W)
        self.moduleEnableButton = Button(moduleInfoFrame, text=self.ENABLE, state=DISABLED, command=self.moduleEnable)
        ToolTip(self.moduleEnableButton, text=_("Enable/disable plug in."), wraplength=240)
        self.moduleEnableButton.grid(row=7, column=1, sticky=E)
        self.moduleReloadButton = Button(moduleInfoFrame, text=_("Reload"), state=DISABLED, command=self.moduleReload)
        ToolTip(self.moduleReloadButton, text=_("Reload/update plug in."), wraplength=240)
        self.moduleReloadButton.grid(row=7, column=2, sticky=E)
        self.moduleRemoveButton = Button(moduleInfoFrame, text=_("Remove"), state=DISABLED, command=self.moduleRemove)
        ToolTip(self.moduleRemoveButton, text=_("Remove plug in from plug in table (does not erase the plug in's file)."), wraplength=240)
        self.moduleRemoveButton.grid(row=7, column=3, sticky=E)
        moduleInfoFrame.grid(row=2, column=0, columnspan=5, sticky=(N, S, E, W), padx=3, pady=3)
        moduleInfoFrame.config(borderwidth=4, relief="groove")
        
        okButton = Button(frame, text=_("Close"), command=self.ok)
        ToolTip(okButton, text=_("Accept and changes (if any) and close dialog."), wraplength=240)
        cancelButton = Button(frame, text=_("Cancel"), command=self.close)
        ToolTip(cancelButton, text=_("Cancel changes (if any) and close dialog."), wraplength=240)
        okButton.grid(row=3, column=3, sticky=(S,E), pady=3)
        cancelButton.grid(row=3, column=4, sticky=(S,E), pady=3, padx=3)
        
        self.loadTreeViews()

        frame.grid(row=0, column=0, sticky=(N,S,E,W))
        frame.columnconfigure(0, weight=1)
        frame.columnconfigure(1, weight=1)
        window = self.winfo_toplevel()
        window.columnconfigure(0, weight=1)
        self.geometry("+{0}+{1}".format(dialogX+50,dialogY+100))
        
        self.bind("<Return>", self.ok)
        self.bind("<Escape>", self.close)
        
        self.protocol("WM_DELETE_WINDOW", self.close)
        self.grab_set()
        self.wait_window(self)
        
    def loadTreeViews(self):
        self.selectedModule = None

        # clear previous treeview entries
        for previousNode in self.modulesView.get_children(""): 
            self.modulesView.delete(previousNode)

        for i, moduleItem in enumerate(sorted(self.pluginConfig.get("modules", {}).items())):
            moduleInfo = moduleItem[1]
            name = moduleInfo.get("name", moduleItem[0])
            node = self.modulesView.insert("", "end", name, text=name)
            self.modulesView.set(node, "author", moduleInfo.get("author"))
            self.modulesView.set(node, "ver", moduleInfo.get("version"))
            self.modulesView.set(node, "status", moduleInfo.get("status"))
            self.modulesView.set(node, "date", moduleInfo.get("fileDate"))
            if name in self.modulesWithNewerFileDates:
                self.modulesView.set(node, "update", _("available"))
            self.modulesView.set(node, "descr", moduleInfo.get("description"))
            self.modulesView.set(node, "license", moduleInfo.get("license"))
        
        # clear previous treeview entries
        for previousNode in self.classesView.get_children(""): 
            self.classesView.delete(previousNode)

        for i, classItem in enumerate(sorted(self.pluginConfig.get("classes", {}).items())):
            className, moduleList = classItem
            node = self.classesView.insert("", "end", className, text=className)
            self.classesView.set(node, "modules", ', '.join(moduleList))
            
        self.moduleSelect()  # clear out prior selection

    def ok(self, event=None):
        if self.pluginConfigChanged:
            PluginManager.pluginConfig = self.pluginConfig
            PluginManager.pluginConfigChanged = True
            PluginManager.reset()  # force reloading of modules
        if self.uiClassMethodsChanged:  # may require reloading UI
            if messagebox.askyesno(_("User interface plug-in change"),
                                   _("A change in plug-in class methods may have affected the menus "
                                     "of the user interface.  It may be necessary to restart Arelle to "
                                     "access the menu entries or the changes to their plug-in methods.  \n\n"
                                     "Should Arelle restart with changed user interface language, "
                                     "(if there are any unsaved changes they would be lost!)?"),
                                   parent=self):
                self.cntlr.uiThreadQueue.put((self.cntlr.quit, [None, True]))
        self.close()
        
    def close(self, event=None):
        self.parent.focus_set()
        self.destroy()
                
    def moduleSelect(self, *args):
        node = (self.modulesView.selection() or (None,))[0]
        moduleInfo = self.pluginConfig.get("modules", {}).get(node)
        if moduleInfo:
            self.selectedModule = node
            name = moduleInfo["name"]
            self.moduleNameLabel.config(text=name)
            self.moduleAuthorHdr.config(state=ACTIVE)
            self.moduleAuthorLabel.config(text=moduleInfo["author"])
            self.moduleDescrHdr.config(state=ACTIVE)
            self.moduleDescrLabel.config(text=moduleInfo["description"])
            self.moduleClassesHdr.config(state=ACTIVE)
            self.moduleClassesLabel.config(text=', '.join(moduleInfo["classMethods"]))
            self.moduleUrlHdr.config(state=ACTIVE)
            self.moduleUrlLabel.config(text=moduleInfo["moduleURL"])
            self.moduleDateHdr.config(state=ACTIVE)
            self.moduleDateLabel.config(text=moduleInfo["fileDate"] + " " +
                    (_("(an update is available)") if name in self.modulesWithNewerFileDates else ""))
            self.moduleLicenseHdr.config(state=ACTIVE)
            self.moduleLicenseLabel.config(text=moduleInfo["license"])
            self.moduleEnableButton.config(state=ACTIVE,
                                           text={"enabled":self.DISABLE,
                                                 "disabled":self.ENABLE}[moduleInfo["status"]])
            self.moduleReloadButton.config(state=ACTIVE)
            self.moduleRemoveButton.config(state=ACTIVE)
        else:
            self.selectedModule = None
            self.moduleNameLabel.config(text="")
            self.moduleAuthorHdr.config(state=DISABLED)
            self.moduleAuthorLabel.config(text="")
            self.moduleDescrHdr.config(state=DISABLED)
            self.moduleDescrLabel.config(text="")
            self.moduleClassesHdr.config(state=DISABLED)
            self.moduleClassesLabel.config(text="")
            self.moduleUrlHdr.config(state=DISABLED)
            self.moduleUrlLabel.config(text="")
            self.moduleDateHdr.config(state=DISABLED)
            self.moduleDateLabel.config(text="")
            self.moduleLicenseHdr.config(state=DISABLED)
            self.moduleLicenseLabel.config(text="")
            self.moduleEnableButton.config(state=DISABLED, text=self.ENABLE)
            self.moduleReloadButton.config(state=DISABLED)
            self.moduleRemoveButton.config(state=DISABLED)
        
    def findLocally(self):
        filename = self.cntlr.uiFileDialog("open",
                                           owner=self,
                                           title=_("Choose plug-in module file"),
                                           initialdir=self.cntlr.config.setdefault("pluginOpenDir","."),
                                           filetypes=[(_("Python files"), "*.py")],
                                           defaultextension=".py")
        if filename:
            self.cntlr.config["pluginOpenDir"] = os.path.dirname(filename)
            moduleInfo = PluginManager.moduleModuleInfo(filename)
            self.loadFoundModuleInfo(moduleInfo, filename)
                

    def findOnWeb(self):
        url = DialogURL.askURL(self)
        if url:  # url is the in-cache or local file
            moduleInfo = PluginManager.moduleModuleInfo(url)
            self.cntlr.showStatus("") # clear web loading status
            self.loadFoundModuleInfo(moduleInfo, url)
                
    def loadFoundModuleInfo(self, moduleInfo, url):
        if moduleInfo and moduleInfo.get("name"):
            self.addPluginConfigModuleInfo(moduleInfo)
            self.loadTreeViews()
        else:
            messagebox.showwarning(_("Module is not a plug-in"),
                                   _("File does not contain a python program with an appropriate __pluginInfo__ declaration: \n\n{0}")
                                   .format(url),
                                   parent=self)
            
    def removePluginConfigModuleInfo(self, name):
        moduleInfo = self.pluginConfig["modules"].get(name)
        if moduleInfo:
            for classMethod in moduleInfo["classMethods"]:
                classMethods = self.pluginConfig["classes"].get(classMethod)
                if classMethods and name in classMethods:
                    classMethods.remove(name)
                    if not classMethods: # list has become unused
                        del self.pluginConfig["classes"][classMethod] # remove class
                    if classMethod.startswith("CntlrWinMain.Menu"):
                        self.uiClassMethodsChanged = True  # may require reloading UI
            del self.pluginConfig["modules"][name]
            self.pluginConfigChanged = True

    def addPluginConfigModuleInfo(self, moduleInfo):
        name = moduleInfo["name"]
        self.removePluginConfigModuleInfo(name)  # remove any prior entry for this module
        self.modulesWithNewerFileDates.discard(name) # no longer has an update available
        self.pluginConfig["modules"][name] = moduleInfo
        # add classes
        for classMethod in moduleInfo["classMethods"]:
            classMethods = self.pluginConfig["classes"].setdefault(classMethod, [])
            if name not in classMethods:
                classMethods.append(name)
            if classMethod.startswith("CntlrWinMain.Menu"):
                self.uiClassMethodsChanged = True  # may require reloading UI
        self.pluginConfigChanged = True

    def moduleEnable(self):
        if self.selectedModule in self.pluginConfig["modules"]:
            moduleInfo = self.pluginConfig["modules"][self.selectedModule]
            if self.moduleEnableButton['text'] == self.ENABLE:
                moduleInfo["status"] = "enabled"
                self.moduleEnableButton['text'] = self.DISABLE
            elif self.moduleEnableButton['text'] == self.DISABLE:
                moduleInfo["status"] = "disabled"
                self.moduleEnableButton['text'] = self.ENABLE
            self.pluginConfigChanged = True
            self.loadTreeViews()
            
    def moduleReload(self):
        if self.selectedModule in self.pluginConfig["modules"]:
            url = self.pluginConfig["modules"][self.selectedModule].get("moduleURL")
            if url:
                moduleInfo = PluginManager.moduleModuleInfo(url, reload=True)
                if moduleInfo:
                    self.addPluginConfigModuleInfo(moduleInfo)
                    self.loadTreeViews()
                self.cntlr.showStatus(_("{0} reloaded").format(moduleInfo.get("name")), clearAfter=5000)

    def moduleRemove(self):
        if self.selectedModule in self.pluginConfig["modules"]:
            self.removePluginConfigModuleInfo(self.selectedModule)
            self.pluginConfigChanged = True
            self.loadTreeViews()
                    
Exemple #44
0
class NotebookDemo:
    def __init__(self, fr):

        self.fr = fr
        self.style = Style()  # ts.ThemedStyle() # Style()
        self._create_demo_panel()  # run this before allBtns
        self.allBtns = self.ttkbut + self.cbs[1:] + self.rb
        try:
            piratz_theme.install('piratz')
        except Exception:
            import warnings
            warnings.warn("piratz theme being used without images")

    def _create_demo_panel(self):
        demoPanel = Frame(self.fr, name="demo")
        demoPanel.pack(side='top', fill='both', expand='y')

        # create the notebook
        self.nb = nb = Notebook(demoPanel, name="nb")
        nb.bind("<<NotebookTabChanged>>", self._on_tab_changed)

        # extend bindings to top level window allowing
        #   CTRL+TAB - cycles thru tabs
        #   SHIFT+CTRL+TAB - previous tab
        #   ALT+K - select tab using mnemonic (K = underlined letter)
        nb.enable_traversal()

        nb.pack(fill='both', expand='y', padx=2, pady=3)
        self._create_descrip_tab(nb)
        self._create_treeview_tab(nb)
        self._create_text_tab(nb)

    def _create_descrip_tab(self, nb):
        # frame to hold contents
        frame = Frame(nb, name='descrip')

        # widgets to be displayed on 'Description' tab
        # position and set resize behaviour

        frame.rowconfigure(1, weight=1)
        frame.columnconfigure((0, 1), weight=1, uniform=1)
        lf = LabelFrame(frame, text='Animals')
        lf.pack(pady=5, padx=5, side='left', fill='y')
        themes = ['horse', 'elephant', 'crocodile', 'bat', 'grouse']
        self.ttkbut = []
        for t in themes:
            b = Button(lf, text=t)
            b.pack(pady=2)
            self.ttkbut.append(b)

        lF2 = LabelFrame(frame, text="Theme Combobox")
        lF2.pack(pady=5, padx=5)
        themes = list(sorted(
            self.style.theme_names()))  # get_themes # used in ttkthemes
        themes.insert(0, "Pick a theme")
        self.cb = cb = Combobox(lF2,
                                values=themes,
                                state="readonly",
                                height=10)
        cb.set(themes[0])
        #cb.bind('<<ComboboxSelected>>', self.change_style)
        cb.grid(row=0, column=0, sticky='nw', pady=5)

        lf1 = LabelFrame(frame, text='Checkbuttons')
        lf1.pack(pady=5, padx=5, side='left', fill='y')

        # control variables
        self.enabled = IntVar()
        self.cheese = IntVar()
        self.tomato = IntVar()
        self.basil = IntVar()
        self.oregano = IntVar()
        # checkbuttons
        self.cbOpt = Checkbutton(lf1,
                                 text='Enabled',
                                 variable=self.enabled,
                                 command=self._toggle_opt)
        cbCheese = Checkbutton(text='Cheese',
                               variable=self.cheese,
                               command=self._show_vars)
        cbTomato = Checkbutton(text='Tomato',
                               variable=self.tomato,
                               command=self._show_vars)
        sep1 = Separator(orient='h')
        cbBasil = Checkbutton(text='Basil',
                              variable=self.basil,
                              command=self._show_vars)
        cbOregano = Checkbutton(text='Oregano',
                                variable=self.oregano,
                                command=self._show_vars)
        sep2 = Separator(orient='h')

        self.cbs = [
            self.cbOpt, sep1, cbCheese, cbTomato, sep2, cbBasil, cbOregano
        ]
        for opt in self.cbs:
            if opt.winfo_class() == 'TCheckbutton':
                opt.configure(onvalue=1, offvalue=0)
                opt.setvar(opt.cget('variable'), 0)

            opt.pack(in_=lf1,
                     side='top',
                     fill='x',
                     pady=2,
                     padx=5,
                     anchor='nw')

        lf2 = LabelFrame(frame, text='Radiobuttons', labelanchor='n')
        lf2.pack(pady=5, padx=5, side='left', fill='y')

        self.rb = []
        self.happiness = StringVar()
        for s in ['Great', 'Good', 'OK', 'Poor', 'Awful']:
            b = Radiobutton(lf2,
                            text=s,
                            value=s,
                            variable=self.happiness,
                            command=lambda s=s: self._show_vars())
            b.pack(anchor='nw', side='top', fill='x', pady=5, padx=5)
            self.rb.append(b)

        right = LabelFrame(frame, text='Control Variables')
        right.pack(pady=5, padx=5, side='left', fill='y')

        self.vb0 = Label(right, font=('Courier', 10))
        self.vb1 = Label(right, font=('Courier', 10))
        self.vb2 = Label(right, font=('Courier', 10))
        self.vb3 = Label(right, font=('Courier', 10))
        self.vb4 = Label(right, font=('Courier', 10))
        self.vb5 = Label(right, font=('Courier', 10))

        self.vb0.pack(anchor='nw', pady=5, padx=5)
        self.vb1.pack(anchor='nw', pady=5, padx=5)
        self.vb2.pack(anchor='nw', pady=5, padx=5)
        self.vb3.pack(anchor='nw', pady=5, padx=5)
        self.vb4.pack(anchor='nw', pady=5, padx=5)
        self.vb5.pack(anchor='nw', pady=5, padx=5)

        self._show_vars()
        # add to notebook (underline = index for short-cut character)
        nb.add(frame, text='Description', underline=0, padding=2)

    # =============================================================================
    def _create_treeview_tab(self, nb):
        # Populate the second pane. Note that the content doesn't really matter
        tree = None
        self.backg = ["white", '#f0f0ff']
        tree_columns = ("country", "capital", "currency")
        tree_data = [("Argentina", "Buenos Aires", "ARS"),
                     ("Australia", "Canberra", "AUD"),
                     ("Brazil", "Brazilia", "BRL"),
                     ("Canada", "Ottawa", "CAD"), ("China", "Beijing", "CNY"),
                     ("France", "Paris", "EUR"), ("Germany", "Berlin", "EUR"),
                     ("India", "New Delhi", "INR"), ("Italy", "Rome", "EUR"),
                     ("Japan", "Tokyo", "JPY"),
                     ("Mexico", "Mexico City", "MXN"),
                     ("Russia", "Moscow", "RUB"),
                     ("South Africa", "Pretoria", "ZAR"),
                     ("United Kingdom", "London", "GBP"),
                     ("United States", "Washington, D.C.", "USD")]

        container = Frame(nb)
        container.pack(fill='both', expand=False)
        self.tree = Treeview(container, columns=tree_columns, show="headings")
        vsb = Scrollbar(container, orient="vertical", command=self.tree.yview)
        hsb = Scrollbar(container,
                        orient="horizontal",
                        command=self.tree.xview)
        self.tree.configure(yscrollcommand=vsb.set, xscrollcommand=hsb.set)
        self.tree.grid(column=0, row=0, sticky='ns', in_=container)
        vsb.grid(column=1, row=0, sticky='ns', in_=container)
        hsb.grid(column=0, row=1, sticky='ew', in_=container)

        container.grid_columnconfigure(0, weight=1)
        container.grid_rowconfigure(0, weight=1)

        for col in tree_columns:
            self.tree.heading(
                col,
                text=col.title(),
                command=lambda c=col: self.sortby(self.tree, c, 0))
            # XXX tkFont.Font().measure expected args are incorrect according
            #     to the Tk docs
            self.tree.column(col,
                             width=Font().measure(col.title()),
                             stretch=False)

        for ix, item in enumerate(tree_data):
            itemID = self.tree.insert('', 'end', values=item)
            self.tree.item(itemID, tags=itemID)
            self.tree.tag_configure(itemID, background=self.backg[ix % 2])

            # adjust columns lengths if necessary
            for indx, val in enumerate(item):
                ilen = Font().measure(val)
                if self.tree.column(tree_columns[indx], width=None) < ilen:
                    self.tree.column(tree_columns[indx], width=ilen)

        sg = Sizegrip(container)
        sg.grid(sticky='e')

        nb.add(container, text='Treeview', underline=0, padding=2)

    # =============================================================================
    def _create_text_tab(self, nb):
        self.dir0 = 1
        self.dir1 = 1
        # populate the third frame with other widgets
        fr = Frame(nb, name='fr')

        lF = LabelFrame(fr, text="Slider")
        fr1 = Frame(lF)
        fr1.grid(row=0, column=0, sticky='nsew')
        from_ = 100
        to = 0
        value = 0
        step = 10
        fontSize = 9
        self.scvar = IntVar()
        scRange = self.any_number_range(from_, to, step)
        scLen = len(scRange[1]) * (fontSize + 10)
        self.sc = Scale(fr1,
                        from_=from_,
                        to=to,
                        variable=self.scvar,
                        orient='vertical',
                        length=scLen,
                        command=self.v_scale)
        self.sc.set(value)
        l1 = Label(fr1, textvariable=self.scvar, width=5)
        l1.grid(row=0, column=0, padx=5, pady=5)
        self.sc.grid(row=0, column=1, padx=5, pady=5)
        fr4 = Frame(fr1)
        fr4.grid(row=0, column=2)
        sc_split = '\n'.join(scRange[0].split())
        lb = Label(fr1, text=sc_split, font=('Courier New', str(fontSize)))
        lb.grid(row=0, column=2, padx=5, pady=5)

        fr2 = Frame(lF, name='fr2')
        fr2.grid(row=0, column=1, sticky='nsew')
        self.schvar = IntVar()
        a = 0
        b = 100
        schRange = self.any_number_range(a, b, s=10)
        schLen = Font().measure(schRange[0])
        self.sch = Scale(fr2,
                         from_=a,
                         to=b,
                         length=schLen,
                         variable=self.schvar,
                         orient='horizontal',
                         command=self.h_scale)

        self.sch.set(0)
        l2 = Label(fr2, textvariable=self.schvar)
        l2.grid(row=1, column=1, pady=2)
        self.sch.grid(row=2, column=1, padx=5, pady=5, sticky='nsew')
        l3 = Label(fr2, text=schRange[0], font=('Courier New', str(fontSize)))
        l3.grid(row=3, column=1, padx=5, pady=5)
        lF.grid(row=0, column=0, sticky='nesw', pady=5, padx=5)

        lF1 = LabelFrame(fr, text="Progress", name='lf')
        pb1var = IntVar()
        pb2var = IntVar()
        self.pbar = Progressbar(lF1,
                                variable=pb1var,
                                length=150,
                                mode="indeterminate",
                                name='pb1',
                                orient='horizontal')
        self.pb2 = Progressbar(lF1,
                               variable=pb2var,
                               length=150,
                               mode='indeterminate',
                               name='pb2',
                               orient='vertical')
        self.pbar["value"] = 25
        self.h_progress()
        self.v_progress()
        self.pbar.grid(row=1, column=0, padx=5, pady=5, sticky='nw')
        self.pb2.grid(row=1, column=1, padx=5, pady=5, sticky='nw')
        l3 = Label(lF1, textvariable=pb1var)
        l3.grid(row=0, column=0, pady=2, sticky='nw')
        l4 = Label(lF1, textvariable=pb2var)
        l4.grid(row=0, column=1, pady=2, sticky='nw')

        sg1 = Sizegrip(fr)
        sg1.grid(row=2, column=2, sticky='e')

        lF1.grid(row=1, column=0, sticky='nesw', pady=5, padx=5)

        # add to notebook (underline = index for short-cut character)
        nb.add(fr, text='Sliders & Others', underline=0)

    #=========================================================================
    def _toggle_opt(self):
        # state of the option buttons controlled
        # by the state of the Option frame label widget

        for opt in self.allBtns:
            if opt.winfo_class() != 'TSeparator':
                if self.cbOpt.instate(('selected', )):
                    opt['state'] = '!disabled'  # enable option
                    self.nb.tab(1, state='normal')
                else:
                    opt['state'] = 'disabled'
                    self.nb.tab(1, state='disabled')
        self._show_vars()

    def _show_vars(self):
        # set text for labels in var_panel to include the control
        # variable name and current variable value
        self.vb0['text'] = '{:<11} {:<8}'.format('enabled:',
                                                 self.enabled.get())
        self.vb1['text'] = '{:<11} {:<8}'.format('cheese:', self.cheese.get())
        self.vb2['text'] = '{:<11} {:<8}'.format('tomato:', self.tomato.get())
        self.vb3['text'] = '{:<11} {:<8}'.format('basil:', self.basil.get())
        self.vb4['text'] = '{:<11} {:<8}'.format('oregano:',
                                                 self.oregano.get())
        self.vb5['text'] = '{:<11} {:<8}'.format('happiness:',
                                                 self.happiness.get())

    def sortby(self, tree, col, descending):
        """Sort tree contents when a column is clicked on."""
        # grab values to sort
        data = [(tree.set(child, col), child)
                for child in tree.get_children('')]

        # reorder data
        data.sort(reverse=descending)
        for indx, item in enumerate(data):
            tree.move(item[1], '', indx)

        # switch the heading so that it will sort in the opposite direction
        tree.heading(col,
                     command=lambda col=col: self.sortby(
                         tree, col, int(not descending)))
        # reconfigure tags after ordering
        list_of_items = tree.get_children('')
        for i in range(len(list_of_items)):
            tree.tag_configure(list_of_items[i], background=self.backg[i % 2])

    def any_number_range(self, a, b, s=1):
        """ Generate consecutive values list between two numbers with optional step (default=1)."""
        if (a == b):
            return a
        else:
            mx = max(a, b)
            mn = min(a, b)
            result = []
            output = ''
            # inclusive upper limit. If not needed, delete '+1' in the line below
            while (mn < mx + 1):
                # if step is positive we go from min to max
                if s > 0:
                    result.append(mn)
                    mn += s
                # if step is negative we go from max to min
                if s < 0:
                    result.append(mx)
                    mx += s
                # val
            maxLen = 0
            output = ""
            for ix, res in enumerate(result[:-1]):  # last value ignored
                if len(str(res)) > maxLen:
                    maxLen = len(str(res))
            if maxLen == 1:
                output = ' '.join(str(i)
                                  for i in result)  # converts list to string
            else:
                for ix, res in enumerate(result):
                    if maxLen == 2:
                        if len(str(res)) == 1:
                            output = output + str(res) + " " * maxLen
                        elif len(str(res)) == 2:
                            output = output + str(res) + " "
                        else:
                            output = output + str(res)
            #print(output)
            return output, result

    def change_style(self, event=None):
        """set the Style to the content of the Combobox"""
        content = self.cb.get()
        try:
            self.style.theme_use(content)
        except TclError as err:
            messagebox.showerror('Error', err)
        else:
            root.title(content)

    def change_theme(self, theme):
        window = ttktheme.ThemedTk()
        window.set_theme(theme)
        root.title(theme)

    def _on_tab_changed(self, event):
        event.widget.update_idletasks()
        tab = event.widget.nametowidget(event.widget.select())
        event.widget.configure(height=tab.winfo_reqheight(),
                               width=tab.winfo_reqwidth())

    def h_progress(self):
        widg = self.pbar
        widg['value'] += 1 * self.dir0
        if widg['value'] == 100:
            widg.state(['background', '!active'])
            self.dir0 = -1
            widg.after(50, self.h_progress)
        elif widg['value'] == 0:
            widg.state(['active', '!background'])
            self.dir0 = 1
            widg.after(50, self.h_progress)
        else:
            widg.after(50, self.h_progress)

    def v_progress(self):
        widg1 = self.pb2
        widg1['value'] += 1 * self.dir1
        if widg1['value'] == 0:  # (dir1-1)*100+16
            widg1.state(['active', '!invalid', '!background'])
            self.dir1 = 1
            widg1.after(40, self.v_progress)
        elif widg1['value'] == 16:  # (dir1-1)*100+16
            widg1.state(['background', '!invalid', '!active'])
            widg1.after(40, self.v_progress)
        elif widg1['value'] == 33:
            widg1.state(['invalid', '!background', '!active'])
            widg1.after(40, self.v_progress)
        elif widg1['value'] == 50:
            widg1.state(['active', '!invalid', '!background'])
            widg1.after(40, self.v_progress)
        elif widg1['value'] == 66:
            widg1.state(['background', '!invalid', '!active'])
            widg1.after(40, self.v_progress)
        elif widg1['value'] == 83:
            widg1.state(['invalid', '!background', '!active'])
            widg1.after(40, self.v_progress)
        elif widg1['value'] == 100:
            widg1.state(['active', '!invalid', '!background'])
            self.dir1 = -1
            widg1.after(40, self.v_progress)
        else:
            widg1.after(40, self.v_progress)

    def h_scale(self, schvar):
        v = int(float(schvar))
        widg = self.sch
        imgw = {
            0: ['readonly', '!selected', '!background', '!focus', '!active'],
            1: ['selected', '!readonly', '!background', '!focus', '!active']
        }
        if v >= 0 and v < 10:
            widg.state(['active', '!readonly', '!selected'])
        elif v > 80 and v < 91:
            widg.state(['focus', '!background', '!readonly', '!selected'])
        elif v > 90 and v < 100:
            widg.state(['background', '!invalid', '!focus'])
        elif v == 100:
            widg.state(['invalid', '!background'])
        else:
            widg.state(imgw[v % 2])

    def v_scale(self, scvar):
        v = int(float(scvar))
        widg1 = self.sc
        imgw = {
            0: ['background', '!selected', '!invalid', '!active'],
            1: ['selected', '!invalid', '!background', '!active']
        }
        if v >= 0 and v < 5:
            widg1.state(['active', '!background', '!selected'])
        elif v > 90:
            widg1.state(['invalid', '!selected', '!background'])
        else:
            widg1.state(imgw[v % 2])
class Expenses(Frame):

    # Creates the first option menus in the expense window
    def createOptionButtons(self):
        self.master.title("Expenses")

        # Creates the add item to inventory button
        addItem = Button(root, text="Add item to inventory", command=lambda: self.sequence(self.addItem))#addItem(master)))  # This button will send to the user to the add item page
        addItem.place(x = 130, y = 100)

        # Creates the view items in inventory button
        inventoryButton = Button(root, text="View items in inventory", command=lambda: self.sequence(self.viewInveroty))  # This button will send the user to the view inventory page
        inventoryButton.place(x = 130, y = 150)

        # Create the total cost button
        totalCost = Button(root, text="Total Cost", command=lambda: self.sequence(self.viewTotalCost))
        totalCost.place(x = 130, y = 200)

        # Creates the back button
        backButton = Button(root, text="Back", command=returnHome)  # This button will return the user to the main page. Still working on it.
        backButton.place(x = 50, y = 350)

    # Creates the add item to inventory button and entries
    def addItem(self):
        self.master.title("Add new item")  # Changes the title of the page to Add New Item

        # Creates a label called nameOfItems and an entry called itemName
        nameOfItem = Label(root, text="Item Name: ")
        nameOfItem.place(x = 110, y = 100)
        self.itemName = Entry(root)       # This will allow the user to enter the name of the item that they will be adding
        self.itemName.place(x = 190, y = 100)

        # Creates the label called itemTypeLabel and a drop down menu called itemTypeChoice
        itemTypeLabel = Label(root, text = "Item's type: ")
        itemTypeLabel.place(x = 110, y = 160)
        self.itemTypeChoice = StringVar(root)       # This makes itemTypeChoice a permanent String
        self.itemTypeChoice.set("Tree")             # Tree is set to the default string of itemTypeChoice
        typeChoices = OptionMenu(root, self.itemTypeChoice, "Tree", "Animal", "Machine")    # Drop down menu is created and options Tree, Animal, and Machine are added to the menu
        typeChoices.place(x = 190, y = 160)


        backButton = Button(root, text = "Back", command=lambda: self.sequence(self.createOptionButtons))
        backButton.place(x = 50, y = 350)
        # Next button
        nextButton = Button(root, text = "Next", command=self.saveNameAndType) #This button will send the user to the add inventory page
        nextButton.place(x = 350, y = 350)

    # Function that creates a new item object and assigns it a name and the type
    def saveNameAndType(self):
        name = self.itemName.get()
        self.item = Inventory(name)
        itemType = self.itemTypeChoice.get()
        self.item.itemType = itemType
        self.sequence(self.addToInventory)

    # Creates the add to inventory options
    def addToInventory(self):
        self.master.title("Add %s to %s inventory" % (self.item.name, self.item.itemType))

        # This assigns the variables month, day, and year to be value holder for integer values
        # They are also set to be values of the class expenses (by using self) so that they can
        # be used in the function updateDay and SaveDate
        self.month = IntVar(self)
        self.day = IntVar(self)
        self.year = IntVar(self)

        # This trace function is used to keep track of when the selected months and years change. This is
        # done to adjust the days of the month according to the month or the year
        self.month.trace('w', self.updateDay)
        self.year.trace('w', self.updateDay)

        numMonths = self.nums(1, 12)  # Runs the nums function that creates a list from 1 to 12
        numYears = self.nums(2015, 2030)  # Runs the nums function that creates a list from 2015 to 2030

        # This creates the drop down menu and assigns the options is the menu. The day menu is left empty and
        # is assigned in the updateDay function
        self.optionmenu_month = OptionMenu(root, self.month, *numMonths)
        self.optionmenu_day = OptionMenu(root, self.day, '')
        self.optionmenu_year = OptionMenu(root, self.year, *numYears)

        # Sets the default value of the month and year options to 1 and 2015 respectively
        self.month.set(numMonths[0])
        self.year.set(numYears[0])

        self.optionmenu_month.place(x = 100, y = 120)
        self.optionmenu_day.place(x = 150, y = 120)
        self.optionmenu_year.place(x = 200, y = 120)


        datePurchased = Label(root, text = "Date Purchased")
        datePurchased.place(x = 150, y = 95)

        quantityPurchasedLabel = Label(root, text="Amount purchased:")
        quantityPurchasedLabel.place(x = 50, y = 180)
        self.quantityPurchasedEntry = Entry(root, bd=5) # Creates input box for user to insert the amount of items purchased
        self.quantityPurchasedEntry.place(x = 180, y = 180)

        pricePaidLabe = Label(root, text="Price paid for all: ")
        pricePaidLabe.place(x = 50, y = 210)
        self.pricePaidEntry = Entry(root, bd=5) # Creates input box for user to insert the price paid for the item
        self.pricePaidEntry.place(x = 180, y = 210)


        backButton = Button(root, text = "Back", command=lambda: self.sequence(self.addItem))
        backButton.place(x = 50, y = 350)

        nextButton = Button(root, text = "Next", command=self.saveQuanAndPrice)
        nextButton.place(x = 350, y = 350)

    # This function will update the days of the month according to the selected month and year
    def updateDay(self, *args):
        # The .get() will obtain the selected month and year values from the drop down menu above
        month = self.month.get()
        year = self.year.get()

        # Creates a loop which chooses the last day of the month according to the month or the year
        if month == 1 or month  == 3 or month  == 5 or month  == 7 or month  == 8 or month  == 10 or month  == 12:
            lastDay = 31
        elif month  == 4 or month  == 6 or month  == 9 or month  == 11:
            lastDay = 30
        # This elif loop uses the leap year formula at account for leap years
        elif month  == 2:
            if (year % 4) == 0:
                if (year % 100) == 0:
                    if (year % 400) == 0:
                        lastDay = 29
                    else:
                        lastDay = 28
                else:
                    lastDay = 29
            else:
                lastDay = 28

        numDays = self.nums(1,lastDay)

        # Assigns menu to the day drop down menu and deletes all of the options in the menu
        menu = self.optionmenu_day['menu']
        menu.delete(0, 'end')

        # Loop for generating the new day menu
        for day in numDays:
            menu.add_command(label=day, command=lambda d = day: self.day.set(d))
        self.day.set(1)

    # Function that creates the range of numbers for the drop down menu
    def nums(self, numStart, numEnd):
        num = range(numStart, numEnd + 1)
        return num

    # Function that assigns the price and quantity to an item
    def saveQuanAndPrice(self):
        self.item.price = self.pricePaidEntry.get()
        self.item.quantity = self.quantityPurchasedEntry.get()
        self.saveDate()
        self.sequence(self.confirmation)

    # Function that assigns the purchase date to an item
    def saveDate(self):
        self.item.purchaseMonth = self.month.get()
        self.item.purchaseDay = self.day.get()
        self.item.purchaseYear = self.year.get()
        self.item.purchaseDate = ("%s/%s/%s" % (self.item.purchaseMonth, self.item.purchaseDay, self.item.purchaseYear))

    # Function that displays the user inputted information
    def confirmation(self):
        self.master.title("Confirm %s information" % self.item.name)
        name = Label(root, text="Name of item: ")
        name.place(x = 100, y = 50)
        itemName = Label(root, text=self.item.name)
        itemName.place(x = 100, y = 65)

        type = Label(root, text="%s type: " % self.item.name)
        type.place(x = 100, y = 90)
        itemType = Label(root, text=self.item.itemType)
        itemType.place(x = 100, y = 105)

        quantity = Label(root, text="How many %s were bought?" % self.item.name)
        quantity.place(x = 100, y = 130)
        itemQuantity = Label(root, text=self.item.quantity)
        itemQuantity.place(x = 100, y = 145)

        price = Label(root, text="How much did the %s %s cost?" % (self.item.quantity, self.item.name))
        price.place(x = 100, y = 170)
        itemPrice = Label(root, text=self.item.price)
        itemPrice.place(x = 100, y = 185)

        date = Label(root, text="When were %s bought?" % self.item.name)
        date.place(x = 100, y = 210)
        itemDate = Label(root, text=self.item.purchaseDate)
        itemDate.place(x = 100, y = 225)


        backButton = Button(root, text = "Back", command=lambda: self.sequence(self.addToInventory))
        backButton.place(x = 50, y = 350)

        startOverButton = Button(root, text = "Start Over", command=lambda: self.sequence(self.createOptionButtons))
        startOverButton.place(x = 200, y = 350)

        confirmButton = Button(root, text = "Confirm", command=lambda: self.sequence(self.addToDatabase))
        confirmButton.place(x = 320, y = 350)

    # Adds the item to the database
    def addToDatabase(self):
        self.inventoryDB.insertInvetory(self.item)
        return self.successful()

    # Displays a success message when the item is added
    def successful(self):
        self.master.title("%s was added successfully!" % self.item.name)

        succMessage = Message(root, text = "%s was successfully added to the %s list!" % (self.item.name, self.item.itemType))
        succMessage.place(x = 150, y = 150)

        startOverButton = Button(root, text = "Start Over", command=lambda: self.sequence(self.createOptionButtons))#self.saveNameAndType(itemName)))#(self.saveNameAndType(itemName)))  # (itemName)))# lambda: self.sequence(self.test))  #This button will send the user to the add inventory page
        startOverButton.place(x = 150, y = 350)

    # Used to view the inventory
    def viewInveroty(self):
        # Creates the label called chooseTypeLabel and a drop down menu called chooseItemType
        chooseTypeLabel = Label(root, text = "Item's type: ")
        chooseTypeLabel.place(x = 110, y = 160)
        self.chooseItemType = StringVar(root)       # The drop down menu is created and assigned to chooseItemType
        self.chooseItemType.set("Tree")             # Tree is set to the default option in the drop down menu
        typeChoices = OptionMenu(root, self.chooseItemType, "Tree", "Animal", "Machine", "All")    # Options Tree, Animal, Machine, and ALL are added to the drop down menu
        typeChoices.place(x = 190, y = 160)

        backButton = Button(root, text = "Back", command=lambda: self.sequence(self.createOptionButtons))  # This button will return the user to the expenses option page
        backButton.place(x = 50, y = 350)

        nextButton = Button(root, text = "Next", command=lambda: self.sequence(self.displayGeneralInventory))#self.saveNameAndType(itemName)))#(self.saveNameAndType(itemName)))  # (itemName)))# lambda: self.sequence(self.test))  #This button will send the user to the add inventory page
        nextButton.place(x = 350, y = 350)

    # Used to create the inventory table
    def displayGeneralInventory(self):
        # This creates a table using the function Treeview
        self.tree = Treeview(height="20", columns=("Name", "Current Quantity"))
        self.tree.pack()
        self.tree.heading('#1', text = "Name", anchor = CENTER)
        self.tree.heading('#2', text = "Current Quantity", anchor = CENTER)
        self.tree.column('#1', minwidth=0, width = 100)
        self.tree.column('#2', minwidth=0, width = 100)
        self.tree.column('#0', minwidth=0, width = 0)

        itemType = self.chooseItemType.get()

        if(itemType == "All"):
            self.obtainData("Tree")
            self.obtainData("Animal")
            self.obtainData("Machine")

        else:
            self.obtainData(itemType)

    # Adds database data to the inventory table
    def obtainData(self, type):
        for row in (self.inventoryDB.getOverviewInventory(type)):
            name = row[0]
            totalQuantity = row[1]

            # Inserts data into the table. Each entry is tagged with the name and the type
            # This is done in order to make identifying the entries easier for when detailed
            # tables are requested
            self.tree.insert("", "end", values = (name,totalQuantity), tag= [name, type])

        # Creates a bak function that is used in the displayGeneralInventory functions
        self.backFunction = self.displayGeneralInventory

        # Binds a double click function to the Treeview table. If an entry is double clicked,
        # the function displayGeneralInventory is ran
        self.tree.bind("<Double-1>", self.displayDetailedInventory)

        backButton = Button(root, text="Back", command=lambda: self.sequence(self.viewInveroty))  # This button will return the user to the main page. Still working on it.
        backButton.place(x = 50, y = 350)

    # Creates table when an entry is double clicked
    def displayDetailedInventory(self, event):
        # The selected item's tag are extracted and assigned to name and type
        itemSelected = self.tree.selection()
        name = self.tree.item(itemSelected,"tag")[0]
        type = self.tree.item(itemSelected, "tag")[1]

        for child in root.winfo_children():
            child.destroy()

        self.createDisplayTable()

        self.obtainDetailedData(name, type)

    # Adds detailed database data to the inventory table
    def obtainDetailedData(self,name, type):
        for row in (self.inventoryDB.getDetailedInventory(type, name)):
            name = row[0]
            purchaseDate = row[1]
            Quantity = row[3]
            Price = row[4]
            self.tree.insert("", "end", values = (name,purchaseDate,Quantity, Price))

        backButton = Button(root, text="Back", command=lambda: self.sequence(self.backFunction))
        backButton.place(x = 50, y = 350)

    # Creates the view total cost by month and year buttons
    def viewTotalCost(self):
        viewMonth = Button(root, text="View by month", command=lambda: self.sequence(self.viewByMonth))
        viewMonth.place(x = 120, y = 100)

        viewYear = Button(root, text="View by year", command=lambda: self.sequence(self.viewByYear))
        viewYear.place(x = 120, y = 150)

        backButton = Button(root, text="Back", command=lambda: self.sequence(self.createOptionButtons))#displayGeneralInventory))  # This button will return the user to the main page. Still working on it.
        backButton.place(x = 50, y = 350)

    # Creates the options for the user to select a month and year
    def viewByMonth(self):
        monthLabel = Label(root, text="Month")
        yearLabel = Label(root, text="Year")

        self.month = IntVar(self)
        self.year = IntVar(self)

        numMonths = self.nums(1, 12)
        numYears = self.nums(2015, 2030)

        self.optionmenu_month = OptionMenu(root, self.month, *numMonths)
        self.optionmenu_year = OptionMenu(root, self.year, *numYears)

        self.month.set(numMonths[0])
        self.year.set(numYears[0])

        self.optionmenu_month.place(x = 100, y = 100)
        self.optionmenu_year.place(x = 150, y = 100)

        monthLabel.place(x = 100, y = 140)
        yearLabel.place(x = 150, y = 140)

        backButton = Button(root, text = "Back", command=lambda: self.sequence(self.viewTotalCost))  # This button will return the user to the expenses option page
        backButton.place(x = 50, y = 350)

        nextButton = Button(root, text = "Next", command= self.viewTotalCostMonth)#self.viewTotalCostMonth)#self.saveNameAndType(itemName)))#(self.saveNameAndType(itemName)))  # (itemName)))# lambda: self.sequence(self.test))  #This button will send the user to the add inventory page
        nextButton.place(x = 350, y = 350)

    # Creates database table and inserts the respective values by month and year
    def viewTotalCostMonth(self):
        self.createDisplayTable()

        self.totalPrice = 0
        month = self.month.get()
        year = self.year.get()

        self.lengthMonth = len(str(month))
        self.searchDate = str(month) + "/" + str(year)

        InventoryDB = getDatabaseConnection()
        database = InventoryDB.cursor()

        self.insertData("DetailedTreeInventory", "Tree", database, "Month")
        self.insertData("DetailedAnimalInventory", "Animal", database, "Month")
        self.insertData("DetailedMachineInventory", "Machine", database, "Month")

        InventoryDB.close()

        totalPriceLabel = Label(root, text=("Total price for " + calendar.month_name[month] + " in " + str(year) + " is: " + str(self.totalPrice)))
        totalPriceLabel.place(x = 100, y = 350)

        backButton = Button(root, text = "Back", command=lambda: self.sequence(self.viewByMonth))  # This button will return the user to the expenses option page
        backButton.place(x = 50, y = 350)

    # Creates the option for the user to select the year
    def viewByYear(self):
        yearLabel = Label(root, text="Year")

        self.year = IntVar(self)

        numYears = self.nums(2015, 2030)

        self.optionmenu_year = OptionMenu(root, self.year, *numYears)

        self.year.set(numYears[0])

        self.optionmenu_year.place(x = 100, y = 100)
        yearLabel.place(x = 100, y = 140)


        backButton = Button(root, text = "Back", command=lambda: self.sequence(self.viewTotalCost))  # This button will return the user to the expenses option page
        backButton.place(x = 50, y = 350)

        nextButton = Button(root, text = "Next", command= self.viewTotalCostYear)#self.viewTotalCostMonth)#self.saveNameAndType(itemName)))#(self.saveNameAndType(itemName)))  # (itemName)))# lambda: self.sequence(self.test))  #This button will send the user to the add inventory page
        nextButton.place(x = 350, y = 350)

    # Creates database table and inserts the respective values by year
    def viewTotalCostYear(self):
        self.createDisplayTable()

        self.totalPrice = 0
        year = self.year.get()

        InventoryDB = getDatabaseConnection()
        database = InventoryDB.cursor()

        self.insertData("DetailedTreeInventory", "Tree", database, "Year")
        self.insertData("DetailedAnimalInventory", "Animal", database, "Year")
        self.insertData("DetailedMachineInventory", "Machine", database, "Year")

        totalPriceLabel = Label(root, text="Total price for " + str(year) + " is: " + str(self.totalPrice))
        totalPriceLabel.place(x = 100, y = 350)

        backButton = Button(root, text = "Back", command=lambda: self.sequence(self.viewByYear))  # This button will return the user to the expenses option page
        backButton.place(x = 50, y = 350)

    # Inserts the detailed values into the detailed table
    def insertData(self, table, type, database, yearOrMonth):
        if yearOrMonth == "Year":
            for row in database.execute("SELECT * FROM %s" % table ):
                itemdate = row[1]

                if ( str(self.year.get()) == itemdate[-4:]):
                    name = row[0]
                    purchaseDate = row[1]
                    Quantity = row[3]
                    Price = row[4]

                    self.tree.insert("", "end", values = (name,purchaseDate,Quantity, Price),tag = [name, type] )
                    self.totalPrice = self.totalPrice + Price

                self.backFunction = self.viewTotalCostYear

        else:
            for row in database.execute("SELECT * FROM %s" % table ):
                itemdate = row[1]

                if (self.searchDate == (itemdate[0:(self.lengthMonth + 1)] + itemdate[-4:])):
                    name = row[0]
                    purchaseDate = row[1]
                    Quantity = row[3]
                    Price = row[4]

                    self.tree.insert("", "end", values = (name,purchaseDate,Quantity, Price), tag = [name, type])
                    self.totalPrice = self.totalPrice + Price

                self.backFunction = self.viewTotalCostMonth

        # If entry is double clicked, the table will acknoledge the click and display the detailed table
        self.tree.bind("<Double-1>", self.displayDetailedInventory)

    def createDisplayTable(self):
        for child in root.winfo_children():
            child.destroy()

        self.tree = Treeview(height="15", columns=("Name", "Purchase Date", "Quantity", "Price"))#, "Description"))
        self.tree.pack()
        self.tree.heading('#1', text = "Name",          anchor = CENTER)
        self.tree.heading('#2', text = "Purchase Date", anchor = CENTER)
        self.tree.heading('#3', text = "Quantity",      anchor = CENTER)
        self.tree.heading('#4', text = "Price",         anchor = CENTER)
        self.tree.column('#1', minwidth=0, width = 95)
        self.tree.column('#2', minwidth=0, width = 95)
        self.tree.column('#3', minwidth=0, width = 95)
        self.tree.column('#4', minwidth=0, width = 95)
        self.tree.column('#0', minwidth=0, width = 0)

    # This is a helper function that will delete the current widgets of the frame
    def sequence(self, run):
        for child in root.winfo_children():
            child.destroy()
        run()

    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.place();
        self.inventoryDB = InventoryDatabase()
        # self.inventoryDB.createTable()
        self.createOptionButtons()
Exemple #46
0
class DeleteWindow:
    def __init__(self, data=''):
        self.data = data
        print(self.data)
        self.win = Tk()
        self.canvas = Canvas(self.win, width=800, height=420, bg='white')
        self.canvas.pack(expand=YES, fill=BOTH)

        # show window in center of the screen
        width = self.win.winfo_screenwidth()
        height = self.win.winfo_screenheight()
        x = int(width / 2 - 800 / 2)
        y = int(height / 2 - 420 / 2)
        str1 = "800x420+" + str(x) + "+" + str(y)
        self.win.geometry(str1)

        # disable resize window
        self.win.resizable(False, False)

        # changing title of the window
        self.win.title("| DELETING BOOK DETAILS | LIBRARY MANAGEMENT SYSTEM |")

    def add_frame(self):

        self.frame = Frame(self.win, height=420, width=800)
        self.frame.place(x=0, y=0)

        x, y = 0, 0

        self.label = Label(self.frame, text="DELETE/UPDATE BOOKS", fg='black')
        self.label.config(font=("Poppins", 20, 'underline bold'))
        self.label.place(x=235, y=35)

        # use tree view to show details from the table
        self.tr = Treeview(self.frame,
                           columns=('BOOK_ID', 'BOOK_TITLE', 'AUTHOR_NAME',
                                    'PUBLISHED_YEAR', 'PRICE'),
                           selectmode="extended")

        # heading key + text

        self.tr.heading('#0', text='BOOK_ID')
        self.tr.column('#0', minwidth=0, width=100, stretch=NO)
        self.tr.heading('#1', text='BOOK_TITLE')
        self.tr.column('#1', minwidth=0, width=100, stretch=NO)
        self.tr.heading('#2', text='AUTHOR_NAME')
        self.tr.column('#2', minwidth=0, width=100, stretch=NO)
        self.tr.heading('#3', text='PUBLISHED_YEAR')
        self.tr.column('#3', minwidth=0, width=110, stretch=NO)
        self.tr.heading('#4', text='PRICE')
        self.tr.column('#4', minwidth=0, width=100, stretch=NO)
        self.tr.heading('#5', text='DELETE')
        self.tr.column('#5', minwidth=0, width=100, stretch=NO)
        # self.tr.heading('#6', text='DELETE')
        # self.tr.column('#6', minwidth=0, width=100, stretch=NO)

        j = 0
        for i in Database.database.ViewBooks():
            self.tr.insert('',
                           index=j,
                           text=i[0],
                           values=(i[1], i[2], i[3], i[4], 'DELETE'))
            j += 1

        # create action on deletion
        self.tr.bind('<Double-Button-1>', self.actions)
        self.tr.place(x=100, y=y + 100)

        self.win.mainloop()

    def actions(self, e):
        # get the value of deleted row
        tt = self.tr.focus()
        # get the column id
        col = self.tr.identify_column(e.x)
        print(col)
        print(self.tr.item(tt))

        data = (self.tr.item(tt).get('text'), )

        if col == '#5':
            res = messagebox.askyesno("Message", "Do you want  to delete..!")
            if res:
                d = Database.database.Delete(data)
                if d:
                    messagebox.showinfo("Message",
                                        "Data deleted successfully..!")
                    self.win.destroy()
                    x = Thirdpage
                    # x.add_frame()
            else:
                self.win.destroy()
                x = Student.Delete.DeleteWindow()
                x.add_frame()
Exemple #47
0
class DialogOpenArchive(Toplevel):
    def __init__(self, mainWin, openType, filesource, filenames, title, colHeader, showAltViewButton=False):
        parent = mainWin.parent
        super(DialogOpenArchive, self).__init__(parent)
        self.parent = parent
        self.showAltViewButton = showAltViewButton
        parentGeometry = re.match("(\d+)x(\d+)[+]?([-]?\d+)[+]?([-]?\d+)", parent.geometry())
        dialogX = int(parentGeometry.group(3))
        dialogY = int(parentGeometry.group(4))
        self.accepted = False

        self.transient(self.parent)
        
        frame = Frame(self)

        treeFrame = Frame(frame, width=500)
        vScrollbar = Scrollbar(treeFrame, orient=VERTICAL)
        hScrollbar = Scrollbar(treeFrame, orient=HORIZONTAL)
        self.treeView = Treeview(treeFrame, xscrollcommand=hScrollbar.set, yscrollcommand=vScrollbar.set)
        self.treeView.grid(row=0, column=0, sticky=(N, S, E, W))
        hScrollbar["command"] = self.treeView.xview
        hScrollbar.grid(row=1, column=0, sticky=(E,W))
        vScrollbar["command"] = self.treeView.yview
        vScrollbar.grid(row=0, column=1, sticky=(N,S))
        treeFrame.columnconfigure(0, weight=1)
        treeFrame.rowconfigure(0, weight=1)
        treeFrame.grid(row=0, column=0, columnspan=4, sticky=(N, S, E, W), padx=3, pady=3)
        self.treeView.focus_set()
        
        mainWin.showStatus(_("loading archive {0}").format(filesource.url))
        self.filesource = filesource
        self.filenames = filenames
        self.selection = filesource.selection
        self.hasToolTip = False
        selectedNode = None

        if openType == ENTRY_POINTS:
            try:
                metadataFiles = filesource.taxonomyPackageMetadataFiles
                if len(metadataFiles) > 1:
                    raise IOError(_("Taxonomy package contained more than one metadata file: {0}.")
                                  .format(', '.join(metadataFiles)))
                metadataFile = metadataFiles[0]
                metadata = filesource.file(filesource.url + os.sep + metadataFile)[0]
                self.metadataFilePrefix = os.sep.join(os.path.split(metadataFile)[:-1])
                if self.metadataFilePrefix:
                    self.metadataFilePrefix += os.sep
        
                self.nameToUrls, self.remappings = parseTxmyPkg(mainWin, metadata)
            except Exception as e:
                self.close()
                err = _("Failed to parse metadata; the underlying error was: {0}").format(e)
                messagebox.showerror(_("Malformed taxonomy package"), err)
                mainWin.addToLog(err)
                return
    
        mainWin.showStatus(None)
        
        if openType == DISCLOSURE_SYSTEM:
            y = 3
        else:
            y = 1

        okButton = Button(frame, text=_("OK"), command=self.ok)
        cancelButton = Button(frame, text=_("Cancel"), command=self.close)
        okButton.grid(row=y, column=2, sticky=(S,E,W), pady=3)
        cancelButton.grid(row=y, column=3, sticky=(S,E,W), pady=3, padx=3)
        
        if showAltViewButton:
            self.altViewButton = Button(frame, command=self.showAltView)
            self.altViewButton.grid(row=y, column=0, sticky=(S,W), pady=3, padx=3)
        
        self.loadTreeView(openType, colHeader, title)

        frame.grid(row=0, column=0, sticky=(N,S,E,W))
        frame.columnconfigure(0, weight=1)
        window = self.winfo_toplevel()
        window.columnconfigure(0, weight=1)
        self.geometry("+{0}+{1}".format(dialogX+50,dialogY+100))
        
        self.bind("<Return>", self.ok)
        self.bind("<Escape>", self.close)
        
        self.toolTipText = StringVar()
        if self.hasToolTip:
            self.treeView.bind("<Motion>", self.motion, '+')
            self.treeView.bind("<Leave>", self.leave, '+')
            self.toolTipText = StringVar()
            self.toolTip = ToolTip(self.treeView, 
                                   textvariable=self.toolTipText, 
                                   wraplength=640, 
                                   follow_mouse=True,
                                   state="disabled")
            self.toolTipRowId = None

        self.protocol("WM_DELETE_WINDOW", self.close)
        self.grab_set()
        self.wait_window(self)
        
    def loadTreeView(self, openType, title, colHeader):
        self.title(title)
        self.openType = openType
        selectedNode = None

        # clear previous treeview entries
        for previousNode in self.treeView.get_children(""): 
            self.treeView.delete(previousNode)

        # set up treeView widget and tabbed pane
        if openType in (ARCHIVE, DISCLOSURE_SYSTEM):
            self.treeView.column("#0", width=500, anchor="w")
            self.treeView.heading("#0", text=colHeader)
            try:
                self.isRss = self.filesource.isRss
                if self.isRss:
                    self.treeView.column("#0", width=350, anchor="w")
                    self.treeView["columns"] = ("descr", "date", "instDoc")
                    self.treeView.column("descr", width=50, anchor="center", stretch=False)
                    self.treeView.heading("descr", text="Form")
                    self.treeView.column("date", width=170, anchor="w", stretch=False)
                    self.treeView.heading("date", text="Pub Date")
                    self.treeView.column("instDoc", width=200, anchor="w", stretch=False)
                    self.treeView.heading("instDoc", text="Instance Document")
            except AttributeError:
                self.isRss = False
                self.treeView["columns"] = tuple()
        
            loadedPaths = []
            for i, filename in enumerate(self.filenames):
                if isinstance(filename,tuple):
                    if self.isRss:
                        form, date, instDoc = filename[2:5]
                    filename = filename[0] # ignore tooltip
                    self.hasToolTip = True
                if filename.endswith("/"):
                    filename = filename[:-1]
                path = filename.split("/")
                if not self.isRss and len(path) > 1 and path[:-1] in loadedPaths:
                    parent = "file{0}".format(loadedPaths.index(path[:-1]))
                else:
                    parent = "" 
                node = self.treeView.insert(parent, "end", "file{0}".format(i), text=path[-1])
                if self.isRss:
                    self.treeView.set(node, "descr", form)
                    self.treeView.set(node, "date", date)
                    self.treeView.set(node, "instDoc", os.path.basename(instDoc))
                if self.selection == filename:
                    selectedNode = node
                loadedPaths.append(path)

        elif openType == ENTRY_POINTS:
            self.treeView.column("#0", width=150, anchor="w")
            self.treeView.heading("#0", text="Name")
    
            self.treeView["columns"] = ("url",)
            self.treeView.column("url", width=350, anchor="w")
            self.treeView.heading("url", text="URL")
            
            for name, urls in self.nameToUrls.items():
                displayUrl = urls[1] # display the canonical URL
                self.treeView.insert("", "end", name, values=[displayUrl], text=name)
                
            self.hasToolTip = True
        else: # unknown openType
            return None
        if selectedNode:
            self.treeView.see(selectedNode)
            self.treeView.selection_set(selectedNode)

        if self.showAltViewButton:
            self.altViewButton.config(text=_("Show Files") if openType == ENTRY_POINTS else _("Show Entries"))

        
    def ok(self, event=None):
        selection = self.treeView.selection()
        if len(selection) > 0:
            if self.openType in (ARCHIVE, DISCLOSURE_SYSTEM):
                filename = self.filenames[int(selection[0][4:])]
                if isinstance(filename,tuple):
                    if self.isRss:
                        filename = filename[4]
                    else:
                        filename = filename[0]
                if not filename.endswith("/"):
                    self.filesource.select(filename)
                    self.accepted = True
                    self.close()
            elif self.openType == ENTRY_POINTS:
                epName = selection[0]
                #index 0 is the remapped Url, as opposed to the canonical one used for display
                urlOrFile = self.nameToUrls[epName][0]
                
                # load file source remappings
                self.filesource.mappedPaths = \
                    dict((prefix, 
                          remapping if isHttpUrl(remapping)
                          else (self.filesource.baseurl + os.sep + self.metadataFilePrefix +remapping.replace("/", os.sep)))
                          for prefix, remapping in self.remappings.items())
    
                if not urlOrFile.endswith("/"):
                    # check if it's an absolute URL rather than a path into the archive
                    if isHttpUrl(urlOrFile):
                        self.filesource.select(urlOrFile)  # absolute path selection
                    else:
                        # assume it's a path inside the archive:
                        self.filesource.select(self.metadataFilePrefix + urlOrFile)
                    self.accepted = True
                    self.close()
        
    def close(self, event=None):
        self.parent.focus_set()
        self.destroy()
        
    def showAltView(self, event=None):
        if self.openType == ENTRY_POINTS:
            self.loadTreeView(ARCHIVE, _("Select Entry Point"), _("File"))
        else:
            self.loadTreeView(ENTRY_POINTS, _("Select Archive File"), _("File"))
        
    def leave(self, *args):
        self.toolTipRowId = None

    def motion(self, *args):
        tvRowId = self.treeView.identify_row(args[0].y)
        if tvRowId != self.toolTipRowId:
            text = None
            if self.openType in (ARCHIVE, DISCLOSURE_SYSTEM):
                self.toolTipRowId = tvRowId
                if tvRowId and len(tvRowId) > 4:
                    try:
                        text = self.filenames[ int(tvRowId[4:]) ]
                        if isinstance(text, tuple):
                            text = text[1].replace("\\n","\n")
                    except (KeyError, ValueError):
                        pass
            elif self.openType == ENTRY_POINTS:
                try:
                    epUrl = self.nameToUrls[tvRowId][1]
                    text = "{0}\n{1}".format(tvRowId, epUrl)
                except KeyError:
                    pass
            self.setToolTip(text)
                
    def setToolTip(self, text):
        self.toolTip._hide()
        if text:
            self.toolTipText.set(text)
            self.toolTip.configure(state="normal")
            self.toolTip._schedule()
        else:
            self.toolTipText.set("")
            self.toolTip.configure(state="disabled")
Exemple #48
0
    def treefy(self):
        tk = Tk()
        tk.geometry('850x650+400+250')
        tree = Treeview()
        for index, i in enumerate(self._data):
            tree.insert('', index, text=i.name, values={})

        # #一级目录
        treeF1 = tree.insert("", 0, "上海", text="上海SH",
                             values=("F1"))  # #创建一级树目录
        treeF2 = tree.insert("", 1, "江苏", text="江苏JS", values=("F2"))
        treeF3 = tree.insert("", 2, "浙江", text="浙江ZJ", values=("F3"))
        # #二级目录
        treeF1_1 = tree.insert(treeF1, 0, "黄浦区", text="黄浦区hp",
                               values=("F1_1"))  # #将目录帮到菜单treeF1
        treeF1_2 = tree.insert(treeF1, 1, "静安区", text="静安区ja", values=("F1_2"))
        treeF1_3 = tree.insert(treeF1, 2, "长宁区", text="长宁区cn", values=("F1_3"))
        treeF2_1 = tree.insert(treeF2, 0, "苏州", text="苏州sz",
                               values=("F2_1"))  # #将目录帮到菜单treeF2
        treeF2_2 = tree.insert(treeF2, 1, "南京", text="南京nj", values=("F2_2"))
        treeF2_3 = tree.insert(treeF2, 2, "无锡", text="无锡wx", values=("F2_3"))
        treeF3_1 = tree.insert(treeF3, 0, "杭州", text="杭州hz",
                               values=("F3_1"))  # #将目录帮到菜单treeF3
        treeF3_2 = tree.insert(treeF3, 1, "宁波", text="宁波nb", values=("F3_2"))
        treeF3_3 = tree.insert(treeF3, 2, "温州", text="温州wz", values=("F3_3"))
        # #三级目录
        treeF1_1_1 = tree.insert(treeF1_1,
                                 0,
                                 "南京路",
                                 text="南京路njl",
                                 values=("treeF1_1_1"))
        treeF1_1_2 = tree.insert(treeF1_1,
                                 0,
                                 "河南路",
                                 text="河南路hnl",
                                 values=("treeF1_1_2"))

        tree.pack(side=LEFT, fill=Y)
        tk.mainloop()
class DialogPluginManager(Toplevel):
    def __init__(self, mainWin, modulesWithNewerFileDates):
        super(DialogPluginManager, self).__init__(mainWin.parent)
        
        self.ENABLE = _("Enable")
        self.DISABLE = _("Disable")
        self.parent = mainWin.parent
        self.cntlr = mainWin
        
        # copy plugins for temporary display
        self.pluginConfig = PluginManager.pluginConfig
        self.pluginConfigChanged = False
        self.uiClassMethodsChanged = False
        self.modulesWithNewerFileDates = modulesWithNewerFileDates
        
        parentGeometry = re.match("(\d+)x(\d+)[+]?([-]?\d+)[+]?([-]?\d+)", self.parent.geometry())
        dialogX = int(parentGeometry.group(3))
        dialogY = int(parentGeometry.group(4))

        self.title(_("Plug-in Manager"))
        frame = Frame(self)
        
        # left button frame
        buttonFrame = Frame(frame, width=40)
        buttonFrame.columnconfigure(0, weight=1)
        addLabel = Label(buttonFrame, text=_("Find plug-in modules:"), wraplength=60, justify="center")
        addLocalButton = Button(buttonFrame, text=_("Locally"), command=self.findLocally)
        ToolTip(addLocalButton, text=_("File chooser allows selecting python module files to add (or reload) plug-ins, from the local file system."), wraplength=240)
        addWebButton = Button(buttonFrame, text=_("On Web"), command=self.findOnWeb)
        ToolTip(addWebButton, text=_("Dialog to enter URL full path to load (or reload) plug-ins, from the web or local file system."), wraplength=240)
        addLabel.grid(row=0, column=0, pady=4)
        addLocalButton.grid(row=1, column=0, pady=4)
        addWebButton.grid(row=2, column=0, pady=4)
        buttonFrame.grid(row=0, column=0, rowspan=2, sticky=(N, S, W), padx=3, pady=3)
        
        # right tree frame (plugins already known to arelle)
        modulesFrame = Frame(frame, width=700)
        vScrollbar = Scrollbar(modulesFrame, orient=VERTICAL)
        hScrollbar = Scrollbar(modulesFrame, orient=HORIZONTAL)
        self.modulesView = Treeview(modulesFrame, xscrollcommand=hScrollbar.set, yscrollcommand=vScrollbar.set, height=7)
        self.modulesView.grid(row=0, column=0, sticky=(N, S, E, W))
        self.modulesView.bind('<<TreeviewSelect>>', self.moduleSelect)
        hScrollbar["command"] = self.modulesView.xview
        hScrollbar.grid(row=1, column=0, sticky=(E,W))
        vScrollbar["command"] = self.modulesView.yview
        vScrollbar.grid(row=0, column=1, sticky=(N,S))
        modulesFrame.columnconfigure(0, weight=1)
        modulesFrame.rowconfigure(0, weight=1)
        modulesFrame.grid(row=0, column=1, columnspan=4, sticky=(N, S, E, W), padx=3, pady=3)
        self.modulesView.focus_set()

        self.modulesView.column("#0", width=120, anchor="w")
        self.modulesView.heading("#0", text=_("Name"))
        self.modulesView["columns"] = ("author", "ver", "status", "date", "update", "descr", "license")
        self.modulesView.column("author", width=100, anchor="w", stretch=False)
        self.modulesView.heading("author", text=_("Author"))
        self.modulesView.column("ver", width=50, anchor="w", stretch=False)
        self.modulesView.heading("ver", text=_("Version"))
        self.modulesView.column("status", width=50, anchor="w", stretch=False)
        self.modulesView.heading("status", text=_("Status"))
        self.modulesView.column("date", width=70, anchor="w", stretch=False)
        self.modulesView.heading("date", text=_("File Date"))
        self.modulesView.column("update", width=50, anchor="w", stretch=False)
        self.modulesView.heading("update", text=_("Update"))
        self.modulesView.column("descr", width=200, anchor="w", stretch=False)
        self.modulesView.heading("descr", text=_("Description"))
        self.modulesView.column("license", width=70, anchor="w", stretch=False)
        self.modulesView.heading("license", text=_("License"))

        classesFrame = Frame(frame)
        vScrollbar = Scrollbar(classesFrame, orient=VERTICAL)
        hScrollbar = Scrollbar(classesFrame, orient=HORIZONTAL)
        self.classesView = Treeview(classesFrame, xscrollcommand=hScrollbar.set, yscrollcommand=vScrollbar.set, height=5)
        self.classesView.grid(row=0, column=0, sticky=(N, S, E, W))
        hScrollbar["command"] = self.classesView.xview
        hScrollbar.grid(row=1, column=0, sticky=(E,W))
        vScrollbar["command"] = self.classesView.yview
        vScrollbar.grid(row=0, column=1, sticky=(N,S))
        classesFrame.columnconfigure(0, weight=1)
        classesFrame.rowconfigure(0, weight=1)
        classesFrame.grid(row=1, column=1, columnspan=4, sticky=(N, S, E, W), padx=3, pady=3)
        self.classesView.focus_set()
        
        self.classesView.column("#0", width=200, anchor="w")
        self.classesView.heading("#0", text=_("Class"))
        self.classesView["columns"] = ("modules")
        self.classesView.column("modules", width=500, anchor="w", stretch=False)
        self.classesView.heading("modules", text=_("Modules"))
        
        # bottom frame module info details
        moduleInfoFrame = Frame(frame, width=700)
        moduleInfoFrame.columnconfigure(1, weight=1)
        
        self.moduleNameLabel = Label(moduleInfoFrame, wraplength=600, justify="left", 
                                     font=font.Font(family='Helvetica', size=12, weight='bold'))
        self.moduleNameLabel.grid(row=0, column=0, columnspan=4, sticky=W)
        self.moduleAuthorHdr = Label(moduleInfoFrame, text=_("author:"), state=DISABLED)
        self.moduleAuthorHdr.grid(row=1, column=0, sticky=W)
        self.moduleAuthorLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleAuthorLabel.grid(row=1, column=1, columnspan=3, sticky=W)
        self.moduleDescrHdr = Label(moduleInfoFrame, text=_("description:"), state=DISABLED)
        self.moduleDescrHdr.grid(row=2, column=0, sticky=W)
        self.moduleDescrLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleDescrLabel.grid(row=2, column=1, columnspan=3, sticky=W)
        self.moduleClassesHdr = Label(moduleInfoFrame, text=_("classes:"), state=DISABLED)
        self.moduleClassesHdr.grid(row=3, column=0, sticky=W)
        self.moduleClassesLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleClassesLabel.grid(row=3, column=1, columnspan=3, sticky=W)
        ToolTip(self.moduleClassesLabel, text=_("List of classes that this plug-in handles."), wraplength=240)
        self.moduleUrlHdr = Label(moduleInfoFrame, text=_("URL:"), state=DISABLED)
        self.moduleUrlHdr.grid(row=4, column=0, sticky=W)
        self.moduleUrlLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleUrlLabel.grid(row=4, column=1, columnspan=3, sticky=W)
        ToolTip(self.moduleUrlLabel, text=_("URL of plug-in module (local file path or web loaded file)."), wraplength=240)
        self.moduleDateHdr = Label(moduleInfoFrame, text=_("date:"), state=DISABLED)
        self.moduleDateHdr.grid(row=5, column=0, sticky=W)
        self.moduleDateLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleDateLabel.grid(row=5, column=1, columnspan=3, sticky=W)
        ToolTip(self.moduleDateLabel, text=_("Date of currently loaded module file (with parenthetical node when an update is available)."), wraplength=240)
        self.moduleLicenseHdr = Label(moduleInfoFrame, text=_("license:"), state=DISABLED)
        self.moduleLicenseHdr.grid(row=6, column=0, sticky=W)
        self.moduleLicenseLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleLicenseLabel.grid(row=6, column=1, columnspan=3, sticky=W)
        self.moduleEnableButton = Button(moduleInfoFrame, text=self.ENABLE, state=DISABLED, command=self.moduleEnable)
        ToolTip(self.moduleEnableButton, text=_("Enable/disable plug in."), wraplength=240)
        self.moduleEnableButton.grid(row=7, column=1, sticky=E)
        self.moduleReloadButton = Button(moduleInfoFrame, text=_("Reload"), state=DISABLED, command=self.moduleReload)
        ToolTip(self.moduleReloadButton, text=_("Reload/update plug in."), wraplength=240)
        self.moduleReloadButton.grid(row=7, column=2, sticky=E)
        self.moduleRemoveButton = Button(moduleInfoFrame, text=_("Remove"), state=DISABLED, command=self.moduleRemove)
        ToolTip(self.moduleRemoveButton, text=_("Remove plug in from plug in table (does not erase the plug in's file)."), wraplength=240)
        self.moduleRemoveButton.grid(row=7, column=3, sticky=E)
        moduleInfoFrame.grid(row=2, column=0, columnspan=5, sticky=(N, S, E, W), padx=3, pady=3)
        moduleInfoFrame.config(borderwidth=4, relief="groove")
        
        okButton = Button(frame, text=_("Close"), command=self.ok)
        ToolTip(okButton, text=_("Accept and changes (if any) and close dialog."), wraplength=240)
        cancelButton = Button(frame, text=_("Cancel"), command=self.close)
        ToolTip(cancelButton, text=_("Cancel changes (if any) and close dialog."), wraplength=240)
        okButton.grid(row=3, column=3, sticky=(S,E), pady=3)
        cancelButton.grid(row=3, column=4, sticky=(S,E), pady=3, padx=3)
        
        self.loadTreeViews()

        frame.grid(row=0, column=0, sticky=(N,S,E,W))
        frame.columnconfigure(0, weight=1)
        frame.columnconfigure(1, weight=1)
        window = self.winfo_toplevel()
        window.columnconfigure(0, weight=1)
        self.geometry("+{0}+{1}".format(dialogX+50,dialogY+100))
        
        self.bind("<Return>", self.ok)
        self.bind("<Escape>", self.close)
        
        self.protocol("WM_DELETE_WINDOW", self.close)
        self.grab_set()
        self.wait_window(self)
        
    def loadTreeViews(self):
        self.selectedModule = None

        # clear previous treeview entries
        for previousNode in self.modulesView.get_children(""): 
            self.modulesView.delete(previousNode)

        for i, moduleItem in enumerate(sorted(self.pluginConfig.get("modules", {}).items())):
            moduleInfo = moduleItem[1]
            name = moduleInfo.get("name", moduleItem[0])
            node = self.modulesView.insert("", "end", name, text=name)
            self.modulesView.set(node, "author", moduleInfo.get("author"))
            self.modulesView.set(node, "ver", moduleInfo.get("version"))
            self.modulesView.set(node, "status", moduleInfo.get("status"))
            self.modulesView.set(node, "date", moduleInfo.get("fileDate"))
            if name in self.modulesWithNewerFileDates:
                self.modulesView.set(node, "update", _("available"))
            self.modulesView.set(node, "descr", moduleInfo.get("description"))
            self.modulesView.set(node, "license", moduleInfo.get("license"))
        
        # clear previous treeview entries
        for previousNode in self.classesView.get_children(""): 
            self.classesView.delete(previousNode)

        for i, classItem in enumerate(sorted(self.pluginConfig.get("classes", {}).items())):
            className, moduleList = classItem
            node = self.classesView.insert("", "end", className, text=className)
            self.classesView.set(node, "modules", ', '.join(moduleList))
            
        self.moduleSelect()  # clear out prior selection

    def ok(self, event=None):
        if self.pluginConfigChanged:
            PluginManager.pluginConfig = self.pluginConfig
            PluginManager.pluginConfigChanged = True
            PluginManager.reset()  # force reloading of modules
        if self.uiClassMethodsChanged:  # may require reloading UI
            if messagebox.askyesno(_("User interface plug-in change"),
                                   _("A change in plug-in class methods may have affected the menus "
                                     "of the user interface.  It may be necessary to restart Arelle to "
                                     "access the menu entries or the changes to their plug-in methods.  \n\n"
                                     "Should Arelle restart with changed user interface language, "
                                     "(if there are any unsaved changes they would be lost!)?"),
                                   parent=self):
                self.cntlr.uiThreadQueue.put((self.cntlr.quit, [None, True]))
        self.close()
        
    def close(self, event=None):
        self.parent.focus_set()
        self.destroy()
                
    def moduleSelect(self, *args):
        node = (self.modulesView.selection() or (None,))[0]
        moduleInfo = self.pluginConfig.get("modules", {}).get(node)
        if moduleInfo:
            self.selectedModule = node
            name = moduleInfo["name"]
            self.moduleNameLabel.config(text=name)
            self.moduleAuthorHdr.config(state=ACTIVE)
            self.moduleAuthorLabel.config(text=moduleInfo["author"])
            self.moduleDescrHdr.config(state=ACTIVE)
            self.moduleDescrLabel.config(text=moduleInfo["description"])
            self.moduleClassesHdr.config(state=ACTIVE)
            self.moduleClassesLabel.config(text=', '.join(moduleInfo["classMethods"]))
            self.moduleUrlHdr.config(state=ACTIVE)
            self.moduleUrlLabel.config(text=moduleInfo["moduleURL"])
            self.moduleDateHdr.config(state=ACTIVE)
            self.moduleDateLabel.config(text=moduleInfo["fileDate"] + " " +
                    (_("(an update is available)") if name in self.modulesWithNewerFileDates else ""))
            self.moduleLicenseHdr.config(state=ACTIVE)
            self.moduleLicenseLabel.config(text=moduleInfo["license"])
            self.moduleEnableButton.config(state=ACTIVE,
                                           text={"enabled":self.DISABLE,
                                                 "disabled":self.ENABLE}[moduleInfo["status"]])
            self.moduleReloadButton.config(state=ACTIVE)
            self.moduleRemoveButton.config(state=ACTIVE)
        else:
            self.selectedModule = None
            self.moduleNameLabel.config(text="")
            self.moduleAuthorHdr.config(state=DISABLED)
            self.moduleAuthorLabel.config(text="")
            self.moduleDescrHdr.config(state=DISABLED)
            self.moduleDescrLabel.config(text="")
            self.moduleClassesHdr.config(state=DISABLED)
            self.moduleClassesLabel.config(text="")
            self.moduleUrlHdr.config(state=DISABLED)
            self.moduleUrlLabel.config(text="")
            self.moduleDateHdr.config(state=DISABLED)
            self.moduleDateLabel.config(text="")
            self.moduleLicenseHdr.config(state=DISABLED)
            self.moduleLicenseLabel.config(text="")
            self.moduleEnableButton.config(state=DISABLED, text=self.ENABLE)
            self.moduleReloadButton.config(state=DISABLED)
            self.moduleRemoveButton.config(state=DISABLED)
        
    def findLocally(self):
        filename = self.cntlr.uiFileDialog("open",
                                           owner=self,
                                           title=_("Choose plug-in module file"),
                                           initialdir=self.cntlr.config.setdefault("pluginOpenDir","."),
                                           filetypes=[(_("Python files"), "*.py")],
                                           defaultextension=".py")
        if filename:
            self.cntlr.config["pluginOpenDir"] = os.path.dirname(filename)
            moduleInfo = PluginManager.moduleModuleInfo(filename)
            self.loadFoundModuleInfo(moduleInfo, filename)
                

    def findOnWeb(self):
        url = DialogURL.askURL(self)
        if url:  # url is the in-cache or local file
            moduleInfo = PluginManager.moduleModuleInfo(url)
            self.cntlr.showStatus("") # clear web loading status
            self.loadFoundModuleInfo(moduleInfo, url)
                
    def loadFoundModuleInfo(self, moduleInfo, url):
        if moduleInfo and moduleInfo.get("name"):
            self.addPluginConfigModuleInfo(moduleInfo)
            self.loadTreeViews()
        else:
            messagebox.showwarning(_("Module is not a plug-in"),
                                   _("File does not contain a python program with an appropriate __pluginInfo__ declaration: \n\n{0}")
                                   .format(url),
                                   parent=self)
            
    def removePluginConfigModuleInfo(self, name):
        moduleInfo = self.pluginConfig["modules"].get(name)
        if moduleInfo:
            for classMethod in moduleInfo["classMethods"]:
                classMethods = self.pluginConfig["classes"].get(classMethod)
                if classMethods and name in classMethods:
                    classMethods.remove(name)
                    if not classMethods: # list has become unused
                        del self.pluginConfig["classes"][classMethod] # remove class
                    if classMethod.startswith("CntlrWinMain.Menu"):
                        self.uiClassMethodsChanged = True  # may require reloading UI
            del self.pluginConfig["modules"][name]
            self.pluginConfigChanged = True

    def addPluginConfigModuleInfo(self, moduleInfo):
        name = moduleInfo["name"]
        self.removePluginConfigModuleInfo(name)  # remove any prior entry for this module
        self.modulesWithNewerFileDates.discard(name) # no longer has an update available
        self.pluginConfig["modules"][name] = moduleInfo
        # add classes
        for classMethod in moduleInfo["classMethods"]:
            classMethods = self.pluginConfig["classes"].setdefault(classMethod, [])
            if name not in classMethods:
                classMethods.append(name)
            if classMethod.startswith("CntlrWinMain.Menu"):
                self.uiClassMethodsChanged = True  # may require reloading UI
        self.pluginConfigChanged = True

    def moduleEnable(self):
        if self.selectedModule in self.pluginConfig["modules"]:
            moduleInfo = self.pluginConfig["modules"][self.selectedModule]
            if self.moduleEnableButton['text'] == self.ENABLE:
                moduleInfo["status"] = "enabled"
                self.moduleEnableButton['text'] = self.DISABLE
            elif self.moduleEnableButton['text'] == self.DISABLE:
                moduleInfo["status"] = "disabled"
                self.moduleEnableButton['text'] = self.ENABLE
            self.pluginConfigChanged = True
            self.loadTreeViews()
            
    def moduleReload(self):
        if self.selectedModule in self.pluginConfig["modules"]:
            url = self.pluginConfig["modules"][self.selectedModule].get("moduleURL")
            if url:
                moduleInfo = PluginManager.moduleModuleInfo(url, reload=True)
                if moduleInfo:
                    self.addPluginConfigModuleInfo(moduleInfo)
                    self.loadTreeViews()
                    self.cntlr.showStatus(_("{0} reloaded").format(moduleInfo.get("name")), clearAfter=5000)
                else:
                    messagebox.showwarning(_("Module error"),
                                           _("File or module cannot be reloaded: \n\n{0}")
                                           .format(url),
                                           parent=self)

    def moduleRemove(self):
        if self.selectedModule in self.pluginConfig["modules"]:
            self.removePluginConfigModuleInfo(self.selectedModule)
            self.pluginConfigChanged = True
            self.loadTreeViews()
Exemple #50
0
class Gui(tk.Frame):
    """Main program graphical user interface"""
    def __init__(self, master=None, *args, **kwargs):
        super().__init__(master, *args, **kwargs)
        self.build_menu(), self.build()

    def build_menu(self):
        """Initializes and builds program menu bar"""
        self.top = tk.Menu(self)

        # create file menu
        self.file = tk.Menu(self.top, tearoff=False)
        self.file.add_command(label='Search',
                              accelerator='Ctrl+S',
                              command=self.search,
                              compound=tk.LEFT,
                              underline=0)
        self.file.add_separator()
        self.file.add_command(label='Exit',
                              command=self.quit_program,
                              underline=0)
        self.top.add_cascade(label='File', menu=self.file, underline=0)

        # commands: view help, about
        self.info = tk.Menu(self.top, tearoff=False)
        self.info.add_command(label='About ...',
                              command=self.view_credits,
                              compound=tk.LEFT,
                              underline=0)
        self.top.add_cascade(label='?', menu=self.info, underline=0)

    def build(self):
        """Builds main program interface"""

        # search frame
        f1 = tk.Frame()
        f1.grid(row=0, column=0)
        group = tk.LabelFrame(f1, text="Search", padx=5, pady=5, fg='brown')
        group.pack(side="top",
                   expand='yes',
                   fill='x',
                   padx=2,
                   pady=2,
                   anchor='n')
        self.entry_main = tk.Entry(group, width=73)
        self.entry_main.grid(sticky='ne')

        # results frame
        f2 = tk.Frame()
        f2.grid(row=1, column=0)
        group_2 = tk.LabelFrame(f2, text="Results", padx=5, pady=5, fg='brown')
        group_2.pack(side="top", expand='yes', fill='both', padx=2, pady=2)
        self.status = tk.Label(f2, text='ready', font=('verdana', 6, 'normal'))
        self.status.pack(anchor='se')
        self.treeview = Treeview(group_2,
                                 column=('A', 'B'),
                                 selectmode='extended',
                                 height=5)
        self.treeview.grid(row=0, column=0, sticky='w')
        self.treeview.column("#0", stretch=tk.NO, width=200)
        self.treeview.heading("#0", text='target')
        self.treeview.column("A", width=150, anchor='center')
        self.treeview.heading("A", text='technology')
        self.treeview.column("B", width=70)
        self.treeview.heading("B", text="version")
        self.sbar = tk.Scrollbar(group_2)
        self.treeview.config(yscrollcommand=self.sbar.set)
        self.sbar.config(command=self.treeview.yview)
        self.sbar.grid(column=1, row=0, rowspan=1, pady=0, sticky='ens')

        # key shortcut bindings
        self.entry_main.bind('<Return>', self.search)
        self.entry_main.bind('<Double-1>', self.search)
        self.bind_all('<Control-S>', self.search)
        self.bind_all('<Control-s>', self.search)

    def search(self, event=None):
        """Triggers a threaded technology detection scan"""
        url = self.entry_main.get()
        self.status['text'] = 'scanning...'
        Thread(target=self.scan_target, args=(url, )).start()

    def scan_target(self, url):
        """Function to detect technologies running on target and list them in
        gui treeview"""
        _id = None
        try:
            d = Detector().detect(url=url, timeout=5)
            for result in d:
                if d[result]:
                    ext = tldextract.extract(url)
                    _id = self.treeview.insert('',
                                               'end',
                                               text='.'.join(ext[:3]))
                    tech_type, software = d[result][0].get('type'), \
                                          d[result][0].get('app')
                    version = d[result][0].get('ver')

                    # assign to gui treeview
                    if not version:
                        version = 'None'
                    self.treeview.insert(_id,
                                         'end',
                                         text=tech_type,
                                         values=(software, version))
                    self.status['text'] = 'done'
                else:
                    self.status['text'] = 'No results found'

        except ValueError:
            self.status['text'] = "Invalid! Please input a full url"
        finally:
            del _id

    def view_credits(self):
        """ Opens a new window providing credits information."""

        # launch window and configure window settings
        self.win_credits = CreditsTool(self)
        self.win_credits.title('')
        self.win_credits.iconbitmap('wad/data/magnifier.ico')
        self.win_credits.geometry('+%d+%d' %
                                  (root.winfo_x() + 20, root.winfo_y() + 20))
        self.win_credits.resizable(width=False, height=False)

        # set focus on window
        self.win_credits.grab_set()
        self.win_credits.focus()

        # start mainloop
        self.win_credits.mainloop()

    @staticmethod
    def quit_program():
        """Quits main program window"""
        root.destroy()
Exemple #51
0
class MainFrame(Frame):
    """ Główna ramka aplikacji
    """

    def __init__(self, ui: SharedrawUI):
        Frame.__init__(self, ui.root)
        self.parent = ui.root
        self.ui = ui

        self.parent.title("Sharedraw [%s:%s, id: %s]" % (self.ui.peer_pool.ip, self.ui.peer_pool.port, own_id))
        self.drawer = Drawer(self.parent, WIDTH, HEIGHT, self.save)
        self.clients_table = Treeview(self.parent, columns=('R', 'G', 'from'))
        self.clients_table.heading('#0', text='Id')
        self.clients_table.heading('R', text='R')
        self.clients_table.heading('G', text='G')
        self.clients_table.heading('from', text='Otrzymano od:')
        self.clients_table.pack()
        self.token_owner_label = MutableLabel(self.parent, 'Posiadacz tokena: %s', lambda s: s if s else 'Nikt', None)
        self.token_owner_label.pack()
        self.locked_label = MutableLabel(self.parent, 'Tablica %s', lambda b: 'zablokowana' if b else 'odblokowana',
                                         False)
        self.locked_label.pack()
        # Przycisk czyszczenia
        self.clean_btn = self._create_button(text="Czyść", func=self.clean)
        # Przycisk podłączenia
        self.connect_btn = self._create_button(text="Podłącz", func=self.connect)
        # Przycisk żądania przejęcia na własność
        self.req_btn = self._create_button(text="Chcę przejąć tablicę", func=self._make_request)
        # Rezygnacja z posiadania blokady
        self.resign_btn = self._create_button(text='Zrezygnuj z blokady', func=self._resign)

    def _create_button(self, text: str, func):
        """ Tworzy nowy przycisk w bieżącej ramce
        :param text: tekst przycisku
        :param func: funkcja wywoływana po naciśnięciu
        :return: przycisk
        """
        btn = Button(self.parent, text=text, command=func)
        btn.pack()
        return btn

    def save(self):
        """ Wysyła komunikat o zmianie obrazka do innych klientów
        :return:
        """
        if self.drawer.changed_pxs:
            msg = PaintMessage(self.drawer.changed_pxs, self.drawer.color)
            self.ui.peer_pool.send(msg)
            # Reset listy punktów
            self.drawer.changed_pxs = []

    def clean(self):
        """ Czyści obrazek oraz wysyła komunikat o wyczyszczeniu
        :return:
        """
        self.drawer.clean_img()
        msg = CleanMessage(own_id)
        self.ui.peer_pool.send(msg)

    def _make_request(self):
        """ Żąda przejęcia tablicy na własność
        :return:
        """
        clients_info = self.ui.om.claim_ownership()
        self.update_clients_info(clients_info)

    def _resign(self):
        clients_info = self.ui.om.resign()
        self.update_clients_info(clients_info)

    def connect(self):
        """ Uruchamia okno dialogowe do podłączenia się z innym klientem
        :return:
        """
        d = ConnectDialog(self.ui)
        self.parent.wait_window(d.top)

    def update_clients_info(self, clients: ClientsTable):
        # Aktualizacja listy klientów
        for ch in self.clients_table.get_children():
            self.clients_table.delete(ch)
        for client in clients.clients:
            self.clients_table.insert('', 'end', text=client.id,
                                      values=(client.requested, client.granted, client.received_from_id))
        # Aktualizacja info o właścicielu tokena i blokadzie
        self.locked_label.update_text(clients.locked)
        self.token_owner_label.update_text(clients.token_owner)
        # Aktualizacja blokady
        has_token = clients.token_owner == own_id
        self.__set_lock_state(clients.locked, has_token)
        # Aktualizacja przycisków
        # jeśli zablokowaliśmy, to nie możemy tego zrobić drugi raz
        is_locker = (has_token and clients.locked)
        # tak samo jeśli już zażądaliśmy
        has_requested = clients.find_self().has_requested()
        self.__set_button_enabled(self.req_btn, not (is_locker or has_requested))
        # jeśli nie zablokowaliśmy, to nie możemy rezygnować
        self.__set_button_enabled(self.resign_btn, is_locker)
        # Możemy się podłączyć, tylko, jeśli nie jesteśmy do nikogo podłączeni
        self.__set_button_enabled(self.connect_btn, len(clients.clients) <= 1)
        # Przycisk czyść aktywny jeśli możemy rysować
        self.__set_button_enabled(self.clean_btn, has_token or not clients.locked)

    @staticmethod
    def __set_button_enabled(btn: Button, enabled: bool):
        btn.configure(state=(NORMAL if enabled else DISABLED))

    def __set_lock_state(self, locked: bool, has_token: bool):
        self.drawer.locked = locked and not has_token
        # Dodatkowo ustawiamy kolor tła, żeby było ładnie widać
        if locked:
            if has_token:
                color = '#66FF66'
            else:
                color = '#FF9999'
        else:
            color = '#FFFFFF'
        self.parent.configure(bg=color)
class DialogPluginManager(Toplevel):
    def __init__(self, mainWin, modulesWithNewerFileDates):
        super(DialogPluginManager, self).__init__(mainWin.parent)
        
        self.ENABLE = _("Enable")
        self.DISABLE = _("Disable")
        self.parent = mainWin.parent
        self.cntlr = mainWin
        
        # copy plugins for temporary display
        self.pluginConfig = PluginManager.pluginConfig
        self.pluginConfigChanged = False
        self.uiClassMethodsChanged = False
        self.modelClassesChanged = False
        self.disclosureSystemTypesChanged = False
        self.hostSystemFeaturesChanged = False
        self.modulesWithNewerFileDates = modulesWithNewerFileDates
        
        parentGeometry = re.match("(\d+)x(\d+)[+]?([-]?\d+)[+]?([-]?\d+)", self.parent.geometry())
        dialogX = int(parentGeometry.group(3))
        dialogY = int(parentGeometry.group(4))

        self.title(_("Plug-in Manager"))
        frame = Frame(self)
        
        # left button frame
        buttonFrame = Frame(frame, width=40)
        buttonFrame.columnconfigure(0, weight=1)
        addLabel = Label(buttonFrame, text=_("Find plug-in modules:"), wraplength=60, justify="center")
        addLocalButton = Button(buttonFrame, text=_("Locally"), command=self.findLocally)
        ToolTip(addLocalButton, text=_("File chooser allows selecting python module files to add (or reload) plug-ins, from the local file system."), wraplength=240)
        addWebButton = Button(buttonFrame, text=_("On Web"), command=self.findOnWeb)
        ToolTip(addWebButton, text=_("Dialog to enter URL full path to load (or reload) plug-ins, from the web or local file system."), wraplength=240)
        addLabel.grid(row=0, column=0, pady=4)
        addLocalButton.grid(row=1, column=0, pady=4)
        addWebButton.grid(row=2, column=0, pady=4)
        buttonFrame.grid(row=0, column=0, rowspan=2, sticky=(N, S, W), padx=3, pady=3)
        
        # right tree frame (plugins already known to arelle)
        modulesFrame = Frame(frame, width=700)
        vScrollbar = Scrollbar(modulesFrame, orient=VERTICAL)
        hScrollbar = Scrollbar(modulesFrame, orient=HORIZONTAL)
        self.modulesView = Treeview(modulesFrame, xscrollcommand=hScrollbar.set, yscrollcommand=vScrollbar.set, height=7)
        self.modulesView.grid(row=0, column=0, sticky=(N, S, E, W))
        self.modulesView.bind('<<TreeviewSelect>>', self.moduleSelect)
        hScrollbar["command"] = self.modulesView.xview
        hScrollbar.grid(row=1, column=0, sticky=(E,W))
        vScrollbar["command"] = self.modulesView.yview
        vScrollbar.grid(row=0, column=1, sticky=(N,S))
        modulesFrame.columnconfigure(0, weight=1)
        modulesFrame.rowconfigure(0, weight=1)
        modulesFrame.grid(row=0, column=1, columnspan=4, sticky=(N, S, E, W), padx=3, pady=3)
        self.modulesView.focus_set()

        self.modulesView.column("#0", width=120, anchor="w")
        self.modulesView.heading("#0", text=_("Name"))
        self.modulesView["columns"] = ("author", "ver", "status", "date", "update", "descr", "license")
        self.modulesView.column("author", width=100, anchor="w", stretch=False)
        self.modulesView.heading("author", text=_("Author"))
        self.modulesView.column("ver", width=50, anchor="w", stretch=False)
        self.modulesView.heading("ver", text=_("Version"))
        self.modulesView.column("status", width=50, anchor="w", stretch=False)
        self.modulesView.heading("status", text=_("Status"))
        self.modulesView.column("date", width=70, anchor="w", stretch=False)
        self.modulesView.heading("date", text=_("File Date"))
        self.modulesView.column("update", width=50, anchor="w", stretch=False)
        self.modulesView.heading("update", text=_("Update"))
        self.modulesView.column("descr", width=200, anchor="w", stretch=False)
        self.modulesView.heading("descr", text=_("Description"))
        self.modulesView.column("license", width=70, anchor="w", stretch=False)
        self.modulesView.heading("license", text=_("License"))

        classesFrame = Frame(frame)
        vScrollbar = Scrollbar(classesFrame, orient=VERTICAL)
        hScrollbar = Scrollbar(classesFrame, orient=HORIZONTAL)
        self.classesView = Treeview(classesFrame, xscrollcommand=hScrollbar.set, yscrollcommand=vScrollbar.set, height=5)
        self.classesView.grid(row=0, column=0, sticky=(N, S, E, W))
        hScrollbar["command"] = self.classesView.xview
        hScrollbar.grid(row=1, column=0, sticky=(E,W))
        vScrollbar["command"] = self.classesView.yview
        vScrollbar.grid(row=0, column=1, sticky=(N,S))
        classesFrame.columnconfigure(0, weight=1)
        classesFrame.rowconfigure(0, weight=1)
        classesFrame.grid(row=1, column=1, columnspan=4, sticky=(N, S, E, W), padx=3, pady=3)
        self.classesView.focus_set()
        
        self.classesView.column("#0", width=200, anchor="w")
        self.classesView.heading("#0", text=_("Class"))
        self.classesView["columns"] = ("modules",)
        self.classesView.column("modules", width=500, anchor="w", stretch=False)
        self.classesView.heading("modules", text=_("Modules"))
        
        # bottom frame module info details
        moduleInfoFrame = Frame(frame, width=700)
        moduleInfoFrame.columnconfigure(1, weight=1)
        
        self.moduleNameLabel = Label(moduleInfoFrame, wraplength=600, justify="left", 
                                     font=font.Font(family='Helvetica', size=12, weight='bold'))
        self.moduleNameLabel.grid(row=0, column=0, columnspan=4, sticky=W)
        self.moduleAuthorHdr = Label(moduleInfoFrame, text=_("author:"), state=DISABLED)
        self.moduleAuthorHdr.grid(row=1, column=0, sticky=W)
        self.moduleAuthorLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleAuthorLabel.grid(row=1, column=1, columnspan=3, sticky=W)
        self.moduleDescrHdr = Label(moduleInfoFrame, text=_("description:"), state=DISABLED)
        self.moduleDescrHdr.grid(row=2, column=0, sticky=W)
        self.moduleDescrLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleDescrLabel.grid(row=2, column=1, columnspan=3, sticky=W)
        self.moduleClassesHdr = Label(moduleInfoFrame, text=_("classes:"), state=DISABLED)
        self.moduleClassesHdr.grid(row=3, column=0, sticky=W)
        self.moduleClassesLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleClassesLabel.grid(row=3, column=1, columnspan=3, sticky=W)
        ToolTip(self.moduleClassesLabel, text=_("List of classes that this plug-in handles."), wraplength=240)
        self.moduleUrlHdr = Label(moduleInfoFrame, text=_("URL:"), state=DISABLED)
        self.moduleUrlHdr.grid(row=4, column=0, sticky=W)
        self.moduleUrlLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleUrlLabel.grid(row=4, column=1, columnspan=3, sticky=W)
        ToolTip(self.moduleUrlLabel, text=_("URL of plug-in module (local file path or web loaded file)."), wraplength=240)
        self.moduleDateHdr = Label(moduleInfoFrame, text=_("date:"), state=DISABLED)
        self.moduleDateHdr.grid(row=5, column=0, sticky=W)
        self.moduleDateLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleDateLabel.grid(row=5, column=1, columnspan=3, sticky=W)
        ToolTip(self.moduleDateLabel, text=_("Date of currently loaded module file (with parenthetical node when an update is available)."), wraplength=240)
        self.moduleLicenseHdr = Label(moduleInfoFrame, text=_("license:"), state=DISABLED)
        self.moduleLicenseHdr.grid(row=6, column=0, sticky=W)
        self.moduleLicenseLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleLicenseLabel.grid(row=6, column=1, columnspan=3, sticky=W)
        self.moduleImportsHdr = Label(moduleInfoFrame, text=_("imports:"), state=DISABLED)
        self.moduleImportsHdr.grid(row=7, column=0, sticky=W)
        self.moduleImportsLabel = Label(moduleInfoFrame, wraplength=600, justify="left")
        self.moduleImportsLabel.grid(row=7, column=1, columnspan=3, sticky=W)
        self.moduleEnableButton = Button(moduleInfoFrame, text=self.ENABLE, state=DISABLED, command=self.moduleEnable)
        ToolTip(self.moduleEnableButton, text=_("Enable/disable plug in."), wraplength=240)
        self.moduleEnableButton.grid(row=8, column=1, sticky=E)
        self.moduleReloadButton = Button(moduleInfoFrame, text=_("Reload"), state=DISABLED, command=self.moduleReload)
        ToolTip(self.moduleReloadButton, text=_("Reload/update plug in."), wraplength=240)
        self.moduleReloadButton.grid(row=8, column=2, sticky=E)
        self.moduleRemoveButton = Button(moduleInfoFrame, text=_("Remove"), state=DISABLED, command=self.moduleRemove)
        ToolTip(self.moduleRemoveButton, text=_("Remove plug in from plug in table (does not erase the plug in's file)."), wraplength=240)
        self.moduleRemoveButton.grid(row=8, column=3, sticky=E)
        moduleInfoFrame.grid(row=2, column=0, columnspan=5, sticky=(N, S, E, W), padx=3, pady=3)
        moduleInfoFrame.config(borderwidth=4, relief="groove")
        
        okButton = Button(frame, text=_("Close"), command=self.ok)
        ToolTip(okButton, text=_("Accept and changes (if any) and close dialog."), wraplength=240)
        cancelButton = Button(frame, text=_("Cancel"), command=self.close)
        ToolTip(cancelButton, text=_("Cancel changes (if any) and close dialog."), wraplength=240)
        okButton.grid(row=3, column=3, sticky=(S,E), pady=3)
        cancelButton.grid(row=3, column=4, sticky=(S,E), pady=3, padx=3)
        
        enableDisableFrame = Frame(frame)
        enableDisableFrame.grid(row=3, column=1, sticky=(S,W), pady=3)
        enableAllButton = Button(enableDisableFrame, text=_("Enable All"), command=self.enableAll)
        ToolTip(enableAllButton, text=_("Enable all plug ins."), wraplength=240)
        disableAllButton = Button(enableDisableFrame, text=_("Disable All"), command=self.disableAll)
        ToolTip(disableAllButton, text=_("Disable all plug ins."), wraplength=240)
        enableAllButton.grid(row=1, column=1)
        disableAllButton.grid(row=1, column=2)
        
        self.loadTreeViews()

        self.geometry("+{0}+{1}".format(dialogX+50,dialogY+100))
        frame.grid(row=0, column=0, sticky=(N,S,E,W))
        frame.columnconfigure(0, weight=0)
        frame.columnconfigure(1, weight=1)
        frame.rowconfigure(0, weight=1)
        window = self.winfo_toplevel()
        window.columnconfigure(0, weight=1)
        window.rowconfigure(0, weight=1)
        
        self.bind("<Return>", self.ok)
        self.bind("<Escape>", self.close)
        
        self.protocol("WM_DELETE_WINDOW", self.close)
        self.grab_set()
        self.wait_window(self)
        
    def loadTreeViews(self):
        self.selectedModule = None

        # clear previous treeview entries
        for previousNode in self.modulesView.get_children(""): 
            self.modulesView.delete(previousNode)
            
        def loadSubtree(parentNode, moduleItems):
            for moduleItem in sorted(moduleItems, key=lambda item: item[0]):
                moduleInfo = moduleItem[1]
                if parentNode or not moduleInfo.get("isImported"):
                    nodeName = moduleItem[0]
                    if parentNode:
                        nodeName = parentNode + GROUPSEP + nodeName
                    name = moduleInfo.get("name", nodeName)
                    node = self.modulesView.insert(parentNode, "end", nodeName, text=name)
                    self.modulesView.set(node, "author", moduleInfo.get("author"))
                    self.modulesView.set(node, "ver", moduleInfo.get("version"))
                    self.modulesView.set(node, "status", moduleInfo.get("status"))
                    self.modulesView.set(node, "date", moduleInfo.get("fileDate"))
                    if name in self.modulesWithNewerFileDates:
                        self.modulesView.set(node, "update", _("available"))
                    self.modulesView.set(node, "descr", moduleInfo.get("description"))
                    self.modulesView.set(node, "license", moduleInfo.get("license"))
                    if moduleInfo.get("imports"):
                        loadSubtree(node, [(importModuleInfo["name"],importModuleInfo)
                                           for importModuleInfo in moduleInfo["imports"]])
            
        loadSubtree("", self.pluginConfig.get("modules", {}).items())
        
        # clear previous treeview entries
        for previousNode in self.classesView.get_children(""): 
            self.classesView.delete(previousNode)

        for i, classItem in enumerate(sorted(self.pluginConfig.get("classes", {}).items())):
            className, moduleList = classItem
            node = self.classesView.insert("", "end", className, text=className)
            self.classesView.set(node, "modules", ', '.join(moduleList))
            
        self.moduleSelect()  # clear out prior selection

    def ok(self, event=None):
        if self.pluginConfigChanged:
            PluginManager.pluginConfig = self.pluginConfig
            PluginManager.pluginConfigChanged = True
            PluginManager.reset()  # force reloading of modules
        if self.uiClassMethodsChanged or self.modelClassesChanged or self.disclosureSystemTypesChanged or self.hostSystemFeaturesChanged:  # may require reloading UI
            affectedItems = ""
            if self.uiClassMethodsChanged:
                affectedItems += _("menus of the user interface")
            if self.modelClassesChanged:
                if affectedItems:
                    affectedItems += _(" and ")
                affectedItems += _("model objects of the processor")
            if self.disclosureSystemTypesChanged:
                if affectedItems:
                    affectedItems += _(" and ")
                affectedItems += _("disclosure system types")
            if self.hostSystemFeaturesChanged:
                if affectedItems:
                    affectedItems += _(" and ")
                affectedItems += _("host system features")
            if messagebox.askyesno(_("User interface plug-in change"),
                                   _("A change in plug-in class methods may have affected {0}.  " 
                                     "Please restart Arelle to due to these changes.  \n\n"
                                     "Should Arelle restart itself now "
                                     "(if there are any unsaved changes they would be lost!)?"
                                     ).format(affectedItems),
                                   parent=self):
                self.cntlr.uiThreadQueue.put((self.cntlr.quit, [None, True]))
        self.close()
        
    def close(self, event=None):
        self.parent.focus_set()
        self.destroy()
                
    def moduleSelect(self, *args):
        node = (self.modulesView.selection() or (None,))[0]
        if node:
            node = node.rpartition(GROUPSEP)[2] # drop leading path names for module name
        moduleInfo = self.pluginConfig.get("modules", {}).get(node)
        if moduleInfo:
            self.selectedModule = node
            name = moduleInfo["name"]
            self.moduleNameLabel.config(text=name)
            self.moduleAuthorHdr.config(state=ACTIVE)
            self.moduleAuthorLabel.config(text=moduleInfo["author"])
            self.moduleDescrHdr.config(state=ACTIVE)
            self.moduleDescrLabel.config(text=moduleInfo["description"])
            self.moduleClassesHdr.config(state=ACTIVE)
            self.moduleClassesLabel.config(text=', '.join(moduleInfo["classMethods"]))
            self.moduleUrlHdr.config(state=ACTIVE)
            self.moduleUrlLabel.config(text=moduleInfo["moduleURL"])
            self.moduleDateHdr.config(state=ACTIVE)
            self.moduleDateLabel.config(text=moduleInfo["fileDate"] + " " +
                    (_("(an update is available)") if name in self.modulesWithNewerFileDates else ""))
            self.moduleLicenseHdr.config(state=ACTIVE)
            self.moduleLicenseLabel.config(text=moduleInfo["license"])
            if moduleInfo.get("imports"):
                self.moduleImportsHdr.config(state=ACTIVE)
                _text = ", ".join(mi["name"] for mi in moduleInfo["imports"][:3])
                if len(moduleInfo["imports"]) >= 3:
                    _text += ", ..."
                self.moduleImportsLabel.config(text=_text)
            _buttonState = DISABLED if moduleInfo.get("isImported") else ACTIVE
            self.moduleEnableButton.config(state=_buttonState,
                                           text={"enabled":self.DISABLE,
                                                 "disabled":self.ENABLE}[moduleInfo["status"]])
            self.moduleReloadButton.config(state=_buttonState)
            self.moduleRemoveButton.config(state=_buttonState)
        else:
            self.selectedModule = None
            self.moduleNameLabel.config(text="")
            self.moduleAuthorHdr.config(state=DISABLED)
            self.moduleAuthorLabel.config(text="")
            self.moduleDescrHdr.config(state=DISABLED)
            self.moduleDescrLabel.config(text="")
            self.moduleClassesHdr.config(state=DISABLED)
            self.moduleClassesLabel.config(text="")
            self.moduleUrlHdr.config(state=DISABLED)
            self.moduleUrlLabel.config(text="")
            self.moduleDateHdr.config(state=DISABLED)
            self.moduleDateLabel.config(text="")
            self.moduleLicenseHdr.config(state=DISABLED)
            self.moduleLicenseLabel.config(text="")
            self.moduleImportsHdr.config(state=DISABLED)
            self.moduleImportsLabel.config(text="")
            self.moduleEnableButton.config(state=DISABLED, text=self.ENABLE)
            self.moduleReloadButton.config(state=DISABLED)
            self.moduleRemoveButton.config(state=DISABLED)
        
    def findLocally(self):
        initialdir = self.cntlr.pluginDir # default plugin directory
        if not self.cntlr.isMac: # can't navigate within app easily, always start in default directory
            initialdir = self.cntlr.config.setdefault("pluginOpenDir", initialdir)
        filename = self.cntlr.uiFileDialog("open",
                                           parent=self,
                                           title=_("Choose plug-in module file"),
                                           initialdir=initialdir,
                                           filetypes=[(_("Python files"), "*.py")],
                                           defaultextension=".py")
        if filename:
            # check if a package is selected (any file in a directory containing an __init__.py
            #if (os.path.basename(filename) == "__init__.py" and os.path.isdir(os.path.dirname(filename)) and
            #    os.path.isfile(filename)):
            #    filename = os.path.dirname(filename) # refer to the package instead
            self.cntlr.config["pluginOpenDir"] = os.path.dirname(filename)
            moduleInfo = PluginManager.moduleModuleInfo(filename)
            self.loadFoundModuleInfo(moduleInfo, filename)
                

    def findOnWeb(self):
        url = DialogURL.askURL(self)
        if url:  # url is the in-cache or local file
            moduleInfo = PluginManager.moduleModuleInfo(url)
            self.cntlr.showStatus("") # clear web loading status
            self.loadFoundModuleInfo(moduleInfo, url)
                
    def loadFoundModuleInfo(self, moduleInfo, url):
        if moduleInfo and moduleInfo.get("name"):
            self.addPluginConfigModuleInfo(moduleInfo)
            self.loadTreeViews()
        else:
            messagebox.showwarning(_("Module is not itself a plug-in or in a directory with package __init__.py plug-in.  "),
                                   _("File does not itself contain a python program with an appropriate __pluginInfo__ declaration: \n\n{0}")
                                   .format(url),
                                   parent=self)
        
    def checkIfImported(self, moduleInfo):
        if moduleInfo.get("isImported"):
            messagebox.showwarning(_("Plug-in is imported by a parent plug-in.  "),
                                   _("Plug-in has a parent, please request operation on the parent: \n\n{0}")
                                   .format(moduleInfo.get("name")),
                                   parent=self)
            return True
        return False
    
    def removePluginConfigModuleInfo(self, name):
        moduleInfo = self.pluginConfig["modules"].get(name)
        if moduleInfo:
            if self.checkIfImported(moduleInfo):
                return;
            def _removePluginConfigModuleInfo(moduleInfo):
                _name = moduleInfo.get("name")
                if _name:
                    for classMethod in moduleInfo["classMethods"]:
                        classMethods = self.pluginConfig["classes"].get(classMethod)
                        if classMethods and _name in classMethods:
                            classMethods.remove(_name)
                            if not classMethods: # list has become unused
                                del self.pluginConfig["classes"][classMethod] # remove class
                            if classMethod.startswith("CntlrWinMain.Menu"):
                                self.uiClassMethodsChanged = True  # may require reloading UI
                            elif classMethod == "ModelObjectFactory.ElementSubstitutionClasses":
                                self.modelClassesChanged = True # model object factor classes changed
                            elif classMethod == "DisclosureSystem.Types":
                                self.disclosureSystemTypesChanged = True # disclosure system types changed
                            elif classMethod.startswith("Proxy."):
                                self.hostSystemFeaturesChanged = True # system features (e.g., proxy) changed
                    for importModuleInfo in moduleInfo.get("imports", EMPTYLIST):
                        _removePluginConfigModuleInfo(importModuleInfo)
                    self.pluginConfig["modules"].pop(_name, None)
            _removePluginConfigModuleInfo(moduleInfo)
            self.pluginConfigChanged = True

    def addPluginConfigModuleInfo(self, moduleInfo):
        if self.checkIfImported(moduleInfo):
            return;
        name = moduleInfo.get("name")
        self.removePluginConfigModuleInfo(name)  # remove any prior entry for this module
        def _addPlugin(moduleInfo):
            _name = moduleInfo.get("name")
            if _name:
                self.modulesWithNewerFileDates.discard(_name) # no longer has an update available
                self.pluginConfig["modules"][_name] = moduleInfo
                # add classes
                for classMethod in moduleInfo["classMethods"]:
                    classMethods = self.pluginConfig["classes"].setdefault(classMethod, [])
                    if name not in classMethods:
                        classMethods.append(_name)
                    if classMethod.startswith("CntlrWinMain.Menu"):
                        self.uiClassMethodsChanged = True  # may require reloading UI
                    elif classMethod == "ModelObjectFactory.ElementSubstitutionClasses":
                        self.modelClassesChanged = True # model object factor classes changed
                    elif classMethod == "DisclosureSystem.Types":
                        self.disclosureSystemTypesChanged = True # disclosure system types changed
                    elif classMethod.startswith("Proxy."):
                        self.hostSystemFeaturesChanged = True # system features (e.g., proxy) changed
            for importModuleInfo in moduleInfo.get("imports", EMPTYLIST):
                _addPlugin(importModuleInfo)
        _addPlugin(moduleInfo)
        self.pluginConfigChanged = True

    def moduleEnable(self):
        if self.selectedModule in self.pluginConfig["modules"]:
            moduleInfo = self.pluginConfig["modules"][self.selectedModule]
            if self.checkIfImported(moduleInfo):
                return;
            def _moduleEnable(moduleInfo):
                if self.moduleEnableButton['text'] == self.ENABLE:
                    moduleInfo["status"] = "enabled"
                elif self.moduleEnableButton['text'] == self.DISABLE:
                    moduleInfo["status"] = "disabled"
                for importModuleInfo in moduleInfo.get("imports", EMPTYLIST):
                    _moduleEnable(importModuleInfo)
            _moduleEnable(moduleInfo)
            if self.moduleEnableButton['text'] == self.ENABLE:
                self.moduleEnableButton['text'] = self.DISABLE
            elif self.moduleEnableButton['text'] == self.DISABLE:
                self.moduleEnableButton['text'] = self.ENABLE
            self.pluginConfigChanged = True
            self.loadTreeViews()
            
    def moduleReload(self):
        if self.selectedModule in self.pluginConfig["modules"]:
            url = self.pluginConfig["modules"][self.selectedModule].get("moduleURL")
            if url:
                moduleInfo = PluginManager.moduleModuleInfo(url, reload=True)
                if moduleInfo:
                    if self.checkIfImported(moduleInfo):
                        return;
                    self.addPluginConfigModuleInfo(moduleInfo)
                    self.loadTreeViews()
                    self.cntlr.showStatus(_("{0} reloaded").format(moduleInfo["name"]), clearAfter=5000)
                else:
                    messagebox.showwarning(_("Module error"),
                                           _("File or module cannot be reloaded: \n\n{0}")
                                           .format(url),
                                           parent=self)

    def moduleRemove(self):
        if self.selectedModule in self.pluginConfig["modules"]:
            self.removePluginConfigModuleInfo(self.selectedModule)
            self.pluginConfigChanged = True
            self.loadTreeViews()
                    
    def enableAll(self):
        self.enableDisableAll(True)
                    
    def disableAll(self):
        self.enableDisableAll(False)
                    
    def enableDisableAll(self, doEnable):
        for module in self.pluginConfig["modules"]:
            if not module.get("isImported"):
                moduleInfo = self.pluginConfig["modules"][module]
                def _enableDisableAll(moduleInfo):
                    if doEnable:
                        moduleInfo["status"] = "enabled"
                    else:
                        moduleInfo["status"] = "disabled"
                    for importModuleInfo in moduleInfo.get("imports", EMPTYLIST):
                        _enableDisableAll(importModuleInfo)
                _enableDisableAll(moduleInfo)
                if doEnable:
                    self.moduleEnableButton['text'] = self.DISABLE
                else:
                    self.moduleEnableButton['text'] = self.ENABLE
        self.pluginConfigChanged = True
        self.loadTreeViews()