Пример #1
0
class SelectGame(tkSimpleDialog.Dialog, object):
    """Server settings window class."""

    def __init__(self, *args, **kwargs):
        """Initiates SelectGame instance with additional attributes.

        :param args: positional arguments - positional arguments passed to parent __init__ method
        :param kwargs: keyword arguments - keyword arguments passed to parent __init__ method
        """
        self.select_game, self.num_players, self.num_turns = None, None, None
        super(SelectGame, self).__init__(*args, **kwargs)

    def body(self, master):
        """Creates select game window.

        :param master: instance - master widget instance
        :return: Entry instance
        """
        self.resizable(False, False)
        Label(master, text='Type in new game title or select existing one').grid(row=0, columnspan=2)
        Label(master, text='Select game:').grid(row=1, sticky='W')
        Label(master, text='Number of players:').grid(row=2, sticky='W')
        Label(master, text='Game duration:').grid(row=3, sticky='W')
        self.select_game = Combobox(master)
        self.select_game.bind('<Button-1>', self.refresh_games)
        self.select_game.grid(row=1, column=1, sticky='W')
        self.num_players = Entry(master)
        self.num_players.insert(END, self.parent.num_players if self.parent.num_players else '')
        self.num_players.grid(row=2, column=1, sticky='W')
        self.num_turns = Entry(master)
        self.num_turns.insert(END, self.parent.num_turns if self.parent.num_turns else '')
        self.num_turns.grid(row=3, column=1, sticky='W')
        return self.select_game

    def apply(self):
        """Assigns entered values to parent game and num_players attributes."""
        self.parent.game = self.select_game.get() if self.select_game.get() != '' else None
        if self.parent.game not in self.parent.available_games:
            self.parent.num_players = int(self.num_players.get()) if self.num_players.get().isdigit() else None
            self.parent.num_turns = int(self.num_turns.get()) if self.num_turns.get().isdigit() else None

    def refresh_games(self, _):
        """Refreshes games list."""
        self.select_game.configure(values=self.parent.available_games)
Пример #2
0
class SolinetteGUI(Tk):
    def __init__(self):
        # basics settings
        Tk.__init__(self)               # constructor of parent graphic class
        self.title(u'Solinette: geolocalizar direcciones en Lima y Callo')
        self.iconbitmap('icone_Solinette.ico')
        self.resizable(width = False, height = False)
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

        # Frames
        self.FrPath = LabelFrame(self, name ='primero',
                            text = u'1: las direcciones para geolocalizar',
                            padx = 5, pady = 5)
        self.FrAttr = LabelFrame(self, name ='segundo',
                            text = u'2: columnas indispensables',
                            padx = 5, pady = 5)
        self.FrConn = LabelFrame(self, name ='tercero',
                            text = u'3: parámetros de conexión a la base de datos',
                            padx=5, pady=5)

        # Variables
        inutile = ['Esperando que se elige el archivo Excel']
        self.typcols = []
        self.host = StringVar()
        self.port = IntVar()
        self.dbnb = StringVar()
        self.usua = StringVar()
        self.mdpa = StringVar()
        self.ok = 0
        self.dico_cols = OD()
        self.dico_vals = OD()
        self.dico_param = {}

            ## Frame 1
        # target folder
        labtarg = Label(self.FrPath, text = u'Archivo Excel (.xls): ')
        self.target = Entry(self.FrPath, width = 35)
        self.browsetarg = Button(self.FrPath,
                                 text = 'Explorar',
                                 command = self.setpathtarg)

        # widgets placement
        labtarg.grid(row = 1, column = 1, columnspan = 1, sticky = N+S+W+E, padx = 2, pady = 2)
        self.target.grid(row = 1, column = 2, columnspan = 1, sticky = N+S+W+E, padx = 2, pady = 2)
        self.browsetarg.grid(row = 1, column = 3, columnspan = 1, sticky = N+S+W+E, padx = 2, pady = 2)

            ## Frame 2
        # Drop-down lists of columns
        labdir = Label(self.FrAttr, text = u'Columna dirección: ')
        self.ddl_dir = Combobox(self.FrAttr, values = inutile)
        labdis = Label(self.FrAttr, text = u'Columna distrito: ')
        self.ddl_dis = Combobox(self.FrAttr, values = inutile)

        # nombre de la tabla en PostgreSQL
        labtabl = Label(self.FrAttr, text = u'Nombre de la tabla: ')
        self.tabl = Entry(self.FrAttr, width = 35)

        # widgets placement
        labdir.grid(row = 1, column = 1, sticky = N+S+W, padx = 2, pady = 2)
        self.ddl_dir.grid(row = 1, column = 2, sticky = N+S+W+E, padx = 2, pady = 2)
        labdis.grid(row = 2, column = 1, sticky = N+S+W, padx = 2, pady = 2)
        self.ddl_dis.grid(row = 2, column = 2, sticky = N+S+W+E, padx = 2, pady = 2)
        labtabl.grid(row = 3, column = 1, sticky = N+S+W, padx = 2, pady = 2)
        self.tabl.grid(row = 3, column = 2, sticky = N+S+W+E, padx = 2, pady = 2)

            ## Frame 3

        # Etiquetas
        Label(self.FrConn, text = u'Host: ').grid(row = 1, column = 1,
                                                  padx = 2, pady = 2,
                                                  sticky = N+S+W)
        Label(self.FrConn, text = u'Puerto: ').grid(row = 2, column = 1,
                                             padx = 2, pady = 2,
                                             sticky = N+S+W)
        Label(self.FrConn, text = u'Base de datos: ').grid(row = 3,
                                                    column = 1,
                                                    padx = 2,
                                                    pady = 2,
                                                    sticky = N+S+W)
        Label(self.FrConn, text = u'Usuario: ').grid(row = 4,
                                              column = 1,
                                              padx = 2,
                                              pady = 2,
                                              sticky = N+S+W)
        Label(self.FrConn, text = u'Contraseña: ').grid(row = 5,
                                                 column = 1,
                                                 padx = 2,
                                                 pady = 2,
                                                 sticky = N+S+W)

        # Formulario
        self.H = Entry(self.FrConn, textvariable = self.host)
        self.P = Entry(self.FrConn, textvariable = self.port)
        self.D = Entry(self.FrConn, textvariable = self.dbnb)
        self.U = Entry(self.FrConn, textvariable = self.usua)
        self.M = Entry(self.FrConn, textvariable = self.mdpa, show='*')
        # pre relleno
        self.host.set('localhost')
        self.port.set('5432')
        self.usua.set('postgres')
        self.mdpa.set('')
        self.dbnb.set('solinette')

        # widgets placement
        self.H.grid(row = 1, column = 2, padx = 3, pady = 5, sticky = N+S+W+E)
        self.P.grid(row = 2, column = 2, padx = 3, pady = 5, sticky = N+S+W+E)
        self.D.grid(row = 3, column = 2, padx = 3, pady = 5, sticky = N+S+W+E)
        self.U.grid(row = 4, column = 2, padx = 3, pady = 5, sticky = N+S+W+E)
        self.M.grid(row = 5, column = 2, padx = 3, pady = 5, sticky = N+S+W+E)


            ## Global frame
        # Hola
        Label(self, text = '¡Hola! ' + env.get(u'USERNAME')).grid(row = 0, column = 0,
                                                 columnspan = 2, sticky = W+E,
                                                 padx = 2, pady = 5)
        # Imagen
        self.icone = PhotoImage(file = r'sources/logo_Solinette.GIF')
        Label(self, borderwidth = 2, relief = 'ridge',
                                     image = self.icone).grid(row = 1,
                                                              rowspan = 4,
                                                              column = 0,
                                                              padx = 1,
                                                              pady = 1,
                                                              sticky = W)

        # Basic buttons
        self.val = Button(self, text = u'Probar la conexión',
                                relief= 'raised',
                                command = self.process,
                                state = DISABLED)
        can = Button(self, text = 'Cancel (quit)',
                                relief= 'groove',
                                command = self.quit)

        # widgets placement
        self.FrPath.grid(row = 2, column = 1, sticky = N+S+W+E, padx = 2, pady = 2)
        self.val.grid(row = 5, column = 1, columnspan = 2,
                            sticky = N+S+W+E, padx = 2, pady = 5)
        can.grid(row = 5, column = 0, sticky = N+S+W+E, padx = 2, pady = 5)

    def setpathtarg(self):
        """ ...browse and insert the path of target folder """
        self.xls = askopenfilename(parent = self,
                                   title = u'Seleccionar el archivo Excel',
                                   filetypes = (("Archivos Excel (2003)", "*.xls"),
                                                ("All files", "*.*")),
                                   initialdir = '../sources')

        if path.splitext(self.xls)[1] == '.xls':
            hoy = '_' + strftime('%y%m%d', localtime())
            self.target.insert(0, self.xls)
            self.licolumns()
            self.browsetarg.config(state=DISABLED)
            self.target.config(state=DISABLED)
            self.FrAttr.grid(row = 3, column = 1, sticky = N+S+W+E, padx = 2, pady = 2)
            self.FrConn.grid(row = 4, column = 1, sticky = N+S+W+E, padx = 2, pady = 2)
            self.tabl.insert(0, path.basename(self.xls).split('.')[0] + hoy)
            self.val.config(state = ACTIVE)
        # end of function
        return self.xls

    def licolumns(self):
        u""" litsing columns names and types from Excel file """
        book = xlrd.open_workbook(self.target.get())   # lectura del archivo
        if book.nsheets > 1:
            print book.sheets()
        ish = 0
        sheet = book.sheet_by_index(ish)    # ouverture de la feuille 1
        # names of columns (first row/line)
        cols = sheet.row_values(0)
        self.ddl_dir['values'] = cols
        self.ddl_dis['values'] = cols
        self.ddl_dir.current(1)
        self.ddl_dis.current(2)
        # types of columns
        self.typcols = list(sheet.row_types(1))
        # add universal ID to list of columns
        self.dico_cols['SOL_IDU'] = 9
        # loop on names and types of columns
        for i in range(len(cols)):
            self.dico_cols[cols[i]] = self.typcols[i]
        # End of function
        return book, self.typcols, self.dico_cols, self.ddl_dir, self.ddl_dis

    def check_campos(self):
        u""" Verifica que los campos del formulario son bien rellenos """
        # conteo y mensaje de los errores
        err = 0
        msj = u'Rellenar todos los campos'
        # checkeo de los campos vacios
        if self.host.get() == u'':
            self.H.configure(background = 'red')
            err = err +1
        if self.port.get() == 0:
            self.P.configure(background = 'red')
            err = err +1
        if self.dbnb.get() == u'':
            self.D.configure(background = 'red')
            err = err +1
        if self.usua.get() == u'':
            self.U.configure(background = 'red')
            err = err +1
        if self.mdpa.get() == u'':
            self.M.configure(background = 'red')
            err = err +1
        if self.tabl.get() == u'':
            self.tabl.configure(background = 'red')
            err = err +1
        if self.ddl_dir.get() == u'':
            self.ddl_dir.configure(background = 'red')
            err = err +1
        if self.ddl_dis.get() == u'':
            self.ddl_dis.configure(background = 'red')
            err = err +1
        # se colunas direcciones y distrito son diferentes
        if self.ddl_dir.get() == self.ddl_dis.get():
            msj = msj + u'\nLas dos columnas no deben ser iguales'
            err = err +1

        # Acción según si hay error(es) o no
        if err != 0:
            showerror(title = u'Error: campo(s) vacío(s)',
                      message = msj)
        # End of function
        return err

    def testconnexion(self):
        u""" testing connection settings """
        try:
            conn = pg.connect(host = self.host.get(), dbname = self.dbnb.get(),
                              port = self.port.get(), user = self.usua.get(),
                              password = self.mdpa.get())
            curs = conn.cursor()
            # check PostgreSQL and PostGIS versions
            try:
                curs.execute('SELECT version()')
                ver = curs.fetchone()
                print ver
            except DatabaseError, e:
                showerror(title = u'Prueba de conexión ',
                message = 'Prueba de conexión fracasó. Mensaje de error:\n' + str(e))
                return
            # check if destination table already exists
            query = "select table_name from information_schema.tables where 'sql_identifier' LIKE 'public'" #% (self.tabl.get())
            curs.execute(query)
            li_tablas = curs.fetchall()
            print 'elle existe déjà connard : ', li_tablas
            # información al usuario
            self.val.config(text='¡D A L E!')
            showinfo(title = u'Prueba de conexión ',
                     message = u'Prueba de conexión terminó con éxito')
            self.ok = 1
            # clausura de la conexión
            conn.close()

        except pg.OperationalError, e:
            showerror(title = u'Prueba de conexión ',
                      message = 'Prueba de conexión fracasó. Mensaje de error:\n' + str(e))
            return
