## dataseteditor.py
## author: Matthew Marquissee, NASA GSFC, Code 632
## date started:  July 10, 2003
## last modified:  July 28, 2003
## purpose:  This file sets up a GUI for a module that will create and
##  maintain the XML files needed for the Dataset Finder.  I'm using the
##  PyTix module for design.

# import the relevant Python modules
import Tix
import tkMessageBox
import treedisplay # module with two tree viewers

# messages
MSG_WELCOME = """Welcome to the Space Physics Dataset Editor!"""
MSG_ABOUT = """Space Physics Dataset Editor

Created by Matthew Marquissee, June/July 2003

Space Physics Data Facility, NASA Goddard Space Flight Center

Last Updated: 7/31/03"""

class DatasetEditor(Tix.Frame):
    def __init__(self, master = None):
        """Initialize the Dataset Editor application."""
        Tix.Frame.__init__(self, master)
        # menu, main frame, and status bar
        frame1 = self.createMenu()
        frame2 = self.createWidgets()
        frame3 = self.createStatus()
        frame1.pack(side=Tix.TOP, fill=Tix.X)
        frame3.pack(side=Tix.BOTTOM, fill=Tix.X)
        frame2.pack(side=Tix.TOP, expand=1, fill=Tix.BOTH, padx=4, pady=4)
        self.pack()
        self.master.title('Space Physics Dataset Editor')

    def createMenu(self):
        w = Tix.Frame(self.master, bd=2, relief=Tix.RAISED)
        file = Tix.Menubutton(w, text='File', underline=0, takefocus=0)
        help = Tix.Menubutton(w, text='Help', underline=0, takefocus=0)
        file.pack(side=Tix.LEFT)
        help.pack(side=Tix.RIGHT)
        fm = Tix.Menu(file, tearoff=0)
        file['menu'] = fm
        hm = Tix.Menu(help, tearoff=0)
        help['menu'] = hm

        fm.add_command(label='Exit', underline=1,
                     command = lambda self=self: self.doDestroy () )
        hm.add_command(label='About', underline=1,
                     command=self.popabout )
        return w

    def createWidgets(self):
        # status bar
        widgets = Tix.Frame(self.master)        
        # Create the panedwindow widget
        panewin = Tix.PanedWindow(widgets, orientation='horizontal', height=500)
        panewin.pack(expand=1, fill=Tix.BOTH, padx=5, pady=5, side=Tix.BOTTOM)

        # First Pane: XML Tree Editor
        p1 = panewin.add('xml_tree', min=300, size=400)
        pane1 = Tix.Frame(p1)
        l1 = Tix.Label(pane1, text='XML Tree Editor')
        pane1.pack(expand=1, fill=Tix.BOTH, padx=5, pady=5, side=Tix.LEFT)                
        l1.pack(fill=Tix.X, padx=5, pady=5, side=Tix.TOP)        
        # three frames: tree, top buttons, bottom buttons
        f = Tix.Frame(pane1)
        fbuttons = Tix.Frame(pane1)
        common = Tix.Frame(pane1)
        
        f.pack(side=Tix.LEFT, padx=2, pady=2, fill=Tix.BOTH, expand=1)
        fbuttons.pack(side=Tix.BOTTOM, padx=2, pady=2, fill=Tix.X)
        common.pack(side=Tix.TOP, padx=2, pady=2, fill=Tix.X)
        # XML Tree Display
        top = Tix.Frame(f, relief=Tix.RAISED, bd=1)
        self.xt = treedisplay.XMLTreeDisplay(top)
        self.xt.pack(expand=1, fill=Tix.BOTH, padx=10, pady=10, side=Tix.LEFT)
        top.pack(side=Tix.TOP, fill=Tix.BOTH, expand=1)
        # create the buttons
        self.createXMLTreeButtons(fbuttons)
        self.createCommonButtons(common)
	
        # Second Pane: FTP Tree Importer
        p2 = panewin.add('ftp_import', min=300, size=400)
        pane2 = Tix.Frame(p2)
        l2 = Tix.Label(pane2, text='Import Elements from an FTP Site')
        pane2.pack(expand=1, fill=Tix.BOTH, padx=5, pady=5, side=Tix.LEFT)                
        l2.pack(fill=Tix.X, padx=5, pady=5, side=Tix.TOP)        
        # three frames: tree, top buttons, bottom buttons
        f = Tix.Frame(pane2)
        fbuttons = Tix.Frame(pane2)
        params = Tix.Frame(pane2)
            
        f.pack(side=Tix.LEFT, padx=2, pady=2, fill=Tix.BOTH, expand=1)
        fbuttons.pack(side=Tix.BOTTOM, padx=2, pady=2, fill=Tix.X)
        params.pack(side=Tix.TOP, padx=2, pady=2, fill=Tix.X)

        # URL Entry Box
        fileselectfr = Tix.Frame(f, relief=Tix.RAISED, bd=1)
        lab = Tix.Label(fileselectfr, text='Base URL: ')
        lab.pack(side=Tix.LEFT, fill=Tix.Y, padx=5, pady=5)
        loadent = Tix.Entry(fileselectfr)
        loadent.pack(side=Tix.LEFT, fill=Tix.BOTH, padx=5, pady=5, expand=1)
        loadurl = Tix.Button(fileselectfr, text=' Load ')
        loadurl.pack(side=Tix.RIGHT, fill=Tix.Y, padx=5, pady=5)
        fileselectfr.pack(side=Tix.TOP, fill=Tix.X)
        # FTP Tree Display
        top = Tix.Frame(f, relief=Tix.RAISED, bd=1)
        self.ft = treedisplay.FTPDirTreeDisplay(top)
        self.ft.loadval.set('ftp://')
        loadurl.config(command=self.ft.loadftpurl)
        loadent.config(textvariable=self.ft.loadval)
        self.ft.pack(expand=1, fill=Tix.BOTH, padx=10, pady=10, side=Tix.LEFT)
        top.pack(side=Tix.TOP, fill=Tix.BOTH, expand=1)
        # create the parameters and buttons
        self.createFTPTreeParams(params)
        self.createFTPTreeButtons(fbuttons)

        return widgets

    def createStatus(self):
        w = Tix.Frame(self.master, relief=Tix.RAISED, bd=1)
        self.statusbar = Tix.Label(w, relief=Tix.SUNKEN, bd=1)
        self.statusbar.form(padx=3, pady=3, left=0, right='%70')
        return w
	
    def doDestroy(self):
        """Destroy Dataset Editor."""
        self.master.destroy()

    def createCommonButtons(self, master):
        # Save all of the XML Documents in datasites.pref
        saveall = Tix.Button(master, name='saveall', text='Save All XML', 
                    command=self.xt.saveallfiles)
        # Close application
        close = Tix.Button(master, name='close', 
                        text='Close', 
                        command=self.doDestroy)
        # show/edit instruments?
        check = Tix.Checkbutton(master, text='instruments?',
                                variable=self.xt.showinstruments)
        
        saveall.pack(side=Tix.TOP, padx=2, pady=2, fill=Tix.X)
        close.pack(side=Tix.TOP, padx=2, pady=2, fill=Tix.X)
        check.pack(side=Tix.TOP, padx=2, pady=2, fill=Tix.X)

    def createXMLTreeButtons(self, master):
        treelabel = Tix.Label(master, text='Tree Operations')
        # Pop up view dialog box
        view = Tix.Button(master, name='view', text='View Element',
                           command=self.xt.viewattributes)
        # Pop up edit dialog box
        edit = Tix.Button(master, name='edit', text='Edit Element',
                           command=self.xt.editattributes)
        # Remove a node
        remove = Tix.Button(master, name='remove', text='Remove Element',
                           command=self.xt.removenode)
        # Copy a node
        clone = Tix.Button(master, name='clone', text='Clone Element',
                           command=self.xt.clonenode)
        # Add a child node
        add = Tix.Button(master, name='add', text='Add Child',
                           command=self.xt.addchild)
        sitelabel = Tix.Label(master, text='New Datasite...')
        # Create a new XML file
        addsite = Tix.Button(master, name='addsite', text='From Scratch',
                           command=self.xt.addsite)
        # Import a local XML file
        importfile = Tix.Button(master, name='import', text='From Local File',
                           command=self.xt.importsite)
        # Draw buttons in order
        treelabel.pack(side=Tix.TOP, padx=2, pady=2, fill=Tix.X)
        view.pack(side=Tix.TOP, padx=2, pady=2, fill=Tix.X)
        edit.pack(side=Tix.TOP, padx=2, pady=2, fill=Tix.X)
        remove.pack(side=Tix.TOP, padx=2, pady=2, fill=Tix.X)
        clone.pack(side=Tix.TOP, padx=2, pady=2, fill=Tix.X)
        add.pack(side=Tix.TOP, padx=2, pady=2, fill=Tix.X)
        sitelabel.pack(side=Tix.TOP, padx=2, pady=2, fill=Tix.X)
        addsite.pack(side=Tix.TOP, padx=2, pady=2, fill=Tix.X)
        importfile.pack(side=Tix.TOP, padx=2, pady=2, fill=Tix.X)

        
    def createFTPTreeParams(self, master):
        # Parameter 1: Number of files shown in FTP Tree Viewer
        l1 = Tix.Label(master, text='# of files to show:')
        cont = Tix.Control(master, min=0, variable=self.ft.numfiles)
        check = Tix.Checkbutton(master, text='show all files',
                                variable=self.ft.showall)
        
        check.pack(side=Tix.TOP, padx=2, pady=2, fill=Tix.X)
        l1.pack(side=Tix.TOP, padx=2, pady=2, fill=Tix.X)
        cont.pack(side=Tix.TOP, padx=2, pady=2, fill=Tix.X)
        

    def createFTPTreeButtons(self, master):
        ftplabel = Tix.Label(master, text='FTP Operations')
        # Load the selected path, ignore the rest of the site
        load = Tix.Button(master, name='load', text='Load This Path',
                           command=self.ft.loadselectednode)
        # Load One Directory Up
        dirup = Tix.Button(master, name='dirup', text='Up One Level',
                           command=self.ft.directoryup)
        # Copy the selected path to system clipboard
        copyc = Tix.Button(master, name='copyc', text='Copy to Clipboard',
                           command=self.copyurltoclipboard)
        # Copy name and path as new node in XML Tree
        copyxml = Tix.Button(master, name='copyxml', text='Copy into XML Tree',
                           command=self.copyintoxml)
        
        ftplabel.pack(side=Tix.TOP, padx=2, pady=2, fill=Tix.X)
        load.pack(side=Tix.TOP, padx=2, pady=2, fill=Tix.X)
        dirup.pack(side=Tix.TOP, padx=2, pady=2, fill=Tix.X)
        copyc.pack(side=Tix.TOP, padx=2, pady=2, fill=Tix.X)
        copyxml.pack(side=Tix.TOP, padx=2, pady=2, fill=Tix.X)
        
    # Syntactic sugar functions for convenience
    def loadftpfromurl(self):
        self.ft.loadftpurl(self.loadval.get())

    def copyurltoclipboard(self):
        the_url = self.ft.getfullpath()
        if the_url == None:
            the_url = self.ft.loadval.get()
        self.master.clipboard_clear()
        self.master.clipboard_append(the_url)

    def copyintoxml(self):
        self.xt.addfromftp(self.ft)
        
    def popabout(self):
        tkMessageBox.showinfo("About This Program", MSG_ABOUT)

if __name__ == '__main__':
    root = Tix.Tk()
    dnb = DatasetEditor(root)
    root.mainloop()