def __init__(self, iface, parent=None):
     """Constructor."""
     super(yieldMainWindow, self).__init__(parent)
     self.db = None
     self.iface = iface
     # Set up the user interface from Designer.
     # After setupUI you can access any designer object by doing
     # self.<objectname>, and you can use autoconnect slots - see
     # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
     # #widgets-and-dialogs-with-auto-connect
     self.ui = Ui_YieldDialogBase()
     self.ui.setupUi(self)
     self.tables = []
     
     self.ui.sendRequestButton.clicked.connect(self.request)
     self.ui.textEdit.setText("SELECT table_name FROM information_schema.tables;")
     self.ui.reloadLayersButton.clicked.connect(self.reloadLayers)
     self.ui.refreshStructureButton.clicked.connect(self.refreshStructure)
     self.ui.checkStructureButton.clicked.connect(self.checkStructure)
     self.ui.configureInterfaceButton.clicked.connect(self.configureInterface)
     self.dictLegendRefBySource = {}
     self.dictSourceRefByLegend = {}
     
     self.ui.textEdit.setStyle(QtGui.QStyleFactory.create('Motif'))
     self.center()
class yieldMainWindow(QtGui.QMainWindow):
    def __init__(self, iface, parent=None):
        """Constructor."""
        super(yieldMainWindow, self).__init__(parent)
        self.db = None
        self.iface = iface
        # Set up the user interface from Designer.
        # After setupUI you can access any designer object by doing
        # self.<objectname>, and you can use autoconnect slots - see
        # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
        # #widgets-and-dialogs-with-auto-connect
        self.ui = Ui_YieldDialogBase()
        self.ui.setupUi(self)
        self.tables = []
        
        self.ui.sendRequestButton.clicked.connect(self.request)
        self.ui.textEdit.setText("SELECT table_name FROM information_schema.tables;")
        self.ui.reloadLayersButton.clicked.connect(self.reloadLayers)
        self.ui.refreshStructureButton.clicked.connect(self.refreshStructure)
        self.ui.checkStructureButton.clicked.connect(self.checkStructure)
        self.ui.configureInterfaceButton.clicked.connect(self.configureInterface)
        self.dictLegendRefBySource = {}
        self.dictSourceRefByLegend = {}
        
        self.ui.textEdit.setStyle(QtGui.QStyleFactory.create('Motif'))
        self.center()
    
    def closeEvent(self,e):
        self.db.close()
        self.db.removeDatabase("first2")
        
    def keyPressEvent(self, e):
        if e.key() == QtCore.Qt.Key_Escape:
            self.close()
            
    def configureInterface(self):
        att = 'remark'
        self.tabs = []
        self.groups = []
        self.widgets = []
        for name, layer in QgsMapLayerRegistry.instance().mapLayers().iteritems():
            layer.clearAttributeEditorWidgets()
            layer.setEditorLayout(1)
            self.tabs.append(QgsAttributeEditorContainer("Tab 1", layer))
            fields =  layer.pendingFields()
            for field in fields:
                self.widgets.append(QgsAttributeEditorField(field.name()\
                                    , layer.fieldNameIndex(field.name())\
                                    , layer))
                self.tabs[-1].addChildElement(self.widgets[-1])
            layer.addAttributeEditorWidget(self.tabs[-1])
        
    
    def getNodes(self, node, parent = None):
        if parent == 'source' or parent == 'name' or parent == 'symbology':
            text =  node.firstChild().toText().data()
        else:
            text = []
            n = node.firstChild()
            while (not n.isNull()):
                t = n.nodeName()
                if n.nodeType() == 1:
                    rec = self.getNodes(n, t)
                    if n.toElement().hasAttribute('groupname'):
                        name =  n.toElement().attribute('groupname')
                        group = [t, rec, name]
                        self.barCount += 1
                    else:
                        group = [t, rec]
                    text.append(group)
                n = n.nextSibling()
        return text
    
    def addGroups(self, list, parent = None):
        for group1 in list:
            if group1[0] == 'groupe':
                if len(group1) > 2:
                    index = self.iface.legendInterface().addGroup(group1[2], True, parent)
                else:
                    index = self.iface.legendInterface().addGroup(group1[0], True, parent)
                self.addGroups(group1[1], index)
            elif group1[0] == 'layer':
                dicInfoLayer = dict((key, value) for (key, value) in group1[1])
                if 'source' not in dicInfoLayer:
                    QMessageBox.warning(QDialog(),'configuration', "Source not defined for a layer")
                    raise IOError
                source = dicInfoLayer['source']
                layer = self.loadTable(source)
                self.iface.legendInterface().moveLayer(layer, parent)
                if 'name' in dicInfoLayer:
                    nomTemp = dicInfoLayer['name']
                    nom = ''.join(chr(ord(c)) for c in nomTemp).decode('utf8')
                    layer.setLayerName(nom)
                if 'symbology' in dicInfoLayer:
                    style = dicInfoLayer['symbology']
                    self.getSymbology(layer, style)
                        
    def reloadLayers(self):
        self.tables = []
        self.vlayer = []
        self.barCount = 0
        self.loadSymbologies()
        # Clear legend
        for name, layer in QgsMapLayerRegistry.instance().mapLayers().iteritems():
            QgsMapLayerRegistry.instance().removeMapLayer(name)
        while self.iface.legendInterface().groupExists(0):
                self.iface.legendInterface().removeGroup(0)        
        
        path = os.path.dirname(os.path.realpath(__file__))
        fName =  path + "/config.xml"
        if not fName:
            return
        file=QFile(fName)
        if (not file.open(QIODevice.ReadOnly | QIODevice.Text)):
            QMessageBox.warning(QDialog(),'Application', "Cannot read file %s :\n%s."\
                                %(file.fileName(),file.errorString()))
            return False
        else:
            doc = QtXml.QDomDocument("EnvironmentML");
            if(not doc.setContent(file)):
                file.close()
                QMessageBox.warning(self,"Error","Could not parse xml file.")
            file.close()
            root = doc.documentElement();
            if(root.tagName()!="config"):
                 QMessageBox.warning(self,"Error","Could not parse xml file. Root Element must be <kml/>.")
            else:
                #try:
                t = self.getNodes(root)
                self.initProgressBar()        # create progressbar
                self.addGroups(t)
                #except:
                #    QMessageBox.warning(self,"Configuration failed","Failed to read the configuration file correctly")
                #    return
        self.bar = None
        QtGui.QMessageBox.information(QtGui.QDialog(), "Reloading layers", "Layers are succesfully reloaded")            
        
        
    def loadSymbologies(self):
        text = "SELECT id, stylename, description FROM public.layer_styles";
        query = QSqlQuery(self.db) ;
        test = query.exec_(text);
        self.dicStyle = {}
        while (query.next()):
            i = 0
            self.dicStyle[query.value(1)] = query.value(0)
            
    def getSymbology(self, layer, styleName):
        errorMsg = ''
        print self.dicStyle
        if styleName in self.dicStyle:
            id = self.dicStyle[styleName] 
            styleText = layer.getStyleFromDatabase(str(id),errorMsg)
            layer.applyNamedStyle(styleText,errorMsg)
        else:
            QMessageBox.warning(QDialog(),'Configuration', "Symbology %s not present in database"%styleName)
            raise IOError
             
    def loadTable(self, table):
        QtCore.QCoreApplication.processEvents()
        uri = QgsDataSourceURI()
        # set host name, port, database name, username and password
        uri.setConnection(self.db.hostName(),str(self.db.port()),self.db.databaseName(), self.db.userName(), self.db.password())
        if table.startswith('od_'):
            uri.setDataSource("distribution", table, 'geometry')
        else:
            uri.setDataSource("distribution", table, None)
        self.vlayer.append(QgsVectorLayer(uri.uri(), table, "postgres"))
        inst = QgsMapLayerRegistry.instance()
        legend = self.iface.legendInterface()
        layer = inst.addMapLayer(self.vlayer[-1])
        legend.setLayerVisible(self.vlayer[-1],False)
        self.iface.mapCanvas().refresh()
        self.bar.progressBar.setValue(self.progress)
        self.progress += self.barInc
        return layer
        

    def refreshProjectInfo(self):
        self.dictLegendRefBySource = {}
        self.dictSourceRefByLegend = {}
        self.changeCount = 0
        for name, layer in QgsMapLayerRegistry.instance().mapLayers().iteritems():
            layerSource = layer.source().split(' ')
            for sourceElmt in layerSource:
                if sourceElmt.startswith('table'):
                    tableName = sourceElmt.split('"')[-2]
                    self.dictLegendRefBySource[tableName] = layer.name()
                    self.dictSourceRefByLegend[layer.name()] = tableName
                    
        self.tables = []
        text = "SELECT table_name FROM information_schema.tables WHERE table_schema='distribution';"
        query = QSqlQuery(self.db) ;
        test = query.exec_(text);
        while (query.next()):
            i = 0
            while (query.value(i) is not None): 
                val = str(query.value(i))
                #if val.startswith('od_'):
                self.tables.append(val)
                i = i +1

    def refreshStructure(self):
        self.refreshProjectInfo()
        # dicAttributs:= dic[nom de couche] = liste d'attributs
        # dicCombo := dic[nom de couche, attribut] = liste de valeurs
        # dicType := dic[nom de couche, attribut] = type
        # self.dicStructure := dic[nom de couche, attribut] = [Widget,widgetName, type, valeur(s)]
        while True:
            previous_modif = self.changeCount
            dicAttributs, dicType = self.getDicAttributsAndType()
            dicCombo = self.getDicCombo()
            dicStructure = self.getDicStructure(dicAttributs,dicCombo,dicType)
            shipList = self.getShipList(dicAttributs, dicStructure)
            self.checkStructureDia = checkStructureDialog(shipList)
            shipList = None
            self.checkStructureDia.setApplyAll()
            self.getActions()
            self.checkStructureDia = None
            self.createActionDictionary()
            self.applyActions()
            if previous_modif == self.changeCount:
                break
        QtGui.QMessageBox.information(QtGui.QDialog(), "Change in QGIS project", "Number of modifications applied: %s"%self.changeCount)
    
    def checkStructure(self):
        self.refreshProjectInfo()
        # dicAttributs:= dic[nom de couche] = liste d'attributs
        # dicCombo := dic[nom de couche, attribut] = liste de valeurs
        # dicType := dic[nom de couche, attribut] = type
        # self.dicStructure := dic[nom de couche, attribut] = [Widget,widgetName, type, valeur(s)]
        dicAttributs, dicType = self.getDicAttributsAndType()
        dicCombo = self.getDicCombo()
        dicStructure = self.getDicStructure(dicAttributs,dicCombo,dicType)
        shipList = self.getShipList(dicAttributs, dicStructure)
        self.checkStructureDia = checkStructureDialog(shipList)
        shipList = None
        self.checkStructureDia.show()
        result = self.checkStructureDia.exec_()
        
        if result:
            self.getActions()
            self.checkStructureDia = None
            self.createActionDictionary()
            self.applyActions()
            QtGui.QMessageBox.information(QtGui.QDialog(), "Change in QGIS project", "Number of modifications applied: %s"%self.changeCount)
    
    def createActionDictionary(self):
        self.actionDictionary = {}
        for ship in self.actionShips:
            element = ship.elmt
            elementConfig = ship.dbState
            if (ship.layer,ship.attribute) in self.actionDictionary:
                self.actionDictionary[ship.layer,ship.attribute].append([element,elementConfig])
            else:
                self.actionDictionary[ship.layer,ship.attribute]= [[element,elementConfig]]

    def applyActions(self):
        tables = []
        for key in self.actionDictionary:
            if key[0] not in tables:
                tables.append(key[0])
        for nameLayer, layer in QgsMapLayerRegistry.instance().mapLayers().iteritems():
            if layer.type() == 0:
                # The name of the layer is not equal to the name of his data source table
                if layer.name() not in self.dictSourceRefByLegend:
                    continue
                name = self.dictSourceRefByLegend[layer.name()]
                if name in tables:
                    # layer.setEditorLayout(0)
                    fields = layer.pendingFields()
                    id = 0
                    for field in fields:
                        if (name,field.name()) in self.actionDictionary:
                            for sheep in self.actionDictionary[name,field.name()]:
                                self.changeCount +=1
                                element = sheep[0]
                                elementConfig = sheep[1]
                                if element == 'widget':
                                    layer.setEditorWidgetV2(id,elementConfig)
                                elif element == 'isEditable':
                                    booleanValue = ast.literal_eval(elementConfig)
                                    layer.setFieldEditable(id,booleanValue)
                                elif element == 'isMultiline':
                                    config = layer.editorWidgetV2Config(id)
                                    booleanValue = ast.literal_eval(elementConfig)
                                    config[u'IsMultiline'] = booleanValue
                                    config[u'UseHtml'] = False
                                    layer.setEditorWidgetV2Config(id, config)
                                elif element == 'RelationLayer':
                                    config = layer.editorWidgetV2Config(id)
                                    config[u'Layer'] = elementConfig
                                    layer.setEditorWidgetV2Config(id, config)
                                elif element == 'RelationKey':
                                    config = layer.editorWidgetV2Config(id)
                                    config[u'Key'] = elementConfig
                                    layer.setEditorWidgetV2Config(id, config)
                                elif element == 'RelationValue':
                                    config = layer.editorWidgetV2Config(id)
                                    config[u'Value'] = elementConfig
                                    layer.setEditorWidgetV2Config(id, config)
                                if elementConfig == 'DateTime': 
                                    config = layer.editorWidgetV2Config(id)
                                    config[u'display_format'] = u'dd/MM/yy'
                                    config[u'field_format'] = 'yyyy-MM-dd'
                                    config[u'calendar_popup'] = True
                                    layer.setEditorWidgetV2Config(id, config)
                                   # print layer.editorWidgetV2Config(id)
                            # All fields are, by default, editable. Then depending on type, we will change it!
                        id +=1
        return
    
    def getActions(self):
        # As the order of columns can change,
        # we have to re-extract all information from the model
        self.actionShips = []
        nRow = self.checkStructureDia.model.rowCount()
        nCol = self.checkStructureDia.model.columnCount()
        for row in xrange(nRow):
            index = self.checkStructureDia.model.index(row, 5)
            apply = self.checkStructureDia.model.data(index)
            if apply:
                val = ['' for i in range(nCol)]
                for col in xrange(nCol):
                    index = self.checkStructureDia.model.index(row, col)
                    val[col] = self.checkStructureDia.model.data(index)
                newActionShip = Ship(val[0],val[1],val[2],val[3], val[4])
                self.actionShips.append(newActionShip)      
        
    
    def getShipList(self, dicAttributs, dicStructure):
        shipList = []
        for nameLayer, layer in QgsMapLayerRegistry.instance().mapLayers().iteritems():
            if layer.type() == 0:
                if layer.name() not in self.dictSourceRefByLegend:
                    continue
                name = self.dictSourceRefByLegend[layer.name()]
                if name in self.tables:
                    #layer.setEditorLayout(0)
                    fields = layer.pendingFields()
                    id = 0
                    for field in fields:
                        if field.name() in dicAttributs[name]:
                            db_widget = dicStructure[name,field.name()][0]
                            values = dicStructure[name,field.name()][3]
                            type = dicStructure[name,field.name()][2]
                            project_widget =layer.editorWidgetV2(id)
                            # All fields are, by default, editable. Then depending on type, we will change it!
                            project_isEditable = layer.fieldEditable(id)
                            db_isEditable = True
                            project_config = layer.editorWidgetV2Config(id)
                            solution = ''
                            if db_widget == 'ValueRelation':
                                for nLayer, vlayer in QgsMapLayerRegistry.instance().mapLayers().iteritems():
                                    try:
                                        if self.dictSourceRefByLegend[vlayer.name()] == values[0]:
                                            clayer = nLayer
                                    except:
                                        continue
                                if ('value_fr' not in dicAttributs[values[0]]) \
                                    and ('name' not in dicAttributs[values[0]])\
                                    and  ('tr_value_fr' not in dicAttributs[values[0]]) :
                                    db_widget = 'TextEdit'
                                    db_isEditable = False
                                elif project_widget == 'ValueRelation':
                                    #Widget is ok, but we will check the configuration here
                                    #first, check the related layer
                                    if 'Layer' not in project_config:
                                        solution = 'Set layer of value relation'
                                        newship = Ship(str(name),str(field.name()),\
                                            'RelationLayer',str('None'),\
                                            str(clayer), solution)
                                        shipList.append(newship)
                                    elif project_config[u'Layer'] != clayer:
                                        solution = 'Change layer of value relation'
                                        newship = Ship(str(name),str(field.name()),\
                                            'RelationLayer',str(project_config[u'Layer']),\
                                            str(clayer), solution)
                                        shipList.append(newship)
                                    # then check the related key of the layer is ok
                                    if 'Key' not in project_config:
                                        solution = 'Set key of value relation'
                                        newship = Ship(str(name),str(field.name()),\
                                            'RelationKey',str('None'),\
                                            str(values[1]), solution)
                                        shipList.append(newship)
                                    elif project_config[u'Key'] != str(values[1]):
                                        solution = 'Change key of value relation'
                                        newship = Ship(str(name),str(field.name()),\
                                            'RelationKey',str(project_config[u'Key']),\
                                            str(values[1]), solution)
                                        shipList.append(newship)
                                    # Then check the value of the value is ok
                                    if 'Value' not in project_config:
                                        if 'value_fr' in dicAttributs[values[0]]:
                                            old_value = 'None'; new_value = 'value_fr'
                                            solution = 'Change the value Relation'
                                        elif 'tr_value_fr' in dicAttributs[values[0]]:
                                            old_value = 'None'; new_value = 'tr_value_fr'
                                            solution = 'Change the value Relation'
                                        elif 'name' in dicAttributs[values[0]]:
                                            old_value = 'None'; new_value = 'name'
                                            solution = 'Change the value Relation'
                                        else:
                                            old_value = 'None'; new_value = 'None'
                                            solution = 'No solution, Set manually value of value relation'
                                        newship = Ship(str(name),str(field.name()),\
                                            'RelationValue',old_value,\
                                            new_value, solution)
                                        shipList.append(newship)
                                    # Hypothesis: no table have both value_fr and name attribute
                                    elif project_config[u'Value'] != 'value_fr' and project_config[u'Value'] != 'name' and project_config[u'Value'] != 'tr_value_fr' :
                                        solution = 'Change value of value relation'
                                        if 'value_fr' in dicAttributs[values[0]]:
                                             old_value = project_config[u'Value']; new_value = 'value_fr'
                                        elif 'tr_value_fr' in dicAttributs[values[0]]:
                                             old_value = project_config[u'Value']; new_value = 'tr_value_fr'
                                        else:
                                            old_value = 'None'; new_value = 'None'
                                            solution = 'No solution, Set manually value of value relation' 
                                        newship = Ship(str(name),str(field.name()),\
                                            'RelationValue',old_value,\
                                            new_value, solution)
                                        shipList.append(newship)
                                    
                            if project_widget != db_widget:
                                # Check of Valuerelation, DateTime (date), CheckBox (boolean) and TextEdit
                                if project_widget == 'ValueRelation' and db_widget == 'TextEdit' :
                                    solution = 'No solution (Foreign key may be missing in DB)'
                                else:
                                    solution = 'Change current widget with the proposed one'
                                newship = Ship(str(name),str(field.name()),'widget',str(project_widget),db_widget, solution)
                                shipList.append(newship)
                                solution = ''
                            if type == 'longText':
                                #layer.setFieldMultiLine(id,True)
                                solution = 'Set field multiline'
                                if 'IsMultiline' not in project_config:
                                        newship = Ship(str(name),str(field.name()),\
                                       'isMultiline',str(False),\
                                       str(True), solution)
                                        shipList.append(newship)
                                elif project_config['IsMultiline'] != True:
                                    newship = Ship(str(name),str(field.name()),\
                                               'isMultiline',str(project_config['IsMultiline']),\
                                               str(True))
                                    shipList.append(newship)       
                            if field.name() == 'id':
                                db_isEditable = False
                                solution = 'Set field non editable'
                            if field.name().startswith('tr_'):
                                db_isEditable = False
                                solution = 'Set field non editable'
                            if project_isEditable != db_isEditable:
                                if solution == '':
                                    solution = 'Change editability of the field'
                                newship = Ship(str(name),str(field.name()),\
                                               'isEditable',str(project_isEditable),\
                                               str(db_isEditable), solution)
                                shipList.append(newship)
                            id +=1
        return shipList


    def updateStructure(self, dicAttributs, dicStructure):
        for nameLayer, layer in QgsMapLayerRegistry.instance().mapLayers().iteritems():
            if layer.type() == 0:
                if layer.name() not in self.dictSourceRefByLegend:
                    continue
                name = self.dictSourceRefByLegend[layer.name()]
                if name in self.tables:
                    layer.setEditorLayout(0)
                    fields = layer.pendingFields()
                    id = 0
                    for field in fields:
                        if field.name() in dicAttributs[name]:
                            widget = dicStructure[name,field.name()][0]
                            values = dicStructure[name,field.name()][3]
                            type = dicStructure[name,field.name()][2]
                            layer.setEditorWidgetV2(id,widget)
                            # All fields are, by default, editable. Then depending on type, we will change it!
                            layer.setFieldEditable(id,True)
                            config = {}
                            # DPFE rule
                            if field.name().startswith('tr_') or type == 'primaryKey':
                                layer.setEditorWidgetV2(id,'TextEdit')
                                layer.setFieldEditable(id,False)
                                
                            if widget == 'ValueRelation':
                                for nameLayer, vlayer in QgsMapLayerRegistry.instance().mapLayers().iteritems():
                                    try:
                                        if self.dictSourceRefByLegend[vlayer.name()] == values[0]:
                                            clayer = nameLayer
                                    except:
                                        continue
                                config = {}
                                config[u'Layer'] = clayer
                                config[u'Key'] = str(values[1])
                                config[u'FilterExpression'] = None
                                config[u'AllowMulti'] = False
                                config[u'AllowNull'] = True
                                config[u'OrderByValue'] = False
                                
                                if 'value_fr' in dicAttributs[values[0]]:
                                    config[u'Value'] = 'value_fr'         
                                elif 'tr_value_fr' in dicAttributs[values[0]]:
                                    config[u'Value'] = 'tr_value_fr'   
                                elif 'name'in dicAttributs[values[0]]:
                                    config[u'Value'] = 'name'
                                else:
                                    # DPFE RULE
                                    config[u'Value'] = str(values[1])
                                    
                                    #QWAT RULE
                                    # All fields which are foreign key but not value or name are triggered
                                    # Triggerd are simply TextEdit widgets, non editables
                                    #layer.setEditorWidgetV2(id,'TextEdit')
                                    #layer.setFieldEditable(id,False)
                                    
                            if type == 'longText':
                                #print dir(layer)
                                #layer.setFieldMultiLine(id,True)
                                config = {}
                                config[u'UseHtml'] = False
                                config[u'IsMultiline'] = True
                            if type == 'date':
                                config[u'display_format'] = u'dd/MM/yy'
                                config[u'field_format'] = 'yyyy-MM-dd'
                                config[u'calendar_popup'] = True
                            layer.setEditorWidgetV2Config(id, config)
                            id +=1
        return
    
    def getDicStructure(self, dAtt,dCom,dTyp):
        dicStructure = {}
        for table, attributes in dAtt.items():
            for att in attributes:
                type = dTyp[table, att]
                if (table, att) in dCom:
                    widget = 'ValueRelation'
                    values = dCom[table, att]
                elif type == 'primaryKey':
                    widget = 'TextEdit'
                    values = None
                elif type == 'boolean':
                    # It is important to have the bool check after the foreignKey check.
                    # Because some bollean fields-type need a combo box (Null, True or False)
                    widget = 'CheckBox'
                    values = False
                elif type == 'date':
                    widget = 'DateTime'
                elif att.startswith('geometry'):
                    widget = 'Hidden'
                else:
                    widget = 'TextEdit'
                    values = None
                widgetName = widget +'_'+att 
                dicStructure[table, att] = [widget,widgetName,type,values]
        return dicStructure
    
    def getDicAttributsAndType(self):
        dicAtt = {}
        dicType = {}
        for table in self.tables:
            textPM = """SELECT pg_attribute.attname
FROM pg_index, pg_class, pg_attribute 
WHERE 
  pg_class.oid = 'distribution.%s'::regclass AND
  indrelid = pg_class.oid AND
  pg_attribute.attrelid = pg_class.oid AND 
  pg_attribute.attnum = any(pg_index.indkey)
  AND indisprimary;""" %table
            queryPM = QSqlQuery(self.db) ;
            textPM = queryPM.exec_(textPM);
            while (queryPM.next()):
                primaryKey = queryPM.value(0)
                print primaryKey
            text = "SELECT column_name, data_type\
    FROM information_schema.columns \
    WHERE table_name = '%s' \
    ORDER BY ordinal_position;" %table
            query = QSqlQuery(self.db) ;
            test = query.exec_(text);
            attributesList = []
            while (query.next()):
                attributesList.append(query.value(0))
                if query.value(0) == primaryKey:
                    dicType[table,query.value(0)] = 'primaryKey'
                    # for text fields, check if there are multilines
                elif query.value(1) == u'text' or query.value(1) == u'character varying':
                    textLen = """
                    SELECT max (length) 
                    FROM (SELECT character_length(%s) 
                        AS length FROM distribution.%s 
                        GROUP BY id) AS subquery;""" %(query.value(0),table)
                    queryLen = QSqlQuery(self.db);
                    testLen = queryLen.exec_(textLen);
                    while (queryLen.next()):
                        if queryLen.value(0) > 40:
                            dicType[table,query.value(0)] = 'longText'
                        else:
                            dicType[table,query.value(0)] = query.value(1)
                else: 
                    dicType[table,query.value(0)] = query.value(1)                            
            dicAtt[table] = attributesList
            print attributesList
        return dicAtt, dicType
    
    def getDicCombo(self):
        dicCombo = {}
        for table in self.tables:
            text2 = """SELECT
    tc.constraint_name, tc.table_name, kcu.column_name, 
    ccu.table_name AS foreign_table_name,
    ccu.column_name AS foreign_column_name 
    FROM 
    information_schema.table_constraints AS tc
    JOIN information_schema.key_column_usage AS kcu
      ON tc.constraint_name = kcu.constraint_name
    JOIN information_schema.constraint_column_usage AS ccu
      ON ccu.constraint_name = tc.constraint_name
WHERE constraint_type = 'FOREIGN KEY' AND tc.table_name='%s';""" %table
            query2 = QSqlQuery(self.db) ;
            test = query2.exec_(text2);
            while (query2.next()):
                dicCombo[str(query2.value(1)),str(query2.value(2))] = [query2.value(3),query2.value(4)]
        return dicCombo
    
    def request(self):
        text = self.ui.textEdit.toPlainText()
        query = QSqlQuery(self.db) ;
        test_pass = query.exec_(text);
        print text
        if test_pass:
            while (query.next()):
                i = 0
                text =  []
                while query.value(i) is not None: 
                    
                    #if val.startswith('od_'):
                    text.append(query.value(i))
                    i = i +1
                if text != []:
                    print text
        else:
            QtGui.QMessageBox.critical(QtGui.QDialog(), "Query", "Invalid Query")
        
        # Get columns on which a trigger is defined (The trigger is released when event on this column happened)
        # These columns are therefore not the targets of triggers !
        """SELECT * FROM information_schema.triggered_update_columns WHERE event_object_table = 'od_pipe';"""

    def center(self):
        qr = self.frameGeometry()
        cp = QtGui.QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())
    
    def initProgressBar(self):
        
        self.bar = progress_bar();self.bar.center();self.bar.show()
        self.bar.progressBar = self.bar.ui_progbar.progressBar
        self.bar.progressBar.setValue(0)
        self.progress = 0; 
        self.barInc = 1.0/self.barCount*100.0
        self.barInc = 1.0/self.barCount*100.0