Пример #3
0
class MainFrame(Frame):
    def __init__(self,parent,stdoutq):
        Frame.__init__(self,parent)

        self.parent=parent
        self.width=700
        self.height=400
        self.title='Menotexport v1.0'
        self.stdoutq=stdoutq

        self.initUI()

        self.hasdb=False
        self.hasout=False
        self.hasaction=False
        self.exit=False

        self.path_frame=self.addPathFrame()
        self.action_frame=self.addActionFrame()
        self.message_frame=self.addMessageFrame()
        self.printStr()

        self.stateq=Queue.Queue()
        #self.workproc=Pool(1)




    def centerWindow(self):
        sw=self.parent.winfo_screenwidth()
        sh=self.parent.winfo_screenheight()
        x=(sw-self.width)/2
        y=(sh-self.height)/2
        self.parent.geometry('%dx%d+%d+%d' \
                %(self.width,self.height,x,y))


    def initUI(self):
        self.parent.title(self.title)
        self.style=Style()
        #Choose from default, clam, alt, classic
        self.style.theme_use('alt')
        self.pack(fill=tk.BOTH,expand=True)
        self.centerWindow()


    def printStr(self):
        while self.stdoutq.qsize() and self.exit==False:
            try:
                msg=self.stdoutq.get()
                self.text.update()
                self.text.insert(tk.END,'# '+msg)
                self.text.see(tk.END)
            except Queue.Empty:
                pass
        self.after(100,self.printStr)


    def checkReady(self):
        if self.isexport.get()==1 or self.ishighlight.get()==1\
                or self.isnote.get()==1:
            self.hasaction=True
        else:
            self.hasaction=False

        if self.hasdb and self.hasout and self.hasaction:
            self.start_button.configure(state=tk.NORMAL)
            print('Menotexport Ready.')
        else:
            self.start_button.configure(state=tk.DISABLED)


    def addPathFrame(self):
        frame=Frame(self)
        frame.pack(fill=tk.X,expand=0,side=tk.TOP,padx=8,pady=5)

        frame.columnconfigure(1,weight=1)

        #------------------Database file------------------
        label=tk.Label(frame,text='Mendeley Data file:',\
                bg='#bbb')
        label.grid(row=0,column=0,\
                sticky=tk.W,padx=8)

        self.db_entry=tk.Entry(frame)
        self.db_entry.grid(row=0,column=1,sticky=tk.W+tk.E,padx=8)

        self.db_button=tk.Button(frame,text='Open',command=self.openFile)
        self.db_button.grid(row=0,column=2,padx=8,sticky=tk.E)

        hint='''
Default location on Linux:
~/.local/share/data/Mendeley\ Ltd./Mendeley\ Desktop/[email protected]
Default location on Windows:
C:\Users\Your_name\AppData\Local\Mendeley Ltd\Mendeley Desktop\[email protected]'''

        hint_label=tk.Label(frame,text=hint,\
                justify=tk.LEFT,anchor=tk.NW)
        hint_label.grid(row=1,column=0,columnspan=3,\
                sticky=tk.W,padx=8)

        #--------------------Output dir--------------------
        label2=tk.Label(frame,text='Output folder:',\
                bg='#bbb')
        label2.grid(row=2,column=0,\
                sticky=tk.W,padx=8)

        self.out_entry=tk.Entry(frame)
        self.out_entry.grid(row=2,column=1,sticky=tk.W+tk.E,padx=8)
        self.out_button=tk.Button(frame,text='Choose',command=self.openDir)
        self.out_button.grid(row=2,column=2,padx=8,sticky=tk.E)
        


    def openDir(self):
        self.out_entry.delete(0,tk.END)
        dirname=askdirectory()
        self.out_entry.insert(tk.END,dirname)
        if len(dirname)>0:
            print('Output folder: %s' %dirname)
            self.hasout=True
            self.checkReady()


    def openFile(self):
        self.db_entry.delete(0,tk.END)
        ftypes=[('sqlite files','*.sqlite'),('ALl files','*')]
        filename=askopenfilename(filetypes=ftypes)
        self.db_entry.insert(tk.END,filename)
        if len(filename)>0:
            print('Database file: %s' %filename)
            self.probeFolders()


    def probeFolders(self):
        dbfile=self.db_entry.get()
        try:
            db=sqlite3.connect(dbfile)
            query=\
            '''SELECT Documents.title,
                      DocumentFolders.folderid,
                      Folders.name
               FROM Documents
               LEFT JOIN DocumentFolders
                   ON Documents.id=DocumentFolders.documentId
               LEFT JOIN Folders
                   ON Folders.id=DocumentFolders.folderid
            '''
            ret=db.execute(query)
            data=ret.fetchall()
            df=pd.DataFrame(data=data,columns=['title',\
                    'folerid','name'])
            fetchField=lambda x, f: x[f].unique().tolist()
            folders=fetchField(df,'name')
            folders.sort()
            folders.remove(None)

            self.menfolderlist=['All',]+folders
            self.foldersmenu['values']=tuple(self.menfolderlist)
            self.foldersmenu.current(0)
            db.close()

            self.hasdb=True
            self.checkReady()

        except Exception as e:
            print('Failed to recoganize the given database file.') 
            print(e)





    
    def addActionFrame(self):

        frame=Frame(self,relief=tk.RAISED,borderwidth=1)
        frame.pack(fill=tk.X,side=tk.TOP,\
                expand=0,padx=8,pady=5)

        label=tk.Label(frame,text='Actions:',bg='#bbb')
        label.grid(row=0,column=0,sticky=tk.W,padx=8)

        #---------------Action checkbuttons---------------
        self.isexport=tk.IntVar()
        self.ishighlight=tk.IntVar()
        self.isnote=tk.IntVar()
        self.isseparate=tk.IntVar()

        self.check_export=tk.Checkbutton(frame,text='Export PDFs',\
                variable=self.isexport,command=self.doExport)

        self.check_highlight=tk.Checkbutton(frame,\
                text='Extract highlights',\
                variable=self.ishighlight,command=self.doHighlight)

        self.check_note=tk.Checkbutton(frame,\
                text='Extract notes',\
                variable=self.isnote,command=self.doNote)

        self.check_separate=tk.Checkbutton(frame,\
                text='Save separately',\
                variable=self.isseparate,command=self.doSeparate,\
                state=tk.DISABLED)

        frame.columnconfigure(0,weight=1)

        self.check_export.grid(row=0,column=1,padx=8,sticky=tk.W)
        self.check_highlight.grid(row=0,column=2,padx=8,sticky=tk.W)
        self.check_note.grid(row=0,column=3,padx=8,sticky=tk.W)
        self.check_separate.grid(row=0,column=4,padx=8,sticky=tk.W)

        #---------------------2nd row---------------------
        subframe=Frame(frame)
        subframe.grid(row=1,column=0,columnspan=5,sticky=tk.W+tk.E,\
                pady=5)

        #-------------------Folder options-------------------
        folderlabel=tk.Label(subframe,text='Mendeley folder:',\
                bg='#bbb')
        folderlabel.pack(side=tk.LEFT, padx=8)

        self.menfolder=tk.StringVar()
        self.menfolderlist=['All',]
        self.foldersmenu=Combobox(subframe,textvariable=\
                self.menfolder,values=self.menfolderlist,state='readonly')
        self.foldersmenu.current(0)
        self.foldersmenu.bind('<<ComboboxSelected>>',self.setfolder)
        self.foldersmenu.pack(side=tk.LEFT,padx=8)

        
        #-------------------Quit button-------------------
        quit_button=tk.Button(subframe,text='Quit',\
                command=self.quit)
        quit_button.pack(side=tk.RIGHT,padx=8)

        #-------------------Stop button-------------------
        '''
        self.stop_button=tk.Button(subframe,text='Stop',\
                command=self.stop)
        self.stop_button.pack(side=tk.RIGHT,padx=8)
        '''
                
        #-------------------Start button-------------------
        self.start_button=tk.Button(subframe,text='Start',\
                command=self.start,state=tk.DISABLED)
        self.start_button.pack(side=tk.RIGHT,pady=8)

        #-------------------Help button-------------------

        self.help_button=tk.Button(subframe,text='Help',\
                command=self.showHelp)
        self.help_button.pack(side=tk.RIGHT,padx=8)



    def setfolder(self,x):
        self.foldersmenu.selection_clear()
        self.menfolder=self.foldersmenu.get()
        self.foldersmenu.set(self.menfolder)
        if self.menfolder=='All':
            print('Work on all folders.')
        else:
            print('Select Mendeley folder: '+str(self.menfolder))



    def doExport(self):
        if self.isexport.get()==1:
            print('Export annotated PDFs.')
        else:
            print('Dont export annotated PDFs.')

        self.checkReady()



    def doHighlight(self):
        if self.ishighlight.get()==1:
            print('Extract highlighted texts.')
            self.check_separate.configure(state=tk.NORMAL)
        else:
            print('Dont extract highlighted texts.')
            if self.isnote.get()==0:
                self.check_separate.configure(state=tk.DISABLED)
        self.checkReady()

    def doNote(self):
        if self.isnote.get()==1:
            print('Extract notes.')
            self.check_separate.configure(state=tk.NORMAL)
        else:
            print('Dont extract notes.')
            self.check_separate.state=tk.DISABLED
            if self.ishighlight.get()==0:
                self.check_separate.configure(state=tk.DISABLED)
        self.checkReady()


    def doSeparate(self):
        if self.isseparate.get()==1:
            print('Save annotations separately.')
        else:
            print('Save all annotations to single file.')



    def showHelp(self):
        helpstr='''
Menotexport v1.0\n\n
- Export PDFs: Bulk export PDFs with annotations to <output folder>.\n
- Extract highlights: Extract highlighted texts and output to a txt file in <output folder>.\n
- Extract highlights: Extract notes and output to a txt file in <output folder>.\n
- Save separately: If on, save each PDF's annotations to a separate txt.\n
- See README.md for more info.\n
'''

        tkMessageBox.showinfo(title='Help', message=helpstr)
        print(self.menfolder.get())




    def start(self):
        dbfile=self.db_entry.get()
        outdir=self.out_entry.get()
        action=[]
        if self.isexport.get()==1:
            action.append('e')
        if self.ishighlight.get()==1:
            action.append('m')
        if self.isnote.get()==1:
            action.append('n')
        if self.isseparate.get()==1:
            separate=True
        else:
            separate=False
            
        if 'e' in action or 'm' in action or 'n' in action:
            self.db_button.configure(state=tk.DISABLED)
            self.out_button.configure(state=tk.DISABLED)
            self.start_button.configure(state=tk.DISABLED)
            self.help_button.configure(state=tk.DISABLED)
            self.foldersmenu.configure(state=tk.DISABLED)
            self.check_export.configure(state=tk.DISABLED)
            self.check_highlight.configure(state=tk.DISABLED)
            self.check_note.configure(state=tk.DISABLED)
            self.check_separate.configure(state=tk.DISABLED)
	    self.messagelabel.configure(text='Message (working...)')

            folder=None if self.menfolder=='All' else [self.menfolder,]

            args=[dbfile,outdir,action,folder,True,True,separate,True]

            self.workthread=WorkThread('work',False,self.stateq)
            self.workthread.deamon=True

            self.workthread.args=args
            self.workthread.start()
            self.reset()
            '''
            self.workproc.apply_async(menotexport.main,args,\
                    callback=self.reset)
            self.workproc.join()
            '''



    def reset(self):
        while self.stateq.qsize() and self.exit==False:
            try:
                msg=self.stateq.get()
                if msg=='done':
                    self.db_button.configure(state=tk.NORMAL)
                    self.out_button.configure(state=tk.NORMAL)
                    self.start_button.configure(state=tk.NORMAL)
                    self.help_button.configure(state=tk.NORMAL)
                    self.foldersmenu.configure(state='readonly')
                    self.check_export.configure(state=tk.NORMAL)
                    self.check_highlight.configure(state=tk.NORMAL)
                    self.check_note.configure(state=tk.NORMAL)
                    self.check_separate.configure(state=tk.NORMAL)
                    self.messagelabel.configure(text='Message')
                    return
            except Queue.Empty:
                pass
        self.after(100,self.reset)


    
    def stop(self):
        #self.workthread.stop()
        pass
        

    def addMessageFrame(self):
        frame=Frame(self)
        frame.pack(fill=tk.BOTH,side=tk.TOP,\
                expand=1,padx=8,pady=5)

        self.messagelabel=tk.Label(frame,text='Message',bg='#bbb')
        self.messagelabel.pack(side=tk.TOP,fill=tk.X)

        self.text=tk.Text(frame)
        self.text.pack(side=tk.TOP,fill=tk.BOTH,expand=1)
        self.text.height=10

        scrollbar=tk.Scrollbar(self.text)
        scrollbar.pack(side=tk.RIGHT,fill=tk.Y)

        self.text.config(yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.text.yview)
Пример #4
0
class MainFrame(Frame):
    def __init__(self,parent,stdoutq):
        Frame.__init__(self,parent)

        self.parent=parent
        self.width=750
        self.height=450
        self.title=ximaexport.__version__
        self.stdoutq=stdoutq
        
        self.initUI()

        self.hasdb=False
        self.hasout=False
        self.exit=False

        self.path_frame=self.addPathFrame()
        self.action_frame=self.addActionFrame()
        self.message_frame=self.addMessageFrame()
        self.printStr()

        self.stateq=Queue.Queue()


    def centerWindow(self):
        sw=self.parent.winfo_screenwidth()
        sh=self.parent.winfo_screenheight()
        x=(sw-self.width)/2
        y=(sh-self.height)/2
        self.parent.geometry('%dx%d+%d+%d' \
                %(self.width,self.height,x,y))


    def initUI(self):
        self.parent.title(self.title)
        self.style=Style()
        #Choose from default, clam, alt, classic
        self.style.theme_use('alt')
        self.pack(fill=tk.BOTH,expand=True)
        self.centerWindow()


    def printStr(self):
        while self.stdoutq.qsize() and self.exit==False:
            try:
                msg=self.stdoutq.get()
                self.text.update()
                self.text.insert(tk.END,msg)
                self.text.see(tk.END)
            except Queue.Empty:
                pass
        self.after(100,self.printStr)



    def checkReady(self):

        if self.hasdb and self.hasout:
            self.start_button.configure(state=tk.NORMAL)
            #print('XimaExport Ready.')
            printch('XimaExport 就绪.')
        else:
            self.start_button.configure(state=tk.DISABLED)


    def addPathFrame(self):
        frame=Frame(self)
        frame.pack(fill=tk.X,expand=0,side=tk.TOP,padx=8,pady=5)

        frame.columnconfigure(1,weight=1)

        #------------------Database file------------------
        label=tk.Label(frame,text=dgbk('ting.sqlite文件:'),\
                bg='#bbb')
        label.grid(row=0,column=0,\
                sticky=tk.W,padx=8)

        self.db_entry=tk.Entry(frame)
        self.db_entry.grid(row=0,column=1,sticky=tk.W+tk.E,padx=8)

        self.db_button=tk.Button(frame,text=dgbk('打开'),command=self.openFile)
        self.db_button.grid(row=0,column=2,padx=8,sticky=tk.E)

        #--------------------Output dir--------------------
        label2=tk.Label(frame,text=dgbk('导出到文件夹:'),\
                bg='#bbb')
        label2.grid(row=2,column=0,\
                sticky=tk.W,padx=8)

        self.out_entry=tk.Entry(frame)
        self.out_entry.grid(row=2,column=1,sticky=tk.W+tk.E,padx=8)
        self.out_button=tk.Button(frame,text=dgbk('选择'),command=self.openDir)
        self.out_button.grid(row=2,column=2,padx=8,sticky=tk.E)
        


    def openDir(self):
        self.out_entry.delete(0,tk.END)
        dirname=askdirectory()
        self.out_entry.insert(tk.END,dirname)
        if len(dirname)>0:
            #print('Output folder: %s' %dirname)
            printch('输出到文件夹:')
	    print('   '+dirname)
            self.hasout=True
            self.checkReady()


    def openFile(self):
        self.db_entry.delete(0,tk.END)
        ftypes=[('sqlite files','*.sqlite'),('ALL files','*')]
        filename=askopenfilename(filetypes=ftypes)
        self.db_entry.insert(tk.END,filename)
        if len(filename)>0:
            #print('Database file: %s' %filename)
            printch('数据文件:')
	    print('   '+filename)
            self.probeAlbums()


    def probeAlbums(self):
        dbfile=self.db_entry.get()
        try:
            db=sqlite3.connect(dbfile)
            df=ximaexport.getData(db)
            self.albumlist=ximaexport.getAlbumList(df,None)   #(id, name)
            self.albumnames=['All']+[ii[1] for ii in self.albumlist] #names to display
            self.albummenu['values']=tuple(self.albumnames)
            self.albummenu.current(0)
            db.close()

            self.hasdb=True
            self.checkReady()

        except Exception as e:
            #print('Failed to recoganize the given database file.') 
            printch('无法识别sqlite数据文件.') 
            print(e)



    
    def addActionFrame(self):

        frame=Frame(self,relief=tk.RAISED,borderwidth=1)
        frame.pack(fill=tk.X,side=tk.TOP,\
                expand=0,padx=8,pady=5)

        #label=tk.Label(frame,text='Actions:',bg='#bbb')
        #label.grid(row=0,column=0,sticky=tk.W,padx=8)

        #---------------Action checkbuttons---------------
        frame.columnconfigure(0,weight=1)

        #---------------------2nd row---------------------
        subframe=Frame(frame)
        subframe.grid(row=1,column=0,columnspan=6,sticky=tk.W+tk.E,\
                pady=5)

        #-------------------Album options-------------------
        albumlabel=tk.Label(subframe,text=dgbk('专辑:'),\
                bg='#bbb')
        albumlabel.pack(side=tk.LEFT, padx=8)

        self.album=tk.StringVar()
        self.albumnames=['All',]
        self.albummenu=Combobox(subframe,textvariable=\
                self.album,values=self.albumnames,state='readonly')
        self.albummenu.current(0)
        self.albummenu.bind('<<ComboboxSelected>>',self.setAlbum)
        self.albummenu.pack(side=tk.LEFT,padx=8)
        
        #-------------------Quit button-------------------
        quit_button=tk.Button(subframe,text=dgbk('退出'),\
                command=self.quit)
        quit_button.pack(side=tk.RIGHT,padx=8)

        #-------------------Stop button-------------------
        '''
        self.stop_button=tk.Button(subframe,text='Stop',\
                command=self.stop)
        self.stop_button.pack(side=tk.RIGHT,padx=8)
        '''
                
        #-------------------Start button-------------------
        self.start_button=tk.Button(subframe,text=dgbk('开始'),\
                command=self.start,state=tk.DISABLED)
        self.start_button.pack(side=tk.RIGHT,pady=8)

        #-------------------Help button-------------------
        self.help_button=tk.Button(subframe,text=dgbk('帮助'),\
                command=self.showHelp)
        self.help_button.pack(side=tk.RIGHT,padx=8)





    def setAlbum(self,x):
	import json
        self.albummenu.selection_clear()
        self.album=self.albummenu.get()
        self.albummenu.set(self.album)
        if self.album=='All':
            #print('Work on all albums.')
            printch('导出所有专辑.')
        else:
            #print('Select album: '+self.album)
            printch('导出所选专辑:')
	    print('   '+self.album)





    def showHelp(self):
        helpstr=dgbk('''\n\n
导出喜马拉雅下载音频,并自动按专辑归档、重命名:\n
1. 找到手机/pad中的喜马拉雅数据文件夹:\n
    (1)苹果用户:链接电脑itunes,在app一栏中找到“喜马拉雅”,单击,右侧会出现“喜马拉雅”的数据文件。选择“iDoc”,并导出到电脑。\n
    (2)安卓用户:链接电脑后,拷贝出ting文件夹。\n
2. 运行ximaexport-gui.exe。\n
    在 “ting.sqlite文件”一栏,选择步骤1中拷贝出的文件夹里的 ting.sqlite. 文件。\n
    在 “导出到文件夹”一栏,选择音频存储位置。\n
    在 “专辑”下拉菜单,选择要导出的专辑。若全部导出选择“All”。\n
    点击“开始”开始处理。
''')

        tkMessageBox.showinfo(title='Help', message=helpstr)
        #print(self.menfolder.get())



    def start(self):
        dbfile=self.db_entry.get()
        outdir=self.out_entry.get()
        self.album=self.albummenu.get()

        self.out_button.configure(state=tk.DISABLED)
        self.start_button.configure(state=tk.DISABLED)
        self.help_button.configure(state=tk.DISABLED)
        self.albummenu.configure(state=tk.DISABLED)
        self.messagelabel.configure(text=dgbk('信息 (处理中...)'))

        album=None if self.album=='All' else self.album

        args=[dbfile,outdir,album,True]

        self.workthread=WorkThread('work',False,self.stateq)
        self.workthread.deamon=True

        self.workthread.args=args
        self.workthread.start()
        self.reset()


    def reset(self):
        while self.stateq.qsize() and self.exit==False:
            try:
                msg=self.stateq.get()
                if msg=='done':
                    self.db_button.configure(state=tk.NORMAL)
                    self.out_button.configure(state=tk.NORMAL)
                    self.start_button.configure(state=tk.NORMAL)
                    self.help_button.configure(state=tk.NORMAL)
                    self.albummenu.configure(state='readonly')
                    self.messagelabel.configure(text=dgbk('消息'))
                    return
            except Queue.Empty:
                pass
        self.after(100,self.reset)


    
    def stop(self):
        #self.workthread.stop()
        pass
        

    def addMessageFrame(self):
        frame=Frame(self)
        frame.pack(fill=tk.BOTH,side=tk.TOP,\
                expand=1,padx=8,pady=5)

        self.messagelabel=tk.Label(frame,text=dgbk('消息'),bg='#bbb')
        self.messagelabel.pack(side=tk.TOP,fill=tk.X)

        self.text=tk.Text(frame)
        self.text.pack(side=tk.TOP,fill=tk.BOTH,expand=1)
        self.text.height=10

        scrollbar=tk.Scrollbar(self.text)
        scrollbar.pack(side=tk.RIGHT,fill=tk.Y)

        self.text.config(yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.text.yview)
