[Mumps2Py:] [13] re-adding. |
[ Thread Index |
Date Index
| More lists.mumps2py.org/discuss Archives
]
Revision: 13
Author: pgallot
Date: 2008-01-17 18:51:20 +0000 (Thu, 17 Jan 2008)
Log Message:
-----------
re-adding.
Added Paths:
-----------
trunk/mumps2py_ui.pyw
Added: trunk/mumps2py_ui.pyw
===================================================================
--- trunk/mumps2py_ui.pyw (rev 0)
+++ trunk/mumps2py_ui.pyw 2008-01-17 18:51:20 UTC (rev 13)
@@ -0,0 +1,368 @@
+#!/usr/bin/python
+# Copyright 2008 Patrick Gallot
+
+## This file is part of Mumps2Py.
+##
+## Mumps2Py is free software: you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## Mumps2Py is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Mumps2Py. If not, see <http://www.gnu.org/licenses/>.
+""" Implements a user interface for translating Mumps code to Python """
+
+import os, re, fileinput
+import mumps2py.mumps_module, mumps2py.mumps2tok, mumps2py.tok2python
+
+
+from Tkinter import *
+import tkFileDialog
+
+ROOT = Tk()
+if os.path.isfile('optionDB'):
+ ROOT.option_readfile('optionDB')
+
+class Mumps2pyUI:
+ """The class which provides the User Interface to Mumps2Py"""
+ def __init__(self, my_root):
+ self.modules = None
+ self.root = my_root
+
+ def help_about(self):
+ """pop up a dialog showing licensing/waranty information"""
+ popup = Toplevel(self.root)
+ popup.transient(self.root)
+ popup.title = "About Mumps2Py"
+ msg = """
+Mumps2Py Copyright (C) 2008 Patrick Gallot
+
+Mumps2Py is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Mumps2Py is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Mumps2Py. If not, see <http://www.gnu.org/licenses/>.
+"""
+ Label(popup, text = msg).grid(row = 1, column = 1)
+ btn = Button(popup, text = "OK", takefocus = YES)
+ btn.grid(row = 2, column = 1)
+ btn.bind('<Button-1>', lambda event, p = popup: (p.destroy()))
+ btn.bind('<KeyPress-Return>', lambda event, p = popup: (p.destroy()))
+ btn.focus_set()
+
+ def popup_entry(self, msg, entry_width, callback):
+ """ generic pop-up query for a single value."""
+ popup = Toplevel(self.root)
+ popup.transient(self.root)
+ Label(popup, text = msg).grid(row = 1, column = 1)
+ self.entry_val = StringVar()
+ entry_ctl = Entry(popup, \
+ width = entry_width, \
+ textvariable = self.entry_val, \
+ takefocus = YES)
+ entry_ctl.grid(row = 2, column = 1)
+ btn = Button(popup, text = "Go", takefocus = YES)
+ btn.grid(row = 3, column = 1)
+ btn.bind('<Button-1>', \
+ lambda event, c = callback, p = popup: (c(p)))
+ btn.bind('<KeyPress-Return>', \
+ lambda event, c = callback, p = popup: (c(p)))
+ entry_ctl.bind('<KeyPress-Return>', \
+ lambda event, c = callback, p = popup: (c(p)))
+ entry_ctl.focus_set()
+
+ def info_window(self):
+ """ generic popup for displaying a bunch of Text."""
+ popup = Toplevel(self.root)
+ popup.transient(self.root)
+
+ f_info = Frame(popup, borderwidth = 2)
+ info_window = Text(f_info, \
+ width = 60, \
+ font = ("Consolas", 10), \
+ wrap = NONE)
+ dvscroll = Scrollbar(f_info, command = info_window.yview)
+ dhscroll = Scrollbar(f_info, command = info_window.xview, \
+ orient = HORIZONTAL)
+ info_window.configure(yscrollcommand = dvscroll.set, \
+ xscrollcommand = dhscroll.set)
+ dvscroll.pack(side = RIGHT, fill = Y)
+ dhscroll.pack(side = BOTTOM, fill = X)
+ info_window.pack(side = LEFT, expand = YES)
+ f_info.grid(row = 1, column = 1)
+
+ btn = Button(popup, text = "Close", takefocus = YES)
+ btn.grid(row = 2, column = 1)
+ btn.bind('<Button-1>', lambda event, p = popup: (p.destroy()))
+ btn.bind('<KeyPress-Return>', lambda event, p = popup: (p.destroy()))
+
+ return info_window
+
+ def display_before(self, filename, line_start = 1, line_end = -1):
+ """populate the before window with the Mumps module's raw source code"""
+ self.before_window.delete(0.0, END)
+ for line in fileinput.input(filename):
+ line_no = fileinput.lineno()
+ if line_no < line_start:
+ continue
+ if line_end != -1 and line_no >= line_end:
+ break
+ self.before_window.insert(END, line)
+ fileinput.close()
+
+ def display_after(self, a_module, translation):
+ """populate the after window with the translation of the Mumps module"""
+ self.after_window.delete(0.0, END)
+ for line in translation:
+ self.after_window.insert(END, line)
+
+ def display_decomposed(self, a_module):
+ """displays an intermediate decomposition of the Mumps code"""
+ decomposed_window = self.info_window()
+ for token in a_module.TokenList:
+ decomposed_window.insert(END, str(token) + '\n')
+
+ def parse_fromlinemodule(self, popup):
+ """parse from the module containing the line specified by popup"""
+ start_line = int(self.entry_val.get())
+ popup.destroy()
+ if self.modules:
+ for a_module in self.modules:
+ if a_module.end < start_line:
+ continue
+ mumps2py.mumps2tok.parseMumps(a_module)
+
+ def parsegivenmodule(self, popup):
+ """parse the module specified by popup"""
+ mod_name = self.entry_val.get()
+ popup.destroy()
+ if self.modules:
+ for the_module in self.modules:
+ if the_module.mod_name == mod_name:
+ self.display_before(the_module.input_file, \
+ the_module.start, \
+ the_module.end)
+ mumps2py.mumps2tok.parseMumps(the_module)
+ self.display_decomposed(the_module)
+ translation = mumps2py.tok2python.translate(the_module)
+ self.display_after(the_module, translation)
+ return
+
+ def parseuntilmodule(self, popup):
+ """analyze the tokens up until the module specified by popup"""
+ mod_name = self.entry_val.get()
+ popup.destroy()
+ toks = {}
+ if self.modules:
+ for the_module in self.modules:
+ if the_module.mod_name == mod_name:
+ break
+
+ mumps2py.mumps2tok.parseMumps(the_module)
+ for token in the_module.TokenList:
+ token.count_subtokens(toks)
+
+ analysis = [(v, k) for k, v in toks.items()]
+ analysis.sort(reverse = True)
+
+ analysis_window = self.info_window()
+ for count, toktype_key in analysis:
+ analysis_str = "%s: %d\n" % (toktype_key, count)
+ analysis_window.insert(END, analysis_str)
+
+
+ def parse_from(self):
+ """ ask for a value to call parse_fromlinemodule with"""
+ self.popup_entry("Enter the approximate line # to parse from:", 7, \
+ self.parse_fromlinemodule)
+
+ def parse_module(self):
+ """ ask for a value to call parsegivenmodule with"""
+ self.popup_entry("Enter the exact name of the module to parse:", 32, \
+ self.parsegivenmodule)
+
+ def parse_until_module(self):
+ """ ask for a value to call parseuntilmodule with"""
+ self.popup_entry("Enter the exact name of the module at which to stop:", \
+ 32, \
+ self.parseuntilmodule)
+
+ def parse_all(self):
+ """parse all the modules in a Mumps file"""
+ if self.modules:
+ for the_module in self.modules:
+ mumps2py.mumps2tok.parseMumps(the_module)
+ if len(self.modules) == 1:
+ the_module = self.modules[0]
+ mumps2py.mumps2tok.parseMumps(the_module)
+ self.display_decomposed(the_module)
+ translation = mumps2py.tok2python.translate(the_module)
+ self.display_after(the_module, translation)
+
+ def parse_analyze_tokens(self):
+ """count the frequency of the different token types, sort and display"""
+ toks = {}
+ if self.modules:
+ for the_module in self.modules:
+ if the_module.tokenlist_isempty():
+ mumps2py.mumps2tok.parseMumps(the_module)
+ for token in the_module.TokenList:
+ token.count_subtokens(toks)
+
+ analysis = [(v, k) for k, v in toks.items()]
+ analysis.sort(reverse = True)
+
+ analysis_window = self.info_window()
+ for count, toktype_key in analysis:
+ analysis_str = "%s: %d\n" % (toktype_key, count)
+ analysis_window.insert(END, analysis_str)
+ del toks
+
+
+ def file_open(self):
+ """ open a file of Mumps code"""
+ mumps_file = tkFileDialog.askopenfilename(\
+ parent = self.root,
+ filetypes = [ ("MUMPS files", "*.mps"), ("RSA files","*.rsa"), ],
+ initialdir = ".\\testfiles",
+ initialfile = "fm22.rsa")
+ m2py_dir = ".\\out"
+ f = open(mumps_file)
+ headerline = f.readline()
+ f.close()
+
+ if re.search(r"CACHE FORMAT\^~Format=Cache.S~", headerline):
+ self.modules = mumps2py.mumps_module.parseForModules(mumps_file,
+ m2py_dir)
+ else:
+ outputname = re.split(r"\..*$", mumps_file)[0]
+ print "outputname: [%s]" % outputname
+ self.modules = [mumps2py.mumps_module.ModuleInfo(mumps_file, \
+ m2py_dir, \
+ outputname), ]
+ self.display_before(mumps_file)
+
+
+ def file_save(self):
+ """ saves what is in the After window to a file."""
+ if self.modules and len(self.modules) == 1:
+ suggest_name = self.modules[0].output_file
+
+ name = tkFileDialog.asksaveasfilename(parent = self.root,
+ initialfile = suggest_name)
+ print name
+ if name:
+ outfile = open(name,"w")
+ outfile.write( self.after_window.get(0.0, END))
+ outfile.close()
+
+
+ def file_close(self):
+ """ clear out all the information for what was just open"""
+ self.before_window.delete(0.0, END)
+ self.after_window.delete(0.0, END)
+ self.modules = None
+
+
+ def make_dialog(self):
+ """Set up the User Interface"""
+ self.root.title('Mumps2Py')
+ menu_bar = Frame( self.root, relief = RAISED, borderwidth = 2)
+ menu_bar.pack(fill = X)
+ file_btn = Menubutton(menu_bar, text = 'File', underline = 0,
+ takefocus = TRUE)
+ file_btn.pack(side = LEFT, padx = "2m")
+ file_btn.menu = Menu(file_btn)
+ file_btn.menu.add_command( label = "Open", \
+ underline = 0, \
+ command = (lambda s = self: s.file_open()))
+ file_btn.menu.add_command( label = "Save",
+ underline = 0, \
+ command = (lambda s = self: s.file_save()))
+ file_btn.menu.add_command( label = "Close", \
+ underline = 0, \
+ command = (lambda s = self: s.file_close()))
+ file_btn['menu'] = file_btn.menu
+ menu_bar.tk_menuBar(file_btn)
+
+ parse_btn = Menubutton(menu_bar, text = 'Parse', underline = 0,
+ takefocus = TRUE)
+ parse_btn.pack(side = LEFT, padx = "2m")
+ parse_btn.menu = Menu(parse_btn)
+
+ parse_btn.menu.add_command( label = "Analyze tokens", \
+ underline = 1, \
+ command = (lambda s = self: s.parse_analyze_tokens()))
+
+ parse_btn.menu.add_command( label = "Parse From...", \
+ underline = 6, \
+ command = (lambda s = self: s.parse_from()))
+ parse_btn.menu.add_command( label = "Parse until Module...", \
+ underline = 6, \
+ command = (lambda s = self: s.parse_until_module()))
+ parse_btn.menu.add_command( label = "Parse Module...", \
+ underline = 6, \
+ command = (lambda s = self: s.parse_module()))
+ parse_btn.menu.add_command( label = "Parse All", \
+ underline = 6, \
+ command = (lambda s = self: s.parse_all()))
+ parse_btn['menu'] = parse_btn.menu
+ menu_bar.tk_menuBar(parse_btn)
+
+ help_btn = Menubutton(menu_bar, text = 'Help', underline = 0,
+ takefocus = TRUE)
+ help_btn.pack(side = LEFT, padx = "2m")
+ help_btn.menu = Menu(help_btn)
+ help_btn.menu.add_command( label="About", \
+ underline = 0, \
+ command = (lambda s = self: s.help_about()))
+ help_btn['menu'] = help_btn.menu
+ menu_bar.tk_menuBar(help_btn)
+
+ before_frame = Frame(self.root, borderwidth = 2)
+ self.before_window = Text( before_frame, \
+ font = ("Consolas", 10), \
+ width = 60, \
+ wrap=NONE)
+ bvscroll = Scrollbar(before_frame, command = self.before_window.yview)
+ bhscroll = Scrollbar(before_frame, command = self.before_window.xview, \
+ orient = HORIZONTAL)
+ self.before_window.configure(yscrollcommand = bvscroll.set, \
+ xscrollcommand = bhscroll.set)
+ bvscroll.pack(side = RIGHT, fill = Y)
+ bhscroll.pack(side = BOTTOM, fill = X)
+ self.before_window.pack(side = LEFT, expand = YES)
+ before_frame.pack(anchor = NW, side = LEFT, expand = YES)
+
+ after_frame = Frame(self.root, borderwidth = 2)
+ self.after_window = Text(after_frame, \
+ width = 60, \
+ font = ("Consolas", 10), \
+ wrap = NONE)
+ avscroll = Scrollbar(after_frame, command = self.after_window.yview)
+ ahscroll = Scrollbar(after_frame, command = self.after_window.xview, \
+ orient = HORIZONTAL)
+ self.after_window.configure(yscrollcommand = avscroll.set, \
+ xscrollcommand = ahscroll.set)
+ avscroll.pack(side = RIGHT, fill = Y)
+ ahscroll.pack(side = BOTTOM, fill = X)
+ self.after_window.pack(side = LEFT, expand = YES)
+ after_frame.pack(anchor = NE, side = RIGHT, expand = YES)
+
+
+UI = Mumps2pyUI(ROOT)
+UI.make_dialog()
+
+ROOT.mainloop()