Документ взят из кэша поисковой машины. Адрес оригинального документа : http://www.stsci.edu/spst/UnixTransition/doc/namelist_selection_menu.py
Дата изменения: Fri Feb 28 14:46:10 2014
Дата индексирования: Sat Mar 1 22:47:09 2014
Кодировка:
#MODULE namelist_selection_menu
#
#***********************************************************************
"""

**PURPOSE** --
Build a widget for selecting PASS namelist files.

**DEVELOPER** --
K. Clark

**MODIFICATION HISTORY** --

o Initial implementation 05/11/04
o Modified 05/14/04 kwc - Fix browse popup hangs when entered
in dirbox.
o Modified 04/26/06 drc - Handle a bad symbolic link gracefully
o Modified 06/29/06 drc - if must_exist is True, do file exists check
in get_entry
"""
#***********************************************************************
import Tix
import Pmw
from Tkconstants import *
from Tkinter import *
import tkMessageBox

import glob, os, re, string

from boolean import *
import file_Browse_dialog, spss_sys_util


__version__ = "6/29/06"

# Use this to find the descriptive comment line in the file.
re_comment = re.compile('! COMMENT:')

# Primary namelist keyword for each PASS namelist file type.
NAMELIST_DICTIONARY = {'$CLNBASE' : re.compile('CL Basefile'),
'$CLNINPUT' : re.compile('CL Start File'),
'$MINPADS' : re.compile('MS Basefile'),
'$MINCTLINP' : re.compile('MS Command Input file')}
re_namelst_type = re.compile("(?P\$CLNBASE|\$CLNINPUT|\$MINPADS|\$MINCTLINP)")

class namelist_selection_menu:
"""A GUI for selecting a PASS namelist file.
"""
def __init__ (self,
parent,
comment,
Browse_Opt=false,
Browse_dir="~",
file_pattern='*',
allowed_names=(('*','All files.'),),
selection_value=None,
must_exist_flag=true,
namelist_type=None):

self.parent = parent
self.comment = comment
self.must_exist_flag = must_exist_flag
# make sure only one "file does not exist" message box pops up
self.messagebox_showing = False

# Used to determine if file selection.
self.namelist_type = namelist_type

# Store the browse directory as a list.
if (type(Browse_dir) == type([])):
self.browse_hist_list = Browse_dir
else:
self.browse_hist_list = [Browse_dir]

self.file_pattern = file_pattern

# Create storage for the selected browse directory.
self.browse_dir_value = StringVar()
if (len(self.browse_hist_list) > 0):
self.browse_dir_value.set(self.browse_hist_list[0])

# Create storage for the selected namelist file.
if isinstance(selection_value, StringVar):
self.namelst_value = selection_value
default_namelist = selection_value.get()
else:
self.namelst_value = StringVar()
default_namelist = selection_value

# Create storeage for the list of available namelist files.
self.namelst_list = []

# Create new frames.
self.frame = Frame(self.parent)
top_frame = Frame(self.frame)
bottom_frame = Frame(self.frame)


# Add a discriptive label.
label = Tix.Label(top_frame, text=self.comment, padx=5, pady=7)
label.pack()

# Create a Tix ScrolledHList box for choosing a namelist.
self.shlist_box(bottom_frame)

# Create a Tix LabelEntry for selecting the namelist directory.
# Note: Has to occur after shlist_box created because first action
# is to update shlist_box.
self.dir_select_box(top_frame)

# Create a directory browse dialog box for finding the
# namelist directory.
# Note: Has to occur after shlist_box created because first action
# is to update shlist_box.
if (Browse_Opt == true):
self.dir_browse_box(top_frame)

# Create a Tix LabelEntry for selecting the namelist file.
self.file_box(bottom_frame)

# Pack the frames.
top_frame.pack(side='top', pady=10, padx=5)
bottom_frame.pack(side='top', pady=10, padx=5)
self.frame.pack()

# Initialize the gui by searching through all the directories
# for namelists.
self.refresh()

# Set the initial selection if the file exists
self.check_entry(default_namelist)

def shlist_box(self, frame):
""" Creates a Tix ScrolledHList for displaying namelists.
"""
# Create two columns with a header line for each.
Namelist_ScrolledHList = Tix.ScrolledHList(frame,
options='hlist.columns 2 hlist.header 1')

# The HList widget has all the items to be configured.
self.hlist = Namelist_ScrolledHList.hlist

# Finish configuring the HList widget.
self.hlist.config(separator='\/',
width=70,
height=5,
drawbranch=0,
indent=10,
command=self.save_namelist_selection)