class Gui(Frame):
    """ Gui class for Graphical User Interface"""
    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.searcher = Searcher()
        self.initUI()

    def initUI(self):
        self.pack(fill=BOTH, expand=True)
        Grid.columnconfigure(self, 0, weight=1)
        Label(self,
              text='Classroom Finder',
              font=('Arial', 20, 'bold'),
              bg='cyan',
              fg='white').grid(sticky=W + E,
                               columnspan=3)  # classroom finder header
        Label(self, text='Url:').grid(column=0, row=1, pady=10, padx=(50, 0))
        self.urlentry = Entry(self, width=100)  # url entry to get url
        self.urlentry.grid(column=1, row=1, padx=(0, 80))
        self.color_label = Label(
            self, bg='red', width=10)  # color label to make red,yellow,green
        self.color_label.grid(column=0,
                              row=2,
                              sticky=E,
                              columnspan=2,
                              padx=(120),
                              pady=(0, 40))
        self.fetchbtn = Button(self,
                               text='Fetch',
                               height=2,
                               width=10,
                               command=self.dynamic)  # fetch button
        self.fetchbtn.grid(column=1,
                           row=2,
                           sticky=E,
                           padx=(0, 30),
                           pady=(10, 50))
        Label(self,
              text='Filters',
              bg='cyan',
              fg='white',
              font=('Arial', 20, 'bold'),
              width=10).grid(column=0, row=3, padx=10)
        self.frame = Frame(self, borderwidth=3,
                           relief=GROOVE)  # frame to keep filters part
        self.frame.grid(column=0,
                        row=4,
                        columnspan=3,
                        sticky=W + E + S + N,
                        pady=10,
                        padx=10)
        Label(self.frame, text='Where am I?').grid(sticky=W)
        self.where_combo = Combobox(self.frame,
                                    state='readonly')  # where am i combobox
        self.where_combo.grid(column=1, row=0, pady=20)
        self.where_combo.bind(
            '<<ComboboxSelected>>',
            self.change_build)  # to update room button wrt where combo
        Label(self.frame, text='Room').grid(sticky=W)
        self.room_combo = Combobox(self.frame,
                                   state='readonly')  # rooms combobox
        self.room_combo.grid(column=1, row=1)
        Label(self.frame, text='Start').grid(sticky=W)
        self.start_combo = Combobox(self.frame, state='readonly',
                                    width=7)  # start time combobox
        self.start_combo.grid(column=1, row=2, pady=20, sticky=W)
        Label(self.frame, text='End').grid(column=2, row=2, sticky=W)
        self.end_combo = Combobox(self.frame, state='readonly',
                                  width=7)  # end time combobox
        self.end_combo.grid(column=3, row=2, sticky=W)
        Label(self.frame, text='Day').grid(sticky=W)
        self.day_combo = Combobox(self.frame,
                                  state='readonly')  # days combobox
        self.day_combo.grid(column=1, row=3, pady=(0, 20))
        self.search = Button(self.frame,
                             text='Search',
                             width=10,
                             height=2,
                             command=self.add_treeview)  # seach button
        self.search.grid(padx=(0, 50), columnspan=2)
        Label(self.frame, text='Classroom results', bg='gray',
              fg='white').grid(sticky=N + E + W,
                               column=4,
                               row=0,
                               rowspan=5,
                               padx=(55, 0))
        self.scroll = Scrollbar(
            self.frame, orient='vertical')  # vertical scrollbar for treeview
        self.tree = Treeview(self.frame,
                             columns=('', '', '', '', ''),
                             selectmode='extended',
                             show='headings')
        listofcolumn = [
            'Room', 'Traffic', 'Availability %', 'Closeness', 'Overall Score'
        ]  # colums to treeview
        counter = 1
        for column in listofcolumn:
            self.tree.column('#' + str(counter), width=90)  # to resize columns
            self.tree.heading('#' + str(counter), text=column,
                              anchor=CENTER)  # to set headings
            counter += 1
        self.scroll.config(command=self.tree.yview)
        self.tree.config(yscrollcommand=self.scroll.set)
        self.tree.grid(column=4, row=0, rowspan=5, padx=(40, 0), pady=(30, 0))
        self.scroll.grid(column=5,
                         row=0,
                         rowspan=5,
                         sticky=N + S,
                         pady=(30, 0))
        self.urlentry.insert(
            0,
            'https://www.sehir.edu.tr/en/announcements/2018-2019-bahar-donemi-ders-programi'
        )

    def dynamic(self):
        self.color_label.configure(
            bg='yellow'
        )  # make color label yellow at the beginning of the process
        self.update_idletasks()
        self.searcher.fetch(self.urlentry.get(
        ))  # to call fetch method in searcher class to start process
        self.color_label.configure(bg='green')
        room_num = [
            room.room_num
            for room in self.searcher.buildings['ACAD BUILD 1'].classrooms
        ]
        self.where_combo.configure(
            values=[build for build in sorted(self.searcher.buildings)])
        self.where_combo.current(
            0)  # to get values in combobox and set value 0 as a default
        self.room_combo.configure(values=[room for room in sorted(room_num)])
        self.room_combo.current(0)
        self.start_combo.configure(
            values=["{}:00".format(time) for time in range(9, 20)])
        self.start_combo.current(
            0)  # start and end combo both have the same interval from 9 to 19
        self.end_combo.configure(
            values=["{}:00".format(time) for time in range(9, 20)])
        self.end_combo.current(len(self.end_combo['values']) - 1)
        self.day_combo.configure(
            values=["Monday", 'Tuesday', 'Wednesday', 'Thursday', 'Friday'])
        self.day_combo.current(0)

    def change_build(
            self, event
    ):  # when where am i combobox chance, room combobox also chance
        building = self.where_combo.get()
        room_num = [
            room.room_num
            for room in self.searcher.buildings[building].classrooms
        ]
        self.room_combo.configure(values=[room for room in sorted(room_num)])
        self.room_combo.current(0)

    def add_treeview(self):  # to add scores in treeview
        self.tree.delete(*self.tree.get_children())
        self.overall_scores = self.searcher.search(
            self.day_combo.get(),
            self.where_combo.get(), self.room_combo.get(),
            self.start_combo.get(), self.end_combo.get()
        )  # key operator for the sorted dict by values which overall score
        for item, score in sorted(self.overall_scores.items(),
                                  key=operator.itemgetter(1),
                                  reverse=True):
            if item.availability_score == 0:  # to avoid from availability score 0
                continue
            room = str(item.classroom.building_num) + str(
                item.classroom.room_num)
            self.tree.insert('',
                             'end',
                             values=(room, item.traffic_score,
                                     item.availability_score,
                                     item.closeness_score, score))
