# -*- coding: iso-8859-1 -*- # #------------------------------------------------------------------------------- # Code_Saturne version 1.3 # ------------------------ # # # This file is part of the Code_Saturne User Interface, element of the # Code_Saturne CFD tool. # # Copyright (C) 1998-2007 EDF S.A., France # # contact: saturne-support@edf.fr # # The Code_Saturne User Interface 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 2 of # the License, or (at your option) any later version. # # The Code_Saturne User Interface 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 the Code_Saturne Kernel; if not, write to the # Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, # Boston, MA 02110-1301 USA # #------------------------------------------------------------------------------- """ """ #------------------------------------------------------------------------------- # Library modules import #------------------------------------------------------------------------------- import string import Tix from Tkconstants import * #------------------------------------------------------------------------------- # Application modules import #------------------------------------------------------------------------------- from Base.Common import * import Base.Toolbox as Tool import Base.Dialog as Dialog import Base.TkPage as TkPage #------------------------------------------------------------------------------- # Multi-selection string #------------------------------------------------------------------------------- MULTISEL = "********" #------------------------------------------------------------------------------- # Hlist multi-selection class #------------------------------------------------------------------------------- class MultiSelect: """ This class is design in order to manage the storage of the selected items in the Hlist. """ def __init__(self, case, Hlist): """ Constructor """ self.case = case self.Hlist = Hlist def _initList(self): """ For each mouse selection we reinitialize all lists. """ self.nameL = [] self.name_scalL = [] self.typeCoeffL = [] self.coeffL = [] self.mdl = UserScalarPropertiesModel(self.case) def scalarInfo(self, entry): """ Return info from the argument entry. """ # Here we must call the tk function directly without passing in # Tix.py, because of a bug in tix8.1 in the Hlist.item_cget function t = PageText() h = self.Hlist name = h.tk.call(h, 'item', 'cget', entry, 0, '-text') name_scal = h.tk.call(h, 'item', 'cget', entry, 1, '-text') coeff = h.tk.call(h, 'item', 'cget', entry, 2, '-text') return name, name_scal, float(coeff) def setItems(self, entriesL): """ Store values when a new selection is done. """ self._initList() for entry in entriesL: name, name_scal, coeff = self.scalarInfo(entry) self.nameL.append(name) self.name_scalL.append(name_scal) self.coeffL.append(coeff) list = self.mdl.mgetListUserScalars() for scalar in list: if self.mdl.mgetLabelScalar(scalar) == name_scal: typC = self.mdl.mgetTypeCoeff(scalar) self.typeCoeffL.append(typC) def getItems(self): """ Return all the lists. """ return self.nameL, self.name_scalL, self.typeCoeffL, self.coeffL def widgetText(self): """ Find the right texts for the widget layout. """ name, name_scal = self.nameL[0], self.name_scalL[0] typeCoeff = self.typeCoeffL[0] coeff = self.coeffL[0] for i in self.nameL: if name != i: name = MULTISEL for i in self.name_scalL: if name_scal != i: name_scal = MULTISEL for i in self.typeCoeffL: if typeCoeff != i: typeCoeff = MULTISEL for i in self.coeffL: if coeff != i: coeff = MULTISEL return name, name_scal, typeCoeff, coeff #------------------------------------------------------------------------------- # User scalar properties model class #------------------------------------------------------------------------------- class UserScalarPropertiesModel(TkPage.Page): """ """ def __init__(self, case): """ Constructor """ self.case = case self.node_add_scalar = self.case.xmlGetNode('additional_scalars') def mgetListUserScalars(self): """ Get list of scalar'nodes """ return self.node_add_scalar.xmlGetNodeList('scalar', type='user') def mgetLabelScalar(self, node): """ Input the new label in scalar's node """ return node['label'] def mgetTypeCoeff(self, node): """ Get Type of property of the scalar """ type = node.xmlGetNode('property', 'name', 'label') type_C = type['choice'] return type_C def mgetVarianceScalar(self, node): """ Get Type of property of the scalar """ vari = node.xmlGetString('variance') return vari def mgetCoeffValue(self, node): """ Get Type of property of the scalar """ node_property = node.xmlGetNode('property', 'name') label = node_property['label'] coeff_value = node_property.xmlGetDouble('initial_value') if not coeff_value: # pour l'instant, on initialise à 0. Plus tard, on pourra initialiser # à la viscosité du fluide coeff_value = 1.0 self.msetInitialValue(node_property, coeff_value) return label, coeff_value def mgetNodeProperty(self, node): """ Get node of node'property """ node_prop = node.xmlGetNode('property') return node_prop def msetStatusPrintAndRecordStatus(self, node, valchoice): """ Set status of listing_printing and postprocessing_recording if choice is variable """ node['choice'] = valchoice if node['choice'] == "variable": if node.xmlGetNode('listing_printing'): node.xmlRemoveChild('listing_printing') if node.xmlGetNode('postprocessing_recording'): node.xmlRemoveChild('postprocessing_recording') elif node['choice'] == "constant": node.xmlInitNode('listing_printing')['status'] = "off" node.xmlInitNode('postprocessing_recording')['status'] = "off" def msetInitialValue(self, node, val): """ Set initial value ty of the scalar's propety """ node.xmlSetData('initial_value', val) def msetZoneInitialValue(self, node, nameZone, value): """ set initial value on the nameZone zone """ node_init = node.xmlInitChildNode('initial_value', zone=nameZone) node_init.xmlSetTextNode(value) #------------------------------------------------------------------------------- # Main class #------------------------------------------------------------------------------- class UserScalarPropertiesView(TkPage.Page): """ Class to open Define User Scalars Page. """ def _dependsPages(self, name): """ Construction of the list of dependencies Pages. """ self.case[name]['depends'] = ['bounda/scalar'] def _pageControl(self): """ Default value settings. """ self.selectedEntry = None self.currentEntry = None self.entriesNumber = 0 self.mdl = UserScalarPropertiesModel(self.case) def _make_style(self): """ Define beautiful style in order to display columns in the Hlist. """ self.style={} self.style['header'] = Tix.DisplayStyle(Tix.TEXT, refwindow=self.lf1, anchor=CENTER, justify=CENTER, padx=5, pady=2, font=fB) self.style['style'+'b'] = Tix.DisplayStyle(Tix.TEXT, refwindow=self.lf1, padx=5, selectforeground='#fefefe', font=fB) self.style['style'] = Tix.DisplayStyle(Tix.TEXT, refwindow=self.lf1, padx=5, anchor=CENTER, selectforeground='#fefefe', font=fN) def _tkControlVariables(self): """ Tkinter variables declaration. """ self.typeCoeff = Tix.StringVar() self.coeff = Tix.StringVar() self.diffCoeff = Tix.StringVar() def eraseEntries(self, event=None): """ Delete all caracters in the entries. """ self.value.delete(0, END) def insertHlist(self, name, name_scal, coeff): """ Create the item Hlist associated with the new boundary definition and update the listBox """ self.stbar.busy() t = PageText() self.entriesNumber = self.entriesNumber +1 self.scal_num = 'item' + repr(self.entriesNumber) self.h.hlist.add(self.scal_num, itemtype=Tix.TEXT, text=name, style=self.style['style'+'b']) self.h.hlist.item_create(self.scal_num, 1, itemtype=Tix.TEXT, text=name_scal, style=self.style['style']) self.h.hlist.item_create(self.scal_num, 2, itemtype=Tix.TEXT, text="%g"%(coeff), style=self.style['style']) self.stbar.idle() return name def replaceHlist(self, item, name, name_scal, coeff): """ Update the 'item' into the Hlist. """ self.stbar.busy() t = PageText() self.h.hlist.item_configure(item, 0, itemtype=Tix.TEXT, text=name, style=self.style['style'+'b']) self.h.hlist.item_configure(item, 1, itemtype=Tix.TEXT, text=name_scal, style=self.style['style']) self.h.hlist.item_configure(item, 2, itemtype=Tix.TEXT, text=coeff, style=self.style['style']) self.stbar.idle() def selectHlistAll(self): """ Fonction for the Popup Menu. Select everything in the Hlist. """ # self.reloadHlist() try: first = 'item' + repr(1) last = 'item' + repr(self.entriesNumber) self.h.hlist.selection_set(first, last) self.currentEntry = None self.selectHlist() except: pass def cancelSelection(self): """ Fonction for the Popup Menu. Blank the selection. """ self.h.hlist.selection_clear() self.eraseEntries() self.currentEntry = None self.selectHlist() def selectHlist(self, entry=None): """ Browsecmd: Every single Clik on the Button1 of the mouse send TWO signal to the GUI the first one when man push the button, and the second one when the button gets back. Command: Every double-Click and Return send only ONE signal to the GUI. """ self.selectedEntry = self.h.hlist.info_selection() if self.selectedEntry and self.currentEntry != self.selectedEntry: self.currentEntry = self.selectedEntry self.select.setItems(self.currentEntry) name, name_scal, typeCoeff, coeff_value = self.select.widgetText() if typeCoeff == MULTISEL: self.f3.pack_forget() self.bu.config(state=DISABLED) self.bu.menubutton.config(text=typeCoeff) else: self.f3.pack_forget() self.bu.config(state=NORMAL) self.bu.config(value=typeCoeff) self.value.delete(0,END) self.value.insert(0,coeff_value) self.value.icursor(END) def getTypeCoeff(self, event=None): """ """ if not self.currentEntry: return self.stbar.busy() if not self.typeCoeff.get(): self.typeCoeff.set('constant') if self.typeCoeff.get() == 'constant': self.l21.grid_forget() self.l22.grid(row=0, column=2, padx=5) self.f3.pack_forget() else: self.l21.grid(row=0, column=2, padx=5) self.l22.grid_forget() self.f3.pack(side=TOP, fill=X) name, name_scal, typeCoeff, coeff_old = self.select.getItems() for i in range(len(self.currentEntry)): list = self.mdl.mgetListUserScalars() for scalar in list: if self.mdl.mgetLabelScalar(scalar) == name_scal[i]: nodeProp = self.mdl.mgetNodeProperty(scalar) if nodeProp: self.mdl.msetStatusPrintAndRecordStatus(nodeProp, self.typeCoeff.get()) self.stbar.idle() def isFloat(self, entry, var): """ Verify if the 'entry' contents a float. If not, signal an error and return None. """ try: double = float(var.get()) except: self.check2.error(entry) double = None return double def string2float(self, entry, var): """ If the StringVar() 'var' associated to the 'entry', is not a 'MULTISEL', convert it to a float. """ self.check2.begin(entry) # Several selections in Hlist # if self.currentEntry and len(self.currentEntry) > 1: if var.get() != MULTISEL: double = self.isFloat(entry, var) else: double = MULTISEL # Only one selection in Hlist # else: double = self.isFloat(entry, var) return double def getDiffCoeff(self, event=None): """ """ if not self.diffCoeff.get(): self.diffCoeff.set('0.0') return self.string2float(self.value, self.diffCoeff) def addCoeff(self, event=None): """ Upload contents of the definition widget when the "Create" button is pushed. """ if not self.currentEntry: return self.stbar.busy() name, name_scal, typeCoeff, coeff_old = self.select.getItems() coeff_new = self.getDiffCoeff() for i in range(len(self.currentEntry)): list = self.mdl.mgetListUserScalars() for scalar in list: if self.mdl.mgetLabelScalar(scalar) == name_scal[i]: if coeff_new == MULTISEL: coeff = coeff_old[i] else: coeff = coeff_new self.replaceHlist(self.currentEntry[i], name[i], name_scal[i], coeff) nodeProp = self.mdl.mgetNodeProperty(scalar) if nodeProp: self.mdl.msetInitialValue(nodeProp, coeff) self.eraseEntries() self.currentEntry = None self.selectHlist() self.stbar.idle() def _createWidgets(self): t = PageText() self.lf1 = Tix.LabelFrame(self.myPage, bd=2, label=t.TITLE, relief=FLAT) self.lf1.label.config(font=fT) self.lf1.pack(side=TOP, fill=X, padx=10, pady=10) # Put a simple hierarchy into the Hlist (two levels). self.h = Tix.ScrolledHList(self.lf1.frame, options= 'hlist.columns 4 hlist.header 1 ' ) self.h.config(scrollbar="auto +y") self.h.hlist.config(selectmode='extended', browsecmd=self.selectHlist, bg=wm['hlistbackground']) self.h.hsb.config(width=10, bd=1) self.h.vsb.config(width=10, bd=1) self.h.pack(padx=10, pady=10, side=TOP) self.balloon.bind_widget(self.h.hlist, statusmsg=t.MSG_HLIST) # Create the headers self._make_style() self.h.hlist.header_create(0, itemtype=Tix.TEXT, text=t.NAME, style=self.style['header']) self.h.hlist.header_create(1, itemtype=Tix.TEXT, text=t.SCALAR, style=self.style['header']) self.h.hlist.header_create(2, itemtype=Tix.TEXT, text=t.COEFF, style=self.style['header']) # Notice that we use 3 columns in the Hlist widget. This way when the user # expands the windows wide, the right side of the header doesn't look # chopped off. The following line ensures that the 3 column header is # not shown unless the Hlist window is wider than its contents. self.h.hlist.column_width(3,0) # Let configure the appearance of the Hlist subwidget self.h.hlist.config(separator='.', width=42, height=11, drawbranch=0, indent=10) # width of the columns self.h.hlist.column_width(0, chars=14) self.h.hlist.column_width(1, chars=14) self.h.hlist.column_width(2, chars=14) # Create the mouse selection instance self.select = MultiSelect(self.case, self.h.hlist) # Popup Menu of Tree pm = Tix.PopupMenu(self.h.hlist, title=t.POPUP, state=NORMAL) pm.bind_widget(self.h.hlist) pm.menu.add_separator() pm.menu.add_command(label=t.SELECT_ALL, command=self.selectHlistAll) pm.menu.add_command(label=t.UNSELECT, command=self.cancelSelection) pm.menu.m1 = Tix.Menu(pm.menu) # Separator s = Tix.Frame(self.lf1.frame, height=2, bd=2, relief=SUNKEN) s.pack(side=TOP, fill=X) # Create Label and entry f2 = Tix.Frame(self.lf1.frame, relief=FLAT) f2.pack(side=TOP, fill=X) #f1 = Tix.Frame(self.lf1.frame, relief=FLAT) f1 = Tix.Frame(f2, relief=FLAT) f1.pack(side=TOP, fill=X) self.l1 = Tix.Label(f1, text=t.COEFF) self.l1.grid(row=0, column=0, ipadx=5) self.bu = Tix.OptionMenu(f1, options='menubutton.width 40') self.bu.menubutton.config(bd=2, width=8, relief=RAISED) self.bu.add_command('constant', label=t.CONSTANT) #self.bu.add_separator('') self.bu.add_command('variable', label=t.VARIABLE) self.bu.grid(row=0, column=1,padx=15, pady=15) self.bu.config(variable=self.typeCoeff, command=self.getTypeCoeff) self.balloon.bind_widget(self.bu, statusmsg=t.MSG_COEFF, balloonmsg=t.KEYWORD+' ISCALT, ISCSTH') # Separator # s = Tix.Frame(self.lf1.frame, height=2, bd=2, relief=SUNKEN) # s.pack(side=TOP, fill=X) self.l21 = Tix.Label(f1, text=t.INIT_VALUE) self.l22 = Tix.Label(f1, text=t.VALUE) self.l23 = Tix.Label(f1, text=t.UNIT) self.value = Tix.Entry(f1, bd=2, width=12, textvariable =self.diffCoeff ) self.value.grid(row=0, column=4, padx=0, pady=15) self.value.event_add("<>", "", "", "") self.value.bind("<>", self.addCoeff ) self.balloon.bind_widget(self.value, balloonmsg=t.KEYWORD+'VISLSO/RO0') self.l23.grid(row=0, column=5,padx=5) #f3 = Tix.Frame(self.lf1.frame, relief=FLAT) self.f3 = Tix.Frame(f2, relief=FLAT) self.f3.pack(side=TOP, fill=X) self.l3 = Tix.Label(self.f3, bd=2, relief=FLAT, text=t.FORTRAN, \ width=40,foreground='blue', font=fL) self.l3.grid(pady=10) def _initializeWidgets(self): """ """ t = PageText() self.cancelSelection() self.entriesNumber = 0 #nodeList = self.node_user_sca.xmlGetNodeList('scalar') nodeList = self.mdl.mgetListUserScalars() for scalar in nodeList: name = self.mdl.mgetLabelScalar(scalar) vari = self.mdl.mgetVarianceScalar(scalar) if not vari: label, coeff_value = self.mdl.mgetCoeffValue(scalar) id = self.insertHlist(label, name, coeff_value) self.f3.pack_forget() self.bu.config(value='constant') #------------------------------------------------------------------------------- # Text and messages for this page #------------------------------------------------------------------------------- class PageText: """ Storage of all texts and messages for this page. """ def __init__(self): # 1) Texts # if Tool.GuiParam.lang == 'fr': self.KEYWORD = "Mot clé Code_SATURNE : " self.TITLE = "Coefficient de diffusivité des Scalaires Utilisateurs" self.DEFINITION = "DEFINITION\nINITIALISATION" self.NAME = "Nom" self.SCALAR = "Scalaire\nassocié" self.COEFF = "Coefficient\nde diffusion" self.VARIANCE = "Variance" self.ADD = "Valider" self.CONSTANT = "Constant" self.VARIABLE = "Variable" self.INIT_VALUE = "Valeur\ninitiale" self.VALUE = "Valeur de\nréference" self.UNIT = "m2/s" self.FORTRAN = "Vous devez remplir USPHYV.F" self.POPUP = "Menu popup" self.SELECT_ALL = "Tout sélectionner" self.UNSELECT = "Désélectionner" else: self.KEYWORD = "Code_SATURNE Keyword: " self.TITLE = "User Scalar Diffusion Coefficient" self.DEFINITION = "DEFINITION\nINITIALIZATION" self.NAME = "Name" self.SCALAR = "Associated\nScalar" self.COEFF = "Diffusion\nCoefficient" self.VARIANCE = "Variance" self.ADD = "Validate" self.CONSTANT = "Constant" self.VARIABLE = "Variable" self.INIT_VALUE = "Initial\nvalue" self.VALUE = "Reference\nvalue" self.UNIT = "m2/s" self.FORTRAN = "You must complete USPHYV.F" self.POPUP = "Menu popup" self.SELECT_ALL = "Select all" self.UNSELECT = "Désélectionner" # 2) Messages # if Tool.GuiParam.lang == 'fr': self.MSG_COEFF = "Sélectionner variable ou constant" self.MSG_HLIST = "Cliquer le bouton droit pour " +\ "le menu contextuel." else: self.MSG_COEFF = "Select variable or constant" self.MSG_HLIST = "Click right button for popup menu." #------------------------------------------------------------------------------- # End #-------------------------------------------------------------------------------