Ejemplo n.º 1
0
    def sqlInsert(self, t, fL, vL, connName="default"):
        """
        Realiza la inserción de un registro en una tabla mediante un objeto FLSqlCursor

        @param t Nombre de la tabla
        @param fL Lista separada con comas de los nombres de los campos
        @param vL Lista separada con comas de los valores correspondientes
        @param connName Nombre de la conexion
        @return Verdadero en caso de realizar la inserción con éxito, falso en cualquier otro caso
        """
        from pineboolib.fllegacy.FLSqlCursor import FLSqlCursor

        fL = fL.split(",")
        vL = vL.split(",")

        if not len(fL) == len(vL):
            return False

        c = FLSqlCursor(t, True, connName)
        c.setModeAccess(FLSqlCursor.Insert)
        c.refreshBuffer()

        i = 0
        for f in fL:
            if vL[i] is None:
                c.bufferSetNull(f)
            else:
                c.setValueBuffer(f, vL[i])

            i = i + 1

        return c.commitBuffer()
Ejemplo n.º 2
0
    def initCursor(self):
        filtro = None
        self._cursorLoaded = True
        if not self._foreignField:
            return
        if not self._fieldRelation:
            return
        if not self._tableName:
            return

        if self._loaded:

            tipo = self._cursor.model().fieldType(self._fieldRelation)
            foranea = self._parent.parentWidget().cursor().valueBuffer(
                self._foreignField)
            if foranea is None:
                #print("FLTable(%s): campo foraneo \"%s.%s\" no encontrado." % (self._tableName,self._parent.parentWidget()._cursor.table(), self._foreignField))
                return
            if tipo is "uint":
                self._foreignFilter = "%s = %s" % (
                    self._fieldRelation,
                    self._parent.parentWidget().cursor().valueBuffer(
                        self._foreignField))
            else:
                self._foreignFilter = "%s = '%s'" % (
                    self._fieldRelation,
                    self._parent.parentWidget().cursor().valueBuffer(
                        self._foreignField))

            #print("Filtro:%s" % filtro)
            self._cursor.setMainFilter(self._foreignFilter)
            self._cursor.refresh()
        else:
            self._cursor = FLSqlCursor(self._tableName)
Ejemplo n.º 3
0
    def __init__(self, *args, **kwargs):
        parent = None
        name = None
        action = None

        if isinstance(args[0], str):
            # @param actionName Nombre de la acción asociada al formulario

            if len(args) == 2:
                parent = args[1]

            name = args[0]

            self.setAction(name)
            action = self.action
            if action is None:
                return

            table = action.table
            if not table:
                return

            self.cursor_ = FLSqlCursor(table, True, "default", None, None,
                                       self)
            self.accepted_ = False

        elif isinstance(args[0], FLSqlCursor):
            # @param cursor Objeto FLSqlCursor para asignar a este formulario
            # @param actionName Nombre de la acción asociada al formulario

            if len(args) == 3:
                parent = args[2]
                name = args[1]

            self.cursor_ = args[0]
            action = self.cursor_._action

        elif len(args) == 2:
            action = args[0]
            parent = args[1]
            name = action.name()
            self.cursor_ = FLSqlCursor(action.table(), True, "default", None,
                                       None, self)

        if not parent:
            parent = QtWidgets.QApplication.activeModalWidget()

        super(FLFormSearchDB, self).__init__(parent, action, load=True)
        self.setFocusPolicy(QtCore.Qt.NoFocus)

        if not name:
            print("FLFormSearchDB : Nombre de acción vacío")
            return

        if not action:
            print("FLFormSearchDB : No existe la acción", name)
            return

        self.eventloop = QtCore.QEventLoop()
Ejemplo n.º 4
0
    def init(self):
        """
        Acciones de inicialización.
        """
        self.initCount_ = self.initCount_ + 1
        self.createSystemTable("flmetadata")
        self.createSystemTable("flseqs")

        if not self.db_.dbAux():
            return

        q = FLSqlQuery(None, self.db_.dbAux())
        # q.setForwardOnly(True)

        self.createSystemTable("flsettings")
        if not q.exec_("SELECT * FROM flsettings WHERE flkey = 'sysmodver'"):

            if pineboolib.project.conn.driver().cascadeSupport():
                q.exec_("DROP TABLE flsettings CASCADE")
            else:
                q.exec_("DROP TABLE flsettings")

            self.createSystemTable("flsettings")

        if not self.dictKeyMetaData_:
            self.dictKeyMetaData_ = {}
            # self.dictKeyMetaData_.setAutoDelete(True)
        else:
            self.dictKeyMetaData_.clear()

        q.exec_("SELECT tabla,xml FROM flmetadata")
        while q.next():
            self.dictKeyMetaData_[q.value(0)] = q.value(1)

        q.exec_("SELECT * FROM flsettings WHERE flkey = 'sysmodver'")
        if not q.next():

            if pineboolib.project.conn.driver().cascadeSupport():
                q.exec_("DROP TABLE flmetadata CASCADE")
            else:
                q.exec_("DROP TABLE flmetadata")

            self.createSystemTable("flmetadata")

            c = FLSqlCursor("flmetadata", True, self.db_.dbAux())
            for key, value in self.dictKeyMetaData_:
                buffer = c.primeInsert()
                buffer.setValue("tabla", key)
                buffer.setValue("xml", value)
                c.insert()

        if not self.cacheMetaData_:
            self.cacheMetaData_ = []

        if not self.cacheAction_:
            self.cacheAction_ = []

        if not self.cacheMetaDataSys_:
            self.cacheMetaDataSys_ = []
Ejemplo n.º 5
0
    def initCursor(self):
        filtro = None
        self._cursorLoaded = True
        if not self._foreignField:
            return
        if not self._fieldRelation:
            return
        if not self._tableName:
            return
        
        if self._loaded:   

            tipo = self._cursor.model().fieldType(self._fieldRelation)
            foranea = self._parent.parentWidget().cursor().valueBuffer(self._foreignField)
            if foranea is None:
                #print("FLTable(%s): campo foraneo \"%s.%s\" no encontrado." % (self._tableName,self._parent.parentWidget()._cursor.table(), self._foreignField))
                return
            if tipo is "uint":
                self._foreignFilter = "%s = %s" % (self._fieldRelation, self._parent.parentWidget().cursor().valueBuffer(self._foreignField))
            else:
                self._foreignFilter = "%s = '%s'"  % (self._fieldRelation, self._parent.parentWidget().cursor().valueBuffer(self._foreignField))
            
            #print("Filtro:%s" % filtro)
            self._cursor.setMainFilter(self._foreignFilter)
            self._cursor.refresh()
        else:
            self._cursor = FLSqlCursor(self._tableName)
Ejemplo n.º 6
0
    def init(self):
        self.initCount_ = self.initCount_ + 1
        tmpTMD = self.createSystemTable("flmetadata")
        tmpTMD = self.createSystemTable("flseqs")

        if not self.db_.dbAux():
            return

        q = FLSqlQuery(None, self.db_.dbAux())
        q.setForwardOnly(True)

        tmpTMD = self.createSystemTable("flsettings")
        if not q.exec_("SELECT * FROM flsettings WHERE flkey = 'sysmodver'"):
            q.exec_("DROP TABLE flsettings CASCADE")
            tmpTMD = self.createSystemTable("flsettings")

        if not self.dictKeyMetaData_:
            self.dictKeyMetaData_ = {}
            #self.dictKeyMetaData_.setAutoDelete(True)
        else:
            self.dictKeyMetaData_.clear()

        q.exec_("SELECT tabla,xml FROM flmetadata")
        while q.next():
            self.dictKeyMetaData_.insert(q.value(0), q.value(1))

        q.exec_("SELECT * FROM flsettings WHERE flkey = 'sysmodver'")
        if not q.next():
            q.exec_("DROP TABLE flmetadata CASCADE")
            tmpTMD = self.createSystemTable("flmetadata")

            c = FLSqlCursor("flmetadata", True, self.db_.dbAux())
            for key, value in self.dictKeyMetaData_:
                buffer = c.primeInsert()
                buffer.setValue("tabla", key)
                buffer.setValue("xml", value)
                c.insert()

        if not self.cacheMetaData_:
            self.cacheMetaData_ = []

        if not self.cacheAction_:
            self.cacheAction_ = []

        if not self.cacheMetaDataSys_:
            self.cacheMetaDataSys_ = []
Ejemplo n.º 7
0
    def inicialize2(self, *args, **kwargs):
        actionName = str(args[0][0])
        parent = args[0][1]
        f = args[1]

        if parent:
            self.parent_ = parent
        else:
            self.parent_ = QtGui.QWidget(pineboolib.project.mainWidget(),
                                         actionName, f)

        self.layout = None
        self.mainWidget_ = None
        self.layoutButtons = None
        self.pushButtonCancel = None
        self.showed = False
        self.iface = None
        self.oldCursorCtxt = None
        self.isClosing_ = False
        self.initFocusWidget_ = None
        self.oldFormObj = None
        self.accepted_ = False

        self.setFocusPolicy(QtGui.QWidget.NoFocus)

        if actionName.isEmpty():
            self.action_ = None
            print(FLUtil.translate("sys", "FLFormDB : Nombre de acción vacío"))
            return
        else:
            self.action_ = FLSqlConnections.database().manager().action(
                actionName)

        if not self.action_:
            print(
                FLUtil.translate(
                    "sys", "FLFormDB : No existe la acción %s" % actionName))
            return

        self.cursor_ = FLSqlCursor(self.action_.table(), True, "default", 0, 0,
                                   self)
        self.name_ = self.action_.name()

        self.initForm()
Ejemplo n.º 8
0
    def cleanupMetaData(self):
        """
        Limpieza la tabla flmetadata, actualiza el cotenido xml con el de los fichero .mtd
        actualmente cargados
        """
        # util = FLUtil()
        if not self.existsTable("flfiles") or not self.existsTable(
                "flmetadata"):
            return

        q = FLSqlQuery(None, self.db_.dbAux())
        c = FLSqlCursor("flmetadata", True, self.db_.dbAux())
        buffer = None
        table = ""

        # q.setForwardOnly(True)
        # c.setForwardOnly(True)

        if not self.dictKeyMetaData_:
            self.dictKeyMetaData_ = {}
        else:
            self.dictKeyMetaData_.clear()

        self.loadTables()
        self.db_.managerModules().loadKeyFiles()
        self.db_.managerModules().loadAllIdModules()
        self.db_.managerModules().loadIdAreas()

        q.exec_("SELECT tabla, xml FROM flmetadata")
        while q.next():
            self.dictKeyMetaData_[str(q.value(0))] = str(q.value(1))

            q.exec_(
                "SELECT nombre, sha FROM flfiles WHERE nombre LIKE '%.mtd'")
            while q.next():
                table = str(q.value(0))
                table = table.replace(".mtd", "")
                if not self.existsTable(table):
                    self.createTable(table)

                tmd = self.metadata(table)
                if not tmd:
                    qWarning("FLManager::cleanupMetaDAta " + QApplication.tr(
                        "No se ha podido crear los metadatatos para la tabla %1"
                    ).arg(table))

                c.select("tabla='%s'" % table)
                if c.next():
                    buffer = c.primeUpdate()
                    buffer.setValue("xml", str(q.value(1)))
                    c.update()

                self.dictKeyMetaData_[table] = str(q.value(1))
Ejemplo n.º 9
0
    def __init__(self, *args, **kwargs):
        parent = None
        name = None
        action = None

        if isinstance(args[0], str):
            #@param actionName Nombre de la acción asociada al formulario

            if len(args) == 2:
                parent = args[1]

            name = args[0]

            self.cursor_ = FLSqlCursor(name, True, "default", None, None, self)
            action = self.cursor_.action()
            self.accepted_ = False

        elif isinstance(args[0], FLSqlCursor):
            #@param cursor Objeto FLSqlCursor para asignar a este formulario
            #@param actionName Nombre de la acción asociada al formulario

            if len(args) > 2:
                action = args[1]
                name = action.name

            if len(args) == 3:
                parent = args[2]

            self.cursor_ = args[0]

        super(FLFormSearchDB, self).__init__(parent, action)
        self.setFocusPolicy(QtCore.Qt.NoFocus)

        if not name:
            print("FLFormSearchDB : Nombre de acción vacío")
            return

        if not action:
            print("FLFormSearchDB : No existe la acción", name)
            return

        self.initForm()
Ejemplo n.º 10
0
    def runTransaction(self, f, oParam):

        curT = FLSqlCursor("flfiles")
        curT.transaction(False)
        # gui = self.interactiveGUI()
        # if gui:
        #   AQS.Application_setOverrideCursor(AQS.WaitCursor);

        errorMsg = None
        try:
            valor = f(oParam)
            errorMsg = getattr(oParam, "errorMsg", None)
            if valor:
                curT.commit()
            else:
                curT.rollback()
                # if gui:
                #   AQS.Application_restoreOverrideCursor();
                if errorMsg is None:
                    self.warnMsgBox(
                        self.translate(u"Error al ejecutar la función"))
                else:
                    self.warnMsgBox(errorMsg)
                return False

        except Exception:
            curT.rollback()
            # if gui:
            #   AQS.Application_restoreOverrideCursor();
            if errorMsg is None:
                self.warnMsgBox(
                    self.translate(u"Error al ejecutar la función"))
            else:
                self.warnMsgBox(errorMsg)
            return False

        # if gui:
        #   AQS.Application_restoreOverrideCursor();
        return valor
Ejemplo n.º 11
0
    def init1(self, actionName, parent=None):
        self.setFocusPolicy(QtGui.QWidget.NoFocus)
        if actionName.isEmpty():
            self.action_ = False
            print(
                FLUtil.translate("app",
                                 "FLFormSearchDB : Nombre de acción vacío"))
            return
        else:
            self.action_ = FLSqlConnections.database().manager().action(
                actionName)
        if not self.action_:
            print(
                FLUtil.translate(
                    "app",
                    "FLFormSearchDB : No existe la acción %s" % actionName))
            return

        self.cursor_ = FLSqlCursor(self.action_.table(), True, "default", 0, 0,
                                   self)
        self.name_ = self.action_.name()

        self.initForm()
Ejemplo n.º 12
0
 def init1(self, actionName, parent = None):
     self.setFocusPolicy(QtGui.QWidget.NoFocus)
     if actionName.isEmpty():
         self.action_ = False
         print(FLUtil.translate("app","FLFormSearchDB : Nombre de acción vacío"))
         return
     else:
         self.action_ = FLSqlConnections.database().manager().action(actionName)
     if not self.action_:
         print(FLUtil.translate("app","FLFormSearchDB : No existe la acción %s" % actionName))
         return
     
     self.cursor_ = FLSqlCursor(self.action_.table(), True,"default", 0, 0, self)
     self.name_ = self.action_.name()
     
     self.initForm()
Ejemplo n.º 13
0
    def __init__(self, *args, **kwargs):
        parent = None
        name = None
        action = None
        
        if isinstance(args[0], str):
            #@param actionName Nombre de la acción asociada al formulario
            
            if len(args) == 2:
                parent = args[1]
            
            name = args[0]
             
            
            self.cursor_ = FLSqlCursor(name, True, "default", None, None, self)
            action = self.cursor_.action()
            self.accepted_ = False

        elif isinstance(args[0], FLSqlCursor):
            #@param cursor Objeto FLSqlCursor para asignar a este formulario
            #@param actionName Nombre de la acción asociada al formulario
            
            if len(args) > 2:
                action = args[1]
                name = action.name
                
            if len(args) == 3:
                parent = args[2]
            
            self.cursor_ = args[0]
        
        super(FLFormSearchDB,self).__init__(parent, action)
        self.setFocusPolicy(QtCore.Qt.NoFocus)
        
        if not name:
            print("FLFormSearchDB : Nombre de acción vacío")
            return
        
        if not action:
            print("FLFormSearchDB : No existe la acción", name)
            return


        
        self.initForm()
Ejemplo n.º 14
0
    def runTransaction(self, f, oParam):

        curT = FLSqlCursor("flfiles")
        curT.transaction(False)
        # gui = self.interactiveGUI()
        # if gui:
        #   AQS.Application_setOverrideCursor(AQS.WaitCursor);

        errorMsg = None
        try:
            valor = f(oParam)
            errorMsg = getattr(oParam, "errorMsg", None)
            if valor:
                curT.commit()
            else:
                curT.rollback()
                # if gui:
                #   AQS.Application_restoreOverrideCursor();
                if errorMsg is None:
                    self.warnMsgBox(self.translate(u"Error al ejecutar la función"))
                else:
                    self.warnMsgBox(errorMsg)
                return False

        except Exception:
            curT.rollback()
            # if gui:
            #   AQS.Application_restoreOverrideCursor();
            if errorMsg is None:
                self.warnMsgBox(self.translate(u"Error al ejecutar la función"))
            else:
                self.warnMsgBox(errorMsg)
            return False

        # if gui:
        #   AQS.Application_restoreOverrideCursor();
        return valor
Ejemplo n.º 15
0
    def inicialize2(self,*args, **kwargs):
        actionName = str(args[0][0])
        parent = args[0][1]
        f = args[1]

        if parent:
            self.parent_ = parent
        else:
            self.parent_ = QtGui.QWidget(pineboolib.project.mainWidget(), actionName, f)

        self.layout = None
        self.mainWidget_ = None
        self.layoutButtons = None
        self.pushButtonCancel = None
        self.showed = False
        self.iface = None
        self.oldCursorCtxt = None
        self.isClosing_ = False
        self.initFocusWidget_ = None
        self.oldFormObj = None
        self.accepted_ = False
    
        self.setFocusPolicy(QtGui.QWidget.NoFocus)
    
        if actionName.isEmpty():
            self.action_ = None
            print(FLUtil.translate("sys","FLFormDB : Nombre de acción vacío"))
            return
        else:
            self.action_ = FLSqlConnections.database().manager().action(actionName)
        
        if not self.action_:
            print(FLUtil.translate("sys","FLFormDB : No existe la acción %s" % actionName))
            return
        
        self.cursor_ = FLSqlCursor(self.action_.table(), True, "default", 0, 0, self)
        self.name_ = self.action_.name()
        
        self.initForm()
Ejemplo n.º 16
0
    def sqlDelete(self, t, w, connName="default"):
        """
        Borra uno o más registros en una tabla mediante un objeto FLSqlCursor

        @param t Nombre de la tabla
        @param w Sentencia where para identificar los registros a borrar.
        @param connName Nombre de la conexion
        @return Verdadero en caso de realizar la inserción con éxito, falso en cualquier otro caso
        """
        from pineboolib.fllegacy.FLSqlCursor import FLSqlCursor
        c = FLSqlCursor(t, True, connName)
        c.setForwardOnly(True)

        # if not c.select(w):
        #     return False
        c.select(w)

        while c.next():
            c.setModeAccess(FLSqlCursor.Del)
            c.refreshBuffer()
            if not c.commitBuffer():
                return False

        return True
Ejemplo n.º 17
0
    def loaded(self):
        #Asi damos tiempo a que el control se añada al formulario
        self._loaded = True
        value = None
        while True: #Ahora podemos buscar el cursor ... porque ya estamos añadidos al formulario
            parent_cursor = getattr(self._parent,"_cursor", None)
            if parent_cursor: 
                #print("FLFIeldDB(%s):Pariente %s con cursor encontrado" % (self._fieldAlias, self._parent))
                break
            new_parent = self._parent.parentWidget()
            if new_parent is None: 
                print("FLFIeldDB(%s):No se ha encontrado al padre con cursor" % self._fieldAlias)
                break
            self._parent = new_parent
            
        self._cursor = self._parent.parentWidget()._cursor
        if not self._cursor:
            self._cursor = self._parent._cursor
        #Si es un dato externo ...
        if not self._tableName is None and not self._tableName == "":
            self._editable = False
            cursorFr = FLSqlCursor(self._tableName)
            if not cursorFr._model is None and not isinstance(cursorFr._model, DefFun): #Para las tablas qye no existen
                #print("El tipo model es %s" % type(cursorFr._model))
                self._tipo = cursorFr._model.fieldType(self._fieldRelation)
                valueForeignField = self._cursor.valueBuffer(self._foreignField)
                if not valueForeignField is None and not valueForeignField == "":
                    if self._tipo == 'uint':
                        filtro = "%s = %s" % (self._fieldRelation, str(valueForeignField))
                    else:
                        filtro = "%s = '%s'" % (self._fieldRelation, str(valueForeignField))   
                    cursorFr.setMainFilter(filtro)
                    cursorFr.refresh()
                    cursorFr.first()
                    value = cursorFr.valueBuffer(self._fieldName)
                else:
                    value=""
            else:
                print("FLFieldDB: Campo %s.%s no encontrada." % (self._tableName, self._fieldName))
                value=""

        else:
            self._tableName =  self._cursor.table().name
            #print("Solicitando Alias de %s a tabla %s" % (self._fieldName, self._tableName))
            self.setFieldAlias(self._cursor._model.alias(self._fieldName))
            self._tipo = self._cursor._model.fieldType(self._fieldName)
            value = self._cursor.valueBuffer(self._fieldName)
        
        
        #print("\n\nCampo = %s.%s, Tipo = %s\nvalue = \"%s\"\nEditable = %s" % (self._tableName, self.fieldName, self._tipo, value, self._editable))
        if self._tipo == 'string' or self._tipo == 'uint' or self._tipo == 'double' or self._tipo == 'date' or self._tipo == 'serial':
            self._dataControl = QtGui.QLineEdit()
        elif self._tipo == 'bool':
            self._dataControl = QtGui.QCheckBox()
        elif self._tipo == 'stringlist':
            self._dataControl = QtGui.QLineEdit()
        else:
            print("FLFIeldDB(%s):Tipo de dato desconocido (%s) en %s.%s.¿Existe ese campo?" % (self._fieldAlias, self._tipo , self._tableName, self._fieldName ))
            self._dataControl = QtGui.QLineEdit()
        
        self._layout.addWidget(self._dataControl)
        
        if value:
            self.setValue(str(value))
        self.refresh() 
Ejemplo n.º 18
0
class FLTableDB(QtGui.QWidget):
    _tableView = None
    _vlayout = None
    _lineEdit = None
    _comboBox_1 = None
    _comboBox_2 = None
    topWidget = QtGui.QWidget
    showed = False

    def __init__(self, parent = None, action_or_cursor = None, *args):
        print("FLTableDB:", parent, action_or_cursor , args)
        # TODO: Falta el lineeditsearch y el combo, que los QS lo piden
        super(FLTableDB,self).__init__(parent,*args)
        # TODO: LA inicialización final hay que hacerla más tarde, en el primer
        # show(), porque sino obligas a tenerlo todo preparado en el constructor.
        self._tableView = QtGui.QTableView()
        self._lineEdit = QtGui.QLineEdit()
        _label1 = QtGui.QLabel()
        _label2 = QtGui.QLabel()
        self._comboBox_1 = QtGui.QComboBox()
        self._comboBox_2 = QtGui.QComboBox()
        _label1.setText("Buscar")
        _label2.setText("en")
        self._vlayout = QtGui.QVBoxLayout()
        _hlayout =  QtGui.QHBoxLayout()
        self._tableView._v_header = self._tableView.verticalHeader()
        self._tableView._v_header.setDefaultSectionSize(18)
        self._tableView._h_header = self._tableView.horizontalHeader()
        self._tableView._h_header.setDefaultSectionSize(70)
        _hlayout.addWidget(_label1)
        _hlayout.addWidget(self._lineEdit)
        _hlayout.addWidget(_label2)
        _hlayout.addWidget(self._comboBox_1)
        _hlayout.addWidget(self._comboBox_2)
        self._vlayout.addLayout(_hlayout)
        self._vlayout.addWidget(self._tableView)
        self.setLayout(self._vlayout)
        self._parent = parent
        while True:
            parent_cursor = getattr(self._parent,"_cursor", None)
            if parent_cursor: break
            new_parent = self._parent.parentWidget()
            if new_parent is None: break
            self._parent = new_parent
            print(self._parent)

        self._tableView.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
        self._tableView.setSelectionMode(QtGui.QAbstractItemView.SingleSelection)
        self._tableView.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
        self._tableView.setAlternatingRowColors(True)

        if action_or_cursor is None and parent_cursor:
            action_or_cursor = parent_cursor
        if isinstance(action_or_cursor,FLSqlCursor):
            self._cursor = action_or_cursor
        elif isinstance(action_or_cursor,str):
            self._cursor = FLSqlCursor(action_or_cursor)
        else:
            self._cursor = None
        if self._cursor:
            self._tableView._h_header.setResizeMode(QtGui.QHeaderView.ResizeToContents)
            self._tableView.setModel(self._cursor._model)
            self._tableView.setSelectionModel(self._cursor.selection())
        self.tableRecords = self # control de tabla interno

        #Carga de comboBoxs y connects .- posiblemente a mejorar
        if self._cursor:
            for column in range(self._cursor._model.columnCount()):
                self._comboBox_1.addItem(self._cursor._model.headerData(column, QtCore.Qt.Horizontal, QtCore.Qt.DisplayRole))
                self._comboBox_2.addItem(self._cursor._model.headerData(column, QtCore.Qt.Horizontal, QtCore.Qt.DisplayRole))
        self._comboBox_1.addItem("*")
        self._comboBox_2.addItem("*")
        self._comboBox_1.setCurrentIndex(0)
        self._comboBox_2.setCurrentIndex(1)
        self._comboBox_1.currentIndexChanged.connect(self.comboBox_putFirstCol)
        self._comboBox_2.currentIndexChanged.connect(self.comboBox_putSecondCol)        

        self.sort = []
        self.timer_1 = QtCore.QTimer(self)
        self.timer_1.singleShot(100, self.loaded)

    def __getattr__(self, name): return DefFun(self, name)

    def loaded(self):
        # Es necesario pasar a modo interactivo lo antes posible
        # Sino, creamos un bug en el cierre de ventana: se recarga toda la tabla para saber el tamaño
        print("FLTableDB: setting columns in interactive mode")
        self._tableView._h_header.setResizeMode(QtGui.QHeaderView.Interactive)

    def cursor(self):
        assert self._cursor
        return self._cursor

    def obj(self):
        return self

    def comboBox_putFirstCol(self):
        self.putFirstCol(str(self._comboBox_1.currentText()))

    def comboBox_putSecondCol(self):
        self.putSecondCol(str(self._comboBox_2.currentText()))

    def putFirstCol(self, fN):
        _oldPos= None
        _oldFirst = self._tableView._h_header.logicalIndex(0)    
        for column in range(self._cursor._model.columnCount()):
            if self._cursor._model.headerData(column, QtCore.Qt.Horizontal, QtCore.Qt.DisplayRole).lower() == fN.lower():
                _oldPos = self._tableView._h_header.visualIndex(column) 
                if not self._comboBox_1.currentText() == fN:
                    self._comboBox_1.setCurrentIndex(column)
                    return False
                break

        if not _oldPos or fN == "*":
            return False
        else:         
            self._tableView._h_header.swapSections(_oldPos, 0)
            self._comboBox_2.setCurrentIndex(_oldFirst)
            return True

    def putSecondCol(self, fN):
        _oldPos= None
        _oldSecond = self._tableView._h_header.logicalIndex(1)
        for column in range(self._cursor._model.columnCount()):
            if self._cursor._model.headerData(column, QtCore.Qt.Horizontal, QtCore.Qt.DisplayRole).lower() == fN.lower():
                _oldPos = self._tableView._h_header.visualIndex(column)
                break

        if not _oldPos or fN == "*":
            return False
        if not self._comboBox_1.currentText() == fN:           
            self._tableView._h_header.swapSections(_oldPos, 1)
        else:
            self._comboBox_1.setCurrentIndex(_oldSecond)
        return True


    def setTableName(self, tableName):
        self._tableName = tableName
        if self.showed:
            if self.topWidget:
                self.initCursor()
            else:
                self.initFakeEditor()


    def setForeignField(self, foreingField):
        self._foreingField = foreingField
        if self.showed:
            if self.topWidget:
                self.initCursor()
            else:
                self.initFakeEditor()



    def setFieldRelation(self, fieldRelation):
        self._fieldRelation = fieldRelation
        if self.showed:
            if self.topWidget:
                self.initCursor()
            else:
                self.initFakeEditor()







    @decorators.NotImplementedWarn
    def initCursor(self):
        # si no existe crea la tabla
        if not self._cursor: return False
        if not self._cursor._model: return False

        self._tMD = 0

        if not self._sortField: self._tMD = self._cursor._model.name()
        if self._tMD:
            self.sortField_ = self._tMD.value(self._cursor._currentregister, self._tMD.primaryKey())
        ownTMD = False
        if not self._tableName:
            #if not cursor_->db()->manager()->existsTable(tableName_)) {
            ownTMD = True
            #tMD = cursor_->db()->manager()->createTable(tableName_);
        else:
            ownTMD = True
            self._tMD = self._cursor._model._table.name

        if not self._tMD:
            return

        if not self._foreignField or not self._fieldRelation:
            if not self._cursor._model:
                if ownTMD and self._tMD and not self._tMD.inCache():
                    self._tMD = None
        
            return

            if not self._cursor._model.name() == self._tableName:
                ctxt = self._cursor.context();
                self._cursor = FLSqlCursor(self._tableName)
                if self._cursor:
                    self._cursor.setContext(ctxt)
                    cursorAux = 0
        
                if ownTMD and self._tMD and not self._tMD.inCache():
                    self._tMD = None
        
                return
        
        else:
            cursorTopWidget = self.topWidget._cursor() # ::qt_cast<FLFormDB *>(topWidget)->cursor()
            if cursorTopWidget and not cursorTopWidget._model.name() == self._tableName:
                self._cursor = cursorTopWidget
    
  

        if not self._tableName or not self._foreignField or not self._fieldRelation or cursorAux:
            if ownTMD and self._tMD and not self._tMD.inCache():
                tMD = None
    
            return
  
        cursorAux = self._cursor
        curName = self._cursor._model.name()
        rMD = self._cursor._model.relation(self._foreignField,self._fieldRelation,self._tableName)
        testM1 = self._tMD.relation(self._fieldRelation, self._foreignField, curName)
        checkIntegrity = bool(False)

        if not rMD:
            if testM1:
                checkIntegrity = (testM1.cardinality() == FLRelationMetaData.RELATION_M1)
            fMD = FLTableMetaData(self._cursor._model.field(self._foreignField)) 
            if (fMD):
                tmdAux = self._cursor._model(self._tableName);
                if not tmdAux or tmdAux.isQuery():
                    checkIntegrity = False
                if tmdAux and not tmdAux.inCache(): # mirar inCache()
                    tmdAux = None
                rMD = FLRelationMetaData(self._tableName,self._fieldRelation, FLRelationMetaData.RELATION_1M, False, False, checkIntegrity)
                fMD.addRelationMD(rMD)
                print("FLTableDB : La relación entre la tabla del formulario %r y esta tabla %r de este campo no existe, pero sin embargo se han indicado los campos de relación( %r, %r )" % (curName, self._tableName, self._fieldRelation, self._foreignField))
                print("FLTableDB : Creando automáticamente %r.%r --1M--> %r.%r" %  (curName, self._foreignField, self._tableName, self._fieldRelation))

    
            else:
                print("FLTableDB : El campo ( %r ) indicado en la propiedad foreignField no se encuentra en la tabla ( %r )" % (self._foreignField, curName))
        rMD = testM1
        if not rMD:
            fMD = FLFieldMetaData(tMD.field(self._fieldRelation))
            if (fMD):
                rMD = FLRelationMetaData(curName,self._foreignField, FLRelationMetaData.RELATION_1M, False, False, False)
                fMD.addRelationMD(rMD)
                print("FLTableDB : Creando automáticamente %r.%r --1M--> %r.%r" % (self._tableName, self._fieldRelation, curName, self._foreignField))
            else:
                print("FLTableDB : El campo ( %r ) indicado en la propiedad fieldRelation no se encuentra en la tabla ( %r )" % (self._fieldRelation, self._tableName))

        self._cursor = FLSqlCursor(self._tableName, True, self._cursor.db().connectionName(), cursorAux, rMD, self);
        if not self._cursor:
            self._cursor = cursorAux
            cursorAux = 0
        else:
            self._cursor.setContext(cursorAux.context())
        if self.showed:
            self.disconnect(cursorAux, QtCore.SIGNAL('newBuffer()'), self.refresh())
            self.connect(cursorAux,QtCore.SIGNAL('newBuffer()'), self.refresh())
  

        if cursorAux and self.topWidget.isA("FLFormSearchDB"):
            self.topWidget.setCaption(self._cursor._model.alias())
            self.topWidget.setCursor(self._cursor) #::qt_cast<FLFormSearchDB *>(topWidget)->setCursor(cursor_);
  

        if ownTMD and tMD and not tMD.inCache():
            tMD = None


    @QtCore.pyqtSlot()
    def close(self):
        print("FLTableDB: close()")

    @QtCore.pyqtSlot()
    def refresh(self):
        print("FLTableDB: refresh()", self.parent().parent().parent())
        self._cursor.refresh()

    @QtCore.pyqtSlot()
    def show(self):
        print("FLTableDB: show event")
        super(FLTableDB, self).show()

    @QtCore.pyqtSlot()
    def insertRecord(self):
        self._cursor.insertRecord()

    @QtCore.pyqtSlot()
    def editRecord(self):
        self._cursor.editRecord()

    @QtCore.pyqtSlot()
    def deleteRecord(self):
        self._cursor.deleteRecord()

    @QtCore.pyqtSlot()
    def browseRecord(self):
        self._cursor.browseRecord()

    @QtCore.pyqtSlot()
    def copyRecord(self):
        self._cursor.copyRecord()
Ejemplo n.º 19
0
    def __init__(self, parent = None, action_or_cursor = None, *args):
        print("FLTableDB:", parent, action_or_cursor , args)
        # TODO: Falta el lineeditsearch y el combo, que los QS lo piden
        super(FLTableDB,self).__init__(parent,*args)
        # TODO: LA inicialización final hay que hacerla más tarde, en el primer
        # show(), porque sino obligas a tenerlo todo preparado en el constructor.
        self._tableView = QtGui.QTableView()
        self._lineEdit = QtGui.QLineEdit()
        _label1 = QtGui.QLabel()
        _label2 = QtGui.QLabel()
        self._comboBox_1 = QtGui.QComboBox()
        self._comboBox_2 = QtGui.QComboBox()
        _label1.setText("Buscar")
        _label2.setText("en")
        self._vlayout = QtGui.QVBoxLayout()
        _hlayout =  QtGui.QHBoxLayout()
        self._tableView._v_header = self._tableView.verticalHeader()
        self._tableView._v_header.setDefaultSectionSize(18)
        self._tableView._h_header = self._tableView.horizontalHeader()
        self._tableView._h_header.setDefaultSectionSize(70)
        _hlayout.addWidget(_label1)
        _hlayout.addWidget(self._lineEdit)
        _hlayout.addWidget(_label2)
        _hlayout.addWidget(self._comboBox_1)
        _hlayout.addWidget(self._comboBox_2)
        self._vlayout.addLayout(_hlayout)
        self._vlayout.addWidget(self._tableView)
        self.setLayout(self._vlayout)
        self._parent = parent
        while True:
            parent_cursor = getattr(self._parent,"_cursor", None)
            if parent_cursor: break
            new_parent = self._parent.parentWidget()
            if new_parent is None: break
            self._parent = new_parent
            print(self._parent)

        self._tableView.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
        self._tableView.setSelectionMode(QtGui.QAbstractItemView.SingleSelection)
        self._tableView.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
        self._tableView.setAlternatingRowColors(True)

        if action_or_cursor is None and parent_cursor:
            action_or_cursor = parent_cursor
        if isinstance(action_or_cursor,FLSqlCursor):
            self._cursor = action_or_cursor
        elif isinstance(action_or_cursor,str):
            self._cursor = FLSqlCursor(action_or_cursor)
        else:
            self._cursor = None
        if self._cursor:
            self._tableView._h_header.setResizeMode(QtGui.QHeaderView.ResizeToContents)
            self._tableView.setModel(self._cursor._model)
            self._tableView.setSelectionModel(self._cursor.selection())
        self.tableRecords = self # control de tabla interno

        #Carga de comboBoxs y connects .- posiblemente a mejorar
        if self._cursor:
            for column in range(self._cursor._model.columnCount()):
                self._comboBox_1.addItem(self._cursor._model.headerData(column, QtCore.Qt.Horizontal, QtCore.Qt.DisplayRole))
                self._comboBox_2.addItem(self._cursor._model.headerData(column, QtCore.Qt.Horizontal, QtCore.Qt.DisplayRole))
        self._comboBox_1.addItem("*")
        self._comboBox_2.addItem("*")
        self._comboBox_1.setCurrentIndex(0)
        self._comboBox_2.setCurrentIndex(1)
        self._comboBox_1.currentIndexChanged.connect(self.comboBox_putFirstCol)
        self._comboBox_2.currentIndexChanged.connect(self.comboBox_putSecondCol)        

        self.sort = []
        self.timer_1 = QtCore.QTimer(self)
        self.timer_1.singleShot(100, self.loaded)
Ejemplo n.º 20
0
class FLTableDB(QtGui.QWidget):

    """
    PLUGIN que contiene una tabla de la base de datos.

    Este objeto contiene todo lo necesario para manejar
    los datos de una tabla. Además de la funcionalidad de
    busqueda en la tabla por un campo, mediante filtros.

    Este plugin para que sea funcional debe tener como uno
    de sus padres o antecesor a un objeto FLFormDB.

    @author InfoSiAL S.L.
    """

    """
    Tipos de condiciones para el filtro
    """
    All = None
    Contains = None
    Starts = None
    End = None
    Equal = None
    Dist = None
    Greater = None
    Less = None
    FromTo = None
    Null = None
    NotNull = None

    _parent = None
    _name = None
    loadLater_ = None

    comboBoxFieldToSearch = None
    comboBoxFieldToSearch2 = None
    tableRecords_ = None
    lineEditSearch = None

    tabDataLayout = None
    tabControlLayout = None

    _initCursorWhenLoad = None
    _initTableRecordWhenLoad = None

    _controlsInit = None

    """
    constructor
    """

    def __init__(self, parent, name=None):
        super(FLTableDB, self).__init__(parent)

        self.timer_1 = QtCore.QTimer(self)
        self.timer_1.singleShot(0, self.loaded)
        self.topWidget = parent

    def __getattr__(self, name):
        return DefFun(self, name)

    def loaded(self):
        # Es necesario pasar a modo interactivo lo antes posible
        # Sino, creamos un bug en el cierre de ventana: se recarga toda la tabla para saber el tamaño
        # print("FLTableDB(%s): setting columns in interactive mode" % self._tableName)
        self._loaded = True
        while True:  # Ahora podemos buscar el cursor ... porque ya estamos añadidos al formulario
            parent_cursor = getattr(self.topWidget, "cursor_", None)
            if parent_cursor:
                break
            new_parent = self.topWidget.parentWidget()
            if new_parent is None:
                break
            self.topWidget = new_parent

        if getattr(self.topWidget.parentWidget(), "cursor_", None):
            self.topWidget = self.topWidget.parentWidget()

        if not parent_cursor:
            print(
                "FLTableDB : Uno de los padres o antecesores de FLTableDB deber ser de la clase FLFormDB o heredar de ella"
            )
            return

        self.cursor_ = self.topWidget.cursor_
        self.setFont(QtGui.qApp.font())

        if not self._name:
            self.setName("FLTableDB")

        self.timer = QtCore.QTimer(self)
        self.timer.timeout.connect(self.refreshDelayed)

        self.showWidget()

        self.initCursor()

    def setName(self, name):
        self._name = name

    """
    Para obtener el cursor utilizado por el componente.

    return Objeto FLSqlCursor con el cursor que contiene los registros para ser utilizados en el formulario
    """

    def cursor(self):
        if not self.cursor_.d.buffer_:
            self.cursor_.refreshBuffer()
        return self.cursor_

    """
    Para obtener el nombre de la tabla asociada.

    @return Nombre de la tabla asociado
    """

    def tableName(self):
        return self.tableName_

    """
    Para establecer el nombre de la tabla asociada.

    @param fT Nombre de la tabla asociada
    """

    def setTableName(self, fT):
        self.tableName_ = fT
        if self.showed:
            if self.topwidget:
                self.initCursor()
            else:
                self.initFakeEditor()

        else:
            self._initCursorWhenLoad = True
            self._initTableRecordWhenLoad = True

    """
    Para obtener el nombre del campo foráneo.

    @return Nombre del campo
    """

    def foreignField(self):
        return self.foreignField_

    """
    Para establecer el nombre del campo foráneo.

    @param fN Nombre del campo
    """

    def setForeignField(self, fN):
        self.foreignField_ = fN
        if self.showed:
            if self.topwidget:
                self.initCursor()
            else:
                self.initFakeEditor()
        else:
            self._initCursorWhenLoad = True
            self._initTableRecordWhenLoad = True

    """
    Para obtener el nombre del campo relacionado.

    @return Nombre del campo
    """

    def fieldRelation(self):
        return self.fieldRelation_

    """
    Para establecer el nombre del campo relacionado.

    @param fN Nombre del campo
    """

    def setFieldRelation(self, fN):
        self.fieldRelation_ = fN
        if self.showed:
            if self.topwidget:
                self.initCursor()
            else:
                self.initFakeEditor()

        else:
            self._initCursorWhenLoad = True
            self._initTableRecordWhenLoad = True

    """
    Establece si el componente esta en modo solo lectura o no.
    """

    def setReadOnly(self, mode):
        if self.tableRecords_:
            self.readonly = mode
            self.tableRecords_.setFLReadOnly(mode)
            # self.readOnlyChanged(mode).emit() FIXME

        self.reqReadOnly_ = mode

    def readOnly(self):
        return self.reqReadOnly_

    """
    Establece si el componente esta en modo solo edición o no.
    """

    def setEditOnly(self, mode):
        if self.tableRecords_:
            self.editonly_ = mode
            self.tableRecords_.setEditOnly(mode)
            # self.editOnlyChanged(mode).emit() #FIXME

        self.reqEditOnly_ = mode

    def editOnly(self):
        return self.reqEditOnly_

    """
    Establece el componente a sólo inserción o no.
    """

    def setInsertOnly(self, mode):
        if self.tableRecords_:
            self.insertonly_ = mode
            self.tableRecords_.setInsertOnly(mode)
            self.insertOnlyChanged(mode).emit()

        self.reqInsertOnly = mode

    def insertOnly(self):
        return self.reqInsertOnly_

    """
    Establece el filtro inicial de búsqueda
    """

    def setInitSearch(self, iS):
        self.initSearch_ = iS

    """
    Establece el orden de las columnas de la tabla.

    @param fields Lista de los nombres de los campos ordenada según se desea que aparezcan en la tabla de izquierda a derecha
    """

    @decorators.NotImplementedWarn
    def setOrderCols(self, fields):
        pass

    """
    Devuelve la lista de los campos ordenada por sus columnas en la tabla de izquierda a derecha
    """

    @decorators.NotImplementedWarn
    def orderCols(self):
        return None

    """
    Establece el filtro de la tabla

    @param f Sentencia Where que establece el filtro
    """

    @decorators.NotImplementedWarn
    def setFilter(self, f):
        pass

    """
    Devuelve el filtro de la tabla

    @return Filtro
    """

    @decorators.NotImplementedWarn
    def filter(self):
        return None

    """
    Devuelve el filtro de la tabla impuesto en el Find

    @return Filtro
    """

    @decorators.NotImplementedWarn
    def findFilter(self):
        return None

    """
    Obtiene si la columna de selección está activada
    """

    @decorators.NotImplementedWarn
    def checkColumnEnabled(self):
        return None

    """
    Establece el estado de activación de la columna de selección

    El cambio de estado no será efectivo hasta el siguiente refresh.
    """

    @decorators.NotImplementedWarn
    def setCheckColumnEnabled(self, b):
        pass

    """
    Obiente el texto de la etiqueta de encabezado para la columna de selección
    """

    @decorators.NotImplementedWarn
    def aliasCheckColumn(self):
        pass

    """
    Establece el texto de la etiqueta de encabezado para la columna de selección

    El cambio del texto de la etiqueta no será efectivo hasta el próximo refresh
    """

    @decorators.NotImplementedWarn
    def setAliasCheckColumn(self, t):
        pass

    """
    Obtiene si el marco de búsqueda está oculto
    """

    @decorators.NotImplementedWarn
    def findHidden(self):
        return None

    """
    Oculta o muestra el marco de búsqueda

    @param  h TRUE lo oculta, FALSE lo muestra
    """

    @decorators.NotImplementedWarn
    def setFindHidden(self, h):
        pass

    """
    Obtiene si el marco para conmutar entre datos y filtro está oculto
    """

    @decorators.NotImplementedWarn
    def filterHidden(self):
        return None

    """
    Oculta o muestra el marco para conmutar entre datos y filtro

    @param  h TRUE lo oculta, FALSE lo muestra
    """

    @decorators.NotImplementedWarn
    def setFilterHidden(self, h):
        pass

    """
    Ver FLTableDB::showAllPixmaps_
    """

    @decorators.NotImplementedWarn
    def showAllPixmaps(self):
        return None

    """
    Ver FLTableDB::showAllPixmaps_
    """

    @decorators.NotImplementedWarn
    def setShowAllPixmaps(self, s):
        pass

    """
    Ver FLTableDB::functionGetColor_
    """

    @decorators.NotImplementedWarn
    def functionGetColor(self):
        pass

    """
    Ver FLTableDB::functionGetColor_
    """

    @decorators.NotImplementedWarn
    def setFunctionGetColor(self, f):
        pass

    """
    Asigna el nombre de función a llamar cuando cambia el filtro.
    """

    def setFilterRecordsFunction(self, fn):
        self.tableDB_filterRecords_functionName_ = fn

    """
    Ver FLTableDB::onlyTable_
    """

    @decorators.NotImplementedWarn
    def setOnlyTable(self, on=True):
        pass

    def onlyTable(self):
        return self.reqOnlyTable_

    """
    Ver FLTableDB::autoSortColumn_
    """

    @decorators.NotImplementedWarn
    def setAutoSortColumn(self, on=True):
        self.autoSortColumn_ = on

    def autoSortColumn(self):
        return self.autoSortColumn_

    """
    Filtro de eventos
    """

    def eventFilter(self, obj, ev):
        if (
            not self.tableRecords_
            or not self.lineEditSearch
            or not self.comboBoxFieldToSearch
            or not self.comboBoxFieldToSearch2
            or not self.cursor_
        ):
            return super(FLTableDB, self).eventFilter(obj, ev)

        if ev.type() == QtCore.QEvent.KeyPress and isinstance(obj, FLDataTable):
            k = ev

            if k.key() == QtCore.Qt.Key_F2:
                self.comboBoxFieldToSearch.popup()
                return True

        if ev.type() == QtCore.QEvent.KeyPress and isinstance(obj, QtGui.QLineEdit):
            k = ev

            if k.key() == QtCore.Qt.Key_Enter or k.key() == QtCore.Qt.Key_Return:
                self.tableRecords_.setFocus()
                return True

            if k.key() == QtCore.Qt.Key_Up:
                self.comboBoxFieldToSearch.setFocus()
                return True

            if k.key() == QtCore.Qt.Key_Down:
                self.tableRecords_.setFocus()
                return True

            if k.key() == QtCore.Qt.Key_F2:
                self.comboBoxFieldToSearch.popup()
                return True

            if k.text() == "'" or k.text() == "\\":
                return True

        if isinstance(obj, FLDataTable) or isinstance(obj, QtGui.QLineEdit):
            return False
        else:
            return super(FLTableDB, self).eventFilter(obj, ev)

    """
    Captura evento mostrar
    """

    def showEvent(self, e):
        super(FLTableDB, self).showEvent(e)
        self.showWidget()

    """
    Redefinida por conveniencia
    """

    def showWidget(self):
        if not self._loaded:  # Esperamos a que la carga se realice
            timer = QtCore.QTimer(self)
            timer.singleShot(30, self.showWidget)
            return
        else:
            if not self.showed and not self._initCursorWhenLoad and self.cursor_ and self.tableRecords_:
                if not self.topWidget:
                    self.initFakeEditor()
                    self.showed = True
                    return

                tMD = None
                ownTMD = None
                if self.tableName_:
                    if not self.cursor_.db().manager().existsTable(self.tableName_):
                        ownTMD = True
                        tMD = self.cursor_.db().manager().createTable(self.tableName_)
                    else:
                        ownTMD = True
                        tMD = self.cursor_.db().manager().metadata(self.tableName_)

                    if not tMD:
                        return

                if not self.cursorAux:
                    if self.initSearch_:
                        self.refresh(True, True)
                        QtCore.QTimer.singleShot(0, self.tableRecords_.ensureRowSelectedVisible)
                    else:
                        self.refresh(True)
                        if self.tableRecords_.numRows() <= 0:
                            self.refresh(False, True)
                        else:
                            self.refreshDelayed()

                    if not isinstance(self.topWidget, FLFormRecordDB):
                        self.lineEditSearch.setFocus()

                if self.cursorAux:
                    if isinstance(self.topWidget, FLFormRecordDB) and self.cursorAux.modeAccess() == FLSqlCursor.Browse:
                        self.cursor_.setEdition(False)
                        self.setReadOnly(True)

                    if self.initSearch_:
                        self.refresh(True, True)
                        QtCore.QTimer.singleShot(0, self.tableRecords_.ensureRowSelectedVisible)
                    else:
                        self.refresh(True)
                        if self.tableRecords_.numRows() <= 0:
                            self.refresh(False, True)
                        else:
                            self.refreshDelayed()

                elif (
                    isinstance(self.topWidget, FLFormRecordDB)
                    and self.cursor_.modeAccess() == FLSqlCursor.Browse
                    and (tMD and not tMD.isQuery())
                ):
                    self.cursor_.setEdition(False)
                    self.setReadOnly(True)

                if ownTMD and tMD and not tMD.inCache():
                    del tMD

            if self._initCursorWhenLoad:
                self._initCursorWhenLoad = False
                self.initCursor()
                self.showWidget()

            if not self.tableRecords_:
                if not self.tableName_:
                    if not self.cursor_:
                        self.initCursor()
                        QtCore.QTimer.singleShot(50, self.showWidget)
                        return
                    self.tableRecords()
                    self.setTableRecordsCursor()
                    self.showWidget()
                elif self.tableName_:
                    if not self.cursor_:
                        self.initCursor()
                        QtCore.QTimer.singleShot(50, self.showWidget)
                        return

                    if self.tableName_ == self.cursor_.curName():
                        self.tableRecords()
                        if self.cursor_.model():
                            self.setTableRecordsCursor()
                            self.showWidget()

    """
    Obtiene el componente tabla de registros
    """

    def tableRecords(self):

        self.tabDataLayout = QtGui.QVBoxLayout()
        self.comboBoxFieldToSearch = QtGui.QComboBox()
        self.comboBoxFieldToSearch2 = QtGui.QComboBox()
        self.lineEditSearch = QtGui.QLineEdit()
        label1 = QtGui.QLabel()
        label2 = QtGui.QLabel()

        label1.setText("Buscar")
        label2.setText("en")

        self.tabControlLayout = QtGui.QHBoxLayout()

        self.tabControlLayout.addWidget(label1)
        self.tabControlLayout.addWidget(self.lineEditSearch)
        self.tabControlLayout.addWidget(label2)
        self.tabControlLayout.addWidget(self.comboBoxFieldToSearch)
        self.tabControlLayout.addWidget(self.comboBoxFieldToSearch2)

        self.tabDataLayout.addLayout(self.tabControlLayout)

        if not self.tableRecords_:
            self.tableRecords_ = FLDataTable(self, "tableRecords")
            self.tableRecords_.setFocusPolicy(QtCore.Qt.StrongFocus)
            self.setFocusProxy(self.tableRecords_)
            self.tabDataLayout.addWidget(self.tableRecords_)
            self.lineEditSearch.installEventFilter(self)
            self.tableRecords_.installEventFilter(self)

            self.setLayout(self.tabDataLayout)
            self.setTabOrder(self.tableRecords_, self.lineEditSearch)
            self.setTabOrder(self.lineEditSearch, self.comboBoxFieldToSearch)
            self.setTabOrder(self.comboBoxFieldToSearch, self.comboBoxFieldToSearch2)

        self.lineEditSearch.textChanged.connect(self.filterRecords)
        model = self.cursor_.model()

        if model:
            for column in range(model.columnCount()):
                field = model.metadata().indexFieldObject(column)
                if not field.visibleGrid():
                    self.tableRecords_.setColumnHidden(column, True)
                else:
                    self.comboBoxFieldToSearch.addItem(
                        model.headerData(column, QtCore.Qt.Horizontal, QtCore.Qt.DisplayRole)
                    )
                    self.comboBoxFieldToSearch2.addItem(
                        model.headerData(column, QtCore.Qt.Horizontal, QtCore.Qt.DisplayRole)
                    )
            self.comboBoxFieldToSearch.addItem("*")
            self.comboBoxFieldToSearch2.addItem("*")
            self.comboBoxFieldToSearch.setCurrentIndex(0)
            self.comboBoxFieldToSearch2.setCurrentIndex(1)
            self.comboBoxFieldToSearch.currentIndexChanged.connect(self.putFirstCol)
            self.comboBoxFieldToSearch2.currentIndexChanged.connect(self.putSecondCol)
            self._controlsInit = True

        else:
            self.comboBoxFieldToSearch.addItem("*")
            self.comboBoxFieldToSearch2.addItem("*")

        return self.tableRecords_

    """
    Asigna el cursor actual del componente a la tabla de registros
    """

    def setTableRecordsCursor(self):
        self.tableRecords_.setFLSqlCursor(self.cursor_)
        try:
            self.tableRecords_.doubleClicked.disconnect(self.chooseRecord)
        except:
            pass
        self.tableRecords_.doubleClicked.connect(self.chooseRecord)

    """
    Refresca la pestaña datos aplicando el filtro
    """

    @decorators.NotImplementedWarn
    def refreshTabData(self):
        pass

    """
    Refresca la pestaña del filtro
    """

    @decorators.NotImplementedWarn
    def refreshTabFilter(self):
        pass

    """
    Para obtener la enumeración correspondiente a una condición para el filtro a partir de
    su literal
    """

    @decorators.NotImplementedWarn
    def decodeCondType(self, strCondType):
        pass

    """
    Construye la claúsula de filtro en SQL a partir del contenido de los valores
    definidos en la pestaña de filtro
    """

    @decorators.NotImplementedWarn
    def tdbFilterBuildWhere(self):
        pass

    """
    Inicializa un editor falso y no funcional.

    Esto se utiliza cuando se está editando el formulario con el diseñador y no
    se puede mostrar el editor real por no tener conexión a la base de datos.
    Crea una previsualización muy esquemática del editor, pero suficiente para
    ver la posisicón y el tamaño aproximado que tendrá el editor real.
    """

    @decorators.NotImplementedWarn
    def initFakeEditor(self):
        pass

    """
    Componente para visualizar los registros
    """
    tableRecords_ = None

    """
    Nombre de la tabla a la que esta asociado este componente.
    """
    tableName_ = None

    """
    Nombre del campo foráneo
    """
    foreignField_ = None

    """
    Nombre del campo de la relación
    """
    fieldRelation_ = None

    """
    Cursor con los datos de origen para el componente
    """
    cursor_ = None

    """
    Cursor auxiliar de uso interno para almacenar los registros de la tabla
    relacionada con la de origen
    """
    cursorAux = None

    """
    Matiene la ventana padre
    """
    topWidget = None

    """
    Indica que la ventana ya ha sido mostrada una vez
    """
    showed = None

    """
    Mantiene el filtro de la tabla
    """
    filter_ = None

    """
    Almacena si el componente está en modo sólo lectura
    """
    readonly_ = None
    reqReadOnly_ = None

    """
    Almacena si el componente está en modo sólo edición
    """
    editonly_ = None
    reqEditOnly_ = None

    """
    Indica si el componente está en modo sólo permitir añadir registros
    """
    insertonly_ = None
    reqInsertOnly_ = None

    """
    Almacena los metadatos del campo por el que está actualmente ordenada la tabla
    """
    sortField_ = None

    """
    Almacena los metadatos del campo por el que está actualmente ordenada la tabla en segunda instancia

    @author Silix - dpinelo
    """
    sortField2_ = None

    """
    Crónometro interno
    """
    timer = None

    """
    Filtro inicial de búsqueda
    """
    initSearch_ = None

    """
    Indica que la columna de seleción está activada
    """
    checkColumnEnabled_ = None

    """
    Indica el texto de la etiqueta de encabezado para la columna de selección
    """
    aliasCheckColumn_ = None

    """
    Indica el nombre para crear un pseudocampo en el cursor para la columna de selección
    """
    fieldNameCheckColumn_ = None

    """
    Indica que la columna de selección está visible
    """
    checkColumnVisible_ = None

    """
    Indica el número de columna por la que ordenar los registros
    """
    sortColumn_ = None

    """
    Indica el número de columna por la que ordenar los registros

    @author Silix - dpinelo
    """
    sortColumn2_ = None

    """
    Indica el número de columna por la que ordenar los registros

    @author Silix
    """
    sortColumn3_ = None

    """
    Indica el sentido ascendente o descendente del la ordenacion actual de los registros
    """
    orderAsc_ = None

    """
    Indica el sentido ascendente o descendente del la ordenacion actual de los registros

    @author Silix - dpinelo
    """
    orderAsc2_ = None

    """
    Indica el sentido ascendente o descendente del la ordenacion actual de los registros

    @author Silix
    """
    orderAsc3_ = None

    """
    Indica si se debe establecer automáticamente la primera columna como de ordenación
    """
    autoSortColumn_ = None

    """
    Almacena la última claúsula de filtro aplicada en el refresco
    """
    tdbFilterLastWhere_ = None

    """
    Diccionario que relaciona literales descriptivos de una condición de filtro
    con su enumeración
    """
    mapCondType = []

    """
    Indica si el marco de búsqueda está oculto
    """
    findHidden_ = None

    """
    Indica si el marco para conmutar entre datos y filtro está oculto
    """
    filterHidden_ = None

    """
    Indica si se deben mostrar los campos tipo pixmap en todas las filas
    """
    showAllPixmaps_ = None

    """
    Nombre de la función de script a invocar para obtener el color y estilo de las filas y celdas

    El nombre de la función debe tener la forma 'objeto.nombre_funcion' o 'nombre_funcion',
    en el segundo caso donde no se especifica 'objeto' automáticamente se añadirá como
    prefijo el nombre del formulario donde se inicializa el componente FLTableDB seguido de un punto.
    De esta forma si utilizamos un mismo formulario para varias acciones, p.e. master.ui, podemos controlar
    si usamos distintas funciones de obtener color para cada acción (distintos nombres de formularios) o
    una única función común para todas las acciones.

    Ej. Estableciendo 'tdbGetColor' si el componente se inicializa en el formulario maestro de clientes,
    se utilizará 'formclientes.tdbGetColor', si se inicializa en el fomulario maestro de proveedores, se
    utilizará 'formproveedores.tdbGetColor', etc... Si establecemos 'flfactppal.tdbGetColor' siempre se llama a
    esa función independientemente del formulario en el que se inicialize el componente.

    Cuando se está pintando una celda se llamará a esa función pasándole cinco parámentros:
    - Nombre del campo correspondiente a la celda
    - Valor del campo de la celda
    - Cursor de la tabla posicionado en el registro correspondiente a la fila que
      está pintando. AVISO: En este punto los valores del buffer son indefinidos, no se hace refreshBuffer
      por motivos de eficiencia
    - Tipo del campo, ver FLUtilInterface::Type en FLObjectFactory.h
    - Seleccionado. Si es TRUE indica que la celda a pintar está en la fila resaltada/seleccionada.
      Generalmente las celdas en la fila seleccionada se colorean de forma distinta al resto.

    La función debe devolver una array con cuatro cadenas de caracteres;

    [ "color_de_fondo", "color_lapiz", "estilo_fondo", "estilo_lapiz" ]

    En los dos primeros, el color, se puede utilizar cualquier valor aceptado por QColor::setNamedColor, ejemplos;

    "green"
    "#44ADDB"

    En los dos últimos, el estilo, se pueden utilizar los valores aceptados por QBrush::setStyle y QPen::setStyle,
    ver en FLDataTable.cpp las funciones nametoBrushStyle y nametoPenStyle, ejemplos;

    "SolidPattern"
    "DiagCrossPattern"
    "DotLine"
    "SolidLine"

    Si alguno de los valores del array es vacio "", entonces se utilizarán los colores o estilos establecidos por defecto.
    """
    functionGetColor_ = None

    """
    Indica que no se realicen operaciones con la base de datos (abrir formularios). Modo "sólo tabla".
    """
    onlyTable_ = None
    reqOnlyTable_ = None

    """
    Editor falso
    """
    fakeEditor_ = None

    tableDB_filterRecords_functionName_ = None

    """
    Actualiza el conjunto de registros.
    """

    @decorators.BetaImplementation
    @QtCore.pyqtSlot()
    @QtCore.pyqtSlot(bool)
    @QtCore.pyqtSlot(bool, bool)
    def refresh(self, refreshHead=False, refreshData=False):
        if not self.cursor_ or not self.tableRecords_:
            return

        tMD = self.cursor_.metadata()
        if not tMD:
            return

        if not self.tableName_:
            self.tableName_ = tMD.name()

        if refreshHead:
            if not self.tableRecords_.isHidden():
                self.tableRecords_.hide()

            model = self.cursor_.model()

            for column in range(model.columnCount()):
                field = model.metadata().indexFieldObject(column)
                if not field.visibleGrid():
                    self.tableRecords_.setColumnHidden(column, True)
                else:
                    self.tableRecords_.setColumnHidden(column, False)

            # FIXME: Este proceso es MUY LENTO. No deberíamos hacer esto.
            # Hay que buscar alguna forma manual de iterar las primeras N filas, o calcular un
            # valor por defecto rápidamente.
            self.tableRecords_._h_header.setResizeMode(QtGui.QHeaderView.ResizeToContents)
            if model.rows * model.cols > 500 * 10:
                # Esto evitará que se calcule para las que tienen más de 500*10 celdas.
                self.tableRecords_._h_header.setResizeMode(0)
            # ... de todos modos tendríamos que, con un timer o algo para desactivar el modo. Una vez
            # ... ya redimensionadas inicialmente, lo único que hace es lastrar Pineboo mucho.

        if refreshData or self.sender():

            finalFilter = self.filter_
            if self.tdbFilterBuildWhere_:
                if not finalFilter:
                    finalFilter = self.tdbFilterLastWhere_
                else:
                    finalFilter = "%s and %s" % (finalFilter, self.tdbFilterLastWhere_)

            self.tableRecords_.setPersistentFilter(finalFilter)
            self.tableRecords_.refresh()

        if self.initSearch_:
            try:
                self.lineEditSearch.textChanged.disconnect(self.filterRecords)
            except:
                pass
            self.lineEditSearch.setText(self.initSearch_)
            self.lineEditSearch.textChanged.connect(self.filterRecords)
            self.lineEditSearch.selectAll()
            self.initSearch_ = None
            self.seekCursor()

        if not self.readonly_ == self.reqReadOnly_ or (
            self.tableRecords_ and not self.readonly_ == self.tableRecords_.flReadOnly()
        ):
            self.setReadOnly(self.reqReadOnly_)

        if not self.editonly_ == self.reqEditOnly_ or (
            self.tableRecords_ and not self.editonly_ == self.tableRecords_.editOnly()
        ):
            self.setEditOnly(self.reqEditOnly_)

        if not self.insertonly_ == self.reqInsertOnly_ or (
            self.tableRecords_ and not self.insertonly_ == self.tableRecords_.insertOnly()
        ):
            self.setInsetOnly(self.reqInsertOnly_)

        if not self.onlyTable_ == self.reqOnlyTable_ or (
            self.tableRecords_ and not self.onlyTable_ == self.tableRecords_.onlyTable()
        ):
            self.setOnlyTable(self.reqOnlyTable_)

        if self.tableRecords_ and self.tableRecords_.isHidden():
            self.tableRecords_.show()

    """
    Actualiza el conjunto de registros con un retraso.

    Acepta un lapsus de tiempo en milisegundos, activando el cronómetro interno para
    que realize el refresh definitivo al cumplirse dicho lapsus.

    @param msec Cantidad de tiempo del lapsus, en milisegundos.
    """

    def refreshDelayed(self, msec=50, refreshData=True):

        if not self.cursor_.modeAccess() == FLSqlCursor.Browse:
            return

        if refreshData:
            self._refreshData = True
        else:
            self._refreshData = False
            QtCore.QTimer.singleShot(msec, self.refreshDelayed2)

        self.seekCursor()

    def refreshDelayed2(self):
        self.refresh(False, self._refreshData)
        self._refreshData = None

    """
    Invoca al método FLSqlCursor::insertRecord()
    """

    @QtCore.pyqtSlot()
    def insertRecord(self):

        w = self.sender()
        if w and (
            not self.cursor_
            or self.reqReadOnly_
            or self.reqEditOnly_
            or self.reqOnlyTable_
            or (self.cursor_.cursorRelation() and self.cursor_.cursorRelation().isLocked())
        ):
            w.setDisabled(True)
            return

        if self.cursor_:
            self.cursor_.insertRecord()

    """
    Invoca al método FLSqlCursor::editRecord()
    """

    @QtCore.pyqtSlot()
    def editRecord(self):
        w = self.sender()
        if w and (
            not self.cursor_
            or self.reqReadOnly_
            or self.reqEditOnly_
            or self.reqOnlyTable_
            or (self.cursor_.cursorRelation() and self.cursor_.cursorRelation().isLocked())
        ):
            w.setDisabled(True)
            return

        if self.cursor_:
            self.cursor_.editRecord()

    """
    Invoca al método FLSqlCursor::browseRecord()
    """

    @QtCore.pyqtSlot()
    def browseRecord(self):

        w = self.sender()
        if w and (not self.cursor_ or self.reqOnlyTable_):
            w.setDisaBled(True)
            return

        if self.cursor_:
            self.cursor_.browseRecord()

    """
    Invoca al método FLSqlCursor::deleteRecord()
    """

    @QtCore.pyqtSlot()
    def deleteRecord(self):
        w = self.sender()
        if w and (
            not self.cursor_
            or self.reqReadOnly_
            or self.reqInsertOnly_
            or self.reqEditOnly_
            or self.reqOnlyTable_
            or (self.cursor_.cursorRelation() and self.cursor_.cursorRelation().isLocked())
        ):
            w.setDisabled(True)
            return

        if self.cursor_:
            self.cursor_.deleteRecord()

    """
    Invoca al método FLSqlCursor::copyRecord()
    """

    @QtCore.pyqtSlot()
    def copyRecord(self):
        w = self.sender()
        if w and (
            not self.cursor_
            or self.reqReadOnly_
            or self.reqEditOnly_
            or self.reqOnlyTable_
            or (self.cursor_.cursorRelation() and self.cursor_.cursorRelation().isLocked())
        ):
            w.setDisabled(True)
            return

        if self.cursor_:
            self._cursor.copyRecord()

    """
    Coloca la columna como primera pasando el nombre del campo.

    Este slot está conectado al cuadro combinado de busqueda
    del componente. Cuando seleccionamos un campo este se coloca
    como primera columna y se reordena la tabla con esta columna.
    De esta manera siempre tendremos la tabla ordenada mediante
    el campo en el que queremos buscar.

    @param c Nombre del campo, esta columna intercambia su posion con la primera columna
    @return Falso si no existe el campo
    @author [email protected]
    @author InfoSiAL, S.L.
    """

    @QtCore.pyqtSlot(int)
    @QtCore.pyqtSlot(str)
    def putFirstCol(self, c):
        _index = c
        if isinstance(c, str):
            _index = self.tableRecords_.realColumnIndex(c)

        if _index < 0:
            return False

        self.moveCol(_index, 0)
        return True

    """
    Coloca la columna como segunda pasando el nombre del campo.

    @author Silix - dpinelo
    """

    @QtCore.pyqtSlot(int)
    @QtCore.pyqtSlot(str)
    def putSecondCol(self, c):
        _index = c
        if isinstance(c, str):
            _index = self.tableRecords_.realColumnIndex(c)

        if _index < 0:
            return False

        self.moveCol(_index, 1)
        return True

    """
    Mueve una columna de un campo origen a la columna de otro campo destino

    @param  from  Nombre del campo de la columna de origen
    @param  to    Nombre del campo de la columna de destino
    @param  firstSearch dpinelo: Indica si se mueven columnas teniendo en cuenta que esta función
            se ha llamado o no, desde el combo principal de búsqueda y filtrado
    """

    @decorators.BetaImplementation
    def moveCol(self, from_, to, firstSearch=True):

        _oldFirst = None

        if from_ < 0 or to < 0:
            return

        tMD = self.cursor_.metadata()
        if not tMD:
            return

        self.tableRecords_.hide()

        textSearch = self.lineEditSearch.text()

        field = self.cursor_.metadata().indexFieldObject(to)

        if to == 0:  # Si ha cambiado la primera columna

            try:
                self.comboBoxFieldToSearch.currentIndexChanged.disconnect(self.putFirstCol)
            except:
                pass

            self.comboBoxFieldToSearch.setCurrentIndex(from_)
            self.comboBoxFieldToSearch.currentIndexChanged.connect(self.putFirstCol)

            # Actializamos el segundo combo
            try:
                self.comboBoxFieldToSearch2.currentIndexChanged.disconnect(self.putSecondCol)
            except:
                pass
            # Falta mejorar
            if self.comboBoxFieldToSearch.currentIndex() == self.comboBoxFieldToSearch2.currentIndex():
                self.comboBoxFieldToSearch2.setCurrentIndex(self.tableRecords_._h_header.logicalIndex(0))
            self.comboBoxFieldToSearch2.currentIndexChanged.connect(self.putSecondCol)

        if to == 1:  # Si es la segunda columna ...
            try:
                self.comboBoxFieldToSearch2.currentIndexChanged.disconnect(self.putSecondCol)
            except:
                pass
            self.comboBoxFieldToSearch2.setCurrentIndex(from_)
            self.comboBoxFieldToSearch2.currentIndexChanged.connect(self.putSecondCol)

            if self.comboBoxFieldToSearch.currentIndex() == self.comboBoxFieldToSearch2.currentIndex():
                try:
                    self.comboBoxFieldToSearch.currentIndexChanged.disconnect(self.putFirstCol)
                except:
                    pass
                if self.comboBoxFieldToSearch.currentIndex() == self.comboBoxFieldToSearch2.currentIndex():
                    self.comboBoxFieldToSearch.setCurrentIndex(self.tableRecords_._h_header.logicalIndex(1))
                self.comboBoxFieldToSearch.currentIndexChanged.connect(self.putFirstCol)

        if not textSearch:
            textSearch = self.cursor_.value(field.name())

        self.refresh(True)

        if textSearch:
            self.refresh(False, True)
            try:
                self.lineEditSearch.textChanged.disconnect(self.filterRecords)
            except:
                pass
            self.lineEditSearch.setText(textSearch)
            self.lineEditSearch.textChanged.connect(self.filterRecords)
            self.lineEditSearch.selectAll()
            self.seekCursor()
            QtCore.QTimer.singleShot(0, self.tableRecords_.ensureRowSelectedVisible())
        else:
            self.refreshDelayed()

        from_ = self.tableRecords_.visualIndexToRealIndex(from_)
        self.tableRecords_._h_header.swapSections(from_, to)

        self.refresh(True)

        """
        if textSearch:
            self.refresh(False, True)

            if firstSearch:
                self.lineEditSearch.textChanged.disconnect(self.filterRecords)
                self.lineEditSearch.setText(textSearch)
                self.lineEditSearch.textChanged.connect(self.filterRecords)
                self.lineEditSearch.selectAll()

            self.seekCursor()
            QtCore.QTimer.singleShot(0,self.tableRecords_.ensureRowSelectedVisible)
        else:
            self.refreshDelayed()
            if not self.sender():
                self.lineEditSearch.setFocus()

        """
        # self.tableRecords_.show()

    """
    Inicia el cursor segun este campo sea de la tabla origen o de
    una tabla relacionada
    """

    def initCursor(self):
        if not self.topWidget or not self.cursor_:
            return

        if not self.cursor_.metadata():
            return

        tMD = None

        if not self.sortField_:
            tMD = self.cursor_.metadata()
            if tMD:
                self.sortField_ = tMD.field(tMD.primaryKey())

        ownTMD = None
        if self.tableName_:
            if not self.cursor_.db().manager().existsTable(self.tableName_):
                ownTMD = True
                tMD = self.cursor_.db().manager().createTable(self.tableName_)
            else:
                ownTMD = True
                tMD = self.cursor_.db().manager().metadata(self.tableName_)

            if not tMD:
                return

            if not self.foreignField_ or not self.fieldRelation_:
                if not self.cursor_.metadata():
                    if ownTMD and tMD and not tMD.inCache():
                        del tMD
                    return

                if not self.cursor_.metadata().name() == self.tableName_:
                    ctxt = self.cursor_.context()
                    self.cursor_ = FLSqlCursor(
                        self.tableName_, True, self.cursor_.db().connectionName(), None, None, self
                    )

                    if self.cursor_:
                        self.cursor_.setContext(ctxt)
                        self.cursorAux = None

                    if ownTMD and tMD and not tMD.inCache():
                        del tMD

                    return

            else:
                cursorTopWidget = self.topWidget.cursor()
                if cursorTopWidget and not cursorTopWidget.metadata().name() == self.tableName_:
                    self.cursor_ = cursorTopWidget

        if not self.tableName_ or not self.foreignField_ or not self.fieldRelation_ or self.cursorAux:
            if ownTMD and tMD and not tMD.inCache():
                del tMD

            return

        self.cursorAux = self.cursor_
        curName = self.cursor_.metadata().name()
        rMD = self.cursor_.metadata().relation(self.foreignField_, self.fieldRelation_, self.tableName_)
        testM1 = tMD.relation(self.fieldRelation_, self.foreignField_, curName)
        checkIntegrity = False
        if not rMD:
            if testM1:
                if testM1.cardinality() == FLRelationMetaData.RELATION_M1:
                    checkIntegrity = True
            fMD = self.cursor_.metadata().field(self.foreignField_)
            if fMD:
                tmdAux = self.cursor_.db().manager().metadata(self.tableName_)
                if not tmdAux or tmdAux.isQuery():
                    checkIntegrity = False
                if tmdAux and not tmdAux.inCache():
                    del tmdAux

                rMD = FLRelationMetaData(
                    self.tableName_, self.fieldRelation_, FLRelationMetaData.RELATION_1M, False, False, checkIntegrity
                )
                fMD.addRelationMD(rMD)
                # print("FLTableDB : La relación entre la tabla del formulario %s y esta tabla %s de este campo no existe, pero sin embargo se han indicado los campos de relación( %s, %s )" % ( curName, self.tableName_, self.fieldRelation_, self.foreignField_))
                # print("FLTableDB : Creando automáticamente %s.%s --1M--> %s.%s" % (curName, self.foreignField_, self.tableName_, self.fieldRelation_))
            else:
                # print("FLTableDB : El campo ( %s ) indicado en la propiedad foreignField no se encuentra en la tabla ( %s )" % (self.foreignField_, curName))
                pass

        rMD = testM1
        if not rMD:
            fMD = tMD.field(self.fieldRelation_)
            if fMD:
                rMD = FLRelationMetaData(
                    curName, self.foreignField_, FLRelationMetaData.RELATION_1M, False, False, False
                )
                fMD.addRelationMD(rMD)
                print(
                    "FLTableDB : Creando automáticamente %s.%s --1M--> %s.%s"
                    % (self.tableName_, self.fieldRelation_, curName, self.foreignField_)
                )

            else:
                print(
                    "FLTableDB : El campo ( %s ) indicado en la propiedad fieldRelation no se encuentra en la tabla ( %s )"
                    % (self.fieldRelation_, self.tableName_)
                )

        self.cursor_ = FLSqlCursor(self.tableName_, True, self.cursor_.db().connectionName(), self.cursorAux, rMD, self)
        if not self.cursor_:
            self.cursor_ = self.cursorAux
            self.cursorAux = None

        else:

            self.cursor_.setContext(self.cursorAux.context())
            if self.showed:
                try:
                    self.cursorAux.newBuffer.disconnect(self.refresh)
                except:
                    pass

            self.cursorAux.newBuffer.connect(self.refresh)

        if self.cursorAux and isinstance(self.topWidget, FLFormSearchDB):
            self.topWidget.setCaption(self.cursor_.metadata().alias())
            self.topWidget_.setCursor(self.cursor_)

        if ownTMD or tMD and not tMD.inCache():
            del tMD

    """
    Posiciona el cursor en un registro valido
    """

    @decorators.NotImplementedWarn
    def seekCursor(self):
        return
        textSearch = self.lineEditSearch.text()
        if not textSearch:
            return

        if not self.cursor_:
            return

        fN = self.sortField_.name()
        textSearch.replace("%", "")

        if not "'" in textSearch and not "\\" in textSearch:
            sql = self.cursor_.executedQuery() + " LIMIT 1"
        """
            #QSqlQuery qry(sql, cursor_->db()->db()); #FIXME
            if (qry.first()) {
      QString v(qry.value(0).toString());
      int pos = -1;
      if (!v.upper().startsWith(textSearch.upper()))
        pos = cursor_->atFromBinarySearch(fN, textSearch, orderAsc_);
      if (pos == -1)
        pos = cursor_->atFromBinarySearch(fN, v, orderAsc_);
      cursor_->seek(pos, false, true);
      """

    """
    Redefinida por conveniencia
    """

    @decorators.NotImplementedWarn
    def setEnabled(self, b):
        pass

    """
    Establece el ancho de una columna

    @param  field Nombre del campo de la base de datos correspondiente a la columna
    @param  w     Ancho de la columna
    """

    @decorators.NotImplementedWarn
    def setColumnWidth(self, field, w):
        pass

    """
    @return Ancho de la columna
    """

    @decorators.NotImplementedWarn
    def columnWidth(self, c):
        pass

    """
    Establece el alto de una fila

    @param  row Número de orden de la fila, empezando en 0
    @param  h   Alto de la fila
    """

    @decorators.NotImplementedWarn
    def setRowHeight(self, row, h):
        pass

    """
    @return Alto de la fila
    """

    @decorators.NotImplementedWarn
    def rowHeight(self, row):
        pass

    """
    Exporta a una hoja de cálculo ODS y la visualiza
    """

    @decorators.NotImplementedWarn
    def exportToOds(self):
        pass

    """
    Conmuta el sentido de la ordenación de los registros de la tabla, de ascendente a descendente y
    viceversa. Los registros siempre se ordenan por la primera columna.
    Si la propiedad autoSortColumn es TRUE.
    """

    @decorators.NotImplementedWarn
    def switchSortOrder(self, col=0):
        pass

    """
    Filtra los registros de la tabla utilizando el primer campo, según el patrón dado.

    Este slot está conectado al cuadro de texto de busqueda del componente,
    tomando el contenido de este como patrón para el filtrado.

    @param p Cadena de caracteres con el patrón de filtrado
    """

    @QtCore.pyqtSlot(str)
    def filterRecords(self, p):
        if not self.cursor_.model():
            return
        bFilter = None
        p = str(p)
        refreshData = None
        if "%" in p:
            refreshData = True
        msec_refresh = 400
        column = self.tableRecords_._h_header.logicalIndex(0)
        field = self.cursor_.model().metadata().indexFieldObject(column)

        bFilter = self.cursor_.db().manager().formatAssignValue(field, p, True)

        idMod = self.cursor_.db().managerModules().idModuleOfFile(self.cursor_.metadata().name() + ".mtd")

        functionQSA = idMod + ".tableDB_filterRecords_" + self.cursor_.metadata().name()

        vargs = []
        vargs.append(self.cursor_.metadata().name())
        vargs.append(p)
        vargs.append(field.name())
        vargs.append(bFilter)

        if functionQSA:
            msec_refresh = 800
            ret = self.cursor_._prj.call(functionQSA, vargs, None)
            if ret:
                bFilter = ret
                print("functionQSA:%s:" % functionQSA)
            else:
                if p == "":
                    bFilter = None

        self.refreshDelayed(msec_refresh, (bFilter or refreshData))
        self.filter_ = bFilter

    @decorators.NotImplementedWarn
    def setSortOrder(self, ascending):
        pass

    @decorators.NotImplementedWarn
    def isSortOrderAscending(self):
        pass

    """
    Activa la tabla de datos
    """

    @decorators.NotImplementedWarn
    def activeTabData(self, b):
        pass

    """
    Activa la tabla de filtro
    """

    @decorators.NotImplementedWarn
    def activeTabFilter(self, b):
        pass

    """
    Limpia e inicializa el filtro
    """

    @decorators.NotImplementedWarn
    def tdbFilterClear(self):
        pass

    """
    Señal emitida cuando se refresca por cambio de filtro
    """
    refreshed = QtCore.pyqtSignal()

    """
    Señal emitida cuando se establece si el componente es o no de solo lectura.
    """
    readOnlyChanged = QtCore.pyqtSignal(bool)

    """
    Señal emitida cuando se establece si el componente es o no de solo edición.
    """
    editOnlyChanged = QtCore.pyqtSignal(bool)

    """
    Señal emitida cuando se establece si el componente es o no de solo inserción.
    """
    insertOnlyChanged = QtCore.pyqtSignal(bool)

    """
    Señal emitida cuando se establece cambia el registro seleccionado.
    """
    # currentChanged = QtCore.pyqtSignal()

    @QtCore.pyqtSlot()
    @decorators.BetaImplementation
    def chooseRecord(self):
        if isinstance(self.topWidget, FLFormSearchDB):
            if self.topWidget.inExec_:
                self.topWidget.accept()
                return

        if self.cursor().isLocked():
            print("FLTable(%s):Registro bloqueado. Modo Solo lectura" % self.cursor().curName())
            self.browseRecord()
        else:
            self.editRecord()
Ejemplo n.º 21
0
    def insert(table_or_cursor, fields, values, where="", conn=None):

        if isinstance(table_or_cursor, str):
            cur = FLSqlCursor(table_or_cursor, conn)
        else:
            cur = table_or_cursor

        if cur is None:
            return False

        if not cur.metadata():
            return False

        fieldsCount = len(fields)

        cur.setModeAccess(cur.Insert)
        cur.refreshBuffer()

        for i in range(0, fieldsCount - 1):
            cur.setValueBuffer(fields[i], values[i])

        msgCheck = cur.msgCheckIntegrity()
        if msgCheck != "":
            ok = False
            raise Exception(msgCheck)

        ok = False
        actCheck = cur.activatedCheckIntegrity()
        cur.setActivatedCheckIntegrity(False)
        ok = cur.commitBuffer()
        cur.setActivatedCheckIntegrity(actCheck)

        return ok
Ejemplo n.º 22
0
class FLTableDB(QtGui.QWidget):
    _tableView = None
    _vlayout = None
    _lineEdit = None
    _comboBox_1 = None
    _comboBox_2 = None
    topWidget = QtGui.QWidget
    showed = False

    def __init__(self, parent=None, action_or_cursor=None, *args):
        print("FLTableDB:", parent, action_or_cursor, args)
        # TODO: Falta el lineeditsearch y el combo, que los QS lo piden
        super(FLTableDB, self).__init__(parent, *args)
        # TODO: LA inicialización final hay que hacerla más tarde, en el primer
        # show(), porque sino obligas a tenerlo todo preparado en el constructor.
        self._tableView = QtGui.QTableView()
        self._lineEdit = QtGui.QLineEdit()
        _label1 = QtGui.QLabel()
        _label2 = QtGui.QLabel()
        self._comboBox_1 = QtGui.QComboBox()
        self._comboBox_2 = QtGui.QComboBox()
        _label1.setText("Buscar")
        _label2.setText("en")
        self._vlayout = QtGui.QVBoxLayout()
        _hlayout = QtGui.QHBoxLayout()
        self._tableView._v_header = self._tableView.verticalHeader()
        self._tableView._v_header.setDefaultSectionSize(18)
        self._tableView._h_header = self._tableView.horizontalHeader()
        self._tableView._h_header.setDefaultSectionSize(70)
        _hlayout.addWidget(_label1)
        _hlayout.addWidget(self._lineEdit)
        _hlayout.addWidget(_label2)
        _hlayout.addWidget(self._comboBox_1)
        _hlayout.addWidget(self._comboBox_2)
        self._vlayout.addLayout(_hlayout)
        self._vlayout.addWidget(self._tableView)
        self.setLayout(self._vlayout)
        self._parent = parent
        while True:
            parent_cursor = getattr(self._parent, "_cursor", None)
            if parent_cursor: break
            new_parent = self._parent.parentWidget()
            if new_parent is None: break
            self._parent = new_parent
            print(self._parent)

        self._tableView.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
        self._tableView.setSelectionMode(
            QtGui.QAbstractItemView.SingleSelection)
        self._tableView.setSelectionBehavior(
            QtGui.QAbstractItemView.SelectRows)
        self._tableView.setAlternatingRowColors(True)

        if action_or_cursor is None and parent_cursor:
            action_or_cursor = parent_cursor
        if isinstance(action_or_cursor, FLSqlCursor):
            self._cursor = action_or_cursor
        elif isinstance(action_or_cursor, str):
            self._cursor = FLSqlCursor(action_or_cursor)
        else:
            self._cursor = None
        if self._cursor:
            self._tableView._h_header.setResizeMode(
                QtGui.QHeaderView.ResizeToContents)
            self._tableView.setModel(self._cursor._model)
            self._tableView.setSelectionModel(self._cursor.selection())
        self.tableRecords = self  # control de tabla interno

        #Carga de comboBoxs y connects .- posiblemente a mejorar
        if self._cursor:
            for column in range(self._cursor._model.columnCount()):
                self._comboBox_1.addItem(
                    self._cursor._model.headerData(column,
                                                   QtCore.Qt.Horizontal,
                                                   QtCore.Qt.DisplayRole))
                self._comboBox_2.addItem(
                    self._cursor._model.headerData(column,
                                                   QtCore.Qt.Horizontal,
                                                   QtCore.Qt.DisplayRole))
        self._comboBox_1.addItem("*")
        self._comboBox_2.addItem("*")
        self._comboBox_1.setCurrentIndex(0)
        self._comboBox_2.setCurrentIndex(1)
        self._comboBox_1.currentIndexChanged.connect(self.comboBox_putFirstCol)
        self._comboBox_2.currentIndexChanged.connect(
            self.comboBox_putSecondCol)

        self.sort = []
        self.timer_1 = QtCore.QTimer(self)
        self.timer_1.singleShot(100, self.loaded)

    def __getattr__(self, name):
        return DefFun(self, name)

    def loaded(self):
        # Es necesario pasar a modo interactivo lo antes posible
        # Sino, creamos un bug en el cierre de ventana: se recarga toda la tabla para saber el tamaño
        print("FLTableDB: setting columns in interactive mode")
        self._tableView._h_header.setResizeMode(QtGui.QHeaderView.Interactive)

    def cursor(self):
        assert self._cursor
        return self._cursor

    def obj(self):
        return self

    def comboBox_putFirstCol(self):
        self.putFirstCol(str(self._comboBox_1.currentText()))

    def comboBox_putSecondCol(self):
        self.putSecondCol(str(self._comboBox_2.currentText()))

    def putFirstCol(self, fN):
        _oldPos = None
        _oldFirst = self._tableView._h_header.logicalIndex(0)
        for column in range(self._cursor._model.columnCount()):
            if self._cursor._model.headerData(
                    column, QtCore.Qt.Horizontal,
                    QtCore.Qt.DisplayRole).lower() == fN.lower():
                _oldPos = self._tableView._h_header.visualIndex(column)
                if not self._comboBox_1.currentText() == fN:
                    self._comboBox_1.setCurrentIndex(column)
                    return False
                break

        if not _oldPos or fN == "*":
            return False
        else:
            self._tableView._h_header.swapSections(_oldPos, 0)
            self._comboBox_2.setCurrentIndex(_oldFirst)
            return True

    def putSecondCol(self, fN):
        _oldPos = None
        _oldSecond = self._tableView._h_header.logicalIndex(1)
        for column in range(self._cursor._model.columnCount()):
            if self._cursor._model.headerData(
                    column, QtCore.Qt.Horizontal,
                    QtCore.Qt.DisplayRole).lower() == fN.lower():
                _oldPos = self._tableView._h_header.visualIndex(column)
                break

        if not _oldPos or fN == "*":
            return False
        if not self._comboBox_1.currentText() == fN:
            self._tableView._h_header.swapSections(_oldPos, 1)
        else:
            self._comboBox_1.setCurrentIndex(_oldSecond)
        return True

    def setTableName(self, tableName):
        self._tableName = tableName
        if self.showed:
            if self.topWidget:
                self.initCursor()
            else:
                self.initFakeEditor()

    def setForeignField(self, foreingField):
        self._foreingField = foreingField
        if self.showed:
            if self.topWidget:
                self.initCursor()
            else:
                self.initFakeEditor()

    def setFieldRelation(self, fieldRelation):
        self._fieldRelation = fieldRelation
        if self.showed:
            if self.topWidget:
                self.initCursor()
            else:
                self.initFakeEditor()

    @decorators.NotImplementedWarn
    def initCursor(self):
        # si no existe crea la tabla
        if not self._cursor: return False
        if not self._cursor._model: return False

        self._tMD = 0

        if not self._sortField: self._tMD = self._cursor._model.name()
        if self._tMD:
            self.sortField_ = self._tMD.value(self._cursor._currentregister,
                                              self._tMD.primaryKey())
        ownTMD = False
        if not self._tableName:
            #if not cursor_->db()->manager()->existsTable(tableName_)) {
            ownTMD = True
            #tMD = cursor_->db()->manager()->createTable(tableName_);
        else:
            ownTMD = True
            self._tMD = self._cursor._model._table.name

        if not self._tMD:
            return

        if not self._foreignField or not self._fieldRelation:
            if not self._cursor._model:
                if ownTMD and self._tMD and not self._tMD.inCache():
                    self._tMD = None

            return

            if not self._cursor._model.name() == self._tableName:
                ctxt = self._cursor.context()
                self._cursor = FLSqlCursor(self._tableName)
                if self._cursor:
                    self._cursor.setContext(ctxt)
                    cursorAux = 0

                if ownTMD and self._tMD and not self._tMD.inCache():
                    self._tMD = None

                return

        else:
            cursorTopWidget = self.topWidget._cursor(
            )  # ::qt_cast<FLFormDB *>(topWidget)->cursor()
            if cursorTopWidget and not cursorTopWidget._model.name(
            ) == self._tableName:
                self._cursor = cursorTopWidget

        if not self._tableName or not self._foreignField or not self._fieldRelation or cursorAux:
            if ownTMD and self._tMD and not self._tMD.inCache():
                tMD = None

            return

        cursorAux = self._cursor
        curName = self._cursor._model.name()
        rMD = self._cursor._model.relation(self._foreignField,
                                           self._fieldRelation,
                                           self._tableName)
        testM1 = self._tMD.relation(self._fieldRelation, self._foreignField,
                                    curName)
        checkIntegrity = bool(False)

        if not rMD:
            if testM1:
                checkIntegrity = (
                    testM1.cardinality() == FLRelationMetaData.RELATION_M1)
            fMD = FLTableMetaData(self._cursor._model.field(
                self._foreignField))
            if (fMD):
                tmdAux = self._cursor._model(self._tableName)
                if not tmdAux or tmdAux.isQuery():
                    checkIntegrity = False
                if tmdAux and not tmdAux.inCache():  # mirar inCache()
                    tmdAux = None
                rMD = FLRelationMetaData(self._tableName, self._fieldRelation,
                                         FLRelationMetaData.RELATION_1M, False,
                                         False, checkIntegrity)
                fMD.addRelationMD(rMD)
                print(
                    "FLTableDB : La relación entre la tabla del formulario %r y esta tabla %r de este campo no existe, pero sin embargo se han indicado los campos de relación( %r, %r )"
                    % (curName, self._tableName, self._fieldRelation,
                       self._foreignField))
                print(
                    "FLTableDB : Creando automáticamente %r.%r --1M--> %r.%r" %
                    (curName, self._foreignField, self._tableName,
                     self._fieldRelation))

            else:
                print(
                    "FLTableDB : El campo ( %r ) indicado en la propiedad foreignField no se encuentra en la tabla ( %r )"
                    % (self._foreignField, curName))
        rMD = testM1
        if not rMD:
            fMD = FLFieldMetaData(tMD.field(self._fieldRelation))
            if (fMD):
                rMD = FLRelationMetaData(curName, self._foreignField,
                                         FLRelationMetaData.RELATION_1M, False,
                                         False, False)
                fMD.addRelationMD(rMD)
                print(
                    "FLTableDB : Creando automáticamente %r.%r --1M--> %r.%r" %
                    (self._tableName, self._fieldRelation, curName,
                     self._foreignField))
            else:
                print(
                    "FLTableDB : El campo ( %r ) indicado en la propiedad fieldRelation no se encuentra en la tabla ( %r )"
                    % (self._fieldRelation, self._tableName))

        self._cursor = FLSqlCursor(self._tableName, True,
                                   self._cursor.db().connectionName(),
                                   cursorAux, rMD, self)
        if not self._cursor:
            self._cursor = cursorAux
            cursorAux = 0
        else:
            self._cursor.setContext(cursorAux.context())
        if self.showed:
            self.disconnect(cursorAux, QtCore.SIGNAL('newBuffer()'),
                            self.refresh())
            self.connect(cursorAux, QtCore.SIGNAL('newBuffer()'),
                         self.refresh())

        if cursorAux and self.topWidget.isA("FLFormSearchDB"):
            self.topWidget.setCaption(self._cursor._model.alias())
            self.topWidget.setCursor(
                self._cursor
            )  #::qt_cast<FLFormSearchDB *>(topWidget)->setCursor(cursor_);

        if ownTMD and tMD and not tMD.inCache():
            tMD = None

    @QtCore.pyqtSlot()
    def close(self):
        print("FLTableDB: close()")

    @QtCore.pyqtSlot()
    def refresh(self):
        print("FLTableDB: refresh()", self.parent().parent().parent())
        self._cursor.refresh()

    @QtCore.pyqtSlot()
    def show(self):
        print("FLTableDB: show event")
        super(FLTableDB, self).show()

    @QtCore.pyqtSlot()
    def insertRecord(self):
        self._cursor.insertRecord()

    @QtCore.pyqtSlot()
    def editRecord(self):
        self._cursor.editRecord()

    @QtCore.pyqtSlot()
    def deleteRecord(self):
        self._cursor.deleteRecord()

    @QtCore.pyqtSlot()
    def browseRecord(self):
        self._cursor.browseRecord()

    @QtCore.pyqtSlot()
    def copyRecord(self):
        self._cursor.copyRecord()
Ejemplo n.º 23
0
    def sqlDelete(self, t, w, connName="default"):
        """
        Borra uno o más registros en una tabla mediante un objeto FLSqlCursor

        @param t Nombre de la tabla
        @param w Sentencia where para identificar los registros a borrar.
        @param connName Nombre de la conexion
        @return Verdadero en caso de realizar la inserción con éxito, falso en cualquier otro caso
        """
        from pineboolib.fllegacy.FLSqlCursor import FLSqlCursor
        c = FLSqlCursor(t, True, connName)

        # if not c.select(w):
        #     return False
        c.select(w)
        c.setForwardOnly(True)

        while c.next():
            c.setModeAccess(FLSqlCursor.Del)
            c.refreshBuffer()
            if not c.commitBuffer():
                return False

        return True
Ejemplo n.º 24
0
    def initCursor(self):
        if not self.topWidget or not self.cursor_:
            return

        if not self.cursor_.metadata():
            return

        
        tMD = self.cursor_.metadata()
        if not self.sortField_:
            if tMD:
                self.sortField_ = tMD.field(tMD.primaryKey())


        ownTMD = None
        if self.tableName_:
            if DEBUG: print("**FLTableDB::name: %r tableName: %r" % (self.objectName(), self.tableName_))

            if not self.cursor_.db().manager().existsTable(self.tableName_):
                ownTMD = True
                tMD = self.cursor_.db().manager().createTable(self.tableName_)
            else:
                ownTMD = True
                tMD = self.cursor_.db().manager().metadata(self.tableName_)

            if not tMD or isinstance(tMD,bool):
                return

            if not self.foreignField_ or not self.fieldRelation_:
                if not self.cursor_.metadata():
                    if ownTMD and tMD and not tMD.inCache():
                        del tMD
                    return

                if not self.cursor_.metadata().name() == self.tableName_:
                    ctxt = self.cursor_.context()
                    self.cursor_ = FLSqlCursor(self.tableName_, True, self.cursor_.db().connectionName(), None, None , self)


                    if self.cursor_:
                        self.cursor_.setContext(ctxt)
                        self.cursorAux = None

                    if ownTMD and tMD and not tMD.inCache():
                        del tMD

                    return

            else:
                cursorTopWidget = self.topWidget.cursor()
                if cursorTopWidget and not cursorTopWidget.metadata().name() == self.tableName_:
                    self.cursor_ = cursorTopWidget

        if not self.tableName_ or not self.foreignField_ or not self.fieldRelation_ or self.cursorAux:
            if ownTMD and tMD and not tMD.inCache():
                del tMD

            return

        self.cursorAux = self.cursor_
        curName = self.cursor_.metadata().name()
        rMD =  self.cursor_.metadata().relation(self.foreignField_, self.fieldRelation_, self.tableName_)
        testM1 = tMD.relation(self.fieldRelation_, self.foreignField_, curName)
        checkIntegrity = False
        if not rMD:
            if testM1:
                if testM1.cardinality() == FLRelationMetaData.RELATION_M1:
                    checkIntegrity = True
            fMD = self.cursor_.metadata().field(self.foreignField_)
            if fMD:
                tmdAux = self.cursor_.db().manager().metadata(self.tableName_)
                if not tmdAux or tmdAux.isQuery():
                    checkIntegrity = False
                if tmdAux and not tmdAux.inCache():
                    del tmdAux

                rMD = FLRelationMetaData(self.tableName_, self.fieldRelation_, FLRelationMetaData.RELATION_1M, False, False, checkIntegrity)
                fMD.addRelationMD(rMD)
                #print("FLTableDB : La relación entre la tabla del formulario %s y esta tabla %s de este campo no existe, pero sin embargo se han indicado los campos de relación( %s, %s )" % ( curName, self.tableName_, self.fieldRelation_, self.foreignField_))
                #print("FLTableDB : Creando automáticamente %s.%s --1M--> %s.%s" % (curName, self.foreignField_, self.tableName_, self.fieldRelation_))
            else:
                #print("FLTableDB : El campo ( %s ) indicado en la propiedad foreignField no se encuentra en la tabla ( %s )" % (self.foreignField_, curName))
                pass

        rMD = testM1
        if not rMD:
            fMD = tMD.field(self.fieldRelation_)
            if fMD:
                rMD = FLRelationMetaData(curName, self.foreignField_, FLRelationMetaData.RELATION_1M, False, False, False)
                fMD.addRelationMD(rMD)
                if DEBUG: print("FLTableDB : Creando automáticamente %s.%s --1M--> %s.%s" % (self.tableName_, self.fieldRelation_, curName, self.foreignField_))

            else:
                if DEBUG: print("FLTableDB : El campo ( %s ) indicado en la propiedad fieldRelation no se encuentra en la tabla ( %s )" % (self.fieldRelation_, self.tableName_))

        self.cursor_ = FLSqlCursor(self.tableName_, True, self.cursor_.db().connectionName(), self.cursorAux, rMD, self)
        if not self.cursor_:
            self.cursor_ = self.cursorAux
            self.cursorAux = None

        else:

            self.cursor_.setContext(self.cursorAux.context())
            if self.showed:
                try:
                    self.cursorAux.newBuffer.disconnect(self.refresh)
                except:
                    pass

            self.cursorAux.newBuffer.connect(self.refresh)

        if self.cursorAux and isinstance(self.topWidget, FLFormSearchDB):
            self.topWidget.setCaption(self.cursor_.metadata().alias())
            self.topWidget_.setCursor(self.cursor_)

        if ownTMD or tMD and not tMD.inCache():
            del tMD
Ejemplo n.º 25
0
class FLTableDB(QtGui.QWidget):

    """
    PLUGIN que contiene una tabla de la base de datos.

    Este objeto contiene todo lo necesario para manejar
    los datos de una tabla. Además de la funcionalidad de
    busqueda en la tabla por un campo, mediante filtros.

    Este plugin para que sea funcional debe tener como uno
    de sus padres o antecesor a un objeto FLFormDB.

    @author InfoSiAL S.L.
    """

    """
    Tipos de condiciones para el filtro
    """
    All = None
    Contains = None
    Starts = None
    End = None
    Equal = None
    Dist = None
    Greater = None
    Less = None
    FromTo = None
    Null = None
    NotNull = None


    _parent = None
    _name = None
    loadLater_ = None




    comboBoxFieldToSearch = None
    comboBoxFieldToSearch2 = None
    tableRecords_ = None
    lineEditSearch = None

    tabDataLayout = None
    tabControlLayout = None

    _initCursorWhenLoad = None
    _initTableRecordWhenLoad = None


    _controlsInit = None

    """
    constructor
    """

    def __init__(self, parent, name = None):
        super(FLTableDB, self).__init__(parent)

        self.topWidget = parent
        self.timer_1 = QtCore.QTimer(self)
        self.timer_1.singleShot(0, self.loaded)

    def __getattr__(self, name):
        return DefFun(self, name)






    def loaded(self):
        # Es necesario pasar a modo interactivo lo antes posible
        # Sino, creamos un bug en el cierre de ventana: se recarga toda la tabla para saber el tamaño
        #print("FLTableDB(%s): setting columns in interactive mode" % self._tableName)
        while True: #Ahora podemos buscar el cursor ... porque ya estamos añadidos al formulario
            parent_cursor = getattr(self.topWidget,"cursor_", None)
            if parent_cursor: break
            new_parent = self.topWidget.parentWidget()
            if new_parent is None: break
            self.topWidget = new_parent
        
        
        if getattr(self.topWidget.parentWidget(), "cursor_", None):
            self.topWidget = self.topWidget.parentWidget()
            
        if not parent_cursor:
            print("FLTableDB : Uno de los padres o antecesores de FLTableDB deber ser de la clase FLFormDB o heredar de ella")
            return

        self.cursor_ = self.topWidget.cursor_
        self.setFont(QtGui.qApp.font())

        if not self._name:
            self.setName("FLTableDB")
            
        self.timer = QtCore.QTimer(self)
        self.timer.timeout.connect(self.refreshDelayed)

        # FIXME: El problema de que aparezca al editar un registro que no es, es por carga doble de initCursor()
        # ...... Cuando se lanza showWidget, y tiene _initCursorWhenLoad, lanza initCursor y luego otra vez.
        # ...... esta doble carga provoca el error y deja en el formulario el cursor original.
        self._initCursorWhenLoad = False
        self.showWidget() 
        self._loaded = True

        self.initCursor()
        if DEBUG: print("**FLTableDB::name: %r cursor: %r" % (self.objectName(), self.cursor_.d.nameCursor_))
        
    def setName(self, name):
        self._name = name

    """
    Inicia el cursor segun este campo sea de la tabla origen o de
    una tabla relacionada
    """
    def initCursor(self):
        if not self.topWidget or not self.cursor_:
            return

        if not self.cursor_.metadata():
            return

        
        tMD = self.cursor_.metadata()
        if not self.sortField_:
            if tMD:
                self.sortField_ = tMD.field(tMD.primaryKey())


        ownTMD = None
        if self.tableName_:
            if DEBUG: print("**FLTableDB::name: %r tableName: %r" % (self.objectName(), self.tableName_))

            if not self.cursor_.db().manager().existsTable(self.tableName_):
                ownTMD = True
                tMD = self.cursor_.db().manager().createTable(self.tableName_)
            else:
                ownTMD = True
                tMD = self.cursor_.db().manager().metadata(self.tableName_)

            if not tMD or isinstance(tMD,bool):
                return

            if not self.foreignField_ or not self.fieldRelation_:
                if not self.cursor_.metadata():
                    if ownTMD and tMD and not tMD.inCache():
                        del tMD
                    return

                if not self.cursor_.metadata().name() == self.tableName_:
                    ctxt = self.cursor_.context()
                    self.cursor_ = FLSqlCursor(self.tableName_, True, self.cursor_.db().connectionName(), None, None , self)


                    if self.cursor_:
                        self.cursor_.setContext(ctxt)
                        self.cursorAux = None

                    if ownTMD and tMD and not tMD.inCache():
                        del tMD

                    return

            else:
                cursorTopWidget = self.topWidget.cursor()
                if cursorTopWidget and not cursorTopWidget.metadata().name() == self.tableName_:
                    self.cursor_ = cursorTopWidget

        if not self.tableName_ or not self.foreignField_ or not self.fieldRelation_ or self.cursorAux:
            if ownTMD and tMD and not tMD.inCache():
                del tMD

            return

        self.cursorAux = self.cursor_
        curName = self.cursor_.metadata().name()
        rMD =  self.cursor_.metadata().relation(self.foreignField_, self.fieldRelation_, self.tableName_)
        testM1 = tMD.relation(self.fieldRelation_, self.foreignField_, curName)
        checkIntegrity = False
        if not rMD:
            if testM1:
                if testM1.cardinality() == FLRelationMetaData.RELATION_M1:
                    checkIntegrity = True
            fMD = self.cursor_.metadata().field(self.foreignField_)
            if fMD:
                tmdAux = self.cursor_.db().manager().metadata(self.tableName_)
                if not tmdAux or tmdAux.isQuery():
                    checkIntegrity = False
                if tmdAux and not tmdAux.inCache():
                    del tmdAux

                rMD = FLRelationMetaData(self.tableName_, self.fieldRelation_, FLRelationMetaData.RELATION_1M, False, False, checkIntegrity)
                fMD.addRelationMD(rMD)
                #print("FLTableDB : La relación entre la tabla del formulario %s y esta tabla %s de este campo no existe, pero sin embargo se han indicado los campos de relación( %s, %s )" % ( curName, self.tableName_, self.fieldRelation_, self.foreignField_))
                #print("FLTableDB : Creando automáticamente %s.%s --1M--> %s.%s" % (curName, self.foreignField_, self.tableName_, self.fieldRelation_))
            else:
                #print("FLTableDB : El campo ( %s ) indicado en la propiedad foreignField no se encuentra en la tabla ( %s )" % (self.foreignField_, curName))
                pass

        rMD = testM1
        if not rMD:
            fMD = tMD.field(self.fieldRelation_)
            if fMD:
                rMD = FLRelationMetaData(curName, self.foreignField_, FLRelationMetaData.RELATION_1M, False, False, False)
                fMD.addRelationMD(rMD)
                if DEBUG: print("FLTableDB : Creando automáticamente %s.%s --1M--> %s.%s" % (self.tableName_, self.fieldRelation_, curName, self.foreignField_))

            else:
                if DEBUG: print("FLTableDB : El campo ( %s ) indicado en la propiedad fieldRelation no se encuentra en la tabla ( %s )" % (self.fieldRelation_, self.tableName_))

        self.cursor_ = FLSqlCursor(self.tableName_, True, self.cursor_.db().connectionName(), self.cursorAux, rMD, self)
        if not self.cursor_:
            self.cursor_ = self.cursorAux
            self.cursorAux = None

        else:

            self.cursor_.setContext(self.cursorAux.context())
            if self.showed:
                try:
                    self.cursorAux.newBuffer.disconnect(self.refresh)
                except:
                    pass

            self.cursorAux.newBuffer.connect(self.refresh)

        if self.cursorAux and isinstance(self.topWidget, FLFormSearchDB):
            self.topWidget.setCaption(self.cursor_.metadata().alias())
            self.topWidget_.setCursor(self.cursor_)

        if ownTMD or tMD and not tMD.inCache():
            del tMD





    """
    Para obtener el cursor utilizado por el componente.

    return Objeto FLSqlCursor con el cursor que contiene los registros para ser utilizados en el formulario
    """
    def cursor(self):
        if not self.cursor_.d.buffer_:
            self.cursor_.refreshBuffer()
        return self.cursor_

    """
    Para obtener el nombre de la tabla asociada.

    @return Nombre de la tabla asociado
    """
    def tableName(self):
        return self.tableName_


    """
    Para establecer el nombre de la tabla asociada.

    @param fT Nombre de la tabla asociada
    """
    def setTableName(self, fT):
        self.tableName_ = fT

        if self.showed:
            if self.topwidget:
                self.initCursor()
            else:
                self.initFakeEditor()

        else:
            self._initCursorWhenLoad = True
            self._initTableRecordWhenLoad = True


    """
    Para obtener el nombre del campo foráneo.

    @return Nombre del campo
    """
    def foreignField(self):
        return self.foreignField_

    """
    Para establecer el nombre del campo foráneo.

    @param fN Nombre del campo
    """
    def setForeignField(self, fN):
        self.foreignField_ = fN
        if self.showed:
            if self.topwidget:
                self.initCursor()
            else:
                self.initFakeEditor()
        else:
            self._initCursorWhenLoad = True
            self._initTableRecordWhenLoad = True
    """
    Para obtener el nombre del campo relacionado.

    @return Nombre del campo
    """
    def fieldRelation(self):
        return self.fieldRelation_

    """
    Para establecer el nombre del campo relacionado.

    @param fN Nombre del campo
    """
    def setFieldRelation(self, fN):
        self.fieldRelation_ = fN
        if self.showed:
            if self.topwidget:
                self.initCursor()
            else:
                self.initFakeEditor()

        else:
            self._initCursorWhenLoad = True
            self._initTableRecordWhenLoad = True
    """
    Establece si el componente esta en modo solo lectura o no.
    """
    def setReadOnly(self, mode):
        if self.tableRecords_:
            self.readonly = mode
            self.tableRecords_.setFLReadOnly(mode)
            #self.readOnlyChanged(mode).emit() FIXME

        self.reqReadOnly_ = mode


    def readOnly(self):
        return self.reqReadOnly_

    """
    Establece si el componente esta en modo solo edición o no.
    """
    def setEditOnly(self, mode):
        if self.tableRecords_:
            self.editonly_ = mode
            self.tableRecords_.setEditOnly(mode)
            #self.editOnlyChanged(mode).emit() #FIXME

        self.reqEditOnly_ = mode

    def editOnly(self):
        return self.reqEditOnly_

    """
    Establece el componente a sólo inserción o no.
    """
    def setInsertOnly(self, mode):
        if self.tableRecords_:
            self.insertonly_ = mode
            self.tableRecords_.setInsertOnly(mode)
            self.insertOnlyChanged(mode).emit()

        self.reqInsertOnly = mode

    def insertOnly(self):
        return self.reqInsertOnly_

    """
    Establece el filtro inicial de búsqueda
    """
    def setInitSearch(self, iS):
        self.initSearch_ = iS

    """
    Establece el orden de las columnas de la tabla.

    @param fields Lista de los nombres de los campos ordenada según se desea que aparezcan en la tabla de izquierda a derecha
    """
    @decorators.NotImplementedWarn
    def setOrderCols(self, fields):
        pass

    """
    Devuelve la lista de los campos ordenada por sus columnas en la tabla de izquierda a derecha
    """
    @decorators.NotImplementedWarn
    def orderCols(self):
        return None

    """
    Establece el filtro de la tabla

    @param f Sentencia Where que establece el filtro
    """
    @decorators.NotImplementedWarn
    def setFilter(self, f):
        pass

    """
    Devuelve el filtro de la tabla

    @return Filtro
    """
    @decorators.NotImplementedWarn
    def filter(self):
        return None

    """
    Devuelve el filtro de la tabla impuesto en el Find

    @return Filtro
    """
    @decorators.NotImplementedWarn
    def findFilter(self):
        return None

    """
    Obtiene si la columna de selección está activada
    """
    @decorators.NotImplementedWarn
    def checkColumnEnabled(self):
        return None

    """
    Establece el estado de activación de la columna de selección

    El cambio de estado no será efectivo hasta el siguiente refresh.
    """
    @decorators.NotImplementedWarn
    def setCheckColumnEnabled(self, b):
        pass

    """
    Obiente el texto de la etiqueta de encabezado para la columna de selección
    """
    @decorators.NotImplementedWarn
    def aliasCheckColumn(self):
        pass


    """
    Establece el texto de la etiqueta de encabezado para la columna de selección

    El cambio del texto de la etiqueta no será efectivo hasta el próximo refresh
    """
    @decorators.NotImplementedWarn
    def setAliasCheckColumn(self, t):
        pass

    """
    Obtiene si el marco de búsqueda está oculto
    """
    @decorators.NotImplementedWarn
    def findHidden(self):
        return None

    """
    Oculta o muestra el marco de búsqueda

    @param  h TRUE lo oculta, FALSE lo muestra
    """
    @decorators.NotImplementedWarn
    def setFindHidden(self, h):
        pass

    """
    Obtiene si el marco para conmutar entre datos y filtro está oculto
    """
    @decorators.NotImplementedWarn
    def filterHidden(self):
        return None

    """
    Oculta o muestra el marco para conmutar entre datos y filtro

    @param  h TRUE lo oculta, FALSE lo muestra
    """
    @decorators.NotImplementedWarn
    def setFilterHidden(self, h):
        pass

    """
    Ver FLTableDB::showAllPixmaps_
    """
    @decorators.NotImplementedWarn
    def showAllPixmaps(self):
        return None

    """
    Ver FLTableDB::showAllPixmaps_
    """
    @decorators.NotImplementedWarn
    def setShowAllPixmaps(self, s):
        pass

    """
    Ver FLTableDB::functionGetColor_
    """
    @decorators.NotImplementedWarn
    def functionGetColor(self):
        pass

    """
    Ver FLTableDB::functionGetColor_
    """
    @decorators.NotImplementedWarn
    def setFunctionGetColor(self, f):
        pass

    """
    Asigna el nombre de función a llamar cuando cambia el filtro.
    """
    def setFilterRecordsFunction(self, fn):
        self.tableDB_filterRecords_functionName_ = fn

    """
    Ver FLTableDB::onlyTable_
    """
    @decorators.NotImplementedWarn
    def setOnlyTable(self, on = True):
        pass

    def onlyTable(self):
        return self.reqOnlyTable_

    """
    Ver FLTableDB::autoSortColumn_
    """
    @decorators.NotImplementedWarn
    def setAutoSortColumn(self, on = True):
        self.autoSortColumn_ = on

    def autoSortColumn(self):
        return self.autoSortColumn_



    """
    Filtro de eventos
    """

    def eventFilter(self, obj, ev):
        if not self.tableRecords_ or not self.lineEditSearch or not self.comboBoxFieldToSearch or not self.comboBoxFieldToSearch2 or not self.cursor_:
            return super(FLTableDB, self).eventFilter(obj, ev)

        if ev.type() == QtCore.QEvent.KeyPress and isinstance(obj, FLDataTable):
            k = ev

            if k.key() == QtCore.Qt.Key_F2:
                self.comboBoxFieldToSearch.popup()
                return True

        if ev.type() == QtCore.QEvent.KeyPress and isinstance(obj, QtGui.QLineEdit):
            k = ev

            if k.key() == QtCore.Qt.Key_Enter or k.key() == QtCore.Qt.Key_Return:
                self.tableRecords_.setFocus()
                return True


            if k.key() == QtCore.Qt.Key_Up:
                self.comboBoxFieldToSearch.setFocus()
                return True

            if k.key() == QtCore.Qt.Key_Down:
                self.tableRecords_.setFocus()
                return True

            if k.key() == QtCore.Qt.Key_F2:
                self.comboBoxFieldToSearch.popup()
                return True

            if k.text() == "'" or k.text() == "\\":
                return True

        if isinstance(obj, FLDataTable) or isinstance(obj, QtGui.QLineEdit):
            return False
        else:
            return super(FLTableDB, self).eventFilter(obj, ev)



    """
    Captura evento mostrar
    """
    def showEvent(self, e):
        super(FLTableDB, self).showEvent(e)
        self.showWidget()





    """
    Redefinida por conveniencia
    """

    def showWidget(self):
        if not self._loaded: #Esperamos a que la carga se realice
            timer = QtCore.QTimer(self)
            timer.singleShot(30, self.showWidget)
            return
        else:
            if not self.showed and not self._initCursorWhenLoad and self.cursor_ and self.tableRecords_:
                if not self.topWidget:
                    self.initFakeEditor()
                    self.showed = True
                    return

                tMD = None
                ownTMD = None
                if self.tableName_:
                    if not self.cursor_.db().manager().existsTable(self.tableName_):
                        ownTMD = True
                        tMD = self.cursor_.db().manager().createTable(self.tableName_)
                    else:
                        ownTMD = True
                        tMD = self.cursor_.db().manager().metadata(self.tableName_)

                    if not tMD:
                        return







                if not self.cursorAux:
                    if self.initSearch_:
                        self.refresh(True, True)
                        QtCore.QTimer.singleShot(0, self.tableRecords_.ensureRowSelectedVisible)
                    else:
                        self.refresh(True)
                        if self.tableRecords_.numRows() <= 0:
                            self.refresh(False, True)
                        else:
                            self.refreshDelayed()

                    if not isinstance(self.topWidget, FLFormRecordDB):
                        self.lineEditSearch.setFocus()

                if self.cursorAux:
                    if isinstance(self.topWidget, FLFormRecordDB) and self.cursorAux.modeAccess() == FLSqlCursor.Browse:
                        self.cursor_.setEdition(False)
                        self.setReadOnly(True)

                    if self.initSearch_:
                        self.refresh(True, True)
                        QtCore.QTimer.singleShot(0, self.tableRecords_.ensureRowSelectedVisible)
                    else:
                        self.refresh(True)
                        if self.tableRecords_.numRows() <= 0:
                            self.refresh(False, True)
                        else:
                            self.refreshDelayed()

                elif isinstance(self.topWidget, FLFormRecordDB) and self.cursor_.modeAccess() == FLSqlCursor.Browse and (tMD and not tMD.isQuery()):
                    self.cursor_.setEdition(False)
                    self.setReadOnly(True)


                if ownTMD and tMD and not tMD.inCache():
                    del tMD


            if self._initCursorWhenLoad:
                self._initCursorWhenLoad = False
                self.initCursor()
                self.showWidget()

            if not self.tableRecords_:
                if not self.tableName_:
                    if not self.cursor_:
                        self.initCursor()
                        QtCore.QTimer.singleShot(50, self.showWidget)
                        return
                    self.tableRecords()
                    self.setTableRecordsCursor()
                    self.showWidget()
                elif self.tableName_:
                    if not self.cursor_:
                        self.initCursor()
                        QtCore.QTimer.singleShot(50, self.showWidget)
                        return

                    if self.tableName_ == self.cursor_.curName():
                        self.tableRecords()
                        if self.cursor_.model():
                            self.setTableRecordsCursor()
                            self.showWidget()






    """
    Obtiene el componente tabla de registros
    """
    def tableRecords(self):
        if self.tableRecords_:
            print("ERROR: tableRecords - llamada doble")
            return

        self.tabDataLayout = QtGui.QVBoxLayout()
        self.comboBoxFieldToSearch = QtGui.QComboBox()
        self.comboBoxFieldToSearch2 = QtGui.QComboBox()
        self.lineEditSearch = QtGui.QLineEdit()
        label1 = QtGui.QLabel()
        label2 = QtGui.QLabel()

        label1.setText("Buscar")
        label2.setText("en")

        self.tabControlLayout = QtGui.QHBoxLayout()

        self.tabControlLayout.addWidget(label1)
        self.tabControlLayout.addWidget(self.lineEditSearch)
        self.tabControlLayout.addWidget(label2)
        self.tabControlLayout.addWidget(self.comboBoxFieldToSearch)
        self.tabControlLayout.addWidget(self.comboBoxFieldToSearch2)

        self.tabDataLayout.addLayout(self.tabControlLayout)


        if not self.tableRecords_:
            self.tableRecords_ = FLDataTable(self, "tableRecords")
            self.tableRecords_.setFocusPolicy(QtCore.Qt.StrongFocus)
            self.setFocusProxy(self.tableRecords_)
            self.tabDataLayout.addWidget(self.tableRecords_)
            self.lineEditSearch.installEventFilter(self)
            self.tableRecords_.installEventFilter(self)

            self.setLayout(self.tabDataLayout)
            self.setTabOrder(self.tableRecords_, self.lineEditSearch)
            self.setTabOrder(self.lineEditSearch, self.comboBoxFieldToSearch)
            self.setTabOrder(self.comboBoxFieldToSearch, self.comboBoxFieldToSearch2)
            self.tableRecords_.recordChoosed.connect(self.currentChanged)

        self.lineEditSearch.textChanged.connect(self.filterRecords)
        model = self.cursor_.model()

        if model:
            for column in range(model.columnCount()):
                field = model.metadata().indexFieldObject(column)
                if not field.visibleGrid():
                    self.tableRecords_.setColumnHidden(column, True)
                else:
                    self.comboBoxFieldToSearch.addItem(model.headerData(column, QtCore.Qt.Horizontal, QtCore.Qt.DisplayRole))
                    self.comboBoxFieldToSearch2.addItem(model.headerData(column, QtCore.Qt.Horizontal, QtCore.Qt.DisplayRole))
            self.comboBoxFieldToSearch.addItem("*")
            self.comboBoxFieldToSearch2.addItem("*")
            self.comboBoxFieldToSearch.setCurrentIndex(0)
            self.comboBoxFieldToSearch2.setCurrentIndex(1)
            self.comboBoxFieldToSearch.currentIndexChanged.connect(self.putFirstCol)
            self.comboBoxFieldToSearch2.currentIndexChanged.connect(self.putSecondCol)
            self._controlsInit = True

        else:
            self.comboBoxFieldToSearch.addItem("*")
            self.comboBoxFieldToSearch2.addItem("*")

        return self.tableRecords_






    """
    Asigna el cursor actual del componente a la tabla de registros
    """

    def setTableRecordsCursor(self):
        self.tableRecords_.setFLSqlCursor(self.cursor_)
        try:
            self.tableRecords_.doubleClicked.disconnect(self.chooseRecord)
        except:
            pass
        self.tableRecords_.doubleClicked.connect(self.chooseRecord)

    """
    Refresca la pestaña datos aplicando el filtro
    """
    @decorators.NotImplementedWarn
    def refreshTabData(self):
        pass

    """
    Refresca la pestaña del filtro
    """
    @decorators.NotImplementedWarn
    def refreshTabFilter(self):
        pass

    """
    Para obtener la enumeración correspondiente a una condición para el filtro a partir de
    su literal
    """
    @decorators.NotImplementedWarn
    def decodeCondType(self, strCondType):
        pass

    """
    Construye la claúsula de filtro en SQL a partir del contenido de los valores
    definidos en la pestaña de filtro
    """
    @decorators.NotImplementedWarn
    def tdbFilterBuildWhere(self):
        pass

    """
    Inicializa un editor falso y no funcional.

    Esto se utiliza cuando se está editando el formulario con el diseñador y no
    se puede mostrar el editor real por no tener conexión a la base de datos.
    Crea una previsualización muy esquemática del editor, pero suficiente para
    ver la posisicón y el tamaño aproximado que tendrá el editor real.
    """
    @decorators.NotImplementedWarn
    def initFakeEditor(self):
        pass

    """
    Componente para visualizar los registros
    """
    tableRecords_ = None

    """
    Nombre de la tabla a la que esta asociado este componente.
    """
    tableName_ = None

    """
    Nombre del campo foráneo
    """
    foreignField_ = None

    """
    Nombre del campo de la relación
    """
    fieldRelation_ = None

    """
    Cursor con los datos de origen para el componente
    """
    cursor_ = None

    """
    Cursor auxiliar de uso interno para almacenar los registros de la tabla
    relacionada con la de origen
    """
    cursorAux = None

    """
    Matiene la ventana padre
    """
    topWidget = None

    """
    Indica que la ventana ya ha sido mostrada una vez
    """
    showed = None

    """
    Mantiene el filtro de la tabla
    """
    filter_ = None

    """
    Almacena si el componente está en modo sólo lectura
    """
    readonly_ = None
    reqReadOnly_ = None

    """
    Almacena si el componente está en modo sólo edición
    """
    editonly_ = None
    reqEditOnly_ = None

    """
    Indica si el componente está en modo sólo permitir añadir registros
    """
    insertonly_ = None
    reqInsertOnly_ = None

    """
    Almacena los metadatos del campo por el que está actualmente ordenada la tabla
    """
    sortField_ = None

    """
    Almacena los metadatos del campo por el que está actualmente ordenada la tabla en segunda instancia

    @author Silix - dpinelo
    """
    sortField2_ = None

    """
    Crónometro interno
    """
    timer = None

    """
    Filtro inicial de búsqueda
    """
    initSearch_ = None

    """
    Indica que la columna de seleción está activada
    """
    checkColumnEnabled_ = None

    """
    Indica el texto de la etiqueta de encabezado para la columna de selección
    """
    aliasCheckColumn_ = None

    """
    Indica el nombre para crear un pseudocampo en el cursor para la columna de selección
    """
    fieldNameCheckColumn_ = None

    """
    Indica que la columna de selección está visible
    """
    checkColumnVisible_ = None

    """
    Indica el número de columna por la que ordenar los registros
    """
    sortColumn_ = None

    """
    Indica el número de columna por la que ordenar los registros

    @author Silix - dpinelo
    """
    sortColumn2_ = None

    """
    Indica el número de columna por la que ordenar los registros

    @author Silix
    """
    sortColumn3_ = None

    """
    Indica el sentido ascendente o descendente del la ordenacion actual de los registros
    """
    orderAsc_ = None

    """
    Indica el sentido ascendente o descendente del la ordenacion actual de los registros

    @author Silix - dpinelo
    """
    orderAsc2_ = None

    """
    Indica el sentido ascendente o descendente del la ordenacion actual de los registros

    @author Silix
    """
    orderAsc3_ = None

    """
    Indica si se debe establecer automáticamente la primera columna como de ordenación
    """
    autoSortColumn_ = None

    """
    Almacena la última claúsula de filtro aplicada en el refresco
    """
    tdbFilterLastWhere_ = None

    """
    Diccionario que relaciona literales descriptivos de una condición de filtro
    con su enumeración
    """
    mapCondType = []

    """
    Indica si el marco de búsqueda está oculto
    """
    findHidden_ = None

    """
    Indica si el marco para conmutar entre datos y filtro está oculto
    """
    filterHidden_ = None

    """
    Indica si se deben mostrar los campos tipo pixmap en todas las filas
    """
    showAllPixmaps_ = None

    """
    Nombre de la función de script a invocar para obtener el color y estilo de las filas y celdas

    El nombre de la función debe tener la forma 'objeto.nombre_funcion' o 'nombre_funcion',
    en el segundo caso donde no se especifica 'objeto' automáticamente se añadirá como
    prefijo el nombre del formulario donde se inicializa el componente FLTableDB seguido de un punto.
    De esta forma si utilizamos un mismo formulario para varias acciones, p.e. master.ui, podemos controlar
    si usamos distintas funciones de obtener color para cada acción (distintos nombres de formularios) o
    una única función común para todas las acciones.

    Ej. Estableciendo 'tdbGetColor' si el componente se inicializa en el formulario maestro de clientes,
    se utilizará 'formclientes.tdbGetColor', si se inicializa en el fomulario maestro de proveedores, se
    utilizará 'formproveedores.tdbGetColor', etc... Si establecemos 'flfactppal.tdbGetColor' siempre se llama a
    esa función independientemente del formulario en el que se inicialize el componente.

    Cuando se está pintando una celda se llamará a esa función pasándole cinco parámentros:
    - Nombre del campo correspondiente a la celda
    - Valor del campo de la celda
    - Cursor de la tabla posicionado en el registro correspondiente a la fila que
      está pintando. AVISO: En este punto los valores del buffer son indefinidos, no se hace refreshBuffer
      por motivos de eficiencia
    - Tipo del campo, ver FLUtilInterface::Type en FLObjectFactory.h
    - Seleccionado. Si es TRUE indica que la celda a pintar está en la fila resaltada/seleccionada.
      Generalmente las celdas en la fila seleccionada se colorean de forma distinta al resto.

    La función debe devolver una array con cuatro cadenas de caracteres;

    [ "color_de_fondo", "color_lapiz", "estilo_fondo", "estilo_lapiz" ]

    En los dos primeros, el color, se puede utilizar cualquier valor aceptado por QColor::setNamedColor, ejemplos;

    "green"
    "#44ADDB"

    En los dos últimos, el estilo, se pueden utilizar los valores aceptados por QBrush::setStyle y QPen::setStyle,
    ver en FLDataTable.cpp las funciones nametoBrushStyle y nametoPenStyle, ejemplos;

    "SolidPattern"
    "DiagCrossPattern"
    "DotLine"
    "SolidLine"

    Si alguno de los valores del array es vacio "", entonces se utilizarán los colores o estilos establecidos por defecto.
    """
    functionGetColor_ = None

    """
    Indica que no se realicen operaciones con la base de datos (abrir formularios). Modo "sólo tabla".
    """
    onlyTable_ = None
    reqOnlyTable_ = None

    """
    Editor falso
    """
    fakeEditor_ = None

    tableDB_filterRecords_functionName_ = None


    """
    Actualiza el conjunto de registros.
    """
    @QtCore.pyqtSlot()
    @QtCore.pyqtSlot(bool)
    @QtCore.pyqtSlot(bool, bool)
    def refresh(self, refreshHead = False, refreshData = False):
        if not self.cursor_ or not self.tableRecords_:
            return

        tMD = self.cursor_.metadata()
        if not tMD:
            return

        if not self.tableName_:
            self.tableName_ = tMD.name()




        if refreshHead:
            if not self.tableRecords_.isHidden():
                self.tableRecords_.hide()

            model = self.cursor_.model()

            for column in range(model.columnCount()):
                field = model.metadata().indexFieldObject(column)
                if not field.visibleGrid():
                    self.tableRecords_.setColumnHidden(column, True)
                else:
                    self.tableRecords_.setColumnHidden(column, False)
                    
            # FIXME FIX: Esto lo he implementado en otro lado manualmente. A elminar, o mover algo de aquel código aquí.
            
            # FIXME: Este proceso es MUY LENTO. No deberíamos hacer esto.
            # Hay que buscar alguna forma manual de iterar las primeras N filas, o calcular un
            # valor por defecto rápidamente.
            #self.tableRecords_._h_header.setResizeMode(QtGui.QHeaderView.ResizeToContents)
            #if model.rows * model.cols > 500*10:
            #    # Esto evitará que se calcule para las que tienen más de 500*10 celdas.
            #    self.tableRecords_._h_header.setResizeMode(0)
            # ... de todos modos tendríamos que, con un timer o algo para desactivar el modo. Una vez
            # ... ya redimensionadas inicialmente, lo único que hace es lastrar Pineboo mucho.




        if refreshData or self.sender():

            finalFilter = self.filter_
            if self.tdbFilterBuildWhere_:
                if not finalFilter:
                    finalFilter = self.tdbFilterLastWhere_
                else:
                    finalFilter = "%s and %s" % (finalFilter, self.tdbFilterLastWhere_)

            self.tableRecords_.setPersistentFilter(finalFilter)
            self.tableRecords_.refresh()




        if self.initSearch_:
            try:
                self.lineEditSearch.textChanged.disconnect(self.filterRecords)
            except:
                pass
            self.lineEditSearch.setText(self.initSearch_)
            self.lineEditSearch.textChanged.connect(self.filterRecords)
            self.lineEditSearch.selectAll()
            self.initSearch_ = None
            self.seekCursor()

        if not self.readonly_ == self.reqReadOnly_ or (self.tableRecords_ and not self.readonly_ == self.tableRecords_.flReadOnly()):
            self.setReadOnly(self.reqReadOnly_)

        if not self.editonly_ == self.reqEditOnly_ or (self.tableRecords_ and not self.editonly_ == self.tableRecords_.editOnly()):
            self.setEditOnly(self.reqEditOnly_)


        if not self.insertonly_ == self.reqInsertOnly_ or (self.tableRecords_ and not self.insertonly_ == self.tableRecords_.insertOnly()):
            self.setInsetOnly(self.reqInsertOnly_)

        if not self.onlyTable_ == self.reqOnlyTable_ or (self.tableRecords_ and not self.onlyTable_ == self.tableRecords_.onlyTable()):
            self.setOnlyTable(self.reqOnlyTable_)

        if self.tableRecords_ and self.tableRecords_.isHidden():
            self.tableRecords_.show()

    """
    Actualiza el conjunto de registros con un retraso.

    Acepta un lapsus de tiempo en milisegundos, activando el cronómetro interno para
    que realize el refresh definitivo al cumplirse dicho lapsus.

    @param msec Cantidad de tiempo del lapsus, en milisegundos.
    """
    def refreshDelayed(self, msec = 50, refreshData = True):

        if not self.cursor_.modeAccess() == FLSqlCursor.Browse:
            return


        if refreshData:
            self._refreshData = True
        else:
            self._refreshData = False
            QtCore.QTimer.singleShot(msec, self.refreshDelayed2)

        self.seekCursor()

    def refreshDelayed2(self):
        self.refresh(False, self._refreshData)
        self._refreshData = None

    """
    Invoca al método FLSqlCursor::insertRecord()
    """
    @QtCore.pyqtSlot()
    def insertRecord(self):

        w = self.sender()
        if w and (not self.cursor_ or self.reqReadOnly_ or self.reqEditOnly_ or self.reqOnlyTable_ or (self.cursor_.cursorRelation() and self.cursor_.cursorRelation().isLocked())):
            w.setDisabled(True)
            return

        if self.cursor_:
            self.cursor_.insertRecord()

    """
    Invoca al método FLSqlCursor::editRecord()
    """
    @QtCore.pyqtSlot()
    def editRecord(self):
        w = self.sender()
        if w and (not self.cursor_ or self.reqReadOnly_ or self.reqEditOnly_ or self.reqOnlyTable_ or (self.cursor_.cursorRelation() and self.cursor_.cursorRelation().isLocked())):
            w.setDisabled(True)
            return

        if self.cursor_:
            self.cursor_.editRecord()
    """
    Invoca al método FLSqlCursor::browseRecord()
    """
    @QtCore.pyqtSlot()
    def browseRecord(self):

        w = self.sender()
        if w and (not self.cursor_ or self.reqOnlyTable_):
            w.setDisabled(True)
            return

        if self.cursor_:
            self.cursor_.browseRecord()

    """
    Invoca al método FLSqlCursor::deleteRecord()
    """
    @QtCore.pyqtSlot()
    def deleteRecord(self):
        w = self.sender()
        if w and (not self.cursor_ or self.reqReadOnly_ or self.reqInsertOnly_ or self.reqEditOnly_ or self.reqOnlyTable_ or (self.cursor_.cursorRelation() and self.cursor_.cursorRelation().isLocked())):
            w.setDisabled(True)
            return

        if self.cursor_:
            self.cursor_.deleteRecord()

    """
    Invoca al método FLSqlCursor::copyRecord()
    """
    @QtCore.pyqtSlot()
    def copyRecord(self):
        w = self.sender()
        if w and (not self.cursor_ or self.reqReadOnly_ or self.reqEditOnly_ or self.reqOnlyTable_ or (self.cursor_.cursorRelation() and self.cursor_.cursorRelation().isLocked())):
            w.setDisabled(True)
            return

        if self.cursor_:
            self._cursor.copyRecord()

    """
    Coloca la columna como primera pasando el nombre del campo.

    Este slot está conectado al cuadro combinado de busqueda
    del componente. Cuando seleccionamos un campo este se coloca
    como primera columna y se reordena la tabla con esta columna.
    De esta manera siempre tendremos la tabla ordenada mediante
    el campo en el que queremos buscar.

    @param c Nombre del campo, esta columna intercambia su posion con la primera columna
    @return Falso si no existe el campo
    @author [email protected]
    @author InfoSiAL, S.L.
    """
    @QtCore.pyqtSlot(int)
    @QtCore.pyqtSlot(str)
    def putFirstCol(self, c ):
        _index = c
        if isinstance(c, str):
            _index = self.tableRecords_.realColumnIndex(c)

        if _index < 0:
            return False

        self.moveCol(_index, 0)
        return True

    """
    Coloca la columna como segunda pasando el nombre del campo.

    @author Silix - dpinelo
    """
    @QtCore.pyqtSlot(int)
    @QtCore.pyqtSlot(str)
    def putSecondCol(self, c):
        _index = c
        if isinstance(c, str):
            _index = self.tableRecords_.realColumnIndex(c)

        if _index < 0:
            return False

        self.moveCol(_index, 1)
        return True

    """
    Mueve una columna de un campo origen a la columna de otro campo destino

    @param  from  Nombre del campo de la columna de origen
    @param  to    Nombre del campo de la columna de destino
    @param  firstSearch dpinelo: Indica si se mueven columnas teniendo en cuenta que esta función
            se ha llamado o no, desde el combo principal de búsqueda y filtrado
    """
    @decorators.BetaImplementation
    def moveCol(self, from_,  to, firstSearch = True ):

        _oldFirst = None

        if from_ < 0 or to < 0:
            return

        tMD = self.cursor_.metadata()
        if not tMD:
            return

        self.tableRecords_.hide()


        textSearch = self.lineEditSearch.text()



        field = self.cursor_.metadata().indexFieldObject(to)

        if to == 0: # Si ha cambiado la primera columna


            try:
                self.comboBoxFieldToSearch.currentIndexChanged.disconnect(self.putFirstCol)
            except:
                pass

            self.comboBoxFieldToSearch.setCurrentIndex(from_)
            self.comboBoxFieldToSearch.currentIndexChanged.connect(self.putFirstCol)

            #Actializamos el segundo combo
            try:
                self.comboBoxFieldToSearch2.currentIndexChanged.disconnect(self.putSecondCol)
            except:
                pass
            #Falta mejorar
            if self.comboBoxFieldToSearch.currentIndex() == self.comboBoxFieldToSearch2.currentIndex():
                self.comboBoxFieldToSearch2.setCurrentIndex(self.tableRecords_._h_header.logicalIndex(0))
            self.comboBoxFieldToSearch2.currentIndexChanged.connect(self.putSecondCol)




        if (to == 1): #Si es la segunda columna ...
            try:
                self.comboBoxFieldToSearch2.currentIndexChanged.disconnect(self.putSecondCol)
            except:
                pass
            self.comboBoxFieldToSearch2.setCurrentIndex(from_)
            self.comboBoxFieldToSearch2.currentIndexChanged.connect(self.putSecondCol)


            if self.comboBoxFieldToSearch.currentIndex() == self.comboBoxFieldToSearch2.currentIndex():
                try:
                    self.comboBoxFieldToSearch.currentIndexChanged.disconnect(self.putFirstCol)
                except:
                    pass
                if self.comboBoxFieldToSearch.currentIndex() == self.comboBoxFieldToSearch2.currentIndex():
                    self.comboBoxFieldToSearch.setCurrentIndex(self.tableRecords_._h_header.logicalIndex(1))
                self.comboBoxFieldToSearch.currentIndexChanged.connect(self.putFirstCol)


        if not textSearch:
            textSearch = self.cursor_.value(field.name())

        self.refresh(True)

        if textSearch:
            self.refresh(False, True)
            try:
                self.lineEditSearch.textChanged.disconnect(self.filterRecords)
            except:
                pass
            self.lineEditSearch.setText(textSearch)
            self.lineEditSearch.textChanged.connect(self.filterRecords)
            self.lineEditSearch.selectAll()
            self.seekCursor()
            QtCore.QTimer.singleShot(0, self.tableRecords_.ensureRowSelectedVisible())
        else:
            self.refreshDelayed()



        from_ = self.tableRecords_.visualIndexToRealIndex(from_)
        self.tableRecords_._h_header.swapSections(from_, to)

        self.refresh(True)

        """
        if textSearch:
            self.refresh(False, True)

            if firstSearch:
                self.lineEditSearch.textChanged.disconnect(self.filterRecords)
                self.lineEditSearch.setText(textSearch)
                self.lineEditSearch.textChanged.connect(self.filterRecords)
                self.lineEditSearch.selectAll()

            self.seekCursor()
            QtCore.QTimer.singleShot(0,self.tableRecords_.ensureRowSelectedVisible)
        else:
            self.refreshDelayed()
            if not self.sender():
                self.lineEditSearch.setFocus()

        """
        #self.tableRecords_.show()

    """
    Posiciona el cursor en un registro valido
    """
    @decorators.BetaImplementation
    def seekCursor(self):
        return
        textSearch = self.lineEditSearch.text()
        if not textSearch:
            return

        if not self.cursor_:
            return

        fN = self.sortField_.name()
        textSearch.replace("%", "")

        if not "'" in textSearch and not "\\" in textSearch:
            sql = self.cursor_.executedQuery() + " LIMIT 1"
        """
            #QSqlQuery qry(sql, cursor_->db()->db()); #FIXME
            if (qry.first()) {
      QString v(qry.value(0).toString());
      int pos = -1;
      if (!v.upper().startsWith(textSearch.upper()))
        pos = cursor_->atFromBinarySearch(fN, textSearch, orderAsc_);
      if (pos == -1)
        pos = cursor_->atFromBinarySearch(fN, v, orderAsc_);
      cursor_->seek(pos, false, true);
      """
    """
    Redefinida por conveniencia
    """
    @decorators.NotImplementedWarn
    def setEnabled(self, b):
        pass

    """
    Establece el ancho de una columna

    @param  field Nombre del campo de la base de datos correspondiente a la columna
    @param  w     Ancho de la columna
    """
    @decorators.NotImplementedWarn
    def setColumnWidth(self, field, w):
        pass

    """
    @return Ancho de la columna
    """
    @decorators.NotImplementedWarn
    def columnWidth(self, c):
        pass

    """
    Establece el alto de una fila

    @param  row Número de orden de la fila, empezando en 0
    @param  h   Alto de la fila
    """
    @decorators.NotImplementedWarn
    def setRowHeight(self, row, h):
        pass
    """
    @return Alto de la fila
    """
    @decorators.NotImplementedWarn
    def rowHeight(self, row):
        pass

    """
    Exporta a una hoja de cálculo ODS y la visualiza
    """
    @decorators.NotImplementedWarn
    def exportToOds(self):
        pass

    """
    Conmuta el sentido de la ordenación de los registros de la tabla, de ascendente a descendente y
    viceversa. Los registros siempre se ordenan por la primera columna.
    Si la propiedad autoSortColumn es TRUE.
    """
    @decorators.NotImplementedWarn
    def switchSortOrder(self, col = 0):
        pass


    """
    Filtra los registros de la tabla utilizando el primer campo, según el patrón dado.

    Este slot está conectado al cuadro de texto de busqueda del componente,
    tomando el contenido de este como patrón para el filtrado.

    @param p Cadena de caracteres con el patrón de filtrado
    """
    @QtCore.pyqtSlot(str)
    def filterRecords(self, p):
        if not self.cursor_.model():
            return
        bFilter = None
        p = str(p)
        refreshData = None
        if "%" in p:
            refreshData = True
        msec_refresh = 400
        column = self.tableRecords_._h_header.logicalIndex(0)
        field = self.cursor_.model().metadata().indexFieldObject(column)

        bFilter = self.cursor_.db().manager().formatAssignValue(field, p, True)

        idMod = self.cursor_.db().managerModules().idModuleOfFile(self.cursor_.metadata().name() + ".mtd")

        functionQSA = idMod + ".tableDB_filterRecords_" + self.cursor_.metadata().name()

        vargs = []
        vargs.append(self.cursor_.metadata().name())
        vargs.append(p)
        vargs.append(field.name())
        vargs.append(bFilter)

        if functionQSA:
            msec_refresh = 800
            ret = self.cursor_._prj.call(functionQSA, vargs, None)
            if ret:
                bFilter = ret
                print("functionQSA:%s:" % functionQSA)
            else:
                if p == "":
                    bFilter = None


        self.refreshDelayed(msec_refresh, (bFilter or refreshData))
        self.filter_ = bFilter


    @decorators.NotImplementedWarn
    def setSortOrder(self, ascending):
        pass

    @decorators.NotImplementedWarn
    def isSortOrderAscending(self):
        pass

    """
    Activa la tabla de datos
    """
    @decorators.NotImplementedWarn
    def activeTabData(self, b):
        pass

    """
    Activa la tabla de filtro
    """
    @decorators.NotImplementedWarn
    def activeTabFilter(self, b):
        pass

    """
    Limpia e inicializa el filtro
    """
    @decorators.NotImplementedWarn
    def tdbFilterClear(self):
        pass


    """
    Señal emitida cuando se refresca por cambio de filtro
    """
    refreshed = QtCore.pyqtSignal()

    """
    Señal emitida cuando se establece si el componente es o no de solo lectura.
    """
    readOnlyChanged = QtCore.pyqtSignal(bool)

    """
    Señal emitida cuando se establece si el componente es o no de solo edición.
    """
    editOnlyChanged = QtCore.pyqtSignal(bool)

    """
    Señal emitida cuando se establece si el componente es o no de solo inserción.
    """
    insertOnlyChanged = QtCore.pyqtSignal(bool)

    """
    Señal emitida cuando se establece cambia el registro seleccionado.
    """
    currentChanged = QtCore.pyqtSignal()

    @QtCore.pyqtSlot()
    @decorators.BetaImplementation
    def chooseRecord(self):
        if isinstance(self.topWidget, FLFormSearchDB):
            if self.topWidget.inExec_:
                    self.topWidget.accept()
                    return
            
        if self.cursor().isLocked():
            print("FLTable(%s):Registro bloqueado. Modo Solo lectura" % self.cursor().curName())
            self.browseRecord()
        else:   
            self.editRecord()
Ejemplo n.º 26
0
    def alterTable2(self, mtd1, mtd2, key, force=False):

        util = FLUtil()

        oldMTD = None
        newMTD = None
        doc = QDomDocument("doc")
        docElem = None

        if not util.docDocumentSetContect(doc, mtd1):
            print("FLManager::alterTable : " +
                  qApp.tr("Error al cargar los metadatos."))
        else:
            docElem = doc.documentElement()
            oldMTD = self.db_.manager().metadata(docElem, True)

        if oldMTD and oldMTD.isQuery():
            return True

        if not util.docDocumentSetContect(doc, mtd2):
            print("FLManager::alterTable : " +
                  qApp.tr("Error al cargar los metadatos."))
            return False
        else:
            docElem = doc.documentElement()
            newMTD = self.db_.manager().metadata(docElem, True)

        if not oldMTD:
            oldMTD = newMTD

        if not oldMTD.name() == newMTD.name():
            print("FLManager::alterTable : " +
                  qApp.tr("Los nombres de las tablas nueva y vieja difieren."))
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        oldPK = oldMTD.primaryKey()
        newPK = newMTD.primaryKey()

        if not oldPK == newPK:
            print("FLManager::alterTable : " +
                  qApp.tr("Los nombres de las claves primarias difieren."))
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        if not self.db_.manager().checkMetaData(oldMTD, newMTD):
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return True

        if not self.db_.manager().existsTable(oldMTD.name()):
            print("FLManager::alterTable : " + qApp.tr(
                "La tabla %1 antigua de donde importar los registros no existe."
            ).arg(oldMTD.name()))
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        fieldList = oldMTD.fieldList()
        oldField = None

        if not fieldList:
            print("FLManager::alterTable : " +
                  qApp.tr("Los antiguos metadatos no tienen campos."))
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        renameOld = "%salteredtable%s" % (oldMTD.name()[0:5], QDateTime(
        ).currentDateTime().toString("ddhhssz"))

        if not self.db_.dbAux():
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        self.db_.dbAux().transaction()

        if key and len(key) == 40:
            c = FLSqlCursor("flfiles", True, self.db_.dbAux())
            c.setForwardOnly(True)
            c.setFilter("nombre = '%s.mtd'" % renameOld)
            c.select()
            if not c.next():
                buffer = c.primeInsert()
                buffer.setValue("nombre", "%s.mtd" % renameOld)
                buffer.setValue("contenido", mtd1)
                buffer.setValue("sha", key)
                c.insert()

        q = FLSqlQuery("", self.db_.dbAux())
        constraintName = "%s_pkey" % oldMTD.name()

        if self.constraintExists(constraintName) and not q.exec_(
                "ALTER TABLE %s DROP CONSTRAINT %s" %
            (oldMTD.name(), constraintName)):
            print("FLManager : " + qApp.tr(
                "En método alterTable, no se ha podido borrar el índice %1_pkey de la tabla antigua."
            ).arg(oldMTD.name()))
            self.db_.dbAux().rollback()
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        fieldsNamesOld = []
        for it in fieldList:
            if newMTD.field(it.name()):
                fieldsNamesOld.append(it.name())

            if it.isUnique():
                constraintName = "%s_%s_key" % (oldMTD.name(), it.name())
                if self.constraintExists(constraintName) and not q.exec_(
                        "ALTER TABLE %s DROP CONSTRAINT %s" %
                    (oldMTD.name(), constraintName)):
                    print("FLManager : " + qApp.tr(
                        "En método alterTable, no se ha podido borrar el índice %1_%2_key de la tabla antigua."
                    ).arg(oldMTD.name(), oldField.name()))
                    self.db_.dbAux().rollback()
                    if oldMTD and not oldMTD == newMTD:
                        del oldMTD
                    if newMTD:
                        del newMTD

                    return False

        if not q.exec_("ALTER TABLE %s RENAME TO %s" %
                       (oldMTD.name(), renameOld)):
            print("FLManager::alterTable : " +
                  qApp.tr("No se ha podido renombrar la tabla antigua."))

            self.db_.dbAux().rollback()
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        if not self.db_.manager().createTable(newMTD):
            self.db_.dbAux().rollback()
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        v = None
        ok = False

        if not force and not fieldsNamesOld:
            self.db_.dbAux().rollback()
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return self.alterTable2(mtd1, mtd2, key, True)

        oldCursor = FLSqlCursor(renameOld, True, self.db_.dbAux())
        oldCursor.setModeAccess(oldCursor.Browse)
        newCursor = FLSqlCursor(newMTD.name(), True, self.db_.dbAux())
        newCursor.setMode(newCursor.Insert)

        oldCursor.select()
        totalSteps = oldCursor.size()
        progress = QProgressDialog(
            qApp.tr("Reestructurando registros para %1...").arg(
                newMTD.alias()), qApp.tr("Cancelar"), 0, totalSteps)
        progress.setLabelText(qApp.tr("Tabla modificada"))

        step = 0
        newBuffer = None
        newField = None
        listRecords = []
        newBufferInfo = self.recordInfo2(newMTD.name())
        oldFieldsList = {}
        newFieldsList = {}
        defValues = {}
        v = None

        for newField in fieldList:
            oldField = oldMTD.field(newField.name())
            defValues[str(step)] = None
            if not oldField or not oldCursor.field(oldField.name()):
                if not oldField:
                    oldField = newField
                if not newField.type() == "serial":
                    v = newField.defaultValue()
                    defValues[str(step)] = v

            newFieldsList[str(step)] = newField
            oldFieldsList[str(step)] = oldField
            step = step + 1

        step = 0
        ok = True
        while oldCursor.next():
            newBuffer = newBufferInfo

            for reg in defValues.keys():
                newField = newFieldsList[reg]
                oldField = oldFieldsList[reg]
                if defValues[reg]:
                    v = defValues[reg]
                else:
                    v = oldCursor.value(newField.name())
                    if (not oldField.allowNull or not newField.allowNull()
                        ) and not v and not newField.type() == "serial":
                        defVal = newField.defaultValue()
                        if defVal is not None:
                            v = defVal

                    if v is not None and not newBuffer.field(
                            newField.name()).type() == newField.type():
                        print("FLManager::alterTable : " + qApp.tr(
                            "Los tipos del campo %1 no son compatibles. Se introducirá un valor nulo."
                        ).arg(newField.name()))

                if v is not None and newField.type(
                ) == "string" and newField.length() > 0:
                    v = str(v)[0:newField.length()]

                if (not oldField.allowNull()
                        or not newField.allowNull()) and v is None:
                    if oldField.type() == "serial":
                        v = int(
                            self.nextSerialVal(newMTD.name(), newField.name()))
                    elif oldField.type() in ("int", "uint", "bool", "unlock"):
                        v = 0
                    elif oldField.type() == "double":
                        v = 0.0
                    elif oldField.type() == "time":
                        v = QTime().currentTime()
                    elif oldField.type() == "date":
                        v = QDate().currentDate()
                    else:
                        v = "NULL"[0:newField.length()]

                newBuffer.setValue(newField.name(), v)

            listRecords.append(newBuffer)

            if not self.insertMulti(newMTD.name(), listRecords):
                ok = False
                listRecords.clear()
                break

            listRecords.clear()

        if len(listRecords) > 0:
            if not self.insertMulti(newMTD.name(), listRecords):
                ok = False
            listRecords.clear()

        progress.setProgress(totalSteps)

        if oldMTD and not oldMTD == newMTD:
            del oldMTD

        if newMTD:
            del newMTD

        if ok:
            self.db_.dbAux().commit()
        else:
            self.db_.dbAux().rollback()
            return False

        if force and ok:
            q.exec_("DROP TABLE %s CASCADE" % renameOld)

        return True
Ejemplo n.º 27
0
    def alterTable3(self, newMTD):
        if self.hasCheckColumn(newMTD):
            return False

        oldMTD = newMTD
        fieldList = oldMTD.fieldList()

        renameOld = "%salteredtable%s" % (oldMTD.name()[0:5], QDateTime(
        ).currentDateTime().toString("ddhhssz"))

        self.db_.dbAux().transaction()

        q = FLSqlQuery(None, self.db_.dbAux())

        constraintName = "%s_key" % oldMTD.name()

        if self.constraintExists(constraintName) and not q.exec_(
                "ALTER TABLE %s DROP CONSTRAINT %s" %
            (oldMTD.name(), constraintName)):
            self.db_.dbAux().rollback()
            return False

        for oldField in fieldList:
            if oldField.isCheck():
                return False
            if oldField.isUnique():
                constraintName = "%s_%s_key" % (oldMTD.name(), oldField.name())
                if self.constraintExists(constraintName) and not q.exec_(
                        "ALTER TABLE %s DROP CONSTRAINT %s" %
                    (oldMTD.name(), constraintName)):
                    self.db_.dbAux().rollback()
                    return False

        if not q.exec_("ALTER TABLE %s RENAME TO %s" %
                       (oldMTD.name(), renameOld)):
            self.db_.dbAux().rollback()
            return False

        if not self.db_.manager().createTable(newMTD):
            self.db_.dbAux().rollback()
            return False

        oldCursor = FLSqlCursor(renameOld, True, self.db_.dbAux())
        oldCursor.setModeAccess(oldCursor.Browse)
        oldCursor.select()

        fieldList = newMTD.fieldList()

        if not fieldList:
            self.db_.dbAux().rollback()
            return False

        oldCursor.select()
        totalSteps = oldCursor.size()
        progress = QProgressDialog(
            qApp.tr("Reestructurando registros para %1...").arg(
                newMTD.alias()), qApp.tr("Cancelar"), 0, totalSteps)
        progress.setLabelText(qApp.tr("Tabla modificada"))

        step = 0
        newBuffer = None
        newField = None
        listRecords = []
        newBufferInfo = self.recordInfo2(newMTD.name())
        oldFieldsList = {}
        newFieldsList = {}
        defValues = {}
        v = None

        for newField in fieldList:
            oldField = oldMTD.field(newField.name())
            defValues[str(step)] = None
            if not oldField or not oldCursor.field(oldField.name()):
                if not oldField:
                    oldField = newField
                if not newField.type() == "serial":
                    v = newField.defaultValue()
                    defValues[str(step)] = v

            newFieldsList[str(step)] = newField
            oldFieldsList[str(step)] = oldField
            step = step + 1

        ok = True
        while oldCursor.next():
            newBuffer = newBufferInfo

            for reg in defValues.keys():
                newField = newFieldsList[reg]
                oldField = oldFieldsList[reg]
                if defValues[reg]:
                    v = defValues[reg]
                else:
                    v = oldCursor.value(newField.name())
                    if (not oldField.allowNull or not newField.allowNull()
                        ) and not v and not newField.type() == "serial":
                        defVal = newField.defaultValue()
                        if defVal is not None:
                            v = defVal

                    if v is not None and not newBuffer.field(
                            newField.name()).type() == newField.type():
                        print("FLManager::alterTable : " + qApp.tr(
                            "Los tipos del campo %1 no son compatibles. Se introducirá un valor nulo."
                        ).arg(newField.name()))

                    if v is not None and newField.type(
                    ) == "string" and newField.length() > 0:
                        v = str(v)[0:newField.length()]

                    if (not oldField.allowNull()
                            or not newField.allowNull()) and v is None:
                        if oldField.type() == "serial":
                            v = int(
                                self.nextSerialVal(newMTD.name(),
                                                   newField.name()))
                        elif oldField.type() in ("int", "uint", "bool",
                                                 "unlock"):
                            v = 0
                        elif oldField.type() == "double":
                            v = 0.0
                        elif oldField.type() == "time":
                            v = QTime().currentTime()
                        elif oldField.type() == "date":
                            v = QDate().currentDate()
                        else:
                            v = "NULL"[0:newField.length()]

                    newBuffer.setValue(newField.name(), v)

                listRecords.append(newBuffer)

            # if not self.insertMulti(newMTD.name(), listRecords):
            #    ok = False
            #    listRecords.clear()
            #    break

            # listRecords.clear()

        if len(listRecords) > 0:
            if not self.insertMulti(newMTD.name(), listRecords):
                ok = False
            listRecords.clear()

        if ok:
            self.db_.dbAux().commit()
        else:
            self.db_.dbAux().rollback()
            return False

        force = False  # FIXME
        if force and ok:
            q.exec_("DROP TABLE %s CASCADE" % renameOld)
        return True
Ejemplo n.º 28
0
    def Mr_Proper(self):
        util = FLUtil()
        self.db_.dbAux().transaction()

        qry = FLSqlQuery(None, self.db_.dbAux())
        qry2 = FLSqlQuery(None, self.db_.dbAux())
        steps = 0

        rx = QRegExp("^.*\\d{6,9}$")
        listOldBks = rx in self.tables("")
        qry.exec_(
            "select nombre from flfiles where nombre similar to"
            "'%[[:digit:]][[:digit:]][[:digit:]][[:digit:]]-[[:digit:]][[:digit:]]%:[[:digit:]][[:digit:]]%' or nombre similar to"
            "'%alteredtable[[:digit:]][[:digit:]][[:digit:]][[:digit:]]%' or (bloqueo='f' and nombre like '%.mtd')"
        )

        util.createProgressDialog(util.tr("Borrando backups"),
                                  len(listOldBks) + qry.size() + 2)
        while qry.next():
            item = qry.value(0)
            util.setLabelText(util.tr("Borrando registro %1").arg(item))
            qry2.exec_("DELETE FROM flfiles WERE nombre ='%s'" % item)
            if item.find("alteredtable") > -1:
                if self.existsTable(item.replace(".mtd", "")):
                    util.setLabelText(util.tr("Borrando tabla %1").arg(item))
                    qry2.exec_("DROP TABLE %s CASCADE" %
                               item.replace(".mtd", ""))

            steps = steps + 1
            util.setProgress(steps)

        for item in listOldBks:
            if self.existsTable(item):
                util.setLabelText(util.tr("Borrando tabla %1").arg(item))
                qry2.exec_("DROP TABLE %s CASCADE" % item)

            steps = steps + 1
            util.setProgress(steps)

        util.setLabelText(util.tr("Inicializando cachés"))
        steps = steps + 1
        util.setProgress(steps)
        qry.exec_("DELETE FROM flmetadata")
        qry.exec_("DELETE FROM flvar")
        self.db_.manager().cleanupMetaData()
        self.db_.commit()
        util.destroyProgressDialog()

        steps = 0
        qry.exec_("select tablename from pg_tables where schemaname='public'")
        util.createProgressDialog(util.tr("Comprobando base de datos"),
                                  qry.size())
        while qry.next():
            item = qry.value(0)
            util.setLabelText(util.tr("Comprobando tabla %1").arg(item))

            mustAlter = self.mismatchedTable(item, item)
            if mustAlter:
                conte = self.db_.managerModules().content("%s.mtd" % item)
                if conte:
                    msg = util.tr(
                        "La estructura de los metadatos de la tabla '%1' y su "
                        "estructura interna en la base de datos no coinciden. "
                        "Intentando regenerarla.").arg(item)

                    print(msg)
                    self.alterTable2(conte, conte, None, True)

            steps = steps + 1
            util.setProgress(steps)

        self.db_.dbAux().transaction()
        steps = 0
        sqlCursor = FLSqlCursor(None, True, self.db_.dbAux())
        sqlQuery = FLSqlQuery(None, self.db_.dbAux())
        if sqlQuery.exec_(
                "select relname from pg_class where ( relkind = 'r' ) "
                "and ( relname !~ '^Inv' ) "
                "and ( relname !~ '^pg_' ) and ( relname !~ '^sql_' )"):

            util.setTotalSteps(sqlQuery.size())
            while sqlQuery.next():
                item = sqlQuery.value(0)
                steps = steps + 1
                util.setProgress(steps)
                util.setLabelText(util.tr("Creando índices para %1").arg(item))
                mtd = self.db_.manager().metadata(item)
                fL = mtd.fieldList()
                if not mtd or not fL:
                    continue
                for it in fL:
                    if not it or not it.type() == "pixmap":
                        continue
                    cur = FLSqlCursor(item, True, self.db_.dbAux())
                    cur.select("%s not like 'RK@%'" % it.name())
                    while cur.next():
                        v = cur.value(it.name())
                        if v is None:
                            continue

                        v = self.db_.manager().storeLargeValue(mtd, v)
                        if v:
                            buf = cur.primeUpdate()
                            buf.setValue(it.name(), v)
                            cur.update(False)

                sqlCursor.setName(item, True)

        self.db_.dbAux().commit()

        steps = 0
        qry.exec_("select tablename from pg_tables where schemaname='public'")
        util.createProgressDialog(util.tr("Analizando base de datos"),
                                  qry.size())
        while qry.next():
            item = qry.value(0)
            util.setLabelText(util.tr("Analizando tabla %1").arg(item))
            qry2.exec_("vacuum analyze %s" % item)
            steps = steps + 1
            util.setProgress(steps)

        util.destroyProgressDialog()
Ejemplo n.º 29
0
    def run(self):
        value = 0
        cursor = FLSqlCursor("paises")

        try:
            cursor.setModeAccess(cursor.Insert)
            cursor.refreshBuffer()
        except Exception:
            print(traceback.format_exc())
        else:
            value = value + 10

        try:
            cursor.setValueBuffer("codpais", "TEST")
            cursor.setValueBuffer("nombre", "test name")
            cursor.setValueBuffer("codiso", "TS")
        except Exception:
            print(traceback.format_exc())
        else:
            value = value + 10

        try:
            cursor.commitBuffer()
        except Exception:
            print(traceback.format_exc())
        else:
            value = value + 10

        try:
            val1 = cursor.valueBuffer("codpais")
        except Exception:
            print(traceback.format_exc())
        else:
            if val1 == "TEST":
                value = value + 10

        try:
            cursor.select("codpais = 'TEST'")
            while cursor.next():
                cursor.setModeAccess(cursor.Del)
                cursor.refreshBuffer()
                cursor.commitBuffer()
        except Exception:
            print(traceback.format_exc())
        else:
            value = value + 10

        return value
Ejemplo n.º 30
0
    def initCursor(self):
        # si no existe crea la tabla
        if not self._cursor: return False
        if not self._cursor._model: return False

        self._tMD = 0

        if not self._sortField: self._tMD = self._cursor._model.name()
        if self._tMD:
            self.sortField_ = self._tMD.value(self._cursor._currentregister,
                                              self._tMD.primaryKey())
        ownTMD = False
        if not self._tableName:
            #if not cursor_->db()->manager()->existsTable(tableName_)) {
            ownTMD = True
            #tMD = cursor_->db()->manager()->createTable(tableName_);
        else:
            ownTMD = True
            self._tMD = self._cursor._model._table.name

        if not self._tMD:
            return

        if not self._foreignField or not self._fieldRelation:
            if not self._cursor._model:
                if ownTMD and self._tMD and not self._tMD.inCache():
                    self._tMD = None

            return

            if not self._cursor._model.name() == self._tableName:
                ctxt = self._cursor.context()
                self._cursor = FLSqlCursor(self._tableName)
                if self._cursor:
                    self._cursor.setContext(ctxt)
                    cursorAux = 0

                if ownTMD and self._tMD and not self._tMD.inCache():
                    self._tMD = None

                return

        else:
            cursorTopWidget = self.topWidget._cursor(
            )  # ::qt_cast<FLFormDB *>(topWidget)->cursor()
            if cursorTopWidget and not cursorTopWidget._model.name(
            ) == self._tableName:
                self._cursor = cursorTopWidget

        if not self._tableName or not self._foreignField or not self._fieldRelation or cursorAux:
            if ownTMD and self._tMD and not self._tMD.inCache():
                tMD = None

            return

        cursorAux = self._cursor
        curName = self._cursor._model.name()
        rMD = self._cursor._model.relation(self._foreignField,
                                           self._fieldRelation,
                                           self._tableName)
        testM1 = self._tMD.relation(self._fieldRelation, self._foreignField,
                                    curName)
        checkIntegrity = bool(False)

        if not rMD:
            if testM1:
                checkIntegrity = (
                    testM1.cardinality() == FLRelationMetaData.RELATION_M1)
            fMD = FLTableMetaData(self._cursor._model.field(
                self._foreignField))
            if (fMD):
                tmdAux = self._cursor._model(self._tableName)
                if not tmdAux or tmdAux.isQuery():
                    checkIntegrity = False
                if tmdAux and not tmdAux.inCache():  # mirar inCache()
                    tmdAux = None
                rMD = FLRelationMetaData(self._tableName, self._fieldRelation,
                                         FLRelationMetaData.RELATION_1M, False,
                                         False, checkIntegrity)
                fMD.addRelationMD(rMD)
                print(
                    "FLTableDB : La relación entre la tabla del formulario %r y esta tabla %r de este campo no existe, pero sin embargo se han indicado los campos de relación( %r, %r )"
                    % (curName, self._tableName, self._fieldRelation,
                       self._foreignField))
                print(
                    "FLTableDB : Creando automáticamente %r.%r --1M--> %r.%r" %
                    (curName, self._foreignField, self._tableName,
                     self._fieldRelation))

            else:
                print(
                    "FLTableDB : El campo ( %r ) indicado en la propiedad foreignField no se encuentra en la tabla ( %r )"
                    % (self._foreignField, curName))
        rMD = testM1
        if not rMD:
            fMD = FLFieldMetaData(tMD.field(self._fieldRelation))
            if (fMD):
                rMD = FLRelationMetaData(curName, self._foreignField,
                                         FLRelationMetaData.RELATION_1M, False,
                                         False, False)
                fMD.addRelationMD(rMD)
                print(
                    "FLTableDB : Creando automáticamente %r.%r --1M--> %r.%r" %
                    (self._tableName, self._fieldRelation, curName,
                     self._foreignField))
            else:
                print(
                    "FLTableDB : El campo ( %r ) indicado en la propiedad fieldRelation no se encuentra en la tabla ( %r )"
                    % (self._fieldRelation, self._tableName))

        self._cursor = FLSqlCursor(self._tableName, True,
                                   self._cursor.db().connectionName(),
                                   cursorAux, rMD, self)
        if not self._cursor:
            self._cursor = cursorAux
            cursorAux = 0
        else:
            self._cursor.setContext(cursorAux.context())
        if self.showed:
            self.disconnect(cursorAux, QtCore.SIGNAL('newBuffer()'),
                            self.refresh())
            self.connect(cursorAux, QtCore.SIGNAL('newBuffer()'),
                         self.refresh())

        if cursorAux and self.topWidget.isA("FLFormSearchDB"):
            self.topWidget.setCaption(self._cursor._model.alias())
            self.topWidget.setCursor(
                self._cursor
            )  #::qt_cast<FLFormSearchDB *>(topWidget)->setCursor(cursor_);

        if ownTMD and tMD and not tMD.inCache():
            tMD = None
Ejemplo n.º 31
0
    def sqlUpdate(self, t, fL, vL, w, connName="default"):
        """
        Realiza la modificación de uno o más registros en una tabla mediante un objeto FLSqlCursor

        @param t Nombre de la tabla
        @param fL Lista separada con comas de los nombres de los campos
        @param vL Lista separada con comas de los valores correspondientes
        @param w Sentencia where para identificar los registros a editar.
        @param connName Nombre de la conexion
        @return Verdadero en caso de realizar la inserción con éxito, falso en cualquier otro caso
        """
        from pineboolib.fllegacy.FLSqlCursor import FLSqlCursor
        c = FLSqlCursor(t, True, connName)
        c.select(w)
        c.setForwardOnly(True)
        while c.next():

            c.setModeAccess(FLSqlCursor.Edit)
            c.refreshBuffer()

            if isinstance(fL, list):
                i = 0
                for f in fL:
                    c.setValueBuffer(f, vL[i])
                    i = i + 1
            else:
                c.setValueBuffer(fL, vL)

            if not c.commitBuffer():
                return False

        return True
Ejemplo n.º 32
0
    def __init__(self, parent=None, action_or_cursor=None, *args):
        print("FLTableDB:", parent, action_or_cursor, args)
        # TODO: Falta el lineeditsearch y el combo, que los QS lo piden
        super(FLTableDB, self).__init__(parent, *args)
        # TODO: LA inicialización final hay que hacerla más tarde, en el primer
        # show(), porque sino obligas a tenerlo todo preparado en el constructor.
        self._tableView = QtGui.QTableView()
        self._lineEdit = QtGui.QLineEdit()
        _label1 = QtGui.QLabel()
        _label2 = QtGui.QLabel()
        self._comboBox_1 = QtGui.QComboBox()
        self._comboBox_2 = QtGui.QComboBox()
        _label1.setText("Buscar")
        _label2.setText("en")
        self._vlayout = QtGui.QVBoxLayout()
        _hlayout = QtGui.QHBoxLayout()
        self._tableView._v_header = self._tableView.verticalHeader()
        self._tableView._v_header.setDefaultSectionSize(18)
        self._tableView._h_header = self._tableView.horizontalHeader()
        self._tableView._h_header.setDefaultSectionSize(70)
        _hlayout.addWidget(_label1)
        _hlayout.addWidget(self._lineEdit)
        _hlayout.addWidget(_label2)
        _hlayout.addWidget(self._comboBox_1)
        _hlayout.addWidget(self._comboBox_2)
        self._vlayout.addLayout(_hlayout)
        self._vlayout.addWidget(self._tableView)
        self.setLayout(self._vlayout)
        self._parent = parent
        while True:
            parent_cursor = getattr(self._parent, "_cursor", None)
            if parent_cursor: break
            new_parent = self._parent.parentWidget()
            if new_parent is None: break
            self._parent = new_parent
            print(self._parent)

        self._tableView.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
        self._tableView.setSelectionMode(
            QtGui.QAbstractItemView.SingleSelection)
        self._tableView.setSelectionBehavior(
            QtGui.QAbstractItemView.SelectRows)
        self._tableView.setAlternatingRowColors(True)

        if action_or_cursor is None and parent_cursor:
            action_or_cursor = parent_cursor
        if isinstance(action_or_cursor, FLSqlCursor):
            self._cursor = action_or_cursor
        elif isinstance(action_or_cursor, str):
            self._cursor = FLSqlCursor(action_or_cursor)
        else:
            self._cursor = None
        if self._cursor:
            self._tableView._h_header.setResizeMode(
                QtGui.QHeaderView.ResizeToContents)
            self._tableView.setModel(self._cursor._model)
            self._tableView.setSelectionModel(self._cursor.selection())
        self.tableRecords = self  # control de tabla interno

        #Carga de comboBoxs y connects .- posiblemente a mejorar
        if self._cursor:
            for column in range(self._cursor._model.columnCount()):
                self._comboBox_1.addItem(
                    self._cursor._model.headerData(column,
                                                   QtCore.Qt.Horizontal,
                                                   QtCore.Qt.DisplayRole))
                self._comboBox_2.addItem(
                    self._cursor._model.headerData(column,
                                                   QtCore.Qt.Horizontal,
                                                   QtCore.Qt.DisplayRole))
        self._comboBox_1.addItem("*")
        self._comboBox_2.addItem("*")
        self._comboBox_1.setCurrentIndex(0)
        self._comboBox_2.setCurrentIndex(1)
        self._comboBox_1.currentIndexChanged.connect(self.comboBox_putFirstCol)
        self._comboBox_2.currentIndexChanged.connect(
            self.comboBox_putSecondCol)

        self.sort = []
        self.timer_1 = QtCore.QTimer(self)
        self.timer_1.singleShot(100, self.loaded)
Ejemplo n.º 33
0
    def alterTable2(self, mtd1, mtd2, key, force=False):

        util = FLUtil()

        oldMTD = None
        newMTD = None
        doc = QDomDocument("doc")
        docElem = None

        if not util.docDocumentSetContect(doc, mtd1):
            print("FLManager::alterTable : " +
                  qApp.tr("Error al cargar los metadatos."))
        else:
            docElem = doc.documentElement()
            oldMTD = self.db_.manager().metadata(docElem, True)

        if oldMTD and oldMTD.isQuery():
            return True

        if not util.docDocumentSetContect(doc, mtd2):
            print("FLManager::alterTable : " +
                  qApp.tr("Error al cargar los metadatos."))
            return False
        else:
            docElem = doc.documentElement()
            newMTD = self.db_.manager().metadata(docElem, True)

        if not oldMTD:
            oldMTD = newMTD

        if not oldMTD.name() == newMTD.name():
            print("FLManager::alterTable : " +
                  qApp.tr("Los nombres de las tablas nueva y vieja difieren."))
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        oldPK = oldMTD.primaryKey()
        newPK = newMTD.primaryKey()

        if not oldPK == newPK:
            print("FLManager::alterTable : " +
                  qApp.tr("Los nombres de las claves primarias difieren."))
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        if not self.db_.manager().checkMetaData(oldMTD, newMTD):
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return True

        if not self.db_.manager().existsTable(oldMTD.name()):
            print("FLManager::alterTable : " + qApp.tr(
                "La tabla %1 antigua de donde importar los registros no existe.").arg(oldMTD.name()))
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        fieldList = oldMTD.fieldList()
        oldField = None

        if not fieldList:
            print("FLManager::alterTable : " +
                  qApp.tr("Los antiguos metadatos no tienen campos."))
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        renameOld = "%salteredtable%s" % (
            oldMTD.name()[0:5], QDateTime().currentDateTime().toString("ddhhssz"))

        if not self.db_.dbAux():
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        self.db_.dbAux().transaction()

        if key and len(key) == 40:
            c = FLSqlCursor("flfiles", True, self.db_.dbAux())
            c.setForwardOnly(True)
            c.setFilter("nombre = '%s.mtd'" % renameOld)
            c.select()
            if not c.next():
                buffer = c.primeInsert()
                buffer.setValue("nombre", "%s.mtd" % renameOld)
                buffer.setValue("contenido", mtd1)
                buffer.setValue("sha", key)
                c.insert()

        q = FLSqlQuery("", self.db_.dbAux())
        constraintName = "%s_pkey" % oldMTD.name()

        if self.constraintExists(constraintName) and not q.exec_("ALTER TABLE %s DROP CONSTRAINT %s" % (oldMTD.name(), constraintName)):
            print("FLManager : " + qApp.tr("En método alterTable, no se ha podido borrar el índice %1_pkey de la tabla antigua.").arg(oldMTD.name()))
            self.db_.dbAux().rollback()
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        fieldsNamesOld = []
        for it in fieldList:
            if newMTD.field(it.name()):
                fieldsNamesOld.append(it.name())

            if it.isUnique():
                constraintName = "%s_%s_key" % (oldMTD.name(), it.name())
                if self.constraintExists(constraintName) and not q.exec_("ALTER TABLE %s DROP CONSTRAINT %s" % (oldMTD.name(), constraintName)):
                    print("FLManager : " + qApp.tr("En método alterTable, no se ha podido borrar el índice %1_%2_key de la tabla antigua.")
                          .arg(oldMTD.name(), oldField.name()))
                    self.db_.dbAux().rollback()
                    if oldMTD and not oldMTD == newMTD:
                        del oldMTD
                    if newMTD:
                        del newMTD

                    return False

        if not q.exec_("ALTER TABLE %s RENAME TO %s" % (oldMTD.name(), renameOld)):
            print("FLManager::alterTable : " +
                  qApp.tr("No se ha podido renombrar la tabla antigua."))

            self.db_.dbAux().rollback()
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        if not self.db_.manager().createTable(newMTD):
            self.db_.dbAux().rollback()
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        v = None
        ok = False

        if not force and not fieldsNamesOld:
            self.db_.dbAux().rollback()
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return self.alterTable2(mtd1, mtd2, key, True)

        oldCursor = FLSqlCursor(renameOld, True, self.db_.dbAux())
        oldCursor.setModeAccess(oldCursor.Browse)
        newCursor = FLSqlCursor(newMTD.name(), True, self.db_.dbAux())
        newCursor.setMode(newCursor.Insert)

        oldCursor.select()
        totalSteps = oldCursor.size()
        progress = QProgressDialog(qApp.tr("Reestructurando registros para %1...").arg(
            newMTD.alias()), qApp.tr("Cancelar"), 0, totalSteps)
        progress.setLabelText(qApp.tr("Tabla modificada"))

        step = 0
        newBuffer = None
        newField = None
        listRecords = []
        newBufferInfo = self.recordInfo2(newMTD.name())
        oldFieldsList = {}
        newFieldsList = {}
        defValues = {}
        v = None

        for newField in fieldList:
            oldField = oldMTD.field(newField.name())
            defValues[str(step)] = None
            if not oldField or not oldCursor.field(oldField.name()):
                if not oldField:
                    oldField = newField
                if not newField.type() == "serial":
                    v = newField.defaultValue()
                    defValues[str(step)] = v

            newFieldsList[str(step)] = newField
            oldFieldsList[str(step)] = oldField
            step = step + 1

        step = 0
        ok = True
        while oldCursor.next():
            newBuffer = newBufferInfo

            for reg in defValues.keys():
                newField = newFieldsList[reg]
                oldField = oldFieldsList[reg]
                if defValues[reg]:
                    v = defValues[reg]
                else:
                    v = oldCursor.value(newField.name())
                    if (not oldField.allowNull or not newField.allowNull()) and not v and not newField.type() == "serial":
                        defVal = newField.defaultValue()
                        if defVal is not None:
                            v = defVal

                    if v is not None and not newBuffer.field(newField.name()).type() == newField.type():
                        print("FLManager::alterTable : " + qApp.tr(
                            "Los tipos del campo %1 no son compatibles. Se introducirá un valor nulo.").arg(newField.name()))

                if v is not None and newField.type() == "string" and newField.length() > 0:
                    v = str(v)[0:newField.length()]

                if (not oldField.allowNull() or not newField.allowNull()) and v is None:
                    if oldField.type() == "serial":
                        v = int(self.nextSerialVal(
                            newMTD.name(), newField.name()))
                    elif oldField.type() in ("int", "uint", "bool", "unlock"):
                        v = 0
                    elif oldField.type() == "double":
                        v = 0.0
                    elif oldField.type() == "time":
                        v = QTime().currentTime()
                    elif oldField.type() == "date":
                        v = QDate().currentDate()
                    else:
                        v = "NULL"[0:newField.length()]

                newBuffer.setValue(newField.name(), v)

            listRecords.append(newBuffer)

            if not self.insertMulti(newMTD.name(), listRecords):
                ok = False
                listRecords.clear()
                break

            listRecords.clear()

        if len(listRecords) > 0:
            if not self.insertMulti(newMTD.name(), listRecords):
                ok = False
            listRecords.clear()

        progress.setProgress(totalSteps)

        if oldMTD and not oldMTD == newMTD:
            del oldMTD

        if newMTD:
            del newMTD

        if ok:
            self.db_.dbAux().commit()
        else:
            self.db_.dbAux().rollback()
            return False

        if force and ok:
            q.exec_("DROP TABLE %s CASCADE" % renameOld)

        return True
Ejemplo n.º 34
0
    def alterTable(self, mtd1, mtd2, key):
        util = FLUtil()

        oldMTD = None
        newMTD = None
        doc = QDomDocument("doc")
        docElem = None

        if not util.docDocumentSetContect(doc, mtd1):
            print("FLManager::alterTable : " +
                  qApp.tr("Error al cargar los metadatos."))
        else:
            docElem = doc.documentElement()
            oldMTD = self.db_.manager().metadata(docElem, True)

        if oldMTD and oldMTD.isQuery():
            return True

        if not util.docDocumentSetContect(doc, mtd2):
            print("FLManager::alterTable : " +
                  qApp.tr("Error al cargar los metadatos."))
            return False
        else:
            docElem = doc.documentElement()
            newMTD = self.db_.manager().metadata(docElem, True)

        if not oldMTD:
            oldMTD = newMTD

        if not oldMTD.name() == newMTD.name():
            print("FLManager::alterTable : " +
                  qApp.tr("Los nombres de las tablas nueva y vieja difieren."))
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        oldPK = oldMTD.primaryKey()
        newPK = newMTD.primaryKey()

        if not oldPK == newPK:
            print("FLManager::alterTable : " +
                  qApp.tr("Los nombres de las claves primarias difieren."))
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        if not self.db_.manager().checkMetaData(oldMTD, newMTD):
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return True

        if not self.db_.manager().existsTable(oldMTD.name()):
            print("FLManager::alterTable : " + qApp.tr(
                "La tabla %1 antigua de donde importar los registros no existe.").arg(oldMTD.name()))
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        fieldList = oldMTD.fieldList()
        oldField = None

        if not fieldList:
            print("FLManager::alterTable : " +
                  qApp.tr("Los antiguos metadatos no tienen campos."))
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        renameOld = "%salteredtable%s" % (
            oldMTD.name()[0:5], QDateTime().currentDateTime().toString("ddhhssz"))

        if not self.db_.dbAux():
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        self.db_.dbAux().transaction()

        if key and len(key) == 40:
            c = FLSqlCursor("flfiles", True, self.db_.dbAux())
            c.setForwardOnly(True)
            c.setFilter("nombre = '%s.mtd'" % renameOld)
            c.select()
            if not c.next():
                buffer = c.primeInsert()
                buffer.setValue("nombre", "%s.mtd" % renameOld)
                buffer.setValue("contenido", mtd1)
                buffer.setValue("sha", key)
                c.insert()

        q = FLSqlQuery("", self.db_.dbAux())
        if not q.exec_("CREATE TABLE %s AS SELECT * FROM %s;" % (renameOld, oldMTD.name())) or not q.exec_("DROP TABLE %s;" % oldMTD.name()):
            print("FLManager::alterTable : " +
                  qApp.tr("No se ha podido renombrar la tabla antigua."))

            self.db_.dbAux().rollback()
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        if not self.db_.manager().createTable(newMTD):
            self.db_.dbAux().rollback()
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        oldCursor = FLSqlCursor(renameOld, True, self.db_.dbAux())
        oldCursor.setModeAccess(oldCursor.Browse)
        newCursor = FLSqlCursor(newMTD.name(), True, self.db_.dbAux())
        newCursor.setMode(newCursor.Insert)

        oldCursor.select()
        totalSteps = oldCursor.size()
        progress = QProgressDialog(qApp.tr("Reestructurando registros para %1...").arg(
            newMTD.alias()), qApp.tr("Cancelar"), 0, totalSteps)
        progress.setLabelText(qApp.tr("Tabla modificada"))

        step = 0
        newBuffer = None
        # sequence = ""
        fieldList = newMTD.fieldList()
        newField = None

        if not fieldList:
            print("FLManager::alterTable : " +
                  qApp.tr("Los nuevos metadatos no tienen campos."))
            self.db_.dbAux().rollback()
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        v = None
        ok = True
        while oldCursor.next():
            v = None
            newBuffer = newCursor.primeInsert()

            for it in fieldList:
                oldField = oldMTD.field(newField.name())
                if not oldField or not oldCursor.field(oldField.name()):
                    if not oldField:
                        oldField = newField

                    v = newField.defaultValue()

                else:
                    v = oldCursor.value(newField.name())
                    if (not oldField.allowNull() or not newField.allowNull()) and (v is None):
                        defVal = newField.defaultValue()
                        if defVal is not None:
                            v = defVal

                    if not newBuffer.field(newField.name()).type() == newField.type():
                        print("FLManager::alterTable : " + qApp.tr("Los tipos del campo %1 no son compatibles. Se introducirá un valor nulo.")
                              .arg(newField.name()))

                if not oldField.allowNull() or not newField.allowNull() and v is not None:
                    if oldField.type() in ("int", "serial", "uint", "bool", "unlock"):
                        v = 0
                    elif oldField.type() == "double":
                        v = 0.0
                    elif oldField.type() == "time":
                        v = QTime().currentTime()
                    elif oldField.type() == "date":
                        v = QDate().currentDate()
                    else:
                        v = "NULL"[0:newField.length()]

                newBuffer.setValue(newField.name(), v)

            if not newCursor.insert():
                ok = False
                break
            step = step + 1
            progress.setProgress(step)

        progress.setProgress(totalSteps)
        if oldMTD and not oldMTD == newMTD:
            del oldMTD
        if newMTD:
            del newMTD

        if ok:
            self.db_.dbAux().commit()
        else:
            self.db_.dbAux().rollback()
            return False

        return True
Ejemplo n.º 35
0
    def initCursor(self):
        if not self.topWidget or not self.cursor_:
            return

        if not self.cursor_.metadata():
            return

        tMD = None

        if not self.sortField_:
            tMD = self.cursor_.metadata()
            if tMD:
                self.sortField_ = tMD.field(tMD.primaryKey())

        ownTMD = None
        if self.tableName_:
            if not self.cursor_.db().manager().existsTable(self.tableName_):
                ownTMD = True
                tMD = self.cursor_.db().manager().createTable(self.tableName_)
            else:
                ownTMD = True
                tMD = self.cursor_.db().manager().metadata(self.tableName_)

            if not tMD:
                return

            if not self.foreignField_ or not self.fieldRelation_:
                if not self.cursor_.metadata():
                    if ownTMD and tMD and not tMD.inCache():
                        del tMD
                    return

                if not self.cursor_.metadata().name() == self.tableName_:
                    ctxt = self.cursor_.context()
                    self.cursor_ = FLSqlCursor(
                        self.tableName_, True, self.cursor_.db().connectionName(), None, None, self
                    )

                    if self.cursor_:
                        self.cursor_.setContext(ctxt)
                        self.cursorAux = None

                    if ownTMD and tMD and not tMD.inCache():
                        del tMD

                    return

            else:
                cursorTopWidget = self.topWidget.cursor()
                if cursorTopWidget and not cursorTopWidget.metadata().name() == self.tableName_:
                    self.cursor_ = cursorTopWidget

        if not self.tableName_ or not self.foreignField_ or not self.fieldRelation_ or self.cursorAux:
            if ownTMD and tMD and not tMD.inCache():
                del tMD

            return

        self.cursorAux = self.cursor_
        curName = self.cursor_.metadata().name()
        rMD = self.cursor_.metadata().relation(self.foreignField_, self.fieldRelation_, self.tableName_)
        testM1 = tMD.relation(self.fieldRelation_, self.foreignField_, curName)
        checkIntegrity = False
        if not rMD:
            if testM1:
                if testM1.cardinality() == FLRelationMetaData.RELATION_M1:
                    checkIntegrity = True
            fMD = self.cursor_.metadata().field(self.foreignField_)
            if fMD:
                tmdAux = self.cursor_.db().manager().metadata(self.tableName_)
                if not tmdAux or tmdAux.isQuery():
                    checkIntegrity = False
                if tmdAux and not tmdAux.inCache():
                    del tmdAux

                rMD = FLRelationMetaData(
                    self.tableName_, self.fieldRelation_, FLRelationMetaData.RELATION_1M, False, False, checkIntegrity
                )
                fMD.addRelationMD(rMD)
                # print("FLTableDB : La relación entre la tabla del formulario %s y esta tabla %s de este campo no existe, pero sin embargo se han indicado los campos de relación( %s, %s )" % ( curName, self.tableName_, self.fieldRelation_, self.foreignField_))
                # print("FLTableDB : Creando automáticamente %s.%s --1M--> %s.%s" % (curName, self.foreignField_, self.tableName_, self.fieldRelation_))
            else:
                # print("FLTableDB : El campo ( %s ) indicado en la propiedad foreignField no se encuentra en la tabla ( %s )" % (self.foreignField_, curName))
                pass

        rMD = testM1
        if not rMD:
            fMD = tMD.field(self.fieldRelation_)
            if fMD:
                rMD = FLRelationMetaData(
                    curName, self.foreignField_, FLRelationMetaData.RELATION_1M, False, False, False
                )
                fMD.addRelationMD(rMD)
                print(
                    "FLTableDB : Creando automáticamente %s.%s --1M--> %s.%s"
                    % (self.tableName_, self.fieldRelation_, curName, self.foreignField_)
                )

            else:
                print(
                    "FLTableDB : El campo ( %s ) indicado en la propiedad fieldRelation no se encuentra en la tabla ( %s )"
                    % (self.fieldRelation_, self.tableName_)
                )

        self.cursor_ = FLSqlCursor(self.tableName_, True, self.cursor_.db().connectionName(), self.cursorAux, rMD, self)
        if not self.cursor_:
            self.cursor_ = self.cursorAux
            self.cursorAux = None

        else:

            self.cursor_.setContext(self.cursorAux.context())
            if self.showed:
                try:
                    self.cursorAux.newBuffer.disconnect(self.refresh)
                except:
                    pass

            self.cursorAux.newBuffer.connect(self.refresh)

        if self.cursorAux and isinstance(self.topWidget, FLFormSearchDB):
            self.topWidget.setCaption(self.cursor_.metadata().alias())
            self.topWidget_.setCursor(self.cursor_)

        if ownTMD or tMD and not tMD.inCache():
            del tMD
Ejemplo n.º 36
0
class FLTableDB(QtGui.QWidget):
    _tableView = None
    _vlayout = None
    _lineEdit = None
    _comboBox_1 = None
    _comboBox_2 = None
    _topWidget = None
    _cursor = None
    _loaded = False
    _cursorLoaded = False

    _tableName = None
    _foreignField = None
    _fieldRelation = None
    _action = None
    _foreignFilter = None

    def __init__(self, parent=None, action_or_cursor=None, *args):
        #print("FLTableDB:", parent, action_or_cursor , args)
        # TODO: Falta el lineeditsearch y el combo, que los QS lo piden
        super(FLTableDB, self).__init__(parent, *args)
        # TODO: LA inicialización final hay que hacerla más tarde, en el primer
        # show(), porque sino obligas a tenerlo todo preparado en el constructor.
        self._tableView = QtGui.QTableView()
        self._lineEdit = QtGui.QLineEdit()
        _label1 = QtGui.QLabel()
        _label2 = QtGui.QLabel()
        self._comboBox_1 = QtGui.QComboBox()
        self._comboBox_2 = QtGui.QComboBox()
        _label1.setText("Buscar")
        _label2.setText("en")
        self._vlayout = QtGui.QVBoxLayout()
        _hlayout = QtGui.QHBoxLayout()
        self._tableView._v_header = self._tableView.verticalHeader()
        self._tableView._v_header.setDefaultSectionSize(18)
        self._tableView._h_header = self._tableView.horizontalHeader()
        self._tableView._h_header.setDefaultSectionSize(70)
        _hlayout.addWidget(_label1)
        _hlayout.addWidget(self._lineEdit)
        _hlayout.addWidget(_label2)
        _hlayout.addWidget(self._comboBox_1)
        _hlayout.addWidget(self._comboBox_2)
        self._vlayout.addLayout(_hlayout)
        self._vlayout.addWidget(self._tableView)
        self.setLayout(self._vlayout)
        self._parent = parent
        while True:
            parent_cursor = getattr(self._parent, "_cursor", None)
            if parent_cursor: break
            new_parent = self._parent.parentWidget()
            if new_parent is None: break
            self._parent = new_parent
            print(self._parent)

        self._tableView.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
        self._tableView.setSelectionMode(
            QtGui.QAbstractItemView.SingleSelection)
        self._tableView.setSelectionBehavior(
            QtGui.QAbstractItemView.SelectRows)
        self._tableView.setAlternatingRowColors(True)

        if action_or_cursor is None and parent_cursor:
            action_or_cursor = parent_cursor
        if isinstance(action_or_cursor, FLSqlCursor):
            self._cursor = action_or_cursor
        elif isinstance(action_or_cursor, str):
            self._action = action_or_cursor
        else:
            self._cursor = None
        if self._cursor:
            self._tableView._h_header.setResizeMode(
                QtGui.QHeaderView.ResizeToContents)
            self._tableView.setModel(self._cursor.model())
            self._tableView.setSelectionModel(self._cursor.selection())
        self.tableRecords = self  # control de tabla interno

        #Carga de comboBoxs y connects .- posiblemente a mejorar
        if self._cursor:
            i = 0
            for column in range(self._cursor.model().columnCount()):
                #print("Columna ", i)
                self._comboBox_1.addItem(self._cursor.model().headerData(
                    column, QtCore.Qt.Horizontal, QtCore.Qt.DisplayRole))
                self._comboBox_2.addItem(self._cursor.model().headerData(
                    column, QtCore.Qt.Horizontal, QtCore.Qt.DisplayRole))
        self._comboBox_1.addItem("*")
        self._comboBox_2.addItem("*")
        self._comboBox_1.setCurrentIndex(0)
        self._comboBox_2.setCurrentIndex(1)
        self._comboBox_1.currentIndexChanged.connect(self.comboBox_putFirstCol)
        self._comboBox_2.currentIndexChanged.connect(
            self.comboBox_putSecondCol)

        self.sort = []
        self.timer_1 = QtCore.QTimer(self)
        self.timer_1.singleShot(100, self.loaded)
        self._topWidget = parent

    def __getattr__(self, name):
        return DefFun(self, name)

    def loaded(self):
        # Es necesario pasar a modo interactivo lo antes posible
        # Sino, creamos un bug en el cierre de ventana: se recarga toda la tabla para saber el tamaño
        #print("FLTableDB(%s): setting columns in interactive mode" % self._tableName)
        self._tableView._h_header.setResizeMode(QtGui.QHeaderView.Interactive)
        self._loaded = True
        while True:  #Ahora podemos buscar el cursor ... porque ya estamos añadidos al formulario
            parent_cursor = getattr(self._parent, "_cursor", None)
            if parent_cursor: break
            new_parent = self._parent.parentWidget()
            if new_parent is None: break
            self._parent = new_parent
        self.initCursor()

    def cursor(self):
        if not self._cursorLoaded:
            self.timer_cursor = QtCore.QTimer(self)
            self.timer_cursor.singleShot(100, self.cursor)
        else:
            if not self._cursor:
                self._cursor = None
                print("WARN: FLTableDB.cursor(): Cursor Inválido a",
                      self._tableName)
            return self._cursor

    def obj(self):
        return self

    def comboBox_putFirstCol(self):
        self.putFirstCol(str(self._comboBox_1.currentText()))

    def comboBox_putSecondCol(self):
        self.putSecondCol(str(self._comboBox_2.currentText()))

    def putFirstCol(self, fN):
        _oldPos = None
        _oldFirst = self._tableView._h_header.logicalIndex(0)
        for column in range(self._cursor.model().columnCount()):
            if self._cursor.model().headerData(
                    column, QtCore.Qt.Horizontal,
                    QtCore.Qt.DisplayRole).lower() == fN.lower():
                _oldPos = self._tableView._h_header.visualIndex(column)
                if not self._comboBox_1.currentText() == fN:
                    self._comboBox_1.setCurrentIndex(column)
                    return False
                break

        if not _oldPos or fN == "*":
            return False
        else:
            self._tableView._h_header.swapSections(_oldPos, 0)
            self._comboBox_2.setCurrentIndex(_oldFirst)
            return True

    def putSecondCol(self, fN):
        if self._cursor is None:
            return
        _oldPos = None
        _oldSecond = self._tableView._h_header.logicalIndex(1)
        for column in range(self._cursor.model().columnCount()):
            if self._cursor.model().headerData(
                    column, QtCore.Qt.Horizontal,
                    QtCore.Qt.DisplayRole).lower() == fN.lower():
                _oldPos = self._tableView._h_header.visualIndex(column)
                break

        if not _oldPos or fN == "*":
            return False
        if not self._comboBox_1.currentText() == fN:
            self._tableView._h_header.swapSections(_oldPos, 1)
        else:
            self._comboBox_1.setCurrentIndex(_oldSecond)
        return True

    def setTableName(self, tableName):
        self._tableName = tableName
        self.initCursor()
        return True

    def tableName(self):
        return self._tableName

    def foreignField(self):
        return self._foreignField

    def fieldRelation(self):
        return self._fieldRelation

    def setForeignField(self, foreignField):
        self._foreignField = foreignField
        self.initCursor()
        return True

    def setFieldRelation(self, fieldRelation):
        self._fieldRelation = fieldRelation
        self.initCursor()
        return True

    def setActionName(self, action):
        self._action = action

    def showAlias(self, b):
        self._showAlias = b

    def initCursor(self):
        filtro = None
        self._cursorLoaded = True
        if not self._foreignField:
            return
        if not self._fieldRelation:
            return
        if not self._tableName:
            return

        if self._loaded:

            tipo = self._cursor.model().fieldType(self._fieldRelation)
            foranea = self._parent.parentWidget().cursor().valueBuffer(
                self._foreignField)
            if foranea is None:
                #print("FLTable(%s): campo foraneo \"%s.%s\" no encontrado." % (self._tableName,self._parent.parentWidget()._cursor.table(), self._foreignField))
                return
            if tipo is "uint":
                self._foreignFilter = "%s = %s" % (
                    self._fieldRelation,
                    self._parent.parentWidget().cursor().valueBuffer(
                        self._foreignField))
            else:
                self._foreignFilter = "%s = '%s'" % (
                    self._fieldRelation,
                    self._parent.parentWidget().cursor().valueBuffer(
                        self._foreignField))

            #print("Filtro:%s" % filtro)
            self._cursor.setMainFilter(self._foreignFilter)
            self._cursor.refresh()
        else:
            self._cursor = FLSqlCursor(self._tableName)

            #self._cursor.setMainFilter("%s = ")

    @QtCore.pyqtSlot()
    def close(self):
        print("FLTableDB: close()")

    @QtCore.pyqtSlot()
    def refresh(self):
        print("FLTableDB: refresh()", self.parent().parent().parent())
        self._cursor.setMainFilter(self._foreignFilter)

    @QtCore.pyqtSlot()
    def show(self):
        print("FLTableDB: show event")
        #super(FLTableDB, self).show()

        if self._cursor:
            self._tableView._h_header.setResizeMode(
                QtGui.QHeaderView.ResizeToContents)
            self._tableView.setModel(self._cursor.model())
            self._tableView.setSelectionModel(self._cursor.selection())
        self.tableRecords = self  # control de tabla interno

        #Carga de comboBoxs y connects .- posiblemente a mejorar
        if self._cursor:
            for column in range(self._cursor.model().columnCount()):

                self._comboBox_1.addItem(self._cursor.model().headerData(
                    column, QtCore.Qt.Horizontal, QtCore.Qt.DisplayRole))
                self._comboBox_2.addItem(self._cursor.model().headerData(
                    column, QtCore.Qt.Horizontal, QtCore.Qt.DisplayRole))
        self._comboBox_1.addItem("*")
        self._comboBox_2.addItem("*")
        self._comboBox_1.setCurrentIndex(0)
        self._comboBox_2.setCurrentIndex(1)
        self._comboBox_1.currentIndexChanged.connect(self.comboBox_putFirstCol)
        self._comboBox_2.currentIndexChanged.connect(
            self.comboBox_putSecondCol)

        self.sort = []
        self.timer_1 = QtCore.QTimer(self)
        self.timer_1.singleShot(100, self.loaded)

    @QtCore.pyqtSlot()
    def insertRecord(self):
        self._cursor.insertRecord()

    @QtCore.pyqtSlot()
    def editRecord(self):
        self._cursor.editRecord()

    @QtCore.pyqtSlot()
    def deleteRecord(self):
        self._cursor.deleteRecord()

    @QtCore.pyqtSlot()
    def browseRecord(self):
        self._cursor.browseRecord()

    @QtCore.pyqtSlot()
    def copyRecord(self):
        self._cursor.copyRecord()

    @decorators.WorkingOnThis
    def setEditOnly(self, value):
        return True

    @decorators.WorkingOnThis
    def setReadOnly(self, value):
        return True
Ejemplo n.º 37
0
    def alterTable(self, mtd1, mtd2, key):
        util = FLUtil()

        oldMTD = None
        newMTD = None
        doc = QDomDocument("doc")
        docElem = None

        if not util.docDocumentSetContect(doc, mtd1):
            print("FLManager::alterTable : " +
                  qApp.tr("Error al cargar los metadatos."))
        else:
            docElem = doc.documentElement()
            oldMTD = self.db_.manager().metadata(docElem, True)

        if oldMTD and oldMTD.isQuery():
            return True

        if not util.docDocumentSetContect(doc, mtd2):
            print("FLManager::alterTable : " +
                  qApp.tr("Error al cargar los metadatos."))
            return False
        else:
            docElem = doc.documentElement()
            newMTD = self.db_.manager().metadata(docElem, True)

        if not oldMTD:
            oldMTD = newMTD

        if not oldMTD.name() == newMTD.name():
            print("FLManager::alterTable : " +
                  qApp.tr("Los nombres de las tablas nueva y vieja difieren."))
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        oldPK = oldMTD.primaryKey()
        newPK = newMTD.primaryKey()

        if not oldPK == newPK:
            print("FLManager::alterTable : " +
                  qApp.tr("Los nombres de las claves primarias difieren."))
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        if not self.db_.manager().checkMetaData(oldMTD, newMTD):
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return True

        if not self.db_.manager().existsTable(oldMTD.name()):
            print("FLManager::alterTable : " + qApp.tr(
                "La tabla %1 antigua de donde importar los registros no existe."
            ).arg(oldMTD.name()))
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        fieldList = oldMTD.fieldList()
        oldField = None

        if not fieldList:
            print("FLManager::alterTable : " +
                  qApp.tr("Los antiguos metadatos no tienen campos."))
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        renameOld = "%salteredtable%s" % (oldMTD.name()[0:5], QDateTime(
        ).currentDateTime().toString("ddhhssz"))

        if not self.db_.dbAux():
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        self.db_.dbAux().transaction()

        if key and len(key) == 40:
            c = FLSqlCursor("flfiles", True, self.db_.dbAux())
            c.setForwardOnly(True)
            c.setFilter("nombre = '%s.mtd'" % renameOld)
            c.select()
            if not c.next():
                buffer = c.primeInsert()
                buffer.setValue("nombre", "%s.mtd" % renameOld)
                buffer.setValue("contenido", mtd1)
                buffer.setValue("sha", key)
                c.insert()

        q = FLSqlQuery("", self.db_.dbAux())
        if not q.exec_("CREATE TABLE %s AS SELECT * FROM %s;" %
                       (renameOld, oldMTD.name())) or not q.exec_(
                           "DROP TABLE %s;" % oldMTD.name()):
            print("FLManager::alterTable : " +
                  qApp.tr("No se ha podido renombrar la tabla antigua."))

            self.db_.dbAux().rollback()
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        if not self.db_.manager().createTable(newMTD):
            self.db_.dbAux().rollback()
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        oldCursor = FLSqlCursor(renameOld, True, self.db_.dbAux())
        oldCursor.setModeAccess(oldCursor.Browse)
        newCursor = FLSqlCursor(newMTD.name(), True, self.db_.dbAux())
        newCursor.setMode(newCursor.Insert)

        oldCursor.select()
        totalSteps = oldCursor.size()
        progress = QProgressDialog(
            qApp.tr("Reestructurando registros para %1...").arg(
                newMTD.alias()), qApp.tr("Cancelar"), 0, totalSteps)
        progress.setLabelText(qApp.tr("Tabla modificada"))

        step = 0
        newBuffer = None
        # sequence = ""
        fieldList = newMTD.fieldList()
        newField = None

        if not fieldList:
            print("FLManager::alterTable : " +
                  qApp.tr("Los nuevos metadatos no tienen campos."))
            self.db_.dbAux().rollback()
            if oldMTD and not oldMTD == newMTD:
                del oldMTD
            if newMTD:
                del newMTD

            return False

        v = None
        ok = True
        while oldCursor.next():
            v = None
            newBuffer = newCursor.primeInsert()

            for it in fieldList:
                oldField = oldMTD.field(newField.name())
                if not oldField or not oldCursor.field(oldField.name()):
                    if not oldField:
                        oldField = newField

                    v = newField.defaultValue()

                else:
                    v = oldCursor.value(newField.name())
                    if (not oldField.allowNull()
                            or not newField.allowNull()) and (v is None):
                        defVal = newField.defaultValue()
                        if defVal is not None:
                            v = defVal

                    if not newBuffer.field(
                            newField.name()).type() == newField.type():
                        print("FLManager::alterTable : " + qApp.tr(
                            "Los tipos del campo %1 no son compatibles. Se introducirá un valor nulo."
                        ).arg(newField.name()))

                if not oldField.allowNull(
                ) or not newField.allowNull() and v is not None:
                    if oldField.type() in ("int", "serial", "uint", "bool",
                                           "unlock"):
                        v = 0
                    elif oldField.type() == "double":
                        v = 0.0
                    elif oldField.type() == "time":
                        v = QTime().currentTime()
                    elif oldField.type() == "date":
                        v = QDate().currentDate()
                    else:
                        v = "NULL"[0:newField.length()]

                newBuffer.setValue(newField.name(), v)

            if not newCursor.insert():
                ok = False
                break
            step = step + 1
            progress.setProgress(step)

        progress.setProgress(totalSteps)
        if oldMTD and not oldMTD == newMTD:
            del oldMTD
        if newMTD:
            del newMTD

        if ok:
            self.db_.dbAux().commit()
        else:
            self.db_.dbAux().rollback()
            return False

        return True
Ejemplo n.º 38
0
    def sqlUpdate(self, t, fL, vL, w, connName="default"):
        """
        Realiza la modificación de uno o más registros en una tabla mediante un objeto FLSqlCursor

        @param t Nombre de la tabla
        @param fL Lista separada con comas de los nombres de los campos
        @param vL Lista separada con comas de los valores correspondientes
        @param w Sentencia where para identificar los registros a editar.
        @param connName Nombre de la conexion
        @return Verdadero en caso de realizar la inserción con éxito, falso en cualquier otro caso
        """
        from pineboolib.fllegacy.FLSqlCursor import FLSqlCursor
        c = FLSqlCursor(t, True, connName)
        c.setForwardOnly(True)

        # if not c.select(w):
        #     return False
        c.select(w)

        while c.next():
            c.setModeAccess(FLSqlCursor.Edit)
            c.refreshBuffer()

            if isinstance(fL, list):
                i = 0
                for f in fL:
                    c.setValueBuffer(f, vL[i])
                    i = i + 1
            else:
                c.setValueBuffer(fL, vL)

            if not c.commitBuffer():
                return False

        return True
Ejemplo n.º 39
0
    def initCursor(self):
        # si no existe crea la tabla
        if not self._cursor: return False
        if not self._cursor._model: return False

        self._tMD = 0

        if not self._sortField: self._tMD = self._cursor._model.name()
        if self._tMD:
            self.sortField_ = self._tMD.value(self._cursor._currentregister, self._tMD.primaryKey())
        ownTMD = False
        if not self._tableName:
            #if not cursor_->db()->manager()->existsTable(tableName_)) {
            ownTMD = True
            #tMD = cursor_->db()->manager()->createTable(tableName_);
        else:
            ownTMD = True
            self._tMD = self._cursor._model._table.name

        if not self._tMD:
            return

        if not self._foreignField or not self._fieldRelation:
            if not self._cursor._model:
                if ownTMD and self._tMD and not self._tMD.inCache():
                    self._tMD = None
        
            return

            if not self._cursor._model.name() == self._tableName:
                ctxt = self._cursor.context();
                self._cursor = FLSqlCursor(self._tableName)
                if self._cursor:
                    self._cursor.setContext(ctxt)
                    cursorAux = 0
        
                if ownTMD and self._tMD and not self._tMD.inCache():
                    self._tMD = None
        
                return
        
        else:
            cursorTopWidget = self.topWidget._cursor() # ::qt_cast<FLFormDB *>(topWidget)->cursor()
            if cursorTopWidget and not cursorTopWidget._model.name() == self._tableName:
                self._cursor = cursorTopWidget
    
  

        if not self._tableName or not self._foreignField or not self._fieldRelation or cursorAux:
            if ownTMD and self._tMD and not self._tMD.inCache():
                tMD = None
    
            return
  
        cursorAux = self._cursor
        curName = self._cursor._model.name()
        rMD = self._cursor._model.relation(self._foreignField,self._fieldRelation,self._tableName)
        testM1 = self._tMD.relation(self._fieldRelation, self._foreignField, curName)
        checkIntegrity = bool(False)

        if not rMD:
            if testM1:
                checkIntegrity = (testM1.cardinality() == FLRelationMetaData.RELATION_M1)
            fMD = FLTableMetaData(self._cursor._model.field(self._foreignField)) 
            if (fMD):
                tmdAux = self._cursor._model(self._tableName);
                if not tmdAux or tmdAux.isQuery():
                    checkIntegrity = False
                if tmdAux and not tmdAux.inCache(): # mirar inCache()
                    tmdAux = None
                rMD = FLRelationMetaData(self._tableName,self._fieldRelation, FLRelationMetaData.RELATION_1M, False, False, checkIntegrity)
                fMD.addRelationMD(rMD)
                print("FLTableDB : La relación entre la tabla del formulario %r y esta tabla %r de este campo no existe, pero sin embargo se han indicado los campos de relación( %r, %r )" % (curName, self._tableName, self._fieldRelation, self._foreignField))
                print("FLTableDB : Creando automáticamente %r.%r --1M--> %r.%r" %  (curName, self._foreignField, self._tableName, self._fieldRelation))

    
            else:
                print("FLTableDB : El campo ( %r ) indicado en la propiedad foreignField no se encuentra en la tabla ( %r )" % (self._foreignField, curName))
        rMD = testM1
        if not rMD:
            fMD = FLFieldMetaData(tMD.field(self._fieldRelation))
            if (fMD):
                rMD = FLRelationMetaData(curName,self._foreignField, FLRelationMetaData.RELATION_1M, False, False, False)
                fMD.addRelationMD(rMD)
                print("FLTableDB : Creando automáticamente %r.%r --1M--> %r.%r" % (self._tableName, self._fieldRelation, curName, self._foreignField))
            else:
                print("FLTableDB : El campo ( %r ) indicado en la propiedad fieldRelation no se encuentra en la tabla ( %r )" % (self._fieldRelation, self._tableName))

        self._cursor = FLSqlCursor(self._tableName, True, self._cursor.db().connectionName(), cursorAux, rMD, self);
        if not self._cursor:
            self._cursor = cursorAux
            cursorAux = 0
        else:
            self._cursor.setContext(cursorAux.context())
        if self.showed:
            self.disconnect(cursorAux, QtCore.SIGNAL('newBuffer()'), self.refresh())
            self.connect(cursorAux,QtCore.SIGNAL('newBuffer()'), self.refresh())
  

        if cursorAux and self.topWidget.isA("FLFormSearchDB"):
            self.topWidget.setCaption(self._cursor._model.alias())
            self.topWidget.setCursor(self._cursor) #::qt_cast<FLFormSearchDB *>(topWidget)->setCursor(cursor_);
  

        if ownTMD and tMD and not tMD.inCache():
            tMD = None
Ejemplo n.º 40
0
class FLFormSearchDB(FLFormDB):



  
    """
    Subclase de la clase FLFormDB, pensada para buscar un registro
    en una tabla.

    El comportamiento de elegir un registro se modifica para solamente
    cerrar el formulario y así el objeto que lo invoca pueda obtener
    del cursor dicho registro.

    También añade botones Aceptar y Cancelar. Aceptar indica que se ha
    elegido el registro activo (igual que hacer doble clic sobre él o
    pulsar la tecla Intro) y Cancelar aborta la operación.

    @author InfoSiAL S.L.
    """

    """
    Boton Aceptar
    """
    pushButtonAccept = None
    
    """
    Almacena si se ha abierto el formulario con el método FLFormSearchDB::exec()
    """
    loop = None

    acceptingRejecting_ = None
    inExec_ = None
    accepted_ = None
    cursor_ = None
    
    eventloop = None
    """
    constructor.
    """


    
    def __init__(self, *args, **kwargs):
        parent = None
        name = None
        action = None
        
        if isinstance(args[0], str):
            #@param actionName Nombre de la acción asociada al formulario
            
            if len(args) == 2:
                parent = args[1]
            
            name = args[0]
             
            
            self.cursor_ = FLSqlCursor(name, True, "default", None, None, self)
            action = self.cursor_.action()
            self.accepted_ = False

        elif isinstance(args[0], FLSqlCursor):
            #@param cursor Objeto FLSqlCursor para asignar a este formulario
            #@param actionName Nombre de la acción asociada al formulario
            
            if len(args) > 2:
                action = args[1]
                name = action.name
                
            if len(args) == 3:
                parent = args[2]
            
            self.cursor_ = args[0]
        
        super(FLFormSearchDB,self).__init__(parent, action)
        self.setFocusPolicy(QtCore.Qt.NoFocus)
        
        if not name:
            print("FLFormSearchDB : Nombre de acción vacío")
            return
        
        if not action:
            print("FLFormSearchDB : No existe la acción", name)
            return


        
        self.initForm()
                    
        

  
    """
    destructor
    """

    def __delattr__(self, *args, **kwargs):
        if self.cursor_:
            self.cursor_.restoreEditionFlag(self)
            self.cursor_.restoreBrowseFlag(self)
            
        FLFormDB.__delattr__(self, *args, **kwargs)
        
        

    """
    formReady = QtCore.pyqtSignal()
    """
    
    def initForm(self):
        super(FLFormSearchDB, self).initForm()
        
    
    def loadControls(self):
        
        self.bottomToolbar = QtGui.QFrame()
        self.bottomToolbar.setMaximumHeight(64)
        self.bottomToolbar.setMinimumHeight(16)
        self.bottomToolbar.layout = QtGui.QHBoxLayout()
        self.bottomToolbar.setLayout(self.bottomToolbar.layout)
        self.bottomToolbar.layout.setMargin(0)
        self.bottomToolbar.layout.setSpacing(0)
        self.bottomToolbar.layout.addStretch()
        self.bottomToolbar.setFocusPolicy(QtCore.Qt.NoFocus)
        self.layout.addWidget(self.bottomToolbar)

        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Policy(0) ,QtGui.QSizePolicy.Policy(0))
        sizePolicy.setHeightForWidth(True)
        
        pbSize = QtCore.QSize(22,22)

  
                
                
            
        if not self.pushButtonAccept:
            self.pushButtonAccept = QtGui.QToolButton()
            self.pushButtonAccept.clicked.connect(self.accept)
                
        self.pushButtonAccept.setSizePolicy(sizePolicy)
        self.pushButtonAccept.setMaximumSize(pbSize)
        self.pushButtonAccept.setMinimumSize(pbSize)
        self.pushButtonAccept.setIcon(QtGui.QIcon(filedir("icons","gtk-save.png")))
        #pushButtonAccept->setAccel(QKeySequence(Qt::Key_F10)); FIXME
        self.pushButtonAccept.setFocus()
        self.pushButtonAccept.setWhatsThis("Seleccionar registro actual y cerrar formulario (F10)")
        self.pushButtonAccept.setToolTip("Seleccionar registro actual y cerrar formulario (F10)")
        self.pushButtonAccept.setFocusPolicy(QtCore.Qt.NoFocus)
        self.bottomToolbar.layout.addWidget(self.pushButtonAccept)
        self.pushButtonAccept.show()
                
            
        if not self.pushButtonCancel:
            self.pushButtonCancel = QtGui.QToolButton()
            self.pushButtonCancel.clicked.connect(self.reject)
                
        self.pushButtonCancel.setSizePolicy(sizePolicy)
        self.pushButtonCancel.setMaximumSize(pbSize)
        self.pushButtonCancel.setMinimumSize(pbSize)
        self.pushButtonCancel.setIcon(QtGui.QIcon(filedir("icons","gtk-stop.png")))
        self.pushButtonCancel.setFocusPolicy(QtCore.Qt.NoFocus)  
        #pushButtonCancel->setAccel(Esc); FIXME
        self.pushButtonCancel.setWhatsThis("Cerrar formulario sin seleccionar registro (Esc)")
        self.pushButtonCancel.setToolTip("Cerrar formulario sin seleccionar registro (Esc)")
        self.bottomToolbar.layout.addWidget(self.pushButtonCancel)
        self.pushButtonCancel.show()
        
        self.cursor_.setEdition(False)
        self.cursor_.setBrowse(False)
        self.cursor_.recordChoosed.connect(self.accept)                
            
                   
    
    def __getattr__(self, name): 
        return DefFun(self, name)

    
    
    """
    Muestra el formulario y entra en un nuevo bucle de eventos
    para esperar, a seleccionar registro.

    Se espera el nombre de un campo del cursor
    devolviendo el valor de dicho campo si se acepta el formulario
    y un QVariant::Invalid si se cancela.

    @param n Nombre del un campo del cursor del formulario
    @return El valor del campo si se acepta, o QVariant::Invalid si se cancela
    """
    @decorators.BetaImplementation
    def exec_(self, valor):
        if not self.cursor_:
            return None
        
        if not self.cursor_.isLocked():
            self.cursor_.setModeAccess(FLSqlCursor.Edit)
            
        if self.loop or self.inExec_:
            print("FLFormSearchDB::exec(): Se ha detectado una llamada recursiva")
            super(FLFormDB,self).show()
            if self.initFocusWidget_:
                self.initFocusWidget_.setFocus()
            
            return None
        
        self.load() #Extra
        self.inExec_ = True
        self.acceptingRejecting_ = False
        
        super(FLFormDB,self).show()
        if self.initFocusWidget_:
            self.initFocusWidget_.setFocus()
        
        if self.iface:
            try:
                timer1 = QtCore.QTimer(self)
                timer1.singleShot(300, self.iface.init)
            except Exception:
                pass
        
        if not self.isClosing_:
            timer2 = QtCore.QTimer(self)
            timer2.singleShot(0, self.emitFormReady)
        
        self.accepted_ = False
        self.loop = True
        self.eventloop = QtCore.QEventLoop()      
        self.eventloop.exec_()
        
        #if not self.isClosing_ and not self.acceptingRejecting_:
            #QtCore.QEventLoop().enterLoop() FIXME
        
        self.loop = False
        
        #self.clearWFlags(WShowModal) FIXME
        
        v = None
        if self.accepted_ and valor:
            v = self.cursor_.valueBuffer(valor)
        else:
            v = None
        
        self.inExec_ = False   
        return v
                    

    """
    Aplica un filtro al cursor
    """
    def setFilter(self, f):

        if not self.cursor_:
            return
        previousF = self.cursor_.mainFilter()
        newF = None
        if not previousF:
            newF = f
        elif previousF.contains(f):
            return
        else:
            newF = "%s AND %s" % (previousF, f)
        self.cursor_.setMainFilter(newF)

    """
    Devuelve el nombre de la clase del formulario en tiempo de ejecución
    """
    def formClassName(self):
        return "FormSearchDB"

    """
    Nombre interno del formulario
    """
    def geoName(self):
        return "formSearch%s" % self.idMDI_

    """
    Captura evento cerrar
    """
    def closeEvent(self, e):
        self.frameGeometry()
        if self.focusWidget():
            fdb = self.focusWidget().parentWidget()
            if fdb and fdb.autoComFrame_ and fdb.autoComFrame_.isvisible():
                fdb.autoComFrame_.hide()
                return
        
        if self.cursor_ and self.pushButtonCancel:
            if not self.pushButtonCancel.isEnabled():
                return
            
            self.isClosing_ = True
            self.setCursor(None)
        else:
            self.isClosing_ = True
        
        if self.isShown():
            self.reject()
        
        if self.isHidden():
            self.closed.emit()
            QtGui.QWidget.closeEvent(e)
            self.deleteLater()
            




    """
    Invoca a la función "init()" del script asociado al formulario
    """
    @QtCore.pyqtSlot()
    def initScript(self):
        return False

    """
    Redefinida por conveniencia
    """
    @QtCore.pyqtSlot()
    def hide(self):
        if self.isHidden():
            return
        
        super(FLFormSearchDB, self).hide()
        if self.loop:
            self.loop = False
            self.eventloop.exit()

    """
    Se activa al pulsar el boton aceptar
    """
    @QtCore.pyqtSlot()
    def accept(self):
        if self.acceptingRejecting_:
            return
        self.frameGeometry()
        if self.cursor_:
            try:
                self.cursor_.recordChoosed.disconnect(self.accept)
            except:
                pass
        self.acceptingRejecting_ = True
        self.accepted_ = True
        self.hide()
        
    """
    Se activa al pulsar el botón cancelar
    """
    @QtCore.pyqtSlot()
    def reject(self):
        if self.acceptingRejecting_:
            return
        self.frameGeometry()
        if self.cursor_:
            try:
                self.cursor_.recordChoosed.disconnect(self.accept)
            except:
                pass
        self.acceptingRejecting_ = True
        self.hide()

    
    """
    Redefinida por conveniencia
    """
    @QtCore.pyqtSlot()
    def show(self):
        self.exec_()





    def accepted(self):
        return self.accepted_
    
    def setMainWidget(self, w=None):
        
        if not self.cursor_:
            return
        
        if w:
            w.hide()
            self.mainWidget_ = w
Ejemplo n.º 41
0
    def sqlInsert(self, t, fL, vL, connName="default"):
        """
        Realiza la inserción de un registro en una tabla mediante un objeto FLSqlCursor

        @param t Nombre de la tabla
        @param fL Lista separada con comas de los nombres de los campos
        @param vL Lista separada con comas de los valores correspondientes
        @param connName Nombre de la conexion
        @return Verdadero en caso de realizar la inserción con éxito, falso en cualquier otro caso
        """
        from pineboolib.fllegacy.FLSqlCursor import FLSqlCursor

        fL = fL.split(",")
        vL = vL.split(",")

        if not len(fL) == len(vL):
            return False

        c = FLSqlCursor(t, True, connName)
        c.setModeAccess(FLSqlCursor.Insert)
        c.refreshBuffer()

        i = 0
        for f in fL:
            if vL[i] is None:
                c.bufferSetNull(f)
            else:
                c.setValueBuffer(f, vL[i])

            i = i + 1

        return c.commitBuffer()
Ejemplo n.º 42
0
class FLFormDB(QtGui.QWidget):
    
    
    """
    Representa un formulario que enlaza con una tabla.

    Se utiliza como contenedor de componentes que quieran
    enlazar con la base de datos y acceder a los registros
    del cursor. Esta estructura simplifica en gran
    medida el acceso a los datos ya que muchas tareas son
    automáticamente gestionadas por este formulario contenedor.

    En un principio el formulario se crea vacío y debemos invocar
    el metodo FLFormDB::setMainWidget(), pasándole como parámetro
    otro widget (generalmente un formulario creado con QtDesigner),
    el cual contiene distintos componentes, este widget se visualizará
    dentro de este contenedor, autofonfigurándose todos los componentes
    que contiene, con los datos y metadatos del cursor. Generalmente los
    componentes serán plugins, como FLFieldDB o FLTableDB.

    @author InfoSiAL S.L.
    """
    
    
    
    
    """
    Cursor, con los registros, utilizado por el formulario
    """
    cursor_ = None

    """
    Nombre de la tabla, contiene un valor no vacío cuando
    la clase es propietaria del cursor
    """
    name_ = None

    """
    Capa principal del formulario
    """
    layout = None

    """
    Widget principal del formulario
    """
    mainWidget_ = None

    """
    Acción asociada al formulario
    """
    action_ = None

    """
    Identificador de ventana MDI.

    Generalmente es el nombre de la acción que abre el formulario
    """
    idMDI_ = None

    """
    Capa para botones
    """
    layoutButtons = None

    """
    Boton Cancelar
    """
    pushButtonCancel = None

    """
    Indica que la ventana ya ha sido mostrada una vez
    """
    showed = None

    """
    Guarda el contexto anterior que tenia el cursor
    """
    oldCursorCtxt = None

    """
    Indica que el formulario se está cerrando
    """
    isClosing_ = None

    """
    Componente con el foco inicial
    """
    initFocusWidget_ = None

    """
    Guarda el último objeto de formulario unido a la interfaz de script (con bindIface())
    """
    oldFormObj = None

    #ifdef QSDEBUGGER
    """
    Boton Debug Script
    """
    pushButtonDebug = None
    #endif

    """
    Almacena que se aceptado, es decir NO se ha pulsado, botón cancelar
    """
    accepted_ = None

    """
    Interface para scripts
    """
    iface = None
    
    parent_= None
    

    @decorators.BetaImplementation
    def __init__(self, *args, **kwargs):
        if isinstance(args[0],FLSqlCursor):
            QtGui.QWidget.__init__(self, args[2])
            self.inicialize3(args, kwargs)
        elif isinstance(args[0], QtGui.QWidget):
            QtGui.QWidget.__init__(self, args[0])
            self.inicialize1(args,kwargs)
        else:
            QtGui.QWidget.__init__(self, args[1])
            self.inicialize2(args,kwargs)
        
            
        
    """
    constructor
    """
    @decorators.BetaImplementation
    def inicialize1(self, *args, **kwargs):            
        parent = args[0][0]
        name = args[0][1]
        f = args[1]
        
        if parent:
            self.parent_ = parent
        else:
            self.parent_ = QtGui.QWidget(pineboolib.project.mainWidget(), name, f)
        
        self.cursor_ = None
        self.layout = None
        self.mainWidget_ = None
        self.layoutButtons = None
        self.pushButtonCancel = None
        self.showed = False
        self.iface = None
        self.oldCursorCtxt = None
        self.isClosing_ = False
        self.initFocusWidget_ = None
        self.oldFormObj = None
        self.accepted_ = False
        self.loaded = False
        
    
    

    """
    constructor.

    @param actionName Nombre de la acción asociada al formulario
    """
    @decorators.BetaImplementation
    def inicialize2(self,*args, **kwargs):
        actionName = str(args[0][0])
        parent = args[0][1]
        f = args[1]

        if parent:
            self.parent_ = parent
        else:
            self.parent_ = QtGui.QWidget(pineboolib.project.mainWidget(), actionName, f)

        self.layout = None
        self.mainWidget_ = None
        self.layoutButtons = None
        self.pushButtonCancel = None
        self.showed = False
        self.iface = None
        self.oldCursorCtxt = None
        self.isClosing_ = False
        self.initFocusWidget_ = None
        self.oldFormObj = None
        self.accepted_ = False
    
        self.setFocusPolicy(QtGui.QWidget.NoFocus)
    
        if actionName.isEmpty():
            self.action_ = None
            print(FLUtil.translate("sys","FLFormDB : Nombre de acción vacío"))
            return
        else:
            self.action_ = FLSqlConnections.database().manager().action(actionName)
        
        if not self.action_:
            print(FLUtil.translate("sys","FLFormDB : No existe la acción %s" % actionName))
            return
        
        self.cursor_ = FLSqlCursor(self.action_.table(), True, "default", 0, 0, self)
        self.name_ = self.action_.name()
        
        self.initForm()
        
        

    """
    constructor sobrecargado.

    @param cursor Objeto FLSqlCursor para asignar a este formulario
    @param actionName Nombre de la acción asociada al formulario
    """
    @decorators.BetaImplementation
    def inicialize3(self, *args, **kwargs):
        
        cursor = args[0]
        actionName = args[1]
        parent = args[2]
        f = args[3]
        
        self.cursor_ = cursor
        self.layout = None
        self.mainWidget_ = None
        self.layoutButtons = None
        self.pushButtonCancel = None
        self.showed = False
        self.iface = None
        self.oldCursorCtxt = None
        self.isClosing_ = False
        self.initFocusWidget_ = None
        self.oldFormObj = None
        self.accepted_ = False
        


        if parent:
            self.parent_ = QtGui.QWidget(parent)
        else:
            self.parent_ = QtGui.QWidget(pineboolib.project.mainWidget(), actionName, f)
        
        self.setFocusPolicy(QtGui.QWidget.NoFocus)
        
        if actionName.isEmpty():
            self.action_ = None
        elif cursor:
            self.action_ = cursor.db().manager().action(actionName)
        else:
            self.action =  FLSqlConnections.database().manager().action(actionName)
        
        if self.action_:
            self.name_ = self.action_.name()
            
      

    """
    destructor
    """
    @decorators.BetaImplementation
    def __del__(self):
        self.unbindIface()

    """
    Establece el cursor que debe utilizar el formulario.

    @param c Cursor con el que trabajar
    """
    @decorators.BetaImplementation
    def setCursor(self, *c):
        if not c == self.cursor_ and self.cursor_ and self.oldCursorCtxt:
            self.cursor_.setContext(self.oldCursorCtxt)
        
        if not c:
            return
        
        if self.cursor_:
            self.cursor_.destroyed.disconnect(self.cursorDestroyed)
        
        self.cursor_ = c 
        self.cursor_.destroyed.connect(self.cursorDestroyed)
        
        if self.iface and self.cursor_:
            self.oldCursorCtxt = self.cursor_.context()
            self.cursor_.setContext(self.iface)    

    """
    Para obtener el cursor utilizado por el formulario.

    return Objeto FLSqlCursor con el cursor que contiene los registros para ser utilizados
      en el formulario
    """
    @decorators.BetaImplementation
    def cursor(self):
        return self.cursor_

    """
    Para obtener el widget principal del formulario.

    return Objeto QWidget que corresponde con el widget principal del formulario
    """
    @decorators.BetaImplementation
    def mainWidget(self):
        return self.mainWidget_

    """
    Establece el identificador MDI
    """
    @decorators.BetaImplementation
    def setIdMDI(self, _id):
        self.idMDI_ = _id

    """
    Obtiene el identificador MDI
    """
    @decorators.BetaImplementation
    def idMDI(self):
        return self.idMDI_
    
    
    
    @decorators.BetaImplementation
    def setMainWidget(self, *args, **kwarg):
        if isinstance(args[0], QtGui.QWidget):
            self.setMainWidgetQWidget(args[0])
        elif isinstance(args[0], str):
            self.setMainWidgetString(args[0])
        else:
            self.setMainWidgetEmpty()
            

    """
    Establece widget como principal del formulario.

    Este widget contendrá componentes que quieran enlazar con la
    base de datos, por lo que esperan estar contenidos en una clase
    FLFormDB, la cual les proporciona el cursor (registros) a los que enlazar.
    Si ya existiera otro widget como principal, este será borrado.

    Si existe un widget principal establecido con anterioridad será borrado

    @param w Widget principal para el formulario
    """
    @decorators.BetaImplementation
    def setMainWidgetQWidget(self, *w):
        
        if not self.cursor_ and not w:
            return
        
        if self.showed:
            if self.mainWidget_ and not self.mainWidget_ == w:
                self.initMainWidget(w)
            else:
                w.hide()
            
            if self.layout:
                del self.Layout
            
            #w.setFont(qApp.font()) #FIXME
            self.layout = QtGui.QVBoxLayout(self, 2,3,"vlay" + self.name_)
            self.layout.add(w)
            self.layoutButtons = QtGui.QHBoxLayout(self.layout , 3, "hlay" + self.name_)
            
            self.layoutButtons.addItem(QtGui.QSpacerItem())
            self.pushButtonCancel = QtGui.QPushButton(self, "pushButtonCancel")
            #self.pushButtonCancel.set_size(QtGui.QSizePolicy) #FIXME
            self.pushButtonCancel.setMinimumSize(22, 22)
            self.pushButtonCancel.setMaximumSize(22, 22)
            self.pushButtonCancel.setIcon(QtGui.QIcon(filedir("icons","gtk-cancel.png")))
            #pushButtonCancel->setFocusPolicy(QWidget::NoFocus);
            #pushButtonCancel->setAccel(QKeySequence(tr("Esc")));
            #QToolTip::add(pushButtonCancel, tr("Cerrar formulario (Esc)"));
            #QWhatsThis::add(pushButtonCancel, tr("Cerrar formulario (Esc)"));
            self.layoutButtons.addWidget(self.pushButtonCancel)
            self.pushButtonCancel.clicked.connect(self.close)
            self.pushButtonCancel.show()
            self.mainWidget_ = w

    """
    Sobrecargado de setMainWidget.

    Aqui toma el nombre de un formulario de la acción asociada y construye el Widget principal, a partir de él.
    """
    @decorators.BetaImplementation
    def setMainWidgetEmpty(self):
        if not self.action_:
            return
    
        if self.cursor_:
            self.setMainWidgetQWidget(self.cursor_.db().managerModules.createUI(self.action_, self, self))
        else:
            self.setMainWidget(FLSqlConnections.database().managerModules().createUI(self.action_, self, self))

    """
    Sobrecargado de setMainWidget.

    Aqui construye el Widget principal a partir del nombre de un fichero de interfaz .ui.

    @param uiFileName Nombre del fichero de descripción de interfaz, incluyendo la extension .ui, p.e. clientes.ui
    """
    @decorators.BetaImplementation
    def setMainWidgetString(self, uiFileName):
        if self.cursor_:
            self.setMainWidgetQWidget(self.cursor_.db().managerModules.createUI(uiFileName, self, self))
        else:
            self.setMainWidget(FLSqlConnections.database().managerModules().createUI(uiFileName, self, self))
    """
    Obtiene la imagen o captura de pantalla del formulario.
    """
    @decorators.BetaImplementation
    def snapShot(self):
        pix = QtGui.QPixmap.grabWidget(self)
        return QtGui.QImage(pix)
    

    """
    Salva en un fichero con formato PNG la imagen o captura de pantalla del formulario.

    @param pathFile Ruta y nombre del fichero donde guardar la imagen
    """
    @decorators.BetaImplementation
    def saveSnapShot(self, pathFile):
        fi = QtCore.QFile(pathFile)
        if not fi.open(QtCore.QFile.WriteOnly):
            print("FLFormDB : " + FLUtil.translate("sys", "Error I/O al intentar escribir el fichero %s" % pathFile))
            return
        self.snapShot().save(fi, "PNG")
            

    """
    Establece el título de la ventana.

    @param text Texto a establecer como título de la ventana
    @author Silix
    """
    @decorators.BetaImplementation
    def setCaptionWidget(self, text):
        if text.isEmpty():
            return
        
        self.setCaption(text)


    """
    Devuelve si se ha aceptado el formulario
    """
    @decorators.BetaImplementation
    def accepted(self):
        return self.accepted_

    """
    Devuelve el nombre de la clase del formulario en tiempo de ejecución
    """
    @decorators.BetaImplementation
    def formClassName(self):
        return "FormDB"

    """
    Sólo para compatibilizar con FLFormSearchDB. Por defecto sólo llama QWidget::show
    """
    @decorators.BetaImplementation
    def exec_(self):
        QtGui.QWidget.show()
        return QtCore.QVariant()
        
        
    #public slots:

    """
    Cierra el formulario
    """
    @decorators.BetaImplementation
    def close(self):
        if self.isClosing_:
            return True
        self.isClosing_ = True
        self.isClosing_ = QtGui.QWidget.close()

    """
    Invoca a la función "init" del script "masterprocess" asociado al formulario
    """
    @decorators.NotImplementedWarn
    def initScript(self):
        if self.iface:
            #pineboolib.project.call("init", QtCore.QSArgumentList(), self.iface) #FIXME
            return True
        else:
            return False
        

    """
    Se activa al pulsar el boton aceptar
    """
    @decorators.BetaImplementation
    def accept(self):
        return

    """
    Se activa al pulsar el botón cancelar
    """
    @decorators.BetaImplementation
    def reject(self):
        return

    """
    Redefinida por conveniencia
    """
    @decorators.BetaImplementation
    def show(self):
        QtGui.QWidget.show()

    """
    Muestra el formulario sin llamar al script "init".
    Utilizado en documentación para evitar conflictos al capturar los formularios
    """
    @decorators.BetaImplementation
    def showForDocument(self):
        self.showed = True
        self.mainWidget_.show()
        self.resize(self.size().expandedTo(self.mainWidget_.size()))
        QtGui.QWidget.show()

    """
    Maximiza el formulario
    """
    @decorators.BetaImplementation
    def setMaximized(self):
        self.setWindowState(self.windowState() | QtCore.Qt.WindowMaximized)

    """
    Muestra el script asociado al formulario en el Workbench para depurar
    """
    @decorators.BetaImplementation
    def debugScript(self):
        return

    """
    Devuelve el script asociado al formulario
    """
    @decorators.BetaImplementation
    def script(self):
        return

    #private slots:
    @decorators.BetaImplementation
    def callInitScript(self):
        if not self.initScript():
            return
        if not self.isClosing_:
            self.emitFormReady.emit()

    #protected:

    """
    Inicialización
    """
    @decorators.BetaImplementation
    def initForm(self):
        if self.cursor_ and self.cursor_.metadata():
            caption = None
            if self.action_:
                self.cursor_.setAction(self.action_)
                caption = self.action_.caption()
                if not self.action_.description().isEmpty():
                    self.QtGui.QWhatsThis.add(self, self.action_.description())
                self.idMDI_ = self.action_.name()
            
            if caption.isEmpty():
                caption = self.cursor_.metadata().alias()
            self.setCaption(caption)
            
            self.bindIface()
            self.setCursor(self.cursor_)
        
        else:
            self.setCaption(FLUtil.translate("sys" ,"No hay metadatos"))
            
                    

    """
    Nombre interno del formulario
    """
    @decorators.BetaImplementation
    def formName(self):
        return ("form%s" % self.idMDI_)
    
    @decorators.BetaImplementation
    def geoName(self):
        return self.formName()

    """
    Une la interfaz de script al objeto del formulario
    """
    @decorators.BetaImplementation
    def bindIface(self):
        p = pineboolib.project
        
        if not p:
            return
        
        self.setName(self.formName())
        o = p.object(self.name())
        
        if not o == self.iface and self.iface and self.oldFormObj:
            self.iface.setObj(self.oldFormObj)
        self.iface = o
        
        ifc = self.iface
        if not ifc:
            return
        
        if not ifc.obj() == self:
            if self.oldFormObj:
                self.oldFormObj.destroyed.disconnect(self.oldFormObjDestroyed())
            
            self.oldFormObj = ifc.obj()
            if self.oldFormObj:
                self.oldFormObj.destroyed.connect(self.oldFormObjDestroyed())
            ifc.setObj(self) 
        

    """
    Desune la interfaz de script al objeto del formulario
    """
    @decorators.BetaImplementation
    def unbindIface(self):
        ifc = self.iface
        if not ifc:
            return
        
        if ifc.obj() == self:
            ifc.setObj(self.oldFormObj) 

    """
    Indica si la interfaz de script está unida al objeto formulario
    """
    @decorators.BetaImplementation
    def isIfaceBind(self):
        ifc = self.iface
        if not ifc:
            return
        return (ifc.obj() == self)

    """
    Captura evento cerrar
    """
    @decorators.BetaImplementation
    def closeEvent(self, *e):
        self.frameGeometry()
        if self.focusWidget():
            fdb = self.focusWidget().parentWidget()
            if fdb and fdb.autoComFrame_ and fdb.autoComFrame_.isVisible():
                fdb.autoComFrame_.hide()
                return 
            

    """
    Captura evento mostrar
    """
    @decorators.NotImplementedWarn
    def showEvent(self, *e):
        if not self.showed and self.mainWidget_:
            self.showed = True
        
            if self.cursor_ and self.iface:
                #v = pineboolib.project.call("preloadMainFilter", QSArgumentList(), self.iface).variant())
                if v and isinstance(v.type(), str):
                    self.cursor_.setMainFilter(str(v), False)
        
            self.initMainWidget()
            self.callInitScript()
        if not self.isIfaceBind():
            self.bindIface()
    """
    Captura evento ocultar
    """
    @decorators.NotImplementedWarn
    def hideEvent(self, *h):
        return     
    """
    {
  QWidget *pW = parentWidget();
  if (pW && pW->isA("QWorkspaceChild")) {
    QRect geo(pW->x(), pW->y(), pW->width(), pW->height());
    if (isMinimized()) {
      geo.setWidth(1);
      aqApp->saveGeometryForm(geoName(), geo);
    } else if (isMaximized()) {
      geo.setWidth(9999);
      aqApp->saveGeometryForm(geoName(), geo);
    } else
      aqApp->saveGeometryForm(geoName(), geo);
  } else {
    QRect geo(x(), y(), width(), height());
    aqApp->saveGeometryForm(geoName(), geo);
  }
}
    """

    """
    Captura evento de entrar foco
    """
    @decorators.BetaImplementation
    def focusInEvent(self, *f):
        self.focusInEvent(f)
        if self.isIfaceBind():
            self.bindIface()

    """
    Inicializa componenentes del widget principal

    @param w Widget a inicializar. Si no se establece utiliza
            por defecto el widget principal actual
    """
    @decorators.NotImplementedWarn
    def initMainWidget(self, *w):
        return
    """
    
{
  QWidget *mWidget = w ? w : mainWidget_;
  if (mWidget) {
    QObjectList *l = static_cast<QObject *>(mWidget)->queryList("FLTableDB");
    QObjectListIt itt(*l);
    FLTableDB *tdb;
    while ((tdb = static_cast<FLTableDB *>(itt.current())) != 0) {
      ++itt;
      tdb->initCursor();
    }
    delete l;

    l = static_cast<QObject *>(mWidget)->queryList("FLFieldDB");
    QObjectListIt itf(*l);
    FLFieldDB *fdb;
    while ((fdb = static_cast<FLFieldDB *>(itf.current())) != 0) {
      ++itf;
      fdb->initCursor();
      fdb->initEditor();
      if (fdb->aqFirstTabStop == 1)
        initFocusWidget_ = fdb;
    }

    while (mWidget->parentWidget() && mWidget->parentWidget() != this)
      mWidget = mWidget->parentWidget();
    mWidget->show();

    FLAccessControlLists *acl = aqApp->acl();
    if (acl)
      acl->process(this);

    QWidget *pW = parentWidget();
    QRect desk;
    bool parentIsDesktop = true;
    
    if (!(pW && pW->isA("QWorkspaceChild"))) {
        desk = QApplication::desktop()->availableGeometry(this);
        pW = this;
    } else {
        desk = pW->parentWidget()->rect();
        parentIsDesktop = false;
    }

    QRect geo(aqApp->geometryForm(QObject::name()));
    pW->show();
    QSize oSz = mWidget->size();
    mWidget->updateGeometry();
    QSize bSz = mWidget->baseSize();
    QSize SzH = mWidget->sizeHint();
    int border = 5, border_b = 48;
    /*
    qDebug("geo: " + QString::number(geo.width()) + "x"  + QString::number(geo.height()));
    qDebug("oSz: " + QString::number(oSz.width()) + "x"  + QString::number(oSz.height()));
    qDebug("bSz: " + QString::number(bSz.width()) + "x"  + QString::number(bSz.height()));
    qDebug("SzH: " + QString::number(SzH.width()) + "x"  + QString::number(SzH.height()));
    */

    if (geo.width() < 100 || geo.width()>9000) {
        // qDebug(" -- reset Form Size and position -- ");
        geo.setWidth(oSz.width());
        geo.setHeight(oSz.height());
        geo.moveCenter(desk.center());
        
        if (!parentIsDesktop) {
            geo.moveTop(desk.top() + border - geo.top()+1);
        }
    }

    if (geo.width() < SzH.width()) {
        // qDebug(" -- geo width too small -- ");
        geo.setWidth(SzH.width());
    }
    if (geo.height() < SzH.height()) {
        // qDebug(" -- geo height too small -- ");
        geo.setHeight(SzH.height());
    }
    // Exceeds available horizontal area:
    if (geo.width() > desk.width() - border * 2) {
        // qDebug(" -- geo width too big -- ");
        geo.setWidth(desk.width() - border * 2 - 5);
    }
    // Exceeds available vertical area:
    if (geo.height() > desk.height() - border - border_b) {
        // qDebug(" -- geo height too big -- ");
        geo.setHeight(desk.height() - border - border_b - 5);
    }
    if (parentIsDesktop) {
        // Invalid position values, re-center
        if (  geo.right() > 9000
         || geo.left() < 1
         || geo.bottom() > 9000
         || geo.top() < 1 ) {
            // qDebug(" -- geo invalid position -- ");
            geo.moveCenter(desk.center());
        }
    

        if ( geo.top() < desk.top() + border)  {
            // qDebug(" -- geo position too high -- ");
            geo.moveTop(desk.top() + border - geo.top()+1);
        }

        if ( geo.left() < desk.left() + border) {
            // qDebug(" -- geo position too left -- ");
            geo.moveLeft(desk.left() + border - geo.left()+1);
        }

        if ( geo.bottom() > desk.bottom() - border_b ) {
            int diff = geo.bottom() - desk.bottom() - border_b;
            // qDebug(" -- geo position too low -- ");
            geo.moveTop(-diff-1);
        }

        if ( geo.right() > desk.right() - border) {
            int diff = geo.right() - desk.right() - border;
            // qDebug(" -- geo position too right -- ");
            geo.moveLeft(-diff-1);
        }

        // Outside of screen, re-center:
        if (  geo.right() > desk.right() - border  
         || geo.left() < desk.left() + border
         || geo.bottom() > desk.bottom() - border_b
         || geo.top() < desk.top() + border ) {
            // qDebug(" -- geo position out of screen -- ");
            geo.moveCenter(desk.center());
        }
    }
    mWidget->resize(geo.size());

    pW->updateGeometry();
    QSize tSz= pW->size();
    QSize tSzH = pW->sizeHint();
    if (tSz.width() < tSzH.width()) {
        tSz.setWidth(tSzH.width());
    }
    if (tSz.height() < tSzH.height()) {
        tSz.setHeight(tSzH.height());
    }
    pW->resize(tSz.expandedTo(mWidget->size()));
    
    pW->move(geo.topLeft());

    if (!initFocusWidget_) {
      itf.toFirst();
      while ((fdb = static_cast<FLFieldDB *>(itf.current())) != 0) {
        ++itf;
        if (fdb->isEnabled()) {
          initFocusWidget_ = fdb;
          break;
        }
      }
      if (!initFocusWidget_)
        initFocusWidget_ = static_cast<QWidget *>(mWidget->focusWidget());
      if (initFocusWidget_)
        initFocusWidget_->setFocus();
    }

    delete l;

    QWidget *focWid = qApp->focusWidget();
    if (focWid) {
      QWidget *topWidget = focWid->topLevelWidget();
      if (topWidget && !topWidget->inherits("FLFormDB")) {
        QWidget *topWid = focWid->parentWidget();
        while (topWid && !topWid->inherits("FLFormDB"))
          topWid = topWid->parentWidget();
        topWidget = topWid;
      }
      if (topWidget != this)
        setFocus();
    } else setFocus();
    
  }
}

"""
        
    #protected slots:

    """
    Emite señal formulari listo. Ver FLFormDB::formReady()
    """
    
    emitFormReady = QtCore.pyqtSignal()

    """
    Uso interno
    """
    @QtCore.pyqtSlot()
    def oldFormObjDestroyed(self):
        print("oldFormObjDestroyed")
        self.oldFormObj = None
        return None
        
    @QtCore.pyqtSlot(QtCore.QObject)
    def cursorDestroyed(self, *obj):
        print("cursorDestroyed")
        if not obj or not obj == self.cursor_:
            return
        
        self.cursor_ = None
        return None

    #signals:

    """
    Señal emitida cuando se cierra el formulario
    """
    closed = QtCore.pyqtSignal() 

    """
    Señal emitida cuando el formulario ya ha sido inicializado y está listo para usarse
    """
    formReady = QtCore.pyqtSignal()
Ejemplo n.º 43
0
class FLFormSearchDB(FLFormDB):
    """
    Subclase de la clase FLFormDB, pensada para buscar un registro
    en una tabla.

    El comportamiento de elegir un registro se modifica para solamente
    cerrar el formulario y así el objeto que lo invoca pueda obtener
    del cursor dicho registro.

    También añade botones Aceptar y Cancelar. Aceptar indica que se ha
    elegido el registro activo (igual que hacer doble clic sobre él o
    pulsar la tecla Intro) y Cancelar aborta la operación.

    @author InfoSiAL S.L.
    """
    """
    Boton Aceptar
    """
    pushButtonAccept = None
    """
    Almacena si se ha abierto el formulario con el método FLFormSearchDB::exec()
    """
    loop = None

    acceptingRejecting_ = None
    inExec_ = None
    accepted_ = None
    cursor_ = None

    eventloop = None
    """
    constructor.
    """
    def __init__(self, *args, **kwargs):
        parent = None
        name = None
        action = None

        if isinstance(args[0], str):
            #@param actionName Nombre de la acción asociada al formulario

            if len(args) == 2:
                parent = args[1]

            name = args[0]

            self.cursor_ = FLSqlCursor(name, True, "default", None, None, self)
            action = self.cursor_.action()
            self.accepted_ = False

        elif isinstance(args[0], FLSqlCursor):
            #@param cursor Objeto FLSqlCursor para asignar a este formulario
            #@param actionName Nombre de la acción asociada al formulario

            if len(args) > 2:
                action = args[1]
                name = action.name

            if len(args) == 3:
                parent = args[2]

            self.cursor_ = args[0]

        super(FLFormSearchDB, self).__init__(parent, action)
        self.setFocusPolicy(QtCore.Qt.NoFocus)

        if not name:
            print("FLFormSearchDB : Nombre de acción vacío")
            return

        if not action:
            print("FLFormSearchDB : No existe la acción", name)
            return

        self.initForm()

    """
    destructor
    """

    def __delattr__(self, *args, **kwargs):
        if self.cursor_:
            self.cursor_.restoreEditionFlag(self)
            self.cursor_.restoreBrowseFlag(self)

        FLFormDB.__delattr__(self, *args, **kwargs)

    """
    formReady = QtCore.pyqtSignal()
    """

    def initForm(self):
        super(FLFormSearchDB, self).initForm()

    def loadControls(self):

        self.bottomToolbar = QtGui.QFrame()
        self.bottomToolbar.setMaximumHeight(64)
        self.bottomToolbar.setMinimumHeight(16)
        self.bottomToolbar.layout = QtGui.QHBoxLayout()
        self.bottomToolbar.setLayout(self.bottomToolbar.layout)
        self.bottomToolbar.layout.setMargin(0)
        self.bottomToolbar.layout.setSpacing(0)
        self.bottomToolbar.layout.addStretch()
        self.bottomToolbar.setFocusPolicy(QtCore.Qt.NoFocus)
        self.layout.addWidget(self.bottomToolbar)

        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Policy(0),
                                       QtGui.QSizePolicy.Policy(0))
        sizePolicy.setHeightForWidth(True)

        pbSize = QtCore.QSize(22, 22)

        if not self.pushButtonAccept:
            self.pushButtonAccept = QtGui.QToolButton()
            self.pushButtonAccept.clicked.connect(self.accept)

        self.pushButtonAccept.setSizePolicy(sizePolicy)
        self.pushButtonAccept.setMaximumSize(pbSize)
        self.pushButtonAccept.setMinimumSize(pbSize)
        self.pushButtonAccept.setIcon(
            QtGui.QIcon(filedir("icons", "gtk-save.png")))
        #pushButtonAccept->setAccel(QKeySequence(Qt::Key_F10)); FIXME
        self.pushButtonAccept.setFocus()
        self.pushButtonAccept.setWhatsThis(
            "Seleccionar registro actual y cerrar formulario (F10)")
        self.pushButtonAccept.setToolTip(
            "Seleccionar registro actual y cerrar formulario (F10)")
        self.pushButtonAccept.setFocusPolicy(QtCore.Qt.NoFocus)
        self.bottomToolbar.layout.addWidget(self.pushButtonAccept)
        self.pushButtonAccept.show()

        if not self.pushButtonCancel:
            self.pushButtonCancel = QtGui.QToolButton()
            self.pushButtonCancel.clicked.connect(self.reject)

        self.pushButtonCancel.setSizePolicy(sizePolicy)
        self.pushButtonCancel.setMaximumSize(pbSize)
        self.pushButtonCancel.setMinimumSize(pbSize)
        self.pushButtonCancel.setIcon(
            QtGui.QIcon(filedir("icons", "gtk-stop.png")))
        self.pushButtonCancel.setFocusPolicy(QtCore.Qt.NoFocus)
        #pushButtonCancel->setAccel(Esc); FIXME
        self.pushButtonCancel.setWhatsThis(
            "Cerrar formulario sin seleccionar registro (Esc)")
        self.pushButtonCancel.setToolTip(
            "Cerrar formulario sin seleccionar registro (Esc)")
        self.bottomToolbar.layout.addWidget(self.pushButtonCancel)
        self.pushButtonCancel.show()

        self.cursor_.setEdition(False)
        self.cursor_.setBrowse(False)
        self.cursor_.recordChoosed.connect(self.accept)

    def __getattr__(self, name):
        return DefFun(self, name)

    """
    Muestra el formulario y entra en un nuevo bucle de eventos
    para esperar, a seleccionar registro.

    Se espera el nombre de un campo del cursor
    devolviendo el valor de dicho campo si se acepta el formulario
    y un QVariant::Invalid si se cancela.

    @param n Nombre del un campo del cursor del formulario
    @return El valor del campo si se acepta, o QVariant::Invalid si se cancela
    """

    @decorators.BetaImplementation
    def exec_(self, valor):
        if not self.cursor_:
            return None

        if not self.cursor_.isLocked():
            self.cursor_.setModeAccess(FLSqlCursor.Edit)

        if self.loop or self.inExec_:
            print(
                "FLFormSearchDB::exec(): Se ha detectado una llamada recursiva"
            )
            super(FLFormDB, self).show()
            if self.initFocusWidget_:
                self.initFocusWidget_.setFocus()

            return None

        self.load()  #Extra
        self.inExec_ = True
        self.acceptingRejecting_ = False

        super(FLFormDB, self).show()
        if self.initFocusWidget_:
            self.initFocusWidget_.setFocus()

        if self.iface:
            try:
                timer1 = QtCore.QTimer(self)
                timer1.singleShot(300, self.iface.init)
            except Exception:
                pass

        if not self.isClosing_:
            timer2 = QtCore.QTimer(self)
            timer2.singleShot(0, self.emitFormReady)

        self.accepted_ = False
        self.loop = True
        self.eventloop = QtCore.QEventLoop()
        self.eventloop.exec_()

        #if not self.isClosing_ and not self.acceptingRejecting_:
        #QtCore.QEventLoop().enterLoop() FIXME

        self.loop = False

        #self.clearWFlags(WShowModal) FIXME

        v = None
        if self.accepted_ and valor:
            v = self.cursor_.valueBuffer(valor)
        else:
            v = None

        self.inExec_ = False
        return v

    """
    Aplica un filtro al cursor
    """

    def setFilter(self, f):

        if not self.cursor_:
            return
        previousF = self.cursor_.mainFilter()
        newF = None
        if not previousF:
            newF = f
        elif previousF.contains(f):
            return
        else:
            newF = "%s AND %s" % (previousF, f)
        self.cursor_.setMainFilter(newF)

    """
    Devuelve el nombre de la clase del formulario en tiempo de ejecución
    """

    def formClassName(self):
        return "FormSearchDB"

    """
    Nombre interno del formulario
    """

    def geoName(self):
        return "formSearch%s" % self.idMDI_

    """
    Captura evento cerrar
    """

    def closeEvent(self, e):
        self.frameGeometry()
        if self.focusWidget():
            fdb = self.focusWidget().parentWidget()
            if fdb and fdb.autoComFrame_ and fdb.autoComFrame_.isvisible():
                fdb.autoComFrame_.hide()
                return

        if self.cursor_ and self.pushButtonCancel:
            if not self.pushButtonCancel.isEnabled():
                return

            self.isClosing_ = True
            self.setCursor(None)
        else:
            self.isClosing_ = True

        if self.isShown():
            self.reject()

        if self.isHidden():
            self.closed.emit()
            super(FLFormSearchDB, self).closeEvent(e)
            self.deleteLater()

    """
    Invoca a la función "init()" del script asociado al formulario
    """

    @QtCore.pyqtSlot()
    def initScript(self):
        return False

    """
    Redefinida por conveniencia
    """

    @QtCore.pyqtSlot()
    def hide(self):
        if self.isHidden():
            return

        super(FLFormSearchDB, self).hide()
        if self.loop:
            self.loop = False
            self.eventloop.exit()

    """
    Se activa al pulsar el boton aceptar
    """

    @QtCore.pyqtSlot()
    def accept(self):
        if self.acceptingRejecting_:
            return
        self.frameGeometry()
        if self.cursor_:
            try:
                self.cursor_.recordChoosed.disconnect(self.accept)
            except:
                pass
        self.acceptingRejecting_ = True
        self.accepted_ = True
        self.hide()

    """
    Se activa al pulsar el botón cancelar
    """

    @QtCore.pyqtSlot()
    def reject(self):
        if self.acceptingRejecting_:
            return
        self.frameGeometry()
        if self.cursor_:
            try:
                self.cursor_.recordChoosed.disconnect(self.accept)
            except:
                pass
        self.acceptingRejecting_ = True
        self.hide()

    """
    Redefinida por conveniencia
    """

    @QtCore.pyqtSlot()
    def show(self):
        self.exec_()

    def accepted(self):
        return self.accepted_

    def setMainWidget(self, w=None):

        if not self.cursor_:
            return

        if w:
            w.hide()
            self.mainWidget_ = w
Ejemplo n.º 44
0
    def sqlDelete(self, t, w, connName="default"):
        from pineboolib.fllegacy.FLSqlCursor import FLSqlCursor
        c = FLSqlCursor(t, True, connName)
        c.setForwardOnly(True)

        # if not c.select(w):
        #     return False
        c.select(w)

        while c.next():
            c.setModeAccess(FLSqlCursor.DEL)
            c.refreshBuffer()
            if not c.commitBuffer():
                return False

        return True
Ejemplo n.º 45
0
class FLFormSearchDB(FLFormDB):
    """
    Subclase de la clase FLFormDB, pensada para buscar un registro
    en una tabla.

    El comportamiento de elegir un registro se modifica para solamente
    cerrar el formulario y así el objeto que lo invoca pueda obtener
    del cursor dicho registro.

    También añade botones Aceptar y Cancelar. Aceptar indica que se ha
    elegido el registro activo (igual que hacer doble clic sobre él o
    pulsar la tecla Intro) y Cancelar aborta la operación.

    @author InfoSiAL S.L.
    """
    """
    Uso interno
    """
    acceptingRejecting_ = False
    inExec_ = False
    """
    Boton Aceptar
    """
    pushButtonAccept = None
    """
    Almacena si se ha abierto el formulario con el método FLFormSearchDB::exec()
    """
    loop = None

    def __init__(self, *args, **kwargs):
        if isinstance(args[0], QString):
            super(FLFormSearchDB, self).__init(
                args[0], args[1],
                (Qt.WStyle_Customize, Qt.WStyle_Maximize, Qt.WStyle_Title,
                 Qt.WStyle_NormalBorder, Qt.WType_Dialog, Qt.WShowModal,
                 Qt.WStyle_SysMenu))
            self.init1(args[0], args[1])
        else:
            super(FLFormSearchDB, self).__init(
                args[1], args[2],
                (Qt.WStyle_Customize, Qt.WStyle_Maximize, Qt.WStyle_Title,
                 Qt.WStyle_NormalBorder, Qt.WType_Dialog, Qt.WShowModal,
                 Qt.WStyle_SysMenu))
            self.init2(args[0], args[1], args[2])

    """
    constructor.

    @param actionName Nombre de la acción asociada al formulario
    """

    def init1(self, actionName, parent=None):
        self.setFocusPolicy(QtGui.QWidget.NoFocus)
        if actionName.isEmpty():
            self.action_ = False
            print(
                FLUtil.translate("app",
                                 "FLFormSearchDB : Nombre de acción vacío"))
            return
        else:
            self.action_ = FLSqlConnections.database().manager().action(
                actionName)
        if not self.action_:
            print(
                FLUtil.translate(
                    "app",
                    "FLFormSearchDB : No existe la acción %s" % actionName))
            return

        self.cursor_ = FLSqlCursor(self.action_.table(), True, "default", 0, 0,
                                   self)
        self.name_ = self.action_.name()

        self.initForm()

    """ constructor sobrecargado.

    @param cursor Objeto FLSqlCursor para asignar a este formulario
    @param actionName Nombre de la acción asociada al formulario
    """

    def init2(self, cursor, actionName=QString.null, parent=None):
        self.setFocusPolicy(QtGui.QWidget.NoFocus)
        if actionName.isEmpty():
            self.action_ = False
        elif cursor:
            self.action_ = FLSqlConnections.database().manager().action(
                actionName)
        self.cursor_ = cursor
        if self.action_:
            self.name_ = self.action_.name()
        else:
            self.name_ = QString.null

    """
    destructor
    """

    def __del__(self):
        if self.cursor_ and not self.cursor_.aqWasDeleted():
            self.cursor_.restoreEditionFlag(self)
            self.cursor_.restoreBrowseFlag(self)

    """
    Establece el cursor que debe utilizar el formulario.

    @param c Cursor con el que trabajar
    """

    def setCursor(self, c):
        if not c == self.cursor_ and self.cursor_ and self.oldCursorCtxt:
            self.cursor_.setContext(self.oldCursorCtxt)

        if not c:
            return

        if self.cursor_:
            self.cursor_.recordChoosed.disconnect(self.accept())
            self.cursor_.destroyed.disconnect(self.cursorDestroyed())

        if self.cursor_ and not c == self.cursor_:
            self.cursor_.restoreEditionFlag(self)
            self.cursor_.restoreBrowseFlag(self)

        self.cursor_ = c
        self.cursor_.setEdition(False, self)
        self.cursor_.setBrowse(False, self)
        self.cursor_.recordChoosed.connect(self.accept())
        self.cursor_.destroyed.connect(self.cursorDestroyed())
        if self.iface and self.cursor_:
            self.oldCursorCtxt = self.cursor_.context()
            self.cursor_.setContext(self.iface)

    """
    Sobrecargado de setMainWidget.

    Aqui toma el nombre de un formulario de la acción asociada y construye el Widget principal, a partir de él.
    """
    """
    Reimplementado, añade un widget como principal del formulario
    """

    def setMainWidget(self, *args, **kwargs):
        if len(args) == 0:
            super(FLFormSearchDB, self).setMainWidget()
        else:
            self.setMainWidgetFLFormSearhDB(args[0])

    def setMainWidgetFLFormSearchDB(self, w):
        if not self.cursor_ or not w:
            return
        if self.showed:
            if self.mainWidget_ and not self.mainWidget_ == w:
                self.initMainWidget(w)
        else:
            w.hide()

        if self.layoutButtons:
            del self.layoutButtons

        if self.layout:
            del self.layout

        w.setFont(QtGui.qApp.font())
        desk = QtGui.QApplication.desktop.availableGeometry(self)
        geo = w.geometry()
        tooLarge = False

        if geo.width() > desk.width() or geo.height() > desk.heigh():
            sv = QtGui.QScrollArea(self)
            #sv->setResizePolicy(QScrollView::AutoOneFit) FIXME
            sv.hide()
            sv.addChild(w)
            self.layout = QtGui.QVBoxLayout(self, 5, 5, "vlay" + self.name_)
            self.Layout.add(sv)
            sv.resize(self.size().expand(desk.size()))
            self.layoutButtons = QtGui.QHBoxLayout(self.layout, 3,
                                                   "hlay" + self.name_)
            self.formReady.connect(sv.show())
            tooLarge = True
        else:
            self.layout = QtGui.QVBoxLayout(self, 2, 3, "vlay" + self.name_)
            self.layout.add(w)
            self.layoutButtons = QtGui.QHBoxLayout(self.layout, 3,
                                                   "hlay" + self.name_)

        pbSize = Qt.qsize(22, 22)
        """
        QToolButton *wt = QWhatsThis::whatsThisButton(this);
        wt->setIconSet(QPixmap::fromMimeSource("about.png"));
        layoutButtons->addWidget(wt);
        wt->show()
        """
        self.layoutButtons.addItem(
            QtGui.QSpacerItem(20, 20, Qt.QSizePolicy.Expanding,
                              Qt.QSizePolicy.Minimum))
        self.pushButtonAccept = QtGui.QPushButton(self, "pushButtonAccept")
        self.pushButtonAccept.sizePolicy(
            Qt.QSizePolicy(
                0, 0, 0, 0,
                self.pushButtonAccept.sizePolicy().hasHeightForWidth()))
        self.pushButtonAccept.setMinimumSize(pbSize)
        self.pushButtonAccept.setMaximumSize(pbSize)
        ok = QtGui.QIcon(FLUtil.filedir("icons", "button_ok.png"))
        self.pushButtonAccept.setIcon(ok)
        self.pushButtonAccept.setFocusPolicy(QtGui.QWidget.NoFocus)

        #pushButtonAccept->setAccel(QKeySequence(Qt::Key_F10)); FIXME
        self.pushButtonAccept.setDefault(True)
        #QToolTip::add(pushButtonAccept, tr("Seleccionar registro actual y cerrar formulario (F10)")); FIXME
        #QWhatsThis::add(pushButtonAccept, tr("Seleccionar registro actual y cerrar formulario (F10)")); FIXME
        self.layoutButtons.addWidget(self.pushButtonAccept)
        self.pushButtonAccept.clicked.connect(self.accept())

        self.pushButtonCancel = QtGui.QPushButton(self, "pushButtonCancel")
        self.pushButtonCancel.sizePolicy(
            Qt.QSizePolicy(
                0, 0, 0, 0,
                self.pushButtonAccept.sizePolicy().hasHeightForWidth()))
        self.pushButtonCancel.setMinimumSize(pbSize)
        self.pushButtonCancel.setMaximumSize(pbSize)
        cancel = QtGui.QIcon(FLUtil.filedir("icons", "button_cancel.png"))
        self.pushButtonAccept.setIcon(cancel)
        self.pushButtonCancel.setFocusPolicy(QtGui.QWidget.NoFocus)
        #pushButtonCancel->setAccel(QKeySequence(tr("Esc"))); #FIXME
        #QToolTip::add(pushButtonCancel, tr("Cerrar formulario sin seleccionar registro (Esc)")); #FIXME
        #QWhatsThis::add(pushButtonCancel, tr("Cerrar formulario sin seleccionar registro (Esc)")); #FIXME
        self.layoutButtons.addItem(
            QtGui.QSpacerItem(20, 20, Qt.QSizePolicy.Fixed,
                              Qt.QSizePolicy.Fixed))
        self.layoutButtons.addWidget(self.pushButtonCancel)
        self.pushButtonCancel.clicked.connect(self.reject())

        self.mainWidget_ = w
        self.cursor_.setEdition(False)
        self.cursor_.setBrowse(False)
        self.cursor_.recordChoosed.connect(self.accept())

        if not tooLarge:
            mWidth = self.mainWidget_.width()
            mHeight = self.mainWidget_.height()
            actWin = QtGui.qApp.activeWindow()
            if actWin:
                screen = actWin.geometry()
            else:
                screen = QtGui.qApp.mainWidget().geometry()
            p = screen.center() - Qt.QPoint(mWidth / 2, mHeight / 2)

            if p.x() + mWidth > desk.width():
                p.setx(desk.width() - mWidth)
            if p.y() + mHeight > desk.height():
                p.sety(desk.height() - mHeight)
            if p.x() < 0:
                p.setx(0)
            if p.y() < 0:
                p.sety(0)
            self.move(p)

    """
    Muestra el formulario y entra en un nuevo bucle de eventos
    para esperar, a seleccionar registro.

    Se espera el nombre de un campo del cursor
    devolviendo el valor de dicho campo si se acepta el formulario
    y un QVariant::Invalid si se cancela.

    @param n Nombre del un campo del cursor del formulario
    @return El valor del campo si se acepta, o QVariant::Invalid si se cancela
    """

    def exec(self, n=QString.null):
        if not self.cursor_:
            return QVariant()

        if self.loop and self.inExec_:
            print(
                FLUtil.translate(
                    "app",
                    "FLFormSearchDB::exec(): Se ha detectado una llamada recursiva"
                ))
            self.QWidget.show()
            if self.initFocusWidget_:
                self.initFocusWidget_.setFocus()
            return QVariant()

        self.inExec_ = True
        self.acceptingRejecting_ = False

        self.QWidget.show()
        if self.initFocusWidget_:
            self.initFocusWidget_.setFocus()

        if self.iface:
            aqApp.call("init", self.QSArgumentList(), self.iface)

        #if (!isClosing_ && !aqApp->project()->interpreter()->hadError()) #FIXME
        #    QTimer::singleShot(0, this, SLOT(emitFormReady())); #FIXME

        self.accepted_ = False
        self.loop = True
        if not self.isClosing_ and not self.acceptingRejecting_:
            QtGui.QApplication.eventLoop().enterLoop()
        self.loop = False

        self.clearWFlags(Qt.WShowModal)
        v = None
        if self.accepted_ and not n.isEmpty():
            v = self.cursor_.valueBuffer(n)
        else:
            v = QVariant()

        self.inExec_ = False
        return v

    """
    Aplica un filtro al cursor
    """

    def setFilter(self, f):
        if not self.cursor_:
            return
        previousF = QString(self.cursor_.mainFilter())
        newF = QString(None)
        if previousF.isEmpty():
            newF = f
        elif previousF.contains(f):
            return
        else:
            newF = previousF + " AND " + f
        self.cursor_.setMainFilter(newF)

    """
    Devuelve el nombre de la clase del formulario en tiempo de ejecución
    """

    def formClassName(self):
        return "FormSearhDB"

    """
    Establece el título de la ventana.

    @param text Texto a establecer como título de la ventana
    @author Silix
    """

    def setCaptionWidget(self, text):
        if text.isEmpty():
            return
        self.setCaption(text)

    """
    Nombre interno del formulario
    """

    def geoName(self):
        return QString("formSearch") + self.idMDI_

    """
    Captura evento cerrar
    """

    def closeEvent(self, e):
        self.frameGeometry()
        if self.focusWidget():
            fdb = self.focusWidget().parentWidget()
            if fdb and fdb.autoComFrame_ and fdb.autoComFrame_.isvisible():
                fdb.autoComFrame_.hide()
                return

        if self.cursor_ and self.pushButtonCancel:
            if not self.pushButtonCancel.isEnabled():
                return
            self.isClosing_ = True
            self.setCursor(None)
        else:
            self.isClosing_ = True
        if self.isShown():
            self.reject()
        if self.isHidden():
            self.closed()
            self.QWidget.closeEvent(e)
            self.deleteLater()

    """
    Invoca a la función "init()" del script asociado al formulario
    """

    @QtCore.pyqtSlot()
    def initScript(self):
        return False

    """
    Redefinida por conveniencia
    """

    @QtCore.pyqtSlot()
    def hide(self):
        if self.isHidden():
            return

        self.QWidget.hide()
        if self.loop:
            self.loop = False
            QtGui.QApplication.eventLoop().exitLoop()

    """
    Se activa al pulsar el boton aceptar
    """

    @QtCore.pyqtSlot()
    def accept(self):
        if self.acceptingRejecting_:
            return
        self.frameGeometry()
        if self.cursor_:
            self.cursor_.recordChoosed.disconnect(self.accept())
            self.accepted_ = True

        self.acceptingRejecting_ = True
        self.hide()

    """
    Se activa al pulsar el botón cancelar
    """

    @QtCore.pyqtSlot()
    def reject(self):
        if self.acceptingRejecting_:
            return
        self.frameGeometry()
        if self.cursor_:
            self.cursor_.recordChoosed.disconnect(self.accept())
        self.acceptingRejecting_ = True
        self.hide()

    """
    Redefinida por conveniencia
    """

    @QtCore.pyqtSlot()
    def show(self):
        self.exec()
Ejemplo n.º 46
0
    def sqlDelete(self, t, w, connName="default"):
        from pineboolib.fllegacy.FLSqlCursor import FLSqlCursor
        c = FLSqlCursor(t, True, connName)
        c.setForwardOnly(True)

        # if not c.select(w):
        #     return False
        c.select(w)

        while c.next():
            c.setModeAccess(FLSqlCursor.DEL)
            c.refreshBuffer()
            if not c.commitBuffer():
                return False

        return True
Ejemplo n.º 47
0
    def sqlInsert(self, t, fL, vL, connName="default"):

        if not fL.len == vL:
            return False

        c = FLSqlCursor(t, True, connName)
        c.setModeAccess(FLSqlCursor.Insert)
        c.refreshBuffer()

        for f, v in (fL, vL):
            if v == "NULL":
                c.bufferSetNull(f)
            else:
                c.setValueBuffer(f, v)

        return c.commitBuffer()
Ejemplo n.º 48
0
    def sqlUpdate(self, t, fL, vL, w, connName="default"):
        from pineboolib.fllegacy.FLSqlCursor import FLSqlCursor
        c = FLSqlCursor(t, True, connName)
        c.setForwardOnly(True)

        # if not c.select(w):
        #     return False
        c.select(w)

        while c.next():
            c.setModeAccess(FLSqlCursor.Edit)
            c.refreshBuffer()
            
            if isinstance(fL, list):
                i = 0
                for f in fL:
                    c.setValueBuffer(f, vL[i])
                    i = i + 1
            else:
                c.setValueBuffer(fL, vL)
                
            if not c.commitBuffer():
                return False

        return True
Ejemplo n.º 49
0
class FLFormDB(QtGui.QWidget):
    """
    Representa un formulario que enlaza con una tabla.

    Se utiliza como contenedor de componentes que quieran
    enlazar con la base de datos y acceder a los registros
    del cursor. Esta estructura simplifica en gran
    medida el acceso a los datos ya que muchas tareas son
    automáticamente gestionadas por este formulario contenedor.

    En un principio el formulario se crea vacío y debemos invocar
    el metodo FLFormDB::setMainWidget(), pasándole como parámetro
    otro widget (generalmente un formulario creado con QtDesigner),
    el cual contiene distintos componentes, este widget se visualizará
    dentro de este contenedor, autofonfigurándose todos los componentes
    que contiene, con los datos y metadatos del cursor. Generalmente los
    componentes serán plugins, como FLFieldDB o FLTableDB.

    @author InfoSiAL S.L.
    """
    """
    Cursor, con los registros, utilizado por el formulario
    """
    cursor_ = None
    """
    Nombre de la tabla, contiene un valor no vacío cuando
    la clase es propietaria del cursor
    """
    name_ = None
    """
    Capa principal del formulario
    """
    layout = None
    """
    Widget principal del formulario
    """
    mainWidget_ = None
    """
    Acción asociada al formulario
    """
    action_ = None
    """
    Identificador de ventana MDI.

    Generalmente es el nombre de la acción que abre el formulario
    """
    idMDI_ = None
    """
    Capa para botones
    """
    layoutButtons = None
    """
    Boton Cancelar
    """
    pushButtonCancel = None
    """
    Indica que la ventana ya ha sido mostrada una vez
    """
    showed = None
    """
    Guarda el contexto anterior que tenia el cursor
    """
    oldCursorCtxt = None
    """
    Indica que el formulario se está cerrando
    """
    isClosing_ = None
    """
    Componente con el foco inicial
    """
    initFocusWidget_ = None
    """
    Guarda el último objeto de formulario unido a la interfaz de script (con bindIface())
    """
    oldFormObj = None

    #ifdef QSDEBUGGER
    """
    Boton Debug Script
    """
    pushButtonDebug = None
    #endif
    """
    Almacena que se aceptado, es decir NO se ha pulsado, botón cancelar
    """
    accepted_ = None
    """
    Interface para scripts
    """
    iface = None

    parent_ = None

    @decorators.BetaImplementation
    def __init__(self, *args, **kwargs):
        if isinstance(args[0], FLSqlCursor):
            QtGui.QWidget.__init__(self, args[2])
            self.inicialize3(args, kwargs)
        elif isinstance(args[0], QtGui.QWidget):
            QtGui.QWidget.__init__(self, args[0])
            self.inicialize1(args, kwargs)
        else:
            QtGui.QWidget.__init__(self, args[1])
            self.inicialize2(args, kwargs)

    """
    constructor
    """

    @decorators.BetaImplementation
    def inicialize1(self, *args, **kwargs):
        parent = args[0][0]
        name = args[0][1]
        f = args[1]

        if parent:
            self.parent_ = parent
        else:
            self.parent_ = QtGui.QWidget(pineboolib.project.mainWidget(), name,
                                         f)

        self.cursor_ = None
        self.layout = None
        self.mainWidget_ = None
        self.layoutButtons = None
        self.pushButtonCancel = None
        self.showed = False
        self.iface = None
        self.oldCursorCtxt = None
        self.isClosing_ = False
        self.initFocusWidget_ = None
        self.oldFormObj = None
        self.accepted_ = False
        self.loaded = False

    """
    constructor.

    @param actionName Nombre de la acción asociada al formulario
    """

    @decorators.BetaImplementation
    def inicialize2(self, *args, **kwargs):
        actionName = str(args[0][0])
        parent = args[0][1]
        f = args[1]

        if parent:
            self.parent_ = parent
        else:
            self.parent_ = QtGui.QWidget(pineboolib.project.mainWidget(),
                                         actionName, f)

        self.layout = None
        self.mainWidget_ = None
        self.layoutButtons = None
        self.pushButtonCancel = None
        self.showed = False
        self.iface = None
        self.oldCursorCtxt = None
        self.isClosing_ = False
        self.initFocusWidget_ = None
        self.oldFormObj = None
        self.accepted_ = False

        self.setFocusPolicy(QtGui.QWidget.NoFocus)

        if actionName.isEmpty():
            self.action_ = None
            print(FLUtil.translate("sys", "FLFormDB : Nombre de acción vacío"))
            return
        else:
            self.action_ = FLSqlConnections.database().manager().action(
                actionName)

        if not self.action_:
            print(
                FLUtil.translate(
                    "sys", "FLFormDB : No existe la acción %s" % actionName))
            return

        self.cursor_ = FLSqlCursor(self.action_.table(), True, "default", 0, 0,
                                   self)
        self.name_ = self.action_.name()

        self.initForm()

    """
    constructor sobrecargado.

    @param cursor Objeto FLSqlCursor para asignar a este formulario
    @param actionName Nombre de la acción asociada al formulario
    """

    @decorators.BetaImplementation
    def inicialize3(self, *args, **kwargs):

        cursor = args[0]
        actionName = args[1]
        parent = args[2]
        f = args[3]

        self.cursor_ = cursor
        self.layout = None
        self.mainWidget_ = None
        self.layoutButtons = None
        self.pushButtonCancel = None
        self.showed = False
        self.iface = None
        self.oldCursorCtxt = None
        self.isClosing_ = False
        self.initFocusWidget_ = None
        self.oldFormObj = None
        self.accepted_ = False

        if parent:
            self.parent_ = QtGui.QWidget(parent)
        else:
            self.parent_ = QtGui.QWidget(pineboolib.project.mainWidget(),
                                         actionName, f)

        self.setFocusPolicy(QtGui.QWidget.NoFocus)

        if actionName.isEmpty():
            self.action_ = None
        elif cursor:
            self.action_ = cursor.db().manager().action(actionName)
        else:
            self.action = FLSqlConnections.database().manager().action(
                actionName)

        if self.action_:
            self.name_ = self.action_.name()

    """
    destructor
    """

    @decorators.BetaImplementation
    def __del__(self):
        self.unbindIface()

    """
    Establece el cursor que debe utilizar el formulario.

    @param c Cursor con el que trabajar
    """

    @decorators.BetaImplementation
    def setCursor(self, *c):
        if not c == self.cursor_ and self.cursor_ and self.oldCursorCtxt:
            self.cursor_.setContext(self.oldCursorCtxt)

        if not c:
            return

        if self.cursor_:
            self.cursor_.destroyed.disconnect(self.cursorDestroyed)

        self.cursor_ = c
        self.cursor_.destroyed.connect(self.cursorDestroyed)

        if self.iface and self.cursor_:
            self.oldCursorCtxt = self.cursor_.context()
            self.cursor_.setContext(self.iface)

    """
    Para obtener el cursor utilizado por el formulario.

    return Objeto FLSqlCursor con el cursor que contiene los registros para ser utilizados
      en el formulario
    """

    @decorators.BetaImplementation
    def cursor(self):
        return self.cursor_

    """
    Para obtener el widget principal del formulario.

    return Objeto QWidget que corresponde con el widget principal del formulario
    """

    @decorators.BetaImplementation
    def mainWidget(self):
        return self.mainWidget_

    """
    Establece el identificador MDI
    """

    @decorators.BetaImplementation
    def setIdMDI(self, _id):
        self.idMDI_ = _id

    """
    Obtiene el identificador MDI
    """

    @decorators.BetaImplementation
    def idMDI(self):
        return self.idMDI_

    @decorators.BetaImplementation
    def setMainWidget(self, *args, **kwarg):
        if isinstance(args[0], QtGui.QWidget):
            self.setMainWidgetQWidget(args[0])
        elif isinstance(args[0], str):
            self.setMainWidgetString(args[0])
        else:
            self.setMainWidgetEmpty()

    """
    Establece widget como principal del formulario.

    Este widget contendrá componentes que quieran enlazar con la
    base de datos, por lo que esperan estar contenidos en una clase
    FLFormDB, la cual les proporciona el cursor (registros) a los que enlazar.
    Si ya existiera otro widget como principal, este será borrado.

    Si existe un widget principal establecido con anterioridad será borrado

    @param w Widget principal para el formulario
    """

    @decorators.BetaImplementation
    def setMainWidgetQWidget(self, *w):

        if not self.cursor_ and not w:
            return

        if self.showed:
            if self.mainWidget_ and not self.mainWidget_ == w:
                self.initMainWidget(w)
            else:
                w.hide()

            if self.layout:
                del self.Layout

            #w.setFont(qApp.font()) #FIXME
            self.layout = QtGui.QVBoxLayout(self, 2, 3, "vlay" + self.name_)
            self.layout.add(w)
            self.layoutButtons = QtGui.QHBoxLayout(self.layout, 3,
                                                   "hlay" + self.name_)

            self.layoutButtons.addItem(QtGui.QSpacerItem())
            self.pushButtonCancel = QtGui.QPushButton(self, "pushButtonCancel")
            #self.pushButtonCancel.set_size(QtGui.QSizePolicy) #FIXME
            self.pushButtonCancel.setMinimumSize(22, 22)
            self.pushButtonCancel.setMaximumSize(22, 22)
            self.pushButtonCancel.setIcon(
                QtGui.QIcon(filedir("icons", "gtk-cancel.png")))
            #pushButtonCancel->setFocusPolicy(QWidget::NoFocus);
            #pushButtonCancel->setAccel(QKeySequence(tr("Esc")));
            #QToolTip::add(pushButtonCancel, tr("Cerrar formulario (Esc)"));
            #QWhatsThis::add(pushButtonCancel, tr("Cerrar formulario (Esc)"));
            self.layoutButtons.addWidget(self.pushButtonCancel)
            self.pushButtonCancel.clicked.connect(self.close)
            self.pushButtonCancel.show()
            self.mainWidget_ = w

    """
    Sobrecargado de setMainWidget.

    Aqui toma el nombre de un formulario de la acción asociada y construye el Widget principal, a partir de él.
    """

    @decorators.BetaImplementation
    def setMainWidgetEmpty(self):
        if not self.action_:
            return

        if self.cursor_:
            self.setMainWidgetQWidget(
                self.cursor_.db().managerModules.createUI(
                    self.action_, self, self))
        else:
            self.setMainWidget(
                FLSqlConnections.database().managerModules().createUI(
                    self.action_, self, self))

    """
    Sobrecargado de setMainWidget.

    Aqui construye el Widget principal a partir del nombre de un fichero de interfaz .ui.

    @param uiFileName Nombre del fichero de descripción de interfaz, incluyendo la extension .ui, p.e. clientes.ui
    """

    @decorators.BetaImplementation
    def setMainWidgetString(self, uiFileName):
        if self.cursor_:
            self.setMainWidgetQWidget(
                self.cursor_.db().managerModules.createUI(
                    uiFileName, self, self))
        else:
            self.setMainWidget(
                FLSqlConnections.database().managerModules().createUI(
                    uiFileName, self, self))

    """
    Obtiene la imagen o captura de pantalla del formulario.
    """

    @decorators.BetaImplementation
    def snapShot(self):
        pix = QtGui.QPixmap.grabWidget(self)
        return QtGui.QImage(pix)

    """
    Salva en un fichero con formato PNG la imagen o captura de pantalla del formulario.

    @param pathFile Ruta y nombre del fichero donde guardar la imagen
    """

    @decorators.BetaImplementation
    def saveSnapShot(self, pathFile):
        fi = QtCore.QFile(pathFile)
        if not fi.open(QtCore.QFile.WriteOnly):
            print("FLFormDB : " + FLUtil.translate(
                "sys", "Error I/O al intentar escribir el fichero %s" %
                pathFile))
            return
        self.snapShot().save(fi, "PNG")

    """
    Establece el título de la ventana.

    @param text Texto a establecer como título de la ventana
    @author Silix
    """

    @decorators.BetaImplementation
    def setCaptionWidget(self, text):
        if text.isEmpty():
            return

        self.setCaption(text)

    """
    Devuelve si se ha aceptado el formulario
    """

    @decorators.BetaImplementation
    def accepted(self):
        return self.accepted_

    """
    Devuelve el nombre de la clase del formulario en tiempo de ejecución
    """

    @decorators.BetaImplementation
    def formClassName(self):
        return "FormDB"

    """
    Sólo para compatibilizar con FLFormSearchDB. Por defecto sólo llama QWidget::show
    """

    @decorators.BetaImplementation
    def exec_(self):
        QtGui.QWidget.show()
        return QtCore.QVariant()

    #public slots:
    """
    Cierra el formulario
    """

    @decorators.BetaImplementation
    def close(self):
        if self.isClosing_:
            return True
        self.isClosing_ = True
        self.isClosing_ = QtGui.QWidget.close()

    """
    Invoca a la función "init" del script "masterprocess" asociado al formulario
    """

    @decorators.NotImplementedWarn
    def initScript(self):
        if self.iface:
            #pineboolib.project.call("init", QtCore.QSArgumentList(), self.iface) #FIXME
            return True
        else:
            return False

    """
    Se activa al pulsar el boton aceptar
    """

    @decorators.BetaImplementation
    def accept(self):
        return

    """
    Se activa al pulsar el botón cancelar
    """

    @decorators.BetaImplementation
    def reject(self):
        return

    """
    Redefinida por conveniencia
    """

    @decorators.BetaImplementation
    def show(self):
        QtGui.QWidget.show()

    """
    Muestra el formulario sin llamar al script "init".
    Utilizado en documentación para evitar conflictos al capturar los formularios
    """

    @decorators.BetaImplementation
    def showForDocument(self):
        self.showed = True
        self.mainWidget_.show()
        self.resize(self.size().expandedTo(self.mainWidget_.size()))
        QtGui.QWidget.show()

    """
    Maximiza el formulario
    """

    @decorators.BetaImplementation
    def setMaximized(self):
        self.setWindowState(self.windowState() | QtCore.Qt.WindowMaximized)

    """
    Muestra el script asociado al formulario en el Workbench para depurar
    """

    @decorators.BetaImplementation
    def debugScript(self):
        return

    """
    Devuelve el script asociado al formulario
    """

    @decorators.BetaImplementation
    def script(self):
        return

    #private slots:
    @decorators.BetaImplementation
    def callInitScript(self):
        if not self.initScript():
            return
        if not self.isClosing_:
            self.emitFormReady.emit()

    #protected:
    """
    Inicialización
    """

    @decorators.BetaImplementation
    def initForm(self):
        if self.cursor_ and self.cursor_.metadata():
            caption = None
            if self.action_:
                self.cursor_.setAction(self.action_)
                caption = self.action_.caption()
                if not self.action_.description().isEmpty():
                    self.QtGui.QWhatsThis.add(self, self.action_.description())
                self.idMDI_ = self.action_.name()

            if caption.isEmpty():
                caption = self.cursor_.metadata().alias()
            self.setCaption(caption)

            self.bindIface()
            self.setCursor(self.cursor_)

        else:
            self.setCaption(FLUtil.translate("sys", "No hay metadatos"))

    """
    Nombre interno del formulario
    """

    @decorators.BetaImplementation
    def formName(self):
        return ("form%s" % self.idMDI_)

    @decorators.BetaImplementation
    def geoName(self):
        return self.formName()

    """
    Une la interfaz de script al objeto del formulario
    """

    @decorators.BetaImplementation
    def bindIface(self):
        p = pineboolib.project

        if not p:
            return

        self.setName(self.formName())
        o = p.object(self.name())

        if not o == self.iface and self.iface and self.oldFormObj:
            self.iface.setObj(self.oldFormObj)
        self.iface = o

        ifc = self.iface
        if not ifc:
            return

        if not ifc.obj() == self:
            if self.oldFormObj:
                self.oldFormObj.destroyed.disconnect(
                    self.oldFormObjDestroyed())

            self.oldFormObj = ifc.obj()
            if self.oldFormObj:
                self.oldFormObj.destroyed.connect(self.oldFormObjDestroyed())
            ifc.setObj(self)

    """
    Desune la interfaz de script al objeto del formulario
    """

    @decorators.BetaImplementation
    def unbindIface(self):
        ifc = self.iface
        if not ifc:
            return

        if ifc.obj() == self:
            ifc.setObj(self.oldFormObj)

    """
    Indica si la interfaz de script está unida al objeto formulario
    """

    @decorators.BetaImplementation
    def isIfaceBind(self):
        ifc = self.iface
        if not ifc:
            return
        return (ifc.obj() == self)

    """
    Captura evento cerrar
    """

    @decorators.BetaImplementation
    def closeEvent(self, *e):
        self.frameGeometry()
        if self.focusWidget():
            fdb = self.focusWidget().parentWidget()
            if fdb and fdb.autoComFrame_ and fdb.autoComFrame_.isVisible():
                fdb.autoComFrame_.hide()
                return

    """
    Captura evento mostrar
    """

    @decorators.NotImplementedWarn
    def showEvent(self, *e):
        if not self.showed and self.mainWidget_:
            self.showed = True

            if self.cursor_ and self.iface:
                #v = pineboolib.project.call("preloadMainFilter", QSArgumentList(), self.iface).variant())
                if v and isinstance(v.type(), str):
                    self.cursor_.setMainFilter(str(v), False)

            self.initMainWidget()
            self.callInitScript()
        if not self.isIfaceBind():
            self.bindIface()

    """
    Captura evento ocultar
    """

    @decorators.NotImplementedWarn
    def hideEvent(self, *h):
        return

    """
    {
  QWidget *pW = parentWidget();
  if (pW && pW->isA("QWorkspaceChild")) {
    QRect geo(pW->x(), pW->y(), pW->width(), pW->height());
    if (isMinimized()) {
      geo.setWidth(1);
      aqApp->saveGeometryForm(geoName(), geo);
    } else if (isMaximized()) {
      geo.setWidth(9999);
      aqApp->saveGeometryForm(geoName(), geo);
    } else
      aqApp->saveGeometryForm(geoName(), geo);
  } else {
    QRect geo(x(), y(), width(), height());
    aqApp->saveGeometryForm(geoName(), geo);
  }
}
    """
    """
    Captura evento de entrar foco
    """

    @decorators.BetaImplementation
    def focusInEvent(self, *f):
        self.focusInEvent(f)
        if self.isIfaceBind():
            self.bindIface()

    """
    Inicializa componenentes del widget principal

    @param w Widget a inicializar. Si no se establece utiliza
            por defecto el widget principal actual
    """

    @decorators.NotImplementedWarn
    def initMainWidget(self, *w):
        return

    """
    
{
  QWidget *mWidget = w ? w : mainWidget_;
  if (mWidget) {
    QObjectList *l = static_cast<QObject *>(mWidget)->queryList("FLTableDB");
    QObjectListIt itt(*l);
    FLTableDB *tdb;
    while ((tdb = static_cast<FLTableDB *>(itt.current())) != 0) {
      ++itt;
      tdb->initCursor();
    }
    delete l;

    l = static_cast<QObject *>(mWidget)->queryList("FLFieldDB");
    QObjectListIt itf(*l);
    FLFieldDB *fdb;
    while ((fdb = static_cast<FLFieldDB *>(itf.current())) != 0) {
      ++itf;
      fdb->initCursor();
      fdb->initEditor();
      if (fdb->aqFirstTabStop == 1)
        initFocusWidget_ = fdb;
    }

    while (mWidget->parentWidget() && mWidget->parentWidget() != this)
      mWidget = mWidget->parentWidget();
    mWidget->show();

    FLAccessControlLists *acl = aqApp->acl();
    if (acl)
      acl->process(this);

    QWidget *pW = parentWidget();
    QRect desk;
    bool parentIsDesktop = true;
    
    if (!(pW && pW->isA("QWorkspaceChild"))) {
        desk = QApplication::desktop()->availableGeometry(this);
        pW = this;
    } else {
        desk = pW->parentWidget()->rect();
        parentIsDesktop = false;
    }

    QRect geo(aqApp->geometryForm(QObject::name()));
    pW->show();
    QSize oSz = mWidget->size();
    mWidget->updateGeometry();
    QSize bSz = mWidget->baseSize();
    QSize SzH = mWidget->sizeHint();
    int border = 5, border_b = 48;
    /*
    qDebug("geo: " + QString::number(geo.width()) + "x"  + QString::number(geo.height()));
    qDebug("oSz: " + QString::number(oSz.width()) + "x"  + QString::number(oSz.height()));
    qDebug("bSz: " + QString::number(bSz.width()) + "x"  + QString::number(bSz.height()));
    qDebug("SzH: " + QString::number(SzH.width()) + "x"  + QString::number(SzH.height()));
    */

    if (geo.width() < 100 || geo.width()>9000) {
        // qDebug(" -- reset Form Size and position -- ");
        geo.setWidth(oSz.width());
        geo.setHeight(oSz.height());
        geo.moveCenter(desk.center());
        
        if (!parentIsDesktop) {
            geo.moveTop(desk.top() + border - geo.top()+1);
        }
    }

    if (geo.width() < SzH.width()) {
        // qDebug(" -- geo width too small -- ");
        geo.setWidth(SzH.width());
    }
    if (geo.height() < SzH.height()) {
        // qDebug(" -- geo height too small -- ");
        geo.setHeight(SzH.height());
    }
    // Exceeds available horizontal area:
    if (geo.width() > desk.width() - border * 2) {
        // qDebug(" -- geo width too big -- ");
        geo.setWidth(desk.width() - border * 2 - 5);
    }
    // Exceeds available vertical area:
    if (geo.height() > desk.height() - border - border_b) {
        // qDebug(" -- geo height too big -- ");
        geo.setHeight(desk.height() - border - border_b - 5);
    }
    if (parentIsDesktop) {
        // Invalid position values, re-center
        if (  geo.right() > 9000
         || geo.left() < 1
         || geo.bottom() > 9000
         || geo.top() < 1 ) {
            // qDebug(" -- geo invalid position -- ");
            geo.moveCenter(desk.center());
        }
    

        if ( geo.top() < desk.top() + border)  {
            // qDebug(" -- geo position too high -- ");
            geo.moveTop(desk.top() + border - geo.top()+1);
        }

        if ( geo.left() < desk.left() + border) {
            // qDebug(" -- geo position too left -- ");
            geo.moveLeft(desk.left() + border - geo.left()+1);
        }

        if ( geo.bottom() > desk.bottom() - border_b ) {
            int diff = geo.bottom() - desk.bottom() - border_b;
            // qDebug(" -- geo position too low -- ");
            geo.moveTop(-diff-1);
        }

        if ( geo.right() > desk.right() - border) {
            int diff = geo.right() - desk.right() - border;
            // qDebug(" -- geo position too right -- ");
            geo.moveLeft(-diff-1);
        }

        // Outside of screen, re-center:
        if (  geo.right() > desk.right() - border  
         || geo.left() < desk.left() + border
         || geo.bottom() > desk.bottom() - border_b
         || geo.top() < desk.top() + border ) {
            // qDebug(" -- geo position out of screen -- ");
            geo.moveCenter(desk.center());
        }
    }
    mWidget->resize(geo.size());

    pW->updateGeometry();
    QSize tSz= pW->size();
    QSize tSzH = pW->sizeHint();
    if (tSz.width() < tSzH.width()) {
        tSz.setWidth(tSzH.width());
    }
    if (tSz.height() < tSzH.height()) {
        tSz.setHeight(tSzH.height());
    }
    pW->resize(tSz.expandedTo(mWidget->size()));
    
    pW->move(geo.topLeft());

    if (!initFocusWidget_) {
      itf.toFirst();
      while ((fdb = static_cast<FLFieldDB *>(itf.current())) != 0) {
        ++itf;
        if (fdb->isEnabled()) {
          initFocusWidget_ = fdb;
          break;
        }
      }
      if (!initFocusWidget_)
        initFocusWidget_ = static_cast<QWidget *>(mWidget->focusWidget());
      if (initFocusWidget_)
        initFocusWidget_->setFocus();
    }

    delete l;

    QWidget *focWid = qApp->focusWidget();
    if (focWid) {
      QWidget *topWidget = focWid->topLevelWidget();
      if (topWidget && !topWidget->inherits("FLFormDB")) {
        QWidget *topWid = focWid->parentWidget();
        while (topWid && !topWid->inherits("FLFormDB"))
          topWid = topWid->parentWidget();
        topWidget = topWid;
      }
      if (topWidget != this)
        setFocus();
    } else setFocus();
    
  }
}

"""

    #protected slots:
    """
    Emite señal formulari listo. Ver FLFormDB::formReady()
    """

    emitFormReady = QtCore.pyqtSignal()
    """
    Uso interno
    """

    @QtCore.pyqtSlot()
    def oldFormObjDestroyed(self):
        print("oldFormObjDestroyed")
        self.oldFormObj = None
        return None

    @QtCore.pyqtSlot(QtCore.QObject)
    def cursorDestroyed(self, *obj):
        print("cursorDestroyed")
        if not obj or not obj == self.cursor_:
            return

        self.cursor_ = None
        return None

    #signals:
    """
    Señal emitida cuando se cierra el formulario
    """
    closed = QtCore.pyqtSignal()
    """
    Señal emitida cuando el formulario ya ha sido inicializado y está listo para usarse
    """
    formReady = QtCore.pyqtSignal()
Ejemplo n.º 50
0
    def Mr_Proper(self):
        util = FLUtil()
        self.db_.dbAux().transaction()

        qry = FLSqlQuery(None, self.db_.dbAux())
        qry2 = FLSqlQuery(None, self.db_.dbAux())
        steps = 0

        rx = QRegExp("^.*\\d{6,9}$")
        if rx in self.tables() is not False:
            listOldBks = rx in self.tables()
        else:
            listOldBks = []

        qry.exec_("select nombre from flfiles where nombre similar to"
                  "'%[[:digit:]][[:digit:]][[:digit:]][[:digit:]]-[[:digit:]][[:digit:]]%:[[:digit:]][[:digit:]]%' or nombre similar to"
                  "'%alteredtable[[:digit:]][[:digit:]][[:digit:]][[:digit:]]%' or (bloqueo='f' and nombre like '%.mtd')")

        util.createProgressDialog(
            util.tr("Borrando backups"), len(listOldBks) + qry.size() + 2)

        while qry.next():
            item = qry.value(0)
            util.setLabelText(util.tr("Borrando registro %1").arg(item))
            qry2.exec_("DELETE FROM flfiles WERE nombre ='%s'" % item)
            if item.find("alteredtable") > -1:
                if self.existsTable(item.replace(".mtd", "")):
                    util.setLabelText(util.tr("Borrando tabla %1").arg(item))
                    qry2.exec_("DROP TABLE %s CASCADE" %
                               item.replace(".mtd", ""))

            steps = steps + 1
            util.setProgress(steps)

        for item in listOldBks:
            if self.existsTable(item):
                util.setLabelText(util.tr("Borrando tabla %s" % item))
                qry2.exec_("DROP TABLE %s CASCADE" % item)

            steps = steps + 1
            util.setProgress(steps)

        util.setLabelText(util.tr("Inicializando cachés"))
        steps = steps + 1
        util.setProgress(steps)
        qry.exec_("DELETE FROM flmetadata")
        qry.exec_("DELETE FROM flvar")
        self.db_.manager().cleanupMetaData()
        # self.db_.driver().commit()
        util.destroyProgressDialog()

        steps = 0
        qry.exec_("select tablename from pg_tables where schemaname='public'")
        util.createProgressDialog(
            util.tr("Comprobando base de datos"), qry.size())
        while qry.next():
            item = qry.value(0)
            util.setLabelText(util.tr("Comprobando tabla %s" % item))

            mustAlter = self.mismatchedTable(item, item)
            if mustAlter:
                conte = self.db_.managerModules().content("%s.mtd" % item)
                if conte:
                    msg = util.tr("La estructura de los metadatos de la tabla '%s' y su "
                                  "estructura interna en la base de datos no coinciden. "
                                  "Intentando regenerarla." % item)

                    print(msg)
                    self.alterTable2(conte, conte, None, True)

            steps = steps + 1
            util.setProgress(steps)

        self.db_.dbAux().driver().transaction()
        steps = 0
        sqlCursor = FLSqlCursor(None, True, self.db_.dbAux())
        sqlQuery = FLSqlQuery(None, self.db_.dbAux())
        if sqlQuery.exec_("select relname from pg_class where ( relkind = 'r' ) "
                          "and ( relname !~ '^Inv' ) " "and ( relname !~ '^pg_' ) and ( relname !~ '^sql_' )"):

            util.setTotalSteps(sqlQuery.size())
            while sqlQuery.next():
                item = sqlQuery.value(0)
                steps = steps + 1
                util.setProgress(steps)
                util.setLabelText(util.tr("Creando índices para %s" % item))
                mtd = self.db_.manager().metadata(item)
                fL = mtd.fieldList()
                if not mtd or not fL:
                    continue
                for it in fL:
                    if not it or not it.type() == "pixmap":
                        continue
                    cur = FLSqlCursor(item, True, self.db_.dbAux())
                    cur.select(it.name() + " not like 'RK@%'")
                    while cur.next():
                        v = cur.value(it.name())
                        if v is None:
                            continue

                        v = self.db_.manager().storeLargeValue(mtd, v)
                        if v:
                            buf = cur.primeUpdate()
                            buf.setValue(it.name(), v)
                            cur.update(False)

                sqlCursor.setName(item, True)

        # self.db_.dbAux().driver().commit()

        steps = 0
        qry.exec_("select tablename from pg_tables where schemaname='public'")
        util.createProgressDialog(
            util.tr("Analizando base de datos"), qry.size())
        while qry.next():
            item = qry.value(0)
            util.setLabelText(util.tr("Analizando tabla %s" % item))
            qry2.exec_("vacuum analyze %s" % item)
            steps = steps + 1
            util.setProgress(steps)

        util.destroyProgressDialog()
Ejemplo n.º 51
0
class FLTableDB(QtGui.QWidget):
    _tableView = None
    _vlayout = None
    _lineEdit = None
    _comboBox_1 = None
    _comboBox_2 = None
    _topWidget = None
    _cursor = None
    _loaded = False
    _cursorLoaded = False

    _tableName = None
    _foreignField = None
    _fieldRelation = None
    _action = None
    _foreignFilter = None

    def __init__(self, parent = None, action_or_cursor = None, *args):
        #print("FLTableDB:", parent, action_or_cursor , args)
        # TODO: Falta el lineeditsearch y el combo, que los QS lo piden
        super(FLTableDB,self).__init__(parent,*args)
        # TODO: LA inicialización final hay que hacerla más tarde, en el primer
        # show(), porque sino obligas a tenerlo todo preparado en el constructor.
        self._tableView = QtGui.QTableView()
        self._lineEdit = QtGui.QLineEdit()
        _label1 = QtGui.QLabel()
        _label2 = QtGui.QLabel()
        self._comboBox_1 = QtGui.QComboBox()
        self._comboBox_2 = QtGui.QComboBox()
        _label1.setText("Buscar")
        _label2.setText("en")
        self._vlayout = QtGui.QVBoxLayout()
        _hlayout =  QtGui.QHBoxLayout()
        self._tableView._v_header = self._tableView.verticalHeader()
        self._tableView._v_header.setDefaultSectionSize(18)
        self._tableView._h_header = self._tableView.horizontalHeader()
        self._tableView._h_header.setDefaultSectionSize(70)
        _hlayout.addWidget(_label1)
        _hlayout.addWidget(self._lineEdit)
        _hlayout.addWidget(_label2)
        _hlayout.addWidget(self._comboBox_1)
        _hlayout.addWidget(self._comboBox_2)
        self._vlayout.addLayout(_hlayout)
        self._vlayout.addWidget(self._tableView)
        self.setLayout(self._vlayout)
        self._parent = parent
        while True:
            parent_cursor = getattr(self._parent,"_cursor", None)
            if parent_cursor: break
            new_parent = self._parent.parentWidget()
            if new_parent is None: break
            self._parent = new_parent
            print(self._parent)

        self._tableView.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
        self._tableView.setSelectionMode(QtGui.QAbstractItemView.SingleSelection)
        self._tableView.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
        self._tableView.setAlternatingRowColors(True)

        if action_or_cursor is None and parent_cursor:
            action_or_cursor = parent_cursor
        if isinstance(action_or_cursor,FLSqlCursor):
            self._cursor = action_or_cursor
        elif isinstance(action_or_cursor,str):
            self._action = action_or_cursor
        else:
            self._cursor = None
        if self._cursor:
            self._tableView._h_header.setResizeMode(QtGui.QHeaderView.ResizeToContents)
            self._tableView.setModel(self._cursor.model())
            self._tableView.setSelectionModel(self._cursor.selection())
        self.tableRecords = self # control de tabla interno

        #Carga de comboBoxs y connects .- posiblemente a mejorar
        if self._cursor:
            i = 0
            for column in range(self._cursor.model().columnCount()):
                #print("Columna ", i)
                self._comboBox_1.addItem(self._cursor.model().headerData(column, QtCore.Qt.Horizontal, QtCore.Qt.DisplayRole))
                self._comboBox_2.addItem(self._cursor.model().headerData(column, QtCore.Qt.Horizontal, QtCore.Qt.DisplayRole))
        self._comboBox_1.addItem("*")
        self._comboBox_2.addItem("*")
        self._comboBox_1.setCurrentIndex(0)
        self._comboBox_2.setCurrentIndex(1)
        self._comboBox_1.currentIndexChanged.connect(self.comboBox_putFirstCol)
        self._comboBox_2.currentIndexChanged.connect(self.comboBox_putSecondCol)        

        self.sort = []
        self.timer_1 = QtCore.QTimer(self)
        self.timer_1.singleShot(100, self.loaded)
        self._topWidget = parent

    def __getattr__(self, name): return DefFun(self, name)

    def loaded(self):
        # Es necesario pasar a modo interactivo lo antes posible
        # Sino, creamos un bug en el cierre de ventana: se recarga toda la tabla para saber el tamaño
        #print("FLTableDB(%s): setting columns in interactive mode" % self._tableName)
        self._tableView._h_header.setResizeMode(QtGui.QHeaderView.Interactive)
        self._loaded = True
        while True: #Ahora podemos buscar el cursor ... porque ya estamos añadidos al formulario
            parent_cursor = getattr(self._parent,"_cursor", None)
            if parent_cursor: break
            new_parent = self._parent.parentWidget()
            if new_parent is None: break
            self._parent = new_parent
        self.initCursor()

    def cursor(self):   
        if not self._cursorLoaded:
            self.timer_cursor = QtCore.QTimer(self)
            self.timer_cursor.singleShot(100, self.cursor)
        else:
            if not self._cursor:
                self._cursor = None
                print("WARN: FLTableDB.cursor(): Cursor Inválido a", self._tableName)
            return self._cursor

    def obj(self):
        return self

    def comboBox_putFirstCol(self):
        self.putFirstCol(str(self._comboBox_1.currentText()))

    def comboBox_putSecondCol(self):
        self.putSecondCol(str(self._comboBox_2.currentText()))

    def putFirstCol(self, fN):
        _oldPos= None
        _oldFirst = self._tableView._h_header.logicalIndex(0)    
        for column in range(self._cursor.model().columnCount()):
            if self._cursor.model().headerData(column, QtCore.Qt.Horizontal, QtCore.Qt.DisplayRole).lower() == fN.lower():
                _oldPos = self._tableView._h_header.visualIndex(column) 
                if not self._comboBox_1.currentText() == fN:
                    self._comboBox_1.setCurrentIndex(column)
                    return False
                break

        if not _oldPos or fN == "*":
            return False
        else:         
            self._tableView._h_header.swapSections(_oldPos, 0)
            self._comboBox_2.setCurrentIndex(_oldFirst)
            return True

    def putSecondCol(self, fN):
        if self._cursor is None:
            return
        _oldPos= None
        _oldSecond = self._tableView._h_header.logicalIndex(1)
        for column in range(self._cursor.model().columnCount()):
            if self._cursor.model().headerData(column, QtCore.Qt.Horizontal, QtCore.Qt.DisplayRole).lower() == fN.lower():
                _oldPos = self._tableView._h_header.visualIndex(column)
                break

        if not _oldPos or fN == "*":
            return False
        if not self._comboBox_1.currentText() == fN:           
            self._tableView._h_header.swapSections(_oldPos, 1)
        else:
            self._comboBox_1.setCurrentIndex(_oldSecond)
        return True


    def setTableName(self, tableName):
        self._tableName = tableName
        self.initCursor()
        return True
    
    def tableName(self):
        return self._tableName
    
    def foreignField(self):
        return self._foreignField
    
    def fieldRelation(self):
        return self._fieldRelation


    def setForeignField(self, foreignField):
        self._foreignField = foreignField
        self.initCursor()
        return True


    def setFieldRelation(self, fieldRelation):
        self._fieldRelation = fieldRelation
        self.initCursor()
        return True
    
    def setActionName(self, action):
        self._action = action


    def showAlias(self, b):
        self._showAlias = b




    def initCursor(self):
        filtro = None
        self._cursorLoaded = True
        if not self._foreignField:
            return
        if not self._fieldRelation:
            return
        if not self._tableName:
            return
        
        if self._loaded:   

            tipo = self._cursor.model().fieldType(self._fieldRelation)
            foranea = self._parent.parentWidget().cursor().valueBuffer(self._foreignField)
            if foranea is None:
                #print("FLTable(%s): campo foraneo \"%s.%s\" no encontrado." % (self._tableName,self._parent.parentWidget()._cursor.table(), self._foreignField))
                return
            if tipo is "uint":
                self._foreignFilter = "%s = %s" % (self._fieldRelation, self._parent.parentWidget().cursor().valueBuffer(self._foreignField))
            else:
                self._foreignFilter = "%s = '%s'"  % (self._fieldRelation, self._parent.parentWidget().cursor().valueBuffer(self._foreignField))
            
            #print("Filtro:%s" % filtro)
            self._cursor.setMainFilter(self._foreignFilter)
            self._cursor.refresh()
        else:
            self._cursor = FLSqlCursor(self._tableName)
        
        
            
            

            #self._cursor.setMainFilter("%s = ")

    @QtCore.pyqtSlot()
    def close(self):
        print("FLTableDB: close()")

    @QtCore.pyqtSlot()
    def refresh(self):
        print("FLTableDB: refresh()", self.parent().parent().parent())
        self._cursor.setMainFilter(self._foreignFilter)

    @QtCore.pyqtSlot()
    def show(self):
        print("FLTableDB: show event")
        #super(FLTableDB, self).show()
        
        if self._cursor:
            self._tableView._h_header.setResizeMode(QtGui.QHeaderView.ResizeToContents)
            self._tableView.setModel(self._cursor.model())
            self._tableView.setSelectionModel(self._cursor.selection())
        self.tableRecords = self # control de tabla interno

        #Carga de comboBoxs y connects .- posiblemente a mejorar
        if self._cursor:
            for column in range(self._cursor.model().columnCount()):
                
                self._comboBox_1.addItem(self._cursor.model().headerData(column, QtCore.Qt.Horizontal, QtCore.Qt.DisplayRole))
                self._comboBox_2.addItem(self._cursor.model().headerData(column, QtCore.Qt.Horizontal, QtCore.Qt.DisplayRole))
        self._comboBox_1.addItem("*")
        self._comboBox_2.addItem("*")
        self._comboBox_1.setCurrentIndex(0)
        self._comboBox_2.setCurrentIndex(1)
        self._comboBox_1.currentIndexChanged.connect(self.comboBox_putFirstCol)
        self._comboBox_2.currentIndexChanged.connect(self.comboBox_putSecondCol)        

        self.sort = []
        self.timer_1 = QtCore.QTimer(self)
        self.timer_1.singleShot(100, self.loaded)
        

    @QtCore.pyqtSlot()
    def insertRecord(self):
        self._cursor.insertRecord()

    @QtCore.pyqtSlot()
    def editRecord(self):
        self._cursor.editRecord()

    @QtCore.pyqtSlot()
    def deleteRecord(self):
        self._cursor.deleteRecord()

    @QtCore.pyqtSlot()
    def browseRecord(self):
        self._cursor.browseRecord()

    @QtCore.pyqtSlot()
    def copyRecord(self):
        self._cursor.copyRecord()
    
    @decorators.WorkingOnThis
    def setEditOnly(self, value):
        return True
    
    @decorators.WorkingOnThis
    def setReadOnly(self, value):
        return True
Ejemplo n.º 52
0
    def alterTable3(self, newMTD):
        if self.hasCheckColumn(newMTD):
            return False

        oldMTD = newMTD
        fieldList = oldMTD.fieldList()

        renameOld = "%salteredtable%s" % (
            oldMTD.name()[0:5], QDateTime().currentDateTime().toString("ddhhssz"))

        self.db_.dbAux().transaction()

        q = FLSqlQuery(None, self.db_.dbAux())

        constraintName = "%s_key" % oldMTD.name()

        if self.constraintExists(constraintName) and not q.exec_("ALTER TABLE %s DROP CONSTRAINT %s" % (oldMTD.name(), constraintName)):
            self.db_.dbAux().rollback()
            return False

        for oldField in fieldList:
            if oldField.isCheck():
                return False
            if oldField.isUnique():
                constraintName = "%s_%s_key" % (oldMTD.name(), oldField.name())
                if self.constraintExists(constraintName) and not q.exec_("ALTER TABLE %s DROP CONSTRAINT %s" % (oldMTD.name(), constraintName)):
                    self.db_.dbAux().rollback()
                    return False

        if not q.exec_("ALTER TABLE %s RENAME TO %s" % (oldMTD.name(), renameOld)):
            self.db_.dbAux().rollback()
            return False

        if not self.db_.manager().createTable(newMTD):
            self.db_.dbAux().rollback()
            return False

        oldCursor = FLSqlCursor(renameOld, True, self.db_.dbAux())
        oldCursor.setModeAccess(oldCursor.Browse)
        oldCursor.select()

        fieldList = newMTD.fieldList()

        if not fieldList:
            self.db_.dbAux().rollback()
            return False

        oldCursor.select()
        totalSteps = oldCursor.size()
        progress = QProgressDialog(qApp.tr("Reestructurando registros para %1...").arg(
            newMTD.alias()), qApp.tr("Cancelar"), 0, totalSteps)
        progress.setLabelText(qApp.tr("Tabla modificada"))

        step = 0
        newBuffer = None
        newField = None
        listRecords = []
        newBufferInfo = self.recordInfo2(newMTD.name())
        oldFieldsList = {}
        newFieldsList = {}
        defValues = {}
        v = None

        for newField in fieldList:
            oldField = oldMTD.field(newField.name())
            defValues[str(step)] = None
            if not oldField or not oldCursor.field(oldField.name()):
                if not oldField:
                    oldField = newField
                if not newField.type() == "serial":
                    v = newField.defaultValue()
                    defValues[str(step)] = v

            newFieldsList[str(step)] = newField
            oldFieldsList[str(step)] = oldField
            step = step + 1

        ok = True
        while oldCursor.next():
            newBuffer = newBufferInfo

            for reg in defValues.keys():
                newField = newFieldsList[reg]
                oldField = oldFieldsList[reg]
                if defValues[reg]:
                    v = defValues[reg]
                else:
                    v = oldCursor.value(newField.name())
                    if (not oldField.allowNull or not newField.allowNull()) and not v and not newField.type() == "serial":
                        defVal = newField.defaultValue()
                        if defVal is not None:
                            v = defVal

                    if v is not None and not newBuffer.field(newField.name()).type() == newField.type():
                        print("FLManager::alterTable : " + qApp.tr(
                            "Los tipos del campo %1 no son compatibles. Se introducirá un valor nulo.").arg(newField.name()))

                    if v is not None and newField.type() == "string" and newField.length() > 0:
                        v = str(v)[0:newField.length()]

                    if (not oldField.allowNull() or not newField.allowNull()) and v is None:
                        if oldField.type() == "serial":
                            v = int(self.nextSerialVal(
                                newMTD.name(), newField.name()))
                        elif oldField.type() in ("int", "uint", "bool", "unlock"):
                            v = 0
                        elif oldField.type() == "double":
                            v = 0.0
                        elif oldField.type() == "time":
                            v = QTime().currentTime()
                        elif oldField.type() == "date":
                            v = QDate().currentDate()
                        else:
                            v = "NULL"[0:newField.length()]

                    newBuffer.setValue(newField.name(), v)

                listRecords.append(newBuffer)

            # if not self.insertMulti(newMTD.name(), listRecords):
            #    ok = False
            #    listRecords.clear()
            #    break

            # listRecords.clear()

        if len(listRecords) > 0:
            if not self.insertMulti(newMTD.name(), listRecords):
                ok = False
            listRecords.clear()

        if ok:
            self.db_.dbAux().commit()
        else:
            self.db_.dbAux().rollback()
            return False

        force = False  # FIXME
        if force and ok:
            q.exec_("DROP TABLE %s CASCADE" % renameOld)
        return True
Ejemplo n.º 53
0
    def insert(table_or_cursor, fields, values, where="", conn=None):

        if isinstance(table_or_cursor, str):
            cur = FLSqlCursor(table_or_cursor, conn)
        else:
            cur = table_or_cursor

        if cur is None:
            return False

        if not cur.metadata():
            return False

        fieldsCount = len(fields)

        cur.setModeAccess(cur.Insert)
        cur.refreshBuffer()

        for i in range(0, fieldsCount - 1):
            cur.setValueBuffer(fields[i], values[i])

        msgCheck = cur.msgCheckIntegrity()
        if msgCheck != "":
            ok = False
            raise Exception(msgCheck)

        ok = False
        actCheck = cur.activatedCheckIntegrity()
        cur.setActivatedCheckIntegrity(False)
        ok = cur.commitBuffer()
        cur.setActivatedCheckIntegrity(actCheck)

        return ok
Ejemplo n.º 54
0
class FLFormSearchDB(FLFormDB):

    """
    Subclase de la clase FLFormDB, pensada para buscar un registro
    en una tabla.

    El comportamiento de elegir un registro se modifica para solamente
    cerrar el formulario y así el objeto que lo invoca pueda obtener
    del cursor dicho registro.

    También añade botones Aceptar y Cancelar. Aceptar indica que se ha
    elegido el registro activo (igual que hacer doble clic sobre él o
    pulsar la tecla Intro) y Cancelar aborta la operación.

    @author InfoSiAL S.L.
    """
    
    """
    Uso interno
    """
    acceptingRejecting_ = False
    inExec_ = False
    
    """
    Boton Aceptar
    """
    pushButtonAccept = None
    
    """
    Almacena si se ha abierto el formulario con el método FLFormSearchDB::exec()
    """
    loop = None


    def __init__(self,*args, **kwargs):
        if isinstance(args[0],QString):
            super(FLFormSearchDB,self).__init(args[0], args[1],(Qt.WStyle_Customize, Qt.WStyle_Maximize, Qt.WStyle_Title, Qt.WStyle_NormalBorder, Qt.WType_Dialog, Qt.WShowModal, Qt.WStyle_SysMenu))
            self.init1(args[0],args[1])
        else:
            super(FLFormSearchDB,self).__init(args[1], args[2],(Qt.WStyle_Customize, Qt.WStyle_Maximize, Qt.WStyle_Title, Qt.WStyle_NormalBorder, Qt.WType_Dialog, Qt.WShowModal, Qt.WStyle_SysMenu))
            self.init2(args[0],args[1],args[2])
    """
    constructor.

    @param actionName Nombre de la acción asociada al formulario
    """
    def init1(self, actionName, parent = None):
        self.setFocusPolicy(QtGui.QWidget.NoFocus)
        if actionName.isEmpty():
            self.action_ = False
            print(FLUtil.translate("app","FLFormSearchDB : Nombre de acción vacío"))
            return
        else:
            self.action_ = FLSqlConnections.database().manager().action(actionName)
        if not self.action_:
            print(FLUtil.translate("app","FLFormSearchDB : No existe la acción %s" % actionName))
            return
        
        self.cursor_ = FLSqlCursor(self.action_.table(), True,"default", 0, 0, self)
        self.name_ = self.action_.name()
        
        self.initForm()
            

    """ constructor sobrecargado.

    @param cursor Objeto FLSqlCursor para asignar a este formulario
    @param actionName Nombre de la acción asociada al formulario
    """
    def init2(self, cursor,actionName = QString.null, parent = None):
        self.setFocusPolicy(QtGui.QWidget.NoFocus)
        if actionName.isEmpty():
            self.action_ = False
        elif cursor:
            self.action_ = FLSqlConnections.database().manager().action(actionName)
        self.cursor_ = cursor 
        if self.action_:
            self.name_ = self.action_.name()
        else:
            self.name_ = QString.null 

    """
    destructor
    """
    def __del__(self):
        if self.cursor_ and not self.cursor_.aqWasDeleted():
            self.cursor_.restoreEditionFlag(self)
            self.cursor_.restoreBrowseFlag(self)

    """
    Establece el cursor que debe utilizar el formulario.

    @param c Cursor con el que trabajar
    """
    def setCursor(self, c):
        if not c == self.cursor_ and self.cursor_ and self.oldCursorCtxt:
            self.cursor_.setContext(self.oldCursorCtxt)
        
        if not c:
            return
        
        if self.cursor_:
            self.cursor_.recordChoosed.disconnect(self.accept())
            self.cursor_.destroyed.disconnect(self.cursorDestroyed())
        
        if self.cursor_ and not c == self.cursor_:
            self.cursor_.restoreEditionFlag(self)
            self.cursor_.restoreBrowseFlag(self)
        
        self.cursor_ = c
        self.cursor_.setEdition(False, self)
        self.cursor_.setBrowse(False, self)
        self.cursor_.recordChoosed.connect(self.accept())
        self.cursor_.destroyed.connect(self.cursorDestroyed())
        if self.iface and self.cursor_:
            self.oldCursorCtxt = self.cursor_.context()
            self.cursor_.setContext(self.iface)
        
    
    
    """
    Sobrecargado de setMainWidget.

    Aqui toma el nombre de un formulario de la acción asociada y construye el Widget principal, a partir de él.
    """    

    """
    Reimplementado, añade un widget como principal del formulario
    """
    def setMainWidget(self, *args, **kwargs):
        if len(args) == 0:
            super(FLFormSearchDB,self).setMainWidget()
        else:
            self.setMainWidgetFLFormSearhDB(args[0])
    
    def setMainWidgetFLFormSearchDB(self, w):
        if not self.cursor_ or not w:
            return
        if self.showed:
            if self.mainWidget_ and not self.mainWidget_ == w:
                self.initMainWidget(w)
        else:
            w.hide()
        
        if self.layoutButtons:
            del self.layoutButtons
        
        if self.layout:
            del self.layout 
        
        w.setFont(QtGui.qApp.font())
        desk = QtGui.QApplication.desktop.availableGeometry(self)
        geo = w.geometry()
        tooLarge = False
        
        if geo.width() > desk.width() or geo.height() > desk.heigh():
            sv = QtGui.QScrollArea(self)
            #sv->setResizePolicy(QScrollView::AutoOneFit) FIXME
            sv.hide()
            sv.addChild(w)
            self.layout = QtGui.QVBoxLayout(self, 5,5,"vlay" + self.name_)
            self.Layout.add(sv)
            sv.resize(self.size().expand(desk.size()))
            self.layoutButtons = QtGui.QHBoxLayout(self.layout, 3, "hlay" + self.name_)
            self.formReady.connect(sv.show())
            tooLarge = True
        else:
            self.layout = QtGui.QVBoxLayout(self, 2, 3, "vlay" + self.name_)
            self.layout.add(w)
            self.layoutButtons = QtGui.QHBoxLayout(self.layout, 3, "hlay" + self.name_)
            
        
        pbSize = Qt.qsize(22,22)
        """
        QToolButton *wt = QWhatsThis::whatsThisButton(this);
        wt->setIconSet(QPixmap::fromMimeSource("about.png"));
        layoutButtons->addWidget(wt);
        wt->show()
        """
        self.layoutButtons.addItem(QtGui.QSpacerItem(20,20, Qt.QSizePolicy.Expanding, Qt.QSizePolicy.Minimum))
        self.pushButtonAccept = QtGui.QPushButton(self,"pushButtonAccept")
        self.pushButtonAccept.sizePolicy(Qt.QSizePolicy(0,0,0,0, self.pushButtonAccept.sizePolicy().hasHeightForWidth()))
        self.pushButtonAccept.setMinimumSize(pbSize)
        self.pushButtonAccept.setMaximumSize(pbSize)
        ok = QtGui.QIcon(FLUtil.filedir("icons","button_ok.png"))
        self.pushButtonAccept.setIcon(ok)
        self.pushButtonAccept.setFocusPolicy(QtGui.QWidget.NoFocus)
        
        #pushButtonAccept->setAccel(QKeySequence(Qt::Key_F10)); FIXME
        self.pushButtonAccept.setDefault(True)
        #QToolTip::add(pushButtonAccept, tr("Seleccionar registro actual y cerrar formulario (F10)")); FIXME
        #QWhatsThis::add(pushButtonAccept, tr("Seleccionar registro actual y cerrar formulario (F10)")); FIXME
        self.layoutButtons.addWidget(self.pushButtonAccept)
        self.pushButtonAccept.clicked.connect(self.accept())
        
        self.pushButtonCancel = QtGui.QPushButton(self, "pushButtonCancel")
        self.pushButtonCancel.sizePolicy(Qt.QSizePolicy(0,0,0,0, self.pushButtonAccept.sizePolicy().hasHeightForWidth()))
        self.pushButtonCancel.setMinimumSize(pbSize)
        self.pushButtonCancel.setMaximumSize(pbSize)
        cancel = QtGui.QIcon(FLUtil.filedir("icons","button_cancel.png"))
        self.pushButtonAccept.setIcon(cancel)
        self.pushButtonCancel.setFocusPolicy(QtGui.QWidget.NoFocus)
        #pushButtonCancel->setAccel(QKeySequence(tr("Esc"))); #FIXME
        #QToolTip::add(pushButtonCancel, tr("Cerrar formulario sin seleccionar registro (Esc)")); #FIXME
        #QWhatsThis::add(pushButtonCancel, tr("Cerrar formulario sin seleccionar registro (Esc)")); #FIXME
        self.layoutButtons.addItem(QtGui.QSpacerItem(20,20, Qt.QSizePolicy.Fixed, Qt.QSizePolicy.Fixed))
        self.layoutButtons.addWidget(self.pushButtonCancel)
        self.pushButtonCancel.clicked.connect(self.reject())
        
        self.mainWidget_ = w
        self.cursor_.setEdition(False)
        self.cursor_.setBrowse(False)
        self.cursor_.recordChoosed.connect(self.accept())
        
        if not tooLarge:
            mWidth = self.mainWidget_.width()
            mHeight = self.mainWidget_.height()
            actWin = QtGui.qApp.activeWindow()
            if actWin:
                screen = actWin.geometry()
            else:
                screen = QtGui.qApp.mainWidget().geometry()
            p = screen.center() - Qt.QPoint(mWidth / 2, mHeight / 2)
            
            if p.x() + mWidth > desk.width():
                p.setx(desk.width() - mWidth)
            if p.y() + mHeight > desk.height():
                p.sety(desk.height() - mHeight)
            if p.x() < 0:
                p.setx(0)
            if p.y() < 0:
                p.sety(0)
            self.move(p)
            
    """
    Muestra el formulario y entra en un nuevo bucle de eventos
    para esperar, a seleccionar registro.

    Se espera el nombre de un campo del cursor
    devolviendo el valor de dicho campo si se acepta el formulario
    y un QVariant::Invalid si se cancela.

    @param n Nombre del un campo del cursor del formulario
    @return El valor del campo si se acepta, o QVariant::Invalid si se cancela
    """
    def exec(self, n = QString.null):
        if not self.cursor_:
            return QVariant()
        
        if self.loop and self.inExec_:
            print(FLUtil.translate("app","FLFormSearchDB::exec(): Se ha detectado una llamada recursiva"))
            self.QWidget.show()
            if self.initFocusWidget_:
                self.initFocusWidget_.setFocus()
            return QVariant()
        
        self.inExec_ = True
        self.acceptingRejecting_ = False
        
        self.QWidget.show()
        if self.initFocusWidget_:
            self.initFocusWidget_.setFocus()
        
        if self.iface:
            aqApp.call("init", self.QSArgumentList(), self.iface)
        
        #if (!isClosing_ && !aqApp->project()->interpreter()->hadError()) #FIXME
        #    QTimer::singleShot(0, this, SLOT(emitFormReady())); #FIXME
        
        self.accepted_ = False
        self.loop = True
        if not self.isClosing_ and not self.acceptingRejecting_:
            QtGui.QApplication.eventLoop().enterLoop()
        self.loop = False
        
        self.clearWFlags(Qt.WShowModal)
        v = None
        if self.accepted_ and not n.isEmpty():
            v = self.cursor_.valueBuffer(n)
        else:
            v = QVariant()
        
        self.inExec_ = False
        return v
        

    """
    Aplica un filtro al cursor
    """
    def setFilter(self, f):
        if not self.cursor_:
            return
        previousF = QString(self.cursor_.mainFilter())
        newF = QString(None)
        if previousF.isEmpty():
            newF = f
        elif previousF.contains(f):
            return
        else:
            newF = previousF + " AND " + f
        self.cursor_.setMainFilter(newF)
    

    """
    Devuelve el nombre de la clase del formulario en tiempo de ejecución
    """
    def formClassName(self):
        return "FormSearhDB"
        

    """
    Establece el título de la ventana.

    @param text Texto a establecer como título de la ventana
    @author Silix
    """
    def setCaptionWidget(self, text):
        if text.isEmpty():
            return 
        self.setCaption(text)
        

    """
    Nombre interno del formulario
    """
    def geoName(self):
        return QString("formSearch") + self.idMDI_

    """
    Captura evento cerrar
    """
    def closeEvent(self, e):
        self.frameGeometry()
        if self.focusWidget():
            fdb = self.focusWidget().parentWidget()
            if fdb and fdb.autoComFrame_ and fdb.autoComFrame_.isvisible():
                fdb.autoComFrame_.hide()
                return
        
        if self.cursor_ and self.pushButtonCancel:
            if not self.pushButtonCancel.isEnabled():
                return
            self.isClosing_ = True
            self.setCursor(None)
        else:
            self.isClosing_ = True
        if self.isShown():
            self.reject()
        if self.isHidden():
            self.closed()
            self.QWidget.closeEvent(e)
            self.deleteLater()
        
            
        


    """
    Invoca a la función "init()" del script asociado al formulario
    """
    @QtCore.pyqtSlot()
    def initScript(self):
        return False

    """
    Redefinida por conveniencia
    """
    @QtCore.pyqtSlot()
    def hide(self):
        if self.isHidden():
            return
        
        self.QWidget.hide()
        if self.loop:
            self.loop = False
            QtGui.QApplication.eventLoop().exitLoop()

    """
    Se activa al pulsar el boton aceptar
    """
    @QtCore.pyqtSlot()
    def accept(self):
        if self.acceptingRejecting_:
            return
        self.frameGeometry()
        if self.cursor_:
            self.cursor_.recordChoosed.disconnect(self.accept())
            self.accepted_ = True
        
        self.acceptingRejecting_ = True
        self.hide()
        

    """
    Se activa al pulsar el botón cancelar
    """
    @QtCore.pyqtSlot()
    def reject(self):
        if self.acceptingRejecting_:
            return
        self.frameGeometry()
        if self.cursor_:
            self.cursor_.recordChoosed.disconnect(self.accept())
        self.acceptingRejecting_ = True
        self.hide()

    """
    Redefinida por conveniencia
    """
    @QtCore.pyqtSlot()
    def show(self):
        self.exec()