Пример #6
0
class MainFrame(Frame):
    def __init__(self, parent, stdoutq):
        Frame.__init__(self, parent)

        self.parent = parent
        self.width = 850
        self.height = 650
        self.title = menotexport.__version__
        self.stdoutq = stdoutq

        self.initUI()

        self.hasdb = False
        self.hasout = False
        self.hasaction = False
        self.exit = False

        self.path_frame = self.addPathFrame()
        self.action_frame = self.addActionFrame()
        self.message_frame = self.addMessageFrame()
        self.printStr()

        self.stateq = Queue.Queue()
        #self.workproc=Pool(1)

    def centerWindow(self):
        sw = self.parent.winfo_screenwidth()
        sh = self.parent.winfo_screenheight()
        x = (sw - self.width) / 2
        y = (sh - self.height) / 2
        self.parent.geometry('%dx%d+%d+%d' \
                %(self.width,self.height,x,y))

    def initUI(self):
        self.parent.title(self.title)
        self.style = Style()
        #Choose from default, clam, alt, classic
        self.style.theme_use('alt')
        self.pack(fill=tk.BOTH, expand=True)
        self.centerWindow()

    def printStr(self):
        while self.stdoutq.qsize() and self.exit == False:
            try:
                msg = self.stdoutq.get()
                self.text.update()
                self.text.insert(tk.END, msg)
                self.text.see(tk.END)
            except Queue.Empty:
                pass
        self.after(100, self.printStr)

    def checkReady(self):
        if self.isexport.get()==1 or self.ishighlight.get()==1\
                or self.isnote.get()==1 or self.isbib.get()==1:
            self.hasaction = True
        else:
            self.hasaction = False

        if self.hasdb and self.hasout and self.hasaction:
            self.start_button.configure(state=tk.NORMAL)
            print('# <Menotexport>: Menotexport Ready.')
        else:
            self.start_button.configure(state=tk.DISABLED)

    def addPathFrame(self):
        frame = Frame(self)
        frame.pack(fill=tk.X, expand=0, side=tk.TOP, padx=8, pady=5)

        frame.columnconfigure(1, weight=1)

        #------------------Database file------------------
        label=tk.Label(frame,text='Mendeley Data file:',\
                bg='#bbb')
        label.grid(row=0,column=0,\
                sticky=tk.W,padx=8)

        self.db_entry = tk.Entry(frame)
        self.db_entry.grid(row=0, column=1, sticky=tk.W + tk.E, padx=8)

        self.db_button = tk.Button(frame, text='Open', command=self.openFile)
        self.db_button.grid(row=0, column=2, padx=8, sticky=tk.E)

        hint = '''
Default location on Linux:
~/.local/share/data/Mendeley\ Ltd./Mendeley\ Desktop/[email protected]
Default location on Windows:
C:\Users\Your_name\AppData\Local\Mendeley Ltd\Mendeley Desktop\[email protected]'''

        hint_label=tk.Label(frame,text=hint,\
                justify=tk.LEFT,anchor=tk.NW)
        hint_label.grid(row=1,column=0,columnspan=3,\
                sticky=tk.W,padx=8)

        #--------------------Output dir--------------------
        label2=tk.Label(frame,text='Output folder:',\
                bg='#bbb')
        label2.grid(row=2,column=0,\
                sticky=tk.W,padx=8)

        self.out_entry = tk.Entry(frame)
        self.out_entry.grid(row=2, column=1, sticky=tk.W + tk.E, padx=8)
        self.out_button = tk.Button(frame, text='Choose', command=self.openDir)
        self.out_button.grid(row=2, column=2, padx=8, sticky=tk.E)

    def openDir(self):
        self.out_entry.delete(0, tk.END)
        dirname = askdirectory()
        self.out_entry.insert(tk.END, dirname)
        if len(dirname) > 0:
            print('# <Menotexport>: Output folder: %s' % dirname)
            self.hasout = True
            self.checkReady()

    def openFile(self):
        self.db_entry.delete(0, tk.END)
        ftypes = [('sqlite files', '*.sqlite'), ('ALL files', '*')]
        initialdir = '~/.local/share/data/Mendeley Ltd./Mendeley Desktop'
        initialdir = os.path.expanduser(initialdir)
        if os.path.isdir(initialdir):
            filename = askopenfilename(filetypes=ftypes, initialdir=initialdir)
        else:
            filename = askopenfilename(filetypes=ftypes)
        self.db_entry.insert(tk.END, filename)
        if len(filename) > 0:
            print('# <Menotexport>: Database file: %s' % filename)
            self.probeFolders()

    def probeFolders(self):
        dbfile = self.db_entry.get()
        try:
            db = sqlite3.connect(dbfile)
            self.menfolderlist = menotexport.getFolderList(db,
                                                           None)  #(id, name)
            self.foldernames = ['All'] + [ii[1] for ii in self.menfolderlist
                                          ]  #names to display
            self.foldersmenu['values'] = tuple(self.foldernames)
            self.foldersmenu.current(0)
            db.close()

            self.hasdb = True
            self.checkReady()

        except Exception as e:
            print(
                '# <Menotexport>: Failed to recoganize the given database file.'
            )
            print(e)

    def addActionFrame(self):

        frame = Frame(self, relief=tk.RAISED, borderwidth=1)
        frame.pack(fill=tk.X,side=tk.TOP,\
                expand=0,padx=8,pady=5)

        label = tk.Label(frame, text='Actions:', bg='#bbb')
        label.grid(row=0, column=0, sticky=tk.W, padx=8)

        #---------------Action checkbuttons---------------
        self.isexport = tk.IntVar()
        self.ishighlight = tk.IntVar()
        self.isnote = tk.IntVar()
        self.isbib = tk.IntVar()
        self.isris = tk.IntVar()
        self.isseparate = tk.IntVar()
        self.iszotero = tk.IntVar()
        self.iscustomtemp = tk.IntVar()

        self.check_export=tk.Checkbutton(frame,text='Export PDFs',\
                variable=self.isexport,command=self.doExport)

        self.check_highlight=tk.Checkbutton(frame,\
                text='Extract highlights',\
                variable=self.ishighlight,command=self.doHighlight)

        self.check_note=tk.Checkbutton(frame,\
                text='Extract notes',\
                variable=self.isnote,command=self.doNote)

        self.check_bib=tk.Checkbutton(frame,\
                text='Export .bib',\
                variable=self.isbib,command=self.doBib)

        self.check_ris=tk.Checkbutton(frame,\
                text='Export .ris',\
                variable=self.isris,command=self.doRis)

        self.check_separate=tk.Checkbutton(frame,\
                text='Save separately',\
                variable=self.isseparate,command=self.doSeparate,\
                state=tk.DISABLED)

        self.check_iszotero=tk.Checkbutton(frame,\
                text='For import to Zotero',\
                variable=self.iszotero,command=self.doIszotero,\
                state=tk.DISABLED)

        self.check_custom_template=tk.Checkbutton(frame,\
                text='Use custom template (experimental)',\
                variable=self.iscustomtemp,command=self.doCustomTemp,\
                state=tk.DISABLED)

        frame.columnconfigure(0, weight=1)

        self.check_export.grid(row=1, column=1, padx=8, sticky=tk.W)
        self.check_highlight.grid(row=1, column=2, padx=8, sticky=tk.W)
        self.check_note.grid(row=1, column=3, padx=8, sticky=tk.W)
        self.check_bib.grid(row=2, column=1, padx=8, sticky=tk.W)
        self.check_ris.grid(row=2, column=2, padx=8, sticky=tk.W)
        self.check_separate.grid(row=2, column=3, padx=8, sticky=tk.W)
        self.check_iszotero.grid(row=3, column=1, padx=8, sticky=tk.W)
        self.check_custom_template.grid(row=3, column=2, padx=8, sticky=tk.W)

        #---------------------2nd row---------------------
        subframe = Frame(frame)
        subframe.grid(row=4,column=0,columnspan=6,sticky=tk.W+tk.E,\
                pady=5)

        #-------------------Folder options-------------------
        folderlabel=tk.Label(subframe,text='Mendeley folder:',\
                bg='#bbb')
        folderlabel.pack(side=tk.LEFT, padx=8)

        self.menfolder = tk.StringVar()
        self.menfolderlist = [
            'All',
        ]
        self.foldersmenu=Combobox(subframe,textvariable=\
                self.menfolder,values=self.menfolderlist,state='readonly')
        self.foldersmenu.current(0)
        self.foldersmenu.bind('<<ComboboxSelected>>', self.setfolder)
        self.foldersmenu.pack(side=tk.LEFT, padx=8)

        #-------------------Quit button-------------------
        quit_button=tk.Button(subframe,text='Quit',\
                command=self.quit)
        quit_button.pack(side=tk.RIGHT, padx=8)

        #-------------------Stop button-------------------
        '''
        self.stop_button=tk.Button(subframe,text='Stop',\
                command=self.stop)
        self.stop_button.pack(side=tk.RIGHT,padx=8)
        '''

        #-------------------Start button-------------------
        self.start_button=tk.Button(subframe,text='Start',\
                command=self.start,state=tk.DISABLED)
        self.start_button.pack(side=tk.RIGHT, pady=8)

        #-------------------Help button-------------------
        self.help_button=tk.Button(subframe,text='Help',\
                command=self.showHelp)
        self.help_button.pack(side=tk.RIGHT, padx=8)

    def setfolder(self, x):
        self.foldersmenu.selection_clear()
        self.menfolder = self.foldersmenu.get()
        self.foldersmenu.set(self.menfolder)
        if self.menfolder == 'All':
            print('# <Menotexport>: Work on all folders.')
        else:
            print('# <Menotexport>: Select Mendeley folder: ' +
                  str(self.menfolder))

    def doExport(self):
        if self.isexport.get() == 1:
            print('# <Menotexport>: Export annotated PDFs.')
        else:
            print('# <Menotexport>: Dont export annotated PDFs.')

        self.checkReady()

    def doHighlight(self):
        if self.ishighlight.get() == 1:
            print('# <Menotexport>: Extract highlighted texts.')
            self.check_separate.configure(state=tk.NORMAL)
            self.check_custom_template.configure(state=tk.NORMAL)
        else:
            print('# <Menotexport>: Dont extract highlighted texts.')
            if self.isnote.get() == 0:
                self.check_separate.configure(state=tk.DISABLED)
                self.check_custom_template.configure(state=tk.DISABLED)
        self.checkReady()

    def doNote(self):
        if self.isnote.get() == 1:
            print('# <Menotexport>: Extract notes.')
            self.check_separate.configure(state=tk.NORMAL)
            self.check_custom_template.configure(state=tk.NORMAL)
        else:
            print('# <Menotexport>: Dont extract notes.')
            self.check_separate.state = tk.DISABLED
            if self.ishighlight.get() == 0:
                self.check_separate.configure(state=tk.DISABLED)
                self.check_custom_template.configure(state=tk.DISABLED)
        self.checkReady()
        self.checkReady()

    def doBib(self):
        if self.isbib.get() == 1:
            print('# <Menotexport>: Export to .bib file.')
            self.check_iszotero.configure(state=tk.NORMAL)
        else:
            print('# <Menotexport>: Dont export .bib file.')
            if self.isris.get() == 0:
                self.check_iszotero.configure(state=tk.DISABLED)
        self.checkReady()

    def doRis(self):
        if self.isris.get() == 1:
            print('# <Menotexport>: Export to .ris file.')
            self.check_iszotero.configure(state=tk.NORMAL)
        else:
            print('# <Menotexport>: Dont export .ris file.')
            if self.isbib.get() == 0:
                self.check_iszotero.configure(state=tk.DISABLED)
        self.checkReady()

    def doSeparate(self):
        if self.isseparate.get() == 1:
            print('# <Menotexport>: Save annotations separately.')
        else:
            print('# <Menotexport>: Save all annotations to single file.')

    def doIszotero(self):
        if self.iszotero.get() == 1:
            print(
                '# <Menotexport>: Save .bib/.ris file in Zotero preferred format.'
            )
        else:
            print('# <Menotexport>: Save .bib/.ris file to default format.')

    def doCustomTemp(self):
        if self.iscustomtemp.get() == 1:
            print(
                '# <Menotexport>: Use custom template for exported annotations.'
            )
        else:
            print(
                '# <Menotexport>: Use default template for exported annotations.'
            )

    def showHelp(self):
        helpstr = '''
%s\n\n
- Export PDFs: Bulk export PDFs.\n
- Extract highlights: Extract highlighted texts and output to txt files.\n
- Extract notes: Extract notes and output to txt files.\n
- Export .bib: Export meta-data and annotations to .bib files.\n
- Export .ris: Export meta-data and annotations to .ris files.\n
- For import to Zotero: Exported .bib and/or .ris files have suitable format to import to Zotero.\n
- Save separately: If on, save each PDF's annotations to a separate txt.\n
- Use custom annotation template: Use a custom template to format the exported annotations.
  See annotation_template.py for details.
- See README.md for more info.\n
''' % self.title

        tkMessageBox.showinfo(title='Help', message=helpstr)
        #print(self.menfolder.get())

    def start(self):
        dbfile = self.db_entry.get()
        outdir = self.out_entry.get()
        self.menfolder = self.foldersmenu.get()

        # get (folderid, folder) for folder
        for ii in self.menfolderlist:
            if ii[1] == self.menfolder:
                folder_sel = [ii[0], ii[1].split('/')[-1]]

        action = []
        if self.isexport.get() == 1:
            action.append('p')
        if self.ishighlight.get() == 1:
            action.append('m')
        if self.isnote.get() == 1:
            action.append('n')
        if self.isbib.get() == 1:
            action.append('b')
        if self.isris.get() == 1:
            action.append('r')
        if self.isseparate.get() == 1:
            separate = True
        else:
            separate = False
        if self.iszotero.get() == 1:
            iszotero = True
        else:
            iszotero = False
        if self.iscustomtemp.get() == 1:
            action.append('t')

        if 'p' in action or 'm' in action or 'n' in action or 'b' in action or 'r' in action:
            self.db_button.configure(state=tk.DISABLED)
            self.out_button.configure(state=tk.DISABLED)
            self.start_button.configure(state=tk.DISABLED)
            self.help_button.configure(state=tk.DISABLED)
            self.foldersmenu.configure(state=tk.DISABLED)
            self.check_export.configure(state=tk.DISABLED)
            self.check_highlight.configure(state=tk.DISABLED)
            self.check_note.configure(state=tk.DISABLED)
            self.check_bib.configure(state=tk.DISABLED)
            self.check_ris.configure(state=tk.DISABLED)
            self.check_separate.configure(state=tk.DISABLED)
            self.check_iszotero.configure(state=tk.DISABLED)
            self.check_custom_template.configure(state=tk.DISABLED)
            self.messagelabel.configure(text='Message (working...)')

            folder = None if self.menfolder == 'All' else folder_sel

            args = [dbfile, outdir, action, folder, separate, iszotero, True]

            self.workthread = WorkThread('work', False, self.stateq)
            self.workthread.deamon = True

            self.workthread.args = args
            self.workthread.start()
            self.reset()
            '''
            self.workproc.apply_async(menotexport.main,args,\
                    callback=self.reset)
            self.workproc.join()
            '''

    def reset(self):
        while self.stateq.qsize() and self.exit == False:
            try:
                msg = self.stateq.get()
                if msg == 'done':
                    self.db_button.configure(state=tk.NORMAL)
                    self.out_button.configure(state=tk.NORMAL)
                    self.start_button.configure(state=tk.NORMAL)
                    self.help_button.configure(state=tk.NORMAL)
                    self.foldersmenu.configure(state='readonly')
                    self.check_export.configure(state=tk.NORMAL)
                    self.check_highlight.configure(state=tk.NORMAL)
                    self.check_note.configure(state=tk.NORMAL)
                    self.check_bib.configure(state=tk.NORMAL)
                    self.check_separate.configure(state=tk.NORMAL)
                    self.check_iszotero.configure(state=tk.NORMAL)
                    self.check_custom_template.configure(state=tk.NORMAL)
                    self.messagelabel.configure(text='Message')
                    return
            except Queue.Empty:
                pass
        self.after(100, self.reset)

    def stop(self):
        #self.workthread.stop()
        pass

    def addMessageFrame(self):
        frame = Frame(self)
        frame.pack(fill=tk.BOTH,side=tk.TOP,\
                expand=1,padx=8,pady=5)

        self.messagelabel = tk.Label(frame, text='Message', bg='#bbb')
        self.messagelabel.pack(side=tk.TOP, fill=tk.X)

        self.text = tk.Text(frame)
        self.text.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        self.text.height = 10

        scrollbar = tk.Scrollbar(self.text)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        self.text.config(yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.text.yview)
Пример #7
0
class JobUI(Toplevel):  # 编辑任务窗口
    def __init__(self, parent_window, job, parent_name, job_name):
        self.edit_job = Toplevel()
        Log()
        self.log = logging.getLogger("Data_Collect_Log")
        self.parent = parent_window
        self.edit_job.protocol("WM_DELETE_WINDOW", self.job_cancel)
        self.job_file_ext = '.dat'
        self.job_script_ext = '.bat'
        self.txt_text_job = StringVar()
        self.txt_text_task = StringVar()
        self.txt_text_desc = StringVar()
        self.txt_text_server = StringVar()
        self.txt_text_user = StringVar()
        self.txt_text_pwd = StringVar()
        self.txt_text_tablespace = StringVar()
        self.txt_text_script = StringVar()

        self.job_conf_content = None  # JOB配置内容
        self.job_script_content = None  # JOB脚本内容

        self.edit_job.geometry('600x520')
        self.edit_job.title(u'任务编辑')
        self.edit_job.iconbitmap('ico.ico')
        self.edit_job.resizable(width=False, height=False)

        entry_opt = {'column': 2, 'ipadx': 30, 'sticky': W}  # 文本框的字典GRID参数
        top_frame = Frame(self.edit_job)
        top_frame.configure(borderwidth=2, bg='gray')
        Label(top_frame, text="JOB", bg='gray').grid(row=0, column=1, sticky=W)
        self.combobox_Job_name = Combobox(top_frame,
                                          width=18,
                                          textvariable=self.txt_text_job,
                                          state='readonly')
        self.combobox_Job_name.grid(row=0, **entry_opt)
        Label(top_frame, text=u"任务名称", bg='gray').grid(row=1,
                                                       column=1,
                                                       sticky=W)
        self.entry_text_name = Entry(top_frame,
                                     textvariable=self.txt_text_task)
        self.entry_text_name.grid(row=1, **entry_opt)

        tip = Label(top_frame)
        tip.configure(text=u"任务名称不能为空,表空间用户名密码等信息并没有实际意义。仅仅是为了方便在主界面查看代码是否匹配!")
        tip.configure(bg='gray', wraplength=290, justify='left', fg='red')
        tip.grid(row=2, column=2, sticky=E, rowspan=3)
        Label(top_frame, text=u"任务描述", bg='gray').grid(row=2,
                                                       column=1,
                                                       sticky=W)
        self.entry_text_desc = Entry(top_frame,
                                     textvariable=self.txt_text_desc)
        self.entry_text_desc.grid(row=2, **entry_opt)
        Label(top_frame, text=u"服务器地址", bg='gray').grid(row=3,
                                                        column=1,
                                                        sticky=W)
        self.entry_text_server = Entry(top_frame,
                                       textvariable=self.txt_text_server)
        self.entry_text_server.grid(row=3, **entry_opt)
        Label(top_frame, text=u"用户名", bg='gray').grid(row=4,
                                                      column=1,
                                                      sticky=W)
        self.entry_text_user = Entry(top_frame,
                                     textvariable=self.txt_text_user)
        self.entry_text_user.grid(row=4, **entry_opt)
        Label(top_frame, text=u"密码", bg='gray').grid(row=5, column=1, sticky=W)
        self.entry_text_pwd = Entry(top_frame, textvariable=self.txt_text_pwd)
        self.entry_text_pwd.grid(row=5, **entry_opt)
        Label(top_frame, text=u"表空间", bg='gray').grid(row=6,
                                                      column=1,
                                                      sticky=W)
        self.entry_text_tablespace = Entry(
            top_frame, textvariable=self.txt_text_tablespace)
        self.entry_text_tablespace.grid(row=6, **entry_opt)
        Label(top_frame, text=u"脚本", bg='gray').grid(row=7, column=1, sticky=W)
        self.entry_text_script = ScrolledText(top_frame, width=64, height=25)
        self.entry_text_script.grid(row=7, **entry_opt)
        top_frame.pack(side=TOP)

        bottom_frame = Frame(self.edit_job)
        bottom_frame.configure(height=30, borderwidth=2)
        bottom_frame.pack_propagate(0)
        button_ok = Button(bottom_frame,
                           text=u"保 存",
                           command=self.check_entry_is_empty)
        button_ok.pack(side=LEFT, padx=150, ipadx=10)

        button_cancel = Button(bottom_frame,
                               text=u"取 消",
                               command=self.job_cancel)
        button_cancel.pack(
            side=LEFT,
            ipadx=10,
        )
        bottom_frame.pack(side=BOTTOM, fill=X)
        self.edit_job.update_idletasks()
        self.init_ui(job, parent_name, job_name)
        self.edit_job.deiconify()
        x, y = self.center(600, 520)
        self.edit_job.geometry('%dx%d+%d+%d' % (600, 520, x, y))
        self.edit_job.deiconify()
        self.edit_job.focus_force()

    def init_ui(self, job, parent, job_name):
        u"""
        根据传入的参数,决定窗口的初始状态
        :param job: 0-新建菜单点击创建 1-JOB树右键新建JOB菜单 2-双击JOB 3--菜单打开JOB菜单调用
        :param parent: 父节点
        :param job_name: 节点名称_job_name
        :return:
        """
        if job == 0:
            value_combobox = ManageJob.scan_all_job()
            tuple(value_combobox)
            self.combobox_Job_name['values'] = value_combobox
            self.parent.hide()
        elif job == 1:
            self.txt_text_job.set(job_name)
            self.combobox_Job_name.configure(state='disabled')
            self.parent.hide()
        elif job == 2:
            file_path = ManageJob.get_conf_path(parent, job_name)
            script_path = ManageJob.get_script_path(parent, job_name)
            try:
                self.job_conf_content = open(file_path).readlines()
                self.job_script_content = open(script_path).read()
                self.parent.hide()
            except Exception, e:
                self.log.error(parent + '_' + job_name + u'读取失败' +
                               e.message.decode('gbk'))
                tkMessageBox.showinfo(title=u'警告', message=e.message)
                self.edit_job.destroy()
            self.set_text_value(parent)
            self.combobox_Job_name.configure(state='disabled')
        elif job == 3:
            parent = job_name[job_name.find('Job') +
                              4:job_name.find('/JobConf')]
            job_name = os.path.split(job_name)[1][:-4]
            file_path = ManageJob.get_conf_path(parent, job_name)
            script_path = ManageJob.get_script_path(parent, job_name)
            self.job_conf_content = open(file_path).readlines()
            self.job_script_content = open(script_path).read()
            self.set_text_value(parent)
            self.parent.hide()
