# -*- 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
#
#-------------------------------------------------------------------------------


"""
This module defines the storage system type.

This module contains the following classes and function:
- MatisseThermicModel
- MatisseThermicView
- PageText
"""


#-------------------------------------------------------------------------------
# Library modules import
#-------------------------------------------------------------------------------


import Tix
from Tkconstants import *
import sys, unittest


#-------------------------------------------------------------------------------
# Application modules import
#-------------------------------------------------------------------------------

from Base.Common import *
import Base.Toolbox as Tool
import Base.TkPage as TkPage
import Pages.MatisseType as MatisseType 
import Pages.MatisseGeom as MatisseGeom
import Base.Dialog as Dialog

#-------------------------------------------------------------------------------
# Matisse thermic class
#-------------------------------------------------------------------------------


_MULTISEL = "************"
_EPSILON = 1e-6


class MatisseThermicModel:
    """
    Manage the input/output markups in the xml doc about matisse thermiclic load
    """
    def __init__(self, case):
        """
        Constructor.
        """
        self.case               = case
        self.node_matisse       = self.case.root().xmlInitChildNode('matisse')
        self.node_compute       = self.node_matisse.xmlInitChildNode('compute')
        self.node_phymodel      = self.node_compute.xmlInitChildNode('physical_model')

        self.node_mdcnt         = self.node_phymodel.xmlInitChildNode('imdcnt','status')
        
        self.status = ('on',
                       'off')

        #
        # Vars Filters
        self.node_map           = self.node_compute.xmlInitChildNode('map')
        self.node_th_cp         = self.node_map.xmlInitChildNode('thermal_capacity')
        self.node_line          = self.node_th_cp.xmlInitChildNode('line')
        self.node_row           = self.node_th_cp.xmlInitChildNode('row')
        self.node_height        = self.node_th_cp.xmlInitChildNode('height')

        self.list_line_area     = self.node_line.xmlGetNodeList('area','label') 
        self.list_line_min      = self.node_line.xmlGetNodeList('min')
        self.list_line_max      = self.node_line.xmlGetNodeList('max')
        self.list_line_value    = self.node_line.xmlGetNodeList('value')

        self.list_row_area      = self.node_row.xmlGetNodeList('area','label') 
        self.list_row_min       = self.node_row.xmlGetNodeList('min')
        self.list_row_max       = self.node_row.xmlGetNodeList('max')
        self.list_row_value     = self.node_row.xmlGetNodeList('value')

        self.list_height_area   = self.node_height.xmlGetNodeList('area','label') 
        self.list_height_min    = self.node_height.xmlGetNodeList('min')
        self.list_height_max    = self.node_height.xmlGetNodeList('max')
        self.list_height_value  = self.node_height.xmlGetNodeList('value')


    def defaultMatisseThermicValues(self):
        """
        Return in a dictionnary which contains default values
        """
        default = {}

        #
        # bool
        default['imdcnt']='off'

        #
        # double
        default['puicon'] = 1000.
        default['tinit'] = 20.
        default['tcrit'] = 80.
        default['emicon'] = 0.4
        default['emimur'] = 0.8
        default['hepcnt'] = 6.
        default['dhpcnt'] = 0.
        
        #
        # Vars Filters
        default['maplabel'] = 'default'
        default['maplmin']  = 0.
        default['maprmin']  = 0.
        default['maphmin']  = 0.
        default['maplmax']  = 0.
        default['maprmax']  = 0.
        default['maphmax']  = 0.
        default['maplval']  = 1.
        default['maprval']  = 1.
        default['maphval']  = 1.

        return default


    def SetArea(self, areatype, num, label, bmin, bmax, val):
        """
        Add to the XML doc the new values.
        """
        if areatype == 'line' :
            if label: self.list_line_area[num]['label'] = label
            if bmin: self.list_line_area[num].xmlSetData('min',bmin)
            if bmax: self.list_line_area[num].xmlSetData('max',bmax)
            if val: self.list_line_area[num].xmlSetData('value',val)
        elif areatype == 'row' :
            if label: self.list_row_area[num]['label'] = label
            if bmin: self.list_row_area[num].xmlSetData('min',bmin)
            if bmax: self.list_row_area[num].xmlSetData('max',bmax)
            if val: self.list_row_area[num].xmlSetData('value',val)
        elif areatype == 'height' :
            if label: self.list_height_area[num]['label'] = label
            if bmin: self.list_height_area[num].xmlSetData('min',bmin)
            if bmax: self.list_height_area[num].xmlSetData('max',bmax)
            if val: self.list_height_area[num].xmlSetData('value',val)
        else :
            print areatype, " : Unknown area type"
            sys.exit(1)


    def NewArea(self, areatype, label, bmin, bmax, val):
        """
        Add to the XML doc the new values.
        """
        dlabel, dmin, dmax, dval = self.DefaultArea(areatype)

        if areatype == 'line' :
            if label :
                node = self.node_line.xmlAddChild('area', label=label)
            else :
                node = self.node_line.xmlAddChild('area', label=dlabel)
        elif areatype == 'row' :
            if label :
                node = self.node_row.xmlAddChild('area', label=label)
            else :
                node = self.node_row.xmlAddChild('area', label=dlabel)
        elif areatype == 'height' :
            if label :
                node = self.node_height.xmlAddChild('area', label=label)
            else :
                node = self.node_height.xmlAddChild('area', label=dlabel)
        else :
            print areatype + " : Unknown area type"
            sys.exit(1)

        nmin = node.xmlAddChild('min')
        nmax = node.xmlAddChild('max')
        nval = node.xmlAddChild('value')

        if bmin != None and bmin != "":
            nmin.xmlSetTextNode(bmin)
        else:
            nmin.xmlSetTextNode(dmin)
        if bmax != None and bmax != "":
            nmax.xmlSetTextNode(bmax)
        else:
            nmax.xmlSetTextNode(dmax)
        if val != None and val != "":
            nval.xmlSetTextNode(val)
        else:
            nval.xmlSetTextNode(dval)
            
        if areatype == 'line' :
            self.list_line_area.append(node)
        elif areatype == 'row' :
            self.list_row_area.append(node)
        elif areatype == 'height' :
            self.list_height_area.append(node)
        else :
            print areatype + " : Unknown area type"
            sys.exit(1)


    def DefaultArea(self,areatype):
        """
        Return default values of a area
        """ 
        modelgeom = MatisseGeom.MatisseGeomModel(self.case)
        dlabel = "default"
        dmin = 0
        dval = 1.0
        
        if areatype == 'line' :
            dmax = modelgeom.getMatisseGeomDoubleVar('nptran') 
        elif areatype == 'row' :
            dmax = modelgeom.getMatisseGeomDoubleVar('nplgrs')
        elif areatype == 'height' :
            dmax = modelgeom.getMatisseGeomDoubleVar('nchest')
        else :
            print "DefaultArea" + areatype + " : Unknown area type"
            sys.exit(1)

        return dlabel, dmin, dmax, dval


    def GetArea(self, areatype, num):
        """
        Get area Values.
        """
        if areatype == 'line' :
            label = self.list_line_area[num]['label']
            bmin = self.list_line_area[num].xmlGetString('min')
            bmax = self.list_line_area[num].xmlGetString('max')
            val = self.list_line_area[num].xmlGetString('value')
        elif areatype == 'row' :
            label = self.list_row_area[num]['label']
            bmin = self.list_row_area[num].xmlGetString('min')
            bmax = self.list_row_area[num].xmlGetString('max')
            val = self.list_row_area[num].xmlGetString('value')
        elif areatype == 'height' :
            label = self.list_height_area[num]['label']
            bmin = self.list_height_area[num].xmlGetString('min')
            bmax = self.list_height_area[num].xmlGetString('max')
            val = self.list_height_area[num].xmlGetString('value')
        else :
            print "GetArea" + areatype + " : Unknown area type"
            sys.exit(1)

        return label, bmin, bmax, val


    def GetAreas(self, areatype):
        """
        Get areas Values.
        """
        llabel=[]
        lbmin=[]
        lbmax=[]
        lval=[]

        if areatype == 'line' :
            nodes_nb = len(self.list_line_area)
        elif areatype == 'row' :
            nodes_nb = len(self.list_row_area)
        elif areatype == 'height' :
            nodes_nb = len(self.list_height_area)
        else :
            print "GetAreas '" + areatype +  "' : Unknown area type"
            sys.exit(1)

        for i in range(0,nodes_nb) :
            label, bmin, bmax, val = self.GetArea(areatype, i)
            llabel.append(label)
            lbmin.append(bmin)
            lbmax.append(bmax)
            lval.append(val)

        return llabel, lbmin, lbmax, lval 

        
    def EraseArea(self, areatype, num):
        """
        Remove Area.
        """
        if areatype == 'line' :
            node = self.list_line_area.pop(num)
        elif areatype == 'row' :
            node = self.list_row_area.pop(num)
        elif areatype == 'height' :
            node = self.list_height_area.pop(num)
        else :
            print "EraseErea" + areatype, " : Unknown area type"
            sys.exit(1)

        node.xmlRemoveChild('min')
        node.xmlRemoveChild('max')
        node.xmlRemoveChild('value')
        node.xmlRemoveNode()


    def setMatisseThermicVar(self, tag, val):
        """
        """
        self.node_phymodel.xmlSetData(tag, val)

        tinit = None
        tcrit = None
        
        if tag == 'tinit':
            tinit = val
        elif tag == 'tcrit':
            tcrit = val

        import Pages.Matisse as Matisse
        Matisse.MatisseThermUpdate(self.case,tinit,tcrit).compute()
        del Matisse
        

    def getMatisseThermicDoubleVar(self,tag):
        """
        """
        val = self.node_phymodel.xmlGetDouble(tag)

        if val == "" or val == None:
            self.node_phymodel.xmlInitChildNode(tag)
            val = self.defaultMatisseThermicValues()[tag]
            self.setMatisseThermicVar(tag, val)

        return val


    def setNatConvPanacheStatus(self, stat):
        """
        Input natural convection panache status
        """
        if stat not in self.status :
            sys.exit(1)

        self.node_mdcnt['status'] = stat


    def getNatConvPanacheStatus(self):
        """
        Return natural convection panache status
        """
        stat = self.node_mdcnt['status']
            
        if stat not in self.status :
            stat = self.defaultMatisseThermicValues()['imdcnt']
            self.setNatConvPanacheStatus(stat)
        return stat


