Ejemplo n.º 1
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.º 2
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.º 3
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.º 4
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.º 5
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.º 6
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()