Пример #8
0
class Example(Frame):
    counter = 0

    def __init__(self, parent):
        Frame.__init__(self, parent)

        self.parent = parent

        self.initUI()

    def nuevoVoluntario(self, nombre, apellidos, dni, direccion, correo_electronico, localidad_id, estudio_id,
                        parroquial_id, proyecto_id, telefono_1, telefono_2, genero, fecha_nacimiento,t,estado,id):
        global cnx
        cursor = cnx.cursor()
        if estado:
            query = (
                "INSERT INTO caritas.voluntario (nombre, apellidos, dni, direccion, correo_electronico, localidad_id, estudio_id, parroquial_id, proyecto_id, telefono_1, telefono_2, genero, fecha_nacimiento) VALUES ('%s','%s','%s','%s','%s','%d','%d','%d','%d','%s','%s','%s','%s')" % (
                    nombre, apellidos, dni, direccion, correo_electronico, localidad_id, estudio_id, parroquial_id,
                    proyecto_id,
                    telefono_1, telefono_2, genero, fecha_nacimiento))
        else:
            query = (
                "UPDATE caritas.voluntario SET nombre = ('%s'), apellidos = ('%s'), dni = ('%s'), direccion = ('%s'), correo_electronico = ('%s'), localidad_id = ('%d'), estudio_id = ('%d'), parroquial_id = ('%d'),proyecto_id = ('%d'), telefono_1 = ('%s'), telefono_2 = ('%s'), genero = ('%s'), fecha_nacimiento = ('%s') WHERE id = ('%d')"
                % ( nombre, apellidos, dni, direccion, correo_electronico, localidad_id, estudio_id, parroquial_id,proyecto_id, telefono_1, telefono_2, genero, fecha_nacimiento,id))
        cursor.execute(query)
        cnx.commit()
        cursor.close()

        t.destroy()

    def getEstudios(self):
        global cnx
        cursor = cnx.cursor(dictionary=True)
        query = ("SELECT * FROM estudio e")
        cursor.execute(query)
        valores = []
        strings = []
        for row in cursor:
            valores.append(row['id'])
            strings.append(row['nombre'])

        cursor.close()
        self.listadoEstudios = [strings, valores]

    def getParroquial(self):
        global cnx
        cursor = cnx.cursor(dictionary=True)
        query = ("SELECT * FROM parroquial e")
        cursor.execute(query)
        valores = []
        strings = []
        for row in cursor:
            valores.append(row['id'])
            strings.append(row['nombre'])

        cursor.close()
        self.listadoParroquial = [strings, valores]

    def getPais(self):
        global cnx
        cursor = cnx.cursor(dictionary=True)
        query = ("SELECT * FROM pais e")
        cursor.execute(query)
        valores = []
        strings = []
        for row in cursor:
            valores.append(row['id'])
            strings.append(row['nombre'])

        cursor.close()
        self.listadoPais = [strings, valores]

    def nuevoEstudio(self):
        t = Toplevel(self)
        t.wm_title("Estudio")

        Label(t, text="Nombre").grid(row=0, column=1)
        E2 = Entry(t)
        E2.grid(row=1, column=1)

        button1 = Button(t, text="Cancelar", command=lambda: t.destroy())
        button2 = Button(t, text="Guardar", command=lambda: self.nuevaEntradaEstudios(E2.get(), t))
        button3 = Button(t, text="Borrar", command=lambda: self.BorrarEstudios(E2.get(), t))
        button3.config(state="disabled")

        button1.grid(row=2, column=0)
        button2.grid(row=2, column=1)
        button3.grid(row=2, column=2)

    def nuevoPais(self):
        t = Toplevel(self)
        t.wm_title("Pais")

        Label(t, text="Nombre").grid(row=0, column=1)
        E2 = Entry(t)
        E2.grid(row=1, column=1)

        button1 = Button(t, text="Cancelar", command=lambda: t.destroy())
        button2 = Button(t, text="Guardar", command=lambda: self.nuevaEntradaPais(E2.get(), t))
        button3 = Button(t, text="Borrar", command=lambda: self.BorrarPais(E2.get(), t))
        button3.config(state="disabled")

        button1.grid(row=2, column=0)
        button2.grid(row=2, column=1)
        button3.grid(row=2, column=2)

    def nuevaParroquia(self):
        t = Toplevel(self)
        t.wm_title("Parroquial")

        Label(t, text="Nombre").grid(row=0, column=1)
        E2 = Entry(t)
        E2.grid(row=1, column=1)

        button1 = Button(t, text="Cancelar", command=lambda: t.destroy())
        button2 = Button(t, text="Guardar", command=lambda: self.nuevaEntradaParroquia(E2.get(), t))
        button3 = Button(t, text="Borrar", command=lambda: self.BorrarParroquial(E2.get(), t))
        button3.config(state="disabled")

        button1.grid(row=2, column=0)
        button2.grid(row=2, column=1)
        button3.grid(row=2, column=2)

    def editarEstudio(self):
        t = Toplevel(self)
        t.wm_title("Estudio")

        Label(t, text="Nombre").grid(row=0, column=1)
        E2 = Entry(t)
        E2.insert(END, self.selectorEstudios.get())
        E2.grid(row=1, column=1)

        nombreOld = self.selectorEstudios.get()


        button1 = Button(t, text="Cancelar", command=lambda: t.destroy())
        button2 = Button(t, text="Guardar", command=lambda: self.actualizarEstudio(nombreOld, E2.get(), t))
        button3 = Button(t, text="Borrar", command=lambda: self.BorrarEstudios(E2.get(), t))

        button1.grid(row=2, column=0)
        button2.grid(row=2, column=1)
        button3.grid(row=2, column=2)

    def editarPais(self):
        t = Toplevel(self)
        t.wm_title("Pais")

        Label(t, text="Nombre").grid(row=0, column=1)
        E2 = Entry(t)
        E2.insert(END, self.selectorPais.get())
        E2.grid(row=1, column=1)

        nombreOld = self.selectorPais.get()

        button1 = Button(t, text="Cancelar", command=lambda: t.destroy())
        button2 = Button(t, text="Guardar", command=lambda: self.actualizarPais(nombreOld, E2.get(), t))
        button3 = Button(t, text="Borrar", command=lambda: self.BorrarPais(E2.get(), t))

        button1.grid(row=2, column=0)
        button2.grid(row=2, column=1)
        button3.grid(row=2, column=2)

    def editarParroquia(self):
        t = Toplevel(self)
        t.wm_title("Estudio")

        Label(t, text="Nombre").grid(row=0, column=1)
        E2 = Entry(t)
        E2.insert(END, self.selectorParroquial.get())
        E2.grid(row=1, column=1)

        nombreOld = self.selectorParroquial.get()

        button1 = Button(t, text="Cancelar", command=lambda: t.destroy())
        button2 = Button(t, text="Guardar", command=lambda: self.actualizarParroquia(nombreOld, E2.get(), t))
        button3 = Button(t, text="Borrar", command=lambda: self.BorrarParroquial(E2.get(), t))

        button1.grid(row=2, column=0)
        button2.grid(row=2, column=1)
        button3.grid(row=2, column=2)

    def actualizarPais(self, nombreOld, nombreN, t):
        global cnx
        cursor = cnx.cursor()
        query = ("UPDATE caritas.pais SET nombre= ('%s') WHERE nombre = ('%s')" % (nombreN, nombreOld))
        cursor.execute(query)
        cnx.commit()
        cursor.close()

        self.getPais()
        self.selectorPais['values'] = self.listadoPais[0]

        t.destroy()

    def actualizarEstudio(self, nombreOld, nombreN, t):
        global cnx
        cursor = cnx.cursor()
        query = ("UPDATE caritas.estudio SET nombre= ('%s') WHERE nombre = ('%s')" % (nombreN, nombreOld))
        cursor.execute(query)
        cnx.commit()
        cursor.close()

        self.getEstudios()
        self.selectorEstudios['values'] = self.listadoEstudios[0]

        t.destroy()

    def actualizarParroquia(self, nombreOld, nombreN, t):
        global cnx
        cursor = cnx.cursor()
        query = ("UPDATE caritas.parroquial SET nombre= ('%s') WHERE nombre = ('%s')" % (nombreN, nombreOld))
        cursor.execute(query)
        cnx.commit()
        cursor.close()

        self.getParroquial()
        self.selectorParroquial['values'] = self.listadoParroquial[0]

        t.destroy()

    def BorrarEstudios(self, nombre, t):
        global cnx
        cursor = cnx.cursor()
        query = ("DELETE FROM caritas.estudio WHERE nombre = ('%s')" % nombre)
        cursor.execute(query)
        cnx.commit()
        cursor.close()

        self.getEstudios()
        self.selectorEstudios['values'] = self.listadoEstudios[0]

        t.destroy()

    def BorrarPais(self, nombre, t):
        global cnx
        cursor = cnx.cursor()
        query = ("DELETE FROM caritas.pais WHERE nombre = ('%s')" % nombre)
        cursor.execute(query)
        cnx.commit()
        cursor.close()

        self.getPais()
        self.selectorPais['values'] = self.listadoPais[0]

        t.destroy()

    def BorrarParroquial(self, nombre, t):
        global cnx
        cursor = cnx.cursor()
        query = ("DELETE FROM caritas.parroquial WHERE nombre = ('%s')" % nombre)
        cursor.execute(query)
        cnx.commit()
        cursor.close()

        self.getParroquial()
        self.selectorParroquial['values'] = self.listadoParroquial[0]

        t.destroy()

    def nuevaEntradaEstudios(self, nombre, t):
        global cnx
        cursor = cnx.cursor()
        query = ("INSERT INTO caritas.estudio (nombre) VALUE ('%s')" % nombre)
        cursor.execute(query)
        cnx.commit()
        cursor.close()

        self.getEstudios()
        self.selectorEstudios['values'] = self.listadoEstudios[0]

        t.destroy()

    def nuevaEntradaPais(self, nombre, t):
        global cnx
        cursor = cnx.cursor()
        query = ("INSERT INTO caritas.pais (nombre) VALUE ('%s')" % nombre)
        cursor.execute(query)
        cnx.commit()
        cursor.close()

        self.getPais()
        self.selectorPais['values'] = self.listadoPais[0]

        t.destroy()

    def nuevaEntradaParroquia(self, nombre, t):
        global cnx
        cursor = cnx.cursor()
        query = ("INSERT INTO caritas.parroquial (nombre) VALUE ('%s')" % nombre)
        cursor.execute(query)
        cnx.commit()
        cursor.close()

        self.getParroquial()
        self.selectorParroquial['values'] = self.listadoParroquial[0]

        t.destroy()

    def ventanaVoluntarios(self,row):

        id = -1
        guardar = TRUE
        # Creamos una ventana nueva
        t = Toplevel(self)
        t.wm_title("Crear Voluntario")

        # Etiqueta y entrada de nombre
        Label(t, text="Nombre").grid(row=0)
        entradaNombre = Entry(t)
        entradaNombre.grid(row=0, column=1,sticky = "ew")

        # Etiqueta y entrada de apellidos
        Label(t, text="Apellidos").grid(row=1)
        entradaApellidos = Entry(t)
        entradaApellidos.grid(row=1, column=1,sticky = "ew")

        # Etiqueta y entrada de DNI
        Label(t, text="DNI").grid(row=2)
        entradaDNI = Entry(t)
        entradaDNI.grid(row=2, column=1,sticky = "ew")

        # Etiqueta y entrada de Dirreccion
        Label(t, text="Direccion").grid(row=3)
        entradaDireccion = Entry(t)
        entradaDireccion.grid(row=3, column=1)

        # Etiqueta y seleccion de Estudios
        Label(t, text="Estudios").grid(row=4)
        box_value = StringVar()
        self.getEstudios()
        self.selectorEstudios = Combobox(t, textvariable=box_value, state='readonly')
        self.selectorEstudios['values'] = self.listadoEstudios[0]
        self.selectorEstudios.configure(width=25)
        self.selectorEstudios.current(0)
        self.selectorEstudios.grid(row=4, column=1)

        botonEditarEstudios = Button(t, text="Editar", command=self.editarEstudio)
        botonNuevosEstudios = Button(t, text="Nuevo", command=self.nuevoEstudio)
        botonEditarEstudios.grid(row=4, column=2)
        botonNuevosEstudios.grid(row=4, column=3)

        # Etiqueta y seleccion de Genero
        Label(t, text="Genero").grid(row=5)
        seleccionGenero = Combobox(t, values=["Masculino (M)", "Femenino (F)"], state='readonly')
        seleccionGenero.grid(row=5, column=1)

        # Etiqueta y seleccion de Parroquial
        Label(t, text="Parroquial").grid(row=6)
        box_value = StringVar()
        self.getParroquial()
        self.selectorParroquial = Combobox(t, textvariable=box_value, state='readonly')
        self.selectorParroquial['values'] = self.listadoParroquial[0]
        self.selectorParroquial.configure(width=25)
        self.selectorParroquial.current(0)
        self.selectorParroquial.grid(row=6, column=1)

        botonEditarParroquial = Button(t, text="Editar", command=self.editarParroquia)
        botonNuevaParroqual = Button(t, text="Nuevo", command=self.nuevaParroquia)
        botonEditarParroquial.grid(row=6, column=2)
        botonNuevaParroqual.grid(row=6, column=3)

        # Etiqueta y seleccion de Correo
        Label(t, text="Correo").grid(row=0, column=4)
        entradaCorreo = Entry(t)
        entradaCorreo.grid(row=0, column=5)

        Label(t, text="Telefono 1").grid(row=1, column=4)
        entradaTelefono1 = Entry(t)
        entradaTelefono1.grid(row=1, column=5)

        Label(t, text="Telefono 2").grid(row=2, column=4)
        entradaTelefono2 = Entry(t)
        entradaTelefono2.grid(row=2, column=5)

        # Etiqueta y entrada de Fecha
        Label(t, text="Fecha").grid(row=3, column=4)
        entradaAno = Entry(t)
        entradaMes = Entry(t)
        entradaDia = Entry(t)
        entradaAno.grid(row=3, column=5)
        entradaMes.grid(row=3, column=6)
        entradaDia.grid(row=3, column=7)

        # Etiqueta y seleccion de Pais
        Label(t, text="Pais").grid(row=4, column=4)
        box_value = StringVar()
        self.getPais()
        self.selectorPais = Combobox(t, textvariable=box_value, state='readonly')
        self.selectorPais['values'] = self.listadoPais[0]
        self.selectorPais.configure(width=25)
        self.selectorPais.current(0)
        self.selectorPais.grid(row=4, column=5)

        botonEditarPais = Button(t, text="Editar", command=self.editarPais)
        botonNuevaPais = Button(t, text="Nuevo", command=self.nuevoPais)
        botonEditarPais.grid(row=4, column=6)
        botonNuevaPais.grid(row=4, column=7)

        #Rellenamos los cambos si estamos editando
        if row > -1:
            voluntario = self.table.model.getRecordAtRow(row)
            entradaNombre.insert(END,voluntario['nombre'])
            entradaApellidos.insert(END,voluntario['apellidos'])
            entradaCorreo.insert(END,voluntario['correo_electronico'])
            entradaTelefono1.insert(END,voluntario['telefono_1'])
            entradaTelefono2.insert(END,voluntario['telefono_2'])
            entradaDireccion.insert(END,voluntario['direccion'])
            entradaDNI.insert(END,voluntario['dni'])
            self.selectorEstudios.set(voluntario['estudio'])
            self.selectorParroquial.set(voluntario['parroquial'])
            guardar = FALSE
            id = voluntario['id']





        button5 = Button(t, text="Guardar", command=lambda: self.nuevoVoluntario(entradaNombre.get(),
                                                                                 entradaApellidos.get(),entradaDNI.get(),entradaDireccion.get(),
                                                                                 entradaCorreo.get(),1,self.listadoEstudios[1][self.selectorEstudios.current()],
                                                                                 self.listadoParroquial[1][self.selectorParroquial.current()],
                                                                                 1,entradaTelefono1.get(),entradaTelefono2.get(),"M","2001-01-01",t,guardar,id))
        button6 = Button(t, text="Cancelar", command=t.destroy)

        button5.grid(row=7, column=4)
        button6.grid(row=7, column=5)


    def validarVoluntario(self, nombre, apellidos, dni, direccion, correo_electronico, localidad_id, estudio_id,
                        parroquial_id, proyecto_id, telefono_1, telefono_2, genero, fecha_nacimiento,t,estado,id):

        guarda = True
        error = ""

        if len(nombre)<3 :
            error = error + "Nombre debe tener mas de 2 caracteres\n"
            guarda = False

        if len(apellidos)<3 :
            error = error + "Apellidos debe tener mas de 2 caracteres\n"
            guarda = False

        if len(dni)==9 and dni[8].isalpha() and dni[0-7].isdigit():
            error = error + "Dni tiene el formato NNNNNNNNX donde N es un digito y X una letra \n"
            guarda = False

        if len(direccion)==0:
            error = error + "Introduzca una Dirección \n"
            guarda = False

        if len(correo_electronico)<5:
            error = error + "Introduzca una dirección de correo valida \n"
            guarda = False


        if len(telefono_1)<9:
            error = error + "Introduzca un numero valido \n"
            guarda = False

        if len(telefono_1)==0:
            telefono_1=0

        if guarda:self.nuevoVoluntario(nombre, apellidos, dni, direccion, correo_electronico, localidad_id, estudio_id,
                        parroquial_id, proyecto_id, telefono_1, telefono_2, genero, fecha_nacimiento,t,estado,id)
        # añadir el error
        else:
            print error

    def ventanaImprimir(self):
        t = Toplevel(self)
        t.wm_title("Imprimir")

        Label(t, text="Numero de Copias por etiqueta").pack()
        w = Spinbox(t, from_=1, to=10)
        w.pack()

        buttonImprimir = Button(t, text="Imprimir",  command=lambda:self.imprimir(int(w.get()),t))
        buttonImprimir.pack()

    def agregarListado(self,numero):
        voluntario = self.table.model.getRecordAtRow(numero)
        modelNuevo = TableModel()

        modelNuevo.addColumn("nombre")
        modelNuevo.addColumn("apellidos")
        modelNuevo.addColumn("dni")
        modelNuevo.addColumn("direccion")
        modelNuevo.addColumn("correo_electronico")
        modelNuevo.addColumn("estudio")
        modelNuevo.addColumn("parroquial")
        modelNuevo.addColumn("proyecto")
        modelNuevo.addColumn("genero")
        modelNuevo.addColumn("fecha_nacimiento")
        modelNuevo.addColumn("telefono_1")
        modelNuevo.addColumn("telefono_2")

        arrayListado = self.selectTable.getModel().data
        valores = {}
        i=1
        for values in arrayListado:
            valores['row',i]=arrayListado['row',i]
            i+=1
        valores['row',i]=voluntario
        modelNuevo.importDict(valores)

        self.selectTable.updateModel(modelNuevo)
        self.selectTable.redrawTable()

    def quitarListado(self,numero):
        voluntario = self.selectTable.model.getRecordAtRow(numero)
        modelNuevo = TableModel()

        modelNuevo.addColumn("nombre")
        modelNuevo.addColumn("apellidos")
        modelNuevo.addColumn("dni")
        modelNuevo.addColumn("direccion")
        modelNuevo.addColumn("correo_electronico")
        modelNuevo.addColumn("estudio")
        modelNuevo.addColumn("parroquial")
        modelNuevo.addColumn("proyecto")
        modelNuevo.addColumn("genero")
        modelNuevo.addColumn("fecha_nacimiento")
        modelNuevo.addColumn("telefono_1")
        modelNuevo.addColumn("telefono_2")

        print numero

        arrayListado = self.selectTable.getModel().data
        valores = {}
        i=1
        for values in arrayListado:
            if numero+1 != i:
                valores['row',i]=arrayListado['row',i]
            i+=1
        modelNuevo.importDict(valores)

        self.selectTable.updateModel(modelNuevo)
        self.selectTable.redrawTable()

    def imprimir(self,numero,label):
        pdf = fpdf.FPDF(format='letter')
        pdf.add_page()
        pdf.set_font("Arial", size=14)

        indice=1
        columna=1
        fila=0
        p=0
        for ficha in self.listadoSeleccionado:
            row = self.listadoSeleccionado['row',indice]
            for x in range(0, numero):
                if p==9:
                    pdf.add_page()
                    p=0
                else:
                    p+=1

                texto = 'Nombre: %s\nApellidos: %s\nDireccion: %s\nTelefono: %s' %(row["nombre"],row["apellidos"],row["direccion"],row["telefono_1"])
                pdf.multi_cell(65, 10,texto,align='C')
                pdf.set_xy(70*columna,60*fila +10)
                columna = columna + 1
                if columna == 4:
                    columna=1
                    fila=fila+1
                    pdf.set_xy(10,60*fila +10)

            indice = indice + 1
        pdf.output("tutorial.pdf")

        label.destroy()

    def buscar(self,nombre,apellidos):

        modelCompleto = TableModel()
        modelNuevo = TableModel()

        modelNuevo.addColumn("nombre")
        modelNuevo.addColumn("apellidos")
        modelNuevo.addColumn("dni")
        modelNuevo.addColumn("direccion")
        modelNuevo.addColumn("correo_electronico")
        modelNuevo.addColumn("estudio")
        modelNuevo.addColumn("parroquial")
        modelNuevo.addColumn("proyecto")
        modelNuevo.addColumn("genero")
        modelNuevo.addColumn("fecha_nacimiento")
        modelNuevo.addColumn("telefono_1")
        modelNuevo.addColumn("telefono_2")

        self.listilla= queryAllVoluntarios()
        modelCompleto.importDict(self.listilla)
        searchterms = [('nombre', nombre, 'contains', 'AND'),('apellidos', apellidos, 'contains', 'AND')]
        result=modelCompleto.getDict(modelCompleto.columnNames, filters=searchterms)
        modelNuevo.importDict(result)
        self.listadoSeleccionado = result
        self.table.updateModel(modelNuevo)
        self.table.redrawTable()

    def eventoClic(self):
        print "Clicado"
        return


    def initUI(self):

        self.parent.title("Caritas")
        self.style = Style()
        self.style.theme_use("default")

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

        frameMenu = Frame(self)
        frameMenu.pack(fill="both", expand="0", side=RIGHT)

        labelBusqueda = LabelFrame(frameMenu, text="Busqueda")
        labelBusqueda.pack(fill="x",expand =1)

        labelVoluntarios = LabelFrame(frameMenu)
        labelVoluntarios.pack(fill="both",expand =0)

        frameTabla = Frame(self)
        frameTabla.pack(fill="both", expand="1", side=LEFT)

        labelTabla = LabelFrame(frameTabla)
        labelTabla.pack(fill="both", expand="1")

        labelBotonera = LabelFrame(frameTabla)
        labelTabla.pack(fill="both", expand="1")

        labelSelect = LabelFrame(frameTabla)
        labelSelect.pack(fill="both", expand="1")

        model = TableModel()
        modelSelect = TableModel()

        model.addColumn("nombre")
        model.addColumn("apellidos")
        model.addColumn("dni")
        model.addColumn("direccion")
        model.addColumn("correo_electronico")
        model.addColumn("estudio")
        model.addColumn("parroquial")
        model.addColumn("proyecto")
        model.addColumn("genero")
        model.addColumn("fecha_nacimiento")
        model.addColumn("telefono_1")
        model.addColumn("telefono_2")

        modelSelect.addColumn("nombre")
        modelSelect.addColumn("apellidos")
        modelSelect.addColumn("dni")
        modelSelect.addColumn("direccion")
        modelSelect.addColumn("correo_electronico")
        modelSelect.addColumn("estudio")
        modelSelect.addColumn("parroquial")
        modelSelect.addColumn("proyecto")
        modelSelect.addColumn("genero")
        modelSelect.addColumn("fecha_nacimiento")
        modelSelect.addColumn("telefono_1")
        modelSelect.addColumn("telefono_2")

        #Tabla Voluntarios
        self.listilla= queryAllVoluntarios()
        model.importDict(self.listilla)
        self.table = TableCanvas(labelTabla, model=model,editable=False)
        self.table.createTableFrame()
        self.table.handle_double_click(self.eventoClic)

        #Tabla Seleccionados
        self.selectTable = TableCanvas(labelSelect, model=modelSelect,editable=False)
        self.selectTable.createTableFrame()
        self.listadoSeleccionado = []

        L1 = Label(labelBusqueda, text="Nombre")
        L1.pack()
        E1 = Entry(labelBusqueda)
        E1.pack()

        L2 = Label(labelBusqueda, text="Apellidos")
        L2.pack()
        E2 = Entry(labelBusqueda)
        E2.pack()

        botonArriba = Button(labelVoluntarios, text="Agregar al listado",  command=lambda:self.agregarListado(self.table.getSelectedRow()))
        botonArriba.pack()
        botonAbajo = Button(labelVoluntarios, text="Quitar del listado",  command=lambda:self.quitarListado(self.selectTable.getSelectedRow()))
        botonAbajo.pack()

        button = Button(labelBusqueda, text="Buscar", command=lambda: self.buscar(E1.get(),E2.get()))
        button.pack()

        button = Button(labelVoluntarios, text="Nuevo Voluntario",  command=lambda:self.ventanaVoluntarios(-1))
        button.pack()

        buttonEditar = Button(labelVoluntarios, text="Editar Voluntario",  command=lambda:self.ventanaVoluntarios(self.table.getSelectedRow()))
        buttonEditar.pack()

        buttonImprimir = Button(labelVoluntarios, text="Imprimir",  command=lambda:self.ventanaImprimir())
        buttonImprimir.pack()