# Define the style for the header line in the HList.
boldfont = self.hlist.tk.call('tix','option','get','bold_font')
style={}
style['header'] = Tix.DisplayStyle(Tix.TEXT, refwindow=self.hlist,
anchor=Tix.CENTER, padx=8, pady=2, font = boldfont )
style['header2'] = Tix.DisplayStyle(Tix.TEXT, refwindow=self.hlist,
anchor=Tix.W, padx=8, pady=2, font = boldfont )

# Define the two columns for the HList.
self.hlist.header_create(0, itemtype=Tix.TEXT, text='Namelist',
style=style['header'])
self.hlist.header_create(1, itemtype=Tix.TEXT, text=' Comment',
style=style['header2'])

Namelist_ScrolledHList.pack()

def dir_select_box(self, frame):
""" Creates a Tix ComboBox for selecting the namelist directory.
"""
# Set up an entry box for the namelist directory.
self.dir_selec_entry = Tix.ComboBox(frame, history=1,
editable=1)
self.dir_selec_entry.entry.configure(width=40)

comment = self.comment + \
" Namelist Directory:"
self.dir_selec_entry.label.configure(width=len(comment),
anchor=Tix.E,
text=comment)
self.dir_selec_entry.configure(variable=self.browse_dir_value,
command=self.update_namelst_list)

# Populate the widget the initial browse directory list.
for dir in self.browse_hist_list:
self.dir_selec_entry.append_history(dir)

self.dir_selec_entry.pack(side='left', anchor='nw')

def dir_browse_box(self, frame):
""" Creates a directory browse dialog box for finding the namelist
directory.
"""
# Create a directory browse dialog box.
Dir_browse_box = spss_dir_dialog('')
Dir_browse_box.dirbox.config(value=self.browse_dir_value.get())
Dir_browse_box.dirbox.config(command=self.update_browse_hist)
Dir_browse_box.config(command=self.update_browse_hist)

Browse_btn = Button(frame,
text='Browse ...',
command=Dir_browse_box.popup)
Browse_btn.pack(side='left')

def file_box(self, frame):
""" Creates a Tix LabelEntry for selecting the namelist file.
"""
# Set up an entry box for the namelist file.
Namelist_LabelEntry = Tix.LabelEntry(frame,
label="Selection:",
labelside='left')

Namelist_LabelEntry.entry.configure(textvariable=self.namelst_value,
borderwidth=3,
relief='sunken',
background='snow',
width=65)

# Erase the entry widget when Control-u entered.
Namelist_LabelEntry.entry.bind('',
self.Clear_namelist_entry_menus)

Namelist_LabelEntry.pack(side='left', anchor='nw')

def check_entry(self, File=None):
"""Checks that the file exists.
If the 'must_exist' flag is true, the gui will produce an error
box if the input file does not exist.
"""
if (File != None):
if (not self.messagebox_showing and self.must_exist_flag and (os.path.isfile(File) != 1)):
self.messagebox_showing = True
tkMessageBox.showerror('No Such File ', self.comment + ': ' + \
File + ' file not found.')
self.messagebox_showing = False
else:
# Update the browse history with this file's directory.
self.update_browse_hist(os.path.dirname(File))
# Record this as the selected file.
self.namelst_value.set(File)

def get_entry(self):
"""Return the selected file.
"""
File = self.namelst_value.get()
if self.must_exist_flag:
self.check_entry(File)
return File

def get_file(self):
"""Synonym of get_entry.
"""
return self.get_entry()

def set_entry(self, file, must_exist=true):
"""Set the file in the entry box.

"""
if not file:
# Clear the selection.
self.clear()
else:
# Store the file name.
self.must_exist_flag = must_exist
file = os.path.normpath(os.path.expandvars(os.path.expanduser(file)))
self.check_entry(file)

def Clear_namelist_entry_menus(self, event):
"""Clear the input namelist widget.
"""
event.widget.delete(0,'end')

def save_namelist_selection(self, event):
"""Get the full file name from the ScrolledListBox selection.
Record this in self.namelst_value.
"""
# Record the full file name corresponding to this index.
self.namelst_value.set(self.hlist.info_selection()[0])

def update_browse_hist (self, path):
"""This function is called when the user hits the enter key
while in the namelist directory entry window.
"""
path = os.path.normpath(os.path.abspath(path))
self.browse_dir_value.set(path)

# Make sure this entry is recorded in the history box.
if path not in self.browse_hist_list:
self.browse_hist_list.append(path)
self.dir_selec_entry.append_history(path)

return path

def update_namelst_list(self, path):
"""When a directory is chosen in the dialog box, update the directory
list accordingly.
"""
path = self.update_browse_hist(path)
search_path = os.path.join(path,self.file_pattern)
self.namelst_list = glob.glob(search_path)

