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

# Copyright 2012-2013 Calculate Ltd. 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 PySide import QtGui, QtCore
from PySide.QtGui import QLabel, QLineEdit, QCheckBox, QGroupBox, QComboBox
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
from sudsds import WebFault
from calculate.lib.utils.tools import Sizes
from SelectTable import SelectedTableWidget
from ReturnMessage import ReturnedMessage
import urllib2, time
from os import path


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(QtCore.QThread):
    '''For using page_offset and page_count'''
    collect_sig = QtCore.Signal()
    call_meth_sig = QtCore.Signal()
    def __init__(self, parent):
        QtCore.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(QtGui.QRadioButton):
    def __init__(self, text = None, parent = None):
        QtGui.QRadioButton.__init__(self, text, parent)

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

class MainFrame(QtGui.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

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

    def isBrief(self, step = None):
        steps = self.ClientObj.param_objects[self.method_name]['steps_field']
        if hasattr (steps, 'label'):
            if steps.label:
                if step == None:
                    step = self.ClientObj.param_objects[self.method_name]\
                                                       ['step']
                if len(steps.tablevalue.head.string) == step:
                    return True
        return False

    add_standart_button = QtCore.Signal(object, int, int, bool, str)

    def initUI(self):
#        _print (self.view)
        self.common_layout = QtGui.QVBoxLayout(self)
        self.common_layout.setAlignment(QtCore.Qt.AlignTop)
        self.common_layout.setContentsMargins(0, 0, 0, 0)
        self.common_layout.setSpacing(0)

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

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

        from ConnectionTabs import SelectedMethodWgt
        self.tabWidget = SelectedMethodWgt
        # for advanced settings
        self.expert = False
        self.expert_list = []
        self.changed_expert_list = []
        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 = {}

        if not self.ClientObj.param_objects.has_key(self.method_name):
            self.ClientObj.param_objects[self.method_name] = {}
            self.ClientObj.param_objects[self.method_name]['step'] = 0
            self.ClientObj.param_objects[self.method_name]['error'] = None
            self.ClientObj.param_objects[self.method_name]['offset'] = 0
            self.ClientObj.param_objects[self.method_name]['fields'] = {}
            self.ClientObj.param_objects[self.method_name] \
                                                        ['steps_field'] = None

        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 = []

        self.param_object = create_obj(self.ClientObj.client, self.method_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:
            self.call_server_method(collect_flag = False)
            return
        if hasattr (self.view, 'groups'):
            if not self.view.groups:
                self.call_server_method(collect_flag = False)
                return

        if self.isBrief():
            self.print_brief(self.view.groups.GroupField, x)
            return
        lastTable = None

        for Group in self.view.groups.GroupField:
            for field in Group.fields.Field:
                if field.element == 'table' and field.type == 'steps':
                    self.add_element_steps (field)

        if self.skip_options:
            self.call_server_method(collect_flag = False)
            return

        for Group in self.view.groups.GroupField:
            if Group.name:
                self.group_name_label = LabelWordWrap(Group.name, self)
                self.group_name_label.setAlignment(QtCore.Qt.AlignLeft)
                self.group_name_label.setStyleSheet("font-size: 16px;"
                                            "color: #000; font: bold;");

                self.grid.addWidget(self.group_name_label, x, y, 1, 2)
                x += 1
            
            for field in Group.fields.Field:
                if lastTable:
                    self.resize_table(lastTable)
                lastTable = None
                # add element in frame
                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

                    # 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 field.element == 'input' or \
                    field.type and  "onepassword" in field.type:
                    if field.name in ['cl_page_count','cl_page_offset']:
                        continue
                    if "size" in field.type:
                        field.value = get_size_by_type(field.type,field.value)
                    self.add_element_input (field, x, y)
                    x += 2

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

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

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

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

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

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

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

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

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

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

                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
                
                elif field.element == 'button':
                    add_button_flag = True
                    self._parent.control_button.del_button()
                    x = self.add_button (field, x, y)

        c = 1 if hasattr(self, 'group_name_label') else 0

        if lastTable:
            lastTable.bFixedHeight = False
            self.resize_table(lastTable)
        # When used page_offset and page_count
        if self.grid.count() <= c:
#            call_button = QtGui.QPushButton(self)
            if c == 1:
                self.group_name_label.hide()
            self.call_server_method(change_offset = True)
            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 not add_button_flag:
            # add 1 (or 2) button ok (next) [and previous] 
            self.add_standart_button.connect(self._parent.control_button.\
                                             add_standart_button)
            self.add_standart_button.emit(Group, x, y, None, None)

#        self.grid.setSizeConstraint(self.grid.SizeConstraint.SetMinimumSize)
        self.grid.setSizeConstraint \
                                (QtGui.QLayout.SizeConstraint.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']:
            self.highlight_errors()
        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']:
            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(QtGui.QSpacerItem( 0, 0, QtGui.QSizePolicy.\
                            Expanding, QtGui.QSizePolicy.Expanding), x+1, y, 1, 2)

        self.common_layout.addLayout(self.grid)

        # add spacer
        #self.common_layout.addItem(QtGui.QSpacerItem( 0, 0, \
        #           QtGui.QSizePolicy.Expanding, QtGui.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
            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
            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, \
                              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):
        call_method = CallMethod(self)
        if collect_flag:
            call_method.collect_sig.connect(self.collect_object(False))
        else:
            self.param_object = None
        call_method.call_meth_sig.connect(self.calling(True, \
                                          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):
        #add label
        self.label_dict[field.name] = LabelWordWrap(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)
            
        self.grid.addWidget(self.label_dict[field.name], x, y)

        self.view_dict[field.name] = QLineEdit(self)
        if field.value:
            self.view_dict[field.name].setText(field.value)
        if field.type == 'int':
            self.rx = QtCore.QRegExp ("^[\d]{1,50}$")
            self.validator = QtGui.QRegExpValidator(self.rx, self)
            self.view_dict[field.name].setValidator(self.validator)
        elif field.type == 'float':
            self.rx = QtCore.QRegExp ("^[\d]{1,50}[.][\d]{1,50}$")
            self.validator = QtGui.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(QtGui.QLineEdit.Password)

        exp = QtGui.QSizePolicy.Policy.Expanding
        pref = QtGui.QSizePolicy.Policy.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.append(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 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] = 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] = QCheckBox(self)
            self.view_dict[field.name].setStyleSheet(
                "QCheckBox:hover {background-color:#FFFFFF}")

        self.view_dict[field.name].setFocusPolicy(QtCore.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(QtCore.Qt.CheckState.\
                                                                       Checked)
            elif field.value == 'off':
                self.view_dict[field.name].setCheckState(QtCore.Qt.CheckState.\
                                                                     Unchecked)
            elif field.value == 'auto':
                self.view_dict[field.name].setCheckState(QtCore.Qt.CheckState.\
                                                              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(QtCore.Qt.CheckState.\
                                                              PartiallyChecked)
            if field.default:
                self.expert_list.append(field.name)
            else:
                self.changed_expert_list.append(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 = QtGui.QLabel(self)
        exp = QtGui.QSizePolicy.Policy.Expanding
        pref = QtGui.QSizePolicy.Policy.Preferred
        check_widget.setSizePolicy(exp, pref)
        check_layout = QtGui.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(QtCore.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() == \
                                        QtCore.Qt.CheckState.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] = 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 = QGroupBox(field.label, self)
        self.GroupBox.setStyleSheet("QGroupBox {"
            'padding-top: 24px; padding-bottom: 0px;'
            'padding-left: 5px; padding-right: 5px;'
            'border: 1px solid transparent;'
            'border-top-color: gray;'
            'border-left-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,'
            'stop: 0 gray, stop: 0.7 gray, stop: 1 transparent);'

            'border-right-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,'
            'stop: 0 gray, stop: 0.7 gray, stop: 1 transparent);'

            'background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,'
            'stop: 0 #eeeeee, stop: 0.8 transparent, stop: 1 transparent);'
            'border-bottom: 0px;'
            'border-top-left-radius: 4px;'
            'border-top-right-radius: 4px;}'

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

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

        for i in range(0,len(choice)):
            radio_but = RadioButton(self)
            radio_but.setFocusPolicy(QtCore.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.append(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] = 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 = QtGui.QSizePolicy.Policy.Expanding
        pref = QtGui.QSizePolicy.Policy.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.append(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] = 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 = QtGui.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 = QtGui.QSizePolicy.Policy.Expanding
        pref = QtGui.QSizePolicy.Policy.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.append(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] = QLabel(field.label, self)
        if self.expert:
            if field.default:
                self.expert_list.append(field.name)
            else:
                self.changed_expert_list.append(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.append(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] = 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.append(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] = 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.append(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.append(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':
            self.view_dict[field.name].clicked.connect \
                                               (self.collect_object(True))
            self.view_dict[field.name].clicked.connect(self.calling(True))
            self.view_dict[field.name].clicked.connect \
                                              (self.expert_clicked(field))
        else:
            self.expert_signal.connect(self.collect_object(True))
            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 = QtCore.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
            else:
                expert = True
            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 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)
        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 == QtGui.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 add_button (self, field, x, y, brief = False):
        if not hasattr (self, 'buttons_widget'):
            self.buttons_widget = ButtonsWidget(self)
            self.grid.addWidget(self.buttons_widget, x, y, 1, 2)
            x += 1

        button = QtGui.QPushButton(field.label, self.buttons_widget)
        self.buttons_widget.add_button(button)
        self.view_dict[field.name] = button

        def init_param_object(self, cur_field):
            def wrapper():
                method_name = cur_field.value
                self.param_object = create_obj(self.ClientObj.client, \
                                               method_name)
            return wrapper

        def button_clicked(self, cur_field):
            def wrapper():
                method_name = cur_field.value
                # Call server method
                if self.check_run_threads():
                    return
#                _print ('========>>>>>>', self.param_object)
                self.button_call_thread = ClientServiceThread(self.ClientObj,\
                                        method_name, int(self.ClientObj.sid),\
                                        self.param_object, \
                                        through_object = method_name)
                self.button_call_thread.signal_extended.connect \
                                            (self.button_clicked_after)
                self.button_call_thread.start()
            return wrapper

        self.view_dict[field.name].clicked.connect \
                                           (init_param_object(self, field))
        if not brief:
            self.view_dict[field.name].clicked.connect(self.collect_object \
                                                      (False))
        self.view_dict[field.name].clicked.connect(button_clicked(self, field))
        return x

    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()
#            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'] = QtGui.QVBoxLayout()
            self.ClientObj.process_dict[meth_result[0].message] \
                          ['layout'].setAlignment(QtCore.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 = QtGui.QSizePolicy.Minimum
        expanding = QtGui.QSizePolicy.Expanding
        self.table_widget.setSizePolicy(minimum, minimum)

        self.view_dict[field.name] = self.table_widget
        self.label_dict[field.name] = LabelWordWrap(field.label, self)
        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.append(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 = QtGui.QWidget(self)
        if brief:
            widget_for_grid.setStyleSheet("background: transparent;")
        wfg_layout = QtGui.QVBoxLayout(widget_for_grid)
        wfg_layout.setSpacing(0)
        wfg_layout.setContentsMargins(0, 0, 0, 0)
        # add 2 button if field type = writable
        if field.type == 'writable':
            self.view_dict[field.name].horizontalHeader().setClickable(False)

            unit_widget = QtGui.QWidget(self)
            unit_layout = QtGui.QHBoxLayout(unit_widget)
            unit_layout.setContentsMargins(0, 0, 0, 0)
            unit_layout.setSpacing(3)

            plus_but = QtGui.QPushButton(self)
            try:
                plus_but.setIcon(QtGui.QIcon.fromTheme('list-add'))
            except:
                plus_but.setText('+')

            plus_but.setToolTip(_('Add a row'))
            plus_but.setFixedWidth(30)

            self.view_dict[field.name].minus_but = QtGui.QPushButton(self)
            try:
                self.view_dict[field.name].minus_but.setIcon \
                                        (QtGui.QIcon.fromTheme('list-remove'))
            except:
               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.setFixedWidth(30)
            self.view_dict[field.name].minus_but.setDisabled(True)

            refresh_but = QtGui.QPushButton(self)
            try:
                refresh_but.setIcon(QtGui.QIcon.fromTheme('edit-undo'))
            except:
                refresh_but.setText('R')

            refresh_but.setToolTip(_('Recover the table'))
            refresh_but.setFixedWidth(30)

            clear_but = QtGui.QPushButton(self)
            try:
                clear_but.setIcon(QtGui.QIcon.fromTheme('edit-clear'))
            except:
                clear_but.setText('C')

            clear_but.setToolTip(_('Clear the table'))
            clear_but.setFixedWidth(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(QtCore.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)

        # set width column
        #self.view_dict[field.name].horizontalHeader().resizeSections\
        #                        (QtGui.QHeaderView.ResizeMode.ResizeToContents)

        # No Selection
        self.view_dict[field.name].setSelectionMode \
                            (QtGui.QAbstractItemView.SelectionMode.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 \
                                      (QtGui.QAbstractItemView.NoEditTriggers)
                for row in range (len(table.body.stringArray)):
                    tablewidgetitem = QtGui.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 = QtGui.QTableWidgetItem \
                                (table.body.stringArray[row].string[column])
                    table_widget.setItem(row, col, tablewidgetitem)

                    table_widget.item(row, col).setFlags \
                                                (QtCore.Qt.ItemIsEditable)
                    brush = QtGui.QBrush(QtCore.Qt.black)
                    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 \
                                      (QtGui.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 = QtGui.QTableWidgetItem('***')
                    else:
                        tablewidgetitem = QtGui.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 = QtGui.QTableWidgetItem(val)
                    table_widget.setItem(row, col, tablewidgetitem)

                    table_widget.item(row, col).setFlags \
                                                    (QtCore.Qt.ItemIsEditable)
                    brush = QtGui.QBrush(QtCore.Qt.black)
                    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 = QtGui.QTableWidgetItem(val)
                    table_widget.setItem(row, col, tablewidgetitem)

                    table_widget.item(row, col).setFlags \
                                                    (QtCore.Qt.ItemIsEditable)
                    brush = QtGui.QBrush(QtCore.Qt.black)
                    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 = QtGui.QTableWidgetItem(val)
                    tablewidgetitem.setData(1, data)
                    table_widget.setItem(row, col, tablewidgetitem)

                    table_widget.item(row, col).setFlags \
                                                    (QtCore.Qt.ItemIsEditable)
                    brush = QtGui.QBrush(QtCore.Qt.black)
                    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 = QtGui.QTableWidgetItem(val)
                    table_widget.setItem(row, col, tablewidgetitem)

                    table_widget.item(row, col).setFlags \
                                                    (QtCore.Qt.ItemIsEditable)
                    brush = QtGui.QBrush(QtCore.Qt.black)
                    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 = QtGui.QTableWidgetItem(val)
                    tablewidgetitem.setData(1, passwd)
                    table_widget.setItem(row, col, tablewidgetitem)

                    table_widget.item(row, col).setFlags \
                                                    (QtCore.Qt.ItemIsEditable)
                    brush = QtGui.QBrush(QtCore.Qt.black)
                    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 = QtGui.QTableWidgetItem()
                table.setItem(row, 0, tablewidgetitem)
#                table.item(row, 0).setFlags(QtCore.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.setAttribute(QtCore.Qt.WA_ShowModal)
            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.setAttribute(QtCore.Qt.WA_ShowModal)
            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\
                               (QtGui.QHeaderView.ResizeMode.ResizeToContents)
        table.setColumnWidth(0, 40)
############# End add Table
    def print_brief(self, GroupField, x):
        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

        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 = QtGui.QScrollArea(self)
        brief_widget = QtGui.QWidget(self)

        self.brief_grid = QtGui.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 Group in GroupField:
            x = self.print_brief_group(Group, x)

        # add spacer
#        spacer_brief =  QtGui.QSpacerItem( 0, 0, \
#                    QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
#        self.brief_grid.addItem(spacer_brief, x, y, 1, 2)
        brief_widget.setFixedHeight(brief_widget.sizeHint().height())
        brief_widget.setObjectName('Brief_w')
        brief_widget.setStyleSheet("#Brief_w "
                "{background-color: transparent;}")

        exp = QtGui.QSizePolicy.Policy.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

        self.add_standart_button.connect(self._parent.control_button.\
                                         add_standart_button)
        self.add_standart_button.emit(GroupField[-1], x, y, True, \
                                          next_button_text)

        # add image
        self.add_image()

        # add spacer
        self.spacer_item =  QtGui.QSpacerItem(0, 0, exp, exp)
        self.grid.addItem(self.spacer_item)
        self.grid.setSizeConstraint \
                                (QtGui.QLayout.SizeConstraint.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 = QGroupBox(Group.name)
            GroupBox.setObjectName('GroupBoxBrief')
#            brief_widget.setStyleSheet("#Brief_w "
            GroupBox.setStyleSheet('#GroupBoxBrief {'
            'font-weight: bold;'
            'padding-top: 24px; padding-bottom: 0px;'
            'padding-left: 5px; padding-right: 5px;'
            'border: 1px solid transparent;'
            'border-top-color: gray;'

            'border-left-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,'
            'stop: 0 gray, stop: 0.7 gray, stop: 1 transparent);'

            'border-right-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,'
            'stop: 0 gray, stop: 0.7 gray, stop: 1 transparent);'

            'background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,'
            'stop: 0 #eeeeee, stop: 0.8 transparent, stop: 1 transparent);'

            'border-bottom: 0px;'
            'border-top-left-radius: 4px;'
            'border-top-right-radius: 4px;}'

            'QGroupBox::title {'
            'background-color: transparent;'
            'subcontrol-position: top center;'
            'margin-top: 6px;}')
        else:
            return grid_x
        gb_layout = QtGui.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 = QtGui.QSizePolicy.Minimum
        maximum = QtGui.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)

            if not field_name in self.changed_expert_list:
                self.changed_expert_list.append(field_name)
        return wrapper
        
    def remove_expert(self, field_name):
        if field_name in self.expert_list:
            self.expert_list.remove(field_name)

        if not field_name in self.changed_expert_list:
            self.changed_expert_list.append(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 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)

    def collect_object(self, expert = False):
        def wrapper():
            '''add variable values from widget in param_object'''
            # store params name if list for each step
            for Group in self.view.groups.GroupField:
                if not Group.fields:
                    continue
                for field in Group.fields.Field:
                    if hasattr (self.param_object, 'cl_page_count'):
                        self.param_object.cl_page_count = \
                                            self.ClientObj.count_row_res_table
                    if hasattr (self.param_object, 'cl_page_offset'):
                        self.param_object.cl_page_offset = str(0 + \
                                                self.ClientObj.param_objects \
                                                [self.method_name]['offset'])
                    if not hasattr (self.param_object, field.name):
                        continue
                    if field.name == 'cl_page_count':
                        self.param_object[field.name] = \
                                            self.ClientObj.count_row_res_table
                        continue
                    if field.name == 'cl_page_offset':
                        self.param_object[field.name] = str(0 + \
                                                self.ClientObj.param_objects \
                                                [self.method_name]['offset'])
                        continue    
#                    self.ClientObj.param_objects[self.method_name] \
#                                      ['fields'][step_num].append(field.name)
                    if not self.view_dict.has_key(field.name):
                        continue
                    
                    if field.uncompatible:
                        continue
                    
                    if type (self.view_dict[field.name]) == QGroupBox:
                        if self.ButGrp_dict[field.name].checkedButton():
                            self.param_object[field.name] = \
                                        self.ButGrp_dict[field.name].\
                                        checkedButton().get_data()
                        elif field.value:
                            self.param_object[field.name] = field.value
                        else:
                            self.param_object[field.name] = ''
                        if field.element == 'radio' and field.type == 'bool':
                            if self.param_object[field.name].lower() == 'on':
                                self.param_object[field.name] = True
                            else:
                                self.param_object[field.name] = False

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

                    elif type (self.view_dict[field.name]) in \
                                                    [QComboBox, QComboWgt]:
                        ind = self.view_dict[field.name].currentIndex()
                        text = self.view_dict[field.name].currentText()
                        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)
                        if text in choice and \
                                    self.view_dict[field.name].itemData(ind):
                            self.param_object[field.name] = \
                                     self.view_dict[field.name].itemData(ind)
                        else:
                            self.param_object[field.name] = \
                                     self.view_dict[field.name].currentText()

                    elif type (self.view_dict[field.name]) == QLineEdit:
                        try:
                            self.param_object[field.name] = \
                                    str(self.view_dict[field.name].text()\
                                    .encode('utf-8'))
                            self.param_object[field.name] = \
                            self.param_object[field.name].decode('utf-8')
                        except  (UnicodeDecodeError, UnicodeEncodeError):
                            self.param_object[field.name] = \
                                    str(self.view_dict[field.name].text())
    
                    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]
                        self.param_object[field.name] = \
                                listToArray(self.ClientObj.client, list_result)
                        
                    elif type (self.view_dict[field.name]) == FileOpenWgt:
                        val = str(self.view_dict[field.name].data)
                        if not val:
                            val = ''
                        self.param_object[field.name] = val

                    elif type (self.view_dict[field.name]) == ComboFileWgt:
                        val = self.view_dict[field.name].text()
                        if not val:
                            val = ''
                        try:
                            self.param_object[field.name] = \
                                    str(val.encode('utf-8'))
                            self.param_object[field.name] = \
                            self.param_object[field.name].decode('utf-8')
                        except  (UnicodeDecodeError, UnicodeEncodeError):
                            self.param_object[field.name] = str(val)

                    elif type (self.view_dict[field.name]) == PasswordWidget:
                        try:
                            self.param_object[field.name] = \
                                    str(self.view_dict[field.name].get_text()\
                                    .encode('utf-8'))
                            self.param_object[field.name] = \
                            self.param_object[field.name].decode('utf-8')
                        except  (UnicodeDecodeError, UnicodeEncodeError):
                            self.param_object[field.name] = \
                                    str(self.view_dict[field.name].text())
                        
                    elif type (self.view_dict[field.name]) == \
                                                          SelectedTableWidget:
                        self.collect_table(field)

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

    def collect_table (self, field):
        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 = []
                    if ChoiceValue.comments and \
                                      hasattr (ChoiceValue.comments, 'string'):
                        for val in val_list:
                            if val in ChoiceValue.comments.string:
                                ind = ChoiceValue.comments.string.index(text)
                                res_list.append(ChoiceValue.values.string[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]]
        self.param_object[field.name] = listToArrayArray \
                                        (self.ClientObj.client, table_result)

    def calling(self, CheckOnly = False, change_offset = False, \
                from_left_frame = False):
    # call method on server
        def wrapper():
            if hasattr (self.param_object, 'CheckOnly'):
                self.param_object['CheckOnly'] = CheckOnly

#            _print (self.param_object)

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

            self.ClientObj.sid = get_sid(self.ClientObj.client)
            try:
                sid = int(self.ClientObj.sid)
                # call method on server
                try:
                    if self.param_object:
                        meth_result_temp = self.ClientObj.client.service[0] \
                                    [self.method_name](sid, self.param_object)
                    else:
                        meth_result_temp = self.ClientObj.client.service[0] \
                                                       [self.method_name](sid)
                except Exception, 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[self.method_name] \
                                                       ['error'] = meth_result
                        error = True

                if error:
                    #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()

                    self.error_display(from_left_frame)
#                    self.ClientObj.param_objects[self.method_name]['error'] =\
#                                                                        None
                    return 0
                if hasattr (self.param_object, 'CheckOnly'):
                    if self.param_object['CheckOnly']: 
                        return 0
                self.ClientObj.param_objects[self.method_name]['step'] = 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'] = self.method_name
                    self.ClientObj.process_dict[meth_result[0].message] \
                                               ['layout'] = QtGui.QVBoxLayout()
                    self.ClientObj.process_dict[meth_result[0].message] \
                                  ['layout'].setAlignment(QtCore.Qt.AlignTop)

                # set new window title
                temp = self.ClientObj._parent.windowTitle().split('-')
                if not _(' Step ') in temp[len(temp)-1]:
                    self.ClientObj._parent.setWindowTitle \
                                (self.ClientObj._parent.windowTitle() + \
                                ' - ' + _("Running"))
                else:
                    temp.pop()
                    self.ClientObj._parent.setWindowTitle('-'.join(temp) \
                                                            + ' - ' + _("Running"))
                self.calling_error = False
                # Call method display process results
                self.ClientObj.MainWidget.main_frame_res(self.method_name, \
                                meth_result[0], change_offset = change_offset)

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

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

    def refresh_view(self, step=0, expert=False, from_left_frame=False):
        """
        Обновить элемены view
        :param step: текущая закладка параметров
        :param expert: отображать экспертные параметры
        :param brief: отображение предварительных установок
        :param from_left_frame: запуск из закладок
        """
        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, from_left_frame = False):
        '''display error and warning in current view'''
        if not self.error_output:
            self.error_output = True
            return
        self.button_enabled()
        self.error_fined = False
        curError = {str(x.field): x
                    for x in
                    self.ClientObj.param_objects[self.method_name]['error']}

        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]
            for step_num in range(len(self.ClientObj.param_objects \
                                                [self.method_name]['fields'])):
                if error.field in self.ClientObj.param_objects \
                                        [self.method_name]['fields'][step_num]:
                    self.error_fined = True
                    # Проверка на экспертное поле
                    field_names = self.ClientObj.param_objects \
                                    [self.method_name]['fields'][step_num]
                    ind = field_names.index(error.field)
                    # None - экспертный разделитель
                    expert = True if (None in field_names[:ind]) else False

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

                    if from_left_frame and self.ClientObj.param_objects \
                                [self.method_name]['step'] != step_num:
                        continue
                    brief = self.isBrief(self.ClientObj.param_objects \
                                                [self.method_name]['step'])
                    if (self.ClientObj.param_objects[self.method_name]['step']\
                                 != self.ClientObj.MainWidget.left_frame.step \
                                 or expert) or brief:
                        self.refresh_view(step_num, expert, from_left_frame)
                        return

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

    def unhighliht_element_errors(self,field_name):
        if type (self.view_dict[field_name]) in [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 [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]) == QCheckBox:
            self.view_dict[field_name].setStyleSheet('QCheckBox { '
                                                    'border: 0px solid red;}')
        else:
            self.view_dict[field_name].setStyleSheet('border: 0px solid red;')

    def highlight_element_error(self, field_name):
        if type (self.view_dict[field_name]) in [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 [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]) == 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:
                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()

                        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(QtCore.Qt.CheckState. \
                                                      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)) == 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)) == 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()