Пример #9
0
class IniGenGui(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.parent = parent
        self.inigen = IniGen()
        self.initUIGlobals()

    def initUIGlobals(self):
        """
      This is the first part of the window to be rendered. After these have been
       set by the user and 'Emit Globals' has been clicked, the given algorithm
       can then specify how to generate the second part of the window. All fields
       are disabled for user input after globals have been emitted.

      Information in Global Parameters:
        Algorithm
          - name of the algorithm to use
        File Name
          - name of the output file to be generated
        Min Time
          - Minimum Time for distillers to run
        Max Time
          - Maximum Time for distillers to run
        Set Enabled:
          - checkbox to specify if the distiller should be enabled True or False
    """
        self.parent.title("Ini Generator")

        Style().configure("TButton", padding=(0, 5, 0, 5), font='serif 10')

        # initialize row counter. This is incremented after each element added to grid
        row = 0
        # initialize column counter. This is incremented after a column has been filled
        self.column = 0

        # Globals: entries for info common to all runs
        label_globals = Label(self, text="Globals")
        label_globals.grid(row=row, column=self.column)
        row += 1

        label_alg = Label(self, text="Algorithm")
        label_alg.grid(row=row, column=self.column, sticky=E + W)
        row += 1
        self.cbox_alg = Combobox(self,
                                 values=algorithms.keys(),
                                 state='readonly')
        self.cbox_alg.current(0)
        self.cbox_alg.grid(row=row, column=self.column, sticky=E + W + S + N)
        row += 1

        label_filename = Label(self, text="Output File Name")
        label_filename.grid(row=row, column=self.column, sticky=E + W)
        row += 1
        self.entry_filename = Entry(self)
        self.entry_filename.grid(row=row, column=self.column, sticky=W + E)
        row += 1

        label_mintime = Label(self, text="Min Time")
        label_mintime.grid(row=row, column=self.column, sticky=E + W)
        row += 1
        self.entry_mintime = Entry(self)
        self.entry_mintime.grid(row=row, column=self.column, sticky=W + E)
        row += 1

        label_maxtime = Label(self, text="Max Time")
        label_maxtime.grid(row=row, column=self.column, sticky=W + E)
        row += 1
        self.entry_maxtime = Entry(self)
        self.entry_maxtime.grid(row=row, column=self.column, sticky=W + E)
        row += 1

        self.enabled = IntVar()
        self.check_enabled = Checkbutton(self,
                                         text="set enabled",
                                         variable=self.enabled)
        self.check_enabled.grid(row=row, column=self.column, sticky=W + E)
        row += 1

        # Control: buttons used to emmiting text and generating file
        self.button_emit_globals = Button(self,
                                          text="Emit Globals",
                                          command=self.emit_globals)
        self.button_emit_globals.grid(row=row,
                                      column=self.column,
                                      sticky=W + E)
        row += 1

        button_addrun = Button(self, text="Add Run", command=self.emit_run)
        button_addrun.grid(row=row, column=self.column, sticky=W + E)
        row += 1

        button_generate = Button(self,
                                 text="Generate File",
                                 command=self.generate_file)
        button_generate.grid(row=row, column=self.column, sticky=W + E)
        row += 1

        self.column += 1

        self.pack()

    def initUIRuns(self):
        """
      Second part of gui to be rendered. This contains all the fields needed to emit
       a single run within a distiller file. Multiple runs can be added by clicking
       'Add Run' multiple times.

      Information in Run Parameters:
        Run Name
          - header name for run
        Dependencies
          - description and uuid fields for each dependency in the algorithm
        Params
          - parameter fields for each parameter in the algorithm
    """

        self.entry_run_name = None
        self.entries_dep_description = []
        self.entries_dep_uuid = []
        self.entries_param = []

        row = 0

        label_runs = Label(self, text="Runs")
        label_runs.grid(row=row, column=self.column)
        row += 1

        label_run_name = Label(self, text="Run Name")
        label_run_name.grid(row=row, column=self.column, sticky=W + E)
        row += 1

        self.entry_run_name = Entry(self)
        self.entry_run_name.grid(row=row, column=self.column, sticky=W + E)
        row += 1

        algorithm = self.cbox_alg.get()
        settings = algorithms[algorithm]

        for dep in settings['deps']:

            if row >= 21:
                self.column += 1
                row = 1

            label_dep_description = Label(self,
                                          text="{0} (description)".format(dep))
            label_dep_description.grid(row=row,
                                       column=self.column,
                                       sticky=W + E)
            row += 1

            entry_dep_description = Entry(self)
            entry_dep_description.grid(row=row,
                                       column=self.column,
                                       sticky=W + E)
            row += 1

            label_dep_uuid = Label(self, text="{0} (uuid)".format(dep))
            label_dep_uuid.grid(row=row, column=self.column, sticky=W + E)
            row += 1

            entry_dep_uuid = Entry(self)
            entry_dep_uuid.grid(row=row, column=self.column, sticky=W + E)
            row += 1

            self.entries_dep_description.append(entry_dep_description)
            self.entries_dep_uuid.append(entry_dep_uuid)

        for param in settings['params']:

            if row >= 21:
                self.column += 1
                row = 1

            label_param = Label(self, text=param)
            label_param.grid(row=row, column=self.column, sticky=W + E)
            row += 1

            entry_param = Entry(self)
            entry_param.grid(row=row, column=self.column, sticky=W + E)
            row += 1

            self.entries_param.append(entry_param)

        row = 0
        self.column += 1

        self.text_file = Text(self)
        self.text_file.grid(row=row,
                            column=self.column,
                            rowspan=31,
                            sticky=W + E + N + S,
                            padx=5,
                            pady=5)
        self.column += 1
        scrollbar = Scrollbar(self, command=self.text_file.yview)
        self.text_file.config(yscrollcommand=scrollbar.set)
        scrollbar.grid(row=row, column=self.column, rowspan=31, sticky=N + S)

        self.pack()

    def emit_globals(self):
        self.algorithm = algorithms[self.cbox_alg.get()]
        path = self.algorithm['path']
        if self.enabled.get():
            enabled = 'True'
        else:
            enabled = 'False'

        lines = self.inigen.emit_global(path, enabled)

        self.mintime = self.entry_mintime.get()
        self.maxtime = self.entry_maxtime.get()

        self.cbox_alg.configure(state='disabled')
        self.entry_filename.configure(state='disabled')
        self.entry_mintime.configure(state='disabled')
        self.entry_maxtime.configure(state='disabled')
        self.check_enabled.configure(state='disabled')
        self.button_emit_globals.configure(state='disabled')

        self.initUIRuns()
        self.update_text(lines)

    def emit_run(self):
        label = self.entry_run_name.get()
        chunking = 'parallel'  #hardcoded for now
        mintime = self.mintime
        maxtime = self.maxtime
        lines = self.inigen.emit_run_header(label, chunking, mintime, maxtime)
        self.update_text(lines)

        deps = []
        for i in range(len(self.entries_dep_description)):
            deps.append([
                self.entries_dep_description[i].get(),
                self.algorithm['deps'][i], self.entries_dep_uuid[i].get()
            ])
        params = []
        for i in range(len(self.entries_param)):
            params.append(
                [self.algorithm['params'][i], self.entries_param[i].get()])
        outputs = self.algorithm['outputs']
        lines = self.inigen.emit_run_body(deps, params, outputs)
        self.update_text(lines)

    def generate_file(self):
        self.inigen.generate_file(self.entry_filename.get())
        self.quit()

    def update_text(self, lines):
        self.text_file.configure(state='normal')
        string = "\n".join(lines)
        self.text_file.insert(END, string)
        self.text_file.configure(state='disabled')
Пример #10
0
class MainFrame(Frame):
    def __init__(self,parent,stdoutq):
        Frame.__init__(self,parent)

        self.parent=parent
        self.width=850
        self.height=650
        self.title=menotexport.__version__
        self.stdoutq=stdoutq

        self.initUI()

        self.hasdb=False
        self.hasout=False
        self.hasaction=False
        self.exit=False

        self.path_frame=self.addPathFrame()
        self.action_frame=self.addActionFrame()
        self.message_frame=self.addMessageFrame()
        self.printStr()

        self.stateq=Queue.Queue()
        #self.workproc=Pool(1)




    def centerWindow(self):
        sw=self.parent.winfo_screenwidth()
        sh=self.parent.winfo_screenheight()
        x=(sw-self.width)/2
        y=(sh-self.height)/2
        self.parent.geometry('%dx%d+%d+%d' \
                %(self.width,self.height,x,y))


    def initUI(self):
        self.parent.title(self.title)
        self.style=Style()
        #Choose from default, clam, alt, classic
        self.style.theme_use('alt')
        self.pack(fill=tk.BOTH,expand=True)
        self.centerWindow()


    def printStr(self):
        while self.stdoutq.qsize() and self.exit==False:
            try:
                msg=self.stdoutq.get()
                self.text.update()
                self.text.insert(tk.END,msg)
                self.text.see(tk.END)
            except Queue.Empty:
                pass
        self.after(100,self.printStr)


    def checkReady(self):
        if self.isexport.get()==1 or self.ishighlight.get()==1\
                or self.isnote.get()==1 or self.isbib.get()==1:
            self.hasaction=True
        else:
            self.hasaction=False

        if self.hasdb and self.hasout and self.hasaction:
            self.start_button.configure(state=tk.NORMAL)
            print('# <Menotexport>: Menotexport Ready.')
        else:
            self.start_button.configure(state=tk.DISABLED)


    def addPathFrame(self):
        frame=Frame(self)
        frame.pack(fill=tk.X,expand=0,side=tk.TOP,padx=8,pady=5)

        frame.columnconfigure(1,weight=1)

        #------------------Database file------------------
        label=tk.Label(frame,text='Mendeley Data file:',\
                bg='#bbb')
        label.grid(row=0,column=0,\
                sticky=tk.W,padx=8)

        self.db_entry=tk.Entry(frame)
        self.db_entry.grid(row=0,column=1,sticky=tk.W+tk.E,padx=8)

        self.db_button=tk.Button(frame,text='Open',command=self.openFile)
        self.db_button.grid(row=0,column=2,padx=8,sticky=tk.E)

        hint='''
Default location on Linux:
~/.local/share/data/Mendeley\ Ltd./Mendeley\ Desktop/[email protected]
Default location on Windows:
C:\Users\Your_name\AppData\Local\Mendeley Ltd\Mendeley Desktop\[email protected]'''

        hint_label=tk.Label(frame,text=hint,\
                justify=tk.LEFT,anchor=tk.NW)
        hint_label.grid(row=1,column=0,columnspan=3,\
                sticky=tk.W,padx=8)

        #--------------------Output dir--------------------
        label2=tk.Label(frame,text='Output folder:',\
                bg='#bbb')
        label2.grid(row=2,column=0,\
                sticky=tk.W,padx=8)

        self.out_entry=tk.Entry(frame)
        self.out_entry.grid(row=2,column=1,sticky=tk.W+tk.E,padx=8)
        self.out_button=tk.Button(frame,text='Choose',command=self.openDir)
        self.out_button.grid(row=2,column=2,padx=8,sticky=tk.E)
        


    def openDir(self):
        self.out_entry.delete(0,tk.END)
        dirname=askdirectory()
        self.out_entry.insert(tk.END,dirname)
        if len(dirname)>0:
            print('# <Menotexport>: Output folder: %s' %dirname)
            self.hasout=True
            self.checkReady()


    def openFile(self):
        self.db_entry.delete(0,tk.END)
        ftypes=[('sqlite files','*.sqlite'),('ALL files','*')]
        initialdir='~/.local/share/data/Mendeley Ltd./Mendeley Desktop'
        initialdir=os.path.expanduser(initialdir)
        if os.path.isdir(initialdir):
            filename=askopenfilename(filetypes=ftypes,initialdir=initialdir)
        else:
            filename=askopenfilename(filetypes=ftypes)
        self.db_entry.insert(tk.END,filename)
        if len(filename)>0:
            print('# <Menotexport>: Database file: %s' %filename)
            self.probeFolders()


    def probeFolders(self):
        dbfile=self.db_entry.get()
        try:
            db=sqlite3.connect(dbfile)
            self.menfolderlist=menotexport.getFolderList(db,None)   #(id, name)
            self.foldernames=['All']+[ii[1] for ii in self.menfolderlist] #names to display
            self.foldersmenu['values']=tuple(self.foldernames)
            self.foldersmenu.current(0)
            db.close()

            self.hasdb=True
            self.checkReady()

        except Exception as e:
            print('# <Menotexport>: Failed to recoganize the given database file.') 
            print(e)





    
    def addActionFrame(self):

        frame=Frame(self,relief=tk.RAISED,borderwidth=1)
        frame.pack(fill=tk.X,side=tk.TOP,\
                expand=0,padx=8,pady=5)

        label=tk.Label(frame,text='Actions:',bg='#bbb')
        label.grid(row=0,column=0,sticky=tk.W,padx=8)

        #---------------Action checkbuttons---------------
        self.isexport=tk.IntVar()
        self.ishighlight=tk.IntVar()
        self.isnote=tk.IntVar()
        self.isbib=tk.IntVar()
        self.isris=tk.IntVar()
        self.isseparate=tk.IntVar()
        self.iszotero=tk.IntVar()
        self.iscustomtemp=tk.IntVar()

        self.check_export=tk.Checkbutton(frame,text='Export PDFs',\
                variable=self.isexport,command=self.doExport)

        self.check_highlight=tk.Checkbutton(frame,\
                text='Extract highlights',\
                variable=self.ishighlight,command=self.doHighlight)

        self.check_note=tk.Checkbutton(frame,\
                text='Extract notes',\
                variable=self.isnote,command=self.doNote)

        self.check_bib=tk.Checkbutton(frame,\
                text='Export .bib',\
                variable=self.isbib,command=self.doBib)

        self.check_ris=tk.Checkbutton(frame,\
                text='Export .ris',\
                variable=self.isris,command=self.doRis)

        self.check_separate=tk.Checkbutton(frame,\
                text='Save separately',\
                variable=self.isseparate,command=self.doSeparate,\
                state=tk.DISABLED)

        self.check_iszotero=tk.Checkbutton(frame,\
                text='For import to Zotero',\
                variable=self.iszotero,command=self.doIszotero,\
                state=tk.DISABLED)

        self.check_custom_template=tk.Checkbutton(frame,\
                text='Use custom template (experimental)',\
                variable=self.iscustomtemp,command=self.doCustomTemp,\
                state=tk.DISABLED)

        frame.columnconfigure(0,weight=1)

        self.check_export.grid(row=1,column=1,padx=8,sticky=tk.W)
        self.check_highlight.grid(row=1,column=2,padx=8,sticky=tk.W)
        self.check_note.grid(row=1,column=3,padx=8,sticky=tk.W)
        self.check_bib.grid(row=2,column=1,padx=8,sticky=tk.W)
        self.check_ris.grid(row=2,column=2,padx=8,sticky=tk.W)
        self.check_separate.grid(row=2,column=3,padx=8,sticky=tk.W)
        self.check_iszotero.grid(row=3,column=1,padx=8,sticky=tk.W)
        self.check_custom_template.grid(row=3,column=2,padx=8,sticky=tk.W)

        #---------------------2nd row---------------------
        subframe=Frame(frame)
        subframe.grid(row=4,column=0,columnspan=6,sticky=tk.W+tk.E,\
                pady=5)

        #-------------------Folder options-------------------
        folderlabel=tk.Label(subframe,text='Mendeley folder:',\
                bg='#bbb')
        folderlabel.pack(side=tk.LEFT, padx=8)

        self.menfolder=tk.StringVar()
        self.menfolderlist=['All',]
        self.foldersmenu=Combobox(subframe,textvariable=\
                self.menfolder,values=self.menfolderlist,state='readonly')
        self.foldersmenu.current(0)
        self.foldersmenu.bind('<<ComboboxSelected>>',self.setfolder)
        self.foldersmenu.pack(side=tk.LEFT,padx=8)
        
        #-------------------Quit button-------------------
        quit_button=tk.Button(subframe,text='Quit',\
                command=self.quit)
        quit_button.pack(side=tk.RIGHT,padx=8)

        #-------------------Stop button-------------------
        '''
        self.stop_button=tk.Button(subframe,text='Stop',\
                command=self.stop)
        self.stop_button.pack(side=tk.RIGHT,padx=8)
        '''
                
        #-------------------Start button-------------------
        self.start_button=tk.Button(subframe,text='Start',\
                command=self.start,state=tk.DISABLED)
        self.start_button.pack(side=tk.RIGHT,pady=8)

        #-------------------Help button-------------------
        self.help_button=tk.Button(subframe,text='Help',\
                command=self.showHelp)
        self.help_button.pack(side=tk.RIGHT,padx=8)



    def setfolder(self,x):
        self.foldersmenu.selection_clear()
        self.menfolder=self.foldersmenu.get()
        self.foldersmenu.set(self.menfolder)
        if self.menfolder=='All':
            print('# <Menotexport>: Work on all folders.')
        else:
            print('# <Menotexport>: Select Mendeley folder: '+str(self.menfolder))



    def doExport(self):
        if self.isexport.get()==1:
            print('# <Menotexport>: Export annotated PDFs.')
        else:
            print('# <Menotexport>: Dont export annotated PDFs.')

        self.checkReady()



    def doHighlight(self):
        if self.ishighlight.get()==1:
            print('# <Menotexport>: Extract highlighted texts.')
            self.check_separate.configure(state=tk.NORMAL)
            self.check_custom_template.configure(state=tk.NORMAL)
        else:
            print('# <Menotexport>: Dont extract highlighted texts.')
            if self.isnote.get()==0:
                self.check_separate.configure(state=tk.DISABLED)
                self.check_custom_template.configure(state=tk.DISABLED)
        self.checkReady()

    def doNote(self):
        if self.isnote.get()==1:
            print('# <Menotexport>: Extract notes.')
            self.check_separate.configure(state=tk.NORMAL)
            self.check_custom_template.configure(state=tk.NORMAL)
        else:
            print('# <Menotexport>: Dont extract notes.')
            self.check_separate.state=tk.DISABLED
            if self.ishighlight.get()==0:
                self.check_separate.configure(state=tk.DISABLED)
                self.check_custom_template.configure(state=tk.DISABLED)
        self.checkReady()
        self.checkReady()

    def doBib(self):
        if self.isbib.get()==1:
            print('# <Menotexport>: Export to .bib file.')
            self.check_iszotero.configure(state=tk.NORMAL)
        else:
            print('# <Menotexport>: Dont export .bib file.')
            if self.isris.get()==0:
                self.check_iszotero.configure(state=tk.DISABLED)
        self.checkReady()

    def doRis(self):
        if self.isris.get()==1:
            print('# <Menotexport>: Export to .ris file.')
            self.check_iszotero.configure(state=tk.NORMAL)
        else:
            print('# <Menotexport>: Dont export .ris file.')
            if self.isbib.get()==0:
                self.check_iszotero.configure(state=tk.DISABLED)
        self.checkReady()

    def doSeparate(self):
        if self.isseparate.get()==1:
            print('# <Menotexport>: Save annotations separately.')
        else:
            print('# <Menotexport>: Save all annotations to single file.')

    def doIszotero(self):
        if self.iszotero.get()==1:
            print('# <Menotexport>: Save .bib/.ris file in Zotero preferred format.')
        else:
            print('# <Menotexport>: Save .bib/.ris file to default format.')

    def doCustomTemp(self):
        if self.iscustomtemp.get()==1:
            print('# <Menotexport>: Use custom template for exported annotations.')
        else:
            print('# <Menotexport>: Use default template for exported annotations.')



    def showHelp(self):
        helpstr='''
%s\n\n
- Export PDFs: Bulk export PDFs.\n
- Extract highlights: Extract highlighted texts and output to txt files.\n
- Extract notes: Extract notes and output to txt files.\n
- Export .bib: Export meta-data and annotations to .bib files.\n
- Export .ris: Export meta-data and annotations to .ris files.\n
- For import to Zotero: Exported .bib and/or .ris files have suitable format to import to Zotero.\n
- Save separately: If on, save each PDF's annotations to a separate txt.\n
- Use custom annotation template: Use a custom template to format the exported annotations.
  See annotation_template.py for details.
- See README.md for more info.\n
''' %self.title

        tkMessageBox.showinfo(title='Help', message=helpstr)
        #print(self.menfolder.get())




    def start(self):
        dbfile=self.db_entry.get()
        outdir=self.out_entry.get()
        self.menfolder=self.foldersmenu.get()

        # get (folderid, folder) for folder
        for ii in self.menfolderlist:
            if ii[1]==self.menfolder:
                folder_sel=[ii[0],ii[1].split('/')[-1]]

        action=[]
        if self.isexport.get()==1:
            action.append('p')
        if self.ishighlight.get()==1:
            action.append('m')
        if self.isnote.get()==1:
            action.append('n')
        if self.isbib.get()==1:
            action.append('b')
        if self.isris.get()==1:
            action.append('r')
        if self.isseparate.get()==1:
            separate=True
        else:
            separate=False
        if self.iszotero.get()==1:
            iszotero=True
        else:
            iszotero=False
        if self.iscustomtemp.get()==1:
            action.append('t')

            
        if 'p' in action or 'm' in action or 'n' in action or 'b' in action or 'r' in action:
            self.db_button.configure(state=tk.DISABLED)
            self.out_button.configure(state=tk.DISABLED)
            self.start_button.configure(state=tk.DISABLED)
            self.help_button.configure(state=tk.DISABLED)
            self.foldersmenu.configure(state=tk.DISABLED)
            self.check_export.configure(state=tk.DISABLED)
            self.check_highlight.configure(state=tk.DISABLED)
            self.check_note.configure(state=tk.DISABLED)
            self.check_bib.configure(state=tk.DISABLED)
            self.check_ris.configure(state=tk.DISABLED)
            self.check_separate.configure(state=tk.DISABLED)
            self.check_iszotero.configure(state=tk.DISABLED)
            self.check_custom_template.configure(state=tk.DISABLED)
            self.messagelabel.configure(text='Message (working...)')

            folder=None if self.menfolder=='All' else folder_sel

            args=[dbfile,outdir,action,folder,separate,iszotero,True]

            self.workthread=WorkThread('work',False,self.stateq)
            self.workthread.deamon=True

            self.workthread.args=args
            self.workthread.start()
            self.reset()
            '''
            self.workproc.apply_async(menotexport.main,args,\
                    callback=self.reset)
            self.workproc.join()
            '''



    def reset(self):
        while self.stateq.qsize() and self.exit==False:
            try:
                msg=self.stateq.get()
                if msg=='done':
                    self.db_button.configure(state=tk.NORMAL)
                    self.out_button.configure(state=tk.NORMAL)
                    self.start_button.configure(state=tk.NORMAL)
                    self.help_button.configure(state=tk.NORMAL)
                    self.foldersmenu.configure(state='readonly')
                    self.check_export.configure(state=tk.NORMAL)
                    self.check_highlight.configure(state=tk.NORMAL)
                    self.check_note.configure(state=tk.NORMAL)
                    self.check_bib.configure(state=tk.NORMAL)
                    self.check_separate.configure(state=tk.NORMAL)
                    self.check_iszotero.configure(state=tk.NORMAL)
                    self.check_custom_template.configure(state=tk.NORMAL)
                    self.messagelabel.configure(text='Message')
                    return
            except Queue.Empty:
                pass
        self.after(100,self.reset)


    
    def stop(self):
        #self.workthread.stop()
        pass
        

    def addMessageFrame(self):
        frame=Frame(self)
        frame.pack(fill=tk.BOTH,side=tk.TOP,\
                expand=1,padx=8,pady=5)

        self.messagelabel=tk.Label(frame,text='Message',bg='#bbb')
        self.messagelabel.pack(side=tk.TOP,fill=tk.X)

        self.text=tk.Text(frame)
        self.text.pack(side=tk.TOP,fill=tk.BOTH,expand=1)
        self.text.height=10

        scrollbar=tk.Scrollbar(self.text)
        scrollbar.pack(side=tk.RIGHT,fill=tk.Y)

        self.text.config(yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.text.yview)
Пример #11
0
class MainFrame(Frame):
    def __init__(self, parent, stdoutq):
        Frame.__init__(self, parent)

        self.parent = parent
        self.width = 750
        self.height = 450
        self.title = ximaexport.__version__
        self.stdoutq = stdoutq

        self.initUI()

        self.hasdb = False
        self.hasout = False
        self.exit = False

        self.path_frame = self.addPathFrame()
        self.action_frame = self.addActionFrame()
        self.message_frame = self.addMessageFrame()
        self.printStr()

        self.stateq = Queue.Queue()

    def centerWindow(self):
        sw = self.parent.winfo_screenwidth()
        sh = self.parent.winfo_screenheight()
        x = (sw - self.width) / 2
        y = (sh - self.height) / 2
        self.parent.geometry('%dx%d+%d+%d' \
                %(self.width,self.height,x,y))

    def initUI(self):
        self.parent.title(self.title)
        self.style = Style()
        #Choose from default, clam, alt, classic
        self.style.theme_use('alt')
        self.pack(fill=tk.BOTH, expand=True)
        self.centerWindow()

    def printStr(self):
        while self.stdoutq.qsize() and self.exit == False:
            try:
                msg = self.stdoutq.get()
                self.text.update()
                self.text.insert(tk.END, msg)
                self.text.see(tk.END)
            except Queue.Empty:
                pass
        self.after(100, self.printStr)

    def checkReady(self):

        if self.hasdb and self.hasout:
            self.start_button.configure(state=tk.NORMAL)
            #print('XimaExport Ready.')
            printch('XimaExport 就绪.')
        else:
            self.start_button.configure(state=tk.DISABLED)

    def addPathFrame(self):
        frame = Frame(self)
        frame.pack(fill=tk.X, expand=0, side=tk.TOP, padx=8, pady=5)

        frame.columnconfigure(1, weight=1)

        #------------------Database file------------------
        label=tk.Label(frame,text=dgbk('ting.sqlite文件:'),\
                bg='#bbb')
        label.grid(row=0,column=0,\
                sticky=tk.W,padx=8)

        self.db_entry = tk.Entry(frame)
        self.db_entry.grid(row=0, column=1, sticky=tk.W + tk.E, padx=8)

        self.db_button = tk.Button(frame,
                                   text=dgbk('打开'),
                                   command=self.openFile)
        self.db_button.grid(row=0, column=2, padx=8, sticky=tk.E)

        #--------------------Output dir--------------------
        label2=tk.Label(frame,text=dgbk('导出到文件夹:'),\
                bg='#bbb')
        label2.grid(row=2,column=0,\
                sticky=tk.W,padx=8)

        self.out_entry = tk.Entry(frame)
        self.out_entry.grid(row=2, column=1, sticky=tk.W + tk.E, padx=8)
        self.out_button = tk.Button(frame,
                                    text=dgbk('选择'),
                                    command=self.openDir)
        self.out_button.grid(row=2, column=2, padx=8, sticky=tk.E)

    def openDir(self):
        self.out_entry.delete(0, tk.END)
        dirname = askdirectory()
        self.out_entry.insert(tk.END, dirname)
        if len(dirname) > 0:
            #print('Output folder: %s' %dirname)
            printch('输出到文件夹:')
            print('   ' + dirname)
            self.hasout = True
            self.checkReady()

    def openFile(self):
        self.db_entry.delete(0, tk.END)
        ftypes = [('sqlite files', '*.sqlite'), ('ALL files', '*')]
        filename = askopenfilename(filetypes=ftypes)
        self.db_entry.insert(tk.END, filename)
        if len(filename) > 0:
            #print('Database file: %s' %filename)
            printch('数据文件:')
            print('   ' + filename)
            self.probeAlbums()

    def probeAlbums(self):
        dbfile = self.db_entry.get()
        try:
            db = sqlite3.connect(dbfile)
            df = ximaexport.getData(db)
            self.albumlist = ximaexport.getAlbumList(df, None)  #(id, name)
            self.albumnames = ['All'] + [ii[1] for ii in self.albumlist
                                         ]  #names to display
            self.albummenu['values'] = tuple(self.albumnames)
            self.albummenu.current(0)
            db.close()

            self.hasdb = True
            self.checkReady()

        except Exception as e:
            #print('Failed to recoganize the given database file.')
            printch('无法识别sqlite数据文件.')
            print(e)

    def addActionFrame(self):

        frame = Frame(self, relief=tk.RAISED, borderwidth=1)
        frame.pack(fill=tk.X,side=tk.TOP,\
                expand=0,padx=8,pady=5)

        #label=tk.Label(frame,text='Actions:',bg='#bbb')
        #label.grid(row=0,column=0,sticky=tk.W,padx=8)

        #---------------Action checkbuttons---------------
        frame.columnconfigure(0, weight=1)

        #---------------------2nd row---------------------
        subframe = Frame(frame)
        subframe.grid(row=1,column=0,columnspan=6,sticky=tk.W+tk.E,\
                pady=5)

        #-------------------Album options-------------------
        albumlabel=tk.Label(subframe,text=dgbk('专辑:'),\
                bg='#bbb')
        albumlabel.pack(side=tk.LEFT, padx=8)

        self.album = tk.StringVar()
        self.albumnames = [
            'All',
        ]
        self.albummenu=Combobox(subframe,textvariable=\
                self.album,values=self.albumnames,state='readonly')
        self.albummenu.current(0)
        self.albummenu.bind('<<ComboboxSelected>>', self.setAlbum)
        self.albummenu.pack(side=tk.LEFT, padx=8)

        #-------------------Quit button-------------------
        quit_button=tk.Button(subframe,text=dgbk('退出'),\
                command=self.quit)
        quit_button.pack(side=tk.RIGHT, padx=8)

        #-------------------Stop button-------------------
        '''
        self.stop_button=tk.Button(subframe,text='Stop',\
                command=self.stop)
        self.stop_button.pack(side=tk.RIGHT,padx=8)
        '''

        #-------------------Start button-------------------
        self.start_button=tk.Button(subframe,text=dgbk('开始'),\
                command=self.start,state=tk.DISABLED)
        self.start_button.pack(side=tk.RIGHT, pady=8)

        #-------------------Help button-------------------
        self.help_button=tk.Button(subframe,text=dgbk('帮助'),\
                command=self.showHelp)
        self.help_button.pack(side=tk.RIGHT, padx=8)

    def setAlbum(self, x):
        import json
        self.albummenu.selection_clear()
        self.album = self.albummenu.get()
        self.albummenu.set(self.album)
        if self.album == 'All':
            #print('Work on all albums.')
            printch('导出所有专辑.')
        else:
            #print('Select album: '+self.album)
            printch('导出所选专辑:')
            print('   ' + self.album)

    def showHelp(self):
        helpstr = dgbk('''\n\n
导出喜马拉雅下载音频,并自动按专辑归档、重命名:\n
1. 找到手机/pad中的喜马拉雅数据文件夹:\n
    (1)苹果用户:链接电脑itunes,在app一栏中找到“喜马拉雅”,单击,右侧会出现“喜马拉雅”的数据文件。选择“iDoc”,并导出到电脑。\n
    (2)安卓用户:链接电脑后,拷贝出ting文件夹。\n
2. 运行ximaexport-gui.exe。\n
    在 “ting.sqlite文件”一栏,选择步骤1中拷贝出的文件夹里的 ting.sqlite. 文件。\n
    在 “导出到文件夹”一栏,选择音频存储位置。\n
    在 “专辑”下拉菜单,选择要导出的专辑。若全部导出选择“All”。\n
    点击“开始”开始处理。
''')

        tkMessageBox.showinfo(title='Help', message=helpstr)
        #print(self.menfolder.get())

    def start(self):
        dbfile = self.db_entry.get()
        outdir = self.out_entry.get()
        self.album = self.albummenu.get()

        self.out_button.configure(state=tk.DISABLED)
        self.start_button.configure(state=tk.DISABLED)
        self.help_button.configure(state=tk.DISABLED)
        self.albummenu.configure(state=tk.DISABLED)
        self.messagelabel.configure(text=dgbk('信息 (处理中...)'))

        album = None if self.album == 'All' else self.album

        args = [dbfile, outdir, album, True]

        self.workthread = WorkThread('work', False, self.stateq)
        self.workthread.deamon = True

        self.workthread.args = args
        self.workthread.start()
        self.reset()

    def reset(self):
        while self.stateq.qsize() and self.exit == False:
            try:
                msg = self.stateq.get()
                if msg == 'done':
                    self.db_button.configure(state=tk.NORMAL)
                    self.out_button.configure(state=tk.NORMAL)
                    self.start_button.configure(state=tk.NORMAL)
                    self.help_button.configure(state=tk.NORMAL)
                    self.albummenu.configure(state='readonly')
                    self.messagelabel.configure(text=dgbk('消息'))
                    return
            except Queue.Empty:
                pass
        self.after(100, self.reset)

    def stop(self):
        #self.workthread.stop()
        pass

    def addMessageFrame(self):
        frame = Frame(self)
        frame.pack(fill=tk.BOTH,side=tk.TOP,\
                expand=1,padx=8,pady=5)

        self.messagelabel = tk.Label(frame, text=dgbk('消息'), bg='#bbb')
        self.messagelabel.pack(side=tk.TOP, fill=tk.X)

        self.text = tk.Text(frame)
        self.text.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        self.text.height = 10

        scrollbar = tk.Scrollbar(self.text)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        self.text.config(yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.text.yview)
class IniGenGui(Frame):

  def __init__(self, parent):
    Frame.__init__(self, parent)
    self.parent = parent
    self.inigen = IniGen()
    self.initUIGlobals()


  def initUIGlobals(self):
    """
      This is the first part of the window to be rendered. After these have been
       set by the user and 'Emit Globals' has been clicked, the given algorithm
       can then specify how to generate the second part of the window. All fields
       are disabled for user input after globals have been emitted.

      Information in Global Parameters:
        Algorithm
          - name of the algorithm to use
        File Name
          - name of the output file to be generated
        Min Time
          - Minimum Time for distillers to run
        Max Time
          - Maximum Time for distillers to run
        Set Enabled:
          - checkbox to specify if the distiller should be enabled True or False
    """
    self.parent.title("Ini Generator")

    Style().configure("TButton", padding=(0, 5, 0, 5), font='serif 10')

    # initialize row counter. This is incremented after each element added to grid
    row = 0
    # initialize column counter. This is incremented after a column has been filled
    self.column = 0

    # Globals: entries for info common to all runs
    label_globals = Label(self, text="Globals")
    label_globals.grid(row=row, column=self.column)
    row += 1

    label_alg = Label(self, text="Algorithm")
    label_alg.grid(row=row, column=self.column, sticky=E+W)
    row += 1
    self.cbox_alg = Combobox(self, values=algorithms.keys(), state='readonly')
    self.cbox_alg.current(0)
    self.cbox_alg.grid(row=row, column=self.column, sticky=E+W+S+N)
    row += 1

    label_filename = Label(self, text="Output File Name")
    label_filename.grid(row=row, column=self.column, sticky=E+W)
    row += 1
    self.entry_filename = Entry(self)
    self.entry_filename.grid(row=row, column=self.column, sticky=W+E)
    row += 1

    label_mintime = Label(self, text="Min Time")
    label_mintime.grid(row=row, column=self.column, sticky=E+W)
    row += 1
    self.entry_mintime = Entry(self)
    self.entry_mintime.grid(row=row, column=self.column, sticky=W+E)
    row += 1

    label_maxtime = Label(self, text="Max Time")
    label_maxtime.grid(row=row, column=self.column, sticky=W+E)
    row += 1
    self.entry_maxtime = Entry(self)
    self.entry_maxtime.grid(row=row, column=self.column, sticky=W+E)
    row += 1

    self.enabled = IntVar()
    self.check_enabled = Checkbutton(self, text="set enabled", variable=self.enabled)
    self.check_enabled.grid(row=row, column=self.column, sticky=W+E)
    row += 1

    # Control: buttons used to emmiting text and generating file
    self.button_emit_globals = Button(self, text="Emit Globals", command=self.emit_globals)
    self.button_emit_globals.grid(row=row, column=self.column, sticky=W+E)
    row += 1

    button_addrun = Button(self, text="Add Run", command=self.emit_run)
    button_addrun.grid(row=row, column=self.column, sticky=W+E)
    row += 1

    button_generate = Button(self, text="Generate File", command=self.generate_file)
    button_generate.grid(row=row, column=self.column, sticky=W+E)
    row += 1

    self.column += 1

    self.pack()

  def initUIRuns(self):
    """
      Second part of gui to be rendered. This contains all the fields needed to emit
       a single run within a distiller file. Multiple runs can be added by clicking
       'Add Run' multiple times.

      Information in Run Parameters:
        Run Name
          - header name for run
        Dependencies
          - description and uuid fields for each dependency in the algorithm
        Params
          - parameter fields for each parameter in the algorithm
    """

    self.entry_run_name = None
    self.entries_dep_description = []
    self.entries_dep_uuid = []
    self.entries_param = []

    row = 0

    label_runs = Label(self, text="Runs")
    label_runs.grid(row=row, column=self.column)
    row += 1

    label_run_name = Label(self, text="Run Name")
    label_run_name.grid(row=row, column=self.column, sticky=W+E)
    row += 1

    self.entry_run_name = Entry(self)
    self.entry_run_name.grid(row=row, column=self.column, sticky=W+E)
    row += 1

    algorithm = self.cbox_alg.get()
    settings = algorithms[algorithm]

    for dep in settings['deps']:

      if row >= 21:
        self.column += 1
        row = 1

      label_dep_description = Label(self, text="{0} (description)".format(dep))
      label_dep_description.grid(row=row, column=self.column, sticky=W+E)
      row += 1

      entry_dep_description = Entry(self)
      entry_dep_description.grid(row=row, column=self.column, sticky=W+E)
      row += 1

      label_dep_uuid = Label(self, text="{0} (uuid)".format(dep))
      label_dep_uuid.grid(row=row, column=self.column, sticky=W+E)
      row += 1

      entry_dep_uuid = Entry(self)
      entry_dep_uuid.grid(row=row, column=self.column, sticky=W+E)
      row += 1

      self.entries_dep_description.append(entry_dep_description)
      self.entries_dep_uuid.append(entry_dep_uuid)

    for param in settings['params']:

      if row >= 21:
        self.column += 1
        row = 1

      label_param = Label(self, text=param)
      label_param.grid(row=row, column=self.column, sticky=W+E)
      row += 1

      entry_param = Entry(self)
      entry_param.grid(row=row, column=self.column, sticky=W+E)
      row += 1

      self.entries_param.append(entry_param)

    row = 0
    self.column += 1

    self.text_file = Text(self)
    self.text_file.grid(row=row, column=self.column, rowspan=31, sticky=W+E+N+S, padx=5, pady=5)
    self.column += 1
    scrollbar = Scrollbar(self, command=self.text_file.yview)
    self.text_file.config(yscrollcommand=scrollbar.set)
    scrollbar.grid(row=row, column=self.column, rowspan=31, sticky=N+S)

    self.pack()

  def emit_globals(self):
    self.algorithm = algorithms[self.cbox_alg.get()]
    path = self.algorithm['path']
    if self.enabled.get():
      enabled = 'True'
    else:
      enabled = 'False'

    lines = self.inigen.emit_global(path, enabled)

    self.mintime = self.entry_mintime.get()
    self.maxtime = self.entry_maxtime.get()

    self.cbox_alg.configure(state='disabled')
    self.entry_filename.configure(state='disabled')
    self.entry_mintime.configure(state='disabled')
    self.entry_maxtime.configure(state='disabled')
    self.check_enabled.configure(state='disabled')
    self.button_emit_globals.configure(state='disabled')

    self.initUIRuns()
    self.update_text(lines)

  def emit_run(self):
    label = self.entry_run_name.get()
    chunking = 'parallel' #hardcoded for now
    mintime = self.mintime
    maxtime = self.maxtime
    lines = self.inigen.emit_run_header(label, chunking, mintime, maxtime)
    self.update_text(lines)

    deps = []
    for i in range(len(self.entries_dep_description)):
      deps.append([self.entries_dep_description[i].get(),
                   self.algorithm['deps'][i],
                   self.entries_dep_uuid[i].get()])
    params = []
    for i in range(len(self.entries_param)):
      params.append([self.algorithm['params'][i],
                     self.entries_param[i].get()])
    outputs = self.algorithm['outputs']
    lines = self.inigen.emit_run_body(deps, params, outputs)
    self.update_text(lines)

  def generate_file(self):
    self.inigen.generate_file(self.entry_filename.get())
    self.quit()

  def update_text(self, lines):
    self.text_file.configure(state='normal')
    string = "\n".join(lines)
    self.text_file.insert(END, string)
    self.text_file.configure(state='disabled')