# -*- coding: iso-8859-1 -*-
#
#-------------------------------------------------------------------------------
#
#     This file is part of the Code_Saturne User Interface, element of the
#     Code_Saturne CFD tool.
#
#     Copyright (C) 1998-2009 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 contains the following classes:
- LabelDelegate
- CodeNumberDelegate
- BoundaryNatureDelegate
- StandardItemVolumeNature
- FlagBox
- VolumeNatureDelegate
- LocalizationSelectorDelegate
- StandardItemModelLocalization
- LocalizationView
- VolumeLocalizationView
- BoundaryLocalizationView
"""

#-------------------------------------------------------------------------------
# Standard modules
#-------------------------------------------------------------------------------

import string, logging

#-------------------------------------------------------------------------------
# Third-party modules
#-------------------------------------------------------------------------------

from PyQt4.QtCore import *
from PyQt4.QtGui  import *

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

from Base.Toolbox import GuiParam
from LocalizationForm import Ui_LocalizationForm
from Base.Common import LABEL_LENGTH_MAX
from Base.QtPage import IntValidator, RegExpValidator
from Pages.PreProcessingInformationsView import Informations, preprocessorFile
from Pages.LocalizationModel import LocalizationModel, Zone

#-------------------------------------------------------------------------------
# log config
#-------------------------------------------------------------------------------

logging.basicConfig()
log = logging.getLogger("LocalizationView")
log.setLevel(GuiParam.DEBUG)

#-------------------------------------------------------------------------------
# Line edit delegate for the label
#-------------------------------------------------------------------------------

class LabelDelegate(QItemDelegate):
    """
    Use of a QLineEdit in the table.
    """
    def __init__(self, parent, mdl):
        super(LabelDelegate, self).__init__(parent)
        self.parent = parent
        self.mdl    = mdl


    def createEditor(self, parent, option, index):
        editor = QLineEdit(parent)
        rx = "[\-_A-Za-z0-9]{1," + str(LABEL_LENGTH_MAX) + "}"
        self.regExp = QRegExp(rx)
        v = RegExpValidator(editor, self.regExp)
        editor.setValidator(v)
        return editor


    def setEditorData(self, editor, index):
        v = index.model().data(index, Qt.DisplayRole).toString()
        self.p_value = str(v)
        editor.setText(v)


    def setModelData(self, editor, model, index):
        if not editor.isModified():
            return

        if editor.validator().state == QValidator.Acceptable:
            p_value = str(editor.text())

            if p_value in self.mdl.getLabelsZonesList():
                default              = {}
                default['label']     = self.p_value
                default['list']      = self.mdl.getLabelsZonesList()
                default['regexp'] = self.regExp
                log.debug("setModelData-> default = %s" % default)

                from VerifyExistenceLabelDialogView import VerifyExistenceLabelDialogView
                dialog = VerifyExistenceLabelDialogView(self.parent, default)
                if dialog.exec_():
                    result = dialog.get_result()
                    p_value  = result['label']
                    log.debug("setModelData-> result = %s" % result)
                else:
                    p_value = self.p_value

            model.setData(index, QVariant(QString(p_value)), Qt.DisplayRole)

#-------------------------------------------------------------------------------
# QLineEdit delegate for the zone
#-------------------------------------------------------------------------------

class CodeNumberDelegate(QItemDelegate):
    def __init__(self, parent, mdl):
        super(CodeNumberDelegate, self).__init__(parent)
        self.parent = parent
        self.mdl = mdl


    def createEditor(self, parent, option, index):
        editor = QLineEdit(parent)
        validator = IntValidator(editor, min=0, max=999)
        editor.setValidator(validator)
        #editor.installEventFilter(self)
        return editor


    def setEditorData(self, editor, index):
        self.value = index.model().data(index, Qt.DisplayRole).toString()
        editor.setText(self.value)


    def setModelData(self, editor, model, index):
        value, ok = editor.text().toInt()

        # Check for unicity
        if value != self.value and str(value) in self.mdl.getCodeNumbersList():
            title = self.tr("Warning")
            msg   = self.tr("Zone number can be used only once.\n"\
                            "Please give another value.")
            QMessageBox.warning(self.parent, title, msg)
            return

        if editor.validator().state == QValidator.Acceptable:
            model.setData(index, QVariant(value), Qt.DisplayRole)

#-------------------------------------------------------------------------------
# QComboBox delegate for the boundary nature
#-------------------------------------------------------------------------------

class BoundaryNatureDelegate(QItemDelegate):
    """
    Use of a combo box in the table.
    """
    def __init__(self, parent, dicoM2V):
        super(BoundaryNatureDelegate, self).__init__(parent)
        self.parent   = parent
        self.dicoM2V = dicoM2V

        self.dicoV2M = {}
        for k, v in self.dicoM2V.items():
            self.dicoV2M[v] = k


    def createEditor(self, parent, option, index):
        editor = QComboBox(parent)
        for k in self.dicoV2M.keys():
            editor.addItem(k)
        editor.installEventFilter(self)
        #editor.setSizeAdjustPolicy(QComboBox.AdjustToContents)
        editor.setMinimumWidth(100)
        return editor


    def setEditorData(self, comboBox, index):
        row = index.row()
        col = index.column()
        str_model = index.model().getData(row, col)
        idx = self.dicoM2V.keys().index(str_model)
        #str_view  = self.dicoM2V[str_model]
        #comboBox.setItem(str_view)
        comboBox.setCurrentIndex(idx)


    def setModelData(self, comboBox, model, index):
        txt   = str(comboBox.currentText())
        value = self.dicoV2M[txt]
        selectionModel = self.parent.selectionModel()
        for idx in selectionModel.selectedIndexes():
            if idx.column() == index.column():
                model.setData(idx, QVariant(value), Qt.DisplayRole)


    def tr(self, text):
        return text

#-------------------------------------------------------------------------------
# StandarItemModel class for QComboBox in nature delegate (Volumic)
#-------------------------------------------------------------------------------

class StandardItemVolumeNature(QStandardItemModel):
    """
    QStandardItemModel associated with the QComboBox
    in the delegate (validator) for the nature in the case of volumic zone.

    Attr. natureList is a dictionnary between model string and view string.
    Attr. dicoNature holds value 'on' or 'off' if the item is checked or not.
    """

    def __init__(self, dicoM2V, data):
        """
        """
        QStandardItemModel.__init__(self)

        # Dictionary item to label for display
        self.dicoM2V = dicoM2V
        # Dictionary item to status (on/off)
        self.dicoNature = data

        #self.keys = self.natureList.keys() # ordered tuple
        self.keys = Zone('VolumicZone').getNatureList()

        self.setColumnCount(1)

        row = 0
        for key in self.keys:
            if key in ('initialization', 'head_losses'):
                self.setItem(row, QStandardItem(QString(str(self.dicoM2V[key]))))
                row += 1
        self.setRowCount(row)


    def data(self, index, role):
        if not index.isValid():
            return QVariant()

        if role == Qt.EditRole:
            key = self.keys[index.row()]
            return QVariant(self.dicoM2V[key])

        elif role == Qt.DisplayRole:
            key = self.keys[index.row()]
            return QVariant(self.dicoM2V[key])

        elif role == Qt.CheckStateRole:
            key = self.keys[index.row()]
            value = self.dicoNature[key]
            if value == 'on':
                return QVariant(Qt.Checked)
            else:
                return QVariant(Qt.Unchecked)

        return QVariant()


    def flags(self, index):
        if not index.isValid():
            return Qt.ItemIsEnabled

        cpt = 0
        disable_row = 0
        for row in range(self.rowCount()):
            if self.dicoNature[self.keys[row]] == "on":
                disable_row = row
                cpt += 1

        if cpt == 1 and index.row() == disable_row:
            return Qt.ItemIsSelectable | Qt.ItemIsUserCheckable
        else:
            return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsUserCheckable


    def setData(self, index, value, role=None):
        if not index.isValid():
            return QVariant()

        if role == Qt.EditRole:
            pass

        elif role == Qt.DisplayRole:
            key = self.keys[index.row()]
            self.dicoNature[key] = str(value)

        elif role == Qt.CheckStateRole:
            state, ok = value.toInt()
            key = self.keys[index.row()]
            if state == Qt.Unchecked:
                self.dicoNature[key] = "off"
            else:
                self.dicoNature[key] = "on"

        id1 = self.index(0, 0)
        id2 = self.index(self.rowCount(), 0)
        self.emit(SIGNAL("dataChanged(const QModelIndex &, const QModelIndex &)"), id1, id2)
        return True


    def getChecked(self):
        s = []
        for k, v in self.dicoNature.items():
            if v == "on":
                s.append(k)
        return string.join(s, ";")

#-------------------------------------------------------------------------------
# FlagBox: new QComboBox to construct Delegate for the volume nature
#-------------------------------------------------------------------------------

class FlagBox(QComboBox):
    def __init__(self, parent):
        QComboBox.__init__(self, parent)

        opt = QStyleOptionComboBox()
        opt.initFrom(self)
        opt.editable = self.isEditable()
        if (self.style().styleHint(QStyle.SH_ComboBox_Popup, opt)):
            self.setItemDelegate(QItemDelegate(self))

        self.connect(self, SIGNAL("activated(int)"), self.slotActivated)


    @pyqtSignature("int")
    def slotActivated(self, index):
        value = self.itemData(index, Qt.CheckStateRole)
        state, ok = value.toInt()
        if state == Qt.Unchecked:
            s = Qt.Checked
        else:
            s = Qt.Unchecked
        self.setItemData(index, QVariant(s), Qt.CheckStateRole)


#    def hidePopup(self):
#        pass

#-------------------------------------------------------------------------------
# Delegate for the volume nature
#-------------------------------------------------------------------------------

class VolumeNatureDelegate(QItemDelegate):
    """
    Use of a combo box in the table.
    """
    def __init__(self, parent):
        super(VolumeNatureDelegate, self).__init__(parent)


    def createEditor(self, parent, option, index):
        editor = FlagBox(parent)
        editor.setEditable(False)
        #editor.setSizeAdjustPolicy(QComboBox.AdjustToContents)
        editor.setMinimumWidth(160)
        editor.installEventFilter(self)
        return editor


    def setEditorData(self, editor, index):
        data = index.model().getData(index.row(), index.column())
        dicoM2V = index.model().dicoM2V

        self.flagbox_model = StandardItemVolumeNature(dicoM2V, data)
        editor.setModel(self.flagbox_model)


    def setModelData(self, editor, model, index):
        value = self.flagbox_model.getChecked()
        model.setData(index, QVariant(value), Qt.DisplayRole)

#-------------------------------------------------------------------------------
# QLineEdit delegate for localization
#-------------------------------------------------------------------------------

class LocalizationSelectorDelegate(QItemDelegate):
    def __init__(self, parent, mdl):
        super(LocalizationSelectorDelegate, self).__init__(parent)
        self.parent = parent
        self.mdl = mdl


    def createEditor(self, parent, option, index):
        editor = QLineEdit(parent)
        #editor.installEventFilter(self)
        return editor


    def setEditorData(self, editor, index):
        self.value = index.model().data(index, Qt.DisplayRole).toString()
        editor.setText(self.value)


    def setModelData(self, editor, model, index):
        value = editor.text()

#        if str(value) == "" :
#            title = self.tr("Warning")
#            msg   = self.tr("Please give a localization")
#            QMessageBox.information(self.parent, title, msg)
#            return

        if value != self.value and str(value) in self.mdl.getLocalizationsZonesList():
            title = self.tr("Warning")
            msg   = self.tr("This localization is already used.\n"\
                            "Please give another one.")
            QMessageBox.information(self.parent, title, msg)
            return

        if str(value) != "" :
            model.setData(index, QVariant(value), Qt.DisplayRole)

#-------------------------------------------------------------------------------
# StandarItemModel class
#-------------------------------------------------------------------------------

class StandardItemModelLocalization(QStandardItemModel):
    def __init__(self, mdl, zoneType, dicoM2V):
        """
        """
        QStandardItemModel.__init__(self)
        self.headers = [self.tr("Label"),
                        self.tr("Zone"),
                        self.tr("Nature"),
                        self.tr("Selection criteria")]
        self.setColumnCount(len(self.headers))

        self.mdl      = mdl
        self.zoneType = zoneType
        self.dicoM2V  = dicoM2V

        self._data = []
        self._disable = []


    def data(self, index, role):
        if not index.isValid():
            return QVariant()

        if role == Qt.DisplayRole:
            row = index.row()
            col = index.column()

            if col in [0, 1, 3]:
                return QVariant(self._data[row][col])

            elif col == 2:
                if self.zoneType == "VolumicZone":
                    data = self._data[row][col]
                    item = string.join([self.dicoM2V[key] for key in self.dicoM2V.keys() if data[key] == "on"], "\n")
#                    item = ""
#                    for key in dico.keys():
#                        print key
#                        if dico[key] == "on":
#                            item += key + "\n"
                    return QVariant(item)

                elif self.zoneType == "BoundaryZone":
                    key = self._data[row][col]
                    return QVariant(self.dicoM2V[key])

        return QVariant()


    def flags(self, index):
        if not index.isValid():
            return Qt.ItemIsEnabled
        if (index.row(), index.column()) in self._disable:
            return Qt.ItemIsSelectable
        return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable


    def headerData(self, section, orientation, role):
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            return QVariant(self.headers[section])
        return QVariant()


    def setData(self, index, value, role):
        row = index.row()
        col = index.column()

        [old_label, old_code, old_nature, old_local] = self._data[row]

        old_zone = Zone(self.zoneType,
                        label        = old_label,
                        codeNumber   = old_code,
                        localization = old_local,
                        nature       = old_nature)

        new_label  = old_label
        new_code   = old_code
        new_nature = old_nature
        new_local  = old_local

        if col == 0:
            new_label = str(value.toString())
            self._data[row][col] = new_label

        elif col == 1:
            new_code, ok = value.toInt()
            self._data[row][col] = new_code

        elif col == 2:

            if self.zoneType == "VolumicZone":

                # We modify the dictionary here
                nature_list = string.split(str(value.toString()), ";")

                for key in self._data[row][col].keys():
                    if key in nature_list:
                        self._data[row][col][key] = "on"
                    else:
                        self._data[row][col][key] = "off"

                    new_nature = self._data[row][col].copy()

            elif self.zoneType == "BoundaryZone":

                new_nature = str(value.toString())
                self._data[row][col] = new_nature

        elif col == 3:
            new_local = str(value.toString())
            self._data[row][col] = new_local

        new_zone = Zone(self.zoneType,
                        label        = new_label,
                        codeNumber   = new_code,
                        localization = new_local,
                        nature       = new_nature)

        self.mdl.replaceZone(old_zone, new_zone)

        self.emit(SIGNAL("dataChanged(const QModelIndex &, const QModelIndex &)"), index, index)
        return True


    def addItem(self, zone=None):
        """
        Add an element in the table view.
        """
        if not zone:
            zone = self.mdl.addZone(Zone(self.zoneType))

        line = [zone.getLabel(),
                zone.getCodeNumber(),
                zone.getNature(),
                zone.getLocalization()]
        self._data.append(line)
        row = self.rowCount()
        self.setRowCount(row+1)

        # Warning: the Volume region 'all_cells' is mandatory, and can not be modified.
        if self.zoneType == "VolumicZone" and zone.getLabel() == "all_cells":
            for c in range(self.columnCount()):
                self._disable.append((row, c))


    def getItem(self, row):
        return self._data[row]


    def deleteItem(self, irow):
        del self._data[irow]
        nb_rows = self.rowCount()
        self.setRowCount(nb_rows-1)


    def getData(self, row, column):
        return self._data[row][column]

#-------------------------------------------------------------------------------
# Main class
#-------------------------------------------------------------------------------

class LocalizationView(QWidget, Ui_LocalizationForm):
    """
    Main class
    """
    def __init__(self, zoneType, parent, case, dicoM2V):
        """
        Constructor
        """
        QWidget.__init__(self, parent)

        Ui_LocalizationForm.__init__(self)
        self.setupUi(self)

        self.zoneType = zoneType
        self.mdl = LocalizationModel(zoneType, case)

        # Model for table View
        self.modelLocalization = StandardItemModelLocalization(self.mdl, zoneType, dicoM2V)
        self.tableView.setModel(self.modelLocalization)

        # Delegates
        delegateLabel = LabelDelegate(self.tableView, self.mdl)
        delegateCode  = CodeNumberDelegate(self.tableView, self.mdl)
        delegateLocal = LocalizationSelectorDelegate(self.tableView, self.mdl)

        self.tableView.setItemDelegateForColumn(0, delegateLabel)
        self.tableView.setItemDelegateForColumn(1, delegateCode)
        self.tableView.setItemDelegateForColumn(3, delegateLocal)

        # Populate QTableView model
        for zone in self.mdl.getZones():
            self.modelLocalization.addItem(zone)

        self.tableView.verticalHeader().setResizeMode(QHeaderView.ResizeToContents)
        self.tableView.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents)
        #col = self.tableView.model().rowCount() -1
        self.tableView.horizontalHeader().setResizeMode(3, QHeaderView.Stretch)

        # Connections
        self.connect(self.pushButtonNew,      SIGNAL("clicked()"), self.slotAddZone)
        self.connect(self.pushButtonDelete,   SIGNAL("clicked()"), self.slotDeleteZone)
        self.connect(self.toolButtonCreation, SIGNAL("clicked()"), self.slotAddFromPrePro)
        self.connect(self.modelLocalization,  SIGNAL("dataChanged(const QModelIndex &, const QModelIndex &)"), self.dataChanged)

        self.pushButtonSalome.hide()
        if case['salome']:
            self.pushButtonSalome.show()
            self.connect(self.pushButtonSalome, SIGNAL("clicked()"), self.slotAddFromSalome)

        # Context menu
        self.tableView.setContextMenuPolicy(Qt.CustomContextMenu)
        self.connect(self.tableView, SIGNAL("customContextMenuRequested(QPoint)"), self.slotContextMenu)


    @pyqtSignature("")
    def slotAddZone(self):
        """
        Insert a new item in the table view.
        """
        self.modelLocalization.addItem()


    @pyqtSignature("")
    def slotDeleteZone(self):
        """
        Private Slot.
        Warning: the Volume region 'all_cells' is mandatory, therefore it can not be deleted.
        """
        list = []
        for index in self.tableView.selectionModel().selectedRows():
            row = index.row()
            list.append(row)

        list.sort()
        list.reverse()

        for row in list:
            [label, codeNumber, nature, localization] = self.modelLocalization.getItem(row)
            if not (label == "all_cells" and self.zoneType == 'VolumicZone'):
                self.mdl.deleteZone(label)
                self.modelLocalization.deleteItem(row)


    @pyqtSignature("")
    def slotAddFromPrePro(self):
        """
        Research a Preprocessor listing to pick colors or groups of cells or faces.
        """
        if self.zoneType == 'VolumicZone':
            entity = 'cells'
        elif self.zoneType == 'BoundaryZone':
            entity = 'faces'

        file_name = preprocessorFile(self, self.case['resu_path'])

        if file_name:
            for loc in Informations(file_name, entity).getLocalizations():
                if loc not in self.mdl.getLocalizationsZonesList():
                    zone = Zone(self.zoneType, localization = loc)
                    self.mdl.addZone(zone)
                    self.modelLocalization.addItem(zone)


    @pyqtSignature("")
    def slotContextMenu(self):
        """
        Public slot

        Create the popup menu of the Browser
        """
        fileMenu = QMenu(self.tableView)

        actionMerge = QAction(self.tr("Merge selected zones"), self.tableView)
        self.connect(actionMerge, SIGNAL("triggered()"), self.slotMerge)
        fileMenu.addAction(actionMerge)

        if self.zoneType == 'BoundaryZone':
            fileMenu.addSeparator()

            self.actionInlet = QAction(self.tr("Select all inlets"), self.tableView)
            self.connect(self.actionInlet, SIGNAL("triggered()"), self.slotSelectBoudaries)
            fileMenu.addAction(self.actionInlet)

            self.actionOutlet = QAction(self.tr("Select all outlets"), self.tableView)
            self.connect(self.actionOutlet, SIGNAL("triggered()"), self.slotSelectBoudaries)
            fileMenu.addAction(self.actionOutlet)

            self.actionWall = QAction(self.tr("Select all walls"), self.tableView)
            self.connect(self.actionWall, SIGNAL("triggered()"), self.slotSelectBoudaries)
            fileMenu.addAction(self.actionWall)

            self.actionSymmetry = QAction(self.tr("Select all symmeties"), self.tableView)
            self.connect(self.actionSymmetry, SIGNAL("triggered()"), self.slotSelectBoudaries)
            fileMenu.addAction(self.actionSymmetry)

        fileMenu.popup(QCursor().pos())
        fileMenu.show()


    @pyqtSignature("")
    def slotMerge(self):
        """
        public slot
        """
        list = []
        for index in self.tableView.selectionModel().selectedRows():
            list.append(index.row())

        row = list.pop(0)
        [label, code, nature, new_localization] = self.modelLocalization.getItem(row)

        new_zone = Zone(self.zoneType,
                        label        = label,
                        codeNumber   = code,
                        localization = new_localization,
                        nature       = nature)

        for row in list:
            [label, code, nature, localization] = self.modelLocalization.getItem(row)
            if "all[]" not in string.split(new_localization, " "):
                new_localization += " or " + localization
            if localization == "all[]":
                new_localization = "all[]"

        new_zone.setLocalization(new_localization)
        self.slotDeleteZone()
        self.mdl.addZone(new_zone)
        self.modelLocalization.addItem(new_zone)


    @pyqtSignature("")
    def slotAddFromSalome(self):
        """
        When GUI is embeded in the Salome desktop. Add selection criteria from
        graphical selection in the VTK viwver, or in the ObjectBrowser.
        """
        if self.case['salome']:
            from SalomeHandler import BoundaryGroup, VolumeGroup

            log.debug("slotAddFromSalome: zoneType -> %s" % self.zoneType)
            if self.zoneType == 'VolumicZone':
                loc = VolumeGroup()
            elif self.zoneType == 'BoundaryZone':
                loc = BoundaryGroup()

            log.debug("slotAddFromSalome: selection criteria -> %s" % loc)
            if loc not in self.mdl.getLocalizationsZonesList():
                zone = Zone(self.zoneType, localization = loc)
                self.mdl.addZone(zone)
                self.modelLocalization.addItem(zone)


    @pyqtSignature("const QModelIndex &, const QModelIndex &")
    def dataChanged(self, topLeft, bottomRight):
        for row in range(topLeft.row(), bottomRight.row()+1):
            self.tableView.resizeRowToContents(row)
        for col in range(topLeft.column(), bottomRight.column()+1):
            self.tableView.resizeColumnToContents(col)


    def tr(self, text):
        """
        Translation.
        """
        return text

#-------------------------------------------------------------------------------
# Define Volumic regions class
#-------------------------------------------------------------------------------

class VolumeLocalizationView(LocalizationView):
    """
    Define volume regions class.
    """
    def __init__(self, parent=None, case=None):
        """
        Constructor.
        """
        self.case = case
        dicoM2V = Zone("VolumicZone").getModel2ViewDictionary()

        LocalizationView.__init__(self, "VolumicZone", parent, self.case, dicoM2V)

        title = self.tr("Definition of volume regions")
        self.groupBoxLocalization.setTitle(title)

        # Delegates
        delegateNature = VolumeNatureDelegate(self.tableView)
        self.tableView.setItemDelegateForColumn(2, delegateNature)

#-------------------------------------------------------------------------------
# Define Boundary regions class
#-------------------------------------------------------------------------------

class BoundaryLocalizationView(LocalizationView):
    """
    Define boundary regions class.
    """
    def __init__(self, parent=None, case=None):
        """
        Constructor.
        """
        self.case = case
        dicoM2V = Zone("BoundaryZone").getModel2ViewDictionary()

        LocalizationView.__init__(self, "BoundaryZone", parent, self.case, dicoM2V)

        title = self.tr("Definition of boundary regions")
        self.groupBoxLocalization.setTitle(title)

        # Delegates
        delegateNature = BoundaryNatureDelegate(self.tableView, dicoM2V)
        self.tableView.setItemDelegateForColumn(2, delegateNature)


    @pyqtSignature("")
    def slotSelectBoudaries(self):
        """
        Public slot.

        Warning: works only if the selection mode of the view is set to MultiSelection.
        """
        previous_selecion_mode = self.tableView.selectionMode()
        self.tableView.setSelectionMode(QAbstractItemView.MultiSelection)
        self.tableView.clearSelection()

        if self.sender() == self.actionInlet:
            select  = "inlet"
        elif self.sender() == self.actionOutlet:
            select  = "outlet"
        elif self.sender() == self.actionWall:
            select  = "wall"
        elif self.sender() == self.actionSymmetry:
            select  = "symmetry"

        for row in range(self.modelLocalization.rowCount()):
            [label, code, nature, localization] = self.modelLocalization.getItem(row)
            if nature == select:
                self.tableView.selectRow(row)

        self.tableView.setSelectionMode(previous_selecion_mode)

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