class yieldMainWindow(QtGui.QMainWindow):
    def __init__(self, iface, parent=None):
        """Constructor."""
        super(yieldMainWindow, self).__init__(parent)
        self.db = None
        self.iface = iface
        # Set up the user interface from Designer.
        # After setupUI you can access any designer object by doing
        # self.<objectname>, and you can use autoconnect slots - see
        # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
        # #widgets-and-dialogs-with-auto-connect
        self.ui = Ui_YieldDialogBase()
        self.ui.setupUi(self)
        self.tables = []

        self.ui.sendRequestButton.clicked.connect(self.request)
        self.ui.textEdit.setText(
            "SELECT table_name FROM information_schema.tables;")
        self.ui.reloadLayersButton.clicked.connect(self.reloadLayers)
        self.ui.refreshStructureButton.clicked.connect(self.refreshStructure)
        self.ui.checkStructureButton.clicked.connect(self.checkStructure)
        self.ui.configureInterfaceButton.clicked.connect(
            self.configureInterface)
        self.dictLegendRefBySource = {}
        self.dictSourceRefByLegend = {}

        self.ui.textEdit.setStyle(QtGui.QStyleFactory.create('Motif'))
        self.center()

    def closeEvent(self, e):
        self.db.close()
        self.db.removeDatabase("first2")

    def keyPressEvent(self, e):
        if e.key() == QtCore.Qt.Key_Escape:
            self.close()

    def configureInterface(self):
        att = 'remark'
        self.tabs = []
        self.groups = []
        self.widgets = []
        for name, layer in QgsMapLayerRegistry.instance().mapLayers(
        ).iteritems():
            layer.clearAttributeEditorWidgets()
            layer.setEditorLayout(1)
            self.tabs.append(QgsAttributeEditorContainer("Tab 1", layer))
            fields = layer.pendingFields()
            for field in fields:
                self.widgets.append(QgsAttributeEditorField(field.name()\
                                    , layer.fieldNameIndex(field.name())\
                                    , layer))
                self.tabs[-1].addChildElement(self.widgets[-1])
            layer.addAttributeEditorWidget(self.tabs[-1])

    def getNodes(self, node, parent=None):
        if parent == 'source' or parent == 'name' or parent == 'symbology':
            text = node.firstChild().toText().data()
        else:
            text = []
            n = node.firstChild()
            while (not n.isNull()):
                t = n.nodeName()
                if n.nodeType() == 1:
                    rec = self.getNodes(n, t)
                    if n.toElement().hasAttribute('groupname'):
                        name = n.toElement().attribute('groupname')
                        group = [t, rec, name]
                        self.barCount += 1
                    else:
                        group = [t, rec]
                    text.append(group)
                n = n.nextSibling()
        return text

    def addGroups(self, list, parent=None):
        for group1 in list:
            if group1[0] == 'groupe':
                if len(group1) > 2:
                    index = self.iface.legendInterface().addGroup(
                        group1[2], True, parent)
                else:
                    index = self.iface.legendInterface().addGroup(
                        group1[0], True, parent)
                self.addGroups(group1[1], index)
            elif group1[0] == 'layer':
                dicInfoLayer = dict((key, value) for (key, value) in group1[1])
                if 'source' not in dicInfoLayer:
                    QMessageBox.warning(QDialog(), 'configuration',
                                        "Source not defined for a layer")
                    raise IOError
                source = dicInfoLayer['source']
                layer = self.loadTable(source)
                self.iface.legendInterface().moveLayer(layer, parent)
                if 'name' in dicInfoLayer:
                    nomTemp = dicInfoLayer['name']
                    nom = ''.join(chr(ord(c)) for c in nomTemp).decode('utf8')
                    layer.setLayerName(nom)
                if 'symbology' in dicInfoLayer:
                    style = dicInfoLayer['symbology']
                    self.getSymbology(layer, style)

    def reloadLayers(self):
        self.tables = []
        self.vlayer = []
        self.barCount = 0
        self.loadSymbologies()
        # Clear legend
        for name, layer in QgsMapLayerRegistry.instance().mapLayers(
        ).iteritems():
            QgsMapLayerRegistry.instance().removeMapLayer(name)
        while self.iface.legendInterface().groupExists(0):
            self.iface.legendInterface().removeGroup(0)

        path = os.path.dirname(os.path.realpath(__file__))
        fName = path + "/config.xml"
        if not fName:
            return
        file = QFile(fName)
        if (not file.open(QIODevice.ReadOnly | QIODevice.Text)):
            QMessageBox.warning(QDialog(),'Application', "Cannot read file %s :\n%s."\
                                %(file.fileName(),file.errorString()))
            return False
        else:
            doc = QtXml.QDomDocument("EnvironmentML")
            if (not doc.setContent(file)):
                file.close()
                QMessageBox.warning(self, "Error", "Could not parse xml file.")
            file.close()
            root = doc.documentElement()
            if (root.tagName() != "config"):
                QMessageBox.warning(
                    self, "Error",
                    "Could not parse xml file. Root Element must be <kml/>.")
            else:
                #try:
                t = self.getNodes(root)
                self.initProgressBar()  # create progressbar
                self.addGroups(t)
                #except:
                #    QMessageBox.warning(self,"Configuration failed","Failed to read the configuration file correctly")
                #    return
        self.bar = None
        QtGui.QMessageBox.information(QtGui.QDialog(), "Reloading layers",
                                      "Layers are succesfully reloaded")

    def loadSymbologies(self):
        text = "SELECT id, stylename, description FROM public.layer_styles"
        query = QSqlQuery(self.db)
        test = query.exec_(text)
        self.dicStyle = {}
        while (query.next()):
            i = 0
            self.dicStyle[query.value(1)] = query.value(0)

    def getSymbology(self, layer, styleName):
        errorMsg = ''
        print self.dicStyle
        if styleName in self.dicStyle:
            id = self.dicStyle[styleName]
            styleText = layer.getStyleFromDatabase(str(id), errorMsg)
            layer.applyNamedStyle(styleText, errorMsg)
        else:
            QMessageBox.warning(
                QDialog(), 'Configuration',
                "Symbology %s not present in database" % styleName)
            raise IOError

    def loadTable(self, table):
        QtCore.QCoreApplication.processEvents()
        uri = QgsDataSourceURI()
        # set host name, port, database name, username and password
        uri.setConnection(self.db.hostName(), str(self.db.port()),
                          self.db.databaseName(), self.db.userName(),
                          self.db.password())
        if table.startswith('od_'):
            uri.setDataSource("distribution", table, 'geometry')
        else:
            uri.setDataSource("distribution", table, None)
        self.vlayer.append(QgsVectorLayer(uri.uri(), table, "postgres"))
        inst = QgsMapLayerRegistry.instance()
        legend = self.iface.legendInterface()
        layer = inst.addMapLayer(self.vlayer[-1])
        legend.setLayerVisible(self.vlayer[-1], False)
        self.iface.mapCanvas().refresh()
        self.bar.progressBar.setValue(self.progress)
        self.progress += self.barInc
        return layer

    def refreshProjectInfo(self):
        self.dictLegendRefBySource = {}
        self.dictSourceRefByLegend = {}
        self.changeCount = 0
        for name, layer in QgsMapLayerRegistry.instance().mapLayers(
        ).iteritems():
            layerSource = layer.source().split(' ')
            for sourceElmt in layerSource:
                if sourceElmt.startswith('table'):
                    tableName = sourceElmt.split('"')[-2]
                    self.dictLegendRefBySource[tableName] = layer.name()
                    self.dictSourceRefByLegend[layer.name()] = tableName

        self.tables = []
        text = "SELECT table_name FROM information_schema.tables WHERE table_schema='distribution';"
        query = QSqlQuery(self.db)
        test = query.exec_(text)
        while (query.next()):
            i = 0
            while (query.value(i) is not None):
                val = str(query.value(i))
                #if val.startswith('od_'):
                self.tables.append(val)
                i = i + 1

    def refreshStructure(self):
        self.refreshProjectInfo()
        # dicAttributs:= dic[nom de couche] = liste d'attributs
        # dicCombo := dic[nom de couche, attribut] = liste de valeurs
        # dicType := dic[nom de couche, attribut] = type
        # self.dicStructure := dic[nom de couche, attribut] = [Widget,widgetName, type, valeur(s)]
        while True:
            previous_modif = self.changeCount
            dicAttributs, dicType = self.getDicAttributsAndType()
            dicCombo = self.getDicCombo()
            dicStructure = self.getDicStructure(dicAttributs, dicCombo,
                                                dicType)
            shipList = self.getShipList(dicAttributs, dicStructure)
            self.checkStructureDia = checkStructureDialog(shipList)
            shipList = None
            self.checkStructureDia.setApplyAll()
            self.getActions()
            self.checkStructureDia = None
            self.createActionDictionary()
            self.applyActions()
            if previous_modif == self.changeCount:
                break
        QtGui.QMessageBox.information(
            QtGui.QDialog(), "Change in QGIS project",
            "Number of modifications applied: %s" % self.changeCount)

    def checkStructure(self):
        self.refreshProjectInfo()
        # dicAttributs:= dic[nom de couche] = liste d'attributs
        # dicCombo := dic[nom de couche, attribut] = liste de valeurs
        # dicType := dic[nom de couche, attribut] = type
        # self.dicStructure := dic[nom de couche, attribut] = [Widget,widgetName, type, valeur(s)]
        dicAttributs, dicType = self.getDicAttributsAndType()
        dicCombo = self.getDicCombo()
        dicStructure = self.getDicStructure(dicAttributs, dicCombo, dicType)
        shipList = self.getShipList(dicAttributs, dicStructure)
        self.checkStructureDia = checkStructureDialog(shipList)
        shipList = None
        self.checkStructureDia.show()
        result = self.checkStructureDia.exec_()

        if result:
            self.getActions()
            self.checkStructureDia = None
            self.createActionDictionary()
            self.applyActions()
            QtGui.QMessageBox.information(
                QtGui.QDialog(), "Change in QGIS project",
                "Number of modifications applied: %s" % self.changeCount)

    def createActionDictionary(self):
        self.actionDictionary = {}
        for ship in self.actionShips:
            element = ship.elmt
            elementConfig = ship.dbState
            if (ship.layer, ship.attribute) in self.actionDictionary:
                self.actionDictionary[ship.layer, ship.attribute].append(
                    [element, elementConfig])
            else:
                self.actionDictionary[ship.layer, ship.attribute] = [[
                    element, elementConfig
                ]]

    def applyActions(self):
        tables = []
        for key in self.actionDictionary:
            if key[0] not in tables:
                tables.append(key[0])
        for nameLayer, layer in QgsMapLayerRegistry.instance().mapLayers(
        ).iteritems():
            if layer.type() == 0:
                # The name of the layer is not equal to the name of his data source table
                if layer.name() not in self.dictSourceRefByLegend:
                    continue
                name = self.dictSourceRefByLegend[layer.name()]
                if name in tables:
                    # layer.setEditorLayout(0)
                    fields = layer.pendingFields()
                    id = 0
                    for field in fields:
                        if (name, field.name()) in self.actionDictionary:
                            for sheep in self.actionDictionary[name,
                                                               field.name()]:
                                self.changeCount += 1
                                element = sheep[0]
                                elementConfig = sheep[1]
                                if element == 'widget':
                                    layer.setEditorWidgetV2(id, elementConfig)
                                elif element == 'isEditable':
                                    booleanValue = ast.literal_eval(
                                        elementConfig)
                                    layer.setFieldEditable(id, booleanValue)
                                elif element == 'isMultiline':
                                    config = layer.editorWidgetV2Config(id)
                                    booleanValue = ast.literal_eval(
                                        elementConfig)
                                    config[u'IsMultiline'] = booleanValue
                                    config[u'UseHtml'] = False
                                    layer.setEditorWidgetV2Config(id, config)
                                elif element == 'RelationLayer':
                                    config = layer.editorWidgetV2Config(id)
                                    config[u'Layer'] = elementConfig
                                    layer.setEditorWidgetV2Config(id, config)
                                elif element == 'RelationKey':
                                    config = layer.editorWidgetV2Config(id)
                                    config[u'Key'] = elementConfig
                                    layer.setEditorWidgetV2Config(id, config)
                                elif element == 'RelationValue':
                                    config = layer.editorWidgetV2Config(id)
                                    config[u'Value'] = elementConfig
                                    layer.setEditorWidgetV2Config(id, config)
                                if elementConfig == 'DateTime':
                                    config = layer.editorWidgetV2Config(id)
                                    config[u'display_format'] = u'dd/MM/yy'
                                    config[u'field_format'] = 'yyyy-MM-dd'
                                    config[u'calendar_popup'] = True
                                    layer.setEditorWidgetV2Config(id, config)
                                # print layer.editorWidgetV2Config(id)
                            # All fields are, by default, editable. Then depending on type, we will change it!
                        id += 1
        return

    def getActions(self):
        # As the order of columns can change,
        # we have to re-extract all information from the model
        self.actionShips = []
        nRow = self.checkStructureDia.model.rowCount()
        nCol = self.checkStructureDia.model.columnCount()
        for row in xrange(nRow):
            index = self.checkStructureDia.model.index(row, 5)
            apply = self.checkStructureDia.model.data(index)
            if apply:
                val = ['' for i in range(nCol)]
                for col in xrange(nCol):
                    index = self.checkStructureDia.model.index(row, col)
                    val[col] = self.checkStructureDia.model.data(index)
                newActionShip = Ship(val[0], val[1], val[2], val[3], val[4])
                self.actionShips.append(newActionShip)

    def getShipList(self, dicAttributs, dicStructure):
        shipList = []
        for nameLayer, layer in QgsMapLayerRegistry.instance().mapLayers(
        ).iteritems():
            if layer.type() == 0:
                if layer.name() not in self.dictSourceRefByLegend:
                    continue
                name = self.dictSourceRefByLegend[layer.name()]
                if name in self.tables:
                    #layer.setEditorLayout(0)
                    fields = layer.pendingFields()
                    id = 0
                    for field in fields:
                        if field.name() in dicAttributs[name]:
                            db_widget = dicStructure[name, field.name()][0]
                            values = dicStructure[name, field.name()][3]
                            type = dicStructure[name, field.name()][2]
                            project_widget = layer.editorWidgetV2(id)
                            # All fields are, by default, editable. Then depending on type, we will change it!
                            project_isEditable = layer.fieldEditable(id)
                            db_isEditable = True
                            project_config = layer.editorWidgetV2Config(id)
                            solution = ''
                            if db_widget == 'ValueRelation':
                                for nLayer, vlayer in QgsMapLayerRegistry.instance(
                                ).mapLayers().iteritems():
                                    try:
                                        if self.dictSourceRefByLegend[
                                                vlayer.name()] == values[0]:
                                            clayer = nLayer
                                    except:
                                        continue
                                if ('value_fr' not in dicAttributs[values[0]]) \
                                    and ('name' not in dicAttributs[values[0]])\
                                    and  ('tr_value_fr' not in dicAttributs[values[0]]) :
                                    db_widget = 'TextEdit'
                                    db_isEditable = False
                                elif project_widget == 'ValueRelation':
                                    #Widget is ok, but we will check the configuration here
                                    #first, check the related layer
                                    if 'Layer' not in project_config:
                                        solution = 'Set layer of value relation'
                                        newship = Ship(str(name),str(field.name()),\
                                            'RelationLayer',str('None'),\
                                            str(clayer), solution)
                                        shipList.append(newship)
                                    elif project_config[u'Layer'] != clayer:
                                        solution = 'Change layer of value relation'
                                        newship = Ship(str(name),str(field.name()),\
                                            'RelationLayer',str(project_config[u'Layer']),\
                                            str(clayer), solution)
                                        shipList.append(newship)
                                    # then check the related key of the layer is ok
                                    if 'Key' not in project_config:
                                        solution = 'Set key of value relation'
                                        newship = Ship(str(name),str(field.name()),\
                                            'RelationKey',str('None'),\
                                            str(values[1]), solution)
                                        shipList.append(newship)
                                    elif project_config[u'Key'] != str(
                                            values[1]):
                                        solution = 'Change key of value relation'
                                        newship = Ship(str(name),str(field.name()),\
                                            'RelationKey',str(project_config[u'Key']),\
                                            str(values[1]), solution)
                                        shipList.append(newship)
                                    # Then check the value of the value is ok
                                    if 'Value' not in project_config:
                                        if 'value_fr' in dicAttributs[
                                                values[0]]:
                                            old_value = 'None'
                                            new_value = 'value_fr'
                                            solution = 'Change the value Relation'
                                        elif 'tr_value_fr' in dicAttributs[
                                                values[0]]:
                                            old_value = 'None'
                                            new_value = 'tr_value_fr'
                                            solution = 'Change the value Relation'
                                        elif 'name' in dicAttributs[values[0]]:
                                            old_value = 'None'
                                            new_value = 'name'
                                            solution = 'Change the value Relation'
                                        else:
                                            old_value = 'None'
                                            new_value = 'None'
                                            solution = 'No solution, Set manually value of value relation'
                                        newship = Ship(str(name),str(field.name()),\
                                            'RelationValue',old_value,\
                                            new_value, solution)
                                        shipList.append(newship)
                                    # Hypothesis: no table have both value_fr and name attribute
                                    elif project_config[
                                            u'Value'] != 'value_fr' and project_config[
                                                u'Value'] != 'name' and project_config[
                                                    u'Value'] != 'tr_value_fr':
                                        solution = 'Change value of value relation'
                                        if 'value_fr' in dicAttributs[
                                                values[0]]:
                                            old_value = project_config[
                                                u'Value']
                                            new_value = 'value_fr'
                                        elif 'tr_value_fr' in dicAttributs[
                                                values[0]]:
                                            old_value = project_config[
                                                u'Value']
                                            new_value = 'tr_value_fr'
                                        else:
                                            old_value = 'None'
                                            new_value = 'None'
                                            solution = 'No solution, Set manually value of value relation'
                                        newship = Ship(str(name),str(field.name()),\
                                            'RelationValue',old_value,\
                                            new_value, solution)
                                        shipList.append(newship)

                            if project_widget != db_widget:
                                # Check of Valuerelation, DateTime (date), CheckBox (boolean) and TextEdit
                                if project_widget == 'ValueRelation' and db_widget == 'TextEdit':
                                    solution = 'No solution (Foreign key may be missing in DB)'
                                else:
                                    solution = 'Change current widget with the proposed one'
                                newship = Ship(str(name),
                                               str(field.name()), 'widget',
                                               str(project_widget), db_widget,
                                               solution)
                                shipList.append(newship)
                                solution = ''
                            if type == 'longText':
                                #layer.setFieldMultiLine(id,True)
                                solution = 'Set field multiline'
                                if 'IsMultiline' not in project_config:
                                    newship = Ship(str(name),str(field.name()),\
                                   'isMultiline',str(False),\
                                   str(True), solution)
                                    shipList.append(newship)
                                elif project_config['IsMultiline'] != True:
                                    newship = Ship(str(name),str(field.name()),\
                                               'isMultiline',str(project_config['IsMultiline']),\
                                               str(True))
                                    shipList.append(newship)
                            if field.name() == 'id':
                                db_isEditable = False
                                solution = 'Set field non editable'
                            if field.name().startswith('tr_'):
                                db_isEditable = False
                                solution = 'Set field non editable'
                            if project_isEditable != db_isEditable:
                                if solution == '':
                                    solution = 'Change editability of the field'
                                newship = Ship(str(name),str(field.name()),\
                                               'isEditable',str(project_isEditable),\
                                               str(db_isEditable), solution)
                                shipList.append(newship)
                            id += 1
        return shipList

    def updateStructure(self, dicAttributs, dicStructure):
        for nameLayer, layer in QgsMapLayerRegistry.instance().mapLayers(
        ).iteritems():
            if layer.type() == 0:
                if layer.name() not in self.dictSourceRefByLegend:
                    continue
                name = self.dictSourceRefByLegend[layer.name()]
                if name in self.tables:
                    layer.setEditorLayout(0)
                    fields = layer.pendingFields()
                    id = 0
                    for field in fields:
                        if field.name() in dicAttributs[name]:
                            widget = dicStructure[name, field.name()][0]
                            values = dicStructure[name, field.name()][3]
                            type = dicStructure[name, field.name()][2]
                            layer.setEditorWidgetV2(id, widget)
                            # All fields are, by default, editable. Then depending on type, we will change it!
                            layer.setFieldEditable(id, True)
                            config = {}
                            # DPFE rule
                            if field.name().startswith(
                                    'tr_') or type == 'primaryKey':
                                layer.setEditorWidgetV2(id, 'TextEdit')
                                layer.setFieldEditable(id, False)

                            if widget == 'ValueRelation':
                                for nameLayer, vlayer in QgsMapLayerRegistry.instance(
                                ).mapLayers().iteritems():
                                    try:
                                        if self.dictSourceRefByLegend[
                                                vlayer.name()] == values[0]:
                                            clayer = nameLayer
                                    except:
                                        continue
                                config = {}
                                config[u'Layer'] = clayer
                                config[u'Key'] = str(values[1])
                                config[u'FilterExpression'] = None
                                config[u'AllowMulti'] = False
                                config[u'AllowNull'] = True
                                config[u'OrderByValue'] = False

                                if 'value_fr' in dicAttributs[values[0]]:
                                    config[u'Value'] = 'value_fr'
                                elif 'tr_value_fr' in dicAttributs[values[0]]:
                                    config[u'Value'] = 'tr_value_fr'
                                elif 'name' in dicAttributs[values[0]]:
                                    config[u'Value'] = 'name'
                                else:
                                    # DPFE RULE
                                    config[u'Value'] = str(values[1])

                                    #QWAT RULE
                                    # All fields which are foreign key but not value or name are triggered
                                    # Triggerd are simply TextEdit widgets, non editables
                                    #layer.setEditorWidgetV2(id,'TextEdit')
                                    #layer.setFieldEditable(id,False)

                            if type == 'longText':
                                #print dir(layer)
                                #layer.setFieldMultiLine(id,True)
                                config = {}
                                config[u'UseHtml'] = False
                                config[u'IsMultiline'] = True
                            if type == 'date':
                                config[u'display_format'] = u'dd/MM/yy'
                                config[u'field_format'] = 'yyyy-MM-dd'
                                config[u'calendar_popup'] = True
                            layer.setEditorWidgetV2Config(id, config)
                            id += 1
        return

    def getDicStructure(self, dAtt, dCom, dTyp):
        dicStructure = {}
        for table, attributes in dAtt.items():
            for att in attributes:
                type = dTyp[table, att]
                if (table, att) in dCom:
                    widget = 'ValueRelation'
                    values = dCom[table, att]
                elif type == 'primaryKey':
                    widget = 'TextEdit'
                    values = None
                elif type == 'boolean':
                    # It is important to have the bool check after the foreignKey check.
                    # Because some bollean fields-type need a combo box (Null, True or False)
                    widget = 'CheckBox'
                    values = False
                elif type == 'date':
                    widget = 'DateTime'
                elif att.startswith('geometry'):
                    widget = 'Hidden'
                else:
                    widget = 'TextEdit'
                    values = None
                widgetName = widget + '_' + att
                dicStructure[table, att] = [widget, widgetName, type, values]
        return dicStructure

    def getDicAttributsAndType(self):
        dicAtt = {}
        dicType = {}
        for table in self.tables:
            textPM = """SELECT pg_attribute.attname
FROM pg_index, pg_class, pg_attribute 
WHERE 
  pg_class.oid = 'distribution.%s'::regclass AND
  indrelid = pg_class.oid AND
  pg_attribute.attrelid = pg_class.oid AND 
  pg_attribute.attnum = any(pg_index.indkey)
  AND indisprimary;""" % table
            queryPM = QSqlQuery(self.db)
            textPM = queryPM.exec_(textPM)
            while (queryPM.next()):
                primaryKey = queryPM.value(0)
                print primaryKey
            text = "SELECT column_name, data_type\
    FROM information_schema.columns \
    WHERE table_name = '%s' \
    ORDER BY ordinal_position;" % table
            query = QSqlQuery(self.db)
            test = query.exec_(text)
            attributesList = []
            while (query.next()):
                attributesList.append(query.value(0))
                if query.value(0) == primaryKey:
                    dicType[table, query.value(0)] = 'primaryKey'
                    # for text fields, check if there are multilines
                elif query.value(1) == u'text' or query.value(
                        1) == u'character varying':
                    textLen = """
                    SELECT max (length) 
                    FROM (SELECT character_length(%s) 
                        AS length FROM distribution.%s 
                        GROUP BY id) AS subquery;""" % (query.value(0), table)
                    queryLen = QSqlQuery(self.db)
                    testLen = queryLen.exec_(textLen)
                    while (queryLen.next()):
                        if queryLen.value(0) > 40:
                            dicType[table, query.value(0)] = 'longText'
                        else:
                            dicType[table, query.value(0)] = query.value(1)
                else:
                    dicType[table, query.value(0)] = query.value(1)
            dicAtt[table] = attributesList
            print attributesList
        return dicAtt, dicType

    def getDicCombo(self):
        dicCombo = {}
        for table in self.tables:
            text2 = """SELECT
    tc.constraint_name, tc.table_name, kcu.column_name, 
    ccu.table_name AS foreign_table_name,
    ccu.column_name AS foreign_column_name 
    FROM 
    information_schema.table_constraints AS tc
    JOIN information_schema.key_column_usage AS kcu
      ON tc.constraint_name = kcu.constraint_name
    JOIN information_schema.constraint_column_usage AS ccu
      ON ccu.constraint_name = tc.constraint_name
WHERE constraint_type = 'FOREIGN KEY' AND tc.table_name='%s';""" % table
            query2 = QSqlQuery(self.db)
            test = query2.exec_(text2)
            while (query2.next()):
                dicCombo[str(query2.value(1)),
                         str(query2.value(2))] = [
                             query2.value(3), query2.value(4)
                         ]
        return dicCombo

    def request(self):
        text = self.ui.textEdit.toPlainText()
        query = QSqlQuery(self.db)
        test_pass = query.exec_(text)
        print text
        if test_pass:
            while (query.next()):
                i = 0
                text = []
                while query.value(i) is not None:

                    #if val.startswith('od_'):
                    text.append(query.value(i))
                    i = i + 1
                if text != []:
                    print text
        else:
            QtGui.QMessageBox.critical(QtGui.QDialog(), "Query",
                                       "Invalid Query")

        # Get columns on which a trigger is defined (The trigger is released when event on this column happened)
        # These columns are therefore not the targets of triggers !
        """SELECT * FROM information_schema.triggered_update_columns WHERE event_object_table = 'od_pipe';"""

    def center(self):
        qr = self.frameGeometry()
        cp = QtGui.QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def initProgressBar(self):

        self.bar = progress_bar()
        self.bar.center()
        self.bar.show()
        self.bar.progressBar = self.bar.ui_progbar.progressBar
        self.bar.progressBar.setValue(0)
        self.progress = 0
        self.barInc = 1.0 / self.barCount * 100.0
        self.barInc = 1.0 / self.barCount * 100.0