#-------------------------------------------------------------------------------
# Main view class
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# 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, Hlist):
        """
        Constructor
        """
        self.Hlist = Hlist

  
    def _initList(self):
        """
        For each mouse selection we do reinitialize all lists.
        """
        self.labelL = []
        self.minL  = []
        self.maxL   = []
        self.valL = []


    def areaInfo(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
        #
        h = self.Hlist
        label  = h.tk.call(h, 'item', 'cget', entry, 0, '-text')
        bmin   = h.tk.call(h, 'item', 'cget', entry, 1, '-text')
        bmax   = h.tk.call(h, 'item', 'cget', entry, 2, '-text')
        value  = h.tk.call(h, 'item', 'cget', entry, 3, '-text')

        return label, bmin, bmax, value


    def setItems(self, entriesL):
        """
        Store values when a new selection is done.
        """
        self._initList()

        for entry in entriesL:
            label, bmin, bmax, value = self.areaInfo(entry)
            self.labelL.append(label)
            self.minL.append(bmin)
            self.maxL.append(bmax)
            self.valL.append(value)


    def widgetText(self):
        """
        Find the right texts for the widget layout.
        """
        label = self.labelL[0]
        bmin  = self.minL[0]
        bmax  = self.maxL[0]
        val   = self.valL[0]

        for i in self.labelL:
            if label != i: label = _MULTISEL
        for i in self.minL:
            if bmin  != i: bmin  = _MULTISEL
        for i in self.maxL:
            if bmax  != i: bmax  = _MULTISEL
        for i in self.valL:
            if val  != i: val  = _MULTISEL

        return label, bmin, bmax, val


class MatisseThermicView(TkPage.Page):
    """
    Class to open Matisse Page.
    """
    def _tkControlVariables(self):
        """
        Tkinter variables declaration.
        """

        #
        # String Var
        self.imdcnt = Tix.StringVar()

        #
        # Double Var
        self.puicon = Tix.DoubleVar()
        self.tinit  = Tix.DoubleVar() 
        self.tcrit  = Tix.DoubleVar()
        self.emicon = Tix.DoubleVar()
        self.emimur = Tix.DoubleVar()
        self.hepcnt = Tix.DoubleVar()
        self.dhpcnt = Tix.DoubleVar()

        self.label  = Tix.StringVar()
        self.bmin   = Tix.StringVar()
        self.bmax   = Tix.StringVar()
        self.value  = Tix.StringVar()

        # association between tix variable and tag

        self.variables=[
            ('puicon',self.puicon),
            ('tinit', self.tinit),
            ('tcrit', self.tcrit),
            ('emicon',self.emicon),
            ('emimur',self.emimur),
            ('hepcnt',self.hepcnt),
            ('dhpcnt',self.dhpcnt)]


    def ActiveWidget(self, i , stat) :
        if stat == 'off':
            self.e[i].config(state=DISABLED, fg='grey')
            self.e[i].unbind("<<Event>>")
            self.l1[i].config(fg='grey')
            self.l2[i].config(fg='grey')
            try:
                self.l3[i].config(fg='grey')
            except:
                pass
        else :
            self.e[i].config(state=NORMAL, fg='black')
            self.e[i].event_add("<<Event>>", "<Return>", "<Leave>", "<FocusOut>")
            self.e[i].bind("<<Event>>",TkPage.Callback(self.getMatisseThermicVar, i, self.variables[i]))
            self.l1[i].config(fg='black')
            self.l2[i].config(fg='black')
            try:
                self.l3[i].config(fg='black')
            except:
                pass


    def _pageControl(self):
        """
        Instantiate the matisse type modelling class.
        """
        self.model = MatisseThermicModel(self.case)
        self.model_mat_type = MatisseType.MatisseTypeModel(self.case)
        model_geom = MatisseGeom.MatisseGeomModel(self.case)
        self.lineStep = model_geom.getMatisseGeomDoubleVar('ptrres')
        self.rowStep = model_geom.getMatisseGeomDoubleVar('plgres')
        self.heightStep = model_geom.getMatisseGeomDoubleVar('epchel')

        self.lineMax = model_geom.getMatisseGeomDoubleVar('nptran')
        self.rowMax = model_geom.getMatisseGeomDoubleVar('nplgrs')
        self.heightMax = model_geom.getMatisseGeomDoubleVar('nchest')
        
        self.selectedEntry = None
        self.currentEntry = None
        self.entriesNumberH1 = 0
        self.entriesNumberH2 = 0
        self.entriesNumberH3 = 0

 

    def getMatisseThermicVar(self, i, variable, event=None):
        """
        Input thermiclic load variable.
        """
        tag=variable[0]
        var=variable[1]
        
        self.stbar.busy()

        if not (self.e[i].cget('state') == DISABLED) :

            if self.check2.hasType(self.e[i], var):
                t = var.get()
                self.model.setMatisseThermicVar(tag,t)
            
        self.stbar.idle()

 
    def getNatConvPanacheStatus(self, event=None):
        """
        Input constrained convection status.
        """
        
        self.stbar.busy()

        stat = self.imdcnt.get()
        self.model.setNatConvPanacheStatus(stat)

        self.ActiveWidget(5,stat)
        self.ActiveWidget(6,stat)

        self.stbar.idle()


    def selectHlist(self,h, 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 = h.hlist.info_selection()

        if  not self.selectedEntry:
            if h == self.h :
                self.hl2.config(state=NORMAL)
                self.hl3.config(state=NORMAL)
                self.e2.config(state=NORMAL)
                self.e3.config(state=NORMAL)
                self.e2.delete(0,END)
                self.e3.delete(0,END)
            elif h == self.h2 :
                self.h2l2.config(state=NORMAL)
                self.h2l3.config(state=NORMAL)
                self.h2e2.config(state=NORMAL)
                self.h2e3.config(state=NORMAL)
                self.h2e2.delete(0,END)
                self.h2e3.delete(0,END)
                
            elif h == self.h3 :
                self.h3l2.config(state=NORMAL)
                self.h3l3.config(state=NORMAL)
                self.h3e2.config(state=NORMAL)
                self.h3e3.config(state=NORMAL)
                self.h3e2.delete(0,END)
                self.h3e3.delete(0,END)

        elif self.currentEntry != self.selectedEntry:

            self.currentEntry = self.selectedEntry

            if h == self.h :
                if len(self.currentEntry) == 1:
                    self.hl2.config(state=NORMAL)
                    self.hl3.config(state=NORMAL)
                    self.e2.config(state=NORMAL)
                    self.e3.config(state=NORMAL)

                self.select.setItems(self.currentEntry)
                label, bmin, bmax, val = self.select.widgetText()
                self.e1.delete(0,END)
                self.e1.insert(0,label)
                self.e1.icursor(END)
                
                self.e2.delete(0,END)
                self.e2.insert(0,bmin)
                self.e2.icursor(END)
                
                self.e3.delete(0,END)
                self.e3.insert(0,bmax)
                self.e3.icursor(END)

                self.e4.delete(0,END)
                self.e4.insert(0,val)
                self.e4.icursor(END)

                if len(self.currentEntry) > 1:
                    self.hl2.config(state=DISABLED)
                    self.hl3.config(state=DISABLED)
                    self.e2.config(state=DISABLED)
                    self.e3.config(state=DISABLED)
                    
            elif h == self.h2 :
                if len(self.currentEntry) == 1:
                    self.h2l2.config(state=NORMAL)
                    self.h2l3.config(state=NORMAL)
                    self.h2e2.config(state=NORMAL)
                    self.h2e3.config(state=NORMAL)

                self.select2.setItems(self.currentEntry)
                label, bmin, bmax, val = self.select2.widgetText()

                self.h2e1.delete(0,END)
                self.h2e1.insert(0,label)
                self.h2e1.icursor(END)
                
                self.h2e2.delete(0,END)
                self.h2e2.insert(0,bmin)
                self.h2e2.icursor(END)
                
                self.h2e3.delete(0,END)
                self.h2e3.insert(0,bmax)
                self.h2e3.icursor(END)

                self.h2e4.delete(0,END)
                self.h2e4.insert(0,val)
                self.h2e4.icursor(END)

                if len(self.currentEntry) > 1:
                    self.h2l2.config(state=DISABLED)
                    self.h2l3.config(state=DISABLED)
                    self.h2e2.config(state=DISABLED)
                    self.h2e3.config(state=DISABLED)
                    
            elif h == self.h3 :
                if len(self.currentEntry) == 1:
                    self.h3l2.config(state=NORMAL)
                    self.h3l3.config(state=NORMAL)
                    self.h3e2.config(state=NORMAL)
                    self.h3e3.config(state=NORMAL)

                self.select3.setItems(self.currentEntry)
                label, bmin, bmax, val = self.select3.widgetText()

                self.h3e1.delete(0,END)
                self.h3e1.insert(0,label)
                self.h3e1.icursor(END)
                
                self.h3e2.delete(0,END)
                self.h3e2.insert(0,bmin)
                self.h3e2.icursor(END)
                
                self.h3e3.delete(0,END)
                self.h3e3.insert(0,bmax)
                self.h3e3.icursor(END)

                self.h3e4.delete(0,END)
                self.h3e4.insert(0,val)
                self.h3e4.icursor(END)

                if len(self.currentEntry) > 1:
                    self.h3l2.config(state=DISABLED)
                    self.h3l3.config(state=DISABLED)
                    self.h3e2.config(state=DISABLED)
                    self.h3e3.config(state=DISABLED)
                else :
                    self.h3l2.config(state=NORMAL)
                    self.h3l3.config(state=NORMAL)
                    self.h3e2.config(state=NORMAL)
                    self.h3e3.config(state=NORMAL)

    #
    # A Revoir
    def selectH1(self,entry=None):
        self.selectHlist(self.h)

    def selectH2(self,entry=None):
        self.selectHlist(self.h2)

    def selectH3(self,entry=None):
        self.selectHlist(self.h3)
            
    def _make_style(self):
        """
        Define beautyfull style in order to display columns in the Hlist.
        """
        self.style={}

        self.style['header'] = Tix.DisplayStyle(Tix.TEXT,
                                                refwindow=self.w2,
                                                anchor=CENTER,
                                                padx=5, pady=2,
                                                font=fB)

        self.style['valb'] = Tix.DisplayStyle(Tix.TEXT,
                                              refwindow=self.w2,
                                              padx=5,
                                              selectforeground='#fefefe',
                                              font=fB)
        self.style['val'] = Tix.DisplayStyle(Tix.TEXT,
                                             refwindow=self.w2,
                                             anchor=CENTER,
                                             padx=5,
                                             selectforeground='#fefefe',
                                             font=fN)
                                                

    def insertHlist(self, h, label, bmin, bmax, value, step ):
        """
        Create the item Hlist associated with the new boundary definition.
        """
        self.stbar.busy()

        if h == self.h :
            self.entriesNumberH1 = self.entriesNumberH1 +1
            entriesNumber = self.entriesNumberH1
        elif h == self.h2 :
            self.entriesNumberH2 = self.entriesNumberH2 +1
            entriesNumber = self.entriesNumberH2
        elif h == self.h3 :
            self.entriesNumberH3 = self.entriesNumberH3 +1
            entriesNumber = self.entriesNumberH3

#        if not label: label = "label" + "_" + repr(entriesNumber)
        name = 'item' + repr(entriesNumber)

        h.hlist.add(name, itemtype=Tix.TEXT, text=label,
                         style=self.style['valb'])

        h.hlist.item_create(name, 1, itemtype=Tix.TEXT,
                                 text=bmin,
                                 style=self.style['val'])

        h.hlist.item_create(name, 2, itemtype=Tix.TEXT,
                                 text=bmax,
                                 style=self.style['val'])
            
        h.hlist.item_create(name, 3, itemtype=Tix.TEXT,
                                 text=value,
                                 style=self.style['val'])
        val=step*float(bmin)
        h.hlist.item_create(name, 4, itemtype=Tix.TEXT,
                                 text=val,
                                 style=self.style['val'])
        val=step*float(bmax)
        h.hlist.item_create(name, 5, itemtype=Tix.TEXT,
                                 text=val,
                                 style=self.style['val'])

        self.stbar.idle()
        return label


    def getLabel(self, event=None):
        """
        Return the name of the boundary condition. It 's not allowed to have
        blank or not ASCII caracters in this name.
        """
        return  string.join(string.split(self.label.get()), '_')


    def getBmin(self, event=None):
        """
        """
        return self.bmin.get()


    def getBmax(self, event=None):
        """
        """
        return self.bmax.get()


    def getValue(self, event=None):
        """
        """
        return self.value.get()


    def eraseEntries(self,h, event=None):
        """
        This button is for delete all caracters in the three entries.
        """
        if h == self.h :
            self.e1.delete(0, END)
            self.e2.delete(0, END)
            self.e3.delete(0, END)
            self.e4.delete(0, END)
        elif h == self.h2 :    
            self.h2e1.delete(0, END)
            self.h2e2.delete(0, END)
            self.h2e3.delete(0, END)
            self.h2e4.delete(0, END)
        elif h == self.h3 :    
            self.h3e1.delete(0, END)
            self.h3e2.delete(0, END)
            self.h3e3.delete(0, END)
            self.h3e4.delete(0, END)


    def createHlist(self, h, areatype, step, event=None):
        """
        Upload the contents of the definition widget
        when the 'create' button is pushed.
        Checking consistency of values and interpreting
        complexe entry for reference if necessary.
        """
        self.stbar.busy()

        t = PageText()
        label = self.getLabel()
        sbmin  = self.getBmin()
        sbmax  = self.getBmax()
        svalue = self.getValue()

        # Reading  and add to Hlist
        #
        if not label:
            label = "Default"

        try :
            bmin = float(sbmin)
            bmax = float(sbmax)
            value = float(svalue)
        except:
            Dialog.Warning(self.master, title=t.WARNING,
                           text= "'" +label+ "'" + t.OUTOFBOUNDS)
            self.eraseEntries(h)
            self.currentEntry = None
            self.selectHlist(h)
            self.stbar.idle()
            return

        llabel, lbmin, lbmax, lval  = self.model.GetAreas(areatype)
        
        create = True
        #
        # Bounds check
        if (bmin > bmax) or (bmin < 0):
            create = False
        if (areatype == 'line'):
            if (bmax > self.lineMax) :
                create = False
        elif (areatype == 'row'):
            if (bmax > self.rowMax) :
                create = False
        elif (areatype == 'height'):
            if (bmax > self.heightMax) :
                create = False

        for area in range(0,len(llabel)) :
            #
            # No duplicate
            if ((label == llabel[area]) and
                (abs(bmin - float(lbmin[area])) < _EPSILON) and
                (abs(bmax - float(lbmax[area])) < _EPSILON) and
                (abs(value - float(lval[area])) < _EPSILON)) :
                create = False
                
            if (((bmin > float(lbmin[area])) and (bmin < float(lbmax[area]))) or
                ((bmax > float(lbmin[area])) and (bmax < float(lbmax[area])))) :
                create = False


        if create :
            name = self.insertHlist(h, label, sbmin, sbmax, svalue ,step)
            self.model.NewArea(areatype, label, bmin, bmax, value)
        else :
            Dialog.Warning(self.master, title=t.WARNING,
                           text= "'" +label+ "'" + t.OUTOFBOUNDS)


        self.eraseEntries(h)
        self.currentEntry = None
        self.selectHlist(h)
        self.stbar.idle()


    def cancelHlist(self,h, areatype , event=None):
        """
        Just delete the current selected entries from the Hlist and
        of course from the XML file.
        """
        if not self.currentEntry: return

        self.stbar.busy()

        for entry in self.currentEntry:
            if h == self.h :
                label, sbmin, sbmax, svalue = self.select.areaInfo(entry)
            elif h == self.h2 :
                label, sbmin, sbmax, svalue = self.select2.areaInfo(entry)
            elif h == self.h3 :
                label, sbmin, sbmax, svalue = self.select3.areaInfo(entry)

            bmin = float(sbmin)
            bmax = float(sbmax)
            value = float(svalue)

            llabel, lbmin, lbmax, lval  = self.model.GetAreas(areatype)
            cancel = False
            for area in range(0,len(llabel)) :
                if ((label == llabel[area]) and
                    (abs(bmin - float(lbmin[area])) < _EPSILON) and
                    (abs(bmax - float(lbmax[area])) < _EPSILON) and
                    (abs(value - float(lval[area])) < _EPSILON)) :
                    self.model.EraseArea(areatype, area)
                    cancel = True

            # Delete boundary region from the Hlist
            #
            if not cancel :
                print "Entry is in Hlist but not in XML"
                sys.exit(1)
            else :
#
#    Pb : si on ne supprime pas le dernier elt : lors de la creation d'une nouvelle hlist
#         il recupere un nom deja donne !!!
##                if h == self.h :
##                    self.entriesNumberH1 = self.entriesNumberH1 -1
##                elif  h == self.h2 :
##                    self.entriesNumberH2 = self.entriesNumberH2 -1
##                elif  h == self.h3 :
##                    self.entriesNumberH3 = self.entriesNumberH3 -1
                h.hlist.delete_entry(entry)

        self.currentEntry = None
        self.selectHlist(h)
        self.eraseEntries(h)
        self.stbar.idle()


    def replaceHlist(self, h, entry, label, bmin, bmax, value, step):
        """
        Add the item Hlist associated with the new boundary definition.
        """
        self.stbar.busy()

        # Update the Hlist
        #
        h.hlist.item_configure(entry, 0, text=label, style=self.style['valb'])
        h.hlist.item_configure(entry, 1, text=bmin, style=self.style['val'])
        h.hlist.item_configure(entry, 2, text=bmax, style=self.style['val'])
        h.hlist.item_configure(entry, 3, text=value, style=self.style['val'])
        val=step*float(bmin)
        h.hlist.item_configure(entry, 4, text=val, style=self.style['val'])
        val=step*float(bmax)
        h.hlist.item_configure(entry, 5, text=val, style=self.style['val'])
        
        #self.h.hlist.config(selectbackground=self.typeColor[type])

        self.stbar.idle()


    def editHlist(self, h, areatype, step, event = None) :
        """
        Modify previous selected entries.
        """

        if not self.currentEntry: return

        self.stbar.busy()

        t = PageText()
        toto = 0

        new_label = self.getLabel()
        new_bmin = self.getBmin()
        new_bmax = self.getBmax()
        new_value = self.getValue()

        if not new_label:
            new_label = "Default"

        if areatype == 'line' :
            step = self.lineStep 
        elif areatype == 'row' :
            step = self.rowStep
        elif areatype == 'height' :
            step = self.heightStep

        if len(self.currentEntry) == 1 :

            entry = self.currentEntry
            if h == self.h :
                label, sbmin, sbmax, svalue = self.select.areaInfo(entry)
            elif h == self.h2 :
                label, sbmin, sbmax, svalue = self.select2.areaInfo(entry)
            elif h == self.h3 :
                label, sbmin, sbmax, svalue = self.select3.areaInfo(entry)

            bmin = float(sbmin)
            bmax = float(sbmax)
            value = float(svalue)
                
            llabel, lbmin, lbmax, lval  = self.model.GetAreas(areatype)

            #
            # Bounds check
            modify = True

            #
            # Type check
            try : 
                fnew_bmin=float(new_bmin)
                fnew_bmax=float(new_bmax)
                fnew_value=float(new_value)
            except :
                Dialog.Warning(self.master, title=t.WARNING,
                               text= "'" +label+ "'" + t.OUTOFBOUNDS)
                self.eraseEntries(h)
                self.currentEntry = None
                self.selectHlist(h)
                self.stbar.idle()
                return

            if (fnew_bmin > fnew_bmax) or (fnew_bmin < 0):
                modify = False
            if (areatype == 'line'):
                if fnew_bmax > self.lineMax :
                    modify = False
            elif (areatype == 'height'):
                if (fnew_bmax > self.heightMax) :
                    modify = False
            elif (areatype == 'row'):
                if (fnew_bmax > self.rowMax) :
                    modify = False

            if not modify :
                Dialog.Warning(self.master, title=t.WARNING,
                               text= "'" +label+ "'" + t.OUTOFBOUNDS)
            else:
                for area in range(0,len(llabel)) :
                    if ((label == llabel[area]) and
                        (abs(bmin - float(lbmin[area])) <= _EPSILON) and
                        (abs(bmax - float(lbmax[area])) <= _EPSILON) and
                        (abs(value - float(lval[area])) <= _EPSILON)) :

                        if ((label != new_label) or
                            (abs(bmax - fnew_bmax) >= _EPSILON) or
                            (abs(bmin - fnew_bmin) >= _EPSILON) or
                            (abs(value - fnew_value) >= _EPSILON)) :

                            for area1 in range(0,len(llabel)) :
                                if area1 != area :
                                    if (((fnew_bmin > float(lbmin[area1])) and (fnew_bmin < float(lbmax[area1]))) or
                                        ((fnew_bmax > float(lbmin[area1])) and (fnew_bmax < float(lbmax[area1])))) :
                                        modify = False

                            if modify :
                                self.model.SetArea(areatype, area, new_label, new_bmin, new_bmax, new_value)
                                self.replaceHlist(h, entry, new_label, new_bmin, new_bmax, new_value, step)
                            else:
                                Dialog.Warning(self.master, title=t.WARNING,
                                               text= "'" +label+ "'" + t.OUTOFBOUNDS)

        else :
            for entry in self.currentEntry:

                if h == self.h :
                    label, sbmin, sbmax, svalue = self.select.areaInfo(entry)
                elif h == self.h2 :
                    label, sbmin, sbmax, svalue = self.select2.areaInfo(entry)
                elif h == self.h3 :
                    label, sbmin, sbmax, svalue = self.select3.areaInfo(entry)

                bmin = float(sbmin)
                bmax = float(sbmax)
                value = float(svalue)

                llabel, lbmin, lbmax, lval  = self.model.GetAreas(areatype)

                #
                # Type check
                try : 
                    fnew_value=float(new_value)
                except :
                    if new_value != _MULTISEL :
                        Dialog.Warning(self.master, title=t.WARNING,
                                       text= "'" +label+ "'" + t.BADVALUE)
                        self.eraseEntries(h)
                        self.currentEntry = None
                        self.selectHlist(h)
                        self.stbar.idle()
                        return

                for area in range(0,len(llabel)) :
                    if ((label == llabel[area]) or
                        (abs(bmin - float(lbmin[area])) <= _EPSILON) and
                        (abs(bmax - float(lbmax[area])) <= _EPSILON) and
                        (abs(value - float(lval[area])) <= _EPSILON)) :

                        if ((label != new_label) or new_value == _MULTISEL or
                            (abs(value - fnew_value) >= _EPSILON)) :

                            if (new_label == _MULTISEL) and (new_value != _MULTISEL): 
                                self.model.SetArea(areatype, area, None, None , None , new_value)
                                self.replaceHlist( h, entry, label, bmin, bmax, new_value, step)

                            elif (new_value == _MULTISEL) and (new_label != _MULTISEL) :
                                self.model.SetArea(areatype, area, new_label , None , None , None)
                                self.replaceHlist( h, entry, new_label, bmin, bmax, value, step)

                            elif (new_value != _MULTISEL) and (new_label != _MULTISEL) :
                                self.model.SetArea(areatype, area, new_label, None , None , new_value)
                                self.replaceHlist( h, entry, new_label, bmin, bmax, new_value, step)

                            else :
                                pass



        self.eraseEntries(h)
        self.currentEntry = None
        self.selectHlist(h)
        self.stbar.idle()


    def InitHlist(self,h, areatype, step):
        """
        Method for the _initializeWidgets method.
        """
        if h == self.h :
            self.entriesNumberH1 = 0
        elif h == self.h2 :
            self.entriesNumberH2 = 0
        elif h == self.h3 :
            self.entriesNumberH3 = 0

        self.cancelSelection(h)
        try:
            h.hlist.delete_all()
        except:
            pass

        llabel, lbmin, lbmax, lval  = self.model.GetAreas(areatype)

        n = len(llabel)
        if ((n != len(lbmin)) or (n != len(lbmax)) or (n != len(lval))):
            print "XML format error : bad definition of <area> "
            sys.exit(1)
        
        if len(llabel) == 0 :
            dlabel, dmin, dmax, dval = self.model.DefaultArea(areatype)
            self.model.NewArea(areatype, dlabel, dmin, dmax, dval)
            llabel.append(dlabel)
            lbmin.append(dmin)
            lbmax.append(dmax)
            lval.append(dval)

        for area in range(0,len(llabel)):
            self.insertHlist(h,llabel[area], lbmin[area], lbmax[area], lval[area],step)


    def cancelSelection(self,h):
        """
        Fonction for the Popup Menu.
        Blank the selection.
        """
        h.hlist.selection_clear()

        self.currentEntry = None
        self.eraseEntries(h)


    def cancelSelectionH1(self, event = None):
        self.cancelSelection(self.h)


    def cancelSelectionH2(self, event = None):
        self.cancelSelection(self.h2)


    def cancelSelectionH3(self, event = None):
        self.cancelSelection(self.h3)


    def _createWidgets(self):
        """
        Create the Page layout.
        """
        t = PageText()

                # NoteBook and tabs layout
        #
        nb = Tix.NoteBook(self.myPage)
        nb.pack(expand=1, side=TOP, fill=BOTH)
    
        nb.nbframe.config(background=self.bg, backpagecolor=self.bg)
        nb.nbframe.config(focuscolor=self.bg, inactivebackground=wm['inactivebackground'])
        nb.nbframe.config(relief=RAISED)
        nb.nbframe.config(font=fT, tabpadx='10', tabpady='2')
        nb.add('page1', anchor='center', label=t.PARAMETERS)
        nb.add('page2', anchor='center', label=t.FILTER)

        ########################################################
        # NoteBook Page 1
        ########################################################


        lf = Tix.LabelFrame(nb.page1, bd=2, label=t.MATISSE_THERMIC_TITLE, relief=FLAT)
        lf.label.config(font=fT)
        lf.pack(side=TOP, fill=X, padx=10, pady=10)

        self.w1 = Tix.Frame(lf.frame, relief=FLAT)
        self.w1.pack(side=TOP, fill=X, pady=10)

        # Separator
        #
        s1 = Tix.Frame(lf.frame, height=2, bd=2, relief=SUNKEN)
        s1.pack(side=TOP, fill=X)

        self.w2 = Tix.Frame(lf.frame, relief=FLAT)
        self.w2.pack(side=TOP, fill=X, pady=10)

        # IMDCNT
        #
        h1 = Tix.Label(self.w1, text=t.texts['imdcnt'][0])
        h1.grid(row=0, column=0, padx=2, pady=5, sticky=W)

        h2 = Tix.Label(self.w1, text=t.texts['imdcnt'][1])
        h2.grid(row=0, column=1, padx=2, pady=5, sticky=W)


        self.c1 = Tix.Checkbutton(self.w1, onvalue='on', offvalue='off',
                                  variable=self.imdcnt,
                                  command=self.getNatConvPanacheStatus)
        self.c1.grid(row=0, column=2,  padx=3, pady=5 )

        #
        # Vars
        
        self.l1=[0]*len(self.variables)
        self.l2=[0]*len(self.variables)
        self.l3=[0]*len(self.variables)
        self.e=[0]*len(self.variables)
        
        for i in range(len(self.variables)):

            variable=self.variables[i]
 
            self.l1[i] = Tix.Label(self.w2, text=t.texts[variable[0]][0])
            self.l1[i].grid(row=i, column=0, padx=2, pady=5, sticky=W)
            self.l2[i] = Tix.Label(self.w2, text=t.texts[variable[0]][1])
            self.l2[i].grid(row=i, column=1, padx=2, pady=5, sticky=W)

            self.e[i] = Tix.Entry(self.w2, width=10, textvariable=variable[1])
            self.e[i].grid(row=i, column=2, padx=3, pady=5)
            self.e[i].event_add("<<Event>>", "<Return>", "<Leave>", "<FocusOut>")
            self.e[i].bind("<<Event>>",TkPage.Callback(self.getMatisseThermicVar, i, variable))

            try:
                self.l3[i] = Tix.Label(self.w2, text=t.texts[variable[0]][2])
                self.l3[i].grid(row=i, column=3, pady=5, sticky=W)
            except :
                pass

        ########################################################
        # NoteBook Page 2
        ########################################################
    
        nb2 = Tix.NoteBook(nb.page2)
        nb2.pack(expand=1, side=TOP, fill=BOTH)
    
        nb2.nbframe.config(background=self.bg, backpagecolor=self.bg)
        nb2.nbframe.config(focuscolor=self.bg, inactivebackground=wm['inactivebackground'])
        nb2.nbframe.config(relief=RAISED)
        nb2.nbframe.config(font=fT, tabpadx='10', tabpady='2')
        nb2.add('page1', anchor='center', label=t.LINE , raisecmd=self.cancelSelectionH1)
        nb2.add('page2', anchor='center', label=t.ROW, raisecmd=self.cancelSelectionH2)
        nb2.add('page3', anchor='center', label=t.HEIGHT , raisecmd=self.cancelSelectionH3)


        ########################################################
        # NoteBook Page 2.1 Hlist 1
        ########################################################

        lf1 = Tix.LabelFrame(nb2.page1, bd=2, label=t.LOADINLINE, relief=FLAT)
        lf1.label.config(font=fT)
        lf1.pack(side=TOP, fill=X, padx=10, pady=10)

        self.w2 = Tix.Frame(lf1.frame, relief=FLAT)
        self.w2.pack(side=TOP, fill=X)

        # Put a simple hierachy into the Hlist (two levels).
        #

        self.h = Tix.ScrolledHList(self.w2, options='hlist.columns 7 hlist.header 1 ' )
        self.h.config(scrollbar="auto +y +x")

        self._make_style()
        # selectmode='extended' -> multi select with <Shift> and <Ctrl>
        # selectmode='multiple' -> multi select only with <Shift>
        #
        self.h.hlist.config(selectmode='extended',
                            browsecmd=self.selectH1,
                            bg=wm['hlistbackground'])
        self.h.hsb.config(width=10, bd=1)
        self.h.vsb.config(width=10, bd=1)
        self.h.pack(expand=1, fill=BOTH, padx=10, pady=10, side=TOP)

        # Create the headers
        #
        self.h.hlist.header_create(0, itemtype=Tix.TEXT, text=t.LABEL,
                                   style=self.style['header'])
        self.h.hlist.header_create(1, itemtype=Tix.TEXT, text=t.LMIN,
                                   style=self.style['header'])
        self.h.hlist.header_create(2, itemtype=Tix.TEXT, text=t.LMAX,
                                   style=self.style['header'])
        self.h.hlist.header_create(3, itemtype=Tix.TEXT, text=t.VALUE,
                                   style=self.style['header'])
        self.h.hlist.header_create(4, itemtype=Tix.TEXT, text=t.LLMIN,
                                   style=self.style['header'])
        self.h.hlist.header_create(5, itemtype=Tix.TEXT, text=t.LLMAX,
                                   style=self.style['header'])

        # Notice that we use 5 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 5 column header is
        # not shown unless the Hlist window is wider than its contents.
        #
        self.h.hlist.column_width(6,0)

        # Let configure the appearance of the Hlist subwidget 
        #
        self.h.hlist.config(separator='.', width=25, height=11, drawbranch=0, indent=10)

        # Let configure the width of the columns
        #
##        self.h.hlist.column_width(0, chars=16)
##        self.h.hlist.column_width(1, chars=9)
##        self.h.hlist.column_width(2, chars=12)
##        self.h.hlist.column_width(3, chars=16)

        # Create the mouse selection instance
        #
        self.select = MultiSelect(self.h.hlist)

        # Separator
        #
        s = Tix.Frame(lf1.frame, height=2, bd=2, relief=SUNKEN)
        s.pack(side=TOP, fill=X)

        f1 = Tix.Frame(lf1.frame, relief=FLAT)
        f1.pack(side=TOP, fill=X)

        hl1 = Tix.Label(f1, text=t.LABEL)
        self.hl2 = Tix.Label(f1, text=t.LMIN)
        self.hl3 = Tix.Label(f1, text=t.LMAX)
        hl4 = Tix.Label(f1, text=t.VALUE)

        hl1.grid(row=0, column=0, padx=3, pady=5, sticky=E)
        self.hl2.grid(row=1, column=0, padx=3, pady=5, sticky=E)
        self.hl3.grid(row=2, column=0, padx=3, pady=5, sticky=E)
        hl4.grid(row=3, column=0, padx=3, pady=5, sticky=E)

        self.e1 = Tix.Entry(f1, bd=2, width=15, textvariable=self.label)
        self.e2 = Tix.Entry(f1, bd=2, width=15, textvariable=self.bmin)
        self.e3 = Tix.Entry(f1, bd=2, width=15, textvariable=self.bmax)
        self.e4 = Tix.Entry(f1, bd=2, width=15, textvariable=self.value)

        self.e4.bind('<Return>',TkPage.Callback(self.createHlist, self.h, 'line', self.lineStep))

        self.e1.grid(row=0, column=1, padx=5, pady=5, sticky=W)
        self.e2.grid(row=1, column=1, padx=5, pady=5, sticky=W)
        self.e3.grid(row=2, column=1, padx=5, pady=5, sticky=W)
        self.e4.grid(row=3, column=1, padx=5, pady=5, sticky=W)

        box1 = Tix.ButtonBox(f1, orientation=VERTICAL, relief=FLAT)
        box1.add('create', text=t.CREATE)
        box1.create.bind('<ButtonRelease-1>',TkPage.Callback(self.createHlist, self.h,'line',self.lineStep))
        #box1.create.bind("<<Event>>",TkPage.Callback(self.createHlist,self.h, 'line'))
        box1.add('modify', text=t.MODIFY)
        box1.modify.bind('<ButtonRelease-1>',TkPage.Callback(self.editHlist, self.h,'line',self.lineStep))
        box1.add('erase',  text=t.ERASE)
        box1.erase.bind('<ButtonRelease-1>',TkPage.Callback(self.cancelHlist, self.h,'line'))
        box1.grid(row=0, column=2, rowspan=4, padx=15, pady=2, sticky=W)

        ########################################################
        # NoteBook Page 2.2 Hlist 2
        ########################################################

        lf2 = Tix.LabelFrame(nb2.page2, bd=2, label=t.LOADINROW, relief=FLAT)
        lf2.label.config(font=fT)
        lf2.pack(side=TOP, fill=X, padx=10, pady=10)

        self.w3 = Tix.Frame(lf2.frame, relief=FLAT)
        self.w3.pack(side=TOP, fill=X)

        # Put a simple hierachy into the Hlist (two levels).
        #

        self.h2 = Tix.ScrolledHList(self.w3, options='hlist.columns 7 hlist.header 1 ' )
        self.h2.config(scrollbar="auto +y +x")

        self._make_style()
        # selectmode='extended' -> multi select with <Shift> and <Ctrl>
        # selectmode='multiple' -> multi select only with <Shift>
        #
        self.h2.hlist.config(selectmode='extended',
                            browsecmd=self.selectH2,
                            bg=wm['hlistbackground'])
        self.h2.hsb.config(width=10, bd=1)
        self.h2.vsb.config(width=10, bd=1)
        self.h2.pack(expand=1, fill=BOTH, padx=10, pady=10, side=TOP)

        # Create the headers
        #
        self.h2.hlist.header_create(0, itemtype=Tix.TEXT, text=t.LABEL,
                                   style=self.style['header'])
        self.h2.hlist.header_create(1, itemtype=Tix.TEXT, text=t.RMIN,
                                   style=self.style['header'])
        self.h2.hlist.header_create(2, itemtype=Tix.TEXT, text=t.RMAX,
                                   style=self.style['header'])
        self.h2.hlist.header_create(3, itemtype=Tix.TEXT, text=t.VALUE,
                                   style=self.style['header'])
        self.h2.hlist.header_create(4, itemtype=Tix.TEXT, text=t.RRMIN,
                                   style=self.style['header'])
        self.h2.hlist.header_create(5, itemtype=Tix.TEXT, text=t.RRMAX,
                                   style=self.style['header'])

        # Notice that we use 5 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 5 column header is
        # not shown unless the Hlist window is wider than its contents.
        #
        self.h2.hlist.column_width(6,0)

        # Let configure the appearance of the Hlist subwidget 
        #
        self.h2.hlist.config(separator='.', width=25, height=11, drawbranch=0, indent=10)

        # Let configure the width of the columns
        #
##        self.h2.hlist.column_width(0, chars=16)
##        self.h2.hlist.column_width(1, chars=9)
##        self.h2.hlist.column_width(2, chars=12)
##        self.h2.hlist.column_width(3, chars=16)

        # Create the mouse selection instance
        #
        self.select2 = MultiSelect(self.h2.hlist)

        # Separator
        #
        s = Tix.Frame(lf2.frame, height=2, bd=2, relief=SUNKEN)
        s.pack(side=TOP, fill=X)

        f2 = Tix.Frame(lf2.frame, relief=FLAT)
        f2.pack(side=TOP, fill=X)

        h2l1 = Tix.Label(f2, text=t.LABEL)
        self.h2l2 = Tix.Label(f2, text=t.RMIN)
        self.h2l3 = Tix.Label(f2, text=t.RMAX)
        h2l4 = Tix.Label(f2, text=t.VALUE)

        h2l1.grid(row=0, column=0, padx=3, pady=5, sticky=E)
        self.h2l2.grid(row=1, column=0, padx=3, pady=5, sticky=E)
        self.h2l3.grid(row=2, column=0, padx=3, pady=5, sticky=E)
        h2l4.grid(row=3, column=0, padx=3, pady=5, sticky=E)

        self.h2e1 = Tix.Entry(f2, bd=2, width=15, textvariable=self.label)
        self.h2e2 = Tix.Entry(f2, bd=2, width=15, textvariable=self.bmin)
        self.h2e3 = Tix.Entry(f2, bd=2, width=15, textvariable=self.bmax)
        self.h2e4 = Tix.Entry(f2, bd=2, width=15, textvariable=self.value)

        self.h2e4.bind('<Return>',TkPage.Callback(self.createHlist, self.h2, 'row', self.lineStep))

        self.h2e1.grid(row=0, column=1, padx=5, pady=5, sticky=W)
        self.h2e2.grid(row=1, column=1, padx=5, pady=5, sticky=W)
        self.h2e3.grid(row=2, column=1, padx=5, pady=5, sticky=W)
        self.h2e4.grid(row=3, column=1, padx=5, pady=5, sticky=W)

        h2box1 = Tix.ButtonBox(f2, orientation=VERTICAL, relief=FLAT)
        h2box1.add('create', text=t.CREATE)
        h2box1.create.bind('<ButtonRelease-1>',TkPage.Callback(self.createHlist, self.h2,'row',self.rowStep))
        #box1.create.bind("<<Event>>",TkPage.Callback(self.createHlist,self.h2, 'row'))
        h2box1.add('modify', text=t.MODIFY)
        h2box1.modify.bind('<ButtonRelease-1>',TkPage.Callback(self.editHlist, self.h2,'row',self.rowStep))
        h2box1.add('erase',  text=t.ERASE)
        h2box1.erase.bind('<ButtonRelease-1>',TkPage.Callback(self.cancelHlist, self.h2,'row'))
        h2box1.grid(row=0, column=2, rowspan=4, padx=15, pady=2, sticky=W)

        ########################################################
        # NoteBook Page 2.3 Hlist 2
        ########################################################

        lf3 = Tix.LabelFrame(nb2.page3, bd=2, label=t.LOADINHEIGHT, relief=FLAT)
        lf3.label.config(font=fT)
        lf3.pack(side=TOP, fill=X, padx=10, pady=10)

        self.w4 = Tix.Frame(lf3.frame, relief=FLAT)
        self.w4.pack(side=TOP, fill=X)

        # Put a simple hierachy into the Hlist (two levels).
        #

        self.h3 = Tix.ScrolledHList(self.w4, options='hlist.columns 7 hlist.header 1 ' )
        self.h3.config(scrollbar="auto +y +x")

        self._make_style()
        # selectmode='extended' -> multi select with <Shift> and <Ctrl>
        # selectmode='multiple' -> multi select only with <Shift>
        #
        self.h3.hlist.config(selectmode='extended',
                            browsecmd=self.selectH3,
                            bg=wm['hlistbackground'])
        self.h3.hsb.config(width=10, bd=1)
        self.h3.vsb.config(width=10, bd=1)
        self.h3.pack(expand=1, fill=BOTH, padx=10, pady=10, side=TOP)

        # Create the headers
        #
        self.h3.hlist.header_create(0, itemtype=Tix.TEXT, text=t.LABEL,
                                   style=self.style['header'])
        self.h3.hlist.header_create(1, itemtype=Tix.TEXT, text=t.HMIN,
                                   style=self.style['header'])
        self.h3.hlist.header_create(2, itemtype=Tix.TEXT, text=t.HMAX,
                                   style=self.style['header'])
        self.h3.hlist.header_create(3, itemtype=Tix.TEXT, text=t.VALUE,
                                   style=self.style['header'])
        self.h3.hlist.header_create(4, itemtype=Tix.TEXT, text=t.HHMIN,
                                   style=self.style['header'])
        self.h3.hlist.header_create(5, itemtype=Tix.TEXT, text=t.HHMAX,
                                   style=self.style['header'])

        # Notice that we use 5 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 5 column header is
        # not shown unless the Hlist window is wider than its contents.
        #
        self.h3.hlist.column_width(6,0)

        # Let configure the appearance of the Hlist subwidget 
        #
        self.h3.hlist.config(separator='.', width=25, height=11, drawbranch=0, indent=10)

        # Let configure the width of the columns
        #
##        self.h3.hlist.column_width(0, chars=16)
##        self.h3.hlist.column_width(1, chars=9)
##        self.h3.hlist.column_width(2, chars=12)
##        self.h3.hlist.column_width(3, chars=16)

        # Create the mouse selection instance
        #
        self.select3 = MultiSelect(self.h3.hlist)

        # Separator
        #
        s = Tix.Frame(lf3.frame, height=2, bd=2, relief=SUNKEN)
        s.pack(side=TOP, fill=X)

        f3 = Tix.Frame(lf3.frame, relief=FLAT)
        f3.pack(side=TOP, fill=X)

        h3l1 = Tix.Label(f3, text=t.LABEL)
        self.h3l2 = Tix.Label(f3, text=t.HMIN)
        self.h3l3 = Tix.Label(f3, text=t.HMAX)
        h3l4 = Tix.Label(f3, text=t.VALUE)

        h3l1.grid(row=0, column=0, padx=3, pady=5, sticky=E)
        self.h3l2.grid(row=1, column=0, padx=3, pady=5, sticky=E)
        self.h3l3.grid(row=2, column=0, padx=3, pady=5, sticky=E)
        h3l4.grid(row=3, column=0, padx=3, pady=5, sticky=E)

        self.h3e1 = Tix.Entry(f3, bd=2, width=15, textvariable=self.label)
        self.h3e2 = Tix.Entry(f3, bd=2, width=15, textvariable=self.bmin)
        self.h3e3 = Tix.Entry(f3, bd=2, width=15, textvariable=self.bmax)
        self.h3e4 = Tix.Entry(f3, bd=2, width=15, textvariable=self.value)

        self.h3e4.bind('<Return>',TkPage.Callback(self.createHlist, self.h3, 'height', self.lineStep))

        self.h3e1.grid(row=0, column=1, padx=5, pady=5, sticky=W)
        self.h3e2.grid(row=1, column=1, padx=5, pady=5, sticky=W)
        self.h3e3.grid(row=2, column=1, padx=5, pady=5, sticky=W)
        self.h3e4.grid(row=3, column=1, padx=5, pady=5, sticky=W)

        h3box1 = Tix.ButtonBox(f3, orientation=VERTICAL, relief=FLAT)
        h3box1.add('create', text=t.CREATE)
        h3box1.create.bind('<ButtonRelease-1>',TkPage.Callback(self.createHlist, self.h3,'height',self.heightStep))
        h3box1.add('modify', text=t.MODIFY)
        h3box1.modify.bind('<ButtonRelease-1>',TkPage.Callback(self.editHlist, self.h3,'height',self.heightStep))
        h3box1.add('erase',  text=t.ERASE)
        h3box1.erase.bind('<ButtonRelease-1>',TkPage.Callback(self.cancelHlist, self.h3,'height'))
        h3box1.grid(row=0, column=2, rowspan=4, padx=15, pady=2, sticky=W)
# A revoir
##        nb2.page1.bind("<<Event>>",TkPage.Callback(self.eraseEntries, self.h))
##        nb2.page2.bind('<ButtonRelease-1>',TkPage.Callback(self.eraseEntries, self.h2))
##        nb2.page3.bind('<ButtonRelease-1>',TkPage.Callback(self.eraseEntries, self.h3))

    def _initializeWidgets(self):
        """
        Extract resquested informations from XML document.
        This informations are used to initialize the widgets.
        For this page default values of all widgets are necessary
        included in the XML file.
        """

        stat = self.model.getNatConvPanacheStatus()
        self.imdcnt.set(stat)
        self.ActiveWidget(5,stat)
        self.ActiveWidget(6,stat)
        
        for variable in self.variables :
            val = self.model.getMatisseThermicDoubleVar(variable[0])
            variable[1].set(val)

        self.InitHlist(self.h,'line',self.lineStep)
        self.InitHlist(self.h2,'row',self.rowStep)
        self.InitHlist(self.h3,'height',self.heightStep)
        
            

#-------------------------------------------------------------------------------
# Text and messages for this page
#-------------------------------------------------------------------------------


class PageText:
    """
    Storage of all texts and messages for this page.
    """
    def __init__(self):
        if Tool.GuiParam.lang == 'fr':
            self.PARAMETERS = 'Paramètres'
            self.LINE = 'Ligne'
            self.ROW = 'Rangée'
            self.HEIGHT = 'Hauteur'
            self.FILTER = 'Reseau de conteneurs'
            self.LOADINLINE = 'Charge en ligne'
            self.LOADINROW = 'Charge en rangée'
            self.LOADINHEIGHT = 'Charge en hauteur'
            self.LABEL = 'Label'
            self.LMIN = 'Distance min \n  (en lignes)'
            self.LMAX = 'Distance max \n  (en lignes)'
            self.LLMIN = 'Distance min \n      (m)'
            self.LLMAX = 'Distance max \n      (m)'
            self.RMIN = 'Distance min \n (en rangées)'
            self.RMAX = 'Distance min \n (en rangées)'
            self.RRMIN = 'Distance min \n      (m)'
            self.RRMAX = 'Distance max \n      (m)'
            self.HMIN = 'Hauteur min \n (en mailles)'
            self.HMAX = 'Hauteur max \n (en mailles)'
            self.HHMIN = 'Hauteur min \n     (m)'
            self.HHMAX = 'Hauteur max \n     (m)'
            self.VALUE = 'Valeur'
            self.CREATE= "Créer"
            self.ERASE = "Effacer"
            self.MODIFY= "Modifier"
            self.OUTOFBOUNDS = " mal spécifiée : revoir la définition des bornes min et max et de la valeur"
            self.WARNING          = "Attention"
            self.BADVALUE          = " mal spécifiée : revoir la valeur"
           
            self.MATISSE_THERMIC_TITLE="Charge thermique"
            self.texts={}
            self.texts['imdcnt'] = (1,"Modélisation des panaches de convection naturelle")
            self.texts['puicon'] = (2,"Puissance d'un conteneur","W")
            self.texts['tinit'] = (3,"Température d'air en entree","°C")
            self.texts['tcrit'] = (4,"Température d'air de sortie critique","°C")
            self.texts['emicon'] = (5,"Emissivité des conteneurs")
            self.texts['emimur'] = (6,"Emissivité des murs")
            self.texts['hepcnt'] = (8,"Hauteur d'érosion des panaches de convection naturelle","m")
            self.texts['dhpcnt'] = (9,"Débit enthalpique des panaches de convection naturelle","W")
        else:
            self.MATISSE_THERMIC_TITLE = "Thermal load"
            self.FILTER = 'Canisters network'
            self.PARAMETERS = 'Parameters'
            self.LINE = 'Line'
            self.ROW = 'Row'
            self.HEIGHT = 'Height'
            self.LOADINLINE = 'Load in line'
            self.LOADINROW = 'Load in row'
            self.LOADINHEIGHT = 'Load in height'
            self.LABEL = 'Label'
            self.LMIN = 'Distance min \n  (in lines)'
            self.LMAX = 'Distance max \n  (in lines)'
            self.LLMIN = 'Distance min \n      (m)'
            self.LLMAX = 'Distance max \n      (m)'
            self.RMIN = 'Distance min \n (in rows)'
            self.RMAX = 'Distance min \n (in rows)'
            self.RRMIN = 'Distance min \n      (m)'
            self.RRMAX = 'Distance max \n      (m)'
            self.HMIN = 'Height min \n  (in cells)'
            self.HMAX = 'Height max \n  (in cells)'
            self.HHMIN = 'Height min \n     (m)'
            self.HHMAX = 'Height max \n     (m)'
            self.VALUE = 'Value'
            self.CREATE        = "Create"
            self.ERASE         = "Erase"
            self.MODIFY        = "Modify"
            self.WARNING          = "Warning"
            self.OUTOFBOUNDS = " bad definition : see the bounds and the value definition"
            self.BADVALUE          = " bad definition : see the value"

           
            self.texts={}
            self.texts['imdcnt'] = (1,"Natural convection plume modelling")
            self.texts['puicon'] = (2,"Canister heating power","W")
            self.texts['tinit'] = (3,"Inlet air temperature","°C")
            self.texts['tcrit'] = (4,"Critical outlet air temperature","°C")
            self.texts['emicon'] = (5,"Canister emissivity")
            self.texts['emimur'] = (6,"Wall emissivity")
            self.texts['hepcnt'] = (8,"Natural convection plume erosion height","m")
            self.texts['dhpcnt'] = (9,"Natural convection plume heat flowrate","W")


#-------------------------------------------------------------------------------
# End
#-------------------------------------------------------------------------------


syntax highlighted by Code2HTML, v. 0.9.1