# -*- coding: utf-8 -*-

# Copyright 2012-2016 Mir Calculate. http://www.calculate-linux.org
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

from calculate.consolegui import qt
from calculate.core.client.function import create_obj, listToArrayArray, \
    listToArray
# import analysis
from more import show_msg, LabelWordWrap, MultipleChoice, SelectTable, \
    CentralCheckBox, ErrorLabel, icon_visible, FileOpenWgt, \
    ComboFileWgt, PasswordWidget, get_sid, ClientServiceThread, \
    ExpertWidget, ButtonsWidget, show_question, PlusRow, \
    ReadonlyCheckBox, get_view_params, ImageLabel, SelectList, \
    QComboWgt, _print, get_system_rgb, ParameterWindow, get_icon
from sudsds import WebFault
from calculate.lib.utils.text import _u8
from calculate.lib.utils.tools import Sizes
from SelectTable import SelectedTableWidget
from ReturnMessage import ReturnedMessage
import urllib2, time
from os import path

DEBUG_LEVEL = 0


def debug(level, *args):
    if level <= DEBUG_LEVEL:
        for s in args:
            print s,
        print


def get_size_by_type(sizetype, size):
    k = {'size-m': Sizes.M,
         'size-g': Sizes.G}.get(sizetype, 1)
    return str(int(size) / k)


class CallMethod(qt.QThread):
    '''For using page_offset and page_count'''
    collect_sig = qt.Signal()
    call_meth_sig = qt.Signal()

    def __init__(self, parent):
        qt.QThread.__init__(self, parent)

    def run(self):
        self.collect_sig.emit()
        time.sleep(0.1)
        self.call_meth_sig.emit()


class TableValue():
    values = []
    head = []
    body = []


class Table():
    label = str
    help = str
    tablevalue = TableValue


class RadioButton(qt.QRadioButton):
    def __init__(self, text=None, parent=None):
        super(qt.QRadioButton,self).__init__(text, parent)

    def set_data(self, data):
        self.data = data

    def get_data(self):
        return self.data