self.update_namelst_listbox()

def update_namelst_listbox(self):
"""Update the namelist listbox with a list of namelists for the
given namelist list.
"""
# First delete all the entries in the listbox.
self.hlist.delete_all()
self.namelst_value.set('')

# Now start populating the hlist box.
if len(self.namelst_list) == 0:
# Handle empty list when no files are found.
self.hlist.add("Error", itemtype=Tix.TEXT,
text=' No namelist files found.', state='disabled')
else:
# Display the file name, and comment for each namelist file.
self.namelst_list.sort()
old_dir = ''
for namelst_file in self.namelst_list:
(key, name, comment, namelist_type) = self.get_namelist_info(
namelst_file)

# Add this file if it is of the requested type.
if namelist_type != 'bogus' and (self.check_namelist_type(namelist_type) == true):
dir = os.path.dirname(key)
if (dir != old_dir):
# Display the directory name for the next batch of
# namelist files.
self.hlist.add(dir, itemtype=Tix.TEXT, text=dir,
state='disabled')
old_dir = dir

self.hlist.add(key, itemtype=Tix.TEXT, text=name)
self.hlist.item_create(key, 1, itemtype=Tix.TEXT,
text=comment)

def check_namelist_type (self, keyword):
""" Returns true if the keyword is matches the requested namelist type.
"""
# Don't do this check if not defined.
if (self.namelist_type == None):
return true

if NAMELIST_DICTIONARY.has_key(keyword):
match = NAMELIST_DICTIONARY[keyword].search(self.namelist_type)
# True if this is the requested namelist type.
if (match != None):
return true

return false

def get_namelist_info(self, namelist_file):
""" Returns a tuple consisting of the full file name, file name,
comment line, and namelist type from the namelist file.
"""
key = namelist_file
name = os.path.splitext(os.path.basename(namelist_file))[0]
comment = ''
namelist_type = None

# Use the first line of the file as a comment.
try:
Input = open(namelist_file,'r')
data_lines = Input.readlines()
Input.close()
except:
print "Error reading namelist file:", namelist_file
return ('', '', '', 'bogus')

for line in data_lines:
# Look for a comment about what this file is used for.
match = re_comment.match(line)
if (match != None):
comment = string.strip(re_comment.split(line)[1])

# Check to see what type of namelist this file is.
type_match = re_namelst_type.search(line)
if (type_match != None):
namelist_type = type_match.group('type')
# Stop processing namelist lines once this found.
break

return (key, name, comment, namelist_type)

def clear(self):
"""Clear the namelist selection.
"""
self.namelst_value.set('')

def refresh(self):
"""Go get a new list of namelist files.
"""
self.update_namelst_list(self.browse_dir_value.get())


class spss_dir_dialog(Tix.DirSelectDialog):
"""Add focus grabbing capability to the Tix.DirSelectDialog widget.
"""
def __init__(self, master, cnf={}, **kw):
"""Constructor.
"""
Tix.DirSelectDialog.__init__(self, master, cnf, **kw)
# set up ok and cancel buttons
self.ok.config(command=self.popdownok)
self.cancel.config(command=self.popdowncanc)
self.popped_up = 0

def popup(self):
"""Call this when the directory selection widget is
brought up.
"""
Tix.DirSelectDialog.popup(self)
Pmw.pushgrab(self, 0, None)
self.popped_up = 1

def popdownok(self):
"""Call this when you want to get rid of the directory
selection widget.
"""
if self.popped_up:
Tix.DirSelectDialog.popdown(self)
# Have to call parent widget update to get selection.
self.tk.call(self.dirbox.dircbx, 'invoke')
Pmw.popgrab(self)
self.popped_up = 0

def popdowncanc(self):
"""Call this when you want to get rid of the directory
selection widget.
"""
if self.popped_up:
Tix.DirSelectDialog.popdown(self)
Pmw.popgrab(self)
self.popped_up = 0

if __name__ == '__main__':
root = Tix.Tk()
PASS_MSIN_DIRECTORY = spss_sys_util.get_environ_variable("PASS_MSIN_DIRECTORY")
# default_file = StringVar()
# default_file.set('/data/operational1/spss_flight_data/pass/msin/ms_04117i.bas')
default_file =spss_sys_util.resolver('PASS_MSIN_DIRECTORY', 'ms_06100i.bas')
menu = namelist_selection_menu(root, "PASS MS Basefile",
true,
PASS_MSIN_DIRECTORY,
'*.bas',
(('*.bas','PASS MS Basefile.'),
('*','All files')),
default_file, true)
menu.frame.pack(padx=10, pady=10)
root.mainloop()
print menu.namelst_value.get(),