class MainFrame(qt.QWidget):
    def __init__(self, parent, ClientObj, view, method_name, \
                 error_output=True, skip_options=False):
        super(MainFrame, self).__init__(parent)
        self.ClientObj = ClientObj
        self._parent = parent
        self.view = view
        self.skip_options = skip_options
        self.method_name = method_name
        self.error_output = error_output
        self.group_name_label = None
        self.mutable = False
        self.has_errors = False
        # соответстия переменных между методами
        # текущим и тем, который вызывается при нажатии на кнопку
        # используется например при вызове groupdel из groupmod
        self.button_variable_mapper = {}
        self.error_mapper = {}
        self.button_action = None
        self.caller_method_name = None
        # структура отправляемая при вызове метода
        self.param_object = None

        self.buttons = []

        # for clear memory after closed this window
        self.setAttribute(qt.Qt.WA_DeleteOnClose)
        #        icon_visible(ClientObj.MainWidget, 'Methods', True)
        icon_visible(ClientObj.MainWidget, 'Back', True)

    def hasBrief(self):
        steps = self.ClientObj.param_objects[self.method_name]['steps_field']
        if hasattr(steps, 'label'):
            if steps.label:
                debug(11, "! method has brief")
                return True
        debug(11, "! method has not brief")
        return False

    def isMultistep(self):
        """
        Метод содержит несколько шагов
        :return:
        """
        steps = self.ClientObj.param_objects[self.method_name]['steps_field']
        if steps:
            return len(steps.tablevalue.head.string) > 1
        else:
            return False

    def isBrief(self, step=None):
        """
        Определяет является ли данный шаг отображением brief
        :param step:
        :return:
        """
        steps = self.ClientObj.param_objects[self.method_name]['steps_field']
        if hasattr(steps, 'label'):
            if steps.label:
                if step is None:
                    step = self.ClientObj.param_objects[
                        self.method_name]['step']
                    debug(11, "! use cached step %d" % step)
                else:
                    debug(11, "! use specified step %d" % step)
                if len(steps.tablevalue.head.string) == step:
                    debug(11, "! brief page")
                    return True
                else:
                    debug(11,
                          "! not brief page because step(%d) != len steps (%d)" %
                          (step, len(steps.tablevalue.head.string)))
            else:
                debug(11, "! not brief page because empty field label")
        else:
            debug(11, "! not brief page because has not steps field label")
        return False

    add_standart_button_signal = qt.Signal(object, int, int, bool, str)
    add_custom_button_signal = qt.Signal(object, int, int, bool, str)

    def add_standart_button(self, group, x, y, brief=False, next_label=""):
        self.add_standart_button_signal.emit(group, x, y, brief, next_label)

    def add_custom_button(self, group, x, y, brief=False, next_label=""):
        self.add_custom_button_signal.emit(group, x, y, brief, next_label)

    def init_params(self, params, method_name):
        if method_name not in params:
            debug(10, "CREATE NEW PARAM for method", method_name)
            params[method_name] = {}
            params[method_name]['step'] = 0
            params[method_name]['info'] = None
            params[method_name]['error'] = None
            params[method_name]['expert'] = False
            params[method_name]['expert_changed'] = set()
            params[method_name]['offset'] = 0
            params[method_name]['fields'] = {}
            params[method_name]['steps_field'] = None

    def get_param_object(self, method_name):
        self.init_params(self.ClientObj.param_objects, method_name)
        if not self.ClientObj.param_objects[method_name]['info']:
            debug(10, "CREATE NEW info obj for method", method_name)
            return create_obj(self.ClientObj.client, method_name)
        else:
            debug(10, "GET FROM CACHE info obj for method", method_name)
            debug(15, self.param_object)
            return self.ClientObj.param_objects[method_name]['info']

    def clear_cache_info(self, method_name):
        """
        Удалить кэшированные данные
        :param method_name:
        :return:
        """
        if method_name in self.ClientObj.param_objects:
            debug(10, "CLEAR CACHE INFO for ", method_name)
            self.ClientObj.param_objects[method_name]['info'] = None
            self.ClientObj.param_objects[method_name]['offset'] = 0
            self.ClientObj.param_objects[method_name]['expert'] = False
            self.ClientObj.param_objects[method_name]['expert_changed'] = set()

    def initUI(self, change_offset=False):
        #        _print (self.view)
        debug(10, "=" * 20)
        if self.skip_options:
            debug(10, "METHOD was call with --skip-options", self.method_name)
        if change_offset:
            debug(10, "CHANGE OFFSET for", self.method_name)
        else:
            debug(10, "SHOW NEW FRAME for", self.method_name)
        self.common_layout = qt.QVBoxLayout(self)
        self.common_layout.setAlignment(qt.Qt.AlignTop)
        self.common_layout.setContentsMargins(0, 0, 0, 0)
        self.common_layout.setSpacing(0)

        self.grid = qt.QGridLayout()
        self.grid.setSpacing(10)
        self.grid.setColumnStretch(0, 10)
        self.grid.setColumnStretch(1, 17)

        self.setObjectName('MainFrame')
        self.setStyleSheet("QWidget#MainFrame "
                           "{background-color: %s;}"%
                           get_system_rgb(self, ParameterWindow))
        #                  " QWidget { border: 1px solid blue;}")
        # x = 0 - space for image
        x = 1
        y = 0

        from ConnectionTabs import SelectedMethodWgt

        self.hidden_fields = {}

        self.tabWidget = SelectedMethodWgt
        # for advanced settings
        self.expert = False
        self.expert_list = []
        self.changed_expert_list = set()
        add_button_flag = False
        self.calling_error = False
        #        self.error_output = self.error_output

        self.view_dict = {}

        self.radio_dict = {}
        self.ButGrp_dict = {}
        self.label_dict = {}
        self.error_label_dict = {}

        self.table_dict = {}

        self.param_object = self.get_param_object(self.method_name)
        cached_info = self.ClientObj.param_objects[self.method_name]['info']
        cached = cached_info == self.param_object
        if cached:
            self.changed_expert_list = self.ClientObj.param_objects[
                self.method_name]['expert_changed']

        if self.ClientObj.param_objects[self.method_name]['error']:
            self.error_fields_name = map(lambda x: x.field,
                                         self.ClientObj.param_objects[
                                             self.method_name]['error'])
        else:
            self.error_fields_name = []

        list_param = dir(self.param_object)

        param_list = []
        for param in list_param:
            if not param.startswith('_'):
                param_list.append(param)

        if not self.view:
            debug(10, "CALL METHOD without view", self.method_name)
            self.call_server_method(collect_flag=False)
            return
        if hasattr(self.view, 'groups'):
            if not self.view.groups:
                debug(10, "CALL METHOD without groups", self.method_name)
                self.call_server_method(collect_flag=False)
                return

        for Group in self.view.groups.GroupField:
            if not Group.fields:
                continue
            for field in Group.fields.Field:
                if field.element == 'table' and field.type == 'steps':
                    debug(10, "GET STEP info", self.method_name)
                    if len(field.tablevalue.head.string) > 1:
                        debug(10, "MULTISTEP method", self.method_name)
                    else:
                        debug(10, "SINGLESTEP method", self.method_name)
                    self.add_element_steps(field)

        if self.isBrief():
            debug(10, "SHOW BRIEF for method", self.method_name)
            self.print_brief(self.view.groups.GroupField, x)
            return
        lastTable = None

        if self.skip_options:
            debug(10, "CALL METHOD", self.method_name, "by skip_options")
            self.call_server_method(collect_flag=False)
            return

        # метод содержащий page_offset, page_count
        pager = False
        # метод содержит сообщения об ошибке
        self.has_errors = False
        # метод модержащий настраиваемые элементы
        self.mutable = False
        self.buttons = []

        for Group in self.view.groups.GroupField:
            if self.isMultistep():
                groupname = Group.name
                fontsize = "16px"
            else:
                groupname = " "
                fontsize = "1px"
            self.group_name_label = LabelWordWrap(groupname, self)
            self.group_name_label.setAlignment(qt.Qt.AlignLeft)
            self.group_name_label.setStyleSheet("font-size: %s;"
                                                "font-weight: bold;"%fontsize);

            self.grid.addWidget(self.group_name_label, x, y, 1, 2)
            x += 1

            if not Group.fields:
                continue
            if cached:
                debug(10, "CACHE DEBUG", self.param_object)
            for field in Group.fields.Field:
                if lastTable:
                    self.resize_table(lastTable)
                    minimum = qt.QSizePolicy.Minimum
                    lastTable.setSizePolicy(minimum, minimum)
                lastTable = None
                # add element in frame
                if cached:
                    if hasattr(self.param_object, field.name):
                        if field.name == 'cl_page_offset':
                            field.value = str(self.ClientObj.param_objects[
                                                  self.method_name]['offset'])
                        value = getattr(self.param_object, field.name)
                        debug(5, "GET VALUE", value.__repr__(), "for field",
                              field.name, "FROM CACHE")
                        debug(5, "FIELD VALUE", field)
                        if "list" in field.type:
                            field.listvalue = value
                            if field.name in self.changed_expert_list:
                                field.default = False
                        else:
                            boolmapping = {True: 'on', False: 'off'}
                            field.value = boolmapping.get(value, value)
                            if field.name in self.changed_expert_list:
                                field.default = False
                if field.guitype == "hidden":
                    if not field.uncompatible:
                        self.hidden_fields[field.name] = field.value
                    continue
                if field.element == 'label':
                    self.add_element_label(field, x, y)
                    x += 1

                elif field.element in ['error', 'pwderror', 'commonerror']:
                    error_lbl = ErrorLabel(self, field.label)
                    error_lbl.setStyleSheet("QLabel {color: red;}")
                    error_lbl.show()
                    self.label_dict[field.name] = error_lbl
                    self.grid.addWidget(self.label_dict[field.name], x, y, 1, 2)
                    x += 1
                    self.has_errors = True

                    # add close button if one field
                    if len(self.view.groups.GroupField) == 1 \
                            and len(Group.fields.Field) == 1:
                        add_button_flag = True
                        self._parent.control_button.del_button()
                        self._parent.control_button.add_clear_cache_button()

                elif "button" in field.element:
                    add_button_flag = True
                    callback = self.button_callback(field, self.isBrief())
                    self.buttons.append((field, callback))
                    self.mutable = True

                elif (field.element == 'input' or
                              field.guitype == "readonly" or
                              field.element == 'readonly' or
                              field.type and "onepassword" in field.type):
                    if field.name in ['cl_page_count', 'cl_page_offset']:
                        pager = True
                        continue
                    if "size" in field.type:
                        field.value = get_size_by_type(field.type, field.value)
                    ro = (field.guitype == "readonly"
                          or field.element == "readonly")
                    self.add_element_input(field, x, y, readonly=ro)
                    x += 2
                    self.mutable = True

                elif field.element in ['check', 'check_tristate']:
                    self.add_element_check(field, x, y)
                    x += 2
                    self.mutable = True

                elif field.element == 'radio':
                    self.add_element_radio(field, x, y)
                    x += 2
                    self.mutable = True

                elif field.element == 'combo':
                    self.add_element_combo(field, x, y)
                    x += 2
                    self.mutable = True

                elif field.element == 'comboEdit':
                    self.add_element_comboEdit(field, x, y)
                    x += 2
                    self.mutable = True

                elif field.element in ['multichoice', 'multichoice_add']:
                    self.add_element_multichoice(field, x, y)
                    x += 2
                    self.mutable = True

                elif field.element in ['selecttable', \
                                       'selecttable_add']:
                    self.add_element_selecttable(field, x, y)
                    x += 4
                    self.mutable = True

                # add file open dialog
                elif field.element == 'openfile':
                    self.add_element_openfile(field, x, y)
                    x += 2
                    self.mutable = True

                # add file open dialog
                elif field.element == 'file':
                    self.add_element_file(field, x, y)
                    x += 2
                    self.mutable = True

                elif field.element == 'password':
                    self.add_element_password(field, x, y)
                    x += 2
                    self.mutable = True

                elif field.element == 'expert':
                    self.add_element_expert(field, x, y)
                    x += 1
                    self.mutable = True

                elif field.element == 'table' and field.type != 'steps':
                    self.add_element_table(field, x, y)
                    lastTable = self.view_dict[field.name]
                    x += 3
                    if field.type == 'writable':
                        x += 1
                    self.mutable = True

        if self.mutable:
            debug(10, "METHOD", self.method_name, "is mutable")
        else:
            debug(10, "METHOD", self.method_name, "is not mutable")
        if pager:
            debug(10, "METHOD", self.method_name, "has pagination")
        else:
            if change_offset:
                debug(10, "METHOD", self.method_name,
                      "has not pagination, but has change offset")
            else:
                debug(10, "METHOD", self.method_name,
                      "has not pagination")

        # кэшируем info параметры для настраиваемое пагинатор метода
        if self.mutable and pager:
            self.ClientObj.param_objects[
                self.method_name]['info'] = self.param_object

        if self.mutable and not change_offset:
            if not pager:
                debug(10, "SIMPLE METHOD", self.method_name)
            else:
                debug(10, "MUTABLE PAGER METHOD", self.method_name)

        if lastTable:
            lastTable.bFixedHeight = False
            self.resize_table(lastTable)
        # When used page_offset and page_count or not mutable elements
        if not self.mutable or change_offset:
            if pager:
                if self.group_name_label:
                    self.group_name_label.hide()
                debug(10, "CALL METHOD with change offset", self.method_name)
                self.call_server_method(change_offset=True, check_only=False)
                # ad-hoc для вывода brief у метода без параметров
            else:
                if self.hasBrief():
                    debug(10, "REFRESH VIEW for not mutable method",
                          self.method_name)
                    debug(1, "!!!HARDCODED refresh view to 1",
                          self.method_name)
                    self.refresh_view(1)
            if not self.has_errors:
                return

        # Show Control Buttons widget
        self._parent.methodname_wgt.show()
        self._parent.control_button.show()
        if self.ClientObj.method_names.has_key(self.method_name):
            view_method = self.ClientObj.method_names[self.method_name]
        else:
            view_method = self.method_name
        self._parent.methodname_wgt.setMethodName(view_method)

        # add image
        self.add_image()

        if add_button_flag:
            debug(10, "METHOD has custom buttons", self.method_name)
        else:
            debug(10, "METHOD has next button", self.method_name)

        if not add_button_flag:
            self.add_standart_button_signal.connect(
                self._parent.control_button.add_standart_button)
            debug(10, "ADD STANDARD BUTTONS (no brief) (Next name)",
                  self.method_name)
            self.add_standart_button(Group, x, y)
        else:
            self.add_custom_button_signal.connect(
                self._parent.control_button.add_custom_button)
            self.add_custom_button(Group, x, y)

        self.grid.setSizeConstraint(qt.QLayout.SetMaximumSize)
        # hide expert settings
        self.grid.setContentsMargins(28, 28, 28, 28)

        # If errors came in parameters
        if self.ClientObj.param_objects[self.method_name]['error']:
            debug(10, "METHOD has errors", self.method_name)
            debug(15, "ERRORS",
                  self.ClientObj.param_objects[self.method_name]['error'])
            self.highlight_errors()
        else:
            debug(10, "METHOD has not errors", self.method_name)
        self.error_output = True
        # create steps

        if (self.ClientObj.param_objects[self.method_name]['step'] > 0) and \
                self.ClientObj.param_objects[self.method_name]['steps_field']:
            debug(10, "CREATE STEP PANEL from cache", self.method_name)
            self.add_element_steps(
                self.ClientObj.param_objects[self.method_name]['steps_field'])
            self.ClientObj.MainWidget.left_frame.changed_step(
                self.ClientObj.param_objects[self.method_name]['step'])
        if not lastTable:
            self.grid.addItem(qt.QSpacerItem(
                0, 0, qt.QSizePolicy.Expanding,
                qt.QSizePolicy.Expanding),
                x + 1, y, 1, 2)

        self.common_layout.addLayout(self.grid)

        # add spacer
        # self.common_layout.addItem(qt.QSpacerItem( 0, 0, \
        #           qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding))
        self.update()
        self.ClientObj.app.processEvents()
        self.updateGeometry()

    # add 1 or 2 button to bottom
    def button_call_view(self, step):
        '''if call next view'''

        def wrapper():
            # break if error
            debug(10, "CLICK to Next/Prev button", self.method_name)
            if self.ClientObj.param_objects[self.method_name]['error']:
                if step != (-1):
                    self.button_enabled()
                    return

            if self.calling_error:
                self.button_enabled()
                return
            # call view
            self.diff_step = step
            self.ClientObj.param_objects[self.method_name]['step'] += step
            num = self.ClientObj.param_objects[self.method_name]['step']

            # Call server method
            if self.check_run_threads():
                return
            expert = None
            brief = False
            if self.isBrief():
                num = None
                brief = True
                expert = True
            else:
                debug(11, "!next step not brief")
            view_params = get_view_params(self.ClientObj.client,
                                          self.method_name + '_view',
                                          step=num,
                                          expert=expert, brief=brief)
            debug(10, "GET new view params for ", self.method_name,
                  "step=%s,expert=%s,brief=%s" % (num, expert, brief))
            self.button_call_thread = ClientServiceThread(
                self.ClientObj,
                self.method_name + '_view', int(self.ClientObj.sid),
                view_params, return_except=True)
            self.button_call_thread.signal.connect(self.button_call_view_after)
            self.button_call_thread.start()

        return wrapper

    def button_call_view_after(self, view):
        if type(view) == Exception:
            _print('handling button_call_view Exception...')
            self.ClientObj.param_objects[self.method_name]['step'] -= \
                self.diff_step
            return 1

        # change step in left frame
        try:
            self.ClientObj.MainWidget.left_frame.changed_step \
                (self.ClientObj.param_objects[self.method_name]['step'])
        except KeyError:
            pass
        except Exception:
            pass

        # display view in main frame
        self.ClientObj.MainWidget.main_frame_view(view,
                                                  self.method_name,
                                                  step_change=True)

    def call_server_method(self, collect_flag=True, change_offset=False,
                           check_only=True):
        call_method = CallMethod(self)
        if collect_flag:
            call_method.collect_sig.connect(self.collect_object())
        else:
            self.param_object = None
        call_method.call_meth_sig.connect(self.calling(
            check_only, change_offset=change_offset))
        call_method.start()

    def add_image(self):
        if not self.ClientObj.height_image:
            return
        field = self.ClientObj.param_objects[self.method_name]['steps_field']
        if not field:
            return
        step = self.ClientObj.param_objects[self.method_name]['step']
        image_name = None
        image_path = self.ClientObj.VarsApi.Get('cl_gui_image_path')
        image_dir = path.join(image_path, self.method_name)

        if hasattr(field.tablevalue.fields, 'string'):
            step_names = field.tablevalue.fields.string
            if len(step_names) > step:
                if not step_names[step]:
                    return
                for file_type in ['png', 'jpg']:
                    file_path = path.join(image_dir, '%s.%s' \
                                          % (step_names[step], file_type))
                    if path.isfile(file_path):
                        image_name = file_path
                        break

        if not image_name:
            return
        height_image = 192
        if hasattr(self.ClientObj, 'height_image'):
            if self.ClientObj.height_image:
                height_image = self.ClientObj.height_image
        self.image_lbl = ImageLabel(image_name, height_image, self)
        self.common_layout.addWidget(self.image_lbl)

    # methods add all elements
    def add_element_label(self, field, x, y):
        self.label_dict[field.name] = LabelWordWrap(field.label, self)
        if field.value:
            self.label_dict[field.name].setStyleSheet(field.value)
        self.grid.addWidget(self.label_dict[field.name], x, y, 1, 2)

    def add_element_input(self, field, x, y, hide=False, readonly=False):
        # add label
        self.label_dict[field.name] = LabelWordWrap(field.label, self)

        # set disable item if uncompatible
        if readonly or field.uncompatible:
            if field.uncompatible:
                self.label_dict[field.name].setToolTip(field.uncompatible)
                # self.label_dict[field.name].setDisabled(True)

        self.grid.addWidget(self.label_dict[field.name], x, y)

        self.view_dict[field.name] = qt.QLineEdit(self)
        if field.value:
            self.view_dict[field.name].setText(field.value)
        if field.type == 'int':
            self.rx = qt.QRegExp("^[\d]{1,50}$")
            self.validator = qt.QRegExpValidator(self.rx, self)
            self.view_dict[field.name].setValidator(self.validator)
        elif field.type == 'float':
            self.rx = qt.QRegExp("^[\d]{1,50}[.][\d]{1,50}$")
            self.validator = qt.QRegExpValidator(self.rx, self)
            self.view_dict[field.name].setValidator(self.validator)
        # password input
        elif "password" in field.type:
            self.view_dict[field.name].setEchoMode(qt.QLineEdit.Password)

        exp = qt.QSizePolicy.Expanding
        pref = qt.QSizePolicy.Preferred
        self.view_dict[field.name].setSizePolicy(exp, pref)
        # advanced settings (expert)
        if self.expert:
            if field.default and not field.name in self.error_fields_name:
                self.view_dict[field.name].setText('')
            if field.default:
                self.expert_list.append(field.name)
            else:
                self.changed_expert_list.add(field.name)
            self.view_dict[field.name].textChanged.connect( \
                self.changed_expert_input(field.name))
        if type(self.window()) == self.tabWidget:
            if not self.window().user_changed_flag:
                self.view_dict[field.name].textChanged.connect( \
                    self.window().user_changed)

        # set disable item if uncompatible
        if readonly or field.uncompatible:
            if field.uncompatible:
                self.view_dict[field.name].setToolTip(field.uncompatible)
            self.view_dict[field.name].setDisabled(True)

        self.grid.addWidget(self.view_dict[field.name], x, y + 1)

        self.error_label_dict[field.name] = ErrorLabel(self)
        self.grid.addWidget(self.error_label_dict[field.name], x + 1, y, 1, 2)

    def changed_expert_input(self, field_name):
        def wrapper(text):
            if text:
                self.remove_expert(field_name)
            else:
                self.add_expert(field_name)

        return wrapper

    def add_element_check(self, field, x, y, brief=False):
        self.error_label_dict[field.name] = ErrorLabel(self)

        self.label_dict[field.name] = qt.QLabel(field.label, self)
        # set disable item if uncompatible
        if field.uncompatible:
            self.label_dict[field.name].setToolTip(field.uncompatible)
            self.label_dict[field.name].setDisabled(True)
        if brief:
            self.brief_grid.addWidget(self.label_dict[field.name], x, y)
        else:
            self.grid.addWidget(self.label_dict[field.name], x, y)
        if brief:
            self.view_dict[field.name] = ReadonlyCheckBox(self)
        else:
            self.view_dict[field.name] = qt.QCheckBox(self)
            #self.view_dict[field.name].setStyleSheet(
            #    "QCheckBox:hover {background-color:#FFFFFF}")

        self.view_dict[field.name].setFocusPolicy(qt.Qt.NoFocus)

        if field.element.lower() == 'check_tristate' or self.expert:
            self.view_dict[field.name].setTristate()
            if field.value == 'on':
                self.view_dict[field.name].setCheckState(qt.Qt. \
                                                         Checked)
            elif field.value == 'off':
                self.view_dict[field.name].setCheckState(qt.Qt. \
                                                         Unchecked)
            elif field.value == 'auto':
                self.view_dict[field.name].setCheckState(qt.Qt.PartiallyChecked)
        else:
            if field.value == 'on':
                self.view_dict[field.name].setChecked(True)
        if self.expert:
            if field.default and not field.name in self.error_fields_name:
                self.view_dict[field.name].setCheckState(qt.Qt.PartiallyChecked)
            if field.default:
                self.expert_list.append(field.name)
            else:
                self.changed_expert_list.add(field.name)
            self.view_dict[field.name].clicked.connect( \
                self.changed_expert_check(field.name))
        if type(self.window()) == self.tabWidget:
            if not self.window().user_changed_flag:
                self.view_dict[field.name].clicked.connect( \
                    self.window().user_changed)
        if field.uncompatible:
            self.view_dict[field.name].setToolTip(field.uncompatible)
            self.view_dict[field.name].setDisabled(True)

        self.view_dict[field.name].setContentsMargins(0, 0, 0, 0)
        check_widget = qt.QLabel(self)
        exp = qt.QSizePolicy.Expanding
        pref = qt.QSizePolicy.Preferred
        check_widget.setSizePolicy(exp, pref)
        check_layout = qt.QHBoxLayout(check_widget)
        check_layout.setContentsMargins(0, 0, 0, 0)
        self.view_dict[field.name].setFixedWidth \
            (self.view_dict[field.name].sizeHint().width() + 4)
        self.view_dict[field.name].setFixedHeight \
            (self.view_dict[field.name].sizeHint().height() + 4)
        check_layout.addWidget(self.view_dict[field.name])
        check_widget.setFixedHeight \
            (self.view_dict[field.name].size().height())
        check_layout.setAlignment(qt.Qt.AlignLeft)

        if brief:
            self.brief_grid.addWidget(check_widget, x, y + 1)
        else:
            self.grid.addWidget(check_widget, x, y + 1)
        # if brief:
        #            self.brief_grid.addWidget(self.view_dict[field.name], x, y+1)
        #        else:
        #            self.grid.addWidget(self.view_dict[field.name], x, y+1)

        if not brief:
            x += 1
            self.grid.addWidget(self.error_label_dict[field.name], x, y, 1, 2)

    def changed_expert_check(self, field_name):
        def wrapper():
            if self.view_dict[field_name].checkState() == \
                    qt.Qt.PartiallyChecked:
                self.add_expert(field_name)
            else:
                self.remove_expert(field_name)

        return wrapper

    def add_element_radio(self, field, x, y):
        self.label_dict[field.name] = qt.QLabel(self)
        if field.uncompatible:
            self.label_dict[field.name].setToolTip(field.uncompatible)
            self.label_dict[field.name].setDisabled(True)
        self.grid.addWidget(self.label_dict[field.name], x, y)

        choice = field.choice[0]
        comments = None
        if field.comments:
            comments = field.comments[0]

        self.GroupBox = qt.QGroupBox(field.label, self)
        self.GroupBox.setStyleSheet( self.GroupBox.styleSheet() +
            "QGroupBox {"
            'padding-top: 24px; padding-bottom: 0px;'
            'padding-left: 5px; padding-right: 5px;'
            'border: 1px solid gray;'
            'border-left-color: qlineargradient( x1: 0, y1: 0, x2: 0, y2: 1,'
            'stop: 0 gray, stop: 1 transparent);'
            'border-top-color: qlineargradient( x1: 0, y1: 0, x2: 1, y2: 0,'
            'stop: 0 gray, stop: 1 transparent);'
            'border-right: 0px; border-bottom: 0px;'
            'border-top-left-radius: 2px;'

            'background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1,'
            'stop: 0 rgba(200, 200, 200,75), stop: 0.5 transparent,'
            'stop: 1 transparent);}'

            'QGroupBox::title {'
            'background-color: transparent;'
            'subcontrol-position: top center;'
            'margin-top: 6px;}')
        self.ButGrp_dict[field.name] = qt.QButtonGroup(self)
        layout = qt.QVBoxLayout(self.GroupBox)
        radiolist = []

        if field.value == None:
            field.value = ''

        for i in range(0, len(choice)):
            radio_but = RadioButton("", self)
            radio_but.setFocusPolicy(qt.Qt.NoFocus)
            if choice[i] == None:
                choice[i] = ''
            try:
                if comments:
                    if comments[i]:
                        radio_but.setText(comments[i])
                    else:
                        radio_but.setText(choice[i])
                else:
                    radio_but.setText(choice[i])
            except (IndexError, TypeError):
                radio_but.setText(choice[i])
            radio_but.set_data(choice[i])

            radiolist.append(radio_but)
            # set default values
            if field.value == choice[i]:
                radiolist[i].setChecked(True)
            self.ButGrp_dict[field.name].addButton(radiolist[i])
            layout.addWidget(radiolist[i])
            if self.expert:
                radiolist[i].clicked.connect(self.expert_remove \
                                                 (field.name))
            if type(self.window()) == self.tabWidget:
                if not self.window().user_changed_flag:
                    radiolist[i].clicked.connect(self.window().user_changed)

        layout.addStretch(1)
        #        self.GroupBox.setLayout(layout)

        self.view_dict[field.name] = self.GroupBox
        if self.expert:
            if field.default:
                self.expert_list.append(field.name)
            else:
                self.changed_expert_list.add(field.name)
        if field.uncompatible:
            self.view_dict[field.name].setToolTip(field.uncompatible)
            self.view_dict[field.name].setDisabled(True)
        self.view_dict[field.name].setFixedHeight \
            (self.view_dict[field.name].sizeHint().height())
        self.grid.addWidget(self.view_dict[field.name], x, y, 1, 2)

        # add error label
        self.error_label_dict[field.name] = ErrorLabel(self)
        self.grid.addWidget(self.error_label_dict[field.name], x + 1, y, 1, 2)

    def add_element_combo(self, field, x, y):
        self.ButGrp_dict[field.name] = False

        if field.comments:
            if hasattr(field.comments, 'string'):
                choice = field.comments.string
                values = field.choice.string
                if not field.value in values and field.value:
                    values.append(field.value)
                    choice.append(field.value)
        else:
            values = None
            if field.choice:
                choice = field.choice.string
            else:
                choice = []
            if not field.value in choice and field.value:
                choice.append(field.value)

        # add label
        self.label_dict[field.name] = qt.QLabel(field.label, self)
        if field.uncompatible:
            self.label_dict[field.name].setToolTip(field.uncompatible)
            self.label_dict[field.name].setDisabled(True)
        self.grid.addWidget(self.label_dict[field.name], x, y)
        self.ComboBox = QComboWgt(self)
        for i in range(len(choice)):
            if choice[i] == '---':
                self.ComboBox.setStyleSheet('QComboBox::separator ' \
                                            '{height : 2px; ' #background: gray;' \
                                            'margin-top: 0 2px 0 2px;}')
                self.ComboBox.insertSeparator(i)
                continue
            self.ComboBox.addItem(choice[i])
            if values:
                self.ComboBox.setItemData(i, values[i])
                if field.value == values[i]:
                    self.ComboBox.setCurrentIndex(i)
            else:
                if field.value == choice[i]:
                    self.ComboBox.setCurrentIndex(i)

        def combo_checked(self, name):
            def wrapper():
                self.ButGrp_dict[name] = True

            return wrapper

        self.ComboBox.currentIndexChanged.connect \
            (combo_checked(self, field.name))

        exp = qt.QSizePolicy.Expanding
        pref = qt.QSizePolicy.Preferred
        self.ComboBox.setSizePolicy(exp, pref)
        self.view_dict[field.name] = self.ComboBox
        if self.expert:
            self.view_dict[field.name].insertItem(0, '')
            self.view_dict[field.name].setItemData(0, None)
            if field.default and not field.name in self.error_fields_name:
                self.view_dict[field.name].setCurrentIndex(0)
            if field.default:
                self.expert_list.append(field.name)
            else:
                self.changed_expert_list.add(field.name)
            self.view_dict[field.name].currentIndexChanged.connect( \
                self.changed_expert_combo(field.name))
        if type(self.window()) == self.tabWidget:
            if not self.window().user_changed_flag:
                self.view_dict[field.name].currentIndexChanged.connect( \
                    self.window().user_changed)
        if field.uncompatible:
            self.view_dict[field.name].setToolTip(field.uncompatible)
            self.view_dict[field.name].setDisabled(True)
        self.grid.addWidget(self.view_dict[field.name], x, y + 1)

        self.error_label_dict[field.name] = ErrorLabel(self)
        self.grid.addWidget(self.error_label_dict[field.name], x + 1, y, 1, 2)

    def changed_expert_combo(self, field_name):
        def wrapper(ind):
            if ind:
                self.remove_expert(field_name)
            else:
                self.add_expert(field_name)

        return wrapper

    def add_element_comboEdit(self, field, x, y):
        self.ButGrp_dict[field.name] = True

        if field.comments:
            if hasattr(field.comments, 'string'):
                choice = field.comments.string
                if not field.choice:
                    values = None
                else:
                    values = field.choice.string
                if not field.value in values and field.value:
                    values.append(field.value)
                    choice.append(field.value)

        else:
            if not field.choice:
                choice = []
            else:
                choice = field.choice.string
            values = None
            if not field.value in choice and field.value:
                choice.append(field.value)

        # add label
        self.label_dict[field.name] = qt.QLabel(field.label, self)
        if field.uncompatible:
            self.label_dict[field.name].setToolTip(field.uncompatible)
            self.label_dict[field.name].setDisabled(True)
        self.grid.addWidget(self.label_dict[field.name], x, y)

        self.ComboBox = QComboWgt(self)
        self.ComboBox.setDuplicatesEnabled(False)
        self.ComboBox.setEditable(True)
        #le = qt.QLineEdit(self)
        #le.setStyleSheet('QLineEdit {background:white;margin: 1px;}')
        #self.ComboBox.setLineEdit(le)
        for i in range(0, len(choice)):
            if choice[i] == '---':
                self.ComboBox.setStyleSheet('QComboBox::separator ' \
                                            '{height : 2px; background: grey;' \
                                            'margin-top: 0 2px 0 2px;}')
                self.ComboBox.insertSeparator(i)
                continue
            self.ComboBox.addItem(choice[i])
            if values:
                self.ComboBox.setItemData(i, values[i])
                if field.value == values[i]:
                    self.ComboBox.setCurrentIndex(i)
            else:
                if field.value == choice[i]:
                    self.ComboBox.setCurrentIndex(i)

        exp = qt.QSizePolicy.Expanding
        pref = qt.QSizePolicy.Preferred
        self.ComboBox.setSizePolicy(exp, pref)
        self.view_dict[field.name] = self.ComboBox
        if self.expert:
            self.view_dict[field.name].insertItem(0, '')
            self.view_dict[field.name].setItemData(0, None)
            if field.default and not field.name in self.error_fields_name:
                self.view_dict[field.name].setCurrentIndex(0)
            if field.default:
                self.expert_list.append(field.name)
            else:
                self.changed_expert_list.add(field.name)
            self.view_dict[field.name].currentIndexChanged.connect(
                self.changed_expert_combo(field.name))
            self.view_dict[field.name].lineEdit().textChanged.connect(
                self.changed_expert_input(field.name))
        if type(self.window()) == self.tabWidget:
            if not self.window().user_changed_flag:
                self.view_dict[field.name].currentIndexChanged.connect(
                    self.window().user_changed)
                self.view_dict[field.name].lineEdit().textChanged.connect(
                    self.window().user_changed)
        if field.uncompatible:
            self.view_dict[field.name].setToolTip(field.uncompatible)
            self.view_dict[field.name].setDisabled(True)

        self.grid.addWidget(self.view_dict[field.name], x, y + 1)

        self.error_label_dict[field.name] = ErrorLabel(self)
        self.grid.addWidget(self.error_label_dict[field.name], x + 1, y, 1, 2)

    def add_element_multichoice(self, field, x, y):
        if field.element == 'multichoice_add':
            add_ability = True
        else:
            add_ability = False
        choice = field.choice.string if field.choice else []

        if field.listvalue:
            default = field.listvalue.string
        elif field.value:
            default = field.value.split(',')
        else:
            default = []
        comments = field.comments
        if self.expert and field.default and \
                not field.name in self.error_fields_name:
            default = []
        self.view_dict[field.name] = MultipleChoice(self, choice, default, \
                                                    comments, add_ability,
                                                    self.expert)
        # add label
        self.label_dict[field.name] = qt.QLabel(field.label, self)
        if self.expert:
            if field.default:
                self.expert_list.append(field.name)
            else:
                self.changed_expert_list.add(field.name)
            self.view_dict[field.name].Changed.connect( \
                self.expert_remove(field.name))
            self.view_dict[field.name].clear_button.clicked.connect( \
                self.expert_add(field.name))
        if type(self.window()) == self.tabWidget:
            if not self.window().user_changed_flag:
                self.view_dict[field.name].Changed.connect( \
                    self.window().user_changed)
                self.view_dict[field.name].clear_button.clicked.connect( \
                    self.window().user_changed)

        if field.uncompatible:
            self.label_dict[field.name].setToolTip(field.uncompatible)
            self.label_dict[field.name].setDisabled(True)
            self.view_dict[field.name].setToolTip(field.uncompatible)
            self.view_dict[field.name].setDisabled(True)
        self.grid.addWidget(self.label_dict[field.name], x, y)
        self.grid.addWidget(self.view_dict[field.name], x, y + 1)

        self.error_label_dict[field.name] = ErrorLabel(self)
        self.grid.addWidget(self.error_label_dict[field.name], x + 1, y, 1, 2)

    def add_element_selecttable(self, field, x, y):
        if field.element == 'selecttable':
            add_ability = False
        else:
            add_ability = True
        choice = field.choice.string if field.choice else []

        if field.listvalue:
            default = field.listvalue.string
        elif field.value:
            default = field.value.split(',')
        else:
            default = []
        comments = field.comments
        #        if field.name in self.error_fields_name:
        #            field.default = False
        self.view_dict[field.name] = SelectList(self, field.label, choice, \
                                                default, comments, add_ability,
                                                self.expert, field.default)

        if self.expert:
            if field.default:
                self.expert_list.append(field.name)
            else:
                self.changed_expert_list.add(field.name)
            self.view_dict[field.name].Changed.connect( \
                self.expert_remove(field.name))
            self.view_dict[field.name].recover_but.clicked.connect( \
                self.expert_add(field.name))
        if type(self.window()) == self.tabWidget:
            if not self.window().user_changed_flag:
                self.view_dict[field.name].Changed.connect( \
                    self.window().user_changed)
                self.view_dict[field.name].recover_but.clicked.connect( \
                    self.window().user_changed)
                #            self.view_dict[field.name].Changed.connect( \
                #                                       self.selectList_changed(False, field))
                #            self.view_dict[field.name].recover_but.clicked.connect( \
                #                                       self.selectList_changed(True, field))

        if field.uncompatible:
            self.view_dict[field.name].setToolTip(field.uncompatible)
            self.view_dict[field.name].setDisabled(True)
        self.grid.addWidget(self.view_dict[field.name], x, y, 2, 2)
        x += 2

        self.error_label_dict[field.name] = ErrorLabel(self)
        self.grid.addWidget(self.error_label_dict[field.name], x, y, 1, 2)

    #    def selectList_changed(self, default, field):
    #        def wrapper():
    #            print 'field.default =', field.default
    #            print 'default =', default
    #            field.default = default
    #        return wrapper

    def add_element_openfile(self, field, x, y):
        self.label_dict[field.name] = qt.QLabel(field.label, self)
        self.grid.addWidget(self.label_dict[field.name], x, y)

        # field.type in ['file','files','dir']
        value = field.value
        if self.expert and field.default and \
                not field.name in self.error_fields_name:
            value = ''
        self.view_dict[field.name] = FileOpenWgt(self, field.type, \
                                                 field.label, value)
        if self.expert:
            if field.default:
                self.expert_list.append(field.name)
            else:
                self.changed_expert_list.add(field.name)
            self.view_dict[field.name].lineEdit.textChanged.connect( \
                self.changed_expert_input(field.name))
        if type(self.window()) == self.tabWidget:
            if not self.window().user_changed_flag:
                self.view_dict[field.name].lineEdit.textChanged.connect( \
                    self.window().user_changed)

        if field.uncompatible:
            self.label_dict[field.name].setToolTip(field.uncompatible)
            self.label_dict[field.name].setDisabled(True)
            self.view_dict[field.name].setToolTip(field.uncompatible)
            self.view_dict[field.name].setDisabled(True)

        self.grid.addWidget(self.view_dict[field.name], x, y + 1)

        self.error_label_dict[field.name] = ErrorLabel(self)
        self.grid.addWidget(self.error_label_dict[field.name], x + 1, y, 1, 2)

    def add_element_file(self, field, x, y):
        self.label_dict[field.name] = qt.QLabel(field.label, self)
        self.grid.addWidget(self.label_dict[field.name], x, y)

        try:
            if field.choice:
                choice = field.choice[0]
            else:
                choice = None
        except IndexError:
            choice = None

        # field.type in ['file','files','dir']
        self.view_dict[field.name] = ComboFileWgt(self, field.type, choice, \
                                                  field.label, field.value,
                                                  field.comments)
        if self.expert:
            if field.default and not field.name in self.error_fields_name:
                self.view_dict[field.name].setCurrentIndex(0)
            if field.default:
                self.expert_list.append(field.name)
            else:
                self.changed_expert_list.add(field.name)
            self.view_dict[field.name].ComboBox.currentIndexChanged.connect( \
                self.expert_remove(field.name))
            self.view_dict[field.name].lineEdit.textChanged.connect( \
                self.expert_remove(field.name))
        if type(self.window()) == self.tabWidget:
            if not self.window().user_changed_flag:
                self.view_dict[field.name].ComboBox.currentIndexChanged. \
                    connect(self.window().user_changed)
                self.view_dict[field.name].lineEdit.textChanged.connect( \
                    self.window().user_changed)

        if field.uncompatible:
            self.label_dict[field.name].setToolTip(field.uncompatible)
            self.label_dict[field.name].setDisabled(True)
            self.view_dict[field.name].setToolTip(field.uncompatible)
            self.view_dict[field.name].setDisabled(True)

        self.grid.addWidget(self.view_dict[field.name], x, y + 1)

        self.error_label_dict[field.name] = ErrorLabel(self)
        self.grid.addWidget(self.error_label_dict[field.name], x + 1, y, 1, 2)

    def add_element_password(self, field, x, y):
        # add label
        self.label_dict[field.name] = LabelWordWrap(field.label, self)
        self.grid.addWidget(self.label_dict[field.name], x, y)

        self.view_dict[field.name] = PasswordWidget(self, field.value,
                                                    field.label)

        # advanced settings (expert)
        if self.expert:
            if field.default:
                self.expert_list.append(field.name)
            else:
                self.changed_expert_list.add(field.name)
            self.view_dict[field.name].textChanged.connect( \
                self.expert_remove(field.name))
        if type(self.window()) == self.tabWidget:
            if not self.window().user_changed_flag:
                self.view_dict[field.name].textChanged.connect( \
                    self.window().user_changed)

        if field.uncompatible:
            self.label_dict[field.name].setToolTip(field.uncompatible)
            self.label_dict[field.name].setDisabled(True)
            self.view_dict[field.name].setToolTip(field.uncompatible)
            self.view_dict[field.name].setDisabled(True)
        self.grid.addWidget(self.view_dict[field.name], x, y + 1)

        self.error_label_dict[field.name] = ErrorLabel(self)
        self.grid.addWidget(self.error_label_dict[field.name], x + 1, y, 1, 2)

    def add_element_expert(self, field, x, y):
        self.expert = True
        # add label
        if field.label:
            self.view_dict[field.name] = ExpertWidget(field.label, self)
        else:
            self.view_dict[field.name] = ExpertWidget \
                (_('Advanced settings'), self)
        self.view_dict[field.name].setFlat(True)
        self.grid.addWidget(self.view_dict[field.name], x, y, 1, 2)

        if field.value == 'open':
            self.view_dict[field.name].set_open()
        else:
            self.view_dict[field.name].set_close()

        x += 1
        self.view_dict[field.name].clicked.connect(self.set_error_output)
        self.view_dict[field.name].clicked.connect(self.set_disabled_expert \
                                                       (field.name))
        if field.value != 'open':
            debug(10, "Close expert")
            self.view_dict[field.name].clicked.connect(self.collect_object())
            self.view_dict[field.name].clicked.connect(self.calling(True))
            self.view_dict[field.name].clicked.connect(
                self.expert_clicked(field))
        else:
            debug(10, "Open expert")
            self.expert_signal.connect(self.collect_object())
            self.expert_signal.connect(self.calling(True))
            self.expert_signal.connect(self.expert_clicked(field))
            self.view_dict[field.name].clicked.connect(self.expert_question(
                field))
            self.view_dict[field.name].clicked.connect(
                self.set_disabled_expert(field.name, False))

    expert_signal = qt.Signal()

    def set_disabled_expert(self, field_name, disabled=True):
        def wrapper():
            self.view_dict[field_name].setDisabled(disabled)
            self.ClientObj.app.processEvents()

        return wrapper

    def set_error_output(self):
        self.error_output = False

    def expert_clicked(self, cur_field):
        def wrapper():
            if self.calling_error:
                self.button_enabled()
                return 1
            if cur_field.value == 'open':
                expert = False
                debug(3, "@DROP changed expert for ", self.method_name)
                self.ClientObj.param_objects[
                    self.method_name]['expert_changed'] = set()
                self.changed_expert_list = set()
            else:
                expert = True
            # Save expert option
            debug(3, "@SAVE expert option", expert)
            self.ClientObj.param_objects[self.method_name]['expert'] = expert
            num = self.ClientObj.param_objects[self.method_name]['step']

            # Call server method
            if self.check_run_threads():
                if hasattr(self, 'button_call_thread'):
                    if self.button_call_thread.isRunning():
                        self.button_call_thread.wait()
                else:
                    return
            brief = self.isBrief()
            if brief:
                num = None
                expert = True
            view_params = get_view_params(self.ClientObj.client,
                                          self.method_name + '_view', step=num,
                                          expert=expert, brief=brief)
            self.button_call_thread = ClientServiceThread(
                self.ClientObj, self.method_name + '_view',
                int(self.ClientObj.sid), view_params)
            self.button_call_thread.signal.connect(self.expert_clicked_after)
            self.button_call_thread.start()

        return wrapper

    def expert_clicked_after(self, view, method_name=None):
        if not method_name:
            method_name = self.method_name
        # display view in main frame
        if method_name in self.ClientObj.method_names:
            view_method = self._parent.ClientObj.method_names[method_name]
        else:
            view_method = method_name
        self.ClientObj._parent.setWindowTitle(view_method + ' - '
                                              + self.ClientObj.Name)
        self.ClientObj.MainWidget.main_frame_view(view, method_name,
                                                  step_change=True,
                                                  error_output=False)

    def expert_question(self, field):
        def wrapper():
            reply = None
            if self.changed_expert_list:
                text = _('Clean the expert parameters?')
                reply = show_question(self, text, cursor_pos=True,
                                      title=_('Calculate Console'))

            if reply == qt.QMessageBox.Yes or not self.changed_expert_list:
                for field_name in self.changed_expert_list:
                    if field_name not in self.expert_list:
                        self.expert_list.append(field_name)
                self.expert_signal.emit()

        return wrapper

    def button_callback(self, field, brief=False):
        # добавляем соответстивем переменных разным методам

        self.button_variable_mapper[field.name] = {}
        self.error_mapper[field.name] = {}
        if field.listvalue:
            for k, v in (x.split('=') for x in field.listvalue.string
                         if "->" not in x):
                self.button_variable_mapper[field.name][k] = v
                self.error_mapper[field.name][v] = k
                debug(10, "ADD mapping %s -> %s" % (v, k), "for method",
                      field.name)
            for k, v in (x.split('->') for x in field.listvalue.string
                         if "->" in x):
                self.error_mapper[field.name][k] = v
                debug(10, "ADD error mapping %s -> %s" % (v, k), "for method",
                      field.name)

        def button_clicked(method_name, var_mapper, error_mapper, brief):
            def error_display_main(from_left_frame=False):
                errors = self.ClientObj.param_objects[method_name]['error']
                debug(10, "REV MAPPER for ", method_name, error_mapper)
                for error in errors:
                    error.field = error_mapper.get(error.field, error.field)

                self.error_display(
                    errors=errors,
                    fields=self.ClientObj.param_objects[
                        self.method_name]['fields'],
                    step=self.ClientObj.param_objects[
                        self.method_name]['step'],
                    from_left_frame=from_left_frame)

            def wrapper():
                param_object = self.get_param_object(method_name)
                if not brief:
                    self.collect_object(var_mapper, param_object, method_name)()

                for k, v in ((k, v) for k, v in var_mapper.items() if
                             k.endswith("!")):
                    debug(10, "FORCE SET for", k[:-1], v.__repr__())
                    mapper = {"on": True, "off": False, "None": None}
                    param_object[k[:-1]] = mapper.get(v, v)

                self.calling(CheckOnly=False, change_offset=False,
                             from_left_frame=False,
                             method_name=method_name,
                             param_object=param_object,
                             display_error_callback=error_display_main)()

            return wrapper

        def change_method(method_name):
            def after_call(view):
                debug(10, "CHANGE METHOD", self._parent.ClientObj.method_names)
                # view_method = self._parent.ClientObj.method_names[
                #    method_name]
                # self._parent.ClientObj._parent.setWindowTitle(
                #    view_method + ' - ' + self.ClientObj.Name)
                self.ClientObj.MainWidget.main_frame_view(view,
                                                          method_name)

            def wrapper():
                if hasattr(self, 'get_Frame_thread'):
                    if self.get_Frame_thread.isRunning():
                        return 1
                sid = int(self.ClientObj.sid)
                view_params = get_view_params(self.ClientObj.client,
                                              method_name + '_view')
                self.get_Frame_thread = ClientServiceThread(
                    self.ClientObj, method_name + '_view', sid, view_params)
                self.get_Frame_thread.signal.connect(after_call)
                self.get_Frame_thread.start()

            return wrapper

        if field.element == 'button_view':
            return change_method(field.value)
        else:
            return button_clicked(
                field.value, self.button_variable_mapper[field.name],
                self.error_mapper[field.name], brief)

    def button_clicked_after(self, result, method_name):
        meth_result = []
        error = False
        if self.calling_error:
            self.button_enabled()
            return
        for res in result[0]:
            meth_result.append(ReturnedMessage(res.type, res.field, \
                                               res.message, res.expert))
            if res.type in ['error', 'pwderror', 'commonerror']:
                error = True
                self.ClientObj.param_objects[self.method_name] \
                    ['error'] = meth_result

        if error:
            self.error_display()
            if self.caller_method_name:
                self.method_name = self.caller_method_name
            # self.ClientObj.param_objects[self.method_name]['error'] = None
            return 0

        if meth_result[0].type == "pid":
            # create process dict
            self.ClientObj.process_dict[meth_result[0].message] = {}
            self.ClientObj.process_dict[meth_result[0].message] \
                ['result'] = meth_result[0]
            self.ClientObj.process_dict[meth_result[0].message] \
                ['name'] = method_name
            self.ClientObj.process_dict[meth_result[0].message] \
                ['layout'] = qt.QVBoxLayout()
            self.ClientObj.process_dict[meth_result[0].message] \
                ['layout'].setAlignment(qt.Qt.AlignTop)

            # set new window title
            if self.ClientObj.method_names.has_key(method_name):
                view_method = self._parent.ClientObj.method_names[method_name]
            else:
                view_method = method_name
            self.ClientObj._parent.setWindowTitle(view_method + ' - ' \
                                                  + self.ClientObj.Name)

            # Call method display process results
            self.ClientObj.MainWidget.main_frame_res(method_name, \
                                                     meth_result[0])
        else:
            if self.check_run_threads():
                return
            view_params = get_view_params(self.ClientObj.client, \
                                          method_name + '_view', step=None, \
                                          expert=None)
            self.button_call_thread = ClientServiceThread(self.ClientObj, \
                                                          method_name + '_view', \
                                                          int(
                                                              self.ClientObj.sid),
                                                          view_params, \
                                                          through_object=method_name)
            self.button_call_thread.signal.connect(self.expert_clicked_after)
            self.button_call_thread.start()

    def add_element_steps(self, field):
        if not field.tablevalue.head:
            return

        steps = field.tablevalue.head.string
        icons = []
        if hasattr(field.listvalue, 'string'):
            icons = field.listvalue.string
        val_steps = field.tablevalue.body.stringArray

        self.ClientObj.param_objects[self.method_name]['steps_field'] = field

        # add all field name in param_object for highlight error
        for num_step in range(len(val_steps)):
            self.ClientObj.param_objects[self.method_name] \
                ['fields'][num_step] = []
            self.ClientObj.param_objects[self.method_name] \
                ['fields'][num_step] = val_steps[num_step].string

        steps_val = steps
        if field.label:
            steps_val = steps + [field.label]
        # create links on steps for each steps
        self.ClientObj.MainWidget.left_frame.create_steps \
            (self.method_name, steps_val)
        self.ClientObj.MainWidget.left_frame.create_steps \
            (self.method_name, steps_val, icons)
        if len(steps) < 2:
            self.ClientObj.MainWidget.left_frame.hide()

            ############# Begin add Table

    def add_element_table(self, field, x, y, brief=False, gb_layout=None):
        self.table_dict[field.name] = field
        table = field.tablevalue

        lenColumn = 0
        lenBody = 0
        if table.body and hasattr(table.body, 'stringArray'):
            if len(table.body.stringArray):
                if len(table.body.stringArray[0].string):
                    lenColumn = len(table.head.string)
                    lenBody = len(table.body.stringArray)

        disabled_table = True if field.uncompatible or brief else False
        self.table_widget = SelectedTableWidget \
            (lenBody, len(table.head.string) + 1, self, disabled_table, \
             brief=brief)

        if None in table.head.string:
            for num_item in range(len(table.head.string)):
                if table.head.string[num_item] == None:
                    table.head.string[num_item] = ' '

        self.table_widget.setHorizontalHeaderLabels([''] + table.head.string)

        self.table_combo_list = []
        self.table_comboEdit_list = []
        self.table_check_list = []
        self.table_multi_list = []

        self.table_widget.setContentsMargins(0, 0, 0, 0)

        # add all items in table
        if lenBody:
            self.add_table_items(table, field, lenColumn, self.table_widget, \
                                 brief)

        minimum = qt.QSizePolicy.Minimum
        expanding = qt.QSizePolicy.Expanding
        self.table_widget.setSizePolicy(minimum, expanding)

        self.view_dict[field.name] = self.table_widget
        self.label_dict[field.name] = LabelWordWrap(field.label, self)
        self.label_dict[field.name].setContentsMargins(0, 0, 0, 0)
        self.table_dict[field.name] = field

        self.table_widget.itemClicked.connect(self.expert_remove(field.name))
        self.table_widget.itemClicked.connect(self.row_changed( \
            self.view_dict[field.name], self.table_dict[field.name]))
        if type(self.window()) == self.tabWidget:
            if not self.window().user_changed_flag:
                self.table_widget.itemClicked.connect \
                    (self.window().user_changed)

        if self.expert:
            if field.default:
                self.expert_list.append(field.name)
            else:
                self.changed_expert_list.add(field.name)

        if brief:
            gb_layout.addWidget(self.label_dict[field.name], x, y, 1, 2)
        else:
            self.grid.addWidget(self.label_dict[field.name], x, y, 1, 2)
        x += 1

        widget_for_grid = qt.QWidget(self)
        if brief:
            widget_for_grid.setStyleSheet("background: transparent;")
        wfg_layout = qt.QVBoxLayout(widget_for_grid)
        wfg_layout.setSpacing(10)
        wfg_layout.setAlignment(qt.Qt.AlignTop)
        wfg_layout.setContentsMargins(0, 0, 0, 0)
        # add 2 button if field type = writable
        if field.type == 'writable':
            hh = self.view_dict[field.name].horizontalHeader()
            hh.setSectionsClickable(False)

            unit_widget = qt.QWidget(self)
            unit_widget.setFixedHeight(32)
            wfg_layout.setAlignment(qt.Qt.AlignTop)
            unit_layout = qt.QHBoxLayout(unit_widget)
            unit_layout.setContentsMargins(0, 0, 0, 0)
            unit_layout.setSpacing(3)

            plus_but = qt.QPushButton(self)
            icon = get_icon('list-add')
            if not icon.isNull():
                plus_but.setIcon(icon)
            else:
                plus_but.setText('+')

            plus_but.setToolTip(_('Add a row'))
            plus_but.setFixedSize(30, 30)

            self.view_dict[field.name].minus_but = qt.QPushButton(self)
            icon = get_icon('list-remove')
            if not icon.isNull():
                self.view_dict[field.name].minus_but.setIcon(icon)
            else:
                self.view_dict[field.name].minus_but.setText('-')
            self.view_dict[field.name].minus_but.setToolTip \
                (_('Delete the selected rows'))
            self.view_dict[field.name].minus_but.setFixedSize(30, 30)
            self.view_dict[field.name].minus_but.setDisabled(True)

            refresh_but = qt.QPushButton(self)
            icon = get_icon('edit-undo')
            if not icon.isNull():
                refresh_but.setIcon(icon)
            else:
                refresh_but.setText('R')

            refresh_but.setToolTip(_('Recover the table'))
            refresh_but.setFixedSize(30, 30)

            clear_but = qt.QPushButton(self)
            icon = get_icon('edit-clear')
            if not icon.isNull():
                clear_but.setIcon(icon)
            else:
                clear_but.setText('C')

            clear_but.setToolTip(_('Clear the table'))
            clear_but.setFixedSize(30, 30)

            plus_but.clicked.connect(self.plus_row(self.view_dict[field.name], \
                                                   self.table_dict[field.name]))
            self.view_dict[field.name].minus_but.clicked.connect \
                (self.minus_row(self.view_dict[field.name]))
            refresh_but.clicked.connect(self.refresh_table(table, field, \
                                                           lenColumn,
                                                           self.view_dict[
                                                               field.name]))
            clear_but.clicked.connect(self.minus_row \
                                          (self.view_dict[field.name], True))

            unit_layout.addWidget(plus_but)
            unit_layout.addWidget(self.view_dict[field.name].minus_but)
            unit_layout.addWidget(refresh_but)
            unit_layout.addWidget(clear_but)

            unit_layout.setAlignment(qt.Qt.AlignLeft)
            wfg_layout.addWidget(unit_widget)
            #            self.grid.addWidget(unit_widget, x, y)
            #            x +=1

            self.add_select_check(self.view_dict[field.name])

            if self.expert:
                plus_but.clicked.connect(self.expert_remove(field.name))
                self.view_dict[field.name].minus_but.clicked.connect( \
                    self.expert_remove(field.name))
                refresh_but.clicked.connect(self.expert_add(field.name))
                clear_but.clicked.connect(self.expert_add(field.name))

                if field.default:
                    clear_but.clicked.emit()
        else:
            self.view_dict[field.name].hideColumn(0)

        # No Selection
        self.view_dict[field.name].setSelectionMode(
            qt.QAbstractItemView.NoSelection)

        if field.uncompatible:
            self.label_dict[field.name].setToolTip(field.uncompatible)
            self.label_dict[field.name].setDisabled(True)
            self.view_dict[field.name].setToolTip(field.uncompatible)
            #            self.view_dict[field.name].setDisabled(True)
            self.view_dict[field.name].viewport().setDisabled(True)
            if field.type == 'writable':
                unit_widget.setToolTip(field.uncompatible)
                unit_widget.setDisabled(True)

        self.table_widget.setColor()

        wfg_layout.addWidget(self.view_dict[field.name])
        if brief:
            gb_layout.addWidget(widget_for_grid, x, y, 1, 2)
        else:
            self.grid.addWidget(widget_for_grid, x, y, 1, 2)

        if not brief:
            self.error_label_dict[field.name] = ErrorLabel(self)
            self.grid.addWidget(self.error_label_dict[field.name], x + 1, y, 1,
                                2)

    def add_table_items(self, table, field, lenColumn, table_widget, \
                        brief=False):
        for column in range(lenColumn):
            # for readonly view
            col = column + 1
            if not table.values:
                table_widget.setEditTriggers \
                    (qt.QAbstractItemView.NoEditTriggers)
                for row in range(len(table.body.stringArray)):
                    tablewidgetitem = qt.QTableWidgetItem \
                        (table.body.stringArray[row].string[column])
                    table_widget.setItem(row, col, tablewidgetitem)

            elif column > (len(table.values.ChoiceValue) - 1):
                for row in range(len(table.body.stringArray)):
                    tablewidgetitem = qt.QTableWidgetItem \
                        (table.body.stringArray[row].string[column])
                    table_widget.setItem(row, col, tablewidgetitem)

                    table_widget.item(row, col).setFlags(
                        qt.Qt.ItemIsEditable)
                    brush = qt.QBrush(
                        self.palette().color(qt.QPalette.Text))
                    table_widget.item(row, col).setForeground(brush)

            elif brief and table.values.ChoiceValue[column].typefield in \
                    ['combo', 'comboEdit', 'multichoice', \
                     'multichoice_add', 'input', 'password']:
                table_widget.setEditTriggers \
                    (qt.QAbstractItemView.NoEditTriggers)
                for row in range(len(table.body.stringArray)):
                    if table.values.ChoiceValue[column].typefield == \
                            'password' and table.body.stringArray \
                            [row].string[column]:
                        tablewidgetitem = qt.QTableWidgetItem('***')
                    else:
                        tablewidgetitem = qt.QTableWidgetItem \
                            (table.body.stringArray[row].string[column])
                    table_widget.setItem(row, col, tablewidgetitem)

            # if not readonly
            elif table.values.ChoiceValue[column].typefield in \
                    ['combo', 'comboEdit']:
                ChoiceValue = table.values.ChoiceValue[column]
                for row in range(len(table.body.stringArray)):
                    val = table.body.stringArray[row].string[column]
                    if val and ChoiceValue.comments and \
                            hasattr(ChoiceValue.comments, 'string'):
                        if val in ChoiceValue.values.string:
                            ind = ChoiceValue.values.string.index \
                                (table.body.stringArray[row].string[column])
                            if ind < len(ChoiceValue.comments.string):
                                val = ChoiceValue.comments.string[ind]

                    tablewidgetitem = qt.QTableWidgetItem(val)
                    table_widget.setItem(row, col, tablewidgetitem)

                    table_widget.item(row, col).setFlags \
                        (qt.Qt.ItemIsEditable)
                    brush = qt.QBrush(
                        self.palette().color(qt.QPalette.Text))
                    table_widget.item(row, col).setForeground(brush)

            elif table.values.ChoiceValue[column].typefield in \
                    ['multichoice', 'multichoice_add']:
                ChoiceValue = table.values.ChoiceValue[column]
                for row in range(len(table.body.stringArray)):
                    choice = ChoiceValue.values.string
                    if table.body.stringArray[row].string[column]:
                        default = table.body.stringArray[row].string[column]. \
                            split(',')
                    else:
                        default = []

                    if ChoiceValue.comments and hasattr \
                                (ChoiceValue.comments, 'string'):
                        Comments = ChoiceValue.comments.string
                    else:
                        Comments = []

                    default = default if default else []
                    value_dict = {}
                    for i in range(len(choice)):
                        if len(Comments) > i:
                            value_dict[choice[i]] = Comments[i]
                        else:
                            value_dict[choice[i]] = choice[i]
                    val = ','.join(map(lambda x: value_dict[x], default))

                    tablewidgetitem = qt.QTableWidgetItem(val)
                    table_widget.setItem(row, col, tablewidgetitem)

                    table_widget.item(row, col).setFlags \
                        (qt.Qt.ItemIsEditable)
                    brush = qt.QBrush(
                        self.palette().color(qt.QPalette.Text))
                    table_widget.item(row, col).setForeground(brush)

            elif table.values.ChoiceValue[column].typefield in \
                    ['check', 'check_tristate']:
                for row in range(len(table.body.stringArray)):
                    val = table.body.stringArray[row].string[column]
                    data = val
                    if val == 'on':
                        val = _('Yes')
                    elif val == 'off':
                        val = _('No')
                    elif not val and not brief:
                        data = ''
                        val = _('Auto')
                    elif not val and brief:
                        data = ''
                        val = ''
                    tablewidgetitem = qt.QTableWidgetItem(val)
                    tablewidgetitem.setData(1, data)
                    table_widget.setItem(row, col, tablewidgetitem)

                    table_widget.item(row, col).setFlags(
                        qt.Qt.ItemIsEditable)
                    brush = qt.QBrush(
                        self.palette().color(qt.QPalette.Text))
                    table_widget.item(row, col).setForeground(brush)

            elif table.values.ChoiceValue[column].typefield in \
                    ['readonly', 'text', 'input']:
                for row in range(len(table.body.stringArray)):
                    val = table.body.stringArray[row].string[column]

                    tablewidgetitem = qt.QTableWidgetItem(val)
                    table_widget.setItem(row, col, tablewidgetitem)

                    table_widget.item(row, col).setFlags(
                        qt.Qt.ItemIsEditable)
                    brush = qt.QBrush(
                        self.palette().color(qt.QPalette.Text))
                    table_widget.item(row, col).setForeground(brush)

            elif table.values.ChoiceValue[column].typefield == 'password':
                for row in range(len(table.body.stringArray)):
                    passwd = table.body.stringArray[row].string[column]
                    val = '***' if passwd else ''
                    tablewidgetitem = qt.QTableWidgetItem(val)
                    tablewidgetitem.setData(1, passwd)
                    table_widget.setItem(row, col, tablewidgetitem)

                    table_widget.item(row, col).setFlags(
                        qt.Qt.ItemIsEditable)
                    brush = qt.QBrush(
                        self.palette().color(qt.QPalette.Text))
                    table_widget.item(row, col).setForeground(brush)

    def add_select_check(self, table):
        # add row Selected
        def selected_row(self, ch, row, minus_but):
            def wrapper():
                minus_but.setDisabled(True)
                for i in range(row):
                    if table.cellWidget(i, 0).isChecked():
                        minus_but.setEnabled(True)
                        return 0

            return wrapper

        for row in range(table.rowCount()):
            if not table.cellWidget(row, 0):
                tablewidgetitem = qt.QTableWidgetItem()
                table.setItem(row, 0, tablewidgetitem)
                #                table.item(row, 0).setFlags(qt.Qt.ItemIsEditable)

                ch = CentralCheckBox(self.table_widget, False, ind_col=True)
                ch.setToolTip(_('Delete the row'))
                ch.pCheckB.clicked.connect(selected_row \
                                               (self, ch, table.rowCount(), \
                                                table.minus_but))
                table.setCellWidget(row, 0, ch)
        table.setColumnWidth(0, 40)

    def plus_row(self, table, field):
        def wrapper():
            self.PlusWgt = PlusRow(self, table, field)
            self.PlusWgt.setWindowModality(qt.Qt.WindowModal)
            self.PlusWgt.show()

        return wrapper

    def row_changed(self, table, field):
        def wrapper(item):
            if not item.column():
                return
            self.PlusWgt = PlusRow(self, table, field, True, item.row())
            self.PlusWgt.setWindowModality(qt.Qt.WindowModal)
            self.PlusWgt.show()

        return wrapper

    def minus_row(self, table, clear=False):
        def wrapper():
            if clear:
                top = 0
                bottom = table.rowCount()
                for i in range(top, bottom + 1):
                    table.model().removeRow(top)
            else:
                for j in range(table.rowCount()):
                    for i in range(table.rowCount()):
                        if table.cellWidget(i, 0).isChecked():
                            table.model().removeRow(i)
                            break
            table.minus_but.setDisabled(True)
            # Resize table
            self.resize_table(table)

        return wrapper

    def refresh_table(self, table, field, lenColumn, table_widget):
        def wrapper():
            self.minus_row(table_widget, True)
            lenBody = 0
            if len(field.tablevalue.body.stringArray):
                if len(field.tablevalue.body.stringArray[0].string):
                    lenBody = len(field.tablevalue.body.stringArray)
            table_widget.setRowCount(lenBody)
            # Resize table
            self.resize_table(table_widget)

            self.add_table_items(table, field, lenColumn, table_widget)
            if field.type == 'writable':
                self.add_select_check(table_widget)
            table_widget.setColor()

        return wrapper

    def resize_table(self, table):
        # Resize table
        if table.bFixedHeight:
            h = table.horizontalHeader().height() + \
                2 * table.frameWidth()
            h += table.horizontalScrollBar().height()
            for row_in_table in range(table.rowCount()):
                h += table.rowHeight(row_in_table)
            table.setFixedHeight(h)
        table.horizontalHeader().resizeSections(
            qt.QHeaderView.ResizeToContents)
        table.setColumnWidth(0, 40)

    ############# End add Table
    def print_brief(self, GroupField, x):
        debug(10, "SHOWING BRIEF FOR", self.method_name)
        y = 0

        group_name = self.ClientObj.param_objects[self.method_name] \
            ['steps_field'].label
        if not group_name:
            group_name = ''
        next_button_text = self.ClientObj.param_objects \
            [self.method_name]['steps_field'].value

        if not next_button_text:
            next_button_text = 'Ok'
        _help = self.ClientObj.param_objects \
            [self.method_name]['steps_field'].help

        if self.isMultistep():
            group_name_label = LabelWordWrap(group_name, self)
            group_name_label.setStyleSheet("font-size: 16px;" # color: #000;"
                                           "font: bold;")
            self.grid.addWidget(group_name_label, x, y, 1, 2)
            x += 1

        if _help:
            help_lbl = LabelWordWrap(_help, self)
            self.grid.addWidget(help_lbl, x, y, 1, 2)
            x += 1

        # brief_sa = qt.QScrollArea(self)
        brief_widget = qt.QWidget(self)

        self.brief_grid = qt.QGridLayout(brief_widget)
        #        self.brief_grid.setContentsMargins(10,10,10,10)
        self.brief_grid.setContentsMargins(0, 0, 0, 0)
        self.brief_grid.setSpacing(10)
        self.brief_grid.setColumnStretch(0, 10)
        self.brief_grid.setColumnStretch(1, 17)

        for i, Group in enumerate(GroupField):
            x = self.print_brief_group(Group, x)

        brief_widget.setFixedHeight(brief_widget.sizeHint().height())
        brief_widget.setObjectName('Brief_w')
        brief_widget.setStyleSheet("#Brief_w "
                                   "{background-color: transparent;}")

        exp = qt.QSizePolicy.Expanding

        expert_brief = ExpertWidget(_('View options'), self)
        expert_brief.setFlat(True)
        expert_brief.set_close()
        expert_brief.clicked.connect(self.show_brief_widget \
                                         (brief_widget, expert_brief))
        self.grid.addWidget(expert_brief, x, y, 1, 2)
        x += 1
        brief_widget.hide()

        self.grid.addWidget(brief_widget, x, y, 1, 2)
        x += 1

        debug(10, "ADD STANDARD BUTTONS (brief) (%s)" % next_button_text,
              self.method_name)
        self.add_standart_button_signal.connect(
            self._parent.control_button.add_standart_button)
        self.add_standart_button(GroupField[-1], x, y, True, \
                                      next_button_text)

        # add image
        self.add_image()

        # add spacer
        self.spacer_item = qt.QSpacerItem(0, 0, exp, exp)
        self.grid.addItem(self.spacer_item)
        self.grid.setSizeConstraint(qt.QLayout.SetMaximumSize)

        self.common_layout.addLayout(self.grid)
        # Show Control Buttons widget
        self._parent.methodname_wgt.show()
        self._parent.control_button.show()
        self._parent.methodname_wgt.setMethodName \
            (self.ClientObj.method_names[self.method_name])

        #        self.grid.setContentsMargins(10,10,10,0)
        self.grid.setContentsMargins(24, 28, 24, 20)
        self.update()
        self.ClientObj.app.processEvents()
        self.updateGeometry()

    def show_brief_widget(self, brief_widget, expert_brief):
        def wrapper():
            if brief_widget.isVisible():
                brief_widget.hide()
                self.grid.addItem(self.spacer_item)
                expert_brief.set_close()
            else:
                brief_widget.show()
                self.grid.removeItem(self.spacer_item)
                expert_brief.set_open()

        return wrapper

    def print_brief_group(self, Group, grid_x):
        if Group.name:
            if not Group.fields:
                return grid_x
            # self.group_name_label = LabelWordWrap(Group.name, self)
            GroupBox = qt.QGroupBox(Group.name)
            GroupBox.setObjectName('GroupBoxBrief')
            #            brief_widget.setStyleSheet("#Brief_w "
            GroupBox.setStyleSheet(
                GroupBox.styleSheet() +
                "#GroupBoxBrief {"
                'padding-top: 24px; padding-bottom: 0px;'
                'padding-left: 5px; padding-right: 5px;'
                'border: 1px solid gray;'
                'border-left-color: qlineargradient( x1: 0, y1: 0, x2: 0, y2: 1,'
                'stop: 0 gray, stop: 1 transparent);'
                'border-top-color: qlineargradient( x1: 0, y1: 0, x2: 1, y2: 0,'
                'stop: 0 gray, stop: 1 transparent);'
                'border-right: 0px; border-bottom: 0px;'
                'border-top-left-radius: 2px;'

                'background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1,'
                'stop: 0 rgba(200, 200, 200,75), stop: 0.5 transparent,'
                'stop: 1 transparent);}'

                'QGroupBox::title {'
                'background-color: transparent;'
                'subcontrol-position: top center;'
                'margin-top: 6px;}')
        else:
            return grid_x
        gb_layout = qt.QGridLayout(GroupBox)

        gb_layout.setContentsMargins(10, 10, 10, 10)
        gb_layout.setSpacing(4)
        gb_layout.setColumnStretch(0, 10)
        gb_layout.setColumnStretch(1, 17)

        x = 0
        y = 0
        uncompatible_count = 0
        Fields = Group.fields.Field
        for field in Fields:
            if field.uncompatible:
                uncompatible_count += 1
                continue
            if field.element in ['input', 'openfile']:
                value = field.value if field.value else ''
                label_name = LabelWordWrap(field.label, self)
                label_value = LabelWordWrap(value, self)
                gb_layout.addWidget(label_name, x, y)
                gb_layout.addWidget(label_value, x, y + 1)
                x += 1

            elif field.element in ['combo', 'comboEdit', 'radio', 'file']:
                if hasattr(field.comments, 'string') and field.value in \
                        field.choice.string:
                    value = filter(None, \
                                   map(lambda x: field.comments.string[x] \
                                       if len(field.comments.string) > x \
                                       else field.choice.string[x],
                                       map(lambda x: field.choice.string.index(
                                           x), \
                                           [field.value])))
                    value = ', '.join(value)
                else:
                    value = field.value if field.value else ''
                label_name = LabelWordWrap(field.label, self)
                label_value = LabelWordWrap(value, self)
                gb_layout.addWidget(label_name, x, y)
                gb_layout.addWidget(label_value, x, y + 1)
                x += 1

            elif field.element in ['multichoice', 'multichoice_add', \
                                   'selecttable', 'selecttable_add']:
                if hasattr(field.comments, 'string') and \
                        hasattr(field.listvalue, 'string'):
                    value = map(lambda x: field.comments.string[x] \
                        if len(field.comments.string) > x \
                        else field.choice.string[x],
                                map(lambda x: field.choice.string.index(x), \
                                    field.listvalue.string))
                    value = ', '.join(value)
                elif hasattr(field.listvalue, 'string'):
                    value = ', '.join(field.listvalue.string)
                else:
                    value = field.value if field.value else ''
                label_name = LabelWordWrap(field.label, self)
                label_value = LabelWordWrap(value, self)
                gb_layout.addWidget(label_name, x, y)
                gb_layout.addWidget(label_value, x, y + 1)
                x += 1

            elif field.element == 'label':
                label = LabelWordWrap(field.label, self)
                gb_layout.addWidget(label, x, y, 1, 2)
                x += 1

            elif field.element in ['error', 'pwderror', 'commonerror']:
                error_lbl = ErrorLabel(self, field.label)
                error_lbl.setStyleSheet("QLabel {color: red;}")
                error_lbl.show()
                gb_layout.addWidget(error_lbl, x, y, 1, 2)
                x += 1

            elif field.element in ['check', 'check_tristate']:
                label_name = LabelWordWrap(field.label, self)
                gb_layout.addWidget(label_name, x, y)

                if field.value == 'on':
                    value = _('Yes')
                elif field.value == 'off':
                    value = _('No')
                elif field.value == 'auto':
                    value = _('Auto')

                label_value = LabelWordWrap(value, self)
                gb_layout.addWidget(label_value, x, y + 1)

                #                self.add_element_check (field, x, y, brief = True)
                #                self.view_dict[field.name].disabled = True
                #                self.view_dict.pop(field.name)
                x += 2

            elif field.element == 'table' and field.type != 'steps':
                field.type = None
                field.default = False
                self.add_element_table(field, x, y, brief=True,
                                       gb_layout=gb_layout)
                self.resize_table(self.view_dict[field.name])
                x += 3
                if field.type == 'writable':
                    x += 1
                self.view_dict.pop(field.name)

            elif field.element == 'table' and field.type == 'steps':
                self.add_element_steps(field)

            else:
                uncompatible_count += 1
        minimum = qt.QSizePolicy.Minimum
        maximum = qt.QSizePolicy.Maximum
        GroupBox.setSizePolicy(minimum, maximum)

        if uncompatible_count != len(Fields):
            self.brief_grid.addWidget(GroupBox, grid_x, 0, 1, 2)
            grid_x += 1
        # self.group_name_label.hide()
        return grid_x

    def expert_remove(self, field_name):
        def wrapper():
            if field_name in self.expert_list:
                self.expert_list.remove(field_name)

            self.changed_expert_list.add(field_name)

        return wrapper

    def remove_expert(self, field_name):
        if field_name in self.expert_list:
            self.expert_list.remove(field_name)

        self.changed_expert_list.add(field_name)

    def expert_add(self, field_name):
        def wrapper():
            if not field_name in self.expert_list:
                self.expert_list.append(field_name)

            if field_name in self.changed_expert_list:
                self.changed_expert_list.remove(field_name)

        return wrapper

    def add_expert(self, field_name):
        if field_name not in self.expert_list:
            self.expert_list.append(field_name)

        if field_name in self.changed_expert_list:
            self.changed_expert_list.remove(field_name)

    def collect_object(self, var_mapper=None, param_object=None,
                       method_name=None):
        """
        Заполнить info объект (используется как параметры для вызова
        серверного метода) из элеменов управления.
        Для заполнения может использоваться таблица соответствия.
        Она может использоваться например при вызове метода
        groupdel из методта groupmod: groupmod содержит поле grouplabel, в
        то время как это поле соответствует полю groupname из groupdel.
        :param var_mapper: таблица соответствия параметров
        :param param_object: заполняемый info объект (если None используется
                             self.param_object)
        :return:
        """
        var_mapper = var_mapper or {}
        if param_object is None:
            param_object = self.param_object
        if method_name is None:
            method_name = self.method_name

        def wrapper():
            debug(3, "@@@@EXPERT LIST CHANGED", self.changed_expert_list)
            debug(3, "@@@@EXPERT LIST ", self.expert_list)
            self.ClientObj.param_objects[method_name]['expert_changed'] = \
                self.changed_expert_list

            debug(10, "COLLECT OBJECT for method", method_name, "by view form",
                  self.method_name)
            # store params name if list for each step
            if hasattr(param_object, 'cl_page_count'):
                debug(10, "SET page count for info", method_name,
                      self.ClientObj.count_row_res_table)
                param_object.cl_page_count = self.ClientObj.count_row_res_table
            if hasattr(param_object, 'cl_page_offset'):
                offset = self.ClientObj.param_objects[method_name]['offset']
                debug(10, "SET offset for info", method_name,
                      offset)
                param_object.cl_page_offset = str(offset)

            for hidden_field in self.hidden_fields:
                paramname = hidden_field
                if var_mapper:
                    paramname = var_mapper.get(paramname, paramname)
                if paramname in param_object:
                    debug(10, "SET", self.hidden_fields[hidden_field],
                          "from hidden field", hidden_field, "for", paramname)
                    param_object[paramname] = self.hidden_fields[hidden_field]
                else:
                    debug(10, "SKIP SET", self.hidden_fields[hidden_field],
                          "from hidden field", hidden_field, "for", paramname)

            for Group in self.view.groups.GroupField:
                if not Group.fields:
                    continue
                for field in Group.fields.Field:
                    paramname = field.name
                    if var_mapper:
                        paramname = var_mapper.get(paramname, paramname)
                    if not hasattr(param_object, paramname):
                        continue

                    if field.name not in self.view_dict:
                        continue

                    # значение неиспользуемой переменной для этого метода
                    # может быть использовано как значение для переменной
                    # в другом методе, иначе значение пропускаем
                    if field.uncompatible and method_name == self.method_name:
                        debug(10, "SKIP uncompatible", field.name)
                        continue

                    if type(self.view_dict[field.name]) == qt.QGroupBox:
                        if self.ButGrp_dict[field.name].checkedButton():
                            param_object[paramname] = (
                                self.ButGrp_dict[field.name].checkedButton(
                                ).get_data())
                        elif field.value:
                            param_object[paramname] = field.value
                        else:
                            param_object[paramname] = ''
                        if field.element == 'radio' and field.type == 'bool':
                            if param_object[paramname].lower() == 'on':
                                param_object[paramname] = True
                            else:
                                param_object[paramname] = False

                    elif type(self.view_dict[field.name]) == qt.QCheckBox:
                        if self.view_dict[field.name].isTristate():
                            if self.view_dict[field.name].checkState() \
                                    == qt.Qt.PartiallyChecked:
                                param_object[paramname] = None
                            elif self.view_dict[field.name].checkState() \
                                    == qt.Qt.Checked:
                                param_object[paramname] = True
                            else:
                                param_object[paramname] = False

                        else:
                            param_object[paramname] = \
                                self.view_dict[field.name].isChecked()

                    elif type(self.view_dict[field.name]) in \
                            [qt.QComboBox, QComboWgt]:
                        ind = self.view_dict[field.name].currentIndex()
                        text = self.view_dict[field.name].currentText()
                        choice = []
                        if field.comments:
                            if hasattr(field.comments, 'string'):
                                choice = field.comments.string
                                if not field.choice:
                                    values = None
                                else:
                                    values = field.choice.string
                                if not field.value in values and field.value:
                                    values.append(field.value)
                                    choice.append(field.value)
                        else:
                            if not field.choice:
                                choice = []
                            else:
                                choice = field.choice.string
                            if not field.value not in choice and field.value:
                                choice.append(field.value)
                        if text in choice and \
                                self.view_dict[field.name].itemData(ind):
                            param_object[paramname] = \
                                self.view_dict[field.name].itemData(ind)
                        else:
                            param_object[paramname] = \
                                self.view_dict[field.name].currentText()

                    elif type(self.view_dict[field.name]) == qt.QLineEdit:
                        val = self.view_dict[field.name].text() or ''
                        param_object[paramname] = self.fix_string_value(val)

                    elif type(self.view_dict[field.name]) in [MultipleChoice,
                                                              SelectTable,
                                                              SelectList]:
                        list_result = self.view_dict[field.name].values()
                        if not list_result:
                            list_result = [None]
                        param_object[paramname] = listToArray(
                            self.ClientObj.client, list_result)

                    elif type(self.view_dict[field.name]) == FileOpenWgt:
                        val = self.view_dict[field.name].data or ''
                        param_object[paramname] = val

                    elif type(self.view_dict[field.name]) == ComboFileWgt:
                        val = self.view_dict[field.name].text() or ''
                        param_object[paramname] = self.fix_string_value(val)

                    elif type(self.view_dict[field.name]) == PasswordWidget:
                        val = self.view_dict[field.name].get_text()
                        debug(15, "Password value", val.__repr__())
                        param_object[paramname] = self.fix_string_value(val)
                    elif type(self.view_dict[field.name]) == \
                            SelectedTableWidget:
                        self.collect_table(field, paramname, param_object)

                    if self.expert:
                        if hasattr(self.param_object, 'Default'):
                            param_object.Default = listToArray(
                                self.ClientObj.client, self.expert_list)
                        for fields in self.expert_list:
                            param_object[fields] = None

        return wrapper

    def fix_string_value(self, value):
        try:
            return (str(value.encode('utf-8')).decode('utf-8'))
        except (UnicodeDecodeError, UnicodeEncodeError):
            return str(value)

    def collect_table(self, field, paramname, param_object):
        column = self.view_dict[field.name].columnCount()
        row = self.view_dict[field.name].rowCount()
        table = field.tablevalue
        table_result = []
        for i in range(row):
            temp = []
            for j in range(1, column):
                # not adding if readonly
                if j > (len(field.tablevalue.values.ChoiceValue)):
                    continue

                col = j - 1
                text = self.view_dict[field.name].item(i, j).text()
                ChoiceValue = table.values.ChoiceValue[col]
                typefield = ChoiceValue.typefield

                if typefield in ['combo', 'comboEdit']:
                    if ChoiceValue.comments and \
                            hasattr(ChoiceValue.comments, 'string'):
                        choice = ChoiceValue.comments.string
                        values = ChoiceValue.values.string

                        if text in choice:
                            ind = choice.index(text)
                            text = values[ind]
                        text = text if text else ''

                elif typefield in ['multichoice', 'multichoice_add']:
                    val_list = text.split(',')
                    res_list = []
                    val_list = [_u8(x) for x in val_list]
                    if ChoiceValue.comments and \
                            hasattr(ChoiceValue.comments, 'string'):
                        comment_list = ChoiceValue.comments.string
                        comment_list = [_u8(x) for x in comment_list]
                        values_list = ChoiceValue.values.string
                        for val in val_list:
                            if val in comment_list:
                                ind = comment_list.index(val)
                                res_list.append(values_list[ind])
                            else:
                                res_list.append(val)
                    else:
                        res_list = val_list

                    if not res_list:
                        text = ''
                    else:
                        text = ','.join(res_list)

                elif typefield in ['check', 'check_tristate']:
                    text = self.view_dict[field.name].item(i, j).data(1)
                    if text.lower() == 'auto' or not text:
                        text = ''
                    elif text.lower() == 'yes':
                        text = 'on'
                    elif text.lower() == 'no':
                        text = 'off'

                elif typefield in ['password']:
                    text = self.view_dict[field.name].item(i, j).data(1)
                    text = text if text else ''

                elif typefield in ['readonly']:
                    continue

                elif self.view_dict[field.name].item(i, j):
                    text = self.view_dict[field.name].item(i, j).text()

                temp.append(text)
            table_result.append(temp)
        if not any(table_result):
            table_result = [[None]]
        param_object[paramname] = listToArrayArray(self.ClientObj.client,
                                                   table_result)

    def calling(self, CheckOnly=False, change_offset=False,
                from_left_frame=False, method_name=None,
                param_object=None, display_error_callback=None):
        """
        Вызов серверного метода на выполнение
        :param CheckOnly: только проверить параметры
        :param change_offset: вызов метода производится для отображения новых
                              результатов, не меняя парамеры
        :param from_left_frame:
        :return:
        """
        # call method on server
        if method_name is None:
            method_name = self.method_name
        if param_object is None:
            param_object = self.param_object
        if display_error_callback is None:
            display_error_callback = self.error_display_self

        def wrapper():
            debug(10, "CALL SERVER METHOD", method_name,
                  "for check" if CheckOnly else "",
                  "for change_offset" if change_offset else "")
            if hasattr(param_object, 'CheckOnly'):
                param_object['CheckOnly'] = CheckOnly

            self.ClientObj.param_objects[method_name]['error'] = None

            self.ClientObj.sid = get_sid(self.ClientObj.client)
            try:
                sid = int(self.ClientObj.sid)
                # call method on server
                try:
                    if param_object:
                        debug(15, "CALL PARAM", param_object)
                        meth_result_temp = self.ClientObj.client.service[0] \
                            [method_name](sid, param_object)
                    else:
                        meth_result_temp = self.ClientObj.client.service[0] \
                            [method_name](sid)
                except Exception as e:
                    self.calling_error = True
                    msg = e.message
                    if not msg:
                        msg = e.reason
                    if type(e.message) == tuple:
                        msg = ' '.join(map(lambda x: str(x), list(e.message)))

                    show_msg(msg)
                    return 1
                meth_result = []
                error = False
                for res in meth_result_temp[0]:
                    meth_result.append(ReturnedMessage(res.type, res.field,
                                                       res.message, res.expert))
                    if res.type in ('error', 'pwderror', 'commonerror'):
                        self.ClientObj.param_objects[method_name]['error'] = \
                            meth_result
                        error = True
                if error:
                    debug(10, "ERROR on method execute", method_name,
                          "by method ", display_error_callback)
                    display_error_callback(from_left_frame)
                    return 0
                else:
                    debug(10, "NO error on method execute", method_name)

                if hasattr(param_object, 'CheckOnly'):
                    if param_object['CheckOnly']:
                        debug(10, "Break checkonly", method_name)
                        return 0
                    else:
                        debug(10, "CheckOnly false for", method_name)
                else:
                    debug(10, "NO checkonly", method_name)

                self.ClientObj.param_objects[method_name]['step'] = 0
                # если вызван другой метод - сбросить кэш этого
                if self.method_name != method_name:
                    self.ClientObj.client.service[0]['clear_method_cache'](
                        sid, self.method_name)
                if meth_result[0].type == "pid":
                    # create process dict
                    self.ClientObj.process_dict[meth_result[0].message] = {}
                    d = self.ClientObj.process_dict[meth_result[0].message]
                    d['result'] = meth_result[0]
                    d['name'] = self.method_name
                    d['layout'] = qt.QVBoxLayout()
                    d['layout'].setAlignment(qt.Qt.AlignTop)

                # set new window title
                temp = self.ClientObj._parent.windowTitle().split('-')
                if not _(' Step ') in temp[len(temp) - 1]:
                    self.ClientObj._parent.setWindowTitle(
                        u"{title} - {action}".format(
                            title=self.ClientObj._parent.windowTitle(),
                            action=_("Running")))
                else:
                    temp.pop()
                    self.ClientObj._parent.setWindowTitle(
                        u"{title} - {action}".format(
                            title="-".join(temp),
                            action=_("Running").decode('utf-8')))

                self.calling_error = False
                # Call method display process results
                debug(10, "CALLING RESULT VIEWING", method_name)
                self.ClientObj.MainWidget.main_frame_res(
                    method_name, meth_result[0], change_offset=change_offset)

            except WebFault, f:
                show_msg(f.message, 'Error from Server!')
                self.ClientObj.param_objects[method_name]['error'] = \
                    'transmitted data is incorrect'

        return wrapper

    left_check_step = qt.Signal(str, int)
    left_check_step_after = qt.Signal()

    def refresh_view(self, step=0, expert=False, from_left_frame=False):
        """
        Обновить элемены view
        :param step: текущая закладка параметров
        :param expert: отображать экспертные параметры
        :param brief: отображение предварительных установок
        :param from_left_frame: запуск из закладок
        """
        debug(10, "REFRESH VIEW for method", self.method_name, "STEP", step,
              "WITH EXPERT" if expert else "",
              "FROM LEFT FRAME" if from_left_frame else "")

        try:
            brief = self.isBrief(step)
            view_name = self.method_name + '_view'
            view_params = get_view_params(self.ClientObj.client,
                                          view_name,
                                          step=None if brief else step,
                                          expert=True if brief else expert,
                                          brief=brief)
            view_method = self.ClientObj.client.service[0][view_name]
            view = view_method(int(self.ClientObj.sid), view_params)
        except urllib2.URLError is e:
            _print('_view in mainframe Exception')
            return 1
        self.ClientObj.param_objects[self.method_name]['step'] = step
        # display view in main frame
        self.ClientObj.MainWidget.main_frame_view(view, self.method_name)

        left_frame = self.ClientObj.MainWidget.left_frame
        if from_left_frame and expert:
            if left_frame.step == step:
                self.left_check_step_after.connect(left_frame.check_step_after)
                self.left_check_step_after.emit()
        if from_left_frame and left_frame.step != step:
            left_frame.check_step(str(self.method_name), left_frame.step)

    def error_display_self(self, from_left_frame=False):
        debug(18, "ERRORS",
              self.ClientObj.param_objects[self.method_name]['error'])
        debug(18, "FIELDS",
              self.ClientObj.param_objects[self.method_name]['fields'])
        self.error_display(
            from_left_frame=from_left_frame,
            errors=self.ClientObj.param_objects[self.method_name]['error'],
            fields=self.ClientObj.param_objects[self.method_name]['fields'],
            step=self.ClientObj.param_objects[self.method_name]['step']
        )

    def error_display(self, from_left_frame=False, errors=None,
                      fields=None, step=None):
        '''display error and warning in current view'''
        if not self.error_output:
            self.error_output = True
            return
        self.button_enabled()

        debug(17, "ERRORS", [(x.field, x.message) for x in errors])
        self.error_fined = False
        curError = {str(x.field): x for x in errors}

        for field in filter(lambda x: x not in curError, self.error_label_dict):
            self.error_label_dict[field].hide()
            self.unhighliht_element_errors(field)

        for field in curError:
            error = curError[field]
            errorfield = error.field
            for i, stepfields in fields.items():
                if errorfield in stepfields:
                    self.error_fined = True
                    # Проверка на экспертное поле
                    ind = stepfields.index(errorfield)
                    # None - экспертный разделитель
                    expert = True if (None in stepfields[:ind]) else False

                    if self.skip_options:
                        self.skip_options = False
                        self.refresh_view(i, expert, from_left_frame)
                        return

                    if from_left_frame and step != i:
                        continue
                    brief = self.isBrief(step)
                    if (i != step or expert) or brief:
                        self.refresh_view(i, expert, from_left_frame)
                        return

            if not self.error_fined:
                fields_name = ''
                for error in errors:
                    fields_name += error.field + ', '
                if fields_name:
                    fields_name = fields_name[:-2]
                show_msg('Fields %s not found' % fields_name, 'Field Error')
            if str(errorfield) in self.error_label_dict:
                self.error_label_dict[errorfield].setStyleSheet(
                    "QLabel { color : red; }")
                error_msg = error.message.strip('\n')
                self.error_label_dict[errorfield].setText(error_msg)
                self.error_label_dict[errorfield].show()
                if str(errorfield) in self.view_dict:
                    self.highlight_element_error(errorfield)

    def unhighliht_element_errors(self, field_name):
        if type(self.view_dict[field_name]) in [qt.QGroupBox, SelectList]:
            self.view_dict[field_name].setStyleSheet( \
                self.view_dict[field_name].styleSheet().replace('red', 'gray'))
        elif type(self.view_dict[field_name]) in [SelectedTableWidget]:
            #            self.view_dict[field_name].setStyleSheet('QTableWidget { '
            #                                                    'border: 1px solid red;}')
            self.view_dict[field_name].unsetErrorBorder()
        elif type(self.view_dict[field_name]) in [qt.QComboBox]:
            self.view_dict[field_name].setStyleSheet('QComboBox { '
                                                     'border: 0px solid red;}')
        elif type(self.view_dict[field_name]) in [ComboFileWgt, QComboWgt]:
            self.view_dict[field_name].unsetErrorBorder()
        elif type(self.view_dict[field_name]) == qt.QCheckBox:
            self.view_dict[field_name].setStyleSheet('QCheckBox { '
                                                     'border: 0px solid red;}')
        else:
            self.view_dict[field_name].setStyleSheet("")

    def highlight_element_error(self, field_name):
        if type(self.view_dict[field_name]) in [qt.QGroupBox, SelectList]:
            self.view_dict[field_name].setStyleSheet( \
                self.view_dict[field_name].styleSheet().replace('gray', 'red'))
        elif type(self.view_dict[field_name]) in [SelectedTableWidget]:
            #            self.view_dict[field_name].setStyleSheet('QTableWidget { '
            #                                                    'border: 1px solid red;}')
            self.view_dict[field_name].setErrorBorder()
        elif type(self.view_dict[field_name]) in [qt.QComboBox]:
            self.view_dict[field_name].setStyleSheet('QComboBox { '
                                                     'border: 1px solid red;}')
        elif type(self.view_dict[field_name]) in [ComboFileWgt, QComboWgt]:
            self.view_dict[field_name].setErrorBorder()
        elif type(self.view_dict[field_name]) == qt.QCheckBox:
            self.view_dict[field_name].setStyleSheet('QCheckBox { '
                                                     'border: 1px solid red;}')
        else:
            self.view_dict[field_name].setStyleSheet('border: 1px solid red;')

    def highlight_errors(self):
        self.button_enabled()
        if not self.error_output:
            self.error_output = True
            return
        '''display error in current view If errors came in parameters'''
        step_num = self.ClientObj.param_objects[self.method_name]['step']

        for error in self.ClientObj.param_objects[self.method_name]['error']:
            try:
                debug(15, "ERROR", error.field, error.message)
                error.field
            except:
                show_msg(self.ClientObj.param_objects \
                             [self.method_name]['error'])
                self.ClientObj.param_objects[self.method_name]['error'] = None
                return 1
            if error.field in self.ClientObj.param_objects[self.method_name] \
                    ['fields'][step_num]:
                if self.error_label_dict.has_key(str(error.field)):
                    try:
                        self.error_label_dict[error.field].setStyleSheet \
                            ("QLabel { color : red; }")
                        self.error_label_dict[error.field].setText \
                            (error.message)
                        self.error_label_dict[error.field].show()

                        debug(15, "ERROR highlight", error.field)
                        self.highlight_element_error(error.field)
                    except RuntimeError:
                        pass

    # method changed value table items
    # Only for fixed size table
    def OnChanged(self, row, column, field):
        def wrapper():
            table = field.tablevalue
            for i in range(len(table.values.ChoiceValue[column - 1].onChanged. \
                                       string)):
                col = i + 1
                if table.values.ChoiceValue[column - 1].onChanged.string[
                    i] == '':
                    ''' do nothing '''
                    pass

                elif table.values.ChoiceValue[column - 1].onChanged.string[i] == \
                        None:
                    '''remove value'''
                    self.OnChanged_None(field, row, col)

                # Event when the state of the widget QComboBox changed
                elif table.values.ChoiceValue[column - 1].onChanged.string[i] == \
                        'get_body':
                    '''insert the value specified in "body table" for this'''
                    self.OnChanged_get_body(field, table, column, row, col)

                elif table.values.ChoiceValue[column - 1].onChanged.string[i] == \
                        'on':
                    '''set Check'''
                    if type(self.view_dict[field.name].cellWidget(row, i)) == \
                            CentralCheckBox:
                        self.view_dict[field.name].cellWidget(row, col). \
                            setChecked(True)

                elif table.values.ChoiceValue[column - 1].onChanged.string[i] == \
                        'off':
                    '''set unCheck'''
                    if type(self.view_dict[field.name].cellWidget(row, col)) == \
                            CentralCheckBox:
                        self.view_dict[field.name].cellWidget(row, col). \
                            setChecked(False)

                elif table.values.ChoiceValue[column - 1].onChanged.string[i] == \
                        'auto':
                    '''set unCheck'''
                    if type(self.view_dict[field.name].cellWidget(row, col)) == \
                            CentralCheckBox:
                        self.view_dict[field.name].cellWidget(row, col). \
                            setCheckState(qt.Qt.PartiallyChecked)

        return wrapper

    def OnChanged_None(self, field, row, i):
        '''remove value'''
        if self.view_dict[field.name].item(row, i):
            self.view_dict[field.name].item(row, i).setText('')
        elif type(self.view_dict[field.name].cellWidget(row, i)) == qt.QComboBox:
            try:
                self.view_dict[field.name].cellWidget(row, i).setEditText('')
            except:
                pass
        elif type(self.view_dict[field.name].cellWidget(row, i)) == \
                MultipleChoice:
            self.view_dict[field.name].cellWidget(row, i).avail += \
                self.view_dict[field.name]. \
                    cellWidget(row, i).select
            self.view_dict[field.name].cellWidget(row, i).Selected = []
            self.view_dict[field.name].cellWidget(row, i).change_value()

    def OnChanged_get_body(self, field, table, column, row, i):
        '''insert the value specified in "body table" for this'''
        text = self.view_dict[field.name].cellWidget(row, column).currentText()
        if self.view_dict[field.name].item(row, i):
            for q in (table.body.stringArray):
                try:
                    ind = q.string.index(text)
                    self.view_dict[field.name].item(row, i).setText \
                        (q.string[i - 1])
                    break
                except Exception, e:
                    #                    _print ('EXCEPT', e)
                    pass
        elif type(self.view_dict[field.name].cellWidget(row, i)) == qt.QComboBox:
            for q in (table.body.stringArray):
                try:
                    ind = q.string.index(text)
                    cur_text = q.string[ind]
                    cur_ind = table.values.ChoiceValue[column].values.string. \
                        index(cur_text)
                    self.view_dict[field.name].cellWidget(row, i). \
                        setCurrentIndex(cur_ind)
                    break
                except:
                    pass
        elif type(self.view_dict[field.name].cellWidget(row, i)) == \
                CentralCheckBox:
            for q in (table.body.stringArray):
                try:
                    ind = q.string.index(text)
                    cur_text = q.string[ind]
                    if q.string[i - 1] == 'on':
                        self.view_dict[field.name].cellWidget(row, i). \
                            setChecked(True)
                    elif q.string[i - 1] == 'off':
                        self.view_dict[field.name].cellWidget(row, i). \
                            setChecked(False)
                    break
                except:
                    pass
        elif type(self.view_dict[field.name].cellWidget(row, i)) == \
                MultipleChoice:
            for q in (table.body.stringArray):
                try:
                    ind = q.string.index(text)
                    cur_text = q.string[i - 1]
                    self.view_dict[field.name].cellWidget(row, i).avail = \
                        table.values.ChoiceValue[column].values.string
                    self.view_dict[field.name].cellWidget(row, i).Selected = \
                        cur_text.split(',')
                    self.view_dict[field.name].cellWidget(row, i).change_value()
                    break
                except:
                    pass

    def button_enabled(self):
        if hasattr(self._parent, 'control_button'):
            self._parent.control_button.button_enabled()
            self.ClientObj.app.processEvents()

    def check_run_threads(self):
        if hasattr(self, 'button_call_thread'):
            if self.button_call_thread.isRunning():
                return 1
        if hasattr(self.ClientObj.MainWidget.left_frame, 'onActivated_thread'):
            if self.ClientObj.MainWidget.left_frame.onActivated_thread. \
                    isRunning():
                return 1
        if hasattr(self.ClientObj.MainWidget.left_frame, 'check_step_thread'):
            if self.ClientObj.MainWidget.left_frame.check_step_thread. \
                    isRunning():
                return 1
        return 0

    def closeEvent(self, event):
        if hasattr(self, 'button_call_thread'):
            if self.button_call_thread.isRunning():
                self.button_call_thread.close()
                self.button_call_thread.wait()

        # Show Control Buttons widget
        self._parent.methodname_wgt._hide()
        self._parent.control_button._hide()
        event